enact-cli 1.0.9 → 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 +1542 -136
- package/dist/index.js.bak +1542 -136
- package/dist/mcp-server.js +3482 -472
- package/dist/mcp-server.js.bak +3482 -472
- 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 +3 -2
- 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
CHANGED
|
@@ -26,6 +26,7 @@ var __export = (target, all) => {
|
|
|
26
26
|
set: (newValue) => all[name] = () => newValue
|
|
27
27
|
});
|
|
28
28
|
};
|
|
29
|
+
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
29
30
|
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
30
31
|
|
|
31
32
|
// node_modules/uri-js/dist/es5/uri.all.js
|
|
@@ -6195,6 +6196,1207 @@ var require_ajv = __commonJS((exports, module) => {
|
|
|
6195
6196
|
function noop() {}
|
|
6196
6197
|
});
|
|
6197
6198
|
|
|
6199
|
+
// src/exec/logger.ts
|
|
6200
|
+
var createLogger = () => {
|
|
6201
|
+
let mcpServer = null;
|
|
6202
|
+
const shouldSuppressConsole = process.env.CI === "true" || process.env.ENACT_SKIP_INTERACTIVE === "true";
|
|
6203
|
+
return {
|
|
6204
|
+
info: (message, ...args) => {
|
|
6205
|
+
if (!shouldSuppressConsole) {
|
|
6206
|
+
console.error("[INFO]", message, ...args);
|
|
6207
|
+
}
|
|
6208
|
+
if (mcpServer) {
|
|
6209
|
+
try {
|
|
6210
|
+
mcpServer.server.sendLoggingMessage({ level: "info", data: message });
|
|
6211
|
+
} catch (error) {}
|
|
6212
|
+
}
|
|
6213
|
+
},
|
|
6214
|
+
error: (message, ...args) => {
|
|
6215
|
+
if (!shouldSuppressConsole) {
|
|
6216
|
+
console.error("[ERROR]", message, ...args);
|
|
6217
|
+
}
|
|
6218
|
+
if (mcpServer) {
|
|
6219
|
+
try {
|
|
6220
|
+
mcpServer.server.sendLoggingMessage({ level: "error", data: message });
|
|
6221
|
+
} catch (error) {}
|
|
6222
|
+
}
|
|
6223
|
+
},
|
|
6224
|
+
warn: (message, ...args) => {
|
|
6225
|
+
if (!shouldSuppressConsole) {
|
|
6226
|
+
console.warn("[WARN]", message, ...args);
|
|
6227
|
+
}
|
|
6228
|
+
if (mcpServer) {
|
|
6229
|
+
try {
|
|
6230
|
+
mcpServer.server.sendLoggingMessage({ level: "warning", data: message });
|
|
6231
|
+
} catch (error) {}
|
|
6232
|
+
}
|
|
6233
|
+
},
|
|
6234
|
+
debug: (message, ...args) => {
|
|
6235
|
+
if ((process.env.DEBUG || process.env.VERBOSE) && !shouldSuppressConsole) {
|
|
6236
|
+
console.error("[DEBUG]", message, ...args);
|
|
6237
|
+
}
|
|
6238
|
+
if (mcpServer) {
|
|
6239
|
+
try {
|
|
6240
|
+
mcpServer.server.sendLoggingMessage({ level: "debug", data: message });
|
|
6241
|
+
} catch (error) {}
|
|
6242
|
+
}
|
|
6243
|
+
},
|
|
6244
|
+
setServer: (server) => {
|
|
6245
|
+
mcpServer = server;
|
|
6246
|
+
},
|
|
6247
|
+
clientLoggingEnabled: () => {
|
|
6248
|
+
return !!mcpServer;
|
|
6249
|
+
}
|
|
6250
|
+
};
|
|
6251
|
+
}, logger, logger_default;
|
|
6252
|
+
var init_logger = __esm(() => {
|
|
6253
|
+
logger = createLogger();
|
|
6254
|
+
logger_default = logger;
|
|
6255
|
+
});
|
|
6256
|
+
|
|
6257
|
+
// node_modules/sisteransi/src/index.js
|
|
6258
|
+
var require_src = __commonJS((exports, module) => {
|
|
6259
|
+
var ESC = "\x1B";
|
|
6260
|
+
var CSI = `${ESC}[`;
|
|
6261
|
+
var beep = "\x07";
|
|
6262
|
+
var cursor = {
|
|
6263
|
+
to(x, y) {
|
|
6264
|
+
if (!y)
|
|
6265
|
+
return `${CSI}${x + 1}G`;
|
|
6266
|
+
return `${CSI}${y + 1};${x + 1}H`;
|
|
6267
|
+
},
|
|
6268
|
+
move(x, y) {
|
|
6269
|
+
let ret = "";
|
|
6270
|
+
if (x < 0)
|
|
6271
|
+
ret += `${CSI}${-x}D`;
|
|
6272
|
+
else if (x > 0)
|
|
6273
|
+
ret += `${CSI}${x}C`;
|
|
6274
|
+
if (y < 0)
|
|
6275
|
+
ret += `${CSI}${-y}A`;
|
|
6276
|
+
else if (y > 0)
|
|
6277
|
+
ret += `${CSI}${y}B`;
|
|
6278
|
+
return ret;
|
|
6279
|
+
},
|
|
6280
|
+
up: (count = 1) => `${CSI}${count}A`,
|
|
6281
|
+
down: (count = 1) => `${CSI}${count}B`,
|
|
6282
|
+
forward: (count = 1) => `${CSI}${count}C`,
|
|
6283
|
+
backward: (count = 1) => `${CSI}${count}D`,
|
|
6284
|
+
nextLine: (count = 1) => `${CSI}E`.repeat(count),
|
|
6285
|
+
prevLine: (count = 1) => `${CSI}F`.repeat(count),
|
|
6286
|
+
left: `${CSI}G`,
|
|
6287
|
+
hide: `${CSI}?25l`,
|
|
6288
|
+
show: `${CSI}?25h`,
|
|
6289
|
+
save: `${ESC}7`,
|
|
6290
|
+
restore: `${ESC}8`
|
|
6291
|
+
};
|
|
6292
|
+
var scroll = {
|
|
6293
|
+
up: (count = 1) => `${CSI}S`.repeat(count),
|
|
6294
|
+
down: (count = 1) => `${CSI}T`.repeat(count)
|
|
6295
|
+
};
|
|
6296
|
+
var erase = {
|
|
6297
|
+
screen: `${CSI}2J`,
|
|
6298
|
+
up: (count = 1) => `${CSI}1J`.repeat(count),
|
|
6299
|
+
down: (count = 1) => `${CSI}J`.repeat(count),
|
|
6300
|
+
line: `${CSI}2K`,
|
|
6301
|
+
lineEnd: `${CSI}K`,
|
|
6302
|
+
lineStart: `${CSI}1K`,
|
|
6303
|
+
lines(count) {
|
|
6304
|
+
let clear = "";
|
|
6305
|
+
for (let i = 0;i < count; i++)
|
|
6306
|
+
clear += this.line + (i < count - 1 ? cursor.up() : "");
|
|
6307
|
+
if (count)
|
|
6308
|
+
clear += cursor.left;
|
|
6309
|
+
return clear;
|
|
6310
|
+
}
|
|
6311
|
+
};
|
|
6312
|
+
module.exports = { cursor, scroll, erase, beep };
|
|
6313
|
+
});
|
|
6314
|
+
|
|
6315
|
+
// node_modules/picocolors/picocolors.js
|
|
6316
|
+
var require_picocolors = __commonJS((exports, module) => {
|
|
6317
|
+
var p = process || {};
|
|
6318
|
+
var argv = p.argv || [];
|
|
6319
|
+
var env = p.env || {};
|
|
6320
|
+
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);
|
|
6321
|
+
var formatter = (open, close, replace = open) => (input) => {
|
|
6322
|
+
let string2 = "" + input, index = string2.indexOf(close, open.length);
|
|
6323
|
+
return ~index ? open + replaceClose(string2, close, replace, index) + close : open + string2 + close;
|
|
6324
|
+
};
|
|
6325
|
+
var replaceClose = (string2, close, replace, index) => {
|
|
6326
|
+
let result = "", cursor = 0;
|
|
6327
|
+
do {
|
|
6328
|
+
result += string2.substring(cursor, index) + replace;
|
|
6329
|
+
cursor = index + close.length;
|
|
6330
|
+
index = string2.indexOf(close, cursor);
|
|
6331
|
+
} while (~index);
|
|
6332
|
+
return result + string2.substring(cursor);
|
|
6333
|
+
};
|
|
6334
|
+
var createColors = (enabled = isColorSupported) => {
|
|
6335
|
+
let f = enabled ? formatter : () => String;
|
|
6336
|
+
return {
|
|
6337
|
+
isColorSupported: enabled,
|
|
6338
|
+
reset: f("\x1B[0m", "\x1B[0m"),
|
|
6339
|
+
bold: f("\x1B[1m", "\x1B[22m", "\x1B[22m\x1B[1m"),
|
|
6340
|
+
dim: f("\x1B[2m", "\x1B[22m", "\x1B[22m\x1B[2m"),
|
|
6341
|
+
italic: f("\x1B[3m", "\x1B[23m"),
|
|
6342
|
+
underline: f("\x1B[4m", "\x1B[24m"),
|
|
6343
|
+
inverse: f("\x1B[7m", "\x1B[27m"),
|
|
6344
|
+
hidden: f("\x1B[8m", "\x1B[28m"),
|
|
6345
|
+
strikethrough: f("\x1B[9m", "\x1B[29m"),
|
|
6346
|
+
black: f("\x1B[30m", "\x1B[39m"),
|
|
6347
|
+
red: f("\x1B[31m", "\x1B[39m"),
|
|
6348
|
+
green: f("\x1B[32m", "\x1B[39m"),
|
|
6349
|
+
yellow: f("\x1B[33m", "\x1B[39m"),
|
|
6350
|
+
blue: f("\x1B[34m", "\x1B[39m"),
|
|
6351
|
+
magenta: f("\x1B[35m", "\x1B[39m"),
|
|
6352
|
+
cyan: f("\x1B[36m", "\x1B[39m"),
|
|
6353
|
+
white: f("\x1B[37m", "\x1B[39m"),
|
|
6354
|
+
gray: f("\x1B[90m", "\x1B[39m"),
|
|
6355
|
+
bgBlack: f("\x1B[40m", "\x1B[49m"),
|
|
6356
|
+
bgRed: f("\x1B[41m", "\x1B[49m"),
|
|
6357
|
+
bgGreen: f("\x1B[42m", "\x1B[49m"),
|
|
6358
|
+
bgYellow: f("\x1B[43m", "\x1B[49m"),
|
|
6359
|
+
bgBlue: f("\x1B[44m", "\x1B[49m"),
|
|
6360
|
+
bgMagenta: f("\x1B[45m", "\x1B[49m"),
|
|
6361
|
+
bgCyan: f("\x1B[46m", "\x1B[49m"),
|
|
6362
|
+
bgWhite: f("\x1B[47m", "\x1B[49m"),
|
|
6363
|
+
blackBright: f("\x1B[90m", "\x1B[39m"),
|
|
6364
|
+
redBright: f("\x1B[91m", "\x1B[39m"),
|
|
6365
|
+
greenBright: f("\x1B[92m", "\x1B[39m"),
|
|
6366
|
+
yellowBright: f("\x1B[93m", "\x1B[39m"),
|
|
6367
|
+
blueBright: f("\x1B[94m", "\x1B[39m"),
|
|
6368
|
+
magentaBright: f("\x1B[95m", "\x1B[39m"),
|
|
6369
|
+
cyanBright: f("\x1B[96m", "\x1B[39m"),
|
|
6370
|
+
whiteBright: f("\x1B[97m", "\x1B[39m"),
|
|
6371
|
+
bgBlackBright: f("\x1B[100m", "\x1B[49m"),
|
|
6372
|
+
bgRedBright: f("\x1B[101m", "\x1B[49m"),
|
|
6373
|
+
bgGreenBright: f("\x1B[102m", "\x1B[49m"),
|
|
6374
|
+
bgYellowBright: f("\x1B[103m", "\x1B[49m"),
|
|
6375
|
+
bgBlueBright: f("\x1B[104m", "\x1B[49m"),
|
|
6376
|
+
bgMagentaBright: f("\x1B[105m", "\x1B[49m"),
|
|
6377
|
+
bgCyanBright: f("\x1B[106m", "\x1B[49m"),
|
|
6378
|
+
bgWhiteBright: f("\x1B[107m", "\x1B[49m")
|
|
6379
|
+
};
|
|
6380
|
+
};
|
|
6381
|
+
module.exports = createColors();
|
|
6382
|
+
module.exports.createColors = createColors;
|
|
6383
|
+
});
|
|
6384
|
+
|
|
6385
|
+
// node_modules/@clack/core/dist/index.cjs
|
|
6386
|
+
var require_dist = __commonJS((exports) => {
|
|
6387
|
+
var sisteransi = require_src();
|
|
6388
|
+
var node_process = __require("node:process");
|
|
6389
|
+
var s$2 = __require("node:readline");
|
|
6390
|
+
var node_stream = __require("node:stream");
|
|
6391
|
+
var i$1 = require_picocolors();
|
|
6392
|
+
function _interopDefaultCompat(C) {
|
|
6393
|
+
return C && typeof C == "object" && "default" in C ? C.default : C;
|
|
6394
|
+
}
|
|
6395
|
+
function _interopNamespaceCompat(C) {
|
|
6396
|
+
if (C && typeof C == "object" && "default" in C)
|
|
6397
|
+
return C;
|
|
6398
|
+
const t = Object.create(null);
|
|
6399
|
+
if (C)
|
|
6400
|
+
for (const F in C)
|
|
6401
|
+
t[F] = C[F];
|
|
6402
|
+
return t.default = C, t;
|
|
6403
|
+
}
|
|
6404
|
+
var s__namespace = _interopNamespaceCompat(s$2);
|
|
6405
|
+
var s__default = _interopDefaultCompat(s$2);
|
|
6406
|
+
var i__default = _interopDefaultCompat(i$1);
|
|
6407
|
+
function ansiRegex({ onlyFirst: C = false } = {}) {
|
|
6408
|
+
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("|");
|
|
6409
|
+
return new RegExp(F, C ? undefined : "g");
|
|
6410
|
+
}
|
|
6411
|
+
var regex = ansiRegex();
|
|
6412
|
+
function stripAnsi(C) {
|
|
6413
|
+
if (typeof C != "string")
|
|
6414
|
+
throw new TypeError(`Expected a \`string\`, got \`${typeof C}\``);
|
|
6415
|
+
return C.replace(regex, "");
|
|
6416
|
+
}
|
|
6417
|
+
function getDefaultExportFromCjs(C) {
|
|
6418
|
+
return C && C.__esModule && Object.prototype.hasOwnProperty.call(C, "default") ? C.default : C;
|
|
6419
|
+
}
|
|
6420
|
+
var eastasianwidth = { exports: {} };
|
|
6421
|
+
(function(C) {
|
|
6422
|
+
var t = {};
|
|
6423
|
+
C.exports = t, t.eastAsianWidth = function(E) {
|
|
6424
|
+
var B = E.charCodeAt(0), A = E.length == 2 ? E.charCodeAt(1) : 0, D = B;
|
|
6425
|
+
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";
|
|
6426
|
+
}, t.characterLength = function(E) {
|
|
6427
|
+
var B = this.eastAsianWidth(E);
|
|
6428
|
+
return B == "F" || B == "W" || B == "A" ? 2 : 1;
|
|
6429
|
+
};
|
|
6430
|
+
function F(E) {
|
|
6431
|
+
return E.match(/[\uD800-\uDBFF][\uDC00-\uDFFF]|[^\uD800-\uDFFF]/g) || [];
|
|
6432
|
+
}
|
|
6433
|
+
t.length = function(E) {
|
|
6434
|
+
for (var B = F(E), A = 0, D = 0;D < B.length; D++)
|
|
6435
|
+
A = A + this.characterLength(B[D]);
|
|
6436
|
+
return A;
|
|
6437
|
+
}, t.slice = function(E, B, A) {
|
|
6438
|
+
textLen = t.length(E), B = B || 0, A = A || 1, B < 0 && (B = textLen + B), A < 0 && (A = textLen + A);
|
|
6439
|
+
for (var D = "", f = 0, y = F(E), d = 0;d < y.length; d++) {
|
|
6440
|
+
var _ = y[d], w = t.length(_);
|
|
6441
|
+
if (f >= B - (w == 2 ? 1 : 0))
|
|
6442
|
+
if (f + w <= A)
|
|
6443
|
+
D += _;
|
|
6444
|
+
else
|
|
6445
|
+
break;
|
|
6446
|
+
f += w;
|
|
6447
|
+
}
|
|
6448
|
+
return D;
|
|
6449
|
+
};
|
|
6450
|
+
})(eastasianwidth);
|
|
6451
|
+
var eastasianwidthExports = eastasianwidth.exports;
|
|
6452
|
+
var eastAsianWidth = getDefaultExportFromCjs(eastasianwidthExports);
|
|
6453
|
+
var emojiRegex3 = function() {
|
|
6454
|
+
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;
|
|
6455
|
+
};
|
|
6456
|
+
var emojiRegex$1 = getDefaultExportFromCjs(emojiRegex3);
|
|
6457
|
+
function stringWidth(C, t = {}) {
|
|
6458
|
+
if (typeof C != "string" || C.length === 0 || (t = { ambiguousIsNarrow: true, ...t }, C = stripAnsi(C), C.length === 0))
|
|
6459
|
+
return 0;
|
|
6460
|
+
C = C.replace(emojiRegex$1(), " ");
|
|
6461
|
+
const F = t.ambiguousIsNarrow ? 1 : 2;
|
|
6462
|
+
let E = 0;
|
|
6463
|
+
for (const B of C) {
|
|
6464
|
+
const A = B.codePointAt(0);
|
|
6465
|
+
if (A <= 31 || A >= 127 && A <= 159 || A >= 768 && A <= 879)
|
|
6466
|
+
continue;
|
|
6467
|
+
switch (eastAsianWidth.eastAsianWidth(B)) {
|
|
6468
|
+
case "F":
|
|
6469
|
+
case "W":
|
|
6470
|
+
E += 2;
|
|
6471
|
+
break;
|
|
6472
|
+
case "A":
|
|
6473
|
+
E += F;
|
|
6474
|
+
break;
|
|
6475
|
+
default:
|
|
6476
|
+
E += 1;
|
|
6477
|
+
}
|
|
6478
|
+
}
|
|
6479
|
+
return E;
|
|
6480
|
+
}
|
|
6481
|
+
var ANSI_BACKGROUND_OFFSET = 10;
|
|
6482
|
+
var wrapAnsi16 = (C = 0) => (t) => `\x1B[${t + C}m`;
|
|
6483
|
+
var wrapAnsi256 = (C = 0) => (t) => `\x1B[${38 + C};5;${t}m`;
|
|
6484
|
+
var wrapAnsi16m = (C = 0) => (t, F, E) => `\x1B[${38 + C};2;${t};${F};${E}m`;
|
|
6485
|
+
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] } };
|
|
6486
|
+
Object.keys(styles.modifier);
|
|
6487
|
+
var foregroundColorNames = Object.keys(styles.color);
|
|
6488
|
+
var backgroundColorNames = Object.keys(styles.bgColor);
|
|
6489
|
+
[...foregroundColorNames];
|
|
6490
|
+
function assembleStyles() {
|
|
6491
|
+
const C = new Map;
|
|
6492
|
+
for (const [t, F] of Object.entries(styles)) {
|
|
6493
|
+
for (const [E, B] of Object.entries(F))
|
|
6494
|
+
styles[E] = { open: `\x1B[${B[0]}m`, close: `\x1B[${B[1]}m` }, F[E] = styles[E], C.set(B[0], B[1]);
|
|
6495
|
+
Object.defineProperty(styles, t, { value: F, enumerable: false });
|
|
6496
|
+
}
|
|
6497
|
+
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) => {
|
|
6498
|
+
const F = /[a-f\d]{6}|[a-f\d]{3}/i.exec(t.toString(16));
|
|
6499
|
+
if (!F)
|
|
6500
|
+
return [0, 0, 0];
|
|
6501
|
+
let [E] = F;
|
|
6502
|
+
E.length === 3 && (E = [...E].map((A) => A + A).join(""));
|
|
6503
|
+
const B = Number.parseInt(E, 16);
|
|
6504
|
+
return [B >> 16 & 255, B >> 8 & 255, B & 255];
|
|
6505
|
+
}, enumerable: false }, hexToAnsi256: { value: (t) => styles.rgbToAnsi256(...styles.hexToRgb(t)), enumerable: false }, ansi256ToAnsi: { value: (t) => {
|
|
6506
|
+
if (t < 8)
|
|
6507
|
+
return 30 + t;
|
|
6508
|
+
if (t < 16)
|
|
6509
|
+
return 90 + (t - 8);
|
|
6510
|
+
let F, E, B;
|
|
6511
|
+
if (t >= 232)
|
|
6512
|
+
F = ((t - 232) * 10 + 8) / 255, E = F, B = F;
|
|
6513
|
+
else {
|
|
6514
|
+
t -= 16;
|
|
6515
|
+
const f = t % 36;
|
|
6516
|
+
F = Math.floor(t / 36) / 5, E = Math.floor(f / 6) / 5, B = f % 6 / 5;
|
|
6517
|
+
}
|
|
6518
|
+
const A = Math.max(F, E, B) * 2;
|
|
6519
|
+
if (A === 0)
|
|
6520
|
+
return 30;
|
|
6521
|
+
let D = 30 + (Math.round(B) << 2 | Math.round(E) << 1 | Math.round(F));
|
|
6522
|
+
return A === 2 && (D += 60), D;
|
|
6523
|
+
}, 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;
|
|
6524
|
+
}
|
|
6525
|
+
var ansiStyles = assembleStyles();
|
|
6526
|
+
var ESCAPES = new Set(["\x1B", ""]);
|
|
6527
|
+
var END_CODE = 39;
|
|
6528
|
+
var ANSI_ESCAPE_BELL = "\x07";
|
|
6529
|
+
var ANSI_CSI = "[";
|
|
6530
|
+
var ANSI_OSC = "]";
|
|
6531
|
+
var ANSI_SGR_TERMINATOR = "m";
|
|
6532
|
+
var ANSI_ESCAPE_LINK = `${ANSI_OSC}8;;`;
|
|
6533
|
+
var wrapAnsiCode = (C) => `${ESCAPES.values().next().value}${ANSI_CSI}${C}${ANSI_SGR_TERMINATOR}`;
|
|
6534
|
+
var wrapAnsiHyperlink = (C) => `${ESCAPES.values().next().value}${ANSI_ESCAPE_LINK}${C}${ANSI_ESCAPE_BELL}`;
|
|
6535
|
+
var wordLengths = (C) => C.split(" ").map((t) => stringWidth(t));
|
|
6536
|
+
var wrapWord = (C, t, F) => {
|
|
6537
|
+
const E = [...t];
|
|
6538
|
+
let B = false, A = false, D = stringWidth(stripAnsi(C[C.length - 1]));
|
|
6539
|
+
for (const [f, y] of E.entries()) {
|
|
6540
|
+
const d = stringWidth(y);
|
|
6541
|
+
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) {
|
|
6542
|
+
A ? y === ANSI_ESCAPE_BELL && (B = false, A = false) : y === ANSI_SGR_TERMINATOR && (B = false);
|
|
6543
|
+
continue;
|
|
6544
|
+
}
|
|
6545
|
+
D += d, D === F && f < E.length - 1 && (C.push(""), D = 0);
|
|
6546
|
+
}
|
|
6547
|
+
!D && C[C.length - 1].length > 0 && C.length > 1 && (C[C.length - 2] += C.pop());
|
|
6548
|
+
};
|
|
6549
|
+
var stringVisibleTrimSpacesRight = (C) => {
|
|
6550
|
+
const t = C.split(" ");
|
|
6551
|
+
let F = t.length;
|
|
6552
|
+
for (;F > 0 && !(stringWidth(t[F - 1]) > 0); )
|
|
6553
|
+
F--;
|
|
6554
|
+
return F === t.length ? C : t.slice(0, F).join(" ") + t.slice(F).join("");
|
|
6555
|
+
};
|
|
6556
|
+
var exec = (C, t, F = {}) => {
|
|
6557
|
+
if (F.trim !== false && C.trim() === "")
|
|
6558
|
+
return "";
|
|
6559
|
+
let E = "", B, A;
|
|
6560
|
+
const D = wordLengths(C);
|
|
6561
|
+
let f = [""];
|
|
6562
|
+
for (const [d, _] of C.split(" ").entries()) {
|
|
6563
|
+
F.trim !== false && (f[f.length - 1] = f[f.length - 1].trimStart());
|
|
6564
|
+
let w = stringWidth(f[f.length - 1]);
|
|
6565
|
+
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) {
|
|
6566
|
+
const S = t - w, $ = 1 + Math.floor((D[d] - S - 1) / t);
|
|
6567
|
+
Math.floor((D[d] - 1) / t) < $ && f.push(""), wrapWord(f, _, t);
|
|
6568
|
+
continue;
|
|
6569
|
+
}
|
|
6570
|
+
if (w + D[d] > t && w > 0 && D[d] > 0) {
|
|
6571
|
+
if (F.wordWrap === false && w < t) {
|
|
6572
|
+
wrapWord(f, _, t);
|
|
6573
|
+
continue;
|
|
6574
|
+
}
|
|
6575
|
+
f.push("");
|
|
6576
|
+
}
|
|
6577
|
+
if (w + D[d] > t && F.wordWrap === false) {
|
|
6578
|
+
wrapWord(f, _, t);
|
|
6579
|
+
continue;
|
|
6580
|
+
}
|
|
6581
|
+
f[f.length - 1] += _;
|
|
6582
|
+
}
|
|
6583
|
+
F.trim !== false && (f = f.map((d) => stringVisibleTrimSpacesRight(d)));
|
|
6584
|
+
const y = [...f.join(`
|
|
6585
|
+
`)];
|
|
6586
|
+
for (const [d, _] of y.entries()) {
|
|
6587
|
+
if (E += _, ESCAPES.has(_)) {
|
|
6588
|
+
const { groups: S } = new RegExp(`(?:\\${ANSI_CSI}(?<code>\\d+)m|\\${ANSI_ESCAPE_LINK}(?<uri>.*)${ANSI_ESCAPE_BELL})`).exec(y.slice(d).join("")) || { groups: {} };
|
|
6589
|
+
if (S.code !== undefined) {
|
|
6590
|
+
const $ = Number.parseFloat(S.code);
|
|
6591
|
+
B = $ === END_CODE ? undefined : $;
|
|
6592
|
+
} else
|
|
6593
|
+
S.uri !== undefined && (A = S.uri.length === 0 ? undefined : S.uri);
|
|
6594
|
+
}
|
|
6595
|
+
const w = ansiStyles.codes.get(Number(B));
|
|
6596
|
+
y[d + 1] === `
|
|
6597
|
+
` ? (A && (E += wrapAnsiHyperlink("")), B && w && (E += wrapAnsiCode(w))) : _ === `
|
|
6598
|
+
` && (B && w && (E += wrapAnsiCode(B)), A && (E += wrapAnsiHyperlink(A)));
|
|
6599
|
+
}
|
|
6600
|
+
return E;
|
|
6601
|
+
};
|
|
6602
|
+
function wrapAnsi(C, t, F) {
|
|
6603
|
+
return String(C).normalize().replace(/\r\n/g, `
|
|
6604
|
+
`).split(`
|
|
6605
|
+
`).map((E) => exec(E, t, F)).join(`
|
|
6606
|
+
`);
|
|
6607
|
+
}
|
|
6608
|
+
var a$1 = ["up", "down", "left", "right", "space", "enter", "cancel"];
|
|
6609
|
+
var settings = { actions: new Set(a$1), aliases: new Map([["k", "up"], ["j", "down"], ["h", "left"], ["l", "right"], ["\x03", "cancel"], ["escape", "cancel"]]) };
|
|
6610
|
+
function updateSettings(C) {
|
|
6611
|
+
for (const t in C) {
|
|
6612
|
+
const F = t;
|
|
6613
|
+
if (!Object.hasOwn(C, F))
|
|
6614
|
+
continue;
|
|
6615
|
+
const E = C[F];
|
|
6616
|
+
switch (F) {
|
|
6617
|
+
case "aliases": {
|
|
6618
|
+
for (const B in E)
|
|
6619
|
+
Object.hasOwn(E, B) && (settings.aliases.has(B) || settings.aliases.set(B, E[B]));
|
|
6620
|
+
break;
|
|
6621
|
+
}
|
|
6622
|
+
}
|
|
6623
|
+
}
|
|
6624
|
+
}
|
|
6625
|
+
function isActionKey(C, t) {
|
|
6626
|
+
if (typeof C == "string")
|
|
6627
|
+
return settings.aliases.get(C) === t;
|
|
6628
|
+
for (const F of C)
|
|
6629
|
+
if (F !== undefined && isActionKey(F, t))
|
|
6630
|
+
return true;
|
|
6631
|
+
return false;
|
|
6632
|
+
}
|
|
6633
|
+
function diffLines(C, t) {
|
|
6634
|
+
if (C === t)
|
|
6635
|
+
return;
|
|
6636
|
+
const F = C.split(`
|
|
6637
|
+
`), E = t.split(`
|
|
6638
|
+
`), B = [];
|
|
6639
|
+
for (let A = 0;A < Math.max(F.length, E.length); A++)
|
|
6640
|
+
F[A] !== E[A] && B.push(A);
|
|
6641
|
+
return B;
|
|
6642
|
+
}
|
|
6643
|
+
var x = globalThis.process.platform.startsWith("win");
|
|
6644
|
+
var CANCEL_SYMBOL = Symbol("clack:cancel");
|
|
6645
|
+
function isCancel(C) {
|
|
6646
|
+
return C === CANCEL_SYMBOL;
|
|
6647
|
+
}
|
|
6648
|
+
function setRawMode(C, t) {
|
|
6649
|
+
const F = C;
|
|
6650
|
+
F.isTTY && F.setRawMode(t);
|
|
6651
|
+
}
|
|
6652
|
+
function block({ input: C = node_process.stdin, output: t = node_process.stdout, overwrite: F = true, hideCursor: E = true } = {}) {
|
|
6653
|
+
const B = s__namespace.createInterface({ input: C, output: t, prompt: "", tabSize: 1 });
|
|
6654
|
+
s__namespace.emitKeypressEvents(C, B), C.isTTY && C.setRawMode(true);
|
|
6655
|
+
const A = (D, { name: f, sequence: y }) => {
|
|
6656
|
+
const d = String(D);
|
|
6657
|
+
if (isActionKey([d, f, y], "cancel")) {
|
|
6658
|
+
E && t.write(sisteransi.cursor.show), process.exit(0);
|
|
6659
|
+
return;
|
|
6660
|
+
}
|
|
6661
|
+
if (!F)
|
|
6662
|
+
return;
|
|
6663
|
+
const _ = f === "return" ? 0 : -1, w = f === "return" ? -1 : 0;
|
|
6664
|
+
s__namespace.moveCursor(t, _, w, () => {
|
|
6665
|
+
s__namespace.clearLine(t, 1, () => {
|
|
6666
|
+
C.once("keypress", A);
|
|
6667
|
+
});
|
|
6668
|
+
});
|
|
6669
|
+
};
|
|
6670
|
+
return E && t.write(sisteransi.cursor.hide), C.once("keypress", A), () => {
|
|
6671
|
+
C.off("keypress", A), E && t.write(sisteransi.cursor.show), C.isTTY && !x && C.setRawMode(false), B.terminal = false, B.close();
|
|
6672
|
+
};
|
|
6673
|
+
}
|
|
6674
|
+
var b = Object.defineProperty;
|
|
6675
|
+
var v$1 = (C, t, F) => (t in C) ? b(C, t, { enumerable: true, configurable: true, writable: true, value: F }) : C[t] = F;
|
|
6676
|
+
var s$1 = (C, t, F) => (v$1(C, typeof t != "symbol" ? t + "" : t, F), F);
|
|
6677
|
+
|
|
6678
|
+
class k {
|
|
6679
|
+
constructor(t, F = true) {
|
|
6680
|
+
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");
|
|
6681
|
+
const { input: E = node_process.stdin, output: B = node_process.stdout, render: A, signal: D, ...f } = t;
|
|
6682
|
+
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;
|
|
6683
|
+
}
|
|
6684
|
+
unsubscribe() {
|
|
6685
|
+
this._subscribers.clear();
|
|
6686
|
+
}
|
|
6687
|
+
setSubscriber(t, F) {
|
|
6688
|
+
const E = this._subscribers.get(t) ?? [];
|
|
6689
|
+
E.push(F), this._subscribers.set(t, E);
|
|
6690
|
+
}
|
|
6691
|
+
on(t, F) {
|
|
6692
|
+
this.setSubscriber(t, { cb: F });
|
|
6693
|
+
}
|
|
6694
|
+
once(t, F) {
|
|
6695
|
+
this.setSubscriber(t, { cb: F, once: true });
|
|
6696
|
+
}
|
|
6697
|
+
emit(t, ...F) {
|
|
6698
|
+
const E = this._subscribers.get(t) ?? [], B = [];
|
|
6699
|
+
for (const A of E)
|
|
6700
|
+
A.cb(...F), A.once && B.push(() => E.splice(E.indexOf(A), 1));
|
|
6701
|
+
for (const A of B)
|
|
6702
|
+
A();
|
|
6703
|
+
}
|
|
6704
|
+
prompt() {
|
|
6705
|
+
return new Promise((t, F) => {
|
|
6706
|
+
if (this._abortSignal) {
|
|
6707
|
+
if (this._abortSignal.aborted)
|
|
6708
|
+
return this.state = "cancel", this.close(), t(CANCEL_SYMBOL);
|
|
6709
|
+
this._abortSignal.addEventListener("abort", () => {
|
|
6710
|
+
this.state = "cancel", this.close();
|
|
6711
|
+
}, { once: true });
|
|
6712
|
+
}
|
|
6713
|
+
const E = new node_stream.Writable;
|
|
6714
|
+
E._write = (B, A, D) => {
|
|
6715
|
+
this._track && (this.value = this.rl?.line.replace(/\t/g, ""), this._cursor = this.rl?.cursor ?? 0, this.emit("value", this.value)), D();
|
|
6716
|
+
}, 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", () => {
|
|
6717
|
+
this.output.write(sisteransi.cursor.show), this.output.off("resize", this.render), setRawMode(this.input, false), t(this.value);
|
|
6718
|
+
}), this.once("cancel", () => {
|
|
6719
|
+
this.output.write(sisteransi.cursor.show), this.output.off("resize", this.render), setRawMode(this.input, false), t(CANCEL_SYMBOL);
|
|
6720
|
+
});
|
|
6721
|
+
});
|
|
6722
|
+
}
|
|
6723
|
+
onKeypress(t, F) {
|
|
6724
|
+
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") {
|
|
6725
|
+
if (!this.value && this.opts.placeholder && (this.rl?.write(this.opts.placeholder), this.emit("value", this.opts.placeholder)), this.opts.validate) {
|
|
6726
|
+
const E = this.opts.validate(this.value);
|
|
6727
|
+
E && (this.error = E instanceof Error ? E.message : E, this.state = "error", this.rl?.write(this.value));
|
|
6728
|
+
}
|
|
6729
|
+
this.state !== "error" && (this.state = "submit");
|
|
6730
|
+
}
|
|
6731
|
+
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();
|
|
6732
|
+
}
|
|
6733
|
+
close() {
|
|
6734
|
+
this.input.unpipe(), this.input.removeListener("keypress", this.onKeypress), this.output.write(`
|
|
6735
|
+
`), setRawMode(this.input, false), this.rl?.close(), this.rl = undefined, this.emit(`${this.state}`, this.value), this.unsubscribe();
|
|
6736
|
+
}
|
|
6737
|
+
restoreCursor() {
|
|
6738
|
+
const t = wrapAnsi(this._prevFrame, process.stdout.columns, { hard: true }).split(`
|
|
6739
|
+
`).length - 1;
|
|
6740
|
+
this.output.write(sisteransi.cursor.move(-999, t * -1));
|
|
6741
|
+
}
|
|
6742
|
+
render() {
|
|
6743
|
+
const t = wrapAnsi(this._render(this) ?? "", process.stdout.columns, { hard: true });
|
|
6744
|
+
if (t !== this._prevFrame) {
|
|
6745
|
+
if (this.state === "initial")
|
|
6746
|
+
this.output.write(sisteransi.cursor.hide);
|
|
6747
|
+
else {
|
|
6748
|
+
const F = diffLines(this._prevFrame, t);
|
|
6749
|
+
if (this.restoreCursor(), F && F?.length === 1) {
|
|
6750
|
+
const E = F[0];
|
|
6751
|
+
this.output.write(sisteransi.cursor.move(0, E)), this.output.write(sisteransi.erase.lines(1));
|
|
6752
|
+
const B = t.split(`
|
|
6753
|
+
`);
|
|
6754
|
+
this.output.write(B[E]), this._prevFrame = t, this.output.write(sisteransi.cursor.move(0, B.length - E - 1));
|
|
6755
|
+
return;
|
|
6756
|
+
}
|
|
6757
|
+
if (F && F?.length > 1) {
|
|
6758
|
+
const E = F[0];
|
|
6759
|
+
this.output.write(sisteransi.cursor.move(0, E)), this.output.write(sisteransi.erase.down());
|
|
6760
|
+
const B = t.split(`
|
|
6761
|
+
`).slice(E);
|
|
6762
|
+
this.output.write(B.join(`
|
|
6763
|
+
`)), this._prevFrame = t;
|
|
6764
|
+
return;
|
|
6765
|
+
}
|
|
6766
|
+
this.output.write(sisteransi.erase.down());
|
|
6767
|
+
}
|
|
6768
|
+
this.output.write(t), this.state === "initial" && (this.state = "active"), this._prevFrame = t;
|
|
6769
|
+
}
|
|
6770
|
+
}
|
|
6771
|
+
}
|
|
6772
|
+
|
|
6773
|
+
class s extends k {
|
|
6774
|
+
get cursor() {
|
|
6775
|
+
return this.value ? 0 : 1;
|
|
6776
|
+
}
|
|
6777
|
+
get _value() {
|
|
6778
|
+
return this.cursor === 0;
|
|
6779
|
+
}
|
|
6780
|
+
constructor(t) {
|
|
6781
|
+
super(t, false), this.value = !!t.initialValue, this.on("value", () => {
|
|
6782
|
+
this.value = this._value;
|
|
6783
|
+
}), this.on("confirm", (F) => {
|
|
6784
|
+
this.output.write(sisteransi.cursor.move(0, -1)), this.value = F, this.state = "submit", this.close();
|
|
6785
|
+
}), this.on("cursor", () => {
|
|
6786
|
+
this.value = !this.value;
|
|
6787
|
+
});
|
|
6788
|
+
}
|
|
6789
|
+
}
|
|
6790
|
+
var v = Object.defineProperty;
|
|
6791
|
+
var g = (C, t, F) => (t in C) ? v(C, t, { enumerable: true, configurable: true, writable: true, value: F }) : C[t] = F;
|
|
6792
|
+
var n$2 = (C, t, F) => (g(C, typeof t != "symbol" ? t + "" : t, F), F);
|
|
6793
|
+
var c$1 = (C, t, F) => {
|
|
6794
|
+
if (!t.has(C))
|
|
6795
|
+
throw TypeError("Cannot " + F);
|
|
6796
|
+
};
|
|
6797
|
+
var l$2 = (C, t, F) => (c$1(C, t, "read from private field"), F ? F.call(C) : t.get(C));
|
|
6798
|
+
var h = (C, t, F) => {
|
|
6799
|
+
if (t.has(C))
|
|
6800
|
+
throw TypeError("Cannot add the same private member more than once");
|
|
6801
|
+
t instanceof WeakSet ? t.add(C) : t.set(C, F);
|
|
6802
|
+
};
|
|
6803
|
+
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);
|
|
6804
|
+
var u$3;
|
|
6805
|
+
var m$1 = class extends k {
|
|
6806
|
+
constructor(t) {
|
|
6807
|
+
super(t, false), n$2(this, "options"), n$2(this, "cursor", 0), h(this, u$3, undefined);
|
|
6808
|
+
const { options: F } = t;
|
|
6809
|
+
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) => {
|
|
6810
|
+
switch (E) {
|
|
6811
|
+
case "left":
|
|
6812
|
+
case "up": {
|
|
6813
|
+
this.cursor = this.cursor === 0 ? this.options.length - 1 : this.cursor - 1;
|
|
6814
|
+
const B = this.options[this.cursor]?.group === true;
|
|
6815
|
+
!l$2(this, u$3) && B && (this.cursor = this.cursor === 0 ? this.options.length - 1 : this.cursor - 1);
|
|
6816
|
+
break;
|
|
6817
|
+
}
|
|
6818
|
+
case "down":
|
|
6819
|
+
case "right": {
|
|
6820
|
+
this.cursor = this.cursor === this.options.length - 1 ? 0 : this.cursor + 1;
|
|
6821
|
+
const B = this.options[this.cursor]?.group === true;
|
|
6822
|
+
!l$2(this, u$3) && B && (this.cursor = this.cursor === this.options.length - 1 ? 0 : this.cursor + 1);
|
|
6823
|
+
break;
|
|
6824
|
+
}
|
|
6825
|
+
case "space":
|
|
6826
|
+
this.toggleValue();
|
|
6827
|
+
break;
|
|
6828
|
+
}
|
|
6829
|
+
});
|
|
6830
|
+
}
|
|
6831
|
+
getGroupItems(t) {
|
|
6832
|
+
return this.options.filter((F) => F.group === t);
|
|
6833
|
+
}
|
|
6834
|
+
isGroupSelected(t) {
|
|
6835
|
+
return this.getGroupItems(t).every((F) => this.value.includes(F.value));
|
|
6836
|
+
}
|
|
6837
|
+
toggleValue() {
|
|
6838
|
+
const t = this.options[this.cursor];
|
|
6839
|
+
if (t.group === true) {
|
|
6840
|
+
const F = t.value, E = this.getGroupItems(F);
|
|
6841
|
+
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));
|
|
6842
|
+
} else {
|
|
6843
|
+
const F = this.value.includes(t.value);
|
|
6844
|
+
this.value = F ? this.value.filter((E) => E !== t.value) : [...this.value, t.value];
|
|
6845
|
+
}
|
|
6846
|
+
}
|
|
6847
|
+
};
|
|
6848
|
+
u$3 = new WeakMap;
|
|
6849
|
+
var o$2 = Object.defineProperty;
|
|
6850
|
+
var a = (C, t, F) => (t in C) ? o$2(C, t, { enumerable: true, configurable: true, writable: true, value: F }) : C[t] = F;
|
|
6851
|
+
var l$1 = (C, t, F) => (a(C, typeof t != "symbol" ? t + "" : t, F), F);
|
|
6852
|
+
var u$2 = class extends k {
|
|
6853
|
+
constructor(t) {
|
|
6854
|
+
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) => {
|
|
6855
|
+
F === "a" && this.toggleAll();
|
|
6856
|
+
}), this.on("cursor", (F) => {
|
|
6857
|
+
switch (F) {
|
|
6858
|
+
case "left":
|
|
6859
|
+
case "up":
|
|
6860
|
+
this.cursor = this.cursor === 0 ? this.options.length - 1 : this.cursor - 1;
|
|
6861
|
+
break;
|
|
6862
|
+
case "down":
|
|
6863
|
+
case "right":
|
|
6864
|
+
this.cursor = this.cursor === this.options.length - 1 ? 0 : this.cursor + 1;
|
|
6865
|
+
break;
|
|
6866
|
+
case "space":
|
|
6867
|
+
this.toggleValue();
|
|
6868
|
+
break;
|
|
6869
|
+
}
|
|
6870
|
+
});
|
|
6871
|
+
}
|
|
6872
|
+
get _value() {
|
|
6873
|
+
return this.options[this.cursor].value;
|
|
6874
|
+
}
|
|
6875
|
+
toggleAll() {
|
|
6876
|
+
const t = this.value.length === this.options.length;
|
|
6877
|
+
this.value = t ? [] : this.options.map((F) => F.value);
|
|
6878
|
+
}
|
|
6879
|
+
toggleValue() {
|
|
6880
|
+
const t = this.value.includes(this._value);
|
|
6881
|
+
this.value = t ? this.value.filter((F) => F !== this._value) : [...this.value, this._value];
|
|
6882
|
+
}
|
|
6883
|
+
};
|
|
6884
|
+
var u$1 = Object.defineProperty;
|
|
6885
|
+
var n$1 = (C, t, F) => (t in C) ? u$1(C, t, { enumerable: true, configurable: true, writable: true, value: F }) : C[t] = F;
|
|
6886
|
+
var e = (C, t, F) => (n$1(C, typeof t != "symbol" ? t + "" : t, F), F);
|
|
6887
|
+
|
|
6888
|
+
class m extends k {
|
|
6889
|
+
constructor({ mask: t, ...F }) {
|
|
6890
|
+
super(F), e(this, "valueWithCursor", ""), e(this, "_mask", "•"), this._mask = t ?? "•", this.on("finalize", () => {
|
|
6891
|
+
this.valueWithCursor = this.masked;
|
|
6892
|
+
}), this.on("value", () => {
|
|
6893
|
+
if (this.cursor >= this.value.length)
|
|
6894
|
+
this.valueWithCursor = `${this.masked}${i__default.inverse(i__default.hidden("_"))}`;
|
|
6895
|
+
else {
|
|
6896
|
+
const E = this.masked.slice(0, this.cursor), B = this.masked.slice(this.cursor);
|
|
6897
|
+
this.valueWithCursor = `${E}${i__default.inverse(B[0])}${B.slice(1)}`;
|
|
6898
|
+
}
|
|
6899
|
+
});
|
|
6900
|
+
}
|
|
6901
|
+
get cursor() {
|
|
6902
|
+
return this._cursor;
|
|
6903
|
+
}
|
|
6904
|
+
get masked() {
|
|
6905
|
+
return this.value.replaceAll(/./g, this._mask);
|
|
6906
|
+
}
|
|
6907
|
+
}
|
|
6908
|
+
var o$1 = Object.defineProperty;
|
|
6909
|
+
var n = (C, t, F) => (t in C) ? o$1(C, t, { enumerable: true, configurable: true, writable: true, value: F }) : C[t] = F;
|
|
6910
|
+
var r = (C, t, F) => (n(C, typeof t != "symbol" ? t + "" : t, F), F);
|
|
6911
|
+
|
|
6912
|
+
class u extends k {
|
|
6913
|
+
constructor(t) {
|
|
6914
|
+
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) => {
|
|
6915
|
+
switch (F) {
|
|
6916
|
+
case "left":
|
|
6917
|
+
case "up":
|
|
6918
|
+
this.cursor = this.cursor === 0 ? this.options.length - 1 : this.cursor - 1;
|
|
6919
|
+
break;
|
|
6920
|
+
case "down":
|
|
6921
|
+
case "right":
|
|
6922
|
+
this.cursor = this.cursor === this.options.length - 1 ? 0 : this.cursor + 1;
|
|
6923
|
+
break;
|
|
6924
|
+
}
|
|
6925
|
+
this.changeValue();
|
|
6926
|
+
});
|
|
6927
|
+
}
|
|
6928
|
+
get _value() {
|
|
6929
|
+
return this.options[this.cursor];
|
|
6930
|
+
}
|
|
6931
|
+
changeValue() {
|
|
6932
|
+
this.value = this._value.value;
|
|
6933
|
+
}
|
|
6934
|
+
}
|
|
6935
|
+
var p = Object.defineProperty;
|
|
6936
|
+
var l = (C, t, F) => (t in C) ? p(C, t, { enumerable: true, configurable: true, writable: true, value: F }) : C[t] = F;
|
|
6937
|
+
var i = (C, t, F) => (l(C, typeof t != "symbol" ? t + "" : t, F), F);
|
|
6938
|
+
|
|
6939
|
+
class c extends k {
|
|
6940
|
+
constructor(t) {
|
|
6941
|
+
super(t, false), i(this, "options"), i(this, "cursor", 0), this.options = t.options;
|
|
6942
|
+
const F = this.options.map(({ value: [E] }) => E?.toLowerCase());
|
|
6943
|
+
this.cursor = Math.max(F.indexOf(t.initialValue), 0), this.on("key", (E) => {
|
|
6944
|
+
if (!F.includes(E))
|
|
6945
|
+
return;
|
|
6946
|
+
const B = this.options.find(({ value: [A] }) => A?.toLowerCase() === E);
|
|
6947
|
+
B && (this.value = B.value, this.state = "submit", this.emit("submit"));
|
|
6948
|
+
});
|
|
6949
|
+
}
|
|
6950
|
+
}
|
|
6951
|
+
|
|
6952
|
+
class o extends k {
|
|
6953
|
+
get valueWithCursor() {
|
|
6954
|
+
if (this.state === "submit")
|
|
6955
|
+
return this.value;
|
|
6956
|
+
if (this.cursor >= this.value.length)
|
|
6957
|
+
return `${this.value}█`;
|
|
6958
|
+
const t = this.value.slice(0, this.cursor), [F, ...E] = this.value.slice(this.cursor);
|
|
6959
|
+
return `${t}${i__default.inverse(F)}${E.join("")}`;
|
|
6960
|
+
}
|
|
6961
|
+
get cursor() {
|
|
6962
|
+
return this._cursor;
|
|
6963
|
+
}
|
|
6964
|
+
constructor(t) {
|
|
6965
|
+
super(t), this.on("finalize", () => {
|
|
6966
|
+
this.value || (this.value = t.defaultValue);
|
|
6967
|
+
});
|
|
6968
|
+
}
|
|
6969
|
+
}
|
|
6970
|
+
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;
|
|
6971
|
+
});
|
|
6972
|
+
|
|
6973
|
+
// node_modules/@clack/prompts/dist/index.cjs
|
|
6974
|
+
var require_dist2 = __commonJS((exports) => {
|
|
6975
|
+
var node_util = __require("node:util");
|
|
6976
|
+
var core = require_dist();
|
|
6977
|
+
var process$1 = __require("node:process");
|
|
6978
|
+
var e = require_picocolors();
|
|
6979
|
+
var sisteransi = require_src();
|
|
6980
|
+
function _interopDefaultCompat(t) {
|
|
6981
|
+
return t && typeof t == "object" && "default" in t ? t.default : t;
|
|
6982
|
+
}
|
|
6983
|
+
var process__default = _interopDefaultCompat(process$1);
|
|
6984
|
+
var e__default = _interopDefaultCompat(e);
|
|
6985
|
+
function isUnicodeSupported() {
|
|
6986
|
+
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";
|
|
6987
|
+
}
|
|
6988
|
+
var P = isUnicodeSupported();
|
|
6989
|
+
var u = (t, o) => P ? t : o;
|
|
6990
|
+
var ie = u("◆", "*");
|
|
6991
|
+
var G = u("■", "x");
|
|
6992
|
+
var L = u("▲", "x");
|
|
6993
|
+
var S = u("◇", "o");
|
|
6994
|
+
var ae = u("┌", "T");
|
|
6995
|
+
var a = u("│", "|");
|
|
6996
|
+
var g = u("└", "—");
|
|
6997
|
+
var _ = u("●", ">");
|
|
6998
|
+
var A = u("○", " ");
|
|
6999
|
+
var C = u("◻", "[•]");
|
|
7000
|
+
var V = u("◼", "[+]");
|
|
7001
|
+
var N = u("◻", "[ ]");
|
|
7002
|
+
var oe = u("▪", "•");
|
|
7003
|
+
var j = u("─", "-");
|
|
7004
|
+
var le = u("╮", "+");
|
|
7005
|
+
var ce = u("├", "+");
|
|
7006
|
+
var ue = u("╯", "+");
|
|
7007
|
+
var B = u("●", "•");
|
|
7008
|
+
var W = u("◆", "*");
|
|
7009
|
+
var H = u("▲", "!");
|
|
7010
|
+
var q = u("■", "x");
|
|
7011
|
+
var b = (t) => {
|
|
7012
|
+
switch (t) {
|
|
7013
|
+
case "initial":
|
|
7014
|
+
case "active":
|
|
7015
|
+
return e__default.cyan(ie);
|
|
7016
|
+
case "cancel":
|
|
7017
|
+
return e__default.red(G);
|
|
7018
|
+
case "error":
|
|
7019
|
+
return e__default.yellow(L);
|
|
7020
|
+
case "submit":
|
|
7021
|
+
return e__default.green(S);
|
|
7022
|
+
}
|
|
7023
|
+
};
|
|
7024
|
+
var E = (t) => {
|
|
7025
|
+
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));
|
|
7026
|
+
let l = 0;
|
|
7027
|
+
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));
|
|
7028
|
+
const $ = n < s.length && l > 0, h = n < s.length && l + n < s.length;
|
|
7029
|
+
return s.slice(l, l + n).map((m, y, w) => {
|
|
7030
|
+
const x = y === 0 && $, M = y === w.length - 1 && h;
|
|
7031
|
+
return x || M ? e__default.dim("...") : i(m, y + l === o);
|
|
7032
|
+
});
|
|
7033
|
+
};
|
|
7034
|
+
var text = (t) => new core.TextPrompt({ validate: t.validate, placeholder: t.placeholder, defaultValue: t.defaultValue, initialValue: t.initialValue, render() {
|
|
7035
|
+
const o = `${e__default.gray(a)}
|
|
7036
|
+
${b(this.state)} ${t.message}
|
|
7037
|
+
`, 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;
|
|
7038
|
+
switch (this.state) {
|
|
7039
|
+
case "error":
|
|
7040
|
+
return `${o.trim()}
|
|
7041
|
+
${e__default.yellow(a)} ${i}
|
|
7042
|
+
${e__default.yellow(g)} ${e__default.yellow(this.error)}
|
|
7043
|
+
`;
|
|
7044
|
+
case "submit":
|
|
7045
|
+
return `${o}${e__default.gray(a)} ${e__default.dim(this.value || t.placeholder)}`;
|
|
7046
|
+
case "cancel":
|
|
7047
|
+
return `${o}${e__default.gray(a)} ${e__default.strikethrough(e__default.dim(this.value ?? ""))}${this.value?.trim() ? `
|
|
7048
|
+
${e__default.gray(a)}` : ""}`;
|
|
7049
|
+
default:
|
|
7050
|
+
return `${o}${e__default.cyan(a)} ${i}
|
|
7051
|
+
${e__default.cyan(g)}
|
|
7052
|
+
`;
|
|
7053
|
+
}
|
|
7054
|
+
} }).prompt();
|
|
7055
|
+
var password = (t) => new core.PasswordPrompt({ validate: t.validate, mask: t.mask ?? oe, render() {
|
|
7056
|
+
const o = `${e__default.gray(a)}
|
|
7057
|
+
${b(this.state)} ${t.message}
|
|
7058
|
+
`, s = this.valueWithCursor, i = this.masked;
|
|
7059
|
+
switch (this.state) {
|
|
7060
|
+
case "error":
|
|
7061
|
+
return `${o.trim()}
|
|
7062
|
+
${e__default.yellow(a)} ${i}
|
|
7063
|
+
${e__default.yellow(g)} ${e__default.yellow(this.error)}
|
|
7064
|
+
`;
|
|
7065
|
+
case "submit":
|
|
7066
|
+
return `${o}${e__default.gray(a)} ${e__default.dim(i)}`;
|
|
7067
|
+
case "cancel":
|
|
7068
|
+
return `${o}${e__default.gray(a)} ${e__default.strikethrough(e__default.dim(i ?? ""))}${i ? `
|
|
7069
|
+
${e__default.gray(a)}` : ""}`;
|
|
7070
|
+
default:
|
|
7071
|
+
return `${o}${e__default.cyan(a)} ${s}
|
|
7072
|
+
${e__default.cyan(g)}
|
|
7073
|
+
`;
|
|
7074
|
+
}
|
|
7075
|
+
} }).prompt();
|
|
7076
|
+
var confirm = (t) => {
|
|
7077
|
+
const o = t.active ?? "Yes", s = t.inactive ?? "No";
|
|
7078
|
+
return new core.ConfirmPrompt({ active: o, inactive: s, initialValue: t.initialValue ?? true, render() {
|
|
7079
|
+
const i = `${e__default.gray(a)}
|
|
7080
|
+
${b(this.state)} ${t.message}
|
|
7081
|
+
`, r = this.value ? o : s;
|
|
7082
|
+
switch (this.state) {
|
|
7083
|
+
case "submit":
|
|
7084
|
+
return `${i}${e__default.gray(a)} ${e__default.dim(r)}`;
|
|
7085
|
+
case "cancel":
|
|
7086
|
+
return `${i}${e__default.gray(a)} ${e__default.strikethrough(e__default.dim(r))}
|
|
7087
|
+
${e__default.gray(a)}`;
|
|
7088
|
+
default:
|
|
7089
|
+
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}`}
|
|
7090
|
+
${e__default.cyan(g)}
|
|
7091
|
+
`;
|
|
7092
|
+
}
|
|
7093
|
+
} }).prompt();
|
|
7094
|
+
};
|
|
7095
|
+
var select = (t) => {
|
|
7096
|
+
const o = (s, i) => {
|
|
7097
|
+
const r = s.label ?? String(s.value);
|
|
7098
|
+
switch (i) {
|
|
7099
|
+
case "selected":
|
|
7100
|
+
return `${e__default.dim(r)}`;
|
|
7101
|
+
case "active":
|
|
7102
|
+
return `${e__default.green(_)} ${r} ${s.hint ? e__default.dim(`(${s.hint})`) : ""}`;
|
|
7103
|
+
case "cancelled":
|
|
7104
|
+
return `${e__default.strikethrough(e__default.dim(r))}`;
|
|
7105
|
+
default:
|
|
7106
|
+
return `${e__default.dim(A)} ${e__default.dim(r)}`;
|
|
7107
|
+
}
|
|
7108
|
+
};
|
|
7109
|
+
return new core.SelectPrompt({ options: t.options, initialValue: t.initialValue, render() {
|
|
7110
|
+
const s = `${e__default.gray(a)}
|
|
7111
|
+
${b(this.state)} ${t.message}
|
|
7112
|
+
`;
|
|
7113
|
+
switch (this.state) {
|
|
7114
|
+
case "submit":
|
|
7115
|
+
return `${s}${e__default.gray(a)} ${o(this.options[this.cursor], "selected")}`;
|
|
7116
|
+
case "cancel":
|
|
7117
|
+
return `${s}${e__default.gray(a)} ${o(this.options[this.cursor], "cancelled")}
|
|
7118
|
+
${e__default.gray(a)}`;
|
|
7119
|
+
default:
|
|
7120
|
+
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(`
|
|
7121
|
+
${e__default.cyan(a)} `)}
|
|
7122
|
+
${e__default.cyan(g)}
|
|
7123
|
+
`;
|
|
7124
|
+
}
|
|
7125
|
+
} }).prompt();
|
|
7126
|
+
};
|
|
7127
|
+
var selectKey = (t) => {
|
|
7128
|
+
const o = (s, i = "inactive") => {
|
|
7129
|
+
const r = s.label ?? String(s.value);
|
|
7130
|
+
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})`) : ""}`;
|
|
7131
|
+
};
|
|
7132
|
+
return new core.SelectKeyPrompt({ options: t.options, initialValue: t.initialValue, render() {
|
|
7133
|
+
const s = `${e__default.gray(a)}
|
|
7134
|
+
${b(this.state)} ${t.message}
|
|
7135
|
+
`;
|
|
7136
|
+
switch (this.state) {
|
|
7137
|
+
case "submit":
|
|
7138
|
+
return `${s}${e__default.gray(a)} ${o(this.options.find((i) => i.value === this.value) ?? t.options[0], "selected")}`;
|
|
7139
|
+
case "cancel":
|
|
7140
|
+
return `${s}${e__default.gray(a)} ${o(this.options[0], "cancelled")}
|
|
7141
|
+
${e__default.gray(a)}`;
|
|
7142
|
+
default:
|
|
7143
|
+
return `${s}${e__default.cyan(a)} ${this.options.map((i, r) => o(i, r === this.cursor ? "active" : "inactive")).join(`
|
|
7144
|
+
${e__default.cyan(a)} `)}
|
|
7145
|
+
${e__default.cyan(g)}
|
|
7146
|
+
`;
|
|
7147
|
+
}
|
|
7148
|
+
} }).prompt();
|
|
7149
|
+
};
|
|
7150
|
+
var multiselect = (t) => {
|
|
7151
|
+
const o = (s, i) => {
|
|
7152
|
+
const r = s.label ?? String(s.value);
|
|
7153
|
+
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)}`;
|
|
7154
|
+
};
|
|
7155
|
+
return new core.MultiSelectPrompt({ options: t.options, initialValues: t.initialValues, required: t.required ?? true, cursorAt: t.cursorAt, validate(s) {
|
|
7156
|
+
if (this.required && s.length === 0)
|
|
7157
|
+
return `Please select at least one option.
|
|
7158
|
+
${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`))}`;
|
|
7159
|
+
}, render() {
|
|
7160
|
+
const s = `${e__default.gray(a)}
|
|
7161
|
+
${b(this.state)} ${t.message}
|
|
7162
|
+
`, i = (r, c) => {
|
|
7163
|
+
const n = this.value.includes(r.value);
|
|
7164
|
+
return c && n ? o(r, "active-selected") : n ? o(r, "selected") : o(r, c ? "active" : "inactive");
|
|
7165
|
+
};
|
|
7166
|
+
switch (this.state) {
|
|
7167
|
+
case "submit":
|
|
7168
|
+
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")}`;
|
|
7169
|
+
case "cancel": {
|
|
7170
|
+
const r = this.options.filter(({ value: c }) => this.value.includes(c)).map((c) => o(c, "cancelled")).join(e__default.dim(", "));
|
|
7171
|
+
return `${s}${e__default.gray(a)} ${r.trim() ? `${r}
|
|
7172
|
+
${e__default.gray(a)}` : ""}`;
|
|
7173
|
+
}
|
|
7174
|
+
case "error": {
|
|
7175
|
+
const r = this.error.split(`
|
|
7176
|
+
`).map((c, n) => n === 0 ? `${e__default.yellow(g)} ${e__default.yellow(c)}` : ` ${c}`).join(`
|
|
7177
|
+
`);
|
|
7178
|
+
return `${s + e__default.yellow(a)} ${E({ options: this.options, cursor: this.cursor, maxItems: t.maxItems, style: i }).join(`
|
|
7179
|
+
${e__default.yellow(a)} `)}
|
|
7180
|
+
${r}
|
|
7181
|
+
`;
|
|
7182
|
+
}
|
|
7183
|
+
default:
|
|
7184
|
+
return `${s}${e__default.cyan(a)} ${E({ options: this.options, cursor: this.cursor, maxItems: t.maxItems, style: i }).join(`
|
|
7185
|
+
${e__default.cyan(a)} `)}
|
|
7186
|
+
${e__default.cyan(g)}
|
|
7187
|
+
`;
|
|
7188
|
+
}
|
|
7189
|
+
} }).prompt();
|
|
7190
|
+
};
|
|
7191
|
+
var groupMultiselect = (t) => {
|
|
7192
|
+
const { selectableGroups: o = true } = t, s = (i, r, c = []) => {
|
|
7193
|
+
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} ` : " " : "";
|
|
7194
|
+
if (r === "active")
|
|
7195
|
+
return `${e__default.dim(m)}${e__default.cyan(C)} ${n} ${i.hint ? e__default.dim(`(${i.hint})`) : ""}`;
|
|
7196
|
+
if (r === "group-active")
|
|
7197
|
+
return `${m}${e__default.cyan(C)} ${e__default.dim(n)}`;
|
|
7198
|
+
if (r === "group-active-selected")
|
|
7199
|
+
return `${m}${e__default.green(V)} ${e__default.dim(n)}`;
|
|
7200
|
+
if (r === "selected") {
|
|
7201
|
+
const w = l || o ? e__default.green(V) : "";
|
|
7202
|
+
return `${e__default.dim(m)}${w} ${e__default.dim(n)} ${i.hint ? e__default.dim(`(${i.hint})`) : ""}`;
|
|
7203
|
+
}
|
|
7204
|
+
if (r === "cancelled")
|
|
7205
|
+
return `${e__default.strikethrough(e__default.dim(n))}`;
|
|
7206
|
+
if (r === "active-selected")
|
|
7207
|
+
return `${e__default.dim(m)}${e__default.green(V)} ${n} ${i.hint ? e__default.dim(`(${i.hint})`) : ""}`;
|
|
7208
|
+
if (r === "submitted")
|
|
7209
|
+
return `${e__default.dim(n)}`;
|
|
7210
|
+
const y = l || o ? e__default.dim(N) : "";
|
|
7211
|
+
return `${e__default.dim(m)}${y} ${e__default.dim(n)}`;
|
|
7212
|
+
};
|
|
7213
|
+
return new core.GroupMultiSelectPrompt({ options: t.options, initialValues: t.initialValues, required: t.required ?? true, cursorAt: t.cursorAt, selectableGroups: o, validate(i) {
|
|
7214
|
+
if (this.required && i.length === 0)
|
|
7215
|
+
return `Please select at least one option.
|
|
7216
|
+
${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`))}`;
|
|
7217
|
+
}, render() {
|
|
7218
|
+
const i = `${e__default.gray(a)}
|
|
7219
|
+
${b(this.state)} ${t.message}
|
|
7220
|
+
`;
|
|
7221
|
+
switch (this.state) {
|
|
7222
|
+
case "submit":
|
|
7223
|
+
return `${i}${e__default.gray(a)} ${this.options.filter(({ value: r }) => this.value.includes(r)).map((r) => s(r, "submitted")).join(e__default.dim(", "))}`;
|
|
7224
|
+
case "cancel": {
|
|
7225
|
+
const r = this.options.filter(({ value: c }) => this.value.includes(c)).map((c) => s(c, "cancelled")).join(e__default.dim(", "));
|
|
7226
|
+
return `${i}${e__default.gray(a)} ${r.trim() ? `${r}
|
|
7227
|
+
${e__default.gray(a)}` : ""}`;
|
|
7228
|
+
}
|
|
7229
|
+
case "error": {
|
|
7230
|
+
const r = this.error.split(`
|
|
7231
|
+
`).map((c, n) => n === 0 ? `${e__default.yellow(g)} ${e__default.yellow(c)}` : ` ${c}`).join(`
|
|
7232
|
+
`);
|
|
7233
|
+
return `${i}${e__default.yellow(a)} ${this.options.map((c, n, l) => {
|
|
7234
|
+
const $ = this.value.includes(c.value) || c.group === true && this.isGroupSelected(`${c.value}`), h = n === this.cursor;
|
|
7235
|
+
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);
|
|
7236
|
+
}).join(`
|
|
7237
|
+
${e__default.yellow(a)} `)}
|
|
7238
|
+
${r}
|
|
7239
|
+
`;
|
|
7240
|
+
}
|
|
7241
|
+
default:
|
|
7242
|
+
return `${i}${e__default.cyan(a)} ${this.options.map((r, c, n) => {
|
|
7243
|
+
const l = this.value.includes(r.value) || r.group === true && this.isGroupSelected(`${r.value}`), $ = c === this.cursor;
|
|
7244
|
+
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);
|
|
7245
|
+
}).join(`
|
|
7246
|
+
${e__default.cyan(a)} `)}
|
|
7247
|
+
${e__default.cyan(g)}
|
|
7248
|
+
`;
|
|
7249
|
+
}
|
|
7250
|
+
} }).prompt();
|
|
7251
|
+
};
|
|
7252
|
+
var note = (t = "", o = "") => {
|
|
7253
|
+
const s = `
|
|
7254
|
+
${t}
|
|
7255
|
+
`.split(`
|
|
7256
|
+
`), i = node_util.stripVTControlCharacters(o).length, r = Math.max(s.reduce((n, l) => {
|
|
7257
|
+
const $ = node_util.stripVTControlCharacters(l);
|
|
7258
|
+
return $.length > n ? $.length : n;
|
|
7259
|
+
}, 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(`
|
|
7260
|
+
`);
|
|
7261
|
+
process.stdout.write(`${e__default.gray(a)}
|
|
7262
|
+
${e__default.green(S)} ${e__default.reset(o)} ${e__default.gray(j.repeat(Math.max(r - i - 1, 1)) + le)}
|
|
7263
|
+
${c}
|
|
7264
|
+
${e__default.gray(ce + j.repeat(r + 2) + ue)}
|
|
7265
|
+
`);
|
|
7266
|
+
};
|
|
7267
|
+
var cancel = (t = "") => {
|
|
7268
|
+
process.stdout.write(`${e__default.gray(g)} ${e__default.red(t)}
|
|
7269
|
+
|
|
7270
|
+
`);
|
|
7271
|
+
};
|
|
7272
|
+
var intro = (t = "") => {
|
|
7273
|
+
process.stdout.write(`${e__default.gray(ae)} ${t}
|
|
7274
|
+
`);
|
|
7275
|
+
};
|
|
7276
|
+
var outro = (t = "") => {
|
|
7277
|
+
process.stdout.write(`${e__default.gray(a)}
|
|
7278
|
+
${e__default.gray(g)} ${t}
|
|
7279
|
+
|
|
7280
|
+
`);
|
|
7281
|
+
};
|
|
7282
|
+
var log = { message: (t = "", { symbol: o = e__default.gray(a) } = {}) => {
|
|
7283
|
+
const s = [`${e__default.gray(a)}`];
|
|
7284
|
+
if (t) {
|
|
7285
|
+
const [i, ...r] = t.split(`
|
|
7286
|
+
`);
|
|
7287
|
+
s.push(`${o} ${i}`, ...r.map((c) => `${e__default.gray(a)} ${c}`));
|
|
7288
|
+
}
|
|
7289
|
+
process.stdout.write(`${s.join(`
|
|
7290
|
+
`)}
|
|
7291
|
+
`);
|
|
7292
|
+
}, info: (t) => {
|
|
7293
|
+
log.message(t, { symbol: e__default.blue(B) });
|
|
7294
|
+
}, success: (t) => {
|
|
7295
|
+
log.message(t, { symbol: e__default.green(W) });
|
|
7296
|
+
}, step: (t) => {
|
|
7297
|
+
log.message(t, { symbol: e__default.green(S) });
|
|
7298
|
+
}, warn: (t) => {
|
|
7299
|
+
log.message(t, { symbol: e__default.yellow(H) });
|
|
7300
|
+
}, warning: (t) => {
|
|
7301
|
+
log.warn(t);
|
|
7302
|
+
}, error: (t) => {
|
|
7303
|
+
log.message(t, { symbol: e__default.red(q) });
|
|
7304
|
+
} };
|
|
7305
|
+
var D = `${e__default.gray(a)} `;
|
|
7306
|
+
var stream = { message: async (t, { symbol: o = e__default.gray(a) } = {}) => {
|
|
7307
|
+
process.stdout.write(`${e__default.gray(a)}
|
|
7308
|
+
${o} `);
|
|
7309
|
+
let s = 3;
|
|
7310
|
+
for await (let i of t) {
|
|
7311
|
+
i = i.replace(/\n/g, `
|
|
7312
|
+
${D}`), i.includes(`
|
|
7313
|
+
`) && (s = 3 + node_util.stripVTControlCharacters(i.slice(i.lastIndexOf(`
|
|
7314
|
+
`))).length);
|
|
7315
|
+
const r = node_util.stripVTControlCharacters(i).length;
|
|
7316
|
+
s + r < process.stdout.columns ? (s += r, process.stdout.write(i)) : (process.stdout.write(`
|
|
7317
|
+
${D}${i.trimStart()}`), s = 3 + node_util.stripVTControlCharacters(i.trimStart()).length);
|
|
7318
|
+
}
|
|
7319
|
+
process.stdout.write(`
|
|
7320
|
+
`);
|
|
7321
|
+
}, 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) }) };
|
|
7322
|
+
var spinner = ({ indicator: t = "dots" } = {}) => {
|
|
7323
|
+
const o = P ? ["◒", "◐", "◓", "◑"] : ["•", "o", "O", "0"], s = P ? 80 : 120, i = process.env.CI === "true";
|
|
7324
|
+
let r, c, n = false, l = "", $, h = performance.now();
|
|
7325
|
+
const m = (p) => {
|
|
7326
|
+
const d = p > 1 ? "Something went wrong" : "Canceled";
|
|
7327
|
+
n && R(d, p);
|
|
7328
|
+
}, y = () => m(2), w = () => m(1), x = () => {
|
|
7329
|
+
process.on("uncaughtExceptionMonitor", y), process.on("unhandledRejection", y), process.on("SIGINT", w), process.on("SIGTERM", w), process.on("exit", m);
|
|
7330
|
+
}, M = () => {
|
|
7331
|
+
process.removeListener("uncaughtExceptionMonitor", y), process.removeListener("unhandledRejection", y), process.removeListener("SIGINT", w), process.removeListener("SIGTERM", w), process.removeListener("exit", m);
|
|
7332
|
+
}, T = () => {
|
|
7333
|
+
if ($ === undefined)
|
|
7334
|
+
return;
|
|
7335
|
+
i && process.stdout.write(`
|
|
7336
|
+
`);
|
|
7337
|
+
const p = $.split(`
|
|
7338
|
+
`);
|
|
7339
|
+
process.stdout.write(sisteransi.cursor.move(-999, p.length - 1)), process.stdout.write(sisteransi.erase.down(p.length));
|
|
7340
|
+
}, I = (p) => p.replace(/\.+$/, ""), k = (p) => {
|
|
7341
|
+
const d = (performance.now() - p) / 1000, v = Math.floor(d / 60), f = Math.floor(d % 60);
|
|
7342
|
+
return v > 0 ? `[${v}m ${f}s]` : `[${f}s]`;
|
|
7343
|
+
}, O = (p = "") => {
|
|
7344
|
+
n = true, r = core.block(), l = I(p), h = performance.now(), process.stdout.write(`${e__default.gray(a)}
|
|
7345
|
+
`);
|
|
7346
|
+
let d = 0, v = 0;
|
|
7347
|
+
x(), c = setInterval(() => {
|
|
7348
|
+
if (i && l === $)
|
|
7349
|
+
return;
|
|
7350
|
+
T(), $ = l;
|
|
7351
|
+
const f = e__default.magenta(o[d]);
|
|
7352
|
+
if (i)
|
|
7353
|
+
process.stdout.write(`${f} ${l}...`);
|
|
7354
|
+
else if (t === "timer")
|
|
7355
|
+
process.stdout.write(`${f} ${l} ${k(h)}`);
|
|
7356
|
+
else {
|
|
7357
|
+
const F = ".".repeat(Math.floor(v)).slice(0, 3);
|
|
7358
|
+
process.stdout.write(`${f} ${l}${F}`);
|
|
7359
|
+
}
|
|
7360
|
+
d = d + 1 < o.length ? d + 1 : 0, v = v < o.length ? v + 0.125 : 0;
|
|
7361
|
+
}, s);
|
|
7362
|
+
}, R = (p = "", d = 0) => {
|
|
7363
|
+
n = false, clearInterval(c), T();
|
|
7364
|
+
const v = d === 0 ? e__default.green(S) : d === 1 ? e__default.red(G) : e__default.red(L);
|
|
7365
|
+
l = I(p ?? l), t === "timer" ? process.stdout.write(`${v} ${l} ${k(h)}
|
|
7366
|
+
`) : process.stdout.write(`${v} ${l}
|
|
7367
|
+
`), M(), r();
|
|
7368
|
+
};
|
|
7369
|
+
return { start: O, stop: R, message: (p = "") => {
|
|
7370
|
+
l = I(p ?? l);
|
|
7371
|
+
} };
|
|
7372
|
+
};
|
|
7373
|
+
var group = async (t, o) => {
|
|
7374
|
+
const s = {}, i = Object.keys(t);
|
|
7375
|
+
for (const r of i) {
|
|
7376
|
+
const c = t[r], n = await c({ results: s })?.catch((l) => {
|
|
7377
|
+
throw l;
|
|
7378
|
+
});
|
|
7379
|
+
if (typeof o?.onCancel == "function" && core.isCancel(n)) {
|
|
7380
|
+
s[r] = "canceled", o.onCancel({ results: s });
|
|
7381
|
+
continue;
|
|
7382
|
+
}
|
|
7383
|
+
s[r] = n;
|
|
7384
|
+
}
|
|
7385
|
+
return s;
|
|
7386
|
+
};
|
|
7387
|
+
var tasks = async (t) => {
|
|
7388
|
+
for (const o of t) {
|
|
7389
|
+
if (o.enabled === false)
|
|
7390
|
+
continue;
|
|
7391
|
+
const s = spinner();
|
|
7392
|
+
s.start(o.title);
|
|
7393
|
+
const i = await o.task(s.message);
|
|
7394
|
+
s.stop(i || o.title);
|
|
7395
|
+
}
|
|
7396
|
+
};
|
|
7397
|
+
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;
|
|
7398
|
+
});
|
|
7399
|
+
|
|
6198
7400
|
// node_modules/dotenv/package.json
|
|
6199
7401
|
var require_package = __commonJS((exports, module) => {
|
|
6200
7402
|
module.exports = {
|
|
@@ -6484,48 +7686,236 @@ var require_main = __commonJS((exports, module) => {
|
|
|
6484
7686
|
}
|
|
6485
7687
|
}
|
|
6486
7688
|
}
|
|
6487
|
-
function populate(processEnv, parsed, options = {}) {
|
|
6488
|
-
const debug = Boolean(options && options.debug);
|
|
6489
|
-
const override = Boolean(options && options.override);
|
|
6490
|
-
if (typeof parsed !== "object") {
|
|
6491
|
-
const err = new Error("OBJECT_REQUIRED: Please check the processEnv argument being passed to populate");
|
|
6492
|
-
err.code = "OBJECT_REQUIRED";
|
|
6493
|
-
throw err;
|
|
7689
|
+
function populate(processEnv, parsed, options = {}) {
|
|
7690
|
+
const debug = Boolean(options && options.debug);
|
|
7691
|
+
const override = Boolean(options && options.override);
|
|
7692
|
+
if (typeof parsed !== "object") {
|
|
7693
|
+
const err = new Error("OBJECT_REQUIRED: Please check the processEnv argument being passed to populate");
|
|
7694
|
+
err.code = "OBJECT_REQUIRED";
|
|
7695
|
+
throw err;
|
|
7696
|
+
}
|
|
7697
|
+
for (const key of Object.keys(parsed)) {
|
|
7698
|
+
if (Object.prototype.hasOwnProperty.call(processEnv, key)) {
|
|
7699
|
+
if (override === true) {
|
|
7700
|
+
processEnv[key] = parsed[key];
|
|
7701
|
+
}
|
|
7702
|
+
if (debug) {
|
|
7703
|
+
if (override === true) {
|
|
7704
|
+
_debug(`"${key}" is already defined and WAS overwritten`);
|
|
7705
|
+
} else {
|
|
7706
|
+
_debug(`"${key}" is already defined and was NOT overwritten`);
|
|
7707
|
+
}
|
|
7708
|
+
}
|
|
7709
|
+
} else {
|
|
7710
|
+
processEnv[key] = parsed[key];
|
|
7711
|
+
}
|
|
7712
|
+
}
|
|
7713
|
+
}
|
|
7714
|
+
var DotenvModule = {
|
|
7715
|
+
configDotenv,
|
|
7716
|
+
_configVault,
|
|
7717
|
+
_parseVault,
|
|
7718
|
+
config,
|
|
7719
|
+
decrypt,
|
|
7720
|
+
parse,
|
|
7721
|
+
populate
|
|
7722
|
+
};
|
|
7723
|
+
exports.configDotenv = DotenvModule.configDotenv;
|
|
7724
|
+
exports._configVault = DotenvModule._configVault;
|
|
7725
|
+
exports._parseVault = DotenvModule._parseVault;
|
|
7726
|
+
exports.config = DotenvModule.config;
|
|
7727
|
+
exports.decrypt = DotenvModule.decrypt;
|
|
7728
|
+
exports.parse = DotenvModule.parse;
|
|
7729
|
+
exports.populate = DotenvModule.populate;
|
|
7730
|
+
module.exports = DotenvModule;
|
|
7731
|
+
});
|
|
7732
|
+
|
|
7733
|
+
// src/utils/env-loader.ts
|
|
7734
|
+
var exports_env_loader = {};
|
|
7735
|
+
__export(exports_env_loader, {
|
|
7736
|
+
validateRequiredEnvironmentVariables: () => validateRequiredEnvironmentVariables,
|
|
7737
|
+
resolveToolEnvironmentVariables: () => resolveToolEnvironmentVariables,
|
|
7738
|
+
loadPackageEnvironmentVariables: () => loadPackageEnvironmentVariables,
|
|
7739
|
+
getWebServerUrl: () => getWebServerUrl,
|
|
7740
|
+
getPackageEnvironmentVariables: () => getPackageEnvironmentVariables,
|
|
7741
|
+
generateConfigLink: () => generateConfigLink,
|
|
7742
|
+
extractPackageNamespace: () => extractPackageNamespace
|
|
7743
|
+
});
|
|
7744
|
+
import { join } from "path";
|
|
7745
|
+
import { homedir } from "os";
|
|
7746
|
+
import { existsSync } from "fs";
|
|
7747
|
+
import { readFile } from "fs/promises";
|
|
7748
|
+
function extractPackageNamespace(toolName) {
|
|
7749
|
+
const parts = toolName.split("/");
|
|
7750
|
+
if (parts.length < 2) {
|
|
7751
|
+
throw new Error('Tool name must be in format "org/package" or "org/package/tool"');
|
|
7752
|
+
}
|
|
7753
|
+
if (parts.length >= 2) {
|
|
7754
|
+
return parts.slice(0, -1).join("/");
|
|
7755
|
+
}
|
|
7756
|
+
return parts[0];
|
|
7757
|
+
}
|
|
7758
|
+
function getPackageEnvPath(packageNamespace) {
|
|
7759
|
+
return join(CONFIG_DIR, "env", packageNamespace, ".env");
|
|
7760
|
+
}
|
|
7761
|
+
function decryptValue(encryptedValue) {
|
|
7762
|
+
try {
|
|
7763
|
+
return Buffer.from(encryptedValue, "base64").toString("utf8");
|
|
7764
|
+
} catch {
|
|
7765
|
+
return encryptedValue;
|
|
7766
|
+
}
|
|
7767
|
+
}
|
|
7768
|
+
async function readPackageEnvConfig(packageNamespace) {
|
|
7769
|
+
const envFile = getPackageEnvPath(packageNamespace);
|
|
7770
|
+
if (!existsSync(envFile)) {
|
|
7771
|
+
return { variables: {} };
|
|
7772
|
+
}
|
|
7773
|
+
try {
|
|
7774
|
+
const data = await readFile(envFile, "utf8");
|
|
7775
|
+
if (data.trim().startsWith("{")) {
|
|
7776
|
+
return JSON.parse(data);
|
|
7777
|
+
} else {
|
|
7778
|
+
return { variables: {} };
|
|
7779
|
+
}
|
|
7780
|
+
} catch (error) {
|
|
7781
|
+
if (!error.message.includes("Unexpected token")) {
|
|
7782
|
+
console.warn(`Failed to read env config from ${envFile}: ${error.message}`);
|
|
7783
|
+
}
|
|
7784
|
+
return { variables: {} };
|
|
7785
|
+
}
|
|
7786
|
+
}
|
|
7787
|
+
async function loadPackageEnvironmentVariables(packageNamespace) {
|
|
7788
|
+
const config = await readPackageEnvConfig(packageNamespace);
|
|
7789
|
+
const envVars = {};
|
|
7790
|
+
for (const [name, envVar] of Object.entries(config.variables)) {
|
|
7791
|
+
const value = envVar.encrypted ? decryptValue(envVar.value) : envVar.value;
|
|
7792
|
+
envVars[name] = value;
|
|
7793
|
+
}
|
|
7794
|
+
return envVars;
|
|
7795
|
+
}
|
|
7796
|
+
function loadPackageEnvFile(toolName) {
|
|
7797
|
+
if (!toolName) {
|
|
7798
|
+
return {};
|
|
7799
|
+
}
|
|
7800
|
+
try {
|
|
7801
|
+
const packageNamespace = extractPackageNamespace(toolName);
|
|
7802
|
+
const packageEnvPath = getPackageEnvPath(packageNamespace);
|
|
7803
|
+
if (!existsSync(packageEnvPath)) {
|
|
7804
|
+
return {};
|
|
7805
|
+
}
|
|
7806
|
+
const result = import_dotenv.config({ path: packageEnvPath });
|
|
7807
|
+
return result.parsed || {};
|
|
7808
|
+
} catch (error) {
|
|
7809
|
+
console.warn(`Warning: Failed to load package .env file: ${error.message}`);
|
|
7810
|
+
return {};
|
|
7811
|
+
}
|
|
7812
|
+
}
|
|
7813
|
+
async function resolveToolEnvironmentVariables(toolName, toolEnvConfig) {
|
|
7814
|
+
const resolved = { ...process.env };
|
|
7815
|
+
const packageEnvVars = loadPackageEnvFile(toolName);
|
|
7816
|
+
Object.assign(resolved, packageEnvVars);
|
|
7817
|
+
if (toolName) {
|
|
7818
|
+
try {
|
|
7819
|
+
const packageNamespace = extractPackageNamespace(toolName);
|
|
7820
|
+
const packageJsonEnvVars = await loadPackageEnvironmentVariables(packageNamespace);
|
|
7821
|
+
Object.assign(resolved, packageJsonEnvVars);
|
|
7822
|
+
} catch (error) {
|
|
7823
|
+
console.warn(`Warning: Could not load package environment variables: ${error.message}`);
|
|
7824
|
+
}
|
|
7825
|
+
}
|
|
7826
|
+
const missing = [];
|
|
7827
|
+
if (toolEnvConfig) {
|
|
7828
|
+
for (const [varName, config] of Object.entries(toolEnvConfig)) {
|
|
7829
|
+
if (typeof config === "object" && config !== null) {
|
|
7830
|
+
const isRequired = config.required === true;
|
|
7831
|
+
const defaultValue = config.default;
|
|
7832
|
+
const source = config.source;
|
|
7833
|
+
if (!(varName in resolved) || resolved[varName] === "") {
|
|
7834
|
+
if (defaultValue !== undefined) {
|
|
7835
|
+
resolved[varName] = String(defaultValue);
|
|
7836
|
+
} else if (isRequired) {
|
|
7837
|
+
missing.push(varName);
|
|
7838
|
+
}
|
|
7839
|
+
}
|
|
7840
|
+
if (source && resolved[varName]) {}
|
|
7841
|
+
}
|
|
7842
|
+
}
|
|
7843
|
+
}
|
|
7844
|
+
let configLink;
|
|
7845
|
+
if (missing.length > 0) {
|
|
7846
|
+
configLink = generateConfigLink(missing, toolName) || undefined;
|
|
7847
|
+
if (configLink) {
|
|
7848
|
+
console.log(`
|
|
7849
|
+
\uD83D\uDD27 Missing environment variables: ${missing.join(", ")}`);
|
|
7850
|
+
console.log(`\uD83D\uDCCB Configure them here: ${configLink}
|
|
7851
|
+
`);
|
|
7852
|
+
} else {
|
|
7853
|
+
console.log(`
|
|
7854
|
+
⚠️ Missing required environment variables: ${missing.join(", ")}`);
|
|
7855
|
+
console.log(`\uD83D\uDCA1 Set them using the 'enact env set' command or your system environment
|
|
7856
|
+
`);
|
|
6494
7857
|
}
|
|
6495
|
-
|
|
6496
|
-
|
|
6497
|
-
|
|
6498
|
-
|
|
6499
|
-
|
|
6500
|
-
|
|
6501
|
-
|
|
6502
|
-
|
|
6503
|
-
|
|
6504
|
-
|
|
6505
|
-
|
|
6506
|
-
|
|
6507
|
-
|
|
6508
|
-
|
|
7858
|
+
}
|
|
7859
|
+
return { resolved, missing, configLink };
|
|
7860
|
+
}
|
|
7861
|
+
async function getPackageEnvironmentVariables(packageNamespace) {
|
|
7862
|
+
const packageConfig = await readPackageEnvConfig(packageNamespace);
|
|
7863
|
+
const packageVars = {};
|
|
7864
|
+
for (const [name, envVar] of Object.entries(packageConfig.variables)) {
|
|
7865
|
+
packageVars[name] = {
|
|
7866
|
+
value: envVar.encrypted ? "[encrypted]" : envVar.value,
|
|
7867
|
+
encrypted: envVar.encrypted || false,
|
|
7868
|
+
description: envVar.description
|
|
7869
|
+
};
|
|
7870
|
+
}
|
|
7871
|
+
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 || ""]));
|
|
7872
|
+
return { package: packageVars, system };
|
|
7873
|
+
}
|
|
7874
|
+
function validateRequiredEnvironmentVariables(toolEnvConfig, availableVars) {
|
|
7875
|
+
const missing = [];
|
|
7876
|
+
const errors2 = [];
|
|
7877
|
+
if (!toolEnvConfig) {
|
|
7878
|
+
return { valid: true, missing, errors: errors2 };
|
|
7879
|
+
}
|
|
7880
|
+
for (const [varName, config] of Object.entries(toolEnvConfig)) {
|
|
7881
|
+
if (typeof config === "object" && config !== null) {
|
|
7882
|
+
const isRequired = config.required === true;
|
|
7883
|
+
const hasDefault = config.default !== undefined;
|
|
7884
|
+
const description = config.description || "";
|
|
7885
|
+
const source = config.source || "";
|
|
7886
|
+
if (isRequired && !hasDefault && (!(varName in availableVars) || availableVars[varName] === "")) {
|
|
7887
|
+
missing.push(varName);
|
|
7888
|
+
const errorMsg = `Required environment variable '${varName}' is not set`;
|
|
7889
|
+
const detailMsg = description ? ` - ${description}` : "";
|
|
7890
|
+
const sourceMsg = source ? ` (source: ${source})` : "";
|
|
7891
|
+
errors2.push(`${errorMsg}${detailMsg}${sourceMsg}`);
|
|
6509
7892
|
}
|
|
6510
7893
|
}
|
|
6511
7894
|
}
|
|
6512
|
-
|
|
6513
|
-
|
|
6514
|
-
|
|
6515
|
-
|
|
6516
|
-
config,
|
|
6517
|
-
decrypt,
|
|
6518
|
-
parse,
|
|
6519
|
-
populate
|
|
7895
|
+
return {
|
|
7896
|
+
valid: missing.length === 0,
|
|
7897
|
+
missing,
|
|
7898
|
+
errors: errors2
|
|
6520
7899
|
};
|
|
6521
|
-
|
|
6522
|
-
|
|
6523
|
-
|
|
6524
|
-
|
|
6525
|
-
|
|
6526
|
-
|
|
6527
|
-
|
|
6528
|
-
|
|
7900
|
+
}
|
|
7901
|
+
function getWebServerUrl() {
|
|
7902
|
+
return "http://localhost:5555";
|
|
7903
|
+
}
|
|
7904
|
+
function generateConfigLink(missingVars, toolName) {
|
|
7905
|
+
const webUrl = getWebServerUrl();
|
|
7906
|
+
if (!webUrl) {
|
|
7907
|
+
return null;
|
|
7908
|
+
}
|
|
7909
|
+
const packageNamespace = extractPackageNamespace(toolName);
|
|
7910
|
+
const encodedVars = encodeURIComponent(JSON.stringify(missingVars));
|
|
7911
|
+
const encodedPackage = encodeURIComponent(packageNamespace);
|
|
7912
|
+
return `${webUrl}/?vars=${encodedVars}&package=${encodedPackage}`;
|
|
7913
|
+
}
|
|
7914
|
+
var import_dotenv, CONFIG_DIR;
|
|
7915
|
+
var init_env_loader = __esm(() => {
|
|
7916
|
+
import_dotenv = __toESM(require_main(), 1);
|
|
7917
|
+
CONFIG_DIR = join(homedir(), ".enact");
|
|
7918
|
+
import_dotenv.config();
|
|
6529
7919
|
});
|
|
6530
7920
|
|
|
6531
7921
|
// node_modules/yaml/dist/nodes/identity.js
|
|
@@ -13431,7 +14821,7 @@ var require_public_api = __commonJS((exports) => {
|
|
|
13431
14821
|
});
|
|
13432
14822
|
|
|
13433
14823
|
// node_modules/yaml/dist/index.js
|
|
13434
|
-
var
|
|
14824
|
+
var require_dist3 = __commonJS((exports) => {
|
|
13435
14825
|
var composer = require_composer();
|
|
13436
14826
|
var Document = require_Document();
|
|
13437
14827
|
var Schema = require_Schema();
|
|
@@ -13479,6 +14869,300 @@ var require_dist = __commonJS((exports) => {
|
|
|
13479
14869
|
exports.visitAsync = visit.visitAsync;
|
|
13480
14870
|
});
|
|
13481
14871
|
|
|
14872
|
+
// src/web/env-manager-server.ts
|
|
14873
|
+
var exports_env_manager_server = {};
|
|
14874
|
+
__export(exports_env_manager_server, {
|
|
14875
|
+
startEnvManagerServer: () => startEnvManagerServer,
|
|
14876
|
+
setPackageEnvVar: () => setPackageEnvVar,
|
|
14877
|
+
getPackageEnvVars: () => getPackageEnvVars,
|
|
14878
|
+
getAllPackageNamespaces: () => getAllPackageNamespaces,
|
|
14879
|
+
deletePackageEnvVar: () => deletePackageEnvVar
|
|
14880
|
+
});
|
|
14881
|
+
import { createServer } from "http";
|
|
14882
|
+
import { parse as parse2 } from "url";
|
|
14883
|
+
import { readFile as readFile2, writeFile, mkdir, readdir, stat } from "fs/promises";
|
|
14884
|
+
import { existsSync as existsSync3 } from "fs";
|
|
14885
|
+
import { join as join3, dirname } from "path";
|
|
14886
|
+
import { homedir as homedir2 } from "os";
|
|
14887
|
+
import { fileURLToPath } from "url";
|
|
14888
|
+
function findStaticDir() {
|
|
14889
|
+
const candidates = [
|
|
14890
|
+
join3(__dirname2, "web", "static"),
|
|
14891
|
+
join3(__dirname2, "static"),
|
|
14892
|
+
join3(__dirname2, "..", "src", "web", "static"),
|
|
14893
|
+
join3(__dirname2, "..", "..", "src", "web", "static"),
|
|
14894
|
+
join3(process.cwd(), "src", "web", "static"),
|
|
14895
|
+
join3(__dirname2, "..", "..", "..", "src", "web", "static"),
|
|
14896
|
+
join3(__dirname2, "..", "..", "src", "web", "static")
|
|
14897
|
+
];
|
|
14898
|
+
for (const candidate of candidates) {
|
|
14899
|
+
if (existsSync3(join3(candidate, "index.html"))) {
|
|
14900
|
+
logger_default.debug(`Found static directory: ${candidate}`);
|
|
14901
|
+
return candidate;
|
|
14902
|
+
}
|
|
14903
|
+
}
|
|
14904
|
+
throw new Error("Could not find static directory. Tried: " + candidates.join(", "));
|
|
14905
|
+
}
|
|
14906
|
+
function parseDotEnv(content) {
|
|
14907
|
+
const vars = {};
|
|
14908
|
+
const lines = content.split(`
|
|
14909
|
+
`);
|
|
14910
|
+
for (const line of lines) {
|
|
14911
|
+
const trimmed = line.trim();
|
|
14912
|
+
if (!trimmed || trimmed.startsWith("#")) {
|
|
14913
|
+
continue;
|
|
14914
|
+
}
|
|
14915
|
+
const equalIndex = trimmed.indexOf("=");
|
|
14916
|
+
if (equalIndex === -1) {
|
|
14917
|
+
continue;
|
|
14918
|
+
}
|
|
14919
|
+
const key = trimmed.slice(0, equalIndex).trim();
|
|
14920
|
+
let value = trimmed.slice(equalIndex + 1).trim();
|
|
14921
|
+
if (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'")) {
|
|
14922
|
+
value = value.slice(1, -1);
|
|
14923
|
+
}
|
|
14924
|
+
if (key) {
|
|
14925
|
+
vars[key] = value;
|
|
14926
|
+
}
|
|
14927
|
+
}
|
|
14928
|
+
return vars;
|
|
14929
|
+
}
|
|
14930
|
+
function generateDotEnv(vars) {
|
|
14931
|
+
return Object.entries(vars).map(([key, value]) => {
|
|
14932
|
+
const needsQuotes = value.includes(" ") || value.includes("\t") || value.includes(`
|
|
14933
|
+
`) || value.includes('"');
|
|
14934
|
+
const escapedValue = needsQuotes ? `"${value.replace(/"/g, "\\\"")}"` : value;
|
|
14935
|
+
return `${key}=${escapedValue}`;
|
|
14936
|
+
}).join(`
|
|
14937
|
+
`) + `
|
|
14938
|
+
`;
|
|
14939
|
+
}
|
|
14940
|
+
async function getAllPackageNamespaces() {
|
|
14941
|
+
const packages = [];
|
|
14942
|
+
if (!existsSync3(ENV_BASE_DIR)) {
|
|
14943
|
+
return packages;
|
|
14944
|
+
}
|
|
14945
|
+
try {
|
|
14946
|
+
await scanDirectory(ENV_BASE_DIR, "", packages);
|
|
14947
|
+
} catch (error) {
|
|
14948
|
+
logger_default.error("Failed to scan env directory:", error);
|
|
14949
|
+
}
|
|
14950
|
+
return packages;
|
|
14951
|
+
}
|
|
14952
|
+
async function scanDirectory(dir, relativePath, packages) {
|
|
14953
|
+
try {
|
|
14954
|
+
const entries = await readdir(dir);
|
|
14955
|
+
for (const entry of entries) {
|
|
14956
|
+
const fullPath = join3(dir, entry);
|
|
14957
|
+
const stats = await stat(fullPath);
|
|
14958
|
+
if (stats.isDirectory()) {
|
|
14959
|
+
const newRelativePath = relativePath ? `${relativePath}/${entry}` : entry;
|
|
14960
|
+
await scanDirectory(fullPath, newRelativePath, packages);
|
|
14961
|
+
} else if (entry === ".env") {
|
|
14962
|
+
const namespace = relativePath || "root";
|
|
14963
|
+
try {
|
|
14964
|
+
const content = await readFile2(fullPath, "utf8");
|
|
14965
|
+
const variables = parseDotEnv(content);
|
|
14966
|
+
packages.push({
|
|
14967
|
+
namespace,
|
|
14968
|
+
path: fullPath,
|
|
14969
|
+
variables
|
|
14970
|
+
});
|
|
14971
|
+
} catch (error) {
|
|
14972
|
+
logger_default.error(`Failed to read .env file at ${fullPath}:`, error);
|
|
14973
|
+
}
|
|
14974
|
+
}
|
|
14975
|
+
}
|
|
14976
|
+
} catch (error) {
|
|
14977
|
+
logger_default.error(`Failed to scan directory ${dir}:`, error);
|
|
14978
|
+
}
|
|
14979
|
+
}
|
|
14980
|
+
async function getPackageEnvVars(namespace) {
|
|
14981
|
+
const envFile = join3(ENV_BASE_DIR, namespace, ".env");
|
|
14982
|
+
if (!existsSync3(envFile)) {
|
|
14983
|
+
return {};
|
|
14984
|
+
}
|
|
14985
|
+
try {
|
|
14986
|
+
const content = await readFile2(envFile, "utf8");
|
|
14987
|
+
return parseDotEnv(content);
|
|
14988
|
+
} catch (error) {
|
|
14989
|
+
logger_default.error(`Failed to read env file for ${namespace}:`, error);
|
|
14990
|
+
return {};
|
|
14991
|
+
}
|
|
14992
|
+
}
|
|
14993
|
+
async function setPackageEnvVar(namespace, key, value) {
|
|
14994
|
+
const envFile = join3(ENV_BASE_DIR, namespace, ".env");
|
|
14995
|
+
const envDir = dirname(envFile);
|
|
14996
|
+
if (!existsSync3(envDir)) {
|
|
14997
|
+
await mkdir(envDir, { recursive: true });
|
|
14998
|
+
}
|
|
14999
|
+
const existingVars = await getPackageEnvVars(namespace);
|
|
15000
|
+
existingVars[key] = value;
|
|
15001
|
+
const envContent = generateDotEnv(existingVars);
|
|
15002
|
+
await writeFile(envFile, envContent, "utf8");
|
|
15003
|
+
}
|
|
15004
|
+
async function deletePackageEnvVar(namespace, key) {
|
|
15005
|
+
const existingVars = await getPackageEnvVars(namespace);
|
|
15006
|
+
if (!(key in existingVars)) {
|
|
15007
|
+
throw new Error(`Environment variable '${key}' not found in package '${namespace}'`);
|
|
15008
|
+
}
|
|
15009
|
+
delete existingVars[key];
|
|
15010
|
+
const envFile = join3(ENV_BASE_DIR, namespace, ".env");
|
|
15011
|
+
const envContent = generateDotEnv(existingVars);
|
|
15012
|
+
await writeFile(envFile, envContent, "utf8");
|
|
15013
|
+
}
|
|
15014
|
+
async function serveStaticFile(filePath, res) {
|
|
15015
|
+
try {
|
|
15016
|
+
const content = await readFile2(filePath, "utf8");
|
|
15017
|
+
const ext = filePath.split(".").pop()?.toLowerCase();
|
|
15018
|
+
let contentType = "text/plain";
|
|
15019
|
+
switch (ext) {
|
|
15020
|
+
case "html":
|
|
15021
|
+
contentType = "text/html";
|
|
15022
|
+
break;
|
|
15023
|
+
case "css":
|
|
15024
|
+
contentType = "text/css";
|
|
15025
|
+
break;
|
|
15026
|
+
case "js":
|
|
15027
|
+
contentType = "application/javascript";
|
|
15028
|
+
break;
|
|
15029
|
+
case "json":
|
|
15030
|
+
contentType = "application/json";
|
|
15031
|
+
break;
|
|
15032
|
+
}
|
|
15033
|
+
res.writeHead(200, { "Content-Type": contentType });
|
|
15034
|
+
res.end(content);
|
|
15035
|
+
} catch (error) {
|
|
15036
|
+
logger_default.error("Error serving static file:", error);
|
|
15037
|
+
res.writeHead(404, { "Content-Type": "text/plain" });
|
|
15038
|
+
res.end("File not found");
|
|
15039
|
+
}
|
|
15040
|
+
}
|
|
15041
|
+
async function handleRequest(req, res) {
|
|
15042
|
+
const urlParts = parse2(req.url || "", true);
|
|
15043
|
+
const pathname = urlParts.pathname || "/";
|
|
15044
|
+
const method = req.method || "GET";
|
|
15045
|
+
res.setHeader("Access-Control-Allow-Origin", "*");
|
|
15046
|
+
res.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
|
|
15047
|
+
res.setHeader("Access-Control-Allow-Headers", "Content-Type");
|
|
15048
|
+
if (method === "OPTIONS") {
|
|
15049
|
+
res.writeHead(200);
|
|
15050
|
+
res.end();
|
|
15051
|
+
return;
|
|
15052
|
+
}
|
|
15053
|
+
try {
|
|
15054
|
+
if (pathname === "/") {
|
|
15055
|
+
await serveStaticFile(join3(STATIC_DIR, "index.html"), res);
|
|
15056
|
+
} else if (pathname === "/style.css") {
|
|
15057
|
+
await serveStaticFile(join3(STATIC_DIR, "style.css"), res);
|
|
15058
|
+
} else if (pathname === "/app.js") {
|
|
15059
|
+
await serveStaticFile(join3(STATIC_DIR, "app.js"), res);
|
|
15060
|
+
} else if (pathname === "/favicon.ico") {
|
|
15061
|
+
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>`;
|
|
15062
|
+
res.writeHead(200, { "Content-Type": "image/svg+xml" });
|
|
15063
|
+
res.end(favicon);
|
|
15064
|
+
} else if (pathname === "/api/packages" && method === "GET") {
|
|
15065
|
+
const packages = await getAllPackageNamespaces();
|
|
15066
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
15067
|
+
res.end(JSON.stringify({ packages }));
|
|
15068
|
+
} else if (pathname === "/api/packages" && method === "POST") {
|
|
15069
|
+
const body = await getRequestBody(req);
|
|
15070
|
+
const { namespace } = JSON.parse(body);
|
|
15071
|
+
if (!namespace) {
|
|
15072
|
+
res.writeHead(400, { "Content-Type": "application/json" });
|
|
15073
|
+
res.end(JSON.stringify({ error: "Namespace is required" }));
|
|
15074
|
+
return;
|
|
15075
|
+
}
|
|
15076
|
+
const envDir = join3(ENV_BASE_DIR, namespace);
|
|
15077
|
+
const envFile = join3(envDir, ".env");
|
|
15078
|
+
if (!existsSync3(envDir)) {
|
|
15079
|
+
await mkdir(envDir, { recursive: true });
|
|
15080
|
+
}
|
|
15081
|
+
if (!existsSync3(envFile)) {
|
|
15082
|
+
await writeFile(envFile, "", "utf8");
|
|
15083
|
+
}
|
|
15084
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
15085
|
+
res.end(JSON.stringify({ success: true }));
|
|
15086
|
+
} else if (pathname?.startsWith("/api/packages/") && method === "GET") {
|
|
15087
|
+
const namespace = decodeURIComponent(pathname.replace("/api/packages/", ""));
|
|
15088
|
+
const variables = await getPackageEnvVars(namespace);
|
|
15089
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
15090
|
+
res.end(JSON.stringify({ namespace, variables }));
|
|
15091
|
+
} else if (pathname?.startsWith("/api/packages/") && pathname.endsWith("/variables") && method === "POST") {
|
|
15092
|
+
const namespace = decodeURIComponent(pathname.replace("/api/packages/", "").replace("/variables", ""));
|
|
15093
|
+
const body = await getRequestBody(req);
|
|
15094
|
+
const { key, value } = JSON.parse(body);
|
|
15095
|
+
if (!key || value === undefined) {
|
|
15096
|
+
res.writeHead(400, { "Content-Type": "application/json" });
|
|
15097
|
+
res.end(JSON.stringify({ error: "Key and value are required" }));
|
|
15098
|
+
return;
|
|
15099
|
+
}
|
|
15100
|
+
await setPackageEnvVar(namespace, key, value);
|
|
15101
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
15102
|
+
res.end(JSON.stringify({ success: true }));
|
|
15103
|
+
} else if (pathname?.includes("/variables/") && method === "DELETE") {
|
|
15104
|
+
const pathParts = pathname.split("/");
|
|
15105
|
+
const variableIndex = pathParts.indexOf("variables");
|
|
15106
|
+
const namespace = decodeURIComponent(pathParts.slice(3, variableIndex).join("/"));
|
|
15107
|
+
const key = decodeURIComponent(pathParts[variableIndex + 1]);
|
|
15108
|
+
await deletePackageEnvVar(namespace, key);
|
|
15109
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
15110
|
+
res.end(JSON.stringify({ success: true }));
|
|
15111
|
+
} else {
|
|
15112
|
+
res.writeHead(404, { "Content-Type": "application/json" });
|
|
15113
|
+
res.end(JSON.stringify({ error: "Not found" }));
|
|
15114
|
+
}
|
|
15115
|
+
} catch (error) {
|
|
15116
|
+
logger_default.error("Web server error:", error);
|
|
15117
|
+
res.writeHead(500, { "Content-Type": "application/json" });
|
|
15118
|
+
res.end(JSON.stringify({
|
|
15119
|
+
error: error instanceof Error ? error.message : "Internal server error"
|
|
15120
|
+
}));
|
|
15121
|
+
}
|
|
15122
|
+
}
|
|
15123
|
+
function getRequestBody(req) {
|
|
15124
|
+
return new Promise((resolve, reject) => {
|
|
15125
|
+
let body = "";
|
|
15126
|
+
req.on("data", (chunk) => {
|
|
15127
|
+
body += chunk.toString();
|
|
15128
|
+
});
|
|
15129
|
+
req.on("end", () => {
|
|
15130
|
+
resolve(body);
|
|
15131
|
+
});
|
|
15132
|
+
req.on("error", reject);
|
|
15133
|
+
});
|
|
15134
|
+
}
|
|
15135
|
+
function startEnvManagerServer(port = 5555) {
|
|
15136
|
+
return new Promise((resolve, reject) => {
|
|
15137
|
+
const server = createServer(handleRequest);
|
|
15138
|
+
server.listen(port, () => {
|
|
15139
|
+
const actualPort = server.address()?.port || port;
|
|
15140
|
+
logger_default.info(`\uD83C\uDF10 Environment Manager web server started on http://localhost:${actualPort}`);
|
|
15141
|
+
resolve({ server, port: actualPort });
|
|
15142
|
+
});
|
|
15143
|
+
server.on("error", (error) => {
|
|
15144
|
+
if (error.code === "EADDRINUSE") {
|
|
15145
|
+
server.listen(0, () => {
|
|
15146
|
+
const actualPort = server.address()?.port;
|
|
15147
|
+
logger_default.info(`\uD83C\uDF10 Environment Manager web server started on http://localhost:${actualPort} (port ${port} was in use)`);
|
|
15148
|
+
resolve({ server, port: actualPort });
|
|
15149
|
+
});
|
|
15150
|
+
} else {
|
|
15151
|
+
reject(error);
|
|
15152
|
+
}
|
|
15153
|
+
});
|
|
15154
|
+
});
|
|
15155
|
+
}
|
|
15156
|
+
var __filename2, __dirname2, CONFIG_DIR2, ENV_BASE_DIR, STATIC_DIR;
|
|
15157
|
+
var init_env_manager_server = __esm(() => {
|
|
15158
|
+
init_logger();
|
|
15159
|
+
__filename2 = fileURLToPath(import.meta.url);
|
|
15160
|
+
__dirname2 = dirname(__filename2);
|
|
15161
|
+
CONFIG_DIR2 = join3(homedir2(), ".enact");
|
|
15162
|
+
ENV_BASE_DIR = join3(CONFIG_DIR2, "env");
|
|
15163
|
+
STATIC_DIR = findStaticDir();
|
|
15164
|
+
});
|
|
15165
|
+
|
|
13482
15166
|
// node_modules/zod/dist/esm/v3/external.js
|
|
13483
15167
|
var exports_external = {};
|
|
13484
15168
|
__export(exports_external, {
|
|
@@ -20458,21 +22142,41 @@ class EnactApiClient {
|
|
|
20458
22142
|
}
|
|
20459
22143
|
async searchTools(query) {
|
|
20460
22144
|
const endpoint = "/functions/v1/tools-search";
|
|
20461
|
-
|
|
20462
|
-
|
|
20463
|
-
|
|
20464
|
-
|
|
20465
|
-
|
|
20466
|
-
|
|
20467
|
-
|
|
20468
|
-
|
|
20469
|
-
|
|
20470
|
-
|
|
20471
|
-
|
|
20472
|
-
|
|
20473
|
-
|
|
20474
|
-
|
|
20475
|
-
|
|
22145
|
+
try {
|
|
22146
|
+
if (true) {
|
|
22147
|
+
console.error(`Search request to ${endpoint}:`, JSON.stringify(query, null, 2));
|
|
22148
|
+
}
|
|
22149
|
+
const response = await this.makeRequest(endpoint, {
|
|
22150
|
+
method: "POST",
|
|
22151
|
+
body: JSON.stringify(query)
|
|
22152
|
+
});
|
|
22153
|
+
if (Array.isArray(response)) {
|
|
22154
|
+
return response;
|
|
22155
|
+
} else if (response.data && Array.isArray(response.data)) {
|
|
22156
|
+
return response.data;
|
|
22157
|
+
} else if (response.results && Array.isArray(response.results)) {
|
|
22158
|
+
return response.results;
|
|
22159
|
+
} else if (response.tools && Array.isArray(response.tools)) {
|
|
22160
|
+
return response.tools;
|
|
22161
|
+
} else {
|
|
22162
|
+
console.warn("Unexpected response structure for searchTools:", response);
|
|
22163
|
+
return [];
|
|
22164
|
+
}
|
|
22165
|
+
} catch (error) {
|
|
22166
|
+
if (error instanceof EnactApiError) {
|
|
22167
|
+
console.error(`Search API error (${error.statusCode}): ${error.message}`);
|
|
22168
|
+
console.error(`Endpoint: ${error.endpoint}`);
|
|
22169
|
+
if (error.statusCode === 502) {
|
|
22170
|
+
console.error("502 Bad Gateway error - this usually indicates:");
|
|
22171
|
+
console.error("• The API server is temporarily unavailable");
|
|
22172
|
+
console.error("• The search service is overloaded");
|
|
22173
|
+
console.error("• Network connectivity issues");
|
|
22174
|
+
console.error("• Try again in a few moments");
|
|
22175
|
+
}
|
|
22176
|
+
} else {
|
|
22177
|
+
console.error("Unexpected search error:", error);
|
|
22178
|
+
}
|
|
22179
|
+
throw error;
|
|
20476
22180
|
}
|
|
20477
22181
|
}
|
|
20478
22182
|
async publishTool(tool, token, tokenType = "cli") {
|
|
@@ -20626,128 +22330,46 @@ class EnactApiClient {
|
|
|
20626
22330
|
errors2.push("Tool name must follow hierarchical format: org/package/tool-name");
|
|
20627
22331
|
}
|
|
20628
22332
|
if (!tool.description || typeof tool.description !== "string") {
|
|
20629
|
-
errors2.push("Tool description is required and must be a string");
|
|
20630
|
-
}
|
|
20631
|
-
if (!tool.command || typeof tool.command !== "string") {
|
|
20632
|
-
errors2.push("Tool command is required and must be a string");
|
|
20633
|
-
}
|
|
20634
|
-
if (tool.timeout && typeof tool.timeout === "string") {
|
|
20635
|
-
if (!/^\d+[smh]$/.test(tool.timeout)) {
|
|
20636
|
-
errors2.push('Timeout must be in Go duration format (e.g., "30s", "5m", "1h")');
|
|
20637
|
-
}
|
|
20638
|
-
}
|
|
20639
|
-
if (tool.tags && !Array.isArray(tool.tags)) {
|
|
20640
|
-
errors2.push("Tags must be an array of strings");
|
|
20641
|
-
}
|
|
20642
|
-
if (tool.inputSchema && typeof tool.inputSchema !== "object") {
|
|
20643
|
-
errors2.push("inputSchema must be a valid JSON Schema object");
|
|
20644
|
-
}
|
|
20645
|
-
if (tool.outputSchema && typeof tool.outputSchema !== "object") {
|
|
20646
|
-
errors2.push("outputSchema must be a valid JSON Schema object");
|
|
20647
|
-
}
|
|
20648
|
-
return {
|
|
20649
|
-
valid: errors2.length === 0,
|
|
20650
|
-
errors: errors2
|
|
20651
|
-
};
|
|
20652
|
-
}
|
|
20653
|
-
}
|
|
20654
|
-
var enactApi = new EnactApiClient;
|
|
20655
|
-
|
|
20656
|
-
class EnactApiError extends Error {
|
|
20657
|
-
statusCode;
|
|
20658
|
-
endpoint;
|
|
20659
|
-
constructor(message, statusCode, endpoint) {
|
|
20660
|
-
super(message);
|
|
20661
|
-
this.statusCode = statusCode;
|
|
20662
|
-
this.endpoint = endpoint;
|
|
20663
|
-
this.name = "EnactApiError";
|
|
20664
|
-
}
|
|
20665
|
-
}
|
|
20666
|
-
|
|
20667
|
-
// src/exec/logger.ts
|
|
20668
|
-
var createLogger = () => {
|
|
20669
|
-
let mcpServer = null;
|
|
20670
|
-
const shouldSuppressConsole = process.env.CI === "true" || process.env.ENACT_SKIP_INTERACTIVE === "true";
|
|
20671
|
-
return {
|
|
20672
|
-
info: (message, ...args) => {
|
|
20673
|
-
if (!shouldSuppressConsole) {
|
|
20674
|
-
console.error("[INFO]", message, ...args);
|
|
20675
|
-
}
|
|
20676
|
-
if (mcpServer) {
|
|
20677
|
-
try {
|
|
20678
|
-
mcpServer.server.sendLoggingMessage({ level: "info", data: message });
|
|
20679
|
-
} catch (error) {}
|
|
20680
|
-
}
|
|
20681
|
-
},
|
|
20682
|
-
error: (message, ...args) => {
|
|
20683
|
-
if (!shouldSuppressConsole) {
|
|
20684
|
-
console.error("[ERROR]", message, ...args);
|
|
20685
|
-
}
|
|
20686
|
-
if (mcpServer) {
|
|
20687
|
-
try {
|
|
20688
|
-
mcpServer.server.sendLoggingMessage({ level: "error", data: message });
|
|
20689
|
-
} catch (error) {}
|
|
20690
|
-
}
|
|
20691
|
-
},
|
|
20692
|
-
warn: (message, ...args) => {
|
|
20693
|
-
if (!shouldSuppressConsole) {
|
|
20694
|
-
console.warn("[WARN]", message, ...args);
|
|
20695
|
-
}
|
|
20696
|
-
if (mcpServer) {
|
|
20697
|
-
try {
|
|
20698
|
-
mcpServer.server.sendLoggingMessage({ level: "warning", data: message });
|
|
20699
|
-
} catch (error) {}
|
|
20700
|
-
}
|
|
20701
|
-
},
|
|
20702
|
-
debug: (message, ...args) => {
|
|
20703
|
-
if ((process.env.DEBUG || process.env.VERBOSE) && !shouldSuppressConsole) {
|
|
20704
|
-
console.error("[DEBUG]", message, ...args);
|
|
20705
|
-
}
|
|
20706
|
-
if (mcpServer) {
|
|
20707
|
-
try {
|
|
20708
|
-
mcpServer.server.sendLoggingMessage({ level: "debug", data: message });
|
|
20709
|
-
} catch (error) {}
|
|
20710
|
-
}
|
|
20711
|
-
},
|
|
20712
|
-
setServer: (server) => {
|
|
20713
|
-
mcpServer = server;
|
|
20714
|
-
},
|
|
20715
|
-
clientLoggingEnabled: () => {
|
|
20716
|
-
return !!mcpServer;
|
|
22333
|
+
errors2.push("Tool description is required and must be a string");
|
|
20717
22334
|
}
|
|
20718
|
-
|
|
20719
|
-
|
|
20720
|
-
var logger = createLogger();
|
|
20721
|
-
var logger_default = logger;
|
|
20722
|
-
|
|
20723
|
-
// src/security/security.ts
|
|
20724
|
-
function verifyToolSignature(tool) {
|
|
20725
|
-
const hasSignature = tool.signature || tool.signatures && Object.keys(tool.signatures).length > 0;
|
|
20726
|
-
if (!hasSignature) {
|
|
20727
|
-
logger_default.warn(`Tool ${tool.name} has no signature`);
|
|
20728
|
-
return false;
|
|
20729
|
-
}
|
|
20730
|
-
try {
|
|
20731
|
-
if (tool.signatures && Object.keys(tool.signatures).length > 0) {
|
|
20732
|
-
logger_default.info(`Tool ${tool.name} has verified signatures from database`);
|
|
20733
|
-
return true;
|
|
22335
|
+
if (!tool.command || typeof tool.command !== "string") {
|
|
22336
|
+
errors2.push("Tool command is required and must be a string");
|
|
20734
22337
|
}
|
|
20735
|
-
if (tool.
|
|
20736
|
-
|
|
20737
|
-
|
|
20738
|
-
if (!isValid2) {
|
|
20739
|
-
logger_default.warn(`Invalid signature for tool ${tool.name}: ${message}`);
|
|
20740
|
-
} else {
|
|
20741
|
-
logger_default.info(`Signature verified for tool ${tool.name}: ${message}`);
|
|
22338
|
+
if (tool.timeout && typeof tool.timeout === "string") {
|
|
22339
|
+
if (!/^\d+[smh]$/.test(tool.timeout)) {
|
|
22340
|
+
errors2.push('Timeout must be in Go duration format (e.g., "30s", "5m", "1h")');
|
|
20742
22341
|
}
|
|
20743
|
-
return isValid2;
|
|
20744
22342
|
}
|
|
20745
|
-
|
|
20746
|
-
|
|
20747
|
-
|
|
20748
|
-
|
|
22343
|
+
if (tool.tags && !Array.isArray(tool.tags)) {
|
|
22344
|
+
errors2.push("Tags must be an array of strings");
|
|
22345
|
+
}
|
|
22346
|
+
if (tool.inputSchema && typeof tool.inputSchema !== "object") {
|
|
22347
|
+
errors2.push("inputSchema must be a valid JSON Schema object");
|
|
22348
|
+
}
|
|
22349
|
+
if (tool.outputSchema && typeof tool.outputSchema !== "object") {
|
|
22350
|
+
errors2.push("outputSchema must be a valid JSON Schema object");
|
|
22351
|
+
}
|
|
22352
|
+
return {
|
|
22353
|
+
valid: errors2.length === 0,
|
|
22354
|
+
errors: errors2
|
|
22355
|
+
};
|
|
22356
|
+
}
|
|
22357
|
+
}
|
|
22358
|
+
var enactApi = new EnactApiClient;
|
|
22359
|
+
|
|
22360
|
+
class EnactApiError extends Error {
|
|
22361
|
+
statusCode;
|
|
22362
|
+
endpoint;
|
|
22363
|
+
constructor(message, statusCode, endpoint) {
|
|
22364
|
+
super(message);
|
|
22365
|
+
this.statusCode = statusCode;
|
|
22366
|
+
this.endpoint = endpoint;
|
|
22367
|
+
this.name = "EnactApiError";
|
|
20749
22368
|
}
|
|
20750
22369
|
}
|
|
22370
|
+
|
|
22371
|
+
// src/security/security.ts
|
|
22372
|
+
init_logger();
|
|
20751
22373
|
function verifyCommandSafety(command, tool) {
|
|
20752
22374
|
const warnings = [];
|
|
20753
22375
|
const blocked = [];
|
|
@@ -21007,6 +22629,29 @@ import { spawn } from "child_process";
|
|
|
21007
22629
|
class ExecutionProvider {
|
|
21008
22630
|
}
|
|
21009
22631
|
|
|
22632
|
+
// src/core/DirectExecutionProvider.ts
|
|
22633
|
+
init_logger();
|
|
22634
|
+
|
|
22635
|
+
// src/utils/timeout.ts
|
|
22636
|
+
function parseTimeout(timeout) {
|
|
22637
|
+
const match = timeout.match(/^(\d+)([smh])$/);
|
|
22638
|
+
if (!match) {
|
|
22639
|
+
return 30000;
|
|
22640
|
+
}
|
|
22641
|
+
const value = parseInt(match[1]);
|
|
22642
|
+
const unit = match[2];
|
|
22643
|
+
switch (unit) {
|
|
22644
|
+
case "s":
|
|
22645
|
+
return value * 1000;
|
|
22646
|
+
case "m":
|
|
22647
|
+
return value * 60 * 1000;
|
|
22648
|
+
case "h":
|
|
22649
|
+
return value * 60 * 60 * 1000;
|
|
22650
|
+
default:
|
|
22651
|
+
return 30000;
|
|
22652
|
+
}
|
|
22653
|
+
}
|
|
22654
|
+
|
|
21010
22655
|
// src/core/DirectExecutionProvider.ts
|
|
21011
22656
|
class DirectExecutionProvider extends ExecutionProvider {
|
|
21012
22657
|
async resolveEnvironmentVariables(envConfig, namespace) {
|
|
@@ -21029,34 +22674,169 @@ class DirectExecutionProvider extends ExecutionProvider {
|
|
|
21029
22674
|
}
|
|
21030
22675
|
return resolved;
|
|
21031
22676
|
}
|
|
21032
|
-
async executeCommand(command, inputs, environment, timeout) {
|
|
22677
|
+
async executeCommand(command, inputs, environment, timeout, options) {
|
|
21033
22678
|
return new Promise((resolve, reject) => {
|
|
21034
22679
|
let stdout = "";
|
|
21035
22680
|
let stderr = "";
|
|
22681
|
+
const verbose = options?.verbose ?? false;
|
|
22682
|
+
const showSpinner = options?.showSpinner ?? false;
|
|
22683
|
+
const streamOutput = options?.streamOutput ?? true;
|
|
22684
|
+
let spinner = null;
|
|
22685
|
+
if (showSpinner) {
|
|
22686
|
+
try {
|
|
22687
|
+
const p = require_dist2();
|
|
22688
|
+
spinner = p.spinner();
|
|
22689
|
+
spinner.start("Executing tool...");
|
|
22690
|
+
} catch (e) {
|
|
22691
|
+
console.log("Executing tool...");
|
|
22692
|
+
}
|
|
22693
|
+
}
|
|
22694
|
+
if (verbose) {
|
|
22695
|
+
try {
|
|
22696
|
+
const pc = require_picocolors();
|
|
22697
|
+
console.error(pc.cyan(`
|
|
22698
|
+
\uD83D\uDE80 Executing command:`));
|
|
22699
|
+
console.error(pc.white(command));
|
|
22700
|
+
} catch (e) {
|
|
22701
|
+
console.error(`
|
|
22702
|
+
\uD83D\uDE80 Executing command:`);
|
|
22703
|
+
console.error(command);
|
|
22704
|
+
}
|
|
22705
|
+
}
|
|
22706
|
+
let substitutedCommand = command;
|
|
22707
|
+
for (const [key, value] of Object.entries(inputs)) {
|
|
22708
|
+
const templateVar = `\${${key}}`;
|
|
22709
|
+
let substitutionValue;
|
|
22710
|
+
if (typeof value === "string") {
|
|
22711
|
+
substitutionValue = value;
|
|
22712
|
+
} else if (typeof value === "object") {
|
|
22713
|
+
substitutionValue = JSON.stringify(value);
|
|
22714
|
+
} else {
|
|
22715
|
+
substitutionValue = String(value);
|
|
22716
|
+
}
|
|
22717
|
+
substitutedCommand = substitutedCommand.replace(new RegExp(`\\$\\{${key}\\}`, "g"), substitutionValue);
|
|
22718
|
+
}
|
|
21036
22719
|
const env = {
|
|
21037
22720
|
...process.env,
|
|
21038
22721
|
...environment.vars
|
|
21039
22722
|
};
|
|
21040
|
-
const commandParts = this.parseCommand(
|
|
22723
|
+
const commandParts = this.parseCommand(substitutedCommand);
|
|
21041
22724
|
const cmd = commandParts[0];
|
|
21042
22725
|
const args = commandParts.slice(1);
|
|
21043
22726
|
logger_default.info(`Executing command: ${command}`);
|
|
21044
22727
|
try {
|
|
21045
22728
|
const proc = spawn(cmd, args, {
|
|
21046
22729
|
env,
|
|
21047
|
-
stdio: ["pipe", "pipe", "pipe"]
|
|
22730
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
22731
|
+
detached: process.platform !== "win32"
|
|
21048
22732
|
});
|
|
22733
|
+
let isCleanedUp = false;
|
|
22734
|
+
let cleanupTimer = null;
|
|
22735
|
+
const cleanup = () => {
|
|
22736
|
+
if (isCleanedUp)
|
|
22737
|
+
return;
|
|
22738
|
+
isCleanedUp = true;
|
|
22739
|
+
if (cleanupTimer) {
|
|
22740
|
+
clearTimeout(cleanupTimer);
|
|
22741
|
+
cleanupTimer = null;
|
|
22742
|
+
}
|
|
22743
|
+
if (proc && !proc.killed) {
|
|
22744
|
+
try {
|
|
22745
|
+
console.log(`[DEBUG] Cleaning up process PID: ${proc.pid}`);
|
|
22746
|
+
if (process.platform === "win32") {
|
|
22747
|
+
proc.kill("SIGKILL");
|
|
22748
|
+
} else {
|
|
22749
|
+
proc.kill("SIGTERM");
|
|
22750
|
+
cleanupTimer = setTimeout(() => {
|
|
22751
|
+
if (!proc.killed && !isCleanedUp) {
|
|
22752
|
+
console.log(`[DEBUG] Force killing process PID: ${proc.pid}`);
|
|
22753
|
+
try {
|
|
22754
|
+
proc.kill("SIGKILL");
|
|
22755
|
+
} catch (killError) {
|
|
22756
|
+
logger_default.debug(`Force kill error (likely harmless): ${killError}`);
|
|
22757
|
+
}
|
|
22758
|
+
}
|
|
22759
|
+
cleanupTimer = null;
|
|
22760
|
+
}, 1000);
|
|
22761
|
+
}
|
|
22762
|
+
} catch (killError) {
|
|
22763
|
+
logger_default.debug(`Process cleanup error (likely harmless): ${killError}`);
|
|
22764
|
+
}
|
|
22765
|
+
}
|
|
22766
|
+
};
|
|
21049
22767
|
proc.stdout.on("data", (data) => {
|
|
21050
22768
|
const chunk = data.toString();
|
|
21051
22769
|
stdout += chunk;
|
|
21052
|
-
|
|
22770
|
+
if (streamOutput) {
|
|
22771
|
+
process.stdout.write(chunk);
|
|
22772
|
+
}
|
|
21053
22773
|
});
|
|
21054
22774
|
proc.stderr.on("data", (data) => {
|
|
21055
22775
|
const chunk = data.toString();
|
|
21056
22776
|
stderr += chunk;
|
|
21057
|
-
|
|
22777
|
+
if (streamOutput) {
|
|
22778
|
+
process.stderr.write(chunk);
|
|
22779
|
+
}
|
|
21058
22780
|
});
|
|
21059
22781
|
proc.on("close", (code) => {
|
|
22782
|
+
console.log(`[DEBUG] Process closed with code: ${code}, PID: ${proc.pid}`);
|
|
22783
|
+
cleanup();
|
|
22784
|
+
if (spinner) {
|
|
22785
|
+
spinner.stop("Execution completed");
|
|
22786
|
+
}
|
|
22787
|
+
if (code === 0) {
|
|
22788
|
+
if (showSpinner || verbose) {
|
|
22789
|
+
try {
|
|
22790
|
+
const pc = require_picocolors();
|
|
22791
|
+
console.error(pc.green(`
|
|
22792
|
+
✅ Tool executed successfully`));
|
|
22793
|
+
if (stdout.trim() && !streamOutput) {
|
|
22794
|
+
console.error(pc.cyan(`
|
|
22795
|
+
\uD83D\uDCE4 Output:`));
|
|
22796
|
+
console.error(stdout.trim());
|
|
22797
|
+
}
|
|
22798
|
+
} catch (e) {
|
|
22799
|
+
console.error(`
|
|
22800
|
+
✅ Tool executed successfully`);
|
|
22801
|
+
if (stdout.trim() && !streamOutput) {
|
|
22802
|
+
console.error(`
|
|
22803
|
+
\uD83D\uDCE4 Output:`);
|
|
22804
|
+
console.error(stdout.trim());
|
|
22805
|
+
}
|
|
22806
|
+
}
|
|
22807
|
+
}
|
|
22808
|
+
} else {
|
|
22809
|
+
if (showSpinner || verbose) {
|
|
22810
|
+
try {
|
|
22811
|
+
const pc = require_picocolors();
|
|
22812
|
+
console.error(pc.red(`
|
|
22813
|
+
❌ Tool execution failed (exit code: ${code})`));
|
|
22814
|
+
if (stderr.trim() && !streamOutput) {
|
|
22815
|
+
console.error(pc.red(`
|
|
22816
|
+
\uD83D\uDCE4 Error output:`));
|
|
22817
|
+
console.error(stderr.trim());
|
|
22818
|
+
}
|
|
22819
|
+
if (stdout.trim() && !streamOutput) {
|
|
22820
|
+
console.error(pc.yellow(`
|
|
22821
|
+
\uD83D\uDCE4 Standard output:`));
|
|
22822
|
+
console.error(stdout.trim());
|
|
22823
|
+
}
|
|
22824
|
+
} catch (e) {
|
|
22825
|
+
console.error(`
|
|
22826
|
+
❌ Tool execution failed (exit code: ${code})`);
|
|
22827
|
+
if (stderr.trim() && !streamOutput) {
|
|
22828
|
+
console.error(`
|
|
22829
|
+
\uD83D\uDCE4 Error output:`);
|
|
22830
|
+
console.error(stderr.trim());
|
|
22831
|
+
}
|
|
22832
|
+
if (stdout.trim() && !streamOutput) {
|
|
22833
|
+
console.error(`
|
|
22834
|
+
\uD83D\uDCE4 Standard output:`);
|
|
22835
|
+
console.error(stdout.trim());
|
|
22836
|
+
}
|
|
22837
|
+
}
|
|
22838
|
+
}
|
|
22839
|
+
}
|
|
21060
22840
|
resolve({
|
|
21061
22841
|
stdout: stdout.trim(),
|
|
21062
22842
|
stderr: stderr.trim(),
|
|
@@ -21064,12 +22844,29 @@ class DirectExecutionProvider extends ExecutionProvider {
|
|
|
21064
22844
|
});
|
|
21065
22845
|
});
|
|
21066
22846
|
proc.on("error", (error) => {
|
|
22847
|
+
cleanup();
|
|
22848
|
+
if (spinner) {
|
|
22849
|
+
spinner.stop("Execution failed");
|
|
22850
|
+
}
|
|
22851
|
+
if (showSpinner || verbose) {
|
|
22852
|
+
try {
|
|
22853
|
+
const pc = require_picocolors();
|
|
22854
|
+
console.error(pc.red(`
|
|
22855
|
+
❌ Failed to execute command: ${error.message}`));
|
|
22856
|
+
} catch (e) {
|
|
22857
|
+
console.error(`
|
|
22858
|
+
❌ Failed to execute command: ${error.message}`);
|
|
22859
|
+
}
|
|
22860
|
+
}
|
|
21067
22861
|
reject(new Error(`Command execution error: ${error.message}`));
|
|
21068
22862
|
});
|
|
21069
22863
|
if (timeout) {
|
|
21070
|
-
const timeoutMs =
|
|
22864
|
+
const timeoutMs = parseTimeout(timeout);
|
|
21071
22865
|
setTimeout(() => {
|
|
21072
|
-
|
|
22866
|
+
cleanup();
|
|
22867
|
+
if (spinner) {
|
|
22868
|
+
spinner.stop("Execution failed");
|
|
22869
|
+
}
|
|
21073
22870
|
reject(new Error(`Command timed out after ${timeout}`));
|
|
21074
22871
|
}, timeoutMs);
|
|
21075
22872
|
}
|
|
@@ -21078,6 +22875,20 @@ class DirectExecutionProvider extends ExecutionProvider {
|
|
|
21078
22875
|
}
|
|
21079
22876
|
});
|
|
21080
22877
|
}
|
|
22878
|
+
async executeCommandExecStyle(command, timeout, verbose = false, envVars = {}) {
|
|
22879
|
+
const environment = {
|
|
22880
|
+
vars: envVars,
|
|
22881
|
+
resources: { timeout }
|
|
22882
|
+
};
|
|
22883
|
+
const result = await this.executeCommand(command, {}, environment, timeout, {
|
|
22884
|
+
verbose,
|
|
22885
|
+
showSpinner: true,
|
|
22886
|
+
streamOutput: false
|
|
22887
|
+
});
|
|
22888
|
+
if (result.exitCode !== 0) {
|
|
22889
|
+
throw new Error(`Command failed with exit code ${result.exitCode}`);
|
|
22890
|
+
}
|
|
22891
|
+
}
|
|
21081
22892
|
async setup(tool) {
|
|
21082
22893
|
logger_default.debug(`Setting up direct execution for tool: ${tool.name}`);
|
|
21083
22894
|
return true;
|
|
@@ -21158,24 +22969,6 @@ class DirectExecutionProvider extends ExecutionProvider {
|
|
|
21158
22969
|
generateExecutionId() {
|
|
21159
22970
|
return `exec_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
|
|
21160
22971
|
}
|
|
21161
|
-
parseTimeout(timeout) {
|
|
21162
|
-
const match = timeout.match(/^(\d+)([smh])$/);
|
|
21163
|
-
if (!match) {
|
|
21164
|
-
throw new Error(`Invalid timeout format: ${timeout}`);
|
|
21165
|
-
}
|
|
21166
|
-
const value = parseInt(match[1]);
|
|
21167
|
-
const unit = match[2];
|
|
21168
|
-
switch (unit) {
|
|
21169
|
-
case "s":
|
|
21170
|
-
return value * 1000;
|
|
21171
|
-
case "m":
|
|
21172
|
-
return value * 60 * 1000;
|
|
21173
|
-
case "h":
|
|
21174
|
-
return value * 60 * 60 * 1000;
|
|
21175
|
-
default:
|
|
21176
|
-
throw new Error(`Unknown timeout unit: ${unit}`);
|
|
21177
|
-
}
|
|
21178
|
-
}
|
|
21179
22972
|
parseCommand(command) {
|
|
21180
22973
|
const parts = [];
|
|
21181
22974
|
let current = "";
|
|
@@ -21210,115 +23003,461 @@ class DirectExecutionProvider extends ExecutionProvider {
|
|
|
21210
23003
|
}
|
|
21211
23004
|
}
|
|
21212
23005
|
|
|
21213
|
-
// src/
|
|
21214
|
-
|
|
21215
|
-
|
|
21216
|
-
|
|
21217
|
-
|
|
21218
|
-
|
|
21219
|
-
var
|
|
21220
|
-
|
|
21221
|
-
|
|
21222
|
-
|
|
21223
|
-
|
|
23006
|
+
// src/core/EnactCore.ts
|
|
23007
|
+
init_env_loader();
|
|
23008
|
+
init_logger();
|
|
23009
|
+
var import_yaml2 = __toESM(require_dist3(), 1);
|
|
23010
|
+
|
|
23011
|
+
// src/security/sign.ts
|
|
23012
|
+
var import_yaml = __toESM(require_dist3(), 1);
|
|
23013
|
+
import * as crypto from "crypto";
|
|
23014
|
+
import * as fs from "fs";
|
|
23015
|
+
import * as path from "path";
|
|
23016
|
+
function createCanonicalToolDefinition(tool) {
|
|
23017
|
+
const canonical = {};
|
|
23018
|
+
const orderedFields = [
|
|
23019
|
+
"name",
|
|
23020
|
+
"description",
|
|
23021
|
+
"command",
|
|
23022
|
+
"protocol_version",
|
|
23023
|
+
"version",
|
|
23024
|
+
"timeout",
|
|
23025
|
+
"tags",
|
|
23026
|
+
"input_schema",
|
|
23027
|
+
"output_schema",
|
|
23028
|
+
"annotations",
|
|
23029
|
+
"env_vars",
|
|
23030
|
+
"examples",
|
|
23031
|
+
"resources",
|
|
23032
|
+
"doc",
|
|
23033
|
+
"authors",
|
|
23034
|
+
"enact"
|
|
23035
|
+
];
|
|
23036
|
+
for (const field of orderedFields) {
|
|
23037
|
+
if (tool[field] !== undefined) {
|
|
23038
|
+
canonical[field] = tool[field];
|
|
23039
|
+
}
|
|
21224
23040
|
}
|
|
21225
|
-
|
|
21226
|
-
|
|
23041
|
+
const remainingFields = Object.keys(tool).filter((key) => !orderedFields.includes(key)).sort();
|
|
23042
|
+
for (const field of remainingFields) {
|
|
23043
|
+
if (tool[field] !== undefined) {
|
|
23044
|
+
canonical[field] = tool[field];
|
|
23045
|
+
}
|
|
21227
23046
|
}
|
|
21228
|
-
return
|
|
23047
|
+
return canonical;
|
|
21229
23048
|
}
|
|
21230
|
-
function
|
|
21231
|
-
|
|
23049
|
+
function createCanonicalToolJson(toolData) {
|
|
23050
|
+
const toolRecord = {
|
|
23051
|
+
name: toolData.name,
|
|
23052
|
+
description: toolData.description,
|
|
23053
|
+
command: toolData.command,
|
|
23054
|
+
protocol_version: toolData.protocol_version,
|
|
23055
|
+
version: toolData.version,
|
|
23056
|
+
timeout: toolData.timeout,
|
|
23057
|
+
tags: toolData.tags,
|
|
23058
|
+
input_schema: toolData.input_schema,
|
|
23059
|
+
output_schema: toolData.output_schema,
|
|
23060
|
+
annotations: toolData.annotations,
|
|
23061
|
+
env_vars: toolData.env_vars,
|
|
23062
|
+
examples: toolData.examples,
|
|
23063
|
+
resources: toolData.resources,
|
|
23064
|
+
doc: toolData.doc,
|
|
23065
|
+
authors: toolData.authors,
|
|
23066
|
+
enact: toolData.enact || "1.0.0"
|
|
23067
|
+
};
|
|
23068
|
+
const canonical = createCanonicalToolDefinition(toolRecord);
|
|
23069
|
+
return JSON.stringify(canonical, Object.keys(canonical).sort());
|
|
21232
23070
|
}
|
|
21233
|
-
|
|
21234
|
-
|
|
21235
|
-
|
|
21236
|
-
|
|
21237
|
-
|
|
23071
|
+
var DEFAULT_POLICY = {
|
|
23072
|
+
minimumSignatures: 1,
|
|
23073
|
+
allowedAlgorithms: ["sha256"]
|
|
23074
|
+
};
|
|
23075
|
+
var TRUSTED_KEYS_DIR = path.join(process.env.HOME || ".", ".enact", "trusted-keys");
|
|
23076
|
+
function getTrustedPublicKeysMap() {
|
|
23077
|
+
const trustedKeys = new Map;
|
|
23078
|
+
if (fs.existsSync(TRUSTED_KEYS_DIR)) {
|
|
23079
|
+
try {
|
|
23080
|
+
const files = fs.readdirSync(TRUSTED_KEYS_DIR);
|
|
23081
|
+
for (const file of files) {
|
|
23082
|
+
if (file.endsWith(".pem")) {
|
|
23083
|
+
const keyPath = path.join(TRUSTED_KEYS_DIR, file);
|
|
23084
|
+
const pemContent = fs.readFileSync(keyPath, "utf8");
|
|
23085
|
+
const base64Key = pemToBase64(pemContent);
|
|
23086
|
+
trustedKeys.set(base64Key, pemContent);
|
|
23087
|
+
}
|
|
23088
|
+
}
|
|
23089
|
+
} catch (error) {
|
|
23090
|
+
console.error(`Error reading trusted keys: ${error.message}`);
|
|
23091
|
+
}
|
|
21238
23092
|
}
|
|
23093
|
+
return trustedKeys;
|
|
21239
23094
|
}
|
|
21240
|
-
|
|
21241
|
-
|
|
21242
|
-
|
|
21243
|
-
|
|
21244
|
-
|
|
23095
|
+
function pemToBase64(pem) {
|
|
23096
|
+
return pem.replace(/-----BEGIN PUBLIC KEY-----/, "").replace(/-----END PUBLIC KEY-----/, "").replace(/\s/g, "");
|
|
23097
|
+
}
|
|
23098
|
+
function base64ToPem(base64) {
|
|
23099
|
+
return `-----BEGIN PUBLIC KEY-----
|
|
23100
|
+
${base64.match(/.{1,64}/g)?.join(`
|
|
23101
|
+
`)}
|
|
23102
|
+
-----END PUBLIC KEY-----`;
|
|
23103
|
+
}
|
|
23104
|
+
async function hashTool(tool) {
|
|
23105
|
+
const canonical = createCanonicalToolDefinition(tool);
|
|
23106
|
+
const { signature, ...toolForSigning } = canonical;
|
|
23107
|
+
const canonicalJson = JSON.stringify(toolForSigning, Object.keys(toolForSigning).sort());
|
|
23108
|
+
console.error("\uD83D\uDD0D Canonical JSON for hashing:", canonicalJson);
|
|
23109
|
+
console.error("\uD83D\uDD0D Canonical JSON length:", canonicalJson.length);
|
|
23110
|
+
const encoder = new TextEncoder;
|
|
23111
|
+
const data = encoder.encode(canonicalJson);
|
|
23112
|
+
const { webcrypto } = await import("node:crypto");
|
|
23113
|
+
const hashBuffer = await webcrypto.subtle.digest("SHA-256", data);
|
|
23114
|
+
const hashBytes = new Uint8Array(hashBuffer);
|
|
23115
|
+
console.error("\uD83D\uDD0D SHA-256 hash length:", hashBytes.length, "bytes (should be 32)");
|
|
23116
|
+
return hashBytes;
|
|
23117
|
+
}
|
|
23118
|
+
async function verifyToolSignature(toolObject, signatureB64, publicKeyObj) {
|
|
21245
23119
|
try {
|
|
21246
|
-
const
|
|
21247
|
-
|
|
21248
|
-
|
|
21249
|
-
|
|
21250
|
-
|
|
21251
|
-
}
|
|
23120
|
+
const toolHash = await hashTool(toolObject);
|
|
23121
|
+
const signatureBytes = new Uint8Array(atob(signatureB64).split("").map((char) => char.charCodeAt(0)));
|
|
23122
|
+
console.error("\uD83D\uDD0D Tool hash byte length:", toolHash.length, "(should be 32 for SHA-256)");
|
|
23123
|
+
console.error("\uD83D\uDD0D Signature bytes length:", signatureBytes.length, "(should be 64 for P-256)");
|
|
23124
|
+
const { webcrypto } = await import("node:crypto");
|
|
23125
|
+
const isValid2 = await webcrypto.subtle.verify({ name: "ECDSA", hash: { name: "SHA-256" } }, publicKeyObj, signatureBytes, toolHash);
|
|
23126
|
+
console.error("\uD83C\uDFAF Web Crypto API verification result:", isValid2);
|
|
23127
|
+
return isValid2;
|
|
21252
23128
|
} catch (error) {
|
|
21253
|
-
|
|
21254
|
-
|
|
21255
|
-
}
|
|
21256
|
-
return { variables: {} };
|
|
21257
|
-
}
|
|
21258
|
-
}
|
|
21259
|
-
async function loadPackageEnvironmentVariables(packageNamespace) {
|
|
21260
|
-
const config = await readPackageEnvConfig(packageNamespace);
|
|
21261
|
-
const envVars = {};
|
|
21262
|
-
for (const [name, envVar] of Object.entries(config.variables)) {
|
|
21263
|
-
const value = envVar.encrypted ? decryptValue(envVar.value) : envVar.value;
|
|
21264
|
-
envVars[name] = value;
|
|
23129
|
+
console.error("❌ Verification error:", error);
|
|
23130
|
+
return false;
|
|
21265
23131
|
}
|
|
21266
|
-
return envVars;
|
|
21267
23132
|
}
|
|
21268
|
-
function
|
|
21269
|
-
|
|
21270
|
-
|
|
21271
|
-
}
|
|
23133
|
+
async function verifyTool(toolYaml, policy = DEFAULT_POLICY) {
|
|
23134
|
+
const errors2 = [];
|
|
23135
|
+
const verifiedSigners = [];
|
|
21272
23136
|
try {
|
|
21273
|
-
const
|
|
21274
|
-
|
|
21275
|
-
|
|
21276
|
-
|
|
23137
|
+
const trustedKeys = getTrustedPublicKeysMap();
|
|
23138
|
+
if (trustedKeys.size === 0) {
|
|
23139
|
+
return {
|
|
23140
|
+
isValid: false,
|
|
23141
|
+
message: "No trusted public keys available",
|
|
23142
|
+
validSignatures: 0,
|
|
23143
|
+
totalSignatures: 0,
|
|
23144
|
+
verifiedSigners: [],
|
|
23145
|
+
errors: ["No trusted keys configured"]
|
|
23146
|
+
};
|
|
21277
23147
|
}
|
|
21278
|
-
|
|
21279
|
-
|
|
23148
|
+
if (process.env.DEBUG) {
|
|
23149
|
+
console.error("Trusted keys available:");
|
|
23150
|
+
for (const [key, pem] of trustedKeys.entries()) {
|
|
23151
|
+
console.error(` Key: ${key.substring(0, 20)}...`);
|
|
23152
|
+
}
|
|
23153
|
+
}
|
|
23154
|
+
const tool = typeof toolYaml === "string" ? import_yaml.parse(toolYaml) : toolYaml;
|
|
23155
|
+
if (!tool.signatures || Object.keys(tool.signatures).length === 0) {
|
|
23156
|
+
return {
|
|
23157
|
+
isValid: false,
|
|
23158
|
+
message: "No signatures found in the tool",
|
|
23159
|
+
validSignatures: 0,
|
|
23160
|
+
totalSignatures: 0,
|
|
23161
|
+
verifiedSigners: [],
|
|
23162
|
+
errors: ["No signatures found"]
|
|
23163
|
+
};
|
|
23164
|
+
}
|
|
23165
|
+
const totalSignatures = Object.keys(tool.signatures).length;
|
|
23166
|
+
const toolForVerification = { ...tool };
|
|
23167
|
+
delete toolForVerification.signatures;
|
|
23168
|
+
const toolHashBytes = await hashTool(toolForVerification);
|
|
23169
|
+
if (true) {
|
|
23170
|
+
console.error("=== VERIFICATION DEBUG (WEBAPP COMPATIBLE) ===");
|
|
23171
|
+
console.error("Original tool signature field:", Object.keys(tool.signatures || {}));
|
|
23172
|
+
console.error("Tool before removing signatures:", JSON.stringify(tool, null, 2));
|
|
23173
|
+
console.error("Tool for verification:", JSON.stringify(toolForVerification, null, 2));
|
|
23174
|
+
console.error("Tool hash bytes length:", toolHashBytes.length, "(should be 32 for SHA-256)");
|
|
23175
|
+
console.error("==============================================");
|
|
23176
|
+
}
|
|
23177
|
+
let validSignatures = 0;
|
|
23178
|
+
for (const [publicKeyBase64, signatureData] of Object.entries(tool.signatures)) {
|
|
23179
|
+
try {
|
|
23180
|
+
if (policy.allowedAlgorithms && !policy.allowedAlgorithms.includes(signatureData.algorithm)) {
|
|
23181
|
+
errors2.push(`Signature by ${signatureData.signer}: unsupported algorithm ${signatureData.algorithm}`);
|
|
23182
|
+
continue;
|
|
23183
|
+
}
|
|
23184
|
+
if (policy.trustedSigners && !policy.trustedSigners.includes(signatureData.signer)) {
|
|
23185
|
+
errors2.push(`Signature by ${signatureData.signer}: signer not in trusted list`);
|
|
23186
|
+
continue;
|
|
23187
|
+
}
|
|
23188
|
+
const publicKeyPem = trustedKeys.get(publicKeyBase64);
|
|
23189
|
+
if (!publicKeyPem) {
|
|
23190
|
+
const reconstructedPem = base64ToPem(publicKeyBase64);
|
|
23191
|
+
if (!trustedKeys.has(pemToBase64(reconstructedPem))) {
|
|
23192
|
+
errors2.push(`Signature by ${signatureData.signer}: public key not trusted`);
|
|
23193
|
+
continue;
|
|
23194
|
+
}
|
|
23195
|
+
}
|
|
23196
|
+
if (process.env.DEBUG) {
|
|
23197
|
+
console.error("Looking for public key:", publicKeyBase64);
|
|
23198
|
+
console.error("Key found in trusted keys:", !!publicKeyPem);
|
|
23199
|
+
}
|
|
23200
|
+
let isValid3 = false;
|
|
23201
|
+
try {
|
|
23202
|
+
const publicKeyToUse = publicKeyPem || base64ToPem(publicKeyBase64);
|
|
23203
|
+
if (process.env.DEBUG) {
|
|
23204
|
+
console.error("Signature base64:", signatureData.value);
|
|
23205
|
+
console.error("Signature buffer length (should be 64):", Buffer.from(signatureData.value, "base64").length);
|
|
23206
|
+
console.error("Public key base64:", publicKeyBase64);
|
|
23207
|
+
}
|
|
23208
|
+
if (signatureData.type === "ecdsa-p256") {
|
|
23209
|
+
const { webcrypto } = await import("node:crypto");
|
|
23210
|
+
const publicKeyData = crypto.createPublicKey({
|
|
23211
|
+
key: publicKeyToUse,
|
|
23212
|
+
format: "pem",
|
|
23213
|
+
type: "spki"
|
|
23214
|
+
}).export({ format: "der", type: "spki" });
|
|
23215
|
+
const publicKeyObj = await webcrypto.subtle.importKey("spki", publicKeyData, { name: "ECDSA", namedCurve: "P-256" }, false, ["verify"]);
|
|
23216
|
+
isValid3 = await verifyToolSignature(toolForVerification, signatureData.value, publicKeyObj);
|
|
23217
|
+
if (process.env.DEBUG) {
|
|
23218
|
+
console.error("Web Crypto API verification result (webapp compatible):", isValid3);
|
|
23219
|
+
}
|
|
23220
|
+
} else {
|
|
23221
|
+
const verify = crypto.createVerify("SHA256");
|
|
23222
|
+
const canonicalJson = createCanonicalToolJson(toolForVerification);
|
|
23223
|
+
verify.update(canonicalJson, "utf8");
|
|
23224
|
+
const signature = Buffer.from(signatureData.value, "base64");
|
|
23225
|
+
isValid3 = verify.verify(publicKeyToUse, signature);
|
|
23226
|
+
}
|
|
23227
|
+
} catch (verifyError) {
|
|
23228
|
+
errors2.push(`Signature by ${signatureData.signer}: verification error - ${verifyError.message}`);
|
|
23229
|
+
continue;
|
|
23230
|
+
}
|
|
23231
|
+
if (isValid3) {
|
|
23232
|
+
validSignatures++;
|
|
23233
|
+
verifiedSigners.push({
|
|
23234
|
+
signer: signatureData.signer,
|
|
23235
|
+
role: signatureData.role,
|
|
23236
|
+
keyId: publicKeyBase64.substring(0, 8)
|
|
23237
|
+
});
|
|
23238
|
+
} else {
|
|
23239
|
+
errors2.push(`Signature by ${signatureData.signer}: cryptographic verification failed`);
|
|
23240
|
+
}
|
|
23241
|
+
} catch (error) {
|
|
23242
|
+
errors2.push(`Signature by ${signatureData.signer}: verification error - ${error.message}`);
|
|
23243
|
+
}
|
|
23244
|
+
}
|
|
23245
|
+
const policyErrors = [];
|
|
23246
|
+
if (policy.minimumSignatures && validSignatures < policy.minimumSignatures) {
|
|
23247
|
+
policyErrors.push(`Policy requires ${policy.minimumSignatures} signatures, but only ${validSignatures} valid`);
|
|
23248
|
+
}
|
|
23249
|
+
if (policy.requireRoles && policy.requireRoles.length > 0) {
|
|
23250
|
+
const verifiedRoles = verifiedSigners.map((s) => s.role).filter(Boolean);
|
|
23251
|
+
const missingRoles = policy.requireRoles.filter((role) => !verifiedRoles.includes(role));
|
|
23252
|
+
if (missingRoles.length > 0) {
|
|
23253
|
+
policyErrors.push(`Policy requires roles: ${missingRoles.join(", ")}`);
|
|
23254
|
+
}
|
|
23255
|
+
}
|
|
23256
|
+
const isValid2 = policyErrors.length === 0 && validSignatures > 0;
|
|
23257
|
+
const allErrors = [...errors2, ...policyErrors];
|
|
23258
|
+
let message;
|
|
23259
|
+
if (isValid2) {
|
|
23260
|
+
message = `Tool "${tool.name}" verified with ${validSignatures}/${totalSignatures} valid signatures`;
|
|
23261
|
+
if (verifiedSigners.length > 0) {
|
|
23262
|
+
const signerInfo = verifiedSigners.map((s) => `${s.signer}${s.role ? ` (${s.role})` : ""}`).join(", ");
|
|
23263
|
+
message += ` from: ${signerInfo}`;
|
|
23264
|
+
}
|
|
23265
|
+
} else {
|
|
23266
|
+
message = `Tool "${tool.name}" verification failed: ${allErrors[0] || "Unknown error"}`;
|
|
23267
|
+
}
|
|
23268
|
+
return {
|
|
23269
|
+
isValid: isValid2,
|
|
23270
|
+
message,
|
|
23271
|
+
validSignatures,
|
|
23272
|
+
totalSignatures,
|
|
23273
|
+
verifiedSigners,
|
|
23274
|
+
errors: allErrors
|
|
23275
|
+
};
|
|
21280
23276
|
} catch (error) {
|
|
21281
|
-
|
|
21282
|
-
|
|
23277
|
+
return {
|
|
23278
|
+
isValid: false,
|
|
23279
|
+
message: `Verification error: ${error.message}`,
|
|
23280
|
+
validSignatures: 0,
|
|
23281
|
+
totalSignatures: 0,
|
|
23282
|
+
verifiedSigners: [],
|
|
23283
|
+
errors: [error.message]
|
|
23284
|
+
};
|
|
21283
23285
|
}
|
|
21284
23286
|
}
|
|
21285
|
-
|
|
21286
|
-
|
|
21287
|
-
|
|
21288
|
-
|
|
21289
|
-
|
|
21290
|
-
|
|
21291
|
-
|
|
21292
|
-
|
|
21293
|
-
|
|
21294
|
-
|
|
21295
|
-
|
|
23287
|
+
var VERIFICATION_POLICIES = {
|
|
23288
|
+
PERMISSIVE: {
|
|
23289
|
+
minimumSignatures: 1,
|
|
23290
|
+
allowedAlgorithms: ["sha256"]
|
|
23291
|
+
},
|
|
23292
|
+
ENTERPRISE: {
|
|
23293
|
+
minimumSignatures: 2,
|
|
23294
|
+
requireRoles: ["author", "reviewer"],
|
|
23295
|
+
allowedAlgorithms: ["sha256"]
|
|
23296
|
+
},
|
|
23297
|
+
PARANOID: {
|
|
23298
|
+
minimumSignatures: 3,
|
|
23299
|
+
requireRoles: ["author", "reviewer", "approver"],
|
|
23300
|
+
allowedAlgorithms: ["sha256"]
|
|
23301
|
+
}
|
|
23302
|
+
};
|
|
23303
|
+
|
|
23304
|
+
// src/security/verification-enforcer.ts
|
|
23305
|
+
init_logger();
|
|
23306
|
+
async function enforceSignatureVerification(tool, options = {}) {
|
|
23307
|
+
const toolName = tool.name || "unknown";
|
|
23308
|
+
if (options.skipVerification) {
|
|
23309
|
+
logger_default.warn(`\uD83D\uDEA8 SECURITY WARNING: Signature verification skipped for tool: ${toolName}`);
|
|
23310
|
+
logger_default.warn(` This bypasses security measures and is NOT recommended for production use!`);
|
|
23311
|
+
return {
|
|
23312
|
+
allowed: true,
|
|
23313
|
+
reason: `Verification skipped by request for tool: ${toolName}`,
|
|
23314
|
+
verificationResult: {
|
|
23315
|
+
isValid: false,
|
|
23316
|
+
message: "Verification skipped",
|
|
23317
|
+
validSignatures: 0,
|
|
23318
|
+
totalSignatures: 0,
|
|
23319
|
+
verifiedSigners: [],
|
|
23320
|
+
errors: ["Signature verification was explicitly skipped"]
|
|
23321
|
+
}
|
|
23322
|
+
};
|
|
23323
|
+
}
|
|
23324
|
+
const hasSignatures = !!(tool.signatures && Object.keys(tool.signatures).length > 0) || !!tool.signature;
|
|
23325
|
+
if (!hasSignatures) {
|
|
23326
|
+
logger_default.warn(`⚠️ Tool has no signatures: ${toolName}`);
|
|
23327
|
+
if (options.allowUnsigned) {
|
|
23328
|
+
logger_default.warn(` Allowing unsigned tool execution due to allowUnsigned flag (DEV/TEST ONLY)`);
|
|
23329
|
+
return {
|
|
23330
|
+
allowed: true,
|
|
23331
|
+
reason: `Unsigned tool allowed by explicit permission: ${toolName}`,
|
|
23332
|
+
verificationResult: {
|
|
23333
|
+
isValid: false,
|
|
23334
|
+
message: "No signatures found, but execution allowed",
|
|
23335
|
+
validSignatures: 0,
|
|
23336
|
+
totalSignatures: 0,
|
|
23337
|
+
verifiedSigners: [],
|
|
23338
|
+
errors: ["Tool has no signatures but execution was explicitly allowed"]
|
|
23339
|
+
}
|
|
23340
|
+
};
|
|
21296
23341
|
}
|
|
23342
|
+
return {
|
|
23343
|
+
allowed: false,
|
|
23344
|
+
reason: `Tool has no signatures and unsigned execution is not permitted: ${toolName}`,
|
|
23345
|
+
error: {
|
|
23346
|
+
message: `Tool "${toolName}" has no cryptographic signatures. For security, only signed tools can be executed.`,
|
|
23347
|
+
code: "NO_SIGNATURES_FOUND",
|
|
23348
|
+
details: {
|
|
23349
|
+
toolName,
|
|
23350
|
+
hasSignature: !!tool.signature,
|
|
23351
|
+
hasSignatures: !!tool.signatures,
|
|
23352
|
+
signatureCount: tool.signatures ? Object.keys(tool.signatures).length : 0
|
|
23353
|
+
}
|
|
23354
|
+
}
|
|
23355
|
+
};
|
|
21297
23356
|
}
|
|
21298
|
-
|
|
21299
|
-
|
|
21300
|
-
|
|
21301
|
-
|
|
21302
|
-
|
|
21303
|
-
|
|
21304
|
-
|
|
21305
|
-
|
|
21306
|
-
|
|
21307
|
-
|
|
21308
|
-
|
|
21309
|
-
|
|
23357
|
+
try {
|
|
23358
|
+
logger_default.info(`\uD83D\uDD10 Verifying signatures for tool: ${toolName}`);
|
|
23359
|
+
const policyKey = (options.verifyPolicy || "permissive").toUpperCase();
|
|
23360
|
+
const policy = VERIFICATION_POLICIES[policyKey] || VERIFICATION_POLICIES.PERMISSIVE;
|
|
23361
|
+
logger_default.info(` Using verification policy: ${policyKey.toLowerCase()}`);
|
|
23362
|
+
if (policy.minimumSignatures) {
|
|
23363
|
+
logger_default.info(` Minimum signatures required: ${policy.minimumSignatures}`);
|
|
23364
|
+
}
|
|
23365
|
+
if (policy.requireRoles) {
|
|
23366
|
+
logger_default.info(` Required roles: ${policy.requireRoles.join(", ")}`);
|
|
23367
|
+
}
|
|
23368
|
+
const verificationResult = await verifyTool(tool, policy);
|
|
23369
|
+
if (verificationResult.isValid) {
|
|
23370
|
+
logger_default.info(`✅ Signature verification passed for tool: ${toolName}`);
|
|
23371
|
+
logger_default.info(` Valid signatures: ${verificationResult.validSignatures}/${verificationResult.totalSignatures}`);
|
|
23372
|
+
if (verificationResult.verifiedSigners.length > 0) {
|
|
23373
|
+
logger_default.info(` Verified signers: ${verificationResult.verifiedSigners.map((s) => `${s.signer}${s.role ? ` (${s.role})` : ""}`).join(", ")}`);
|
|
23374
|
+
}
|
|
23375
|
+
return {
|
|
23376
|
+
allowed: true,
|
|
23377
|
+
reason: `Tool signature verification passed: ${verificationResult.message}`,
|
|
23378
|
+
verificationResult
|
|
23379
|
+
};
|
|
23380
|
+
} else {
|
|
23381
|
+
logger_default.error(`❌ Signature verification failed for tool: ${toolName}`);
|
|
23382
|
+
logger_default.error(` Policy: ${policyKey.toLowerCase()}`);
|
|
23383
|
+
logger_default.error(` Valid signatures: ${verificationResult.validSignatures}/${verificationResult.totalSignatures}`);
|
|
23384
|
+
if (verificationResult.errors.length > 0) {
|
|
23385
|
+
logger_default.error(` Errors:`);
|
|
23386
|
+
verificationResult.errors.forEach((error) => logger_default.error(` - ${error}`));
|
|
23387
|
+
}
|
|
23388
|
+
return {
|
|
23389
|
+
allowed: false,
|
|
23390
|
+
reason: `Tool signature verification failed: ${verificationResult.message}`,
|
|
23391
|
+
verificationResult,
|
|
23392
|
+
error: {
|
|
23393
|
+
message: `Tool "${toolName}" failed signature verification. ${verificationResult.message}`,
|
|
23394
|
+
code: "SIGNATURE_VERIFICATION_FAILED",
|
|
23395
|
+
details: {
|
|
23396
|
+
toolName,
|
|
23397
|
+
policy: policyKey.toLowerCase(),
|
|
23398
|
+
validSignatures: verificationResult.validSignatures,
|
|
23399
|
+
totalSignatures: verificationResult.totalSignatures,
|
|
23400
|
+
errors: verificationResult.errors,
|
|
23401
|
+
verifiedSigners: verificationResult.verifiedSigners
|
|
21310
23402
|
}
|
|
21311
23403
|
}
|
|
21312
|
-
|
|
21313
|
-
}
|
|
23404
|
+
};
|
|
21314
23405
|
}
|
|
23406
|
+
} catch (error) {
|
|
23407
|
+
const errorMessage = error instanceof Error ? error.message : "Unknown verification error";
|
|
23408
|
+
logger_default.error(`\uD83D\uDCA5 Signature verification error for tool: ${toolName} - ${errorMessage}`);
|
|
23409
|
+
return {
|
|
23410
|
+
allowed: false,
|
|
23411
|
+
reason: `Signature verification error: ${errorMessage}`,
|
|
23412
|
+
error: {
|
|
23413
|
+
message: `Signature verification failed due to error: ${errorMessage}`,
|
|
23414
|
+
code: "VERIFICATION_ERROR",
|
|
23415
|
+
details: { toolName, originalError: error }
|
|
23416
|
+
}
|
|
23417
|
+
};
|
|
21315
23418
|
}
|
|
21316
|
-
return { resolved, missing };
|
|
21317
23419
|
}
|
|
21318
|
-
|
|
23420
|
+
function createVerificationFailureResult(tool, verificationResult, executionId) {
|
|
23421
|
+
return {
|
|
23422
|
+
success: false,
|
|
23423
|
+
error: verificationResult.error || {
|
|
23424
|
+
message: verificationResult.reason,
|
|
23425
|
+
code: "VERIFICATION_FAILED"
|
|
23426
|
+
},
|
|
23427
|
+
metadata: {
|
|
23428
|
+
executionId,
|
|
23429
|
+
toolName: tool.name || "unknown",
|
|
23430
|
+
version: tool.version,
|
|
23431
|
+
executedAt: new Date().toISOString(),
|
|
23432
|
+
environment: "direct",
|
|
23433
|
+
command: tool.command
|
|
23434
|
+
}
|
|
23435
|
+
};
|
|
23436
|
+
}
|
|
23437
|
+
function logSecurityAudit(tool, verificationResult, executionAllowed, options) {
|
|
23438
|
+
const auditLog = {
|
|
23439
|
+
timestamp: new Date().toISOString(),
|
|
23440
|
+
tool: tool.name || "unknown",
|
|
23441
|
+
version: tool.version,
|
|
23442
|
+
command: tool.command,
|
|
23443
|
+
executionAllowed,
|
|
23444
|
+
verificationSkipped: options.skipVerification || false,
|
|
23445
|
+
verificationPolicy: options.verifyPolicy || "permissive",
|
|
23446
|
+
verificationResult: verificationResult.verificationResult ? {
|
|
23447
|
+
isValid: verificationResult.verificationResult.isValid,
|
|
23448
|
+
validSignatures: verificationResult.verificationResult.validSignatures,
|
|
23449
|
+
totalSignatures: verificationResult.verificationResult.totalSignatures,
|
|
23450
|
+
verifiedSigners: verificationResult.verificationResult.verifiedSigners
|
|
23451
|
+
} : null,
|
|
23452
|
+
errors: verificationResult.error ? [verificationResult.error.message] : []
|
|
23453
|
+
};
|
|
23454
|
+
logger_default.info(`\uD83D\uDD0D Security Audit Log:`, auditLog);
|
|
23455
|
+
}
|
|
21319
23456
|
|
|
21320
23457
|
// src/core/EnactCore.ts
|
|
21321
|
-
|
|
23458
|
+
import fs2 from "fs";
|
|
23459
|
+
import path2 from "path";
|
|
23460
|
+
var __dirname = "/Users/keithgroves/projects/keithagroves/enact-project/enact-cli/src/core";
|
|
21322
23461
|
|
|
21323
23462
|
class EnactCore {
|
|
21324
23463
|
apiClient;
|
|
@@ -21365,9 +23504,48 @@ class EnactCore {
|
|
|
21365
23504
|
return tools;
|
|
21366
23505
|
} catch (error) {
|
|
21367
23506
|
logger_default.error("Error searching tools:", error);
|
|
23507
|
+
if (error instanceof Error && error.message.includes("502")) {
|
|
23508
|
+
logger_default.info("Search API unavailable, trying fallback to local filtering...");
|
|
23509
|
+
return this.searchToolsFallback(options);
|
|
23510
|
+
}
|
|
21368
23511
|
throw new Error(`Search failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
21369
23512
|
}
|
|
21370
23513
|
}
|
|
23514
|
+
async searchToolsFallback(options) {
|
|
23515
|
+
try {
|
|
23516
|
+
logger_default.info("Using fallback search method...");
|
|
23517
|
+
const allTools = await this.apiClient.getTools({
|
|
23518
|
+
limit: options.limit || 100
|
|
23519
|
+
});
|
|
23520
|
+
const filteredTools = [];
|
|
23521
|
+
const query = options.query.toLowerCase();
|
|
23522
|
+
for (const result of allTools) {
|
|
23523
|
+
if (result.name) {
|
|
23524
|
+
try {
|
|
23525
|
+
const tool = await this.getToolByName(result.name);
|
|
23526
|
+
if (tool) {
|
|
23527
|
+
const matchesQuery = tool.name.toLowerCase().includes(query) || tool.description && tool.description.toLowerCase().includes(query) || tool.tags && tool.tags.some((tag) => tag.toLowerCase().includes(query));
|
|
23528
|
+
const matchesTags = !options.tags || !options.tags.length || tool.tags && options.tags.some((searchTag) => tool.tags.some((toolTag) => toolTag.toLowerCase().includes(searchTag.toLowerCase())));
|
|
23529
|
+
const matchesAuthor = !options.author || tool.authors && tool.authors.some((author) => author.name && author.name.toLowerCase().includes(options.author.toLowerCase()));
|
|
23530
|
+
if (matchesQuery && matchesTags && matchesAuthor) {
|
|
23531
|
+
filteredTools.push(tool);
|
|
23532
|
+
if (options.limit && filteredTools.length >= options.limit) {
|
|
23533
|
+
break;
|
|
23534
|
+
}
|
|
23535
|
+
}
|
|
23536
|
+
}
|
|
23537
|
+
} catch (error) {
|
|
23538
|
+
logger_default.warn(`Failed to fetch tool ${result.name} in fallback search:`, error);
|
|
23539
|
+
}
|
|
23540
|
+
}
|
|
23541
|
+
}
|
|
23542
|
+
logger_default.info(`Fallback search found ${filteredTools.length} tools`);
|
|
23543
|
+
return filteredTools;
|
|
23544
|
+
} catch (fallbackError) {
|
|
23545
|
+
logger_default.error("Fallback search also failed:", fallbackError);
|
|
23546
|
+
throw new Error(`Search failed (including fallback): ${fallbackError instanceof Error ? fallbackError.message : String(fallbackError)}`);
|
|
23547
|
+
}
|
|
23548
|
+
}
|
|
21371
23549
|
async getToolByName(name, version) {
|
|
21372
23550
|
try {
|
|
21373
23551
|
logger_default.info(`Fetching tool: ${name}${version ? `@${version}` : ""}`);
|
|
@@ -21378,12 +23556,12 @@ class EnactCore {
|
|
|
21378
23556
|
}
|
|
21379
23557
|
let tool;
|
|
21380
23558
|
if (response.content && typeof response.content === "string") {
|
|
21381
|
-
tool =
|
|
23559
|
+
tool = import_yaml2.default.parse(response.content);
|
|
21382
23560
|
} else if (response.raw_content && typeof response.raw_content === "string") {
|
|
21383
23561
|
try {
|
|
21384
23562
|
tool = JSON.parse(response.raw_content);
|
|
21385
23563
|
} catch {
|
|
21386
|
-
tool =
|
|
23564
|
+
tool = import_yaml2.default.parse(response.raw_content);
|
|
21387
23565
|
}
|
|
21388
23566
|
if (response.signature || response.signatures) {
|
|
21389
23567
|
tool.signature = response.signature;
|
|
@@ -21462,25 +23640,19 @@ class EnactCore {
|
|
|
21462
23640
|
try {
|
|
21463
23641
|
logger_default.info(`Executing tool: ${tool.name}`);
|
|
21464
23642
|
validateToolStructure(tool);
|
|
21465
|
-
|
|
21466
|
-
|
|
21467
|
-
|
|
21468
|
-
|
|
21469
|
-
|
|
21470
|
-
|
|
21471
|
-
|
|
21472
|
-
|
|
21473
|
-
|
|
21474
|
-
|
|
21475
|
-
|
|
21476
|
-
|
|
21477
|
-
|
|
21478
|
-
executedAt: new Date().toISOString(),
|
|
21479
|
-
environment: "direct",
|
|
21480
|
-
command: tool.command
|
|
21481
|
-
}
|
|
21482
|
-
};
|
|
21483
|
-
}
|
|
23643
|
+
const verificationResult = await enforceSignatureVerification(tool, {
|
|
23644
|
+
skipVerification: options.skipVerification,
|
|
23645
|
+
verifyPolicy: options.verifyPolicy,
|
|
23646
|
+
force: options.force,
|
|
23647
|
+
allowUnsigned: false
|
|
23648
|
+
});
|
|
23649
|
+
logSecurityAudit(tool, verificationResult, verificationResult.allowed, {
|
|
23650
|
+
skipVerification: options.skipVerification,
|
|
23651
|
+
verifyPolicy: options.verifyPolicy,
|
|
23652
|
+
force: options.force
|
|
23653
|
+
});
|
|
23654
|
+
if (!verificationResult.allowed) {
|
|
23655
|
+
return createVerificationFailureResult(tool, verificationResult, executionId);
|
|
21484
23656
|
}
|
|
21485
23657
|
const validatedInputs = validateInputs(tool, inputs);
|
|
21486
23658
|
const safetyCheck = verifyCommandSafety(tool.command, tool);
|
|
@@ -21576,7 +23748,7 @@ class EnactCore {
|
|
|
21576
23748
|
}
|
|
21577
23749
|
async executeRawTool(toolYaml, inputs = {}, options = {}) {
|
|
21578
23750
|
try {
|
|
21579
|
-
const tool =
|
|
23751
|
+
const tool = import_yaml2.default.parse(toolYaml);
|
|
21580
23752
|
if (!tool || typeof tool !== "object") {
|
|
21581
23753
|
throw new Error("Invalid tool definition: YAML must contain a tool object");
|
|
21582
23754
|
}
|
|
@@ -21612,7 +23784,32 @@ class EnactCore {
|
|
|
21612
23784
|
errors: [`Tool not found: ${name}`]
|
|
21613
23785
|
};
|
|
21614
23786
|
}
|
|
21615
|
-
|
|
23787
|
+
let publicKey;
|
|
23788
|
+
try {
|
|
23789
|
+
const keyPath = path2.resolve(__dirname, "../../keys/file-public.pem");
|
|
23790
|
+
publicKey = fs2.readFileSync(keyPath, "utf8");
|
|
23791
|
+
} catch (e) {
|
|
23792
|
+
logger_default.warn("Could not load public key for signature verification:", e);
|
|
23793
|
+
}
|
|
23794
|
+
if (!publicKey) {
|
|
23795
|
+
return {
|
|
23796
|
+
verified: false,
|
|
23797
|
+
signatures: [],
|
|
23798
|
+
policy: policy || "permissive",
|
|
23799
|
+
errors: ["Public key not found for signature verification"]
|
|
23800
|
+
};
|
|
23801
|
+
}
|
|
23802
|
+
const policyKey = (policy || "permissive").toUpperCase();
|
|
23803
|
+
const policyObj = VERIFICATION_POLICIES[policyKey];
|
|
23804
|
+
const verificationResult = await verifyTool(tool, policyObj);
|
|
23805
|
+
if (!verificationResult.isValid) {
|
|
23806
|
+
return {
|
|
23807
|
+
verified: false,
|
|
23808
|
+
signatures: [],
|
|
23809
|
+
policy: policy || "permissive",
|
|
23810
|
+
errors: verificationResult.errors
|
|
23811
|
+
};
|
|
23812
|
+
}
|
|
21616
23813
|
const signatures = [];
|
|
21617
23814
|
if (tool.signature) {
|
|
21618
23815
|
signatures.push(tool.signature);
|
|
@@ -21621,7 +23818,7 @@ class EnactCore {
|
|
|
21621
23818
|
signatures.push(...Object.values(tool.signatures));
|
|
21622
23819
|
}
|
|
21623
23820
|
return {
|
|
21624
|
-
verified,
|
|
23821
|
+
verified: verificationResult.isValid,
|
|
21625
23822
|
signatures,
|
|
21626
23823
|
policy: policy || "permissive"
|
|
21627
23824
|
};
|
|
@@ -21724,6 +23921,9 @@ class EnactCore {
|
|
|
21724
23921
|
}
|
|
21725
23922
|
var enactCore = new EnactCore;
|
|
21726
23923
|
|
|
23924
|
+
// src/mcp-server.ts
|
|
23925
|
+
init_logger();
|
|
23926
|
+
|
|
21727
23927
|
// src/utils/silent-monitor.ts
|
|
21728
23928
|
class McpSilentOperationMonitor {
|
|
21729
23929
|
isMonitoring = false;
|
|
@@ -21861,6 +24061,8 @@ function validateSilentEnvironment() {
|
|
|
21861
24061
|
}
|
|
21862
24062
|
|
|
21863
24063
|
// src/mcp-server.ts
|
|
24064
|
+
init_env_manager_server();
|
|
24065
|
+
init_env_loader();
|
|
21864
24066
|
process.env.CI = process.env.CI || "true";
|
|
21865
24067
|
process.env.ENACT_SKIP_INTERACTIVE = process.env.ENACT_SKIP_INTERACTIVE || "true";
|
|
21866
24068
|
if (true) {
|
|
@@ -21875,7 +24077,8 @@ var enactCore2 = new EnactCore({
|
|
|
21875
24077
|
supabaseUrl: process.env.ENACT_SUPABASE_URL || "https://xjnhhxwxovjifdxdwzih.supabase.co",
|
|
21876
24078
|
executionProvider: "direct",
|
|
21877
24079
|
verificationPolicy: process.env.ENACT_VERIFY_POLICY || "permissive",
|
|
21878
|
-
authToken: process.env.ENACT_AUTH_TOKEN
|
|
24080
|
+
authToken: process.env.ENACT_AUTH_TOKEN,
|
|
24081
|
+
defaultTimeout: "120s"
|
|
21879
24082
|
});
|
|
21880
24083
|
var server = new McpServer({
|
|
21881
24084
|
name: "enact-mcp-server",
|
|
@@ -21887,6 +24090,9 @@ var server = new McpServer({
|
|
|
21887
24090
|
}
|
|
21888
24091
|
}
|
|
21889
24092
|
});
|
|
24093
|
+
var runningOperations = new Map;
|
|
24094
|
+
var webServerPort = null;
|
|
24095
|
+
var webServerInstance = null;
|
|
21890
24096
|
function safeJsonStringify(obj, fallback = "Unable to stringify object") {
|
|
21891
24097
|
try {
|
|
21892
24098
|
return JSON.stringify(obj, null, 2);
|
|
@@ -21895,6 +24101,351 @@ function safeJsonStringify(obj, fallback = "Unable to stringify object") {
|
|
|
21895
24101
|
return fallback;
|
|
21896
24102
|
}
|
|
21897
24103
|
}
|
|
24104
|
+
async function validateMcpToolEnvironmentVariables(toolName, toolEnv) {
|
|
24105
|
+
if (!toolEnv || Object.keys(toolEnv).length === 0) {
|
|
24106
|
+
return { valid: true };
|
|
24107
|
+
}
|
|
24108
|
+
try {
|
|
24109
|
+
const { resolved: envVars } = await resolveToolEnvironmentVariables(toolName, toolEnv);
|
|
24110
|
+
const validation = validateRequiredEnvironmentVariables(toolEnv, envVars);
|
|
24111
|
+
if (!validation.valid) {
|
|
24112
|
+
let errorMessage = `❌ Missing required environment variables:
|
|
24113
|
+
|
|
24114
|
+
`;
|
|
24115
|
+
validation.missing.forEach((varName) => {
|
|
24116
|
+
const config = toolEnv[varName];
|
|
24117
|
+
const description = config?.description ? ` - ${config.description}` : "";
|
|
24118
|
+
const source = config?.source ? ` (source: ${config.source})` : "";
|
|
24119
|
+
const required = config?.required ? " [REQUIRED]" : "";
|
|
24120
|
+
errorMessage += ` • ${varName}${required}${description}${source}
|
|
24121
|
+
`;
|
|
24122
|
+
});
|
|
24123
|
+
errorMessage += `
|
|
24124
|
+
\uD83D\uDCA1 You can set environment variables using:
|
|
24125
|
+
`;
|
|
24126
|
+
errorMessage += ` • enact env set <package> <VAR_NAME> <value> # Package-managed (shared)
|
|
24127
|
+
`;
|
|
24128
|
+
errorMessage += ` • enact env set <package> <VAR_NAME> --encrypt # For sensitive values
|
|
24129
|
+
`;
|
|
24130
|
+
errorMessage += ` • enact env set <VAR_NAME> <value> --project # Project-specific (.env file)
|
|
24131
|
+
`;
|
|
24132
|
+
const configLink = generateConfigLink(validation.missing, toolName);
|
|
24133
|
+
if (configLink) {
|
|
24134
|
+
errorMessage += `
|
|
24135
|
+
\uD83C\uDF10 Or use the web interface to configure all missing variables:
|
|
24136
|
+
`;
|
|
24137
|
+
errorMessage += ` ${configLink}
|
|
24138
|
+
`;
|
|
24139
|
+
}
|
|
24140
|
+
errorMessage += `
|
|
24141
|
+
⚠️ Execution aborted due to missing environment variables.`;
|
|
24142
|
+
return {
|
|
24143
|
+
valid: false,
|
|
24144
|
+
errorMessage
|
|
24145
|
+
};
|
|
24146
|
+
}
|
|
24147
|
+
return { valid: true };
|
|
24148
|
+
} catch (error) {
|
|
24149
|
+
logger_default.error("Failed to validate environment variables:", error);
|
|
24150
|
+
return {
|
|
24151
|
+
valid: false,
|
|
24152
|
+
errorMessage: `❌ Failed to validate environment variables: ${error instanceof Error ? error.message : String(error)}`
|
|
24153
|
+
};
|
|
24154
|
+
}
|
|
24155
|
+
}
|
|
24156
|
+
server.registerTool("execute-tool-by-name-async", {
|
|
24157
|
+
title: "Execute Enact Tool (Async)",
|
|
24158
|
+
description: "Execute an Enact tool by its name using direct core integration with background execution for long-running operations",
|
|
24159
|
+
inputSchema: {
|
|
24160
|
+
name: exports_external.string().describe("Name of the tool to execute"),
|
|
24161
|
+
inputs: exports_external.record(exports_external.any()).optional().describe("Input parameters for the tool"),
|
|
24162
|
+
timeout: exports_external.string().optional().describe("Execution timeout"),
|
|
24163
|
+
verifyPolicy: exports_external.enum(["permissive", "enterprise", "paranoid"]).optional().describe("Verification policy"),
|
|
24164
|
+
skipVerification: exports_external.boolean().optional().describe("Skip signature verification"),
|
|
24165
|
+
force: exports_external.boolean().optional().describe("Force execution"),
|
|
24166
|
+
dryRun: exports_external.boolean().optional().describe("Dry run mode"),
|
|
24167
|
+
verbose: exports_external.boolean().optional().describe("Verbose output"),
|
|
24168
|
+
async: exports_external.boolean().optional().describe("Run in background for long operations")
|
|
24169
|
+
}
|
|
24170
|
+
}, async (params) => {
|
|
24171
|
+
const { name, inputs = {}, timeout, verifyPolicy, skipVerification, force, dryRun, verbose, async = false } = params;
|
|
24172
|
+
try {
|
|
24173
|
+
logger_default.info(`Executing tool ${name} via direct core library`);
|
|
24174
|
+
let tool;
|
|
24175
|
+
try {
|
|
24176
|
+
tool = await enactCore2.getToolByName(name);
|
|
24177
|
+
if (!tool) {
|
|
24178
|
+
return {
|
|
24179
|
+
content: [{
|
|
24180
|
+
type: "text",
|
|
24181
|
+
text: `❌ Tool not found: ${name}`
|
|
24182
|
+
}],
|
|
24183
|
+
isError: true
|
|
24184
|
+
};
|
|
24185
|
+
}
|
|
24186
|
+
} catch (error) {
|
|
24187
|
+
return {
|
|
24188
|
+
content: [{
|
|
24189
|
+
type: "text",
|
|
24190
|
+
text: `❌ Tool not found: ${name}
|
|
24191
|
+
|
|
24192
|
+
Error: ${error instanceof Error ? error.message : String(error)}`
|
|
24193
|
+
}],
|
|
24194
|
+
isError: true
|
|
24195
|
+
};
|
|
24196
|
+
}
|
|
24197
|
+
const envValidation = await validateMcpToolEnvironmentVariables(name, tool.env);
|
|
24198
|
+
if (!envValidation.valid) {
|
|
24199
|
+
return {
|
|
24200
|
+
content: [{
|
|
24201
|
+
type: "text",
|
|
24202
|
+
text: envValidation.errorMessage || "Environment validation failed"
|
|
24203
|
+
}],
|
|
24204
|
+
isError: true
|
|
24205
|
+
};
|
|
24206
|
+
}
|
|
24207
|
+
const isLongRunningTool = name.includes("dagger") || name.includes("docker") || name.includes("build") || async;
|
|
24208
|
+
if (isLongRunningTool) {
|
|
24209
|
+
const operationId = `${name}-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
24210
|
+
const executionPromise = enactCore2.executeToolByName(name, inputs, {
|
|
24211
|
+
timeout: timeout || "300s",
|
|
24212
|
+
verifyPolicy,
|
|
24213
|
+
skipVerification,
|
|
24214
|
+
force,
|
|
24215
|
+
dryRun,
|
|
24216
|
+
verbose
|
|
24217
|
+
});
|
|
24218
|
+
const operation = {
|
|
24219
|
+
id: operationId,
|
|
24220
|
+
name,
|
|
24221
|
+
startTime: new Date,
|
|
24222
|
+
promise: executionPromise,
|
|
24223
|
+
status: "running",
|
|
24224
|
+
result: undefined,
|
|
24225
|
+
error: undefined
|
|
24226
|
+
};
|
|
24227
|
+
runningOperations.set(operationId, operation);
|
|
24228
|
+
executionPromise.then((result2) => {
|
|
24229
|
+
operation.status = "completed";
|
|
24230
|
+
operation.result = result2;
|
|
24231
|
+
logger_default.info(`Background operation completed: ${operationId}`);
|
|
24232
|
+
}).catch((error) => {
|
|
24233
|
+
operation.status = "failed";
|
|
24234
|
+
operation.error = error;
|
|
24235
|
+
logger_default.error(`Background operation failed: ${operationId}`, error);
|
|
24236
|
+
});
|
|
24237
|
+
return {
|
|
24238
|
+
content: [{
|
|
24239
|
+
type: "text",
|
|
24240
|
+
text: `\uD83D\uDE80 Started background execution of tool: ${name}
|
|
24241
|
+
|
|
24242
|
+
Operation ID: ${operationId}
|
|
24243
|
+
Started: ${operation.startTime.toISOString()}
|
|
24244
|
+
|
|
24245
|
+
⏳ This operation is running in the background. Use the "check-operation-status" tool with operation ID "${operationId}" to check progress.
|
|
24246
|
+
|
|
24247
|
+
Estimated completion time: 1-3 minutes for Dagger operations.`
|
|
24248
|
+
}]
|
|
24249
|
+
};
|
|
24250
|
+
}
|
|
24251
|
+
const result = await enactCore2.executeToolByName(name, inputs, {
|
|
24252
|
+
timeout: timeout || "30s",
|
|
24253
|
+
verifyPolicy,
|
|
24254
|
+
skipVerification,
|
|
24255
|
+
force,
|
|
24256
|
+
dryRun,
|
|
24257
|
+
verbose
|
|
24258
|
+
});
|
|
24259
|
+
if (!result.success) {
|
|
24260
|
+
return {
|
|
24261
|
+
content: [{
|
|
24262
|
+
type: "text",
|
|
24263
|
+
text: `❌ Error executing tool ${name}: ${result.error?.message}`
|
|
24264
|
+
}],
|
|
24265
|
+
isError: true
|
|
24266
|
+
};
|
|
24267
|
+
}
|
|
24268
|
+
return {
|
|
24269
|
+
content: [{
|
|
24270
|
+
type: "text",
|
|
24271
|
+
text: `✅ Successfully executed tool ${name}
|
|
24272
|
+
Output: ${safeJsonStringify(result)}`
|
|
24273
|
+
}]
|
|
24274
|
+
};
|
|
24275
|
+
} catch (error) {
|
|
24276
|
+
logger_default.error(`Error executing tool:`, error);
|
|
24277
|
+
if (error instanceof Error && error.message.includes("timed out")) {
|
|
24278
|
+
return {
|
|
24279
|
+
content: [{
|
|
24280
|
+
type: "text",
|
|
24281
|
+
text: `⏰ Tool execution timed out: ${name}
|
|
24282
|
+
|
|
24283
|
+
For long-running operations like Dagger builds, try using the async mode by setting "async": true in your request.
|
|
24284
|
+
|
|
24285
|
+
Original error: ${error.message}`
|
|
24286
|
+
}],
|
|
24287
|
+
isError: true
|
|
24288
|
+
};
|
|
24289
|
+
}
|
|
24290
|
+
return {
|
|
24291
|
+
content: [{
|
|
24292
|
+
type: "text",
|
|
24293
|
+
text: `Internal error executing tool: ${error instanceof Error ? error.message : String(error)}`
|
|
24294
|
+
}],
|
|
24295
|
+
isError: true
|
|
24296
|
+
};
|
|
24297
|
+
}
|
|
24298
|
+
});
|
|
24299
|
+
server.registerTool("check-operation-status", {
|
|
24300
|
+
title: "Check Operation Status",
|
|
24301
|
+
description: "Check the status of a background operation",
|
|
24302
|
+
inputSchema: {
|
|
24303
|
+
operationId: exports_external.string().describe("The operation ID to check")
|
|
24304
|
+
}
|
|
24305
|
+
}, async ({ operationId }) => {
|
|
24306
|
+
try {
|
|
24307
|
+
const operation = runningOperations.get(operationId);
|
|
24308
|
+
if (!operation) {
|
|
24309
|
+
return {
|
|
24310
|
+
content: [{
|
|
24311
|
+
type: "text",
|
|
24312
|
+
text: `❌ Operation not found: ${operationId}
|
|
24313
|
+
|
|
24314
|
+
The operation may have been completed and cleaned up, or the ID is incorrect.`
|
|
24315
|
+
}],
|
|
24316
|
+
isError: true
|
|
24317
|
+
};
|
|
24318
|
+
}
|
|
24319
|
+
const duration = Math.round((Date.now() - operation.startTime.getTime()) / 1000);
|
|
24320
|
+
switch (operation.status) {
|
|
24321
|
+
case "running":
|
|
24322
|
+
return {
|
|
24323
|
+
content: [{
|
|
24324
|
+
type: "text",
|
|
24325
|
+
text: `⏳ Operation Status: RUNNING
|
|
24326
|
+
|
|
24327
|
+
Operation ID: ${operationId}
|
|
24328
|
+
Tool: ${operation.name}
|
|
24329
|
+
Started: ${operation.startTime.toISOString()}
|
|
24330
|
+
Duration: ${duration} seconds
|
|
24331
|
+
|
|
24332
|
+
The operation is still running. Please check again in a moment.`
|
|
24333
|
+
}]
|
|
24334
|
+
};
|
|
24335
|
+
case "completed":
|
|
24336
|
+
if (!operation.resultFetched) {
|
|
24337
|
+
operation.resultFetched = true;
|
|
24338
|
+
setTimeout(() => {
|
|
24339
|
+
console.log(`[INFO] Cleaning up completed operation: ${operationId}`);
|
|
24340
|
+
runningOperations.delete(operationId);
|
|
24341
|
+
}, 60000);
|
|
24342
|
+
}
|
|
24343
|
+
return {
|
|
24344
|
+
content: [{
|
|
24345
|
+
type: "text",
|
|
24346
|
+
text: `✅ Operation Status: COMPLETED
|
|
24347
|
+
|
|
24348
|
+
Operation ID: ${operationId}
|
|
24349
|
+
Tool: ${operation.name}
|
|
24350
|
+
Started: ${operation.startTime.toISOString()}
|
|
24351
|
+
Duration: ${duration} seconds
|
|
24352
|
+
|
|
24353
|
+
Result:
|
|
24354
|
+
${safeJsonStringify(operation.result)}`
|
|
24355
|
+
}]
|
|
24356
|
+
};
|
|
24357
|
+
case "failed":
|
|
24358
|
+
if (!operation.errorFetched) {
|
|
24359
|
+
operation.errorFetched = true;
|
|
24360
|
+
setTimeout(() => {
|
|
24361
|
+
console.log(`[INFO] Cleaning up failed operation: ${operationId}`);
|
|
24362
|
+
runningOperations.delete(operationId);
|
|
24363
|
+
}, 60000);
|
|
24364
|
+
}
|
|
24365
|
+
return {
|
|
24366
|
+
content: [{
|
|
24367
|
+
type: "text",
|
|
24368
|
+
text: `❌ Operation Status: FAILED
|
|
24369
|
+
|
|
24370
|
+
Operation ID: ${operationId}
|
|
24371
|
+
Tool: ${operation.name}
|
|
24372
|
+
Started: ${operation.startTime.toISOString()}
|
|
24373
|
+
Duration: ${duration} seconds
|
|
24374
|
+
|
|
24375
|
+
Error: ${operation.error instanceof Error ? operation.error.message : String(operation.error)}`
|
|
24376
|
+
}],
|
|
24377
|
+
isError: true
|
|
24378
|
+
};
|
|
24379
|
+
default:
|
|
24380
|
+
return {
|
|
24381
|
+
content: [{
|
|
24382
|
+
type: "text",
|
|
24383
|
+
text: `❓ Unknown operation status: ${operation.status}`
|
|
24384
|
+
}],
|
|
24385
|
+
isError: true
|
|
24386
|
+
};
|
|
24387
|
+
}
|
|
24388
|
+
} catch (error) {
|
|
24389
|
+
logger_default.error(`Error checking operation status:`, error);
|
|
24390
|
+
return {
|
|
24391
|
+
content: [{
|
|
24392
|
+
type: "text",
|
|
24393
|
+
text: `Error checking operation status: ${error instanceof Error ? error.message : String(error)}`
|
|
24394
|
+
}],
|
|
24395
|
+
isError: true
|
|
24396
|
+
};
|
|
24397
|
+
}
|
|
24398
|
+
});
|
|
24399
|
+
server.registerTool("list-operations", {
|
|
24400
|
+
title: "List Operations",
|
|
24401
|
+
description: "List all background operations",
|
|
24402
|
+
inputSchema: {}
|
|
24403
|
+
}, async () => {
|
|
24404
|
+
try {
|
|
24405
|
+
const operations = Array.from(runningOperations.values());
|
|
24406
|
+
if (operations.length === 0) {
|
|
24407
|
+
return {
|
|
24408
|
+
content: [{
|
|
24409
|
+
type: "text",
|
|
24410
|
+
text: `\uD83D\uDCCB No background operations currently running or recently completed.`
|
|
24411
|
+
}]
|
|
24412
|
+
};
|
|
24413
|
+
}
|
|
24414
|
+
let summary = `\uD83D\uDCCB Background Operations (${operations.length} total)
|
|
24415
|
+
|
|
24416
|
+
`;
|
|
24417
|
+
operations.forEach((op) => {
|
|
24418
|
+
const duration = Math.round((Date.now() - op.startTime.getTime()) / 1000);
|
|
24419
|
+
const statusEmoji = op.status === "running" ? "⏳" : op.status === "completed" ? "✅" : "❌";
|
|
24420
|
+
summary += `${statusEmoji} ${op.id}
|
|
24421
|
+
`;
|
|
24422
|
+
summary += ` Tool: ${op.name}
|
|
24423
|
+
`;
|
|
24424
|
+
summary += ` Status: ${op.status.toUpperCase()}
|
|
24425
|
+
`;
|
|
24426
|
+
summary += ` Duration: ${duration}s
|
|
24427
|
+
`;
|
|
24428
|
+
summary += ` Started: ${op.startTime.toISOString()}
|
|
24429
|
+
|
|
24430
|
+
`;
|
|
24431
|
+
});
|
|
24432
|
+
return {
|
|
24433
|
+
content: [{
|
|
24434
|
+
type: "text",
|
|
24435
|
+
text: summary
|
|
24436
|
+
}]
|
|
24437
|
+
};
|
|
24438
|
+
} catch (error) {
|
|
24439
|
+
logger_default.error(`Error listing operations:`, error);
|
|
24440
|
+
return {
|
|
24441
|
+
content: [{
|
|
24442
|
+
type: "text",
|
|
24443
|
+
text: `Error listing operations: ${error instanceof Error ? error.message : String(error)}`
|
|
24444
|
+
}],
|
|
24445
|
+
isError: true
|
|
24446
|
+
};
|
|
24447
|
+
}
|
|
24448
|
+
});
|
|
21898
24449
|
server.registerTool("execute-tool-by-name", {
|
|
21899
24450
|
title: "Execute Enact Tool",
|
|
21900
24451
|
description: "Execute an Enact tool by its name using direct core integration",
|
|
@@ -21912,8 +24463,45 @@ server.registerTool("execute-tool-by-name", {
|
|
|
21912
24463
|
const { name, inputs = {}, timeout, verifyPolicy, skipVerification, force, dryRun, verbose } = params;
|
|
21913
24464
|
try {
|
|
21914
24465
|
logger_default.info(`Executing tool ${name} via direct core library`);
|
|
24466
|
+
let tool;
|
|
24467
|
+
try {
|
|
24468
|
+
tool = await enactCore2.getToolByName(name);
|
|
24469
|
+
if (!tool) {
|
|
24470
|
+
return {
|
|
24471
|
+
content: [{
|
|
24472
|
+
type: "text",
|
|
24473
|
+
text: `❌ Tool not found: ${name}`
|
|
24474
|
+
}],
|
|
24475
|
+
isError: true
|
|
24476
|
+
};
|
|
24477
|
+
}
|
|
24478
|
+
} catch (error) {
|
|
24479
|
+
return {
|
|
24480
|
+
content: [{
|
|
24481
|
+
type: "text",
|
|
24482
|
+
text: `❌ Tool not found: ${name}
|
|
24483
|
+
|
|
24484
|
+
Error: ${error instanceof Error ? error.message : String(error)}`
|
|
24485
|
+
}],
|
|
24486
|
+
isError: true
|
|
24487
|
+
};
|
|
24488
|
+
}
|
|
24489
|
+
const envValidation = await validateMcpToolEnvironmentVariables(name, tool.env);
|
|
24490
|
+
if (!envValidation.valid) {
|
|
24491
|
+
return {
|
|
24492
|
+
content: [{
|
|
24493
|
+
type: "text",
|
|
24494
|
+
text: envValidation.errorMessage || "Environment validation failed"
|
|
24495
|
+
}],
|
|
24496
|
+
isError: true
|
|
24497
|
+
};
|
|
24498
|
+
}
|
|
24499
|
+
const isLongRunningTool = name.includes("dagger") || name.includes("docker") || name.includes("build");
|
|
24500
|
+
if (isLongRunningTool) {
|
|
24501
|
+
logger_default.info(`⏳ Starting long-running operation: ${name} (this may take 1-2 minutes)`);
|
|
24502
|
+
}
|
|
21915
24503
|
const result = await enactCore2.executeToolByName(name, inputs, {
|
|
21916
|
-
timeout,
|
|
24504
|
+
timeout: timeout || "120s",
|
|
21917
24505
|
verifyPolicy,
|
|
21918
24506
|
skipVerification,
|
|
21919
24507
|
force,
|
|
@@ -21938,6 +24526,23 @@ Output: ${safeJsonStringify(result)}`
|
|
|
21938
24526
|
};
|
|
21939
24527
|
} catch (error) {
|
|
21940
24528
|
logger_default.error(`Error executing tool:`, error);
|
|
24529
|
+
if (error instanceof Error && error.message.includes("timed out")) {
|
|
24530
|
+
return {
|
|
24531
|
+
content: [{
|
|
24532
|
+
type: "text",
|
|
24533
|
+
text: `⏰ Tool execution timed out: ${name}
|
|
24534
|
+
|
|
24535
|
+
This may happen with long-running operations like Dagger builds. The operation may still be running in the background. Consider:
|
|
24536
|
+
|
|
24537
|
+
1. Running the tool directly from CLI for long operations
|
|
24538
|
+
2. Using smaller, more focused operations
|
|
24539
|
+
3. Checking if the operation completed successfully outside of MCP
|
|
24540
|
+
|
|
24541
|
+
Original error: ${error.message}`
|
|
24542
|
+
}],
|
|
24543
|
+
isError: true
|
|
24544
|
+
};
|
|
24545
|
+
}
|
|
21941
24546
|
return {
|
|
21942
24547
|
content: [{
|
|
21943
24548
|
type: "text",
|
|
@@ -22050,249 +24655,593 @@ server.registerTool("enact-verify-tool", {
|
|
|
22050
24655
|
resultText += `Errors: ${verificationResult.errors.join(", ")}
|
|
22051
24656
|
`;
|
|
22052
24657
|
}
|
|
22053
|
-
resultText += `
|
|
22054
|
-
Full result:
|
|
22055
|
-
${safeJsonStringify(verificationResult)}`;
|
|
22056
|
-
return {
|
|
22057
|
-
content: [{
|
|
22058
|
-
type: "text",
|
|
22059
|
-
text: resultText
|
|
22060
|
-
}],
|
|
22061
|
-
isError: !verificationResult.verified
|
|
22062
|
-
};
|
|
24658
|
+
resultText += `
|
|
24659
|
+
Full result:
|
|
24660
|
+
${safeJsonStringify(verificationResult)}`;
|
|
24661
|
+
return {
|
|
24662
|
+
content: [{
|
|
24663
|
+
type: "text",
|
|
24664
|
+
text: resultText
|
|
24665
|
+
}],
|
|
24666
|
+
isError: !verificationResult.verified
|
|
24667
|
+
};
|
|
24668
|
+
} catch (error) {
|
|
24669
|
+
logger_default.error(`Error verifying tool:`, error);
|
|
24670
|
+
return {
|
|
24671
|
+
content: [{
|
|
24672
|
+
type: "text",
|
|
24673
|
+
text: `Error verifying tool: ${error instanceof Error ? error.message : String(error)}`
|
|
24674
|
+
}],
|
|
24675
|
+
isError: true
|
|
24676
|
+
};
|
|
24677
|
+
}
|
|
24678
|
+
});
|
|
24679
|
+
server.registerTool("enact-get-tools", {
|
|
24680
|
+
title: "Get All Tools",
|
|
24681
|
+
description: "Get all tools with optional filters using direct core integration",
|
|
24682
|
+
inputSchema: {
|
|
24683
|
+
limit: exports_external.number().optional().describe("Maximum number of results"),
|
|
24684
|
+
offset: exports_external.number().optional().describe("Number of results to skip"),
|
|
24685
|
+
tags: exports_external.array(exports_external.string()).optional().describe("Filter by tags"),
|
|
24686
|
+
author: exports_external.string().optional().describe("Filter by author")
|
|
24687
|
+
}
|
|
24688
|
+
}, async ({ limit, offset, tags, author }) => {
|
|
24689
|
+
try {
|
|
24690
|
+
logger_default.info(`Getting tools via direct core library with filters`);
|
|
24691
|
+
const tools = await enactCore2.getTools({ limit, offset, tags, author });
|
|
24692
|
+
return {
|
|
24693
|
+
content: [{
|
|
24694
|
+
type: "text",
|
|
24695
|
+
text: `Found ${tools.length} tools:
|
|
24696
|
+
${safeJsonStringify(tools)}`
|
|
24697
|
+
}]
|
|
24698
|
+
};
|
|
24699
|
+
} catch (error) {
|
|
24700
|
+
logger_default.error(`Error getting tools:`, error);
|
|
24701
|
+
return {
|
|
24702
|
+
content: [{
|
|
24703
|
+
type: "text",
|
|
24704
|
+
text: `Error getting tools: ${error instanceof Error ? error.message : String(error)}`
|
|
24705
|
+
}],
|
|
24706
|
+
isError: true
|
|
24707
|
+
};
|
|
24708
|
+
}
|
|
24709
|
+
});
|
|
24710
|
+
server.registerTool("enact-tool-exists", {
|
|
24711
|
+
title: "Check Tool Existence",
|
|
24712
|
+
description: "Check if a tool exists in the registry using direct core integration",
|
|
24713
|
+
inputSchema: {
|
|
24714
|
+
name: exports_external.string().describe("Name of the tool to check")
|
|
24715
|
+
}
|
|
24716
|
+
}, async ({ name }) => {
|
|
24717
|
+
try {
|
|
24718
|
+
logger_default.info(`Checking tool existence via direct core library: ${name}`);
|
|
24719
|
+
const exists = await enactCore2.toolExists(name);
|
|
24720
|
+
return {
|
|
24721
|
+
content: [{
|
|
24722
|
+
type: "text",
|
|
24723
|
+
text: `✅ Tool "${name}" ${exists ? "exists" : "does not exist"} in the registry.`
|
|
24724
|
+
}]
|
|
24725
|
+
};
|
|
24726
|
+
} catch (error) {
|
|
24727
|
+
logger_default.error(`Error checking if tool exists:`, error);
|
|
24728
|
+
return {
|
|
24729
|
+
content: [{
|
|
24730
|
+
type: "text",
|
|
24731
|
+
text: `Error checking tool existence: ${error instanceof Error ? error.message : String(error)}`
|
|
24732
|
+
}],
|
|
24733
|
+
isError: true
|
|
24734
|
+
};
|
|
24735
|
+
}
|
|
24736
|
+
});
|
|
24737
|
+
server.registerTool("enact-search-and-register-tools", {
|
|
24738
|
+
title: "Search and Register Tools",
|
|
24739
|
+
description: "Search tools and register the first result as a tool using direct core integration with signature verification",
|
|
24740
|
+
inputSchema: {
|
|
24741
|
+
query: exports_external.string().describe("Search query for tools"),
|
|
24742
|
+
limit: exports_external.number().optional().describe("Maximum number of results"),
|
|
24743
|
+
tags: exports_external.array(exports_external.string()).optional().describe("Filter by tags"),
|
|
24744
|
+
author: exports_external.string().optional().describe("Filter by author"),
|
|
24745
|
+
verifyPolicy: exports_external.enum(["permissive", "enterprise", "paranoid"]).optional().describe("Verification policy for signature checking")
|
|
24746
|
+
}
|
|
24747
|
+
}, async ({ query, limit, tags, author, verifyPolicy = "permissive" }) => {
|
|
24748
|
+
try {
|
|
24749
|
+
logger_default.info(`Searching and registering tools via direct core library: "${query}" with policy: ${verifyPolicy}`);
|
|
24750
|
+
const tools = await enactCore2.searchTools({
|
|
24751
|
+
query,
|
|
24752
|
+
limit,
|
|
24753
|
+
tags,
|
|
24754
|
+
author
|
|
24755
|
+
});
|
|
24756
|
+
logger_default.info(`Found ${tools.length} tools matching query "${query}"`);
|
|
24757
|
+
let newlyRegistered = 0;
|
|
24758
|
+
if (tools.length > 0) {
|
|
24759
|
+
const firstTool = tools[0];
|
|
24760
|
+
if (firstTool.name) {
|
|
24761
|
+
try {
|
|
24762
|
+
logger_default.info(`Verifying tool signatures for: ${firstTool.name} with policy: ${verifyPolicy}`);
|
|
24763
|
+
const policyKey = verifyPolicy.toUpperCase();
|
|
24764
|
+
const policy = VERIFICATION_POLICIES[policyKey] || VERIFICATION_POLICIES.PERMISSIVE;
|
|
24765
|
+
const verificationResult = await verifyTool(firstTool, policy);
|
|
24766
|
+
if (!verificationResult.isValid) {
|
|
24767
|
+
logger_default.error(`Tool "${firstTool.name}" signature verification failed: ${verificationResult.message}`);
|
|
24768
|
+
return {
|
|
24769
|
+
content: [{
|
|
24770
|
+
type: "text",
|
|
24771
|
+
text: `❌ Tool "${firstTool.name}" signature verification failed.
|
|
24772
|
+
|
|
24773
|
+
Policy: ${verifyPolicy}
|
|
24774
|
+
Valid signatures: ${verificationResult.validSignatures}/${verificationResult.totalSignatures}
|
|
24775
|
+
|
|
24776
|
+
Errors:
|
|
24777
|
+
${verificationResult.errors.map((e) => ` • ${e}`).join(`
|
|
24778
|
+
`)}
|
|
24779
|
+
|
|
24780
|
+
\uD83D\uDCA1 Use 'enact-register-tool' with a different verification policy or ensure the tool has valid signatures.`
|
|
24781
|
+
}],
|
|
24782
|
+
isError: true
|
|
24783
|
+
};
|
|
24784
|
+
}
|
|
24785
|
+
logger_default.info(`✅ Tool "${firstTool.name}" signature verification passed: ${verificationResult.message}`);
|
|
24786
|
+
await registerDynamicTool(firstTool, {
|
|
24787
|
+
isValid: verificationResult.isValid,
|
|
24788
|
+
message: verificationResult.message,
|
|
24789
|
+
policy: verifyPolicy
|
|
24790
|
+
});
|
|
24791
|
+
newlyRegistered = 1;
|
|
24792
|
+
logger_default.info(`Successfully registered tool: ${firstTool.name}`);
|
|
24793
|
+
} catch (err) {
|
|
24794
|
+
logger_default.error(`Failed to register tool ${firstTool.name}: ${err instanceof Error ? err.message : String(err)}`);
|
|
24795
|
+
}
|
|
24796
|
+
}
|
|
24797
|
+
}
|
|
24798
|
+
return {
|
|
24799
|
+
content: [{
|
|
24800
|
+
type: "text",
|
|
24801
|
+
text: `${newlyRegistered} new tools registered.
|
|
24802
|
+
Found tools:
|
|
24803
|
+
${safeJsonStringify(tools)}`
|
|
24804
|
+
}]
|
|
24805
|
+
};
|
|
24806
|
+
} catch (error) {
|
|
24807
|
+
logger_default.error("Error searching and registering tools:", error);
|
|
24808
|
+
return {
|
|
24809
|
+
content: [{
|
|
24810
|
+
type: "text",
|
|
24811
|
+
text: `Error searching and registering tools: ${error instanceof Error ? error.message : String(error)}`
|
|
24812
|
+
}],
|
|
24813
|
+
isError: true
|
|
24814
|
+
};
|
|
24815
|
+
}
|
|
24816
|
+
});
|
|
24817
|
+
server.registerTool("enact-core-status", {
|
|
24818
|
+
title: "Core Status",
|
|
24819
|
+
description: "Get status and capabilities of the direct core integration",
|
|
24820
|
+
inputSchema: {}
|
|
24821
|
+
}, async () => {
|
|
24822
|
+
try {
|
|
24823
|
+
const status = await enactCore2.getStatus();
|
|
24824
|
+
let statusText = `Enact Core Direct Integration Status
|
|
24825
|
+
`;
|
|
24826
|
+
statusText += `=====================================
|
|
24827
|
+
|
|
24828
|
+
`;
|
|
24829
|
+
statusText += `Integration Mode: Direct Core Library
|
|
24830
|
+
`;
|
|
24831
|
+
statusText += `Execution Provider: ${status.executionProvider}
|
|
24832
|
+
`;
|
|
24833
|
+
statusText += `API URL: ${status.apiUrl}
|
|
24834
|
+
`;
|
|
24835
|
+
statusText += `Verification Policy: ${status.verificationPolicy}
|
|
24836
|
+
`;
|
|
24837
|
+
statusText += `Default Timeout: ${status.defaultTimeout}
|
|
24838
|
+
|
|
24839
|
+
`;
|
|
24840
|
+
statusText += `Available Features:
|
|
24841
|
+
`;
|
|
24842
|
+
statusText += `• ✅ Direct tool execution (no CLI spawning)
|
|
24843
|
+
`;
|
|
24844
|
+
statusText += `• ✅ Signature verification
|
|
24845
|
+
`;
|
|
24846
|
+
statusText += `• ✅ Real-time tool search
|
|
24847
|
+
`;
|
|
24848
|
+
statusText += `• ✅ Tool validation and sanitization
|
|
24849
|
+
`;
|
|
24850
|
+
statusText += `• ✅ Environment variable management
|
|
24851
|
+
`;
|
|
24852
|
+
statusText += `• ✅ Raw YAML tool execution
|
|
24853
|
+
`;
|
|
24854
|
+
statusText += `• ✅ Command safety verification
|
|
24855
|
+
`;
|
|
24856
|
+
statusText += `• ✅ Output schema validation
|
|
24857
|
+
`;
|
|
24858
|
+
statusText += `• \uD83C\uDF10 Web-based environment manager
|
|
24859
|
+
|
|
24860
|
+
`;
|
|
24861
|
+
statusText += `Performance Benefits:
|
|
24862
|
+
`;
|
|
24863
|
+
statusText += `• ⚡ No CLI process spawning overhead
|
|
24864
|
+
`;
|
|
24865
|
+
statusText += `• ⚡ Direct API communication
|
|
24866
|
+
`;
|
|
24867
|
+
statusText += `• ⚡ Shared state and caching
|
|
24868
|
+
`;
|
|
24869
|
+
statusText += `• ⚡ Lower memory footprint
|
|
24870
|
+
`;
|
|
24871
|
+
statusText += `• ⚡ Faster response times
|
|
24872
|
+
`;
|
|
24873
|
+
return {
|
|
24874
|
+
content: [{
|
|
24875
|
+
type: "text",
|
|
24876
|
+
text: statusText
|
|
24877
|
+
}]
|
|
24878
|
+
};
|
|
24879
|
+
} catch (error) {
|
|
24880
|
+
logger_default.error(`Error getting core status:`, error);
|
|
24881
|
+
return {
|
|
24882
|
+
content: [{
|
|
24883
|
+
type: "text",
|
|
24884
|
+
text: `Error getting core status: ${error instanceof Error ? error.message : String(error)}`
|
|
24885
|
+
}],
|
|
24886
|
+
isError: true
|
|
24887
|
+
};
|
|
24888
|
+
}
|
|
24889
|
+
});
|
|
24890
|
+
server.registerTool("launch-env-manager-server", {
|
|
24891
|
+
title: "Launch Environment Manager Server",
|
|
24892
|
+
description: "Start the web-based environment variable manager server asynchronously",
|
|
24893
|
+
inputSchema: {
|
|
24894
|
+
port: exports_external.number().optional().describe("Port to run the server on (default: 5555)"),
|
|
24895
|
+
async: exports_external.boolean().optional().describe("Run in background (default: true)")
|
|
24896
|
+
}
|
|
24897
|
+
}, async ({ port = 5555, async = true }) => {
|
|
24898
|
+
try {
|
|
24899
|
+
if (webServerInstance) {
|
|
24900
|
+
return {
|
|
24901
|
+
content: [{
|
|
24902
|
+
type: "text",
|
|
24903
|
+
text: `\uD83C\uDF10 Environment Manager Server is already running on port ${webServerPort}
|
|
24904
|
+
|
|
24905
|
+
URL: http://localhost:${webServerPort}`
|
|
24906
|
+
}]
|
|
24907
|
+
};
|
|
24908
|
+
}
|
|
24909
|
+
if (async) {
|
|
24910
|
+
const operationId = `web-server-launch-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
24911
|
+
const launchPromise = startEnvManagerServer(port).then(({ server: webServer, port: actualPort }) => {
|
|
24912
|
+
webServerInstance = webServer;
|
|
24913
|
+
webServerPort = actualPort;
|
|
24914
|
+
logger_default.info(`\uD83C\uDF10 Environment Manager available at http://localhost:${actualPort}`);
|
|
24915
|
+
return { server: webServer, port: actualPort };
|
|
24916
|
+
});
|
|
24917
|
+
const operation = {
|
|
24918
|
+
id: operationId,
|
|
24919
|
+
name: "launch-env-manager-server",
|
|
24920
|
+
startTime: new Date,
|
|
24921
|
+
promise: launchPromise,
|
|
24922
|
+
status: "running",
|
|
24923
|
+
result: undefined,
|
|
24924
|
+
error: undefined
|
|
24925
|
+
};
|
|
24926
|
+
runningOperations.set(operationId, operation);
|
|
24927
|
+
launchPromise.then((result) => {
|
|
24928
|
+
operation.status = "completed";
|
|
24929
|
+
operation.result = result;
|
|
24930
|
+
logger_default.info(`Environment Manager Server started successfully on port ${result.port}`);
|
|
24931
|
+
}).catch((error) => {
|
|
24932
|
+
operation.status = "failed";
|
|
24933
|
+
operation.error = error;
|
|
24934
|
+
logger_default.error(`Failed to start Environment Manager Server:`, error);
|
|
24935
|
+
});
|
|
24936
|
+
return {
|
|
24937
|
+
content: [{
|
|
24938
|
+
type: "text",
|
|
24939
|
+
text: `\uD83D\uDE80 Starting Environment Manager Server asynchronously on port ${port}
|
|
24940
|
+
|
|
24941
|
+
Operation ID: ${operationId}
|
|
24942
|
+
Started: ${operation.startTime.toISOString()}
|
|
24943
|
+
|
|
24944
|
+
⏳ Use "check-operation-status" with operation ID "${operationId}" to check when the server is ready.
|
|
24945
|
+
|
|
24946
|
+
Once running, the server will be available at: http://localhost:${port}`
|
|
24947
|
+
}]
|
|
24948
|
+
};
|
|
24949
|
+
} else {
|
|
24950
|
+
const { server: webServer, port: actualPort } = await startEnvManagerServer(port);
|
|
24951
|
+
webServerInstance = webServer;
|
|
24952
|
+
webServerPort = actualPort;
|
|
24953
|
+
return {
|
|
24954
|
+
content: [{
|
|
24955
|
+
type: "text",
|
|
24956
|
+
text: `✅ Environment Manager Server started successfully!
|
|
24957
|
+
|
|
24958
|
+
URL: http://localhost:${actualPort}
|
|
24959
|
+
|
|
24960
|
+
The environment manager allows you to:
|
|
24961
|
+
• View all package namespaces and their environment variables
|
|
24962
|
+
• Add, edit, and delete environment variables
|
|
24963
|
+
• Create new package namespaces
|
|
24964
|
+
• Manage variables following the Enact package structure
|
|
24965
|
+
|
|
24966
|
+
Environment variables are stored in ~/.enact/env/ organized by package namespace.`
|
|
24967
|
+
}]
|
|
24968
|
+
};
|
|
24969
|
+
}
|
|
22063
24970
|
} catch (error) {
|
|
22064
|
-
logger_default.error(`Error
|
|
24971
|
+
logger_default.error(`Error launching Environment Manager Server:`, error);
|
|
22065
24972
|
return {
|
|
22066
24973
|
content: [{
|
|
22067
24974
|
type: "text",
|
|
22068
|
-
text:
|
|
24975
|
+
text: `❌ Error launching Environment Manager Server: ${error instanceof Error ? error.message : String(error)}`
|
|
22069
24976
|
}],
|
|
22070
24977
|
isError: true
|
|
22071
24978
|
};
|
|
22072
24979
|
}
|
|
22073
24980
|
});
|
|
22074
|
-
server.registerTool("
|
|
22075
|
-
title: "
|
|
22076
|
-
description: "
|
|
24981
|
+
server.registerTool("close-env-manager-server", {
|
|
24982
|
+
title: "Close Environment Manager Server",
|
|
24983
|
+
description: "Stop the web-based environment variable manager server",
|
|
22077
24984
|
inputSchema: {
|
|
22078
|
-
|
|
22079
|
-
inputs: exports_external.record(exports_external.any()).optional().describe("Input parameters for the tool"),
|
|
22080
|
-
options: exports_external.record(exports_external.any()).optional().describe("Execution options")
|
|
24985
|
+
force: exports_external.boolean().optional().describe("Force close the server (default: false)")
|
|
22081
24986
|
}
|
|
22082
|
-
}, async ({
|
|
24987
|
+
}, async ({ force = false }) => {
|
|
22083
24988
|
try {
|
|
22084
|
-
|
|
22085
|
-
const result = await enactCore2.executeRawTool(toolYaml, inputs, options);
|
|
22086
|
-
if (!result.success) {
|
|
24989
|
+
if (!webServerInstance) {
|
|
22087
24990
|
return {
|
|
22088
24991
|
content: [{
|
|
22089
24992
|
type: "text",
|
|
22090
|
-
text:
|
|
22091
|
-
}]
|
|
22092
|
-
isError: true
|
|
24993
|
+
text: `ℹ️ Environment Manager Server is not currently running`
|
|
24994
|
+
}]
|
|
22093
24995
|
};
|
|
22094
24996
|
}
|
|
22095
|
-
|
|
22096
|
-
|
|
22097
|
-
|
|
22098
|
-
|
|
22099
|
-
|
|
22100
|
-
|
|
22101
|
-
|
|
24997
|
+
const currentPort = webServerPort;
|
|
24998
|
+
return new Promise((resolve) => {
|
|
24999
|
+
const timeout = force ? 1000 : 5000;
|
|
25000
|
+
const cleanup = () => {
|
|
25001
|
+
webServerInstance = null;
|
|
25002
|
+
webServerPort = null;
|
|
25003
|
+
resolve({
|
|
25004
|
+
content: [{
|
|
25005
|
+
type: "text",
|
|
25006
|
+
text: `✅ Environment Manager Server stopped successfully
|
|
25007
|
+
|
|
25008
|
+
Server was running on port ${currentPort}`
|
|
25009
|
+
}]
|
|
25010
|
+
});
|
|
25011
|
+
};
|
|
25012
|
+
if (force) {
|
|
25013
|
+
webServerInstance.close(cleanup);
|
|
25014
|
+
setTimeout(cleanup, timeout);
|
|
25015
|
+
} else {
|
|
25016
|
+
webServerInstance.close((err) => {
|
|
25017
|
+
if (err) {
|
|
25018
|
+
logger_default.error("Error during graceful shutdown:", err);
|
|
25019
|
+
resolve({
|
|
25020
|
+
content: [{
|
|
25021
|
+
type: "text",
|
|
25022
|
+
text: `⚠️ Server closed with warnings: ${err.message}
|
|
25023
|
+
|
|
25024
|
+
Server was running on port ${currentPort}`
|
|
25025
|
+
}]
|
|
25026
|
+
});
|
|
25027
|
+
} else {
|
|
25028
|
+
cleanup();
|
|
25029
|
+
}
|
|
25030
|
+
});
|
|
25031
|
+
setTimeout(() => {
|
|
25032
|
+
logger_default.warn("Graceful shutdown timeout, forcing close");
|
|
25033
|
+
cleanup();
|
|
25034
|
+
}, timeout);
|
|
25035
|
+
}
|
|
25036
|
+
});
|
|
22102
25037
|
} catch (error) {
|
|
22103
|
-
logger_default.error(`Error
|
|
25038
|
+
logger_default.error(`Error closing Environment Manager Server:`, error);
|
|
22104
25039
|
return {
|
|
22105
25040
|
content: [{
|
|
22106
25041
|
type: "text",
|
|
22107
|
-
text:
|
|
25042
|
+
text: `❌ Error closing Environment Manager Server: ${error instanceof Error ? error.message : String(error)}`
|
|
22108
25043
|
}],
|
|
22109
25044
|
isError: true
|
|
22110
25045
|
};
|
|
22111
25046
|
}
|
|
22112
25047
|
});
|
|
22113
|
-
server.registerTool("
|
|
22114
|
-
title: "Get
|
|
22115
|
-
description: "
|
|
22116
|
-
inputSchema: {
|
|
22117
|
-
|
|
22118
|
-
offset: exports_external.number().optional().describe("Number of results to skip"),
|
|
22119
|
-
tags: exports_external.array(exports_external.string()).optional().describe("Filter by tags"),
|
|
22120
|
-
author: exports_external.string().optional().describe("Filter by author")
|
|
22121
|
-
}
|
|
22122
|
-
}, async ({ limit, offset, tags, author }) => {
|
|
25048
|
+
server.registerTool("get-env-manager-status", {
|
|
25049
|
+
title: "Get Environment Manager Status",
|
|
25050
|
+
description: "Check if the environment manager server is running and get its status",
|
|
25051
|
+
inputSchema: {}
|
|
25052
|
+
}, async () => {
|
|
22123
25053
|
try {
|
|
22124
|
-
|
|
22125
|
-
|
|
25054
|
+
if (!webServerInstance || !webServerPort) {
|
|
25055
|
+
return {
|
|
25056
|
+
content: [{
|
|
25057
|
+
type: "text",
|
|
25058
|
+
text: `\uD83D\uDCCA Environment Manager Server Status: STOPPED
|
|
25059
|
+
|
|
25060
|
+
The server is not currently running.
|
|
25061
|
+
|
|
25062
|
+
\uD83D\uDCA1 Use "launch-env-manager-server" to start the server.`
|
|
25063
|
+
}]
|
|
25064
|
+
};
|
|
25065
|
+
}
|
|
25066
|
+
const isListening = webServerInstance.listening;
|
|
22126
25067
|
return {
|
|
22127
25068
|
content: [{
|
|
22128
25069
|
type: "text",
|
|
22129
|
-
text:
|
|
22130
|
-
|
|
25070
|
+
text: `\uD83D\uDCCA Environment Manager Server Status: ${isListening ? "RUNNING" : "STOPPED"}
|
|
25071
|
+
|
|
25072
|
+
${isListening ? `\uD83C\uDF10 URL: http://localhost:${webServerPort}
|
|
25073
|
+
|
|
25074
|
+
The environment manager allows you to:
|
|
25075
|
+
• View all package namespaces and their environment variables
|
|
25076
|
+
• Add, edit, and delete environment variables
|
|
25077
|
+
• Create new package namespaces
|
|
25078
|
+
• Manage variables following the Enact package structure` : "Server instance exists but is not listening"}
|
|
25079
|
+
|
|
25080
|
+
Environment variables are stored in ~/.enact/env/ organized by package namespace.`
|
|
22131
25081
|
}]
|
|
22132
25082
|
};
|
|
22133
25083
|
} catch (error) {
|
|
22134
|
-
logger_default.error(`Error getting
|
|
25084
|
+
logger_default.error(`Error getting Environment Manager Server status:`, error);
|
|
22135
25085
|
return {
|
|
22136
25086
|
content: [{
|
|
22137
25087
|
type: "text",
|
|
22138
|
-
text:
|
|
25088
|
+
text: `❌ Error getting Environment Manager Server status: ${error instanceof Error ? error.message : String(error)}`
|
|
22139
25089
|
}],
|
|
22140
25090
|
isError: true
|
|
22141
25091
|
};
|
|
22142
25092
|
}
|
|
22143
25093
|
});
|
|
22144
|
-
server.registerTool("
|
|
22145
|
-
title: "
|
|
22146
|
-
description: "
|
|
22147
|
-
inputSchema: {
|
|
22148
|
-
|
|
22149
|
-
}
|
|
22150
|
-
}, async ({ name }) => {
|
|
25094
|
+
server.registerTool("get-env-manager-url", {
|
|
25095
|
+
title: "Get Environment Manager URL",
|
|
25096
|
+
description: "Get the URL for the web-based environment variable manager",
|
|
25097
|
+
inputSchema: {}
|
|
25098
|
+
}, async () => {
|
|
22151
25099
|
try {
|
|
22152
|
-
|
|
22153
|
-
const exists = await enactCore2.toolExists(name);
|
|
25100
|
+
const port = webServerPort || 5555;
|
|
22154
25101
|
return {
|
|
22155
25102
|
content: [{
|
|
22156
25103
|
type: "text",
|
|
22157
|
-
text:
|
|
25104
|
+
text: `\uD83C\uDF10 Environment Manager Web Interface
|
|
25105
|
+
|
|
25106
|
+
URL: http://localhost:${port}
|
|
25107
|
+
|
|
25108
|
+
The environment manager allows you to:
|
|
25109
|
+
• View all package namespaces and their environment variables
|
|
25110
|
+
• Add, edit, and delete environment variables
|
|
25111
|
+
• Create new package namespaces
|
|
25112
|
+
• Manage variables following the Enact package structure
|
|
25113
|
+
|
|
25114
|
+
Environment variables are stored in ~/.enact/env/ organized by package namespace.`
|
|
22158
25115
|
}]
|
|
22159
25116
|
};
|
|
22160
25117
|
} catch (error) {
|
|
22161
|
-
logger_default.error(`Error
|
|
25118
|
+
logger_default.error(`Error getting env manager URL:`, error);
|
|
22162
25119
|
return {
|
|
22163
25120
|
content: [{
|
|
22164
25121
|
type: "text",
|
|
22165
|
-
text: `Error
|
|
25122
|
+
text: `Error getting environment manager URL: ${error instanceof Error ? error.message : String(error)}`
|
|
22166
25123
|
}],
|
|
22167
25124
|
isError: true
|
|
22168
25125
|
};
|
|
22169
25126
|
}
|
|
22170
25127
|
});
|
|
22171
|
-
server.registerTool("
|
|
22172
|
-
title: "
|
|
22173
|
-
description: "
|
|
25128
|
+
server.registerTool("list-package-env-vars", {
|
|
25129
|
+
title: "List Package Environment Variables",
|
|
25130
|
+
description: "List environment variables for a specific package namespace",
|
|
22174
25131
|
inputSchema: {
|
|
22175
|
-
|
|
22176
|
-
limit: exports_external.number().optional().describe("Maximum number of results"),
|
|
22177
|
-
tags: exports_external.array(exports_external.string()).optional().describe("Filter by tags"),
|
|
22178
|
-
author: exports_external.string().optional().describe("Filter by author")
|
|
25132
|
+
namespace: exports_external.string().describe("Package namespace (e.g., 'org/package')")
|
|
22179
25133
|
}
|
|
22180
|
-
}, async ({
|
|
25134
|
+
}, async ({ namespace }) => {
|
|
22181
25135
|
try {
|
|
22182
|
-
|
|
22183
|
-
const
|
|
22184
|
-
|
|
22185
|
-
|
|
22186
|
-
|
|
22187
|
-
|
|
22188
|
-
|
|
22189
|
-
|
|
22190
|
-
|
|
22191
|
-
|
|
22192
|
-
|
|
22193
|
-
|
|
22194
|
-
|
|
22195
|
-
|
|
22196
|
-
|
|
22197
|
-
|
|
22198
|
-
|
|
22199
|
-
|
|
22200
|
-
|
|
25136
|
+
const { getPackageEnvironmentVariables: getPackageEnvironmentVariables2 } = await Promise.resolve().then(() => (init_env_loader(), exports_env_loader));
|
|
25137
|
+
const { package: packageVars } = await getPackageEnvironmentVariables2(namespace);
|
|
25138
|
+
if (Object.keys(packageVars).length === 0) {
|
|
25139
|
+
return {
|
|
25140
|
+
content: [{
|
|
25141
|
+
type: "text",
|
|
25142
|
+
text: `\uD83D\uDCE6 No environment variables found for package namespace: ${namespace}
|
|
25143
|
+
|
|
25144
|
+
Use the web interface at http://localhost:5555 to add variables.`
|
|
25145
|
+
}]
|
|
25146
|
+
};
|
|
25147
|
+
}
|
|
25148
|
+
let result = `\uD83D\uDCE6 Environment Variables for ${namespace}
|
|
25149
|
+
`;
|
|
25150
|
+
result += `${"=".repeat(50)}
|
|
25151
|
+
|
|
25152
|
+
`;
|
|
25153
|
+
for (const [key, info] of Object.entries(packageVars)) {
|
|
25154
|
+
result += `\uD83D\uDD11 ${key}
|
|
25155
|
+
`;
|
|
25156
|
+
result += ` Value: ${info.encrypted ? "[encrypted]" : "[hidden]"}
|
|
25157
|
+
`;
|
|
25158
|
+
if (info.description) {
|
|
25159
|
+
result += ` Description: ${info.description}
|
|
25160
|
+
`;
|
|
22201
25161
|
}
|
|
25162
|
+
result += `
|
|
25163
|
+
`;
|
|
22202
25164
|
}
|
|
25165
|
+
result += `
|
|
25166
|
+
\uD83D\uDCA1 Use the web interface at http://localhost:5555 to view and edit these variables.`;
|
|
22203
25167
|
return {
|
|
22204
25168
|
content: [{
|
|
22205
25169
|
type: "text",
|
|
22206
|
-
text:
|
|
22207
|
-
Found tools:
|
|
22208
|
-
${safeJsonStringify(tools)}`
|
|
25170
|
+
text: result
|
|
22209
25171
|
}]
|
|
22210
25172
|
};
|
|
22211
25173
|
} catch (error) {
|
|
22212
|
-
logger_default.error(
|
|
25174
|
+
logger_default.error(`Error listing package env vars:`, error);
|
|
22213
25175
|
return {
|
|
22214
25176
|
content: [{
|
|
22215
25177
|
type: "text",
|
|
22216
|
-
text: `Error
|
|
25178
|
+
text: `Error listing environment variables: ${error instanceof Error ? error.message : String(error)}`
|
|
22217
25179
|
}],
|
|
22218
25180
|
isError: true
|
|
22219
25181
|
};
|
|
22220
25182
|
}
|
|
22221
25183
|
});
|
|
22222
|
-
server.registerTool("
|
|
22223
|
-
title: "
|
|
22224
|
-
description: "
|
|
25184
|
+
server.registerTool("list-all-package-namespaces", {
|
|
25185
|
+
title: "List All Package Namespaces",
|
|
25186
|
+
description: "List all available package namespaces with environment variables",
|
|
22225
25187
|
inputSchema: {}
|
|
22226
25188
|
}, async () => {
|
|
22227
25189
|
try {
|
|
22228
|
-
const
|
|
22229
|
-
|
|
22230
|
-
|
|
22231
|
-
|
|
25190
|
+
const { getAllPackageNamespaces: getAllPackageNamespaces2 } = await Promise.resolve().then(() => (init_env_manager_server(), exports_env_manager_server));
|
|
25191
|
+
const packages = await getAllPackageNamespaces2();
|
|
25192
|
+
if (packages.length === 0) {
|
|
25193
|
+
return {
|
|
25194
|
+
content: [{
|
|
25195
|
+
type: "text",
|
|
25196
|
+
text: `\uD83D\uDCE6 No package namespaces found
|
|
22232
25197
|
|
|
25198
|
+
Use the web interface at http://localhost:5555 to create and manage packages.`
|
|
25199
|
+
}]
|
|
25200
|
+
};
|
|
25201
|
+
}
|
|
25202
|
+
let result = `\uD83D\uDCE6 Available Package Namespaces
|
|
22233
25203
|
`;
|
|
22234
|
-
|
|
22235
|
-
`;
|
|
22236
|
-
statusText += `Execution Provider: ${status.executionProvider}
|
|
22237
|
-
`;
|
|
22238
|
-
statusText += `API URL: ${status.apiUrl}
|
|
22239
|
-
`;
|
|
22240
|
-
statusText += `Verification Policy: ${status.verificationPolicy}
|
|
22241
|
-
`;
|
|
22242
|
-
statusText += `Default Timeout: ${status.defaultTimeout}
|
|
25204
|
+
result += `${"=".repeat(40)}
|
|
22243
25205
|
|
|
22244
25206
|
`;
|
|
22245
|
-
|
|
22246
|
-
|
|
22247
|
-
|
|
22248
|
-
`;
|
|
22249
|
-
statusText += `• ✅ Signature verification
|
|
22250
|
-
`;
|
|
22251
|
-
statusText += `• ✅ Real-time tool search
|
|
22252
|
-
`;
|
|
22253
|
-
statusText += `• ✅ Tool validation and sanitization
|
|
22254
|
-
`;
|
|
22255
|
-
statusText += `• ✅ Environment variable management
|
|
22256
|
-
`;
|
|
22257
|
-
statusText += `• ✅ Raw YAML tool execution
|
|
25207
|
+
for (const pkg of packages) {
|
|
25208
|
+
const varCount = Object.keys(pkg.variables).length;
|
|
25209
|
+
result += `\uD83C\uDFF7️ ${pkg.namespace}
|
|
22258
25210
|
`;
|
|
22259
|
-
|
|
25211
|
+
result += ` Variables: ${varCount}
|
|
22260
25212
|
`;
|
|
22261
|
-
|
|
25213
|
+
result += ` Path: ${pkg.path}
|
|
22262
25214
|
|
|
22263
25215
|
`;
|
|
22264
|
-
|
|
22265
|
-
|
|
22266
|
-
|
|
22267
|
-
`;
|
|
22268
|
-
statusText += `• ⚡ Direct API communication
|
|
22269
|
-
`;
|
|
22270
|
-
statusText += `• ⚡ Shared state and caching
|
|
22271
|
-
`;
|
|
22272
|
-
statusText += `• ⚡ Lower memory footprint
|
|
22273
|
-
`;
|
|
22274
|
-
statusText += `• ⚡ Faster response times
|
|
22275
|
-
`;
|
|
25216
|
+
}
|
|
25217
|
+
result += `
|
|
25218
|
+
\uD83D\uDCA1 Use the web interface at http://localhost:5555 to manage these packages.`;
|
|
22276
25219
|
return {
|
|
22277
25220
|
content: [{
|
|
22278
25221
|
type: "text",
|
|
22279
|
-
text:
|
|
25222
|
+
text: result
|
|
22280
25223
|
}]
|
|
22281
25224
|
};
|
|
22282
25225
|
} catch (error) {
|
|
22283
|
-
logger_default.error(`Error
|
|
25226
|
+
logger_default.error(`Error listing package namespaces:`, error);
|
|
22284
25227
|
return {
|
|
22285
25228
|
content: [{
|
|
22286
25229
|
type: "text",
|
|
22287
|
-
text: `Error
|
|
25230
|
+
text: `Error listing package namespaces: ${error instanceof Error ? error.message : String(error)}`
|
|
22288
25231
|
}],
|
|
22289
25232
|
isError: true
|
|
22290
25233
|
};
|
|
22291
25234
|
}
|
|
22292
25235
|
});
|
|
22293
|
-
async function registerDynamicTool(tool) {
|
|
25236
|
+
async function registerDynamicTool(tool, verificationInfo) {
|
|
22294
25237
|
const toolName = `enact-${tool.name.replace(/[^a-zA-Z0-9-_]/g, "-")}`;
|
|
22295
|
-
|
|
25238
|
+
let description = tool.description || `Execute ${tool.name} tool`;
|
|
25239
|
+
const status = verificationInfo.isValid ? "✅" : "❌";
|
|
25240
|
+
description += `
|
|
25241
|
+
|
|
25242
|
+
\uD83D\uDD10 Signature Status: ${status} ${verificationInfo.message}`;
|
|
25243
|
+
description += `
|
|
25244
|
+
\uD83D\uDCCB Policy: ${verificationInfo.policy}`;
|
|
22296
25245
|
const inputSchema = {};
|
|
22297
25246
|
if (tool.inputSchema?.properties) {
|
|
22298
25247
|
for (const [key, prop] of Object.entries(tool.inputSchema.properties)) {
|
|
@@ -22355,25 +25304,6 @@ ${safeJsonStringify(result)}`
|
|
|
22355
25304
|
});
|
|
22356
25305
|
server.server.sendToolListChanged();
|
|
22357
25306
|
}
|
|
22358
|
-
async function main() {
|
|
22359
|
-
try {
|
|
22360
|
-
const transport = new StdioServerTransport;
|
|
22361
|
-
await server.connect(transport);
|
|
22362
|
-
logger_default.info("\uD83D\uDE80 Enact MCP Server with Direct Core Integration started successfully");
|
|
22363
|
-
} catch (error) {
|
|
22364
|
-
console.error("❌ Server connection error:", error);
|
|
22365
|
-
if (error instanceof Error) {
|
|
22366
|
-
console.error("Stack trace:", error.stack);
|
|
22367
|
-
}
|
|
22368
|
-
process.exit(1);
|
|
22369
|
-
}
|
|
22370
|
-
}
|
|
22371
|
-
if (__require.main == __require.module) {
|
|
22372
|
-
main().catch((error) => {
|
|
22373
|
-
console.error("❌ Failed to start server:", error);
|
|
22374
|
-
process.exit(1);
|
|
22375
|
-
});
|
|
22376
|
-
}
|
|
22377
25307
|
server.registerTool("enact-get-tools-by-author", {
|
|
22378
25308
|
title: "Get Tools by Author",
|
|
22379
25309
|
description: "Get tools by a specific author using direct core integration",
|
|
@@ -22434,13 +25364,14 @@ ${safeJsonStringify(tools)}`
|
|
|
22434
25364
|
});
|
|
22435
25365
|
server.registerTool("enact-register-tool", {
|
|
22436
25366
|
title: "Register Tool",
|
|
22437
|
-
description: "Register a tool as an MCP tool using direct core integration",
|
|
25367
|
+
description: "Register a tool as an MCP tool using direct core integration with mandatory signature verification",
|
|
22438
25368
|
inputSchema: {
|
|
22439
|
-
name: exports_external.string().describe("Name of the tool to register")
|
|
25369
|
+
name: exports_external.string().describe("Name of the tool to register"),
|
|
25370
|
+
verifyPolicy: exports_external.enum(["permissive", "enterprise", "paranoid"]).optional().describe("Verification policy for signature checking")
|
|
22440
25371
|
}
|
|
22441
|
-
}, async ({ name }) => {
|
|
25372
|
+
}, async ({ name, verifyPolicy = "permissive" }) => {
|
|
22442
25373
|
try {
|
|
22443
|
-
logger_default.info(`Registering tool via direct core library: ${name}`);
|
|
25374
|
+
logger_default.info(`Registering tool via direct core library: ${name} with policy: ${verifyPolicy}`);
|
|
22444
25375
|
const tool = await enactCore2.getToolInfo(name);
|
|
22445
25376
|
if (!tool) {
|
|
22446
25377
|
return {
|
|
@@ -22451,11 +25382,54 @@ server.registerTool("enact-register-tool", {
|
|
|
22451
25382
|
isError: true
|
|
22452
25383
|
};
|
|
22453
25384
|
}
|
|
22454
|
-
|
|
25385
|
+
logger_default.info(`Performing mandatory signature verification for: ${name} with policy: ${verifyPolicy}`);
|
|
25386
|
+
const policyKey = verifyPolicy.toUpperCase();
|
|
25387
|
+
const policy = VERIFICATION_POLICIES[policyKey] || VERIFICATION_POLICIES.PERMISSIVE;
|
|
25388
|
+
const verificationResult = await verifyTool(tool, policy);
|
|
25389
|
+
if (!verificationResult.isValid) {
|
|
25390
|
+
let errorMessage = `❌ Tool "${name}" signature verification failed.
|
|
25391
|
+
|
|
25392
|
+
`;
|
|
25393
|
+
errorMessage += `Policy: ${verifyPolicy}
|
|
25394
|
+
`;
|
|
25395
|
+
errorMessage += `Valid signatures: ${verificationResult.validSignatures}/${verificationResult.totalSignatures}
|
|
25396
|
+
`;
|
|
25397
|
+
if (verificationResult.errors.length > 0) {
|
|
25398
|
+
errorMessage += `
|
|
25399
|
+
Errors:
|
|
25400
|
+
`;
|
|
25401
|
+
verificationResult.errors.forEach((error) => {
|
|
25402
|
+
errorMessage += ` • ${error}
|
|
25403
|
+
`;
|
|
25404
|
+
});
|
|
25405
|
+
}
|
|
25406
|
+
errorMessage += `
|
|
25407
|
+
\uD83D\uDCA1 You can:
|
|
25408
|
+
`;
|
|
25409
|
+
errorMessage += ` • Use a different verification policy (permissive/enterprise/paranoid)
|
|
25410
|
+
`;
|
|
25411
|
+
errorMessage += ` • Verify the tool's signatures manually using 'enact sign verify'
|
|
25412
|
+
`;
|
|
25413
|
+
errorMessage += ` • Ensure the tool has valid cryptographic signatures before registration
|
|
25414
|
+
`;
|
|
25415
|
+
return {
|
|
25416
|
+
content: [{
|
|
25417
|
+
type: "text",
|
|
25418
|
+
text: errorMessage
|
|
25419
|
+
}],
|
|
25420
|
+
isError: true
|
|
25421
|
+
};
|
|
25422
|
+
}
|
|
25423
|
+
logger_default.info(`✅ Tool "${name}" signature verification passed: ${verificationResult.message}`);
|
|
25424
|
+
await registerDynamicTool(tool, {
|
|
25425
|
+
isValid: verificationResult.isValid,
|
|
25426
|
+
message: verificationResult.message,
|
|
25427
|
+
policy: verifyPolicy
|
|
25428
|
+
});
|
|
22455
25429
|
return {
|
|
22456
25430
|
content: [{
|
|
22457
25431
|
type: "text",
|
|
22458
|
-
text: `✅ Successfully registered tool: ${name}`
|
|
25432
|
+
text: `✅ Successfully registered tool: ${name} (signature verified with ${verifyPolicy} policy)`
|
|
22459
25433
|
}]
|
|
22460
25434
|
};
|
|
22461
25435
|
} catch (error) {
|
|
@@ -22514,6 +25488,42 @@ ${safeJsonStringify(allResults)}`
|
|
|
22514
25488
|
};
|
|
22515
25489
|
}
|
|
22516
25490
|
});
|
|
25491
|
+
async function main() {
|
|
25492
|
+
try {
|
|
25493
|
+
process.on("SIGINT", () => {
|
|
25494
|
+
logger_default.info("Received SIGINT, shutting down gracefully...");
|
|
25495
|
+
if (webServerInstance) {
|
|
25496
|
+
logger_default.info("Shutting down web server...");
|
|
25497
|
+
webServerInstance.close();
|
|
25498
|
+
}
|
|
25499
|
+
process.exit(0);
|
|
25500
|
+
});
|
|
25501
|
+
process.on("SIGTERM", () => {
|
|
25502
|
+
logger_default.info("Received SIGTERM, shutting down gracefully...");
|
|
25503
|
+
if (webServerInstance) {
|
|
25504
|
+
logger_default.info("Shutting down web server...");
|
|
25505
|
+
webServerInstance.close();
|
|
25506
|
+
}
|
|
25507
|
+
process.exit(0);
|
|
25508
|
+
});
|
|
25509
|
+
const transport = new StdioServerTransport;
|
|
25510
|
+
await server.connect(transport);
|
|
25511
|
+
logger_default.info("\uD83D\uDE80 Enact MCP Server with Direct Core Integration started successfully");
|
|
25512
|
+
logger_default.info("\uD83D\uDCA1 Use 'launch-env-manager-server' tool to start the web interface for environment management");
|
|
25513
|
+
} catch (error) {
|
|
25514
|
+
console.error("❌ Server connection error:", error);
|
|
25515
|
+
if (error instanceof Error) {
|
|
25516
|
+
console.error("Stack trace:", error.stack);
|
|
25517
|
+
}
|
|
25518
|
+
process.exit(1);
|
|
25519
|
+
}
|
|
25520
|
+
}
|
|
25521
|
+
if (__require.main == __require.module) {
|
|
25522
|
+
main().catch((error) => {
|
|
25523
|
+
console.error("❌ Failed to start server:", error);
|
|
25524
|
+
process.exit(1);
|
|
25525
|
+
});
|
|
25526
|
+
}
|
|
22517
25527
|
export {
|
|
22518
25528
|
server,
|
|
22519
25529
|
enactCore2 as enactCore
|