@mrrlin-dev/mcp 0.4.116 → 0.4.118
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin.cjs +1165 -521
- package/package.json +1 -1
package/dist/bin.cjs
CHANGED
|
@@ -5258,8 +5258,8 @@ var require_utils = __commonJS({
|
|
|
5258
5258
|
}
|
|
5259
5259
|
return ind;
|
|
5260
5260
|
}
|
|
5261
|
-
function removeDotSegments(
|
|
5262
|
-
let input =
|
|
5261
|
+
function removeDotSegments(path33) {
|
|
5262
|
+
let input = path33;
|
|
5263
5263
|
const output3 = [];
|
|
5264
5264
|
let nextSlash = -1;
|
|
5265
5265
|
let len = 0;
|
|
@@ -5668,8 +5668,8 @@ var require_schemes = __commonJS({
|
|
|
5668
5668
|
}
|
|
5669
5669
|
if (wsComponent.resourceName) {
|
|
5670
5670
|
const queryIndex = wsComponent.resourceName.indexOf("?");
|
|
5671
|
-
const
|
|
5672
|
-
wsComponent.path =
|
|
5671
|
+
const path33 = queryIndex === -1 ? wsComponent.resourceName : wsComponent.resourceName.slice(0, queryIndex);
|
|
5672
|
+
wsComponent.path = path33 && path33 !== "/" ? path33 : void 0;
|
|
5673
5673
|
wsComponent.query = queryIndex === -1 ? void 0 : wsComponent.resourceName.slice(queryIndex + 1);
|
|
5674
5674
|
wsComponent.resourceName = void 0;
|
|
5675
5675
|
}
|
|
@@ -9305,7 +9305,7 @@ var require_windows = __commonJS({
|
|
|
9305
9305
|
module2.exports = isexe;
|
|
9306
9306
|
isexe.sync = sync;
|
|
9307
9307
|
var fs16 = require("fs");
|
|
9308
|
-
function checkPathExt(
|
|
9308
|
+
function checkPathExt(path33, options) {
|
|
9309
9309
|
var pathext = options.pathExt !== void 0 ? options.pathExt : process.env.PATHEXT;
|
|
9310
9310
|
if (!pathext) {
|
|
9311
9311
|
return true;
|
|
@@ -9316,25 +9316,25 @@ var require_windows = __commonJS({
|
|
|
9316
9316
|
}
|
|
9317
9317
|
for (var i = 0; i < pathext.length; i++) {
|
|
9318
9318
|
var p = pathext[i].toLowerCase();
|
|
9319
|
-
if (p &&
|
|
9319
|
+
if (p && path33.substr(-p.length).toLowerCase() === p) {
|
|
9320
9320
|
return true;
|
|
9321
9321
|
}
|
|
9322
9322
|
}
|
|
9323
9323
|
return false;
|
|
9324
9324
|
}
|
|
9325
|
-
function checkStat(stat3,
|
|
9325
|
+
function checkStat(stat3, path33, options) {
|
|
9326
9326
|
if (!stat3.isSymbolicLink() && !stat3.isFile()) {
|
|
9327
9327
|
return false;
|
|
9328
9328
|
}
|
|
9329
|
-
return checkPathExt(
|
|
9329
|
+
return checkPathExt(path33, options);
|
|
9330
9330
|
}
|
|
9331
|
-
function isexe(
|
|
9332
|
-
fs16.stat(
|
|
9333
|
-
cb(er, er ? false : checkStat(stat3,
|
|
9331
|
+
function isexe(path33, options, cb) {
|
|
9332
|
+
fs16.stat(path33, function(er, stat3) {
|
|
9333
|
+
cb(er, er ? false : checkStat(stat3, path33, options));
|
|
9334
9334
|
});
|
|
9335
9335
|
}
|
|
9336
|
-
function sync(
|
|
9337
|
-
return checkStat(fs16.statSync(
|
|
9336
|
+
function sync(path33, options) {
|
|
9337
|
+
return checkStat(fs16.statSync(path33), path33, options);
|
|
9338
9338
|
}
|
|
9339
9339
|
}
|
|
9340
9340
|
});
|
|
@@ -9345,13 +9345,13 @@ var require_mode = __commonJS({
|
|
|
9345
9345
|
module2.exports = isexe;
|
|
9346
9346
|
isexe.sync = sync;
|
|
9347
9347
|
var fs16 = require("fs");
|
|
9348
|
-
function isexe(
|
|
9349
|
-
fs16.stat(
|
|
9348
|
+
function isexe(path33, options, cb) {
|
|
9349
|
+
fs16.stat(path33, function(er, stat3) {
|
|
9350
9350
|
cb(er, er ? false : checkStat(stat3, options));
|
|
9351
9351
|
});
|
|
9352
9352
|
}
|
|
9353
|
-
function sync(
|
|
9354
|
-
return checkStat(fs16.statSync(
|
|
9353
|
+
function sync(path33, options) {
|
|
9354
|
+
return checkStat(fs16.statSync(path33), options);
|
|
9355
9355
|
}
|
|
9356
9356
|
function checkStat(stat3, options) {
|
|
9357
9357
|
return stat3.isFile() && checkMode(stat3, options);
|
|
@@ -9384,7 +9384,7 @@ var require_isexe = __commonJS({
|
|
|
9384
9384
|
}
|
|
9385
9385
|
module2.exports = isexe;
|
|
9386
9386
|
isexe.sync = sync;
|
|
9387
|
-
function isexe(
|
|
9387
|
+
function isexe(path33, options, cb) {
|
|
9388
9388
|
if (typeof options === "function") {
|
|
9389
9389
|
cb = options;
|
|
9390
9390
|
options = {};
|
|
@@ -9394,7 +9394,7 @@ var require_isexe = __commonJS({
|
|
|
9394
9394
|
throw new TypeError("callback not provided");
|
|
9395
9395
|
}
|
|
9396
9396
|
return new Promise(function(resolve2, reject) {
|
|
9397
|
-
isexe(
|
|
9397
|
+
isexe(path33, options || {}, function(er, is) {
|
|
9398
9398
|
if (er) {
|
|
9399
9399
|
reject(er);
|
|
9400
9400
|
} else {
|
|
@@ -9403,7 +9403,7 @@ var require_isexe = __commonJS({
|
|
|
9403
9403
|
});
|
|
9404
9404
|
});
|
|
9405
9405
|
}
|
|
9406
|
-
core(
|
|
9406
|
+
core(path33, options || {}, function(er, is) {
|
|
9407
9407
|
if (er) {
|
|
9408
9408
|
if (er.code === "EACCES" || options && options.ignoreErrors) {
|
|
9409
9409
|
er = null;
|
|
@@ -9413,9 +9413,9 @@ var require_isexe = __commonJS({
|
|
|
9413
9413
|
cb(er, is);
|
|
9414
9414
|
});
|
|
9415
9415
|
}
|
|
9416
|
-
function sync(
|
|
9416
|
+
function sync(path33, options) {
|
|
9417
9417
|
try {
|
|
9418
|
-
return core.sync(
|
|
9418
|
+
return core.sync(path33, options || {});
|
|
9419
9419
|
} catch (er) {
|
|
9420
9420
|
if (options && options.ignoreErrors || er.code === "EACCES") {
|
|
9421
9421
|
return false;
|
|
@@ -9431,7 +9431,7 @@ var require_isexe = __commonJS({
|
|
|
9431
9431
|
var require_which = __commonJS({
|
|
9432
9432
|
"../../node_modules/.pnpm/which@2.0.2/node_modules/which/which.js"(exports2, module2) {
|
|
9433
9433
|
var isWindows = process.platform === "win32" || process.env.OSTYPE === "cygwin" || process.env.OSTYPE === "msys";
|
|
9434
|
-
var
|
|
9434
|
+
var path33 = require("path");
|
|
9435
9435
|
var COLON = isWindows ? ";" : ":";
|
|
9436
9436
|
var isexe = require_isexe();
|
|
9437
9437
|
var getNotFoundError = (cmd) => Object.assign(new Error(`not found: ${cmd}`), { code: "ENOENT" });
|
|
@@ -9469,7 +9469,7 @@ var require_which = __commonJS({
|
|
|
9469
9469
|
return opt.all && found.length ? resolve2(found) : reject(getNotFoundError(cmd));
|
|
9470
9470
|
const ppRaw = pathEnv[i];
|
|
9471
9471
|
const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw;
|
|
9472
|
-
const pCmd =
|
|
9472
|
+
const pCmd = path33.join(pathPart, cmd);
|
|
9473
9473
|
const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd;
|
|
9474
9474
|
resolve2(subStep(p, i, 0));
|
|
9475
9475
|
});
|
|
@@ -9496,7 +9496,7 @@ var require_which = __commonJS({
|
|
|
9496
9496
|
for (let i = 0; i < pathEnv.length; i++) {
|
|
9497
9497
|
const ppRaw = pathEnv[i];
|
|
9498
9498
|
const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw;
|
|
9499
|
-
const pCmd =
|
|
9499
|
+
const pCmd = path33.join(pathPart, cmd);
|
|
9500
9500
|
const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd;
|
|
9501
9501
|
for (let j = 0; j < pathExt.length; j++) {
|
|
9502
9502
|
const cur = p + pathExt[j];
|
|
@@ -9544,7 +9544,7 @@ var require_path_key = __commonJS({
|
|
|
9544
9544
|
var require_resolveCommand = __commonJS({
|
|
9545
9545
|
"../../node_modules/.pnpm/cross-spawn@7.0.6/node_modules/cross-spawn/lib/util/resolveCommand.js"(exports2, module2) {
|
|
9546
9546
|
"use strict";
|
|
9547
|
-
var
|
|
9547
|
+
var path33 = require("path");
|
|
9548
9548
|
var which = require_which();
|
|
9549
9549
|
var getPathKey = require_path_key();
|
|
9550
9550
|
function resolveCommandAttempt(parsed, withoutPathExt) {
|
|
@@ -9562,7 +9562,7 @@ var require_resolveCommand = __commonJS({
|
|
|
9562
9562
|
try {
|
|
9563
9563
|
resolved = which.sync(parsed.command, {
|
|
9564
9564
|
path: env[getPathKey({ env })],
|
|
9565
|
-
pathExt: withoutPathExt ?
|
|
9565
|
+
pathExt: withoutPathExt ? path33.delimiter : void 0
|
|
9566
9566
|
});
|
|
9567
9567
|
} catch (e) {
|
|
9568
9568
|
} finally {
|
|
@@ -9571,7 +9571,7 @@ var require_resolveCommand = __commonJS({
|
|
|
9571
9571
|
}
|
|
9572
9572
|
}
|
|
9573
9573
|
if (resolved) {
|
|
9574
|
-
resolved =
|
|
9574
|
+
resolved = path33.resolve(hasCustomCwd ? parsed.options.cwd : "", resolved);
|
|
9575
9575
|
}
|
|
9576
9576
|
return resolved;
|
|
9577
9577
|
}
|
|
@@ -9625,8 +9625,8 @@ var require_shebang_command = __commonJS({
|
|
|
9625
9625
|
if (!match) {
|
|
9626
9626
|
return null;
|
|
9627
9627
|
}
|
|
9628
|
-
const [
|
|
9629
|
-
const binary =
|
|
9628
|
+
const [path33, argument] = match[0].replace(/#! ?/, "").split(" ");
|
|
9629
|
+
const binary = path33.split("/").pop();
|
|
9630
9630
|
if (binary === "env") {
|
|
9631
9631
|
return argument;
|
|
9632
9632
|
}
|
|
@@ -9661,7 +9661,7 @@ var require_readShebang = __commonJS({
|
|
|
9661
9661
|
var require_parse2 = __commonJS({
|
|
9662
9662
|
"../../node_modules/.pnpm/cross-spawn@7.0.6/node_modules/cross-spawn/lib/parse.js"(exports2, module2) {
|
|
9663
9663
|
"use strict";
|
|
9664
|
-
var
|
|
9664
|
+
var path33 = require("path");
|
|
9665
9665
|
var resolveCommand = require_resolveCommand();
|
|
9666
9666
|
var escape2 = require_escape();
|
|
9667
9667
|
var readShebang = require_readShebang();
|
|
@@ -9686,7 +9686,7 @@ var require_parse2 = __commonJS({
|
|
|
9686
9686
|
const needsShell = !isExecutableRegExp.test(commandFile);
|
|
9687
9687
|
if (parsed.options.forceShell || needsShell) {
|
|
9688
9688
|
const needsDoubleEscapeMetaChars = isCmdShimRegExp.test(commandFile);
|
|
9689
|
-
parsed.command =
|
|
9689
|
+
parsed.command = path33.normalize(parsed.command);
|
|
9690
9690
|
parsed.command = escape2.command(parsed.command);
|
|
9691
9691
|
parsed.args = parsed.args.map((arg) => escape2.argument(arg, needsDoubleEscapeMetaChars));
|
|
9692
9692
|
const shellCommand = [parsed.command].concat(parsed.args).join(" ");
|
|
@@ -9782,7 +9782,7 @@ var require_cross_spawn = __commonJS({
|
|
|
9782
9782
|
enoent.hookChildProcess(spawned, parsed);
|
|
9783
9783
|
return spawned;
|
|
9784
9784
|
}
|
|
9785
|
-
function
|
|
9785
|
+
function spawnSync9(command, args, options) {
|
|
9786
9786
|
const parsed = parse8(command, args, options);
|
|
9787
9787
|
const result = cp.spawnSync(parsed.command, parsed.args, parsed.options);
|
|
9788
9788
|
result.error = result.error || enoent.verifyENOENTSync(result.status, parsed);
|
|
@@ -9790,7 +9790,7 @@ var require_cross_spawn = __commonJS({
|
|
|
9790
9790
|
}
|
|
9791
9791
|
module2.exports = spawn8;
|
|
9792
9792
|
module2.exports.spawn = spawn8;
|
|
9793
|
-
module2.exports.sync =
|
|
9793
|
+
module2.exports.sync = spawnSync9;
|
|
9794
9794
|
module2.exports._parse = parse8;
|
|
9795
9795
|
module2.exports._enoent = enoent;
|
|
9796
9796
|
}
|
|
@@ -14017,7 +14017,7 @@ var require_websocket = __commonJS({
|
|
|
14017
14017
|
var http4 = require("http");
|
|
14018
14018
|
var net3 = require("net");
|
|
14019
14019
|
var tls2 = require("tls");
|
|
14020
|
-
var { randomBytes: randomBytes5, createHash:
|
|
14020
|
+
var { randomBytes: randomBytes5, createHash: createHash7 } = require("crypto");
|
|
14021
14021
|
var { Duplex, Readable } = require("stream");
|
|
14022
14022
|
var { URL: URL2 } = require("url");
|
|
14023
14023
|
var PerMessageDeflate2 = require_permessage_deflate();
|
|
@@ -14685,7 +14685,7 @@ var require_websocket = __commonJS({
|
|
|
14685
14685
|
abortHandshake(websocket, socket, "Invalid Upgrade header");
|
|
14686
14686
|
return;
|
|
14687
14687
|
}
|
|
14688
|
-
const digest =
|
|
14688
|
+
const digest = createHash7("sha1").update(key + GUID).digest("base64");
|
|
14689
14689
|
if (res.headers["sec-websocket-accept"] !== digest) {
|
|
14690
14690
|
abortHandshake(websocket, socket, "Invalid Sec-WebSocket-Accept header");
|
|
14691
14691
|
return;
|
|
@@ -15054,7 +15054,7 @@ var require_websocket_server = __commonJS({
|
|
|
15054
15054
|
var EventEmitter3 = require("events");
|
|
15055
15055
|
var http4 = require("http");
|
|
15056
15056
|
var { Duplex } = require("stream");
|
|
15057
|
-
var { createHash:
|
|
15057
|
+
var { createHash: createHash7 } = require("crypto");
|
|
15058
15058
|
var extension2 = require_extension();
|
|
15059
15059
|
var PerMessageDeflate2 = require_permessage_deflate();
|
|
15060
15060
|
var subprotocol2 = require_subprotocol();
|
|
@@ -15361,7 +15361,7 @@ var require_websocket_server = __commonJS({
|
|
|
15361
15361
|
);
|
|
15362
15362
|
}
|
|
15363
15363
|
if (this._state > RUNNING) return abortHandshake(socket, 503);
|
|
15364
|
-
const digest =
|
|
15364
|
+
const digest = createHash7("sha1").update(key + GUID).digest("base64");
|
|
15365
15365
|
const headers = [
|
|
15366
15366
|
"HTTP/1.1 101 Switching Protocols",
|
|
15367
15367
|
"Upgrade: websocket",
|
|
@@ -15500,14 +15500,14 @@ var require_polyfills = __commonJS({
|
|
|
15500
15500
|
fs16.fstatSync = statFixSync(fs16.fstatSync);
|
|
15501
15501
|
fs16.lstatSync = statFixSync(fs16.lstatSync);
|
|
15502
15502
|
if (fs16.chmod && !fs16.lchmod) {
|
|
15503
|
-
fs16.lchmod = function(
|
|
15503
|
+
fs16.lchmod = function(path33, mode, cb) {
|
|
15504
15504
|
if (cb) process.nextTick(cb);
|
|
15505
15505
|
};
|
|
15506
15506
|
fs16.lchmodSync = function() {
|
|
15507
15507
|
};
|
|
15508
15508
|
}
|
|
15509
15509
|
if (fs16.chown && !fs16.lchown) {
|
|
15510
|
-
fs16.lchown = function(
|
|
15510
|
+
fs16.lchown = function(path33, uid, gid, cb) {
|
|
15511
15511
|
if (cb) process.nextTick(cb);
|
|
15512
15512
|
};
|
|
15513
15513
|
fs16.lchownSync = function() {
|
|
@@ -15574,9 +15574,9 @@ var require_polyfills = __commonJS({
|
|
|
15574
15574
|
};
|
|
15575
15575
|
}(fs16.readSync);
|
|
15576
15576
|
function patchLchmod(fs17) {
|
|
15577
|
-
fs17.lchmod = function(
|
|
15577
|
+
fs17.lchmod = function(path33, mode, callback) {
|
|
15578
15578
|
fs17.open(
|
|
15579
|
-
|
|
15579
|
+
path33,
|
|
15580
15580
|
constants2.O_WRONLY | constants2.O_SYMLINK,
|
|
15581
15581
|
mode,
|
|
15582
15582
|
function(err, fd) {
|
|
@@ -15592,8 +15592,8 @@ var require_polyfills = __commonJS({
|
|
|
15592
15592
|
}
|
|
15593
15593
|
);
|
|
15594
15594
|
};
|
|
15595
|
-
fs17.lchmodSync = function(
|
|
15596
|
-
var fd = fs17.openSync(
|
|
15595
|
+
fs17.lchmodSync = function(path33, mode) {
|
|
15596
|
+
var fd = fs17.openSync(path33, constants2.O_WRONLY | constants2.O_SYMLINK, mode);
|
|
15597
15597
|
var threw = true;
|
|
15598
15598
|
var ret;
|
|
15599
15599
|
try {
|
|
@@ -15614,8 +15614,8 @@ var require_polyfills = __commonJS({
|
|
|
15614
15614
|
}
|
|
15615
15615
|
function patchLutimes(fs17) {
|
|
15616
15616
|
if (constants2.hasOwnProperty("O_SYMLINK") && fs17.futimes) {
|
|
15617
|
-
fs17.lutimes = function(
|
|
15618
|
-
fs17.open(
|
|
15617
|
+
fs17.lutimes = function(path33, at, mt, cb) {
|
|
15618
|
+
fs17.open(path33, constants2.O_SYMLINK, function(er, fd) {
|
|
15619
15619
|
if (er) {
|
|
15620
15620
|
if (cb) cb(er);
|
|
15621
15621
|
return;
|
|
@@ -15627,8 +15627,8 @@ var require_polyfills = __commonJS({
|
|
|
15627
15627
|
});
|
|
15628
15628
|
});
|
|
15629
15629
|
};
|
|
15630
|
-
fs17.lutimesSync = function(
|
|
15631
|
-
var fd = fs17.openSync(
|
|
15630
|
+
fs17.lutimesSync = function(path33, at, mt) {
|
|
15631
|
+
var fd = fs17.openSync(path33, constants2.O_SYMLINK);
|
|
15632
15632
|
var ret;
|
|
15633
15633
|
var threw = true;
|
|
15634
15634
|
try {
|
|
@@ -15746,11 +15746,11 @@ var require_legacy_streams = __commonJS({
|
|
|
15746
15746
|
ReadStream,
|
|
15747
15747
|
WriteStream
|
|
15748
15748
|
};
|
|
15749
|
-
function ReadStream(
|
|
15750
|
-
if (!(this instanceof ReadStream)) return new ReadStream(
|
|
15749
|
+
function ReadStream(path33, options) {
|
|
15750
|
+
if (!(this instanceof ReadStream)) return new ReadStream(path33, options);
|
|
15751
15751
|
Stream.call(this);
|
|
15752
15752
|
var self = this;
|
|
15753
|
-
this.path =
|
|
15753
|
+
this.path = path33;
|
|
15754
15754
|
this.fd = null;
|
|
15755
15755
|
this.readable = true;
|
|
15756
15756
|
this.paused = false;
|
|
@@ -15795,10 +15795,10 @@ var require_legacy_streams = __commonJS({
|
|
|
15795
15795
|
self._read();
|
|
15796
15796
|
});
|
|
15797
15797
|
}
|
|
15798
|
-
function WriteStream(
|
|
15799
|
-
if (!(this instanceof WriteStream)) return new WriteStream(
|
|
15798
|
+
function WriteStream(path33, options) {
|
|
15799
|
+
if (!(this instanceof WriteStream)) return new WriteStream(path33, options);
|
|
15800
15800
|
Stream.call(this);
|
|
15801
|
-
this.path =
|
|
15801
|
+
this.path = path33;
|
|
15802
15802
|
this.fd = null;
|
|
15803
15803
|
this.writable = true;
|
|
15804
15804
|
this.flags = "w";
|
|
@@ -15909,14 +15909,14 @@ var require_graceful_fs = __commonJS({
|
|
|
15909
15909
|
return close;
|
|
15910
15910
|
}(fs16.close);
|
|
15911
15911
|
fs16.closeSync = function(fs$closeSync) {
|
|
15912
|
-
function
|
|
15912
|
+
function closeSync2(fd) {
|
|
15913
15913
|
fs$closeSync.apply(fs16, arguments);
|
|
15914
15914
|
resetQueue();
|
|
15915
15915
|
}
|
|
15916
|
-
Object.defineProperty(
|
|
15916
|
+
Object.defineProperty(closeSync2, previousSymbol, {
|
|
15917
15917
|
value: fs$closeSync
|
|
15918
15918
|
});
|
|
15919
|
-
return
|
|
15919
|
+
return closeSync2;
|
|
15920
15920
|
}(fs16.closeSync);
|
|
15921
15921
|
if (/\bgfs4\b/i.test(process.env.NODE_DEBUG || "")) {
|
|
15922
15922
|
process.on("exit", function() {
|
|
@@ -15941,14 +15941,14 @@ var require_graceful_fs = __commonJS({
|
|
|
15941
15941
|
fs17.createWriteStream = createWriteStream;
|
|
15942
15942
|
var fs$readFile = fs17.readFile;
|
|
15943
15943
|
fs17.readFile = readFile9;
|
|
15944
|
-
function readFile9(
|
|
15944
|
+
function readFile9(path33, options, cb) {
|
|
15945
15945
|
if (typeof options === "function")
|
|
15946
15946
|
cb = options, options = null;
|
|
15947
|
-
return go$readFile(
|
|
15948
|
-
function go$readFile(
|
|
15949
|
-
return fs$readFile(
|
|
15947
|
+
return go$readFile(path33, options, cb);
|
|
15948
|
+
function go$readFile(path34, options2, cb2, startTime) {
|
|
15949
|
+
return fs$readFile(path34, options2, function(err) {
|
|
15950
15950
|
if (err && (err.code === "EMFILE" || err.code === "ENFILE"))
|
|
15951
|
-
enqueue([go$readFile, [
|
|
15951
|
+
enqueue([go$readFile, [path34, options2, cb2], err, startTime || Date.now(), Date.now()]);
|
|
15952
15952
|
else {
|
|
15953
15953
|
if (typeof cb2 === "function")
|
|
15954
15954
|
cb2.apply(this, arguments);
|
|
@@ -15958,14 +15958,14 @@ var require_graceful_fs = __commonJS({
|
|
|
15958
15958
|
}
|
|
15959
15959
|
var fs$writeFile = fs17.writeFile;
|
|
15960
15960
|
fs17.writeFile = writeFile5;
|
|
15961
|
-
function writeFile5(
|
|
15961
|
+
function writeFile5(path33, data, options, cb) {
|
|
15962
15962
|
if (typeof options === "function")
|
|
15963
15963
|
cb = options, options = null;
|
|
15964
|
-
return go$writeFile(
|
|
15965
|
-
function go$writeFile(
|
|
15966
|
-
return fs$writeFile(
|
|
15964
|
+
return go$writeFile(path33, data, options, cb);
|
|
15965
|
+
function go$writeFile(path34, data2, options2, cb2, startTime) {
|
|
15966
|
+
return fs$writeFile(path34, data2, options2, function(err) {
|
|
15967
15967
|
if (err && (err.code === "EMFILE" || err.code === "ENFILE"))
|
|
15968
|
-
enqueue([go$writeFile, [
|
|
15968
|
+
enqueue([go$writeFile, [path34, data2, options2, cb2], err, startTime || Date.now(), Date.now()]);
|
|
15969
15969
|
else {
|
|
15970
15970
|
if (typeof cb2 === "function")
|
|
15971
15971
|
cb2.apply(this, arguments);
|
|
@@ -15976,14 +15976,14 @@ var require_graceful_fs = __commonJS({
|
|
|
15976
15976
|
var fs$appendFile = fs17.appendFile;
|
|
15977
15977
|
if (fs$appendFile)
|
|
15978
15978
|
fs17.appendFile = appendFile2;
|
|
15979
|
-
function appendFile2(
|
|
15979
|
+
function appendFile2(path33, data, options, cb) {
|
|
15980
15980
|
if (typeof options === "function")
|
|
15981
15981
|
cb = options, options = null;
|
|
15982
|
-
return go$appendFile(
|
|
15983
|
-
function go$appendFile(
|
|
15984
|
-
return fs$appendFile(
|
|
15982
|
+
return go$appendFile(path33, data, options, cb);
|
|
15983
|
+
function go$appendFile(path34, data2, options2, cb2, startTime) {
|
|
15984
|
+
return fs$appendFile(path34, data2, options2, function(err) {
|
|
15985
15985
|
if (err && (err.code === "EMFILE" || err.code === "ENFILE"))
|
|
15986
|
-
enqueue([go$appendFile, [
|
|
15986
|
+
enqueue([go$appendFile, [path34, data2, options2, cb2], err, startTime || Date.now(), Date.now()]);
|
|
15987
15987
|
else {
|
|
15988
15988
|
if (typeof cb2 === "function")
|
|
15989
15989
|
cb2.apply(this, arguments);
|
|
@@ -16014,31 +16014,31 @@ var require_graceful_fs = __commonJS({
|
|
|
16014
16014
|
var fs$readdir = fs17.readdir;
|
|
16015
16015
|
fs17.readdir = readdir5;
|
|
16016
16016
|
var noReaddirOptionVersions = /^v[0-5]\./;
|
|
16017
|
-
function readdir5(
|
|
16017
|
+
function readdir5(path33, options, cb) {
|
|
16018
16018
|
if (typeof options === "function")
|
|
16019
16019
|
cb = options, options = null;
|
|
16020
|
-
var go$readdir = noReaddirOptionVersions.test(process.version) ? function go$readdir2(
|
|
16021
|
-
return fs$readdir(
|
|
16022
|
-
|
|
16020
|
+
var go$readdir = noReaddirOptionVersions.test(process.version) ? function go$readdir2(path34, options2, cb2, startTime) {
|
|
16021
|
+
return fs$readdir(path34, fs$readdirCallback(
|
|
16022
|
+
path34,
|
|
16023
16023
|
options2,
|
|
16024
16024
|
cb2,
|
|
16025
16025
|
startTime
|
|
16026
16026
|
));
|
|
16027
|
-
} : function go$readdir2(
|
|
16028
|
-
return fs$readdir(
|
|
16029
|
-
|
|
16027
|
+
} : function go$readdir2(path34, options2, cb2, startTime) {
|
|
16028
|
+
return fs$readdir(path34, options2, fs$readdirCallback(
|
|
16029
|
+
path34,
|
|
16030
16030
|
options2,
|
|
16031
16031
|
cb2,
|
|
16032
16032
|
startTime
|
|
16033
16033
|
));
|
|
16034
16034
|
};
|
|
16035
|
-
return go$readdir(
|
|
16036
|
-
function fs$readdirCallback(
|
|
16035
|
+
return go$readdir(path33, options, cb);
|
|
16036
|
+
function fs$readdirCallback(path34, options2, cb2, startTime) {
|
|
16037
16037
|
return function(err, files) {
|
|
16038
16038
|
if (err && (err.code === "EMFILE" || err.code === "ENFILE"))
|
|
16039
16039
|
enqueue([
|
|
16040
16040
|
go$readdir,
|
|
16041
|
-
[
|
|
16041
|
+
[path34, options2, cb2],
|
|
16042
16042
|
err,
|
|
16043
16043
|
startTime || Date.now(),
|
|
16044
16044
|
Date.now()
|
|
@@ -16109,7 +16109,7 @@ var require_graceful_fs = __commonJS({
|
|
|
16109
16109
|
enumerable: true,
|
|
16110
16110
|
configurable: true
|
|
16111
16111
|
});
|
|
16112
|
-
function ReadStream(
|
|
16112
|
+
function ReadStream(path33, options) {
|
|
16113
16113
|
if (this instanceof ReadStream)
|
|
16114
16114
|
return fs$ReadStream.apply(this, arguments), this;
|
|
16115
16115
|
else
|
|
@@ -16129,7 +16129,7 @@ var require_graceful_fs = __commonJS({
|
|
|
16129
16129
|
}
|
|
16130
16130
|
});
|
|
16131
16131
|
}
|
|
16132
|
-
function WriteStream(
|
|
16132
|
+
function WriteStream(path33, options) {
|
|
16133
16133
|
if (this instanceof WriteStream)
|
|
16134
16134
|
return fs$WriteStream.apply(this, arguments), this;
|
|
16135
16135
|
else
|
|
@@ -16147,22 +16147,22 @@ var require_graceful_fs = __commonJS({
|
|
|
16147
16147
|
}
|
|
16148
16148
|
});
|
|
16149
16149
|
}
|
|
16150
|
-
function createReadStream2(
|
|
16151
|
-
return new fs17.ReadStream(
|
|
16150
|
+
function createReadStream2(path33, options) {
|
|
16151
|
+
return new fs17.ReadStream(path33, options);
|
|
16152
16152
|
}
|
|
16153
|
-
function createWriteStream(
|
|
16154
|
-
return new fs17.WriteStream(
|
|
16153
|
+
function createWriteStream(path33, options) {
|
|
16154
|
+
return new fs17.WriteStream(path33, options);
|
|
16155
16155
|
}
|
|
16156
16156
|
var fs$open = fs17.open;
|
|
16157
16157
|
fs17.open = open;
|
|
16158
|
-
function open(
|
|
16158
|
+
function open(path33, flags, mode, cb) {
|
|
16159
16159
|
if (typeof mode === "function")
|
|
16160
16160
|
cb = mode, mode = null;
|
|
16161
|
-
return go$open(
|
|
16162
|
-
function go$open(
|
|
16163
|
-
return fs$open(
|
|
16161
|
+
return go$open(path33, flags, mode, cb);
|
|
16162
|
+
function go$open(path34, flags2, mode2, cb2, startTime) {
|
|
16163
|
+
return fs$open(path34, flags2, mode2, function(err, fd) {
|
|
16164
16164
|
if (err && (err.code === "EMFILE" || err.code === "ENFILE"))
|
|
16165
|
-
enqueue([go$open, [
|
|
16165
|
+
enqueue([go$open, [path34, flags2, mode2, cb2], err, startTime || Date.now(), Date.now()]);
|
|
16166
16166
|
else {
|
|
16167
16167
|
if (typeof cb2 === "function")
|
|
16168
16168
|
cb2.apply(this, arguments);
|
|
@@ -16691,7 +16691,7 @@ var require_mtime_precision = __commonJS({
|
|
|
16691
16691
|
var require_lockfile = __commonJS({
|
|
16692
16692
|
"../../node_modules/.pnpm/proper-lockfile@4.1.2/node_modules/proper-lockfile/lib/lockfile.js"(exports2, module2) {
|
|
16693
16693
|
"use strict";
|
|
16694
|
-
var
|
|
16694
|
+
var path33 = require("path");
|
|
16695
16695
|
var fs16 = require_graceful_fs();
|
|
16696
16696
|
var retry = require_retry2();
|
|
16697
16697
|
var onExit = require_signal_exit();
|
|
@@ -16702,7 +16702,7 @@ var require_lockfile = __commonJS({
|
|
|
16702
16702
|
}
|
|
16703
16703
|
function resolveCanonicalPath(file2, options, callback) {
|
|
16704
16704
|
if (!options.realpath) {
|
|
16705
|
-
return callback(null,
|
|
16705
|
+
return callback(null, path33.resolve(file2));
|
|
16706
16706
|
}
|
|
16707
16707
|
options.fs.realpath(file2, callback);
|
|
16708
16708
|
}
|
|
@@ -18566,10 +18566,10 @@ var require_segments = __commonJS({
|
|
|
18566
18566
|
const segs = getSegmentsFromString(data, Utils.isKanjiModeEnabled());
|
|
18567
18567
|
const nodes = buildNodes(segs);
|
|
18568
18568
|
const graph = buildGraph(nodes, version2);
|
|
18569
|
-
const
|
|
18569
|
+
const path33 = dijkstra.find_path(graph.map, "start", "end");
|
|
18570
18570
|
const optimizedSegs = [];
|
|
18571
|
-
for (let i = 1; i <
|
|
18572
|
-
optimizedSegs.push(graph.table[
|
|
18571
|
+
for (let i = 1; i < path33.length - 1; i++) {
|
|
18572
|
+
optimizedSegs.push(graph.table[path33[i]].node);
|
|
18573
18573
|
}
|
|
18574
18574
|
return exports2.fromArray(mergeSegments(optimizedSegs));
|
|
18575
18575
|
};
|
|
@@ -21046,7 +21046,7 @@ var require_png2 = __commonJS({
|
|
|
21046
21046
|
});
|
|
21047
21047
|
png.pack();
|
|
21048
21048
|
};
|
|
21049
|
-
exports2.renderToFile = function renderToFile(
|
|
21049
|
+
exports2.renderToFile = function renderToFile(path33, qrData, options, cb) {
|
|
21050
21050
|
if (typeof cb === "undefined") {
|
|
21051
21051
|
cb = options;
|
|
21052
21052
|
options = void 0;
|
|
@@ -21057,7 +21057,7 @@ var require_png2 = __commonJS({
|
|
|
21057
21057
|
called = true;
|
|
21058
21058
|
cb.apply(null, args);
|
|
21059
21059
|
};
|
|
21060
|
-
const stream = fs16.createWriteStream(
|
|
21060
|
+
const stream = fs16.createWriteStream(path33);
|
|
21061
21061
|
stream.on("error", done);
|
|
21062
21062
|
stream.on("close", done);
|
|
21063
21063
|
exports2.renderToFileStream(stream, qrData, options);
|
|
@@ -21119,14 +21119,14 @@ var require_utf8 = __commonJS({
|
|
|
21119
21119
|
}
|
|
21120
21120
|
return output3;
|
|
21121
21121
|
};
|
|
21122
|
-
exports2.renderToFile = function renderToFile(
|
|
21122
|
+
exports2.renderToFile = function renderToFile(path33, qrData, options, cb) {
|
|
21123
21123
|
if (typeof cb === "undefined") {
|
|
21124
21124
|
cb = options;
|
|
21125
21125
|
options = void 0;
|
|
21126
21126
|
}
|
|
21127
21127
|
const fs16 = require("fs");
|
|
21128
21128
|
const utf8 = exports2.render(qrData, options);
|
|
21129
|
-
fs16.writeFile(
|
|
21129
|
+
fs16.writeFile(path33, utf8, cb);
|
|
21130
21130
|
};
|
|
21131
21131
|
}
|
|
21132
21132
|
});
|
|
@@ -21247,7 +21247,7 @@ var require_svg_tag = __commonJS({
|
|
|
21247
21247
|
return str;
|
|
21248
21248
|
}
|
|
21249
21249
|
function qrToPath(data, size, margin) {
|
|
21250
|
-
let
|
|
21250
|
+
let path33 = "";
|
|
21251
21251
|
let moveBy = 0;
|
|
21252
21252
|
let newRow = false;
|
|
21253
21253
|
let lineLength = 0;
|
|
@@ -21258,19 +21258,19 @@ var require_svg_tag = __commonJS({
|
|
|
21258
21258
|
if (data[i]) {
|
|
21259
21259
|
lineLength++;
|
|
21260
21260
|
if (!(i > 0 && col > 0 && data[i - 1])) {
|
|
21261
|
-
|
|
21261
|
+
path33 += newRow ? svgCmd("M", col + margin, 0.5 + row + margin) : svgCmd("m", moveBy, 0);
|
|
21262
21262
|
moveBy = 0;
|
|
21263
21263
|
newRow = false;
|
|
21264
21264
|
}
|
|
21265
21265
|
if (!(col + 1 < size && data[i + 1])) {
|
|
21266
|
-
|
|
21266
|
+
path33 += svgCmd("h", lineLength);
|
|
21267
21267
|
lineLength = 0;
|
|
21268
21268
|
}
|
|
21269
21269
|
} else {
|
|
21270
21270
|
moveBy++;
|
|
21271
21271
|
}
|
|
21272
21272
|
}
|
|
21273
|
-
return
|
|
21273
|
+
return path33;
|
|
21274
21274
|
}
|
|
21275
21275
|
exports2.render = function render(qrData, options, cb) {
|
|
21276
21276
|
const opts = Utils.getOptions(options);
|
|
@@ -21278,10 +21278,10 @@ var require_svg_tag = __commonJS({
|
|
|
21278
21278
|
const data = qrData.modules.data;
|
|
21279
21279
|
const qrcodesize = size + opts.margin * 2;
|
|
21280
21280
|
const bg = !opts.color.light.a ? "" : "<path " + getColorAttrib(opts.color.light, "fill") + ' d="M0 0h' + qrcodesize + "v" + qrcodesize + 'H0z"/>';
|
|
21281
|
-
const
|
|
21281
|
+
const path33 = "<path " + getColorAttrib(opts.color.dark, "stroke") + ' d="' + qrToPath(data, size, opts.margin) + '"/>';
|
|
21282
21282
|
const viewBox = 'viewBox="0 0 ' + qrcodesize + " " + qrcodesize + '"';
|
|
21283
21283
|
const width = !opts.width ? "" : 'width="' + opts.width + '" height="' + opts.width + '" ';
|
|
21284
|
-
const svgTag = '<svg xmlns="http://www.w3.org/2000/svg" ' + width + viewBox + ' shape-rendering="crispEdges">' + bg +
|
|
21284
|
+
const svgTag = '<svg xmlns="http://www.w3.org/2000/svg" ' + width + viewBox + ' shape-rendering="crispEdges">' + bg + path33 + "</svg>\n";
|
|
21285
21285
|
if (typeof cb === "function") {
|
|
21286
21286
|
cb(null, svgTag);
|
|
21287
21287
|
}
|
|
@@ -21295,7 +21295,7 @@ var require_svg = __commonJS({
|
|
|
21295
21295
|
"../../node_modules/.pnpm/qrcode@1.5.4/node_modules/qrcode/lib/renderer/svg.js"(exports2) {
|
|
21296
21296
|
var svgTagRenderer = require_svg_tag();
|
|
21297
21297
|
exports2.render = svgTagRenderer.render;
|
|
21298
|
-
exports2.renderToFile = function renderToFile(
|
|
21298
|
+
exports2.renderToFile = function renderToFile(path33, qrData, options, cb) {
|
|
21299
21299
|
if (typeof cb === "undefined") {
|
|
21300
21300
|
cb = options;
|
|
21301
21301
|
options = void 0;
|
|
@@ -21303,7 +21303,7 @@ var require_svg = __commonJS({
|
|
|
21303
21303
|
const fs16 = require("fs");
|
|
21304
21304
|
const svgTag = exports2.render(qrData, options);
|
|
21305
21305
|
const xmlStr = '<?xml version="1.0" encoding="utf-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">' + svgTag;
|
|
21306
|
-
fs16.writeFile(
|
|
21306
|
+
fs16.writeFile(path33, xmlStr, cb);
|
|
21307
21307
|
};
|
|
21308
21308
|
}
|
|
21309
21309
|
});
|
|
@@ -21461,8 +21461,8 @@ var require_server = __commonJS({
|
|
|
21461
21461
|
cb
|
|
21462
21462
|
};
|
|
21463
21463
|
}
|
|
21464
|
-
function getTypeFromFilename(
|
|
21465
|
-
return
|
|
21464
|
+
function getTypeFromFilename(path33) {
|
|
21465
|
+
return path33.slice((path33.lastIndexOf(".") - 1 >>> 0) + 2).toLowerCase();
|
|
21466
21466
|
}
|
|
21467
21467
|
function getRendererFromType(type) {
|
|
21468
21468
|
switch (type) {
|
|
@@ -21526,17 +21526,17 @@ var require_server = __commonJS({
|
|
|
21526
21526
|
const renderer = getRendererFromType(params.opts.type);
|
|
21527
21527
|
return render(renderer.renderToBuffer, text, params);
|
|
21528
21528
|
};
|
|
21529
|
-
exports2.toFile = function toFile(
|
|
21530
|
-
if (typeof
|
|
21529
|
+
exports2.toFile = function toFile(path33, text, opts, cb) {
|
|
21530
|
+
if (typeof path33 !== "string" || !(typeof text === "string" || typeof text === "object")) {
|
|
21531
21531
|
throw new Error("Invalid argument");
|
|
21532
21532
|
}
|
|
21533
21533
|
if (arguments.length < 3 && !canPromise()) {
|
|
21534
21534
|
throw new Error("Too few arguments provided");
|
|
21535
21535
|
}
|
|
21536
21536
|
const params = checkParams(text, opts, cb);
|
|
21537
|
-
const type = params.opts.type || getTypeFromFilename(
|
|
21537
|
+
const type = params.opts.type || getTypeFromFilename(path33);
|
|
21538
21538
|
const renderer = getRendererFromType(type);
|
|
21539
|
-
const renderToFile = renderer.renderToFile.bind(null,
|
|
21539
|
+
const renderToFile = renderer.renderToFile.bind(null, path33);
|
|
21540
21540
|
return render(renderToFile, text, params);
|
|
21541
21541
|
};
|
|
21542
21542
|
exports2.toFileStream = function toFileStream(stream, text, opts) {
|
|
@@ -21593,8 +21593,8 @@ args = ${JSON.stringify(expected.args)}
|
|
|
21593
21593
|
return tomlStr;
|
|
21594
21594
|
}
|
|
21595
21595
|
async function installPublicMcpServerToConfigs(serverId, expected) {
|
|
21596
|
-
const homeDir =
|
|
21597
|
-
const claudePath =
|
|
21596
|
+
const homeDir = import_node_os20.default.homedir();
|
|
21597
|
+
const claudePath = import_node_path41.default.join(homeDir, ".claude.json");
|
|
21598
21598
|
if (await pathExists5(claudePath)) {
|
|
21599
21599
|
try {
|
|
21600
21600
|
const content = await import_promises16.default.readFile(claudePath, "utf8");
|
|
@@ -21608,7 +21608,7 @@ async function installPublicMcpServerToConfigs(serverId, expected) {
|
|
|
21608
21608
|
} else {
|
|
21609
21609
|
await writeAtomic(claudePath, JSON.stringify({ mcpServers: { [serverId]: expected } }, null, 2) + "\n");
|
|
21610
21610
|
}
|
|
21611
|
-
const codexPath =
|
|
21611
|
+
const codexPath = import_node_path41.default.join(homeDir, ".codex", "config.toml");
|
|
21612
21612
|
if (await pathExists5(codexPath)) {
|
|
21613
21613
|
try {
|
|
21614
21614
|
const content = await import_promises16.default.readFile(codexPath, "utf8");
|
|
@@ -21623,11 +21623,11 @@ async function installPublicMcpServerToConfigs(serverId, expected) {
|
|
|
21623
21623
|
console.error(`Failed to inject MCP server into ${codexPath}`, e);
|
|
21624
21624
|
}
|
|
21625
21625
|
} else {
|
|
21626
|
-
await import_promises16.default.mkdir(
|
|
21626
|
+
await import_promises16.default.mkdir(import_node_path41.default.dirname(codexPath), { recursive: true, mode: 448 }).catch(() => {
|
|
21627
21627
|
});
|
|
21628
21628
|
await writeAtomic(codexPath, renderTomlBlock(serverId, expected).trim() + "\n");
|
|
21629
21629
|
}
|
|
21630
|
-
const agyPath =
|
|
21630
|
+
const agyPath = import_node_path41.default.join(homeDir, ".gemini", "antigravity", "mcp_config.json");
|
|
21631
21631
|
if (await pathExists5(agyPath)) {
|
|
21632
21632
|
try {
|
|
21633
21633
|
const content = await import_promises16.default.readFile(agyPath, "utf8");
|
|
@@ -21639,18 +21639,18 @@ async function installPublicMcpServerToConfigs(serverId, expected) {
|
|
|
21639
21639
|
console.error(`Failed to inject MCP server into ${agyPath}`, e);
|
|
21640
21640
|
}
|
|
21641
21641
|
} else {
|
|
21642
|
-
await import_promises16.default.mkdir(
|
|
21642
|
+
await import_promises16.default.mkdir(import_node_path41.default.dirname(agyPath), { recursive: true, mode: 448 }).catch(() => {
|
|
21643
21643
|
});
|
|
21644
21644
|
await writeAtomic(agyPath, JSON.stringify({ mcpServers: { [serverId]: expected } }, null, 2) + "\n");
|
|
21645
21645
|
}
|
|
21646
21646
|
}
|
|
21647
|
-
var import_promises16,
|
|
21647
|
+
var import_promises16, import_node_os20, import_node_path41, toml4;
|
|
21648
21648
|
var init_install_public_mcp = __esm({
|
|
21649
21649
|
"src/install-public-mcp.ts"() {
|
|
21650
21650
|
"use strict";
|
|
21651
21651
|
import_promises16 = __toESM(require("node:fs/promises"), 1);
|
|
21652
|
-
|
|
21653
|
-
|
|
21652
|
+
import_node_os20 = __toESM(require("node:os"), 1);
|
|
21653
|
+
import_node_path41 = __toESM(require("node:path"), 1);
|
|
21654
21654
|
toml4 = __toESM(require_toml(), 1);
|
|
21655
21655
|
}
|
|
21656
21656
|
});
|
|
@@ -21661,11 +21661,11 @@ __export(bin_exports, {
|
|
|
21661
21661
|
augmentProcessPathWithCommonDirs: () => augmentProcessPathWithCommonDirs
|
|
21662
21662
|
});
|
|
21663
21663
|
module.exports = __toCommonJS(bin_exports);
|
|
21664
|
-
var
|
|
21665
|
-
var
|
|
21666
|
-
var
|
|
21667
|
-
var
|
|
21668
|
-
var
|
|
21664
|
+
var import_node_path46 = __toESM(require("node:path"), 1);
|
|
21665
|
+
var import_node_child_process26 = require("node:child_process");
|
|
21666
|
+
var import_node_fs29 = require("node:fs");
|
|
21667
|
+
var import_node_os24 = require("node:os");
|
|
21668
|
+
var import_node_path47 = __toESM(require("node:path"), 1);
|
|
21669
21669
|
|
|
21670
21670
|
// src/install-codex.ts
|
|
21671
21671
|
var import_promises = __toESM(require("node:fs/promises"), 1);
|
|
@@ -22666,14 +22666,14 @@ async function installClaude(options) {
|
|
|
22666
22666
|
|
|
22667
22667
|
// src/install-agy.ts
|
|
22668
22668
|
var import_promises9 = __toESM(require("node:fs/promises"), 1);
|
|
22669
|
-
var
|
|
22670
|
-
var
|
|
22669
|
+
var import_node_os12 = __toESM(require("node:os"), 1);
|
|
22670
|
+
var import_node_path20 = __toESM(require("node:path"), 1);
|
|
22671
22671
|
|
|
22672
22672
|
// src/tools.ts
|
|
22673
22673
|
var import_node_crypto11 = require("node:crypto");
|
|
22674
22674
|
var import_promises8 = require("node:fs/promises");
|
|
22675
|
-
var
|
|
22676
|
-
var
|
|
22675
|
+
var import_node_path19 = __toESM(require("node:path"), 1);
|
|
22676
|
+
var import_node_os11 = __toESM(require("node:os"), 1);
|
|
22677
22677
|
|
|
22678
22678
|
// ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/classic/external.js
|
|
22679
22679
|
var external_exports = {};
|
|
@@ -23441,10 +23441,10 @@ function mergeDefs(...defs) {
|
|
|
23441
23441
|
function cloneDef(schema) {
|
|
23442
23442
|
return mergeDefs(schema._zod.def);
|
|
23443
23443
|
}
|
|
23444
|
-
function getElementAtPath(obj,
|
|
23445
|
-
if (!
|
|
23444
|
+
function getElementAtPath(obj, path33) {
|
|
23445
|
+
if (!path33)
|
|
23446
23446
|
return obj;
|
|
23447
|
-
return
|
|
23447
|
+
return path33.reduce((acc, key) => acc?.[key], obj);
|
|
23448
23448
|
}
|
|
23449
23449
|
function promiseAllObject(promisesObj) {
|
|
23450
23450
|
const keys = Object.keys(promisesObj);
|
|
@@ -23853,11 +23853,11 @@ function explicitlyAborted(x, startIndex = 0) {
|
|
|
23853
23853
|
}
|
|
23854
23854
|
return false;
|
|
23855
23855
|
}
|
|
23856
|
-
function prefixIssues(
|
|
23856
|
+
function prefixIssues(path33, issues) {
|
|
23857
23857
|
return issues.map((iss) => {
|
|
23858
23858
|
var _a3;
|
|
23859
23859
|
(_a3 = iss).path ?? (_a3.path = []);
|
|
23860
|
-
iss.path.unshift(
|
|
23860
|
+
iss.path.unshift(path33);
|
|
23861
23861
|
return iss;
|
|
23862
23862
|
});
|
|
23863
23863
|
}
|
|
@@ -24004,16 +24004,16 @@ function flattenError(error51, mapper = (issue2) => issue2.message) {
|
|
|
24004
24004
|
}
|
|
24005
24005
|
function formatError(error51, mapper = (issue2) => issue2.message) {
|
|
24006
24006
|
const fieldErrors = { _errors: [] };
|
|
24007
|
-
const processError = (error52,
|
|
24007
|
+
const processError = (error52, path33 = []) => {
|
|
24008
24008
|
for (const issue2 of error52.issues) {
|
|
24009
24009
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
24010
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
24010
|
+
issue2.errors.map((issues) => processError({ issues }, [...path33, ...issue2.path]));
|
|
24011
24011
|
} else if (issue2.code === "invalid_key") {
|
|
24012
|
-
processError({ issues: issue2.issues }, [...
|
|
24012
|
+
processError({ issues: issue2.issues }, [...path33, ...issue2.path]);
|
|
24013
24013
|
} else if (issue2.code === "invalid_element") {
|
|
24014
|
-
processError({ issues: issue2.issues }, [...
|
|
24014
|
+
processError({ issues: issue2.issues }, [...path33, ...issue2.path]);
|
|
24015
24015
|
} else {
|
|
24016
|
-
const fullpath = [...
|
|
24016
|
+
const fullpath = [...path33, ...issue2.path];
|
|
24017
24017
|
if (fullpath.length === 0) {
|
|
24018
24018
|
fieldErrors._errors.push(mapper(issue2));
|
|
24019
24019
|
} else {
|
|
@@ -24040,17 +24040,17 @@ function formatError(error51, mapper = (issue2) => issue2.message) {
|
|
|
24040
24040
|
}
|
|
24041
24041
|
function treeifyError(error51, mapper = (issue2) => issue2.message) {
|
|
24042
24042
|
const result = { errors: [] };
|
|
24043
|
-
const processError = (error52,
|
|
24043
|
+
const processError = (error52, path33 = []) => {
|
|
24044
24044
|
var _a3, _b;
|
|
24045
24045
|
for (const issue2 of error52.issues) {
|
|
24046
24046
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
24047
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
24047
|
+
issue2.errors.map((issues) => processError({ issues }, [...path33, ...issue2.path]));
|
|
24048
24048
|
} else if (issue2.code === "invalid_key") {
|
|
24049
|
-
processError({ issues: issue2.issues }, [...
|
|
24049
|
+
processError({ issues: issue2.issues }, [...path33, ...issue2.path]);
|
|
24050
24050
|
} else if (issue2.code === "invalid_element") {
|
|
24051
|
-
processError({ issues: issue2.issues }, [...
|
|
24051
|
+
processError({ issues: issue2.issues }, [...path33, ...issue2.path]);
|
|
24052
24052
|
} else {
|
|
24053
|
-
const fullpath = [...
|
|
24053
|
+
const fullpath = [...path33, ...issue2.path];
|
|
24054
24054
|
if (fullpath.length === 0) {
|
|
24055
24055
|
result.errors.push(mapper(issue2));
|
|
24056
24056
|
continue;
|
|
@@ -24082,8 +24082,8 @@ function treeifyError(error51, mapper = (issue2) => issue2.message) {
|
|
|
24082
24082
|
}
|
|
24083
24083
|
function toDotPath(_path) {
|
|
24084
24084
|
const segs = [];
|
|
24085
|
-
const
|
|
24086
|
-
for (const seg of
|
|
24085
|
+
const path33 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
|
|
24086
|
+
for (const seg of path33) {
|
|
24087
24087
|
if (typeof seg === "number")
|
|
24088
24088
|
segs.push(`[${seg}]`);
|
|
24089
24089
|
else if (typeof seg === "symbol")
|
|
@@ -36775,13 +36775,13 @@ function resolveRef(ref, ctx) {
|
|
|
36775
36775
|
if (!ref.startsWith("#")) {
|
|
36776
36776
|
throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
|
|
36777
36777
|
}
|
|
36778
|
-
const
|
|
36779
|
-
if (
|
|
36778
|
+
const path33 = ref.slice(1).split("/").filter(Boolean);
|
|
36779
|
+
if (path33.length === 0) {
|
|
36780
36780
|
return ctx.rootSchema;
|
|
36781
36781
|
}
|
|
36782
36782
|
const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
|
|
36783
|
-
if (
|
|
36784
|
-
const key =
|
|
36783
|
+
if (path33[0] === defsKey) {
|
|
36784
|
+
const key = path33[1];
|
|
36785
36785
|
if (!key || !ctx.defs[key]) {
|
|
36786
36786
|
throw new Error(`Reference not found: ${ref}`);
|
|
36787
36787
|
}
|
|
@@ -37250,6 +37250,8 @@ var ARTIFACT_DESTINATIONS = {
|
|
|
37250
37250
|
function resolveKindCapability(kind) {
|
|
37251
37251
|
return ARTIFACT_DESTINATIONS[kind];
|
|
37252
37252
|
}
|
|
37253
|
+
var BUILTIN_CAPABILITY_SERVER_ID = "mrrlin-builtin";
|
|
37254
|
+
var LOCAL_GIT_TOOL_NAME = "mrrlin.local-git";
|
|
37253
37255
|
|
|
37254
37256
|
// ../../packages/schemas/dist/capability-refusal.js
|
|
37255
37257
|
var REFUSAL_TEMPLATES = {
|
|
@@ -38521,6 +38523,9 @@ var GIT_SHA_PATTERN = /^(?:[0-9a-f]{40}|[0-9a-f]{64})$/;
|
|
|
38521
38523
|
var SHA256_HEX_PATTERN = /^[0-9a-f]{64}$/;
|
|
38522
38524
|
var MRRLIN_LOCAL_DELIVERY_REF_PATTERN = /^git\+local:\/\/([^/\s@]+)\/(mrrlin\/run-ER-[A-Za-z0-9-]+)@([0-9a-f]{40}|[0-9a-f]{64})$/;
|
|
38523
38525
|
var mrrlinLocalDeliveryRefSchema = external_exports.string().regex(MRRLIN_LOCAL_DELIVERY_REF_PATTERN, "deliveryRef must be git+local://<projectSlug>/mrrlin/run-<runId>@<sha>");
|
|
38526
|
+
function formatLocalDeliveryRef(input) {
|
|
38527
|
+
return mrrlinLocalDeliveryRefSchema.parse(`git+local://${input.projectSlug}/${input.branch}@${input.headSha}`);
|
|
38528
|
+
}
|
|
38524
38529
|
var mrrlinLocalBuildStepSchema = external_exports.object({
|
|
38525
38530
|
command: external_exports.string().trim().min(1).max(200),
|
|
38526
38531
|
exitCode: external_exports.number().int(),
|
|
@@ -38571,6 +38576,7 @@ var mrrlinReceiptSchema = external_exports.object({
|
|
|
38571
38576
|
if (problem)
|
|
38572
38577
|
ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: ["localBuild"], message: problem });
|
|
38573
38578
|
});
|
|
38579
|
+
var LOCAL_BUILD_RECEIPT_PAYLOAD_KEY = "localBuildReceipt";
|
|
38574
38580
|
function buildReceipt(input) {
|
|
38575
38581
|
return {
|
|
38576
38582
|
kind: input.coveredKinds.length === 0 ? "attempt" : "outcome",
|
|
@@ -40688,18 +40694,18 @@ function createMrrlinClient(config2) {
|
|
|
40688
40694
|
const customFetch = config2.fetch ?? globalThis.fetch;
|
|
40689
40695
|
const baseUrl = config2.baseUrl.replace(/\/$/, "");
|
|
40690
40696
|
const token = config2.token;
|
|
40691
|
-
async function request(
|
|
40697
|
+
async function request(path33, init) {
|
|
40692
40698
|
const method = init?.method ?? "GET";
|
|
40693
40699
|
const headers = new Headers(init?.headers ?? {});
|
|
40694
40700
|
if (token && !headers.has("authorization")) {
|
|
40695
40701
|
headers.set("authorization", `Bearer ${token}`);
|
|
40696
40702
|
}
|
|
40697
|
-
const response = await customFetch(`${baseUrl}${
|
|
40703
|
+
const response = await customFetch(`${baseUrl}${path33}`, { ...init, headers });
|
|
40698
40704
|
if (!response.ok) {
|
|
40699
40705
|
const body = await response.text();
|
|
40700
40706
|
let code = `HTTP_${response.status}`;
|
|
40701
40707
|
let violations = null;
|
|
40702
|
-
let message = `Mrrlin API ${method} ${
|
|
40708
|
+
let message = `Mrrlin API ${method} ${path33} failed: ${response.status}`;
|
|
40703
40709
|
try {
|
|
40704
40710
|
const parsed = JSON.parse(body);
|
|
40705
40711
|
const violationsParsed = apiViolationsErrorSchema.safeParse(parsed);
|
|
@@ -40719,7 +40725,7 @@ function createMrrlinClient(config2) {
|
|
|
40719
40725
|
throw new MrrlinApiError({
|
|
40720
40726
|
code,
|
|
40721
40727
|
method,
|
|
40722
|
-
path:
|
|
40728
|
+
path: path33,
|
|
40723
40729
|
responseBody: body,
|
|
40724
40730
|
status: response.status,
|
|
40725
40731
|
violations,
|
|
@@ -40728,18 +40734,18 @@ function createMrrlinClient(config2) {
|
|
|
40728
40734
|
}
|
|
40729
40735
|
return response.json();
|
|
40730
40736
|
}
|
|
40731
|
-
async function requestText(
|
|
40737
|
+
async function requestText(path33, init) {
|
|
40732
40738
|
const method = init?.method ?? "GET";
|
|
40733
40739
|
const headers = new Headers(init?.headers ?? {});
|
|
40734
40740
|
if (token && !headers.has("authorization")) {
|
|
40735
40741
|
headers.set("authorization", `Bearer ${token}`);
|
|
40736
40742
|
}
|
|
40737
|
-
const response = await customFetch(`${baseUrl}${
|
|
40743
|
+
const response = await customFetch(`${baseUrl}${path33}`, { ...init, headers });
|
|
40738
40744
|
if (!response.ok) {
|
|
40739
40745
|
const body = await response.text();
|
|
40740
40746
|
let code = `HTTP_${response.status}`;
|
|
40741
40747
|
let violations = null;
|
|
40742
|
-
let message = `Mrrlin API ${method} ${
|
|
40748
|
+
let message = `Mrrlin API ${method} ${path33} failed: ${response.status}`;
|
|
40743
40749
|
try {
|
|
40744
40750
|
const parsed = JSON.parse(body);
|
|
40745
40751
|
const violationsParsed = apiViolationsErrorSchema.safeParse(parsed);
|
|
@@ -40759,7 +40765,7 @@ function createMrrlinClient(config2) {
|
|
|
40759
40765
|
throw new MrrlinApiError({
|
|
40760
40766
|
code,
|
|
40761
40767
|
method,
|
|
40762
|
-
path:
|
|
40768
|
+
path: path33,
|
|
40763
40769
|
responseBody: body,
|
|
40764
40770
|
status: response.status,
|
|
40765
40771
|
violations,
|
|
@@ -40927,16 +40933,16 @@ function createMrrlinClient(config2) {
|
|
|
40927
40933
|
// rejected against the first, MrrlinTask[]-only overload) -- the `any` here is contained to
|
|
40928
40934
|
// this one implementation signature; MrrlinClient's declared overloads keep callers precise.
|
|
40929
40935
|
async listTasks(projectSlug, filters = {}, options) {
|
|
40930
|
-
const
|
|
40931
|
-
const body = await request(
|
|
40936
|
+
const path33 = buildTaskListPath(projectSlug, filters, options?.view);
|
|
40937
|
+
const body = await request(path33, options?.signal ? { signal: options.signal } : void 0);
|
|
40932
40938
|
if (options?.view === "summary") {
|
|
40933
40939
|
return taskSummaryListResponseSchema.parse(body).data;
|
|
40934
40940
|
}
|
|
40935
40941
|
return taskListResponseSchema.parse(body).data;
|
|
40936
40942
|
},
|
|
40937
40943
|
async listTaskSummaries(projectSlug, filters = {}, options) {
|
|
40938
|
-
const
|
|
40939
|
-
const body = await request(
|
|
40944
|
+
const path33 = buildTaskListPath(projectSlug, filters, "summary");
|
|
40945
|
+
const body = await request(path33, options?.signal ? { signal: options.signal } : void 0);
|
|
40940
40946
|
return taskSummaryListResponseSchema.parse(body).data;
|
|
40941
40947
|
},
|
|
40942
40948
|
async listTaxonomy(projectSlug) {
|
|
@@ -40945,7 +40951,7 @@ function createMrrlinClient(config2) {
|
|
|
40945
40951
|
},
|
|
40946
40952
|
async listWikiPages(projectSlug, filters = {}, options) {
|
|
40947
40953
|
const view = options?.view ?? filters.view;
|
|
40948
|
-
const
|
|
40954
|
+
const path33 = appendQuery(`${projectPath(projectSlug)}/wiki`, {
|
|
40949
40955
|
folder: filters.folder,
|
|
40950
40956
|
id: filters.id,
|
|
40951
40957
|
limit: filters.limit === void 0 ? void 0 : String(filters.limit),
|
|
@@ -40953,20 +40959,20 @@ function createMrrlinClient(config2) {
|
|
|
40953
40959
|
taskId: filters.taskId,
|
|
40954
40960
|
view
|
|
40955
40961
|
});
|
|
40956
|
-
const body = await request(
|
|
40962
|
+
const body = await request(path33, options?.signal ? { signal: options.signal } : void 0);
|
|
40957
40963
|
if (view === "summary") {
|
|
40958
40964
|
return wikiPageSummaryListResponseSchema.parse(body).data;
|
|
40959
40965
|
}
|
|
40960
40966
|
return wikiPageListResponseSchema.parse(body).data;
|
|
40961
40967
|
},
|
|
40962
40968
|
async searchWikiPages(projectSlug, query) {
|
|
40963
|
-
const
|
|
40969
|
+
const path33 = appendQuery(`${projectPath(projectSlug)}/wiki/search`, {
|
|
40964
40970
|
folder: query.folder,
|
|
40965
40971
|
limit: query.limit === void 0 ? void 0 : String(query.limit),
|
|
40966
40972
|
pathPrefix: query.pathPrefix,
|
|
40967
40973
|
q: query.q
|
|
40968
40974
|
});
|
|
40969
|
-
const body = await request(
|
|
40975
|
+
const body = await request(path33);
|
|
40970
40976
|
return wikiPageSearchResponseSchema.parse(body).data;
|
|
40971
40977
|
},
|
|
40972
40978
|
async updatePlan(projectSlug, planId, patch) {
|
|
@@ -57354,8 +57360,8 @@ async function findSessionDays(stateDir, sessionId) {
|
|
|
57354
57360
|
function isRecord5(v) {
|
|
57355
57361
|
return v !== null && typeof v === "object";
|
|
57356
57362
|
}
|
|
57357
|
-
function resolvePath(root,
|
|
57358
|
-
const parts =
|
|
57363
|
+
function resolvePath(root, path33) {
|
|
57364
|
+
const parts = path33.split(".");
|
|
57359
57365
|
let cur = root;
|
|
57360
57366
|
for (let i = 0; i < parts.length - 1; i += 1) {
|
|
57361
57367
|
const part = parts[i];
|
|
@@ -57423,9 +57429,9 @@ async function gate(artifact, prose, ctx) {
|
|
|
57423
57429
|
return { ok: true, gated: true, artifact: withheldExcerptClone(artifact) };
|
|
57424
57430
|
}
|
|
57425
57431
|
const maskedClone = typeof structuredClone === "function" ? structuredClone(artifact) : JSON.parse(JSON.stringify(artifact));
|
|
57426
|
-
for (const { path:
|
|
57427
|
-
const target = resolvePath(maskedClone,
|
|
57428
|
-
if (!target) throw new Error(`pii-gate: path "${
|
|
57432
|
+
for (const { path: path33, masked } of fields) {
|
|
57433
|
+
const target = resolvePath(maskedClone, path33);
|
|
57434
|
+
if (!target) throw new Error(`pii-gate: path "${path33}" failed to resolve on the clone after validating on the original`);
|
|
57429
57435
|
target.parent[target.key] = masked;
|
|
57430
57436
|
}
|
|
57431
57437
|
return { ok: true, gated: false, artifact: maskedClone };
|
|
@@ -57635,9 +57641,9 @@ var CheckoutRegistry = class {
|
|
|
57635
57641
|
get(slug) {
|
|
57636
57642
|
return this.read()[slug] ?? null;
|
|
57637
57643
|
}
|
|
57638
|
-
confirm(slug,
|
|
57644
|
+
confirm(slug, path33, now) {
|
|
57639
57645
|
const all = this.read();
|
|
57640
|
-
all[slug] = { path:
|
|
57646
|
+
all[slug] = { path: path33, confirmedAt: now };
|
|
57641
57647
|
(0, import_node_fs7.writeFileSync)(this.file, JSON.stringify(all, null, 2));
|
|
57642
57648
|
}
|
|
57643
57649
|
/**
|
|
@@ -57775,20 +57781,177 @@ function checkoutStateData(projectSlug, entry, machineLabel) {
|
|
|
57775
57781
|
};
|
|
57776
57782
|
}
|
|
57777
57783
|
|
|
57778
|
-
// src/
|
|
57784
|
+
// src/local-checkout.ts
|
|
57785
|
+
var import_node_child_process14 = require("node:child_process");
|
|
57779
57786
|
var import_node_fs9 = require("node:fs");
|
|
57780
|
-
var import_node_os8 =
|
|
57787
|
+
var import_node_os8 = require("node:os");
|
|
57781
57788
|
var import_node_path16 = __toESM(require("node:path"), 1);
|
|
57789
|
+
var SYSTEM_PATH_PREFIXES = ["/etc", "/usr", "/bin", "/sbin", "/var", "/System", "/Library", "/opt", "/private"];
|
|
57790
|
+
function isUnder(child, parent) {
|
|
57791
|
+
return child === parent || child.startsWith(parent.endsWith(import_node_path16.default.sep) ? parent : `${parent}${import_node_path16.default.sep}`);
|
|
57792
|
+
}
|
|
57793
|
+
function checkLocalPathRules(input, options = {}) {
|
|
57794
|
+
const trimmed = input.trim();
|
|
57795
|
+
if (!import_node_path16.default.isAbsolute(trimmed)) return { ok: false, code: "not_absolute", detail: `Path must be absolute, got: ${trimmed}` };
|
|
57796
|
+
let realPath;
|
|
57797
|
+
try {
|
|
57798
|
+
realPath = (import_node_fs9.realpathSync.native ?? import_node_fs9.realpathSync)(trimmed);
|
|
57799
|
+
} catch {
|
|
57800
|
+
return { ok: false, code: "not_found", detail: `Path does not exist or is not accessible: ${trimmed}` };
|
|
57801
|
+
}
|
|
57802
|
+
const systemPrefixes = options.systemPrefixes ?? SYSTEM_PATH_PREFIXES;
|
|
57803
|
+
const home = options.homeDir ?? (0, import_node_os8.homedir)();
|
|
57804
|
+
let realHome = home;
|
|
57805
|
+
try {
|
|
57806
|
+
realHome = (import_node_fs9.realpathSync.native ?? import_node_fs9.realpathSync)(home);
|
|
57807
|
+
} catch {
|
|
57808
|
+
}
|
|
57809
|
+
if (realPath === import_node_path16.default.parse(realPath).root || realPath === realHome) {
|
|
57810
|
+
return { ok: false, code: "forbidden_path", detail: `Refusing the home directory or a filesystem root: ${realPath}` };
|
|
57811
|
+
}
|
|
57812
|
+
const prefix = systemPrefixes.find((candidate) => isUnder(realPath, candidate));
|
|
57813
|
+
if (prefix) {
|
|
57814
|
+
return { ok: false, code: "forbidden_path", detail: `Refusing a path under the system prefix ${prefix}: ${realPath}` };
|
|
57815
|
+
}
|
|
57816
|
+
const uid = options.uid ?? (typeof process.getuid === "function" ? process.getuid() : void 0);
|
|
57817
|
+
let fd;
|
|
57818
|
+
try {
|
|
57819
|
+
fd = (0, import_node_fs9.openSync)(realPath, import_node_fs9.constants.O_RDONLY | (import_node_fs9.constants.O_DIRECTORY ?? 0) | (import_node_fs9.constants.O_NOFOLLOW ?? 0));
|
|
57820
|
+
const stat3 = (0, import_node_fs9.fstatSync)(fd);
|
|
57821
|
+
if (!stat3.isDirectory()) return { ok: false, code: "not_a_directory", detail: `Not a directory: ${realPath}` };
|
|
57822
|
+
if (uid !== void 0 && stat3.uid !== uid) {
|
|
57823
|
+
return { ok: false, code: "not_owned", detail: `Directory is not owned by the bridge's user: ${realPath}` };
|
|
57824
|
+
}
|
|
57825
|
+
} catch (error51) {
|
|
57826
|
+
const code = error51.code;
|
|
57827
|
+
if (code === "ENOTDIR") return { ok: false, code: "not_a_directory", detail: `Not a directory: ${realPath}` };
|
|
57828
|
+
return { ok: false, code: "path_changed", detail: `Could not open ${realPath} without following links (${code ?? "error"})` };
|
|
57829
|
+
} finally {
|
|
57830
|
+
if (fd !== void 0) (0, import_node_fs9.closeSync)(fd);
|
|
57831
|
+
}
|
|
57832
|
+
return { ok: true, realPath };
|
|
57833
|
+
}
|
|
57834
|
+
function gitTopLevel(realPath) {
|
|
57835
|
+
try {
|
|
57836
|
+
return (0, import_node_child_process14.execFileSync)("git", ["-C", realPath, "rev-parse", "--show-toplevel"], {
|
|
57837
|
+
encoding: "utf8",
|
|
57838
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
57839
|
+
timeout: 15e3,
|
|
57840
|
+
env: { ...process.env, GIT_TERMINAL_PROMPT: "0" }
|
|
57841
|
+
}).trim();
|
|
57842
|
+
} catch {
|
|
57843
|
+
return null;
|
|
57844
|
+
}
|
|
57845
|
+
}
|
|
57846
|
+
function validateLocalCheckoutPath(input, options = {}) {
|
|
57847
|
+
const checked = checkLocalPathRules(input, options);
|
|
57848
|
+
if (!checked.ok) return checked;
|
|
57849
|
+
const top = gitTopLevel(checked.realPath);
|
|
57850
|
+
if (!top) return { ok: false, code: "not_a_git_repo", detail: `Path is not inside a git repository: ${checked.realPath}` };
|
|
57851
|
+
const realTop = (import_node_fs9.realpathSync.native ?? import_node_fs9.realpathSync)(top);
|
|
57852
|
+
if (realTop !== checked.realPath) {
|
|
57853
|
+
return {
|
|
57854
|
+
ok: false,
|
|
57855
|
+
code: "not_a_git_repo",
|
|
57856
|
+
detail: `Path is inside the git repository at ${realTop}, not its top level; register ${realTop} instead.`
|
|
57857
|
+
};
|
|
57858
|
+
}
|
|
57859
|
+
return checked;
|
|
57860
|
+
}
|
|
57861
|
+
function registerLocalOnlyCheckout(registry3, input, machineLabel, options = {}, now = (/* @__PURE__ */ new Date()).toISOString()) {
|
|
57862
|
+
const codeHost = input.project.codeHost ?? null;
|
|
57863
|
+
const eligible = codeHost === "local" || codeHost === null && !input.project.githubRepo;
|
|
57864
|
+
if (!eligible) {
|
|
57865
|
+
return {
|
|
57866
|
+
ok: false,
|
|
57867
|
+
code: "not_local_project",
|
|
57868
|
+
detail: `Project ${input.projectSlug} keeps its code on ${codeHost ?? "GitHub"}; register its clone with \`repo\` instead.`
|
|
57869
|
+
};
|
|
57870
|
+
}
|
|
57871
|
+
const validated = validateLocalCheckoutPath(input.path, options);
|
|
57872
|
+
if (!validated.ok) return validated;
|
|
57873
|
+
registry3.confirm(input.projectSlug, validated.realPath, now);
|
|
57874
|
+
return { ok: true, data: { projectSlug: input.projectSlug, path: validated.realPath, confirmedAt: now, machineLabel } };
|
|
57875
|
+
}
|
|
57876
|
+
var DEFAULT_GITIGNORE = ["node_modules/", "dist/", "build/", ".DS_Store", ".env", ".env.*", "*.log", ""].join("\n");
|
|
57877
|
+
function runGit(realPath, args) {
|
|
57878
|
+
return (0, import_node_child_process14.execFileSync)("git", ["-C", realPath, ...args], {
|
|
57879
|
+
encoding: "utf8",
|
|
57880
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
57881
|
+
timeout: 6e4,
|
|
57882
|
+
env: { ...process.env, GIT_TERMINAL_PROMPT: "0" }
|
|
57883
|
+
}).trim();
|
|
57884
|
+
}
|
|
57885
|
+
function initLocalRepo(registry3, input, machineLabel, options = {}, now = (/* @__PURE__ */ new Date()).toISOString()) {
|
|
57886
|
+
if (input.operatorConsent !== true) {
|
|
57887
|
+
return {
|
|
57888
|
+
ok: false,
|
|
57889
|
+
code: "consent_required",
|
|
57890
|
+
detail: "Ask the operator in chat, in plain words, whether their project folder may be turned into a git repository, and call this again only after they say yes."
|
|
57891
|
+
};
|
|
57892
|
+
}
|
|
57893
|
+
const codeHost = input.project.codeHost ?? null;
|
|
57894
|
+
if (!(codeHost === "local" || codeHost === null && !input.project.githubRepo)) {
|
|
57895
|
+
return { ok: false, code: "not_local_project", detail: `Project ${input.projectSlug} keeps its code on ${codeHost ?? "GitHub"}.` };
|
|
57896
|
+
}
|
|
57897
|
+
const checked = checkLocalPathRules(input.path, options);
|
|
57898
|
+
if (!checked.ok) return checked;
|
|
57899
|
+
if (gitTopLevel(checked.realPath) !== null) {
|
|
57900
|
+
return {
|
|
57901
|
+
ok: false,
|
|
57902
|
+
code: "inside_git_repo",
|
|
57903
|
+
detail: `${checked.realPath} is already inside a git repository; register that repository with register_local_checkout instead.`
|
|
57904
|
+
};
|
|
57905
|
+
}
|
|
57906
|
+
const recheck = checkLocalPathRules(checked.realPath, options);
|
|
57907
|
+
if (!recheck.ok || recheck.realPath !== checked.realPath) {
|
|
57908
|
+
return { ok: false, code: "path_changed", detail: `${checked.realPath} changed while it was being checked; nothing was done.` };
|
|
57909
|
+
}
|
|
57910
|
+
const realPath = recheck.realPath;
|
|
57911
|
+
let wroteGitignore = false;
|
|
57912
|
+
try {
|
|
57913
|
+
runGit(realPath, ["init", "-q", "-b", "main"]);
|
|
57914
|
+
const gitignore = import_node_path16.default.join(realPath, ".gitignore");
|
|
57915
|
+
try {
|
|
57916
|
+
(0, import_node_fs9.writeFileSync)(gitignore, DEFAULT_GITIGNORE, { flag: "wx" });
|
|
57917
|
+
wroteGitignore = true;
|
|
57918
|
+
} catch {
|
|
57919
|
+
}
|
|
57920
|
+
runGit(realPath, ["add", "-A"]);
|
|
57921
|
+
runGit(realPath, [
|
|
57922
|
+
"-c",
|
|
57923
|
+
"user.name=Mrrlin",
|
|
57924
|
+
"-c",
|
|
57925
|
+
"user.email=bridge@mrrlin.local",
|
|
57926
|
+
"commit",
|
|
57927
|
+
"-q",
|
|
57928
|
+
"--no-verify",
|
|
57929
|
+
"--allow-empty",
|
|
57930
|
+
"-m",
|
|
57931
|
+
"Initial commit (Mrrlin)"
|
|
57932
|
+
]);
|
|
57933
|
+
} catch (error51) {
|
|
57934
|
+
return { ok: false, code: "init_failed", detail: error51 instanceof Error ? error51.message : String(error51) };
|
|
57935
|
+
}
|
|
57936
|
+
const initialCommit = runGit(realPath, ["rev-parse", "HEAD"]);
|
|
57937
|
+
registry3.confirm(input.projectSlug, realPath, now);
|
|
57938
|
+
return { ok: true, data: { projectSlug: input.projectSlug, path: realPath, confirmedAt: now, machineLabel, initialCommit, wroteGitignore } };
|
|
57939
|
+
}
|
|
57940
|
+
|
|
57941
|
+
// src/operator-token.ts
|
|
57942
|
+
var import_node_fs10 = require("node:fs");
|
|
57943
|
+
var import_node_os9 = __toESM(require("node:os"), 1);
|
|
57944
|
+
var import_node_path17 = __toESM(require("node:path"), 1);
|
|
57782
57945
|
function operatorDir() {
|
|
57783
|
-
const base = process.env.CODEX_HOME ?
|
|
57946
|
+
const base = process.env.CODEX_HOME ? import_node_path17.default.join(process.env.CODEX_HOME, "mrrlin") : import_node_path17.default.join(import_node_os9.default.homedir(), ".mrrlin");
|
|
57784
57947
|
return base;
|
|
57785
57948
|
}
|
|
57786
57949
|
function operatorTokenPath() {
|
|
57787
|
-
return
|
|
57950
|
+
return import_node_path17.default.join(operatorDir(), "operator-token");
|
|
57788
57951
|
}
|
|
57789
57952
|
function readOperatorToken() {
|
|
57790
57953
|
try {
|
|
57791
|
-
const token = (0,
|
|
57954
|
+
const token = (0, import_node_fs10.readFileSync)(operatorTokenPath(), "utf8").trim();
|
|
57792
57955
|
return token.length > 0 ? token : null;
|
|
57793
57956
|
} catch {
|
|
57794
57957
|
return null;
|
|
@@ -57796,24 +57959,24 @@ function readOperatorToken() {
|
|
|
57796
57959
|
}
|
|
57797
57960
|
function persistOperatorToken(token) {
|
|
57798
57961
|
const dir = operatorDir();
|
|
57799
|
-
(0,
|
|
57800
|
-
(0,
|
|
57962
|
+
(0, import_node_fs10.mkdirSync)(dir, { recursive: true, mode: 448 });
|
|
57963
|
+
(0, import_node_fs10.writeFileSync)(operatorTokenPath(), `${token.trim()}
|
|
57801
57964
|
`, { encoding: "utf8", mode: 384 });
|
|
57802
57965
|
}
|
|
57803
57966
|
function agentCredentialPath() {
|
|
57804
|
-
return
|
|
57967
|
+
return import_node_path17.default.join(operatorDir(), "agent-credential");
|
|
57805
57968
|
}
|
|
57806
57969
|
function persistAgentSecret(secret) {
|
|
57807
57970
|
const dir = operatorDir();
|
|
57808
|
-
(0,
|
|
57809
|
-
(0,
|
|
57971
|
+
(0, import_node_fs10.mkdirSync)(dir, { recursive: true, mode: 448 });
|
|
57972
|
+
(0, import_node_fs10.writeFileSync)(agentCredentialPath(), `${secret.trim()}
|
|
57810
57973
|
`, { encoding: "utf8", mode: 384 });
|
|
57811
57974
|
}
|
|
57812
57975
|
function readAgentSecret() {
|
|
57813
57976
|
const fromEnv = process.env.MRRLIN_AGENT_SECRET?.trim();
|
|
57814
57977
|
if (fromEnv) return fromEnv;
|
|
57815
57978
|
try {
|
|
57816
|
-
const raw = (0,
|
|
57979
|
+
const raw = (0, import_node_fs10.readFileSync)(agentCredentialPath(), "utf8").trim();
|
|
57817
57980
|
return raw || void 0;
|
|
57818
57981
|
} catch {
|
|
57819
57982
|
return void 0;
|
|
@@ -57822,9 +57985,9 @@ function readAgentSecret() {
|
|
|
57822
57985
|
|
|
57823
57986
|
// src/worker-token.ts
|
|
57824
57987
|
var import_node_crypto10 = require("node:crypto");
|
|
57825
|
-
var
|
|
57826
|
-
var
|
|
57827
|
-
var
|
|
57988
|
+
var import_node_fs11 = require("node:fs");
|
|
57989
|
+
var import_node_os10 = __toESM(require("node:os"), 1);
|
|
57990
|
+
var import_node_path18 = __toESM(require("node:path"), 1);
|
|
57828
57991
|
var DEFAULT_WORKER_PORT = 8792;
|
|
57829
57992
|
function workerPort() {
|
|
57830
57993
|
const raw = process.env.MRRLIN_WORKER_PORT;
|
|
@@ -57833,15 +57996,15 @@ function workerPort() {
|
|
|
57833
57996
|
return Number.isFinite(parsed) && parsed > 0 ? parsed : DEFAULT_WORKER_PORT;
|
|
57834
57997
|
}
|
|
57835
57998
|
function workerDir() {
|
|
57836
|
-
const base = process.env.CODEX_HOME ?
|
|
57837
|
-
return
|
|
57999
|
+
const base = process.env.CODEX_HOME ? import_node_path18.default.join(process.env.CODEX_HOME, "mrrlin") : import_node_path18.default.join(import_node_os10.default.homedir(), ".mrrlin");
|
|
58000
|
+
return import_node_path18.default.join(base, "worker");
|
|
57838
58001
|
}
|
|
57839
58002
|
function workerTokenPath() {
|
|
57840
|
-
return
|
|
58003
|
+
return import_node_path18.default.join(workerDir(), "token");
|
|
57841
58004
|
}
|
|
57842
58005
|
function readWorkerToken() {
|
|
57843
58006
|
try {
|
|
57844
|
-
const token = (0,
|
|
58007
|
+
const token = (0, import_node_fs11.readFileSync)(workerTokenPath(), "utf8").trim();
|
|
57845
58008
|
return token.length > 0 ? token : null;
|
|
57846
58009
|
} catch {
|
|
57847
58010
|
return null;
|
|
@@ -57851,9 +58014,9 @@ function readOrCreateWorkerToken() {
|
|
|
57851
58014
|
const existing = readWorkerToken();
|
|
57852
58015
|
if (existing) return existing;
|
|
57853
58016
|
const dir = workerDir();
|
|
57854
|
-
(0,
|
|
58017
|
+
(0, import_node_fs11.mkdirSync)(dir, { recursive: true, mode: 448 });
|
|
57855
58018
|
const token = (0, import_node_crypto10.randomBytes)(32).toString("hex");
|
|
57856
|
-
(0,
|
|
58019
|
+
(0, import_node_fs11.writeFileSync)(workerTokenPath(), `${token}
|
|
57857
58020
|
`, { encoding: "utf8", mode: 384 });
|
|
57858
58021
|
return token;
|
|
57859
58022
|
}
|
|
@@ -57922,6 +58085,8 @@ var mcpToolNames = {
|
|
|
57922
58085
|
recordProducedUrl: "record_produced_url",
|
|
57923
58086
|
updateTaskState: "update_task_state",
|
|
57924
58087
|
registerLocalCheckout: "register_local_checkout",
|
|
58088
|
+
initLocalRepo: "init_local_repo",
|
|
58089
|
+
setProjectCodeHost: "set_project_code_host",
|
|
57925
58090
|
/** Compact-context retrieval: rehydrate a mrrlin:// handle into the canonical full record. */
|
|
57926
58091
|
retrieveContext: "retrieve_context"
|
|
57927
58092
|
};
|
|
@@ -58625,8 +58790,17 @@ var createInboxItemInputSchema = projectScopedSchema.merge(mrrlinInboxItemCreate
|
|
|
58625
58790
|
var decideInboxItemInputSchema = projectScopedSchema.extend({ itemId: mrrlinInboxItemIdSchema }).merge(mrrlinInboxItemDecideSchema);
|
|
58626
58791
|
var resolveHandoffInputSchema = projectScopedSchema.extend({ runId: mrrlinExecutionRunIdSchema }).merge(mrrlinResolveHandoffSchema);
|
|
58627
58792
|
var registerLocalCheckoutInputSchema = projectScopedSchema.extend({
|
|
58628
|
-
path: external_exports.string().min(1).describe("Absolute path to the local git checkout (must be a git repo whose origin matches `repo`)."),
|
|
58629
|
-
repo: external_exports.string().min(1).describe(
|
|
58793
|
+
path: external_exports.string().min(1).describe("Absolute path to the local git checkout (must be a git repo whose origin matches `repo`, or, with no `repo`, the top of a git repo)."),
|
|
58794
|
+
repo: external_exports.string().min(1).optional().describe(
|
|
58795
|
+
"The project's bound GitHub repo full name in `owner/repo` form. Omit it for a project with no GitHub (its code lives only on this computer): the folder then only has to be a git repository the operator owns."
|
|
58796
|
+
)
|
|
58797
|
+
});
|
|
58798
|
+
var initLocalRepoInputSchema = projectScopedSchema.extend({
|
|
58799
|
+
path: external_exports.string().min(1).describe("Absolute path to the operator's project folder (not inside any git repository)."),
|
|
58800
|
+
operatorConsent: external_exports.literal(true).describe("true only after the operator explicitly agreed in chat that this folder may become a git repository.")
|
|
58801
|
+
});
|
|
58802
|
+
var setProjectCodeHostInputSchema = projectScopedSchema.extend({
|
|
58803
|
+
codeHost: mrrlinProjectCodeHostSchema.nullable().describe("local = keep code only on this computer; github / gitlab = the operator wants to push there (connect it next); null = not decided.")
|
|
58630
58804
|
});
|
|
58631
58805
|
var retrieveContextInputSchema = external_exports.object({
|
|
58632
58806
|
handle: external_exports.string().min(1).describe(
|
|
@@ -58699,6 +58873,8 @@ var mcpToolInputSchemas = {
|
|
|
58699
58873
|
[mcpToolNames.recordProducedUrl]: recordProducedUrlInputSchema,
|
|
58700
58874
|
[mcpToolNames.updateTaskState]: updateTaskStateInputSchema,
|
|
58701
58875
|
[mcpToolNames.registerLocalCheckout]: registerLocalCheckoutInputSchema,
|
|
58876
|
+
[mcpToolNames.initLocalRepo]: initLocalRepoInputSchema,
|
|
58877
|
+
[mcpToolNames.setProjectCodeHost]: setProjectCodeHostInputSchema,
|
|
58702
58878
|
[mcpToolNames.retrieveContext]: retrieveContextInputSchema
|
|
58703
58879
|
};
|
|
58704
58880
|
var mcpToolOperationIds = {
|
|
@@ -58821,7 +58997,9 @@ var mcpToolDescriptions = {
|
|
|
58821
58997
|
[mcpToolNames.restartExecutionRun]: "Restart a parked execution run (handoff_requested or handoff_queued) back to pending so the queue can resume it.",
|
|
58822
58998
|
[mcpToolNames.stopExecutionRun]: "Operator stop: park an in-flight execution run at handoff_requested with blockingReason operator_stopped. Parks rather than cancels, so restart_execution_run can resume it later. Refuses (409) a run already at a terminal status.",
|
|
58823
58999
|
[mcpToolNames.resolveHandoff]: "Resolve a tool_assisted handoff for an execution run (outcome success|failure). Success returns the task to the board; failure opens a new handoff cycle. Idempotent.",
|
|
58824
|
-
[mcpToolNames.registerLocalCheckout]: "Register the operator-local git checkout path for `projectSlug` so execution-run workers run code on this machine instead of the cloud. Validates the path is a git repo whose `origin` remote matches `repo`, then writes the (slug -> absolute path) entry to the operator-local checkout registry. Call this after locating the checkout on disk (e.g. via filesystem search) and confirming the choice with the user in chat \u2014 they should NOT have to paste the path into Settings. Returns `{ projectSlug, path, confirmedAt }`. Idempotent: re-registering overwrites the prior entry.",
|
|
59000
|
+
[mcpToolNames.registerLocalCheckout]: "Register the operator-local git checkout path for `projectSlug` so execution-run workers run code on this machine instead of the cloud. Validates the path is a git repo whose `origin` remote matches `repo`, then writes the (slug -> absolute path) entry to the operator-local checkout registry. For a project with no GitHub (code kept only on this computer), omit `repo`: the path must then be the top of a git repository owned by the operator, not the home folder or a system folder. Call this after locating the checkout on disk (e.g. via filesystem search) and confirming the choice with the user in chat \u2014 they should NOT have to paste the path into Settings. Returns `{ projectSlug, path, confirmedAt }`. Idempotent: re-registering overwrites the prior entry.",
|
|
59001
|
+
[mcpToolNames.initLocalRepo]: "For a project with no GitHub whose folder is not a git repository yet: run `git init` and one initial commit in the operator's own folder, then register it. Call ONLY after asking the operator in chat, in plain words, and getting an explicit yes; pass operatorConsent: true. Refuses a folder already inside a git repository, the home folder, a filesystem root or a system folder. Adds a default .gitignore (node_modules, build output, .env files) only when the folder has none.",
|
|
59002
|
+
[mcpToolNames.setProjectCodeHost]: "Record where this project's code lives, after the operator answered the code-host question: local (keep it on this computer), github or gitlab (they want to push there; connect it next). Does not move any code.",
|
|
58825
59003
|
[mcpToolNames.retrieveContext]: "Rehydrate a mrrlin:// handle emitted by the compact-context layer into the full canonical Mrrlin record (task/wiki page/project snapshot/execution run/artifacts). Use whenever you need the full source \u2014 irreversible decisions (closing tasks, dispatching deploys, writing specs) MUST call this first; never act on a compact envelope alone. Returns `{ kind, data }`. Invalid or unsupported handle \u2192 structured `HANDLE_INVALID` error."
|
|
58826
59004
|
};
|
|
58827
59005
|
var ARTIFACT_EXTENSION_TYPES = {
|
|
@@ -59793,7 +59971,7 @@ function createMrrlinTools(options) {
|
|
|
59793
59971
|
"Unable to upload artifact file.",
|
|
59794
59972
|
async (c, { projectSlug, path: filePath, class: artifactClass, taskId, runId, description }) => {
|
|
59795
59973
|
await checkTenantBoundary(projectSlug, "artifact upload");
|
|
59796
|
-
const extension2 =
|
|
59974
|
+
const extension2 = import_node_path19.default.extname(filePath).toLowerCase();
|
|
59797
59975
|
const contentType2 = ARTIFACT_EXTENSION_TYPES[extension2];
|
|
59798
59976
|
if (!contentType2) {
|
|
59799
59977
|
throw new McpToolCodedError(
|
|
@@ -59821,7 +59999,7 @@ function createMrrlinTools(options) {
|
|
|
59821
59999
|
"Artifact exceeds 5MB; split or summarize instead."
|
|
59822
60000
|
);
|
|
59823
60001
|
}
|
|
59824
|
-
const filename =
|
|
60002
|
+
const filename = import_node_path19.default.basename(filePath);
|
|
59825
60003
|
return deliverBuiltIn(
|
|
59826
60004
|
c,
|
|
59827
60005
|
projectSlug,
|
|
@@ -59844,7 +60022,7 @@ function createMrrlinTools(options) {
|
|
|
59844
60022
|
`Invalid filename '${filename}'; provide a bare filename with no path separators or '..'.`
|
|
59845
60023
|
);
|
|
59846
60024
|
}
|
|
59847
|
-
const extension2 =
|
|
60025
|
+
const extension2 = import_node_path19.default.extname(filename).toLowerCase();
|
|
59848
60026
|
const contentType2 = ARTIFACT_EXTENSION_TYPES[extension2];
|
|
59849
60027
|
if (!contentType2) {
|
|
59850
60028
|
throw new McpToolCodedError(
|
|
@@ -59929,10 +60107,37 @@ function createMrrlinTools(options) {
|
|
|
59929
60107
|
mcpToolNames.registerLocalCheckout,
|
|
59930
60108
|
"LOCAL_CHECKOUT_REGISTER_FAILED",
|
|
59931
60109
|
"Unable to register local checkout.",
|
|
59932
|
-
async (
|
|
60110
|
+
async (c, { projectSlug, path: checkoutPath, repo }) => {
|
|
59933
60111
|
await checkTenantBoundary(projectSlug, "local checkout");
|
|
59934
60112
|
const registry3 = new CheckoutRegistry(resolveStateDir());
|
|
59935
|
-
|
|
60113
|
+
if (!repo) {
|
|
60114
|
+
const snapshot = await c.getProjectSnapshot(projectSlug);
|
|
60115
|
+
const local = registerLocalOnlyCheckout(
|
|
60116
|
+
registry3,
|
|
60117
|
+
{
|
|
60118
|
+
projectSlug,
|
|
60119
|
+
path: checkoutPath,
|
|
60120
|
+
project: { codeHost: snapshot.project.codeHost ?? null, githubRepo: snapshot.github?.repo ?? null }
|
|
60121
|
+
},
|
|
60122
|
+
import_node_os11.default.hostname()
|
|
60123
|
+
);
|
|
60124
|
+
if (!local.ok) {
|
|
60125
|
+
const localCodeMap = {
|
|
60126
|
+
not_absolute: "LOCAL_CHECKOUT_PATH_NOT_ABSOLUTE",
|
|
60127
|
+
not_found: "LOCAL_CHECKOUT_PATH_NOT_FOUND",
|
|
60128
|
+
not_a_directory: "LOCAL_CHECKOUT_PATH_NOT_FOUND",
|
|
60129
|
+
not_owned: "LOCAL_CHECKOUT_PATH_FORBIDDEN",
|
|
60130
|
+
forbidden_path: "LOCAL_CHECKOUT_PATH_FORBIDDEN",
|
|
60131
|
+
path_changed: "LOCAL_CHECKOUT_PATH_FORBIDDEN",
|
|
60132
|
+
not_a_git_repo: "LOCAL_CHECKOUT_NOT_A_GIT_REPO",
|
|
60133
|
+
inside_git_repo: "LOCAL_CHECKOUT_NOT_A_GIT_REPO",
|
|
60134
|
+
not_local_project: "LOCAL_CHECKOUT_REPO_REQUIRED"
|
|
60135
|
+
};
|
|
60136
|
+
throw new McpToolCodedError(localCodeMap[local.code], local.detail);
|
|
60137
|
+
}
|
|
60138
|
+
return local.data;
|
|
60139
|
+
}
|
|
60140
|
+
const result = registerCheckout(registry3, { projectSlug, path: checkoutPath, repo }, import_node_os11.default.hostname());
|
|
59936
60141
|
if (!result.ok) {
|
|
59937
60142
|
const codeMap = {
|
|
59938
60143
|
not_absolute: "LOCAL_CHECKOUT_PATH_NOT_ABSOLUTE",
|
|
@@ -59945,6 +60150,53 @@ function createMrrlinTools(options) {
|
|
|
59945
60150
|
return result.data;
|
|
59946
60151
|
}
|
|
59947
60152
|
),
|
|
60153
|
+
[mcpToolNames.initLocalRepo]: makeTool(
|
|
60154
|
+
client,
|
|
60155
|
+
mcpToolNames.initLocalRepo,
|
|
60156
|
+
"LOCAL_REPO_INIT_FAILED",
|
|
60157
|
+
"Unable to initialise the local repository.",
|
|
60158
|
+
async (c, { projectSlug, path: folder, operatorConsent }) => {
|
|
60159
|
+
await checkTenantBoundary(projectSlug, "local repository");
|
|
60160
|
+
const snapshot = await c.getProjectSnapshot(projectSlug);
|
|
60161
|
+
const result = initLocalRepo(
|
|
60162
|
+
new CheckoutRegistry(resolveStateDir()),
|
|
60163
|
+
{
|
|
60164
|
+
projectSlug,
|
|
60165
|
+
path: folder,
|
|
60166
|
+
operatorConsent,
|
|
60167
|
+
project: { codeHost: snapshot.project.codeHost ?? null, githubRepo: snapshot.github?.repo ?? null }
|
|
60168
|
+
},
|
|
60169
|
+
import_node_os11.default.hostname()
|
|
60170
|
+
);
|
|
60171
|
+
if (!result.ok) {
|
|
60172
|
+
const codeMap = {
|
|
60173
|
+
not_absolute: "LOCAL_CHECKOUT_PATH_NOT_ABSOLUTE",
|
|
60174
|
+
not_found: "LOCAL_CHECKOUT_PATH_NOT_FOUND",
|
|
60175
|
+
not_a_directory: "LOCAL_CHECKOUT_PATH_NOT_FOUND",
|
|
60176
|
+
not_owned: "LOCAL_CHECKOUT_PATH_FORBIDDEN",
|
|
60177
|
+
forbidden_path: "LOCAL_CHECKOUT_PATH_FORBIDDEN",
|
|
60178
|
+
path_changed: "LOCAL_CHECKOUT_PATH_FORBIDDEN",
|
|
60179
|
+
not_a_git_repo: "LOCAL_CHECKOUT_NOT_A_GIT_REPO",
|
|
60180
|
+
inside_git_repo: "LOCAL_REPO_ALREADY_EXISTS",
|
|
60181
|
+
not_local_project: "LOCAL_CHECKOUT_REPO_REQUIRED",
|
|
60182
|
+
consent_required: "LOCAL_REPO_CONSENT_REQUIRED",
|
|
60183
|
+
init_failed: "LOCAL_REPO_INIT_FAILED"
|
|
60184
|
+
};
|
|
60185
|
+
throw new McpToolCodedError(codeMap[result.code], result.detail);
|
|
60186
|
+
}
|
|
60187
|
+
return result.data;
|
|
60188
|
+
}
|
|
60189
|
+
),
|
|
60190
|
+
[mcpToolNames.setProjectCodeHost]: makeTool(
|
|
60191
|
+
client,
|
|
60192
|
+
mcpToolNames.setProjectCodeHost,
|
|
60193
|
+
"PROJECT_CODE_HOST_FAILED",
|
|
60194
|
+
"Unable to record where the project's code lives.",
|
|
60195
|
+
async (c, { projectSlug, codeHost }) => {
|
|
60196
|
+
await checkTenantBoundary(projectSlug, "project code host");
|
|
60197
|
+
return await c.renameProject(projectSlug, { codeHost });
|
|
60198
|
+
}
|
|
60199
|
+
),
|
|
59948
60200
|
[mcpToolNames.retrieveContext]: makeTool(
|
|
59949
60201
|
client,
|
|
59950
60202
|
mcpToolNames.retrieveContext,
|
|
@@ -60033,20 +60285,20 @@ function allAgyGrantStrings() {
|
|
|
60033
60285
|
}
|
|
60034
60286
|
function resolveAgyConfigPath(options) {
|
|
60035
60287
|
if (options.agyConfigPath) return options.agyConfigPath;
|
|
60036
|
-
return
|
|
60288
|
+
return import_node_path20.default.join(options.homeDir ?? import_node_os12.default.homedir(), ".gemini", "config", "mcp_config.json");
|
|
60037
60289
|
}
|
|
60038
60290
|
function resolveConfigJsonPath(options) {
|
|
60039
60291
|
if (options.configJsonPath) return options.configJsonPath;
|
|
60040
|
-
return
|
|
60292
|
+
return import_node_path20.default.join(options.homeDir ?? import_node_os12.default.homedir(), ".gemini", "config", "config.json");
|
|
60041
60293
|
}
|
|
60042
60294
|
async function detectInstallDistribution3(options) {
|
|
60043
60295
|
if (options.distribution && options.distribution !== "auto") return options.distribution;
|
|
60044
|
-
let current2 =
|
|
60296
|
+
let current2 = import_node_path20.default.dirname(options.binPath);
|
|
60045
60297
|
while (true) {
|
|
60046
|
-
if (await pathExists4(
|
|
60298
|
+
if (await pathExists4(import_node_path20.default.join(current2, "pnpm-workspace.yaml"))) {
|
|
60047
60299
|
return "local";
|
|
60048
60300
|
}
|
|
60049
|
-
const parent =
|
|
60301
|
+
const parent = import_node_path20.default.dirname(current2);
|
|
60050
60302
|
if (parent === current2) break;
|
|
60051
60303
|
current2 = parent;
|
|
60052
60304
|
}
|
|
@@ -60068,7 +60320,7 @@ function browserTable3(binPath, distribution, homeDir) {
|
|
|
60068
60320
|
return { ...base, env: { PLAYWRIGHT_BROWSERS_PATH: browserPaths(homeDir).browsersPath } };
|
|
60069
60321
|
}
|
|
60070
60322
|
function managedEntries2(options, distribution) {
|
|
60071
|
-
const homeDir = options.homeDir ??
|
|
60323
|
+
const homeDir = options.homeDir ?? import_node_os12.default.homedir();
|
|
60072
60324
|
return [
|
|
60073
60325
|
{ id: "mrrlin", expected: mrrlinTable3(options.binPath, distribution, options.serveEnv) },
|
|
60074
60326
|
{ id: "mrrlin-browser", expected: browserTable3(options.binPath, distribution, homeDir) },
|
|
@@ -60088,8 +60340,8 @@ async function installAgy(options) {
|
|
|
60088
60340
|
const configJsonPath = resolveConfigJsonPath(options);
|
|
60089
60341
|
const distribution = await detectInstallDistribution3(options);
|
|
60090
60342
|
const entries = managedEntries2(options, distribution);
|
|
60091
|
-
await import_promises9.default.mkdir(
|
|
60092
|
-
await import_promises9.default.mkdir(
|
|
60343
|
+
await import_promises9.default.mkdir(import_node_path20.default.dirname(configPath), { recursive: true });
|
|
60344
|
+
await import_promises9.default.mkdir(import_node_path20.default.dirname(configJsonPath), { recursive: true });
|
|
60093
60345
|
let action = "noop";
|
|
60094
60346
|
const preservedEnvBlocks = [];
|
|
60095
60347
|
if (!await pathExists4(configPath)) {
|
|
@@ -60205,14 +60457,14 @@ async function installAgy(options) {
|
|
|
60205
60457
|
|
|
60206
60458
|
// src/provider-readiness.ts
|
|
60207
60459
|
var import_promises10 = require("node:fs/promises");
|
|
60208
|
-
var
|
|
60209
|
-
var
|
|
60210
|
-
var
|
|
60460
|
+
var import_node_fs12 = require("node:fs");
|
|
60461
|
+
var import_node_os13 = __toESM(require("node:os"), 1);
|
|
60462
|
+
var import_node_path21 = __toESM(require("node:path"), 1);
|
|
60211
60463
|
var import_semver2 = __toESM(require_semver2(), 1);
|
|
60212
60464
|
var toml3 = __toESM(require_toml(), 1);
|
|
60213
60465
|
|
|
60214
60466
|
// src/agent-version.ts
|
|
60215
|
-
var
|
|
60467
|
+
var import_node_child_process15 = require("node:child_process");
|
|
60216
60468
|
var import_semver = __toESM(require_semver2(), 1);
|
|
60217
60469
|
var SEMVER_RE = /\b\d+\.\d+\.\d+(?:-[A-Za-z0-9.-]+)?\b/;
|
|
60218
60470
|
var CODEX_PACKAGE = process.env.MRRLIN_CODEX_PACKAGE?.trim() || "@openai/codex";
|
|
@@ -60222,7 +60474,7 @@ function parseCodexVersion(raw) {
|
|
|
60222
60474
|
return m ? m[0] : null;
|
|
60223
60475
|
}
|
|
60224
60476
|
var defaultRun = (args) => {
|
|
60225
|
-
const r = (0,
|
|
60477
|
+
const r = (0, import_node_child_process15.spawnSync)("codex", args, { encoding: "utf8", timeout: 8e3, shell: true });
|
|
60226
60478
|
return { status: r.status, stdout: r.stdout ?? "", stderr: r.stderr ?? "" };
|
|
60227
60479
|
};
|
|
60228
60480
|
function getInstalledAgentVersion(provider, run3) {
|
|
@@ -60298,13 +60550,13 @@ function startCodexProbe(deps = {}) {
|
|
|
60298
60550
|
// src/provider-readiness.ts
|
|
60299
60551
|
function resolveCodexHome2(opts) {
|
|
60300
60552
|
if (opts.codexHome) return opts.codexHome;
|
|
60301
|
-
if (opts.homeDir) return
|
|
60553
|
+
if (opts.homeDir) return import_node_path21.default.join(opts.homeDir, ".codex");
|
|
60302
60554
|
if (process.env.CODEX_HOME) return process.env.CODEX_HOME;
|
|
60303
|
-
return
|
|
60555
|
+
return import_node_path21.default.join(import_node_os13.default.homedir(), ".codex");
|
|
60304
60556
|
}
|
|
60305
60557
|
function resolveClaudeConfigPath2(opts) {
|
|
60306
60558
|
if (opts.claudeConfigPath) return opts.claudeConfigPath;
|
|
60307
|
-
return
|
|
60559
|
+
return import_node_path21.default.join(opts.homeDir ?? import_node_os13.default.homedir(), ".claude.json");
|
|
60308
60560
|
}
|
|
60309
60561
|
function isExternalAgentsWrapper(table) {
|
|
60310
60562
|
if (!table) return false;
|
|
@@ -60373,9 +60625,9 @@ async function verifyProviderReadiness(provider, run3, opts = {}) {
|
|
|
60373
60625
|
if (!checks.version) details.push(`version: ${version2 ?? "unparseable"} is below the required 2.1.232`);
|
|
60374
60626
|
}
|
|
60375
60627
|
if (provider === "codex") {
|
|
60376
|
-
const authPath =
|
|
60628
|
+
const authPath = import_node_path21.default.join(resolveCodexHome2(opts), "auth.json");
|
|
60377
60629
|
try {
|
|
60378
|
-
await (0, import_promises10.access)(authPath,
|
|
60630
|
+
await (0, import_promises10.access)(authPath, import_node_fs12.constants.F_OK);
|
|
60379
60631
|
checks.auth = true;
|
|
60380
60632
|
} catch {
|
|
60381
60633
|
details.push(`auth: ${authPath} not found`);
|
|
@@ -60390,7 +60642,7 @@ async function verifyProviderReadiness(provider, run3, opts = {}) {
|
|
|
60390
60642
|
if (!checks.auth) details.push("auth: `claude auth status` failed");
|
|
60391
60643
|
}
|
|
60392
60644
|
if (provider === "codex") {
|
|
60393
|
-
const configPath =
|
|
60645
|
+
const configPath = import_node_path21.default.join(resolveCodexHome2(opts), "config.toml");
|
|
60394
60646
|
try {
|
|
60395
60647
|
const raw = await (0, import_promises10.readFile)(configPath, "utf8");
|
|
60396
60648
|
const parsed = toml3.parse(raw);
|
|
@@ -60441,9 +60693,9 @@ async function verifyProviderReadiness(provider, run3, opts = {}) {
|
|
|
60441
60693
|
}
|
|
60442
60694
|
|
|
60443
60695
|
// src/browser-interceptor.ts
|
|
60444
|
-
var
|
|
60696
|
+
var import_node_os14 = __toESM(require("node:os"), 1);
|
|
60445
60697
|
var import_node_readline = __toESM(require("node:readline"), 1);
|
|
60446
|
-
var
|
|
60698
|
+
var import_node_child_process16 = require("node:child_process");
|
|
60447
60699
|
var INTERNAL_HOST_PATTERNS = [
|
|
60448
60700
|
/^(?:.*\.)?mrrlin\.(?:com|internal|local)$/i,
|
|
60449
60701
|
/^(?:localhost|127\.0\.0\.1)(?::\d+)?$/i
|
|
@@ -60615,7 +60867,7 @@ function wireBrowserServeProxy(streams) {
|
|
|
60615
60867
|
}
|
|
60616
60868
|
function signalToExitCode(signal) {
|
|
60617
60869
|
if (!signal) return 1;
|
|
60618
|
-
const sigNum =
|
|
60870
|
+
const sigNum = import_node_os14.default.constants.signals[signal];
|
|
60619
60871
|
if (typeof sigNum === "number") {
|
|
60620
60872
|
return 128 + sigNum;
|
|
60621
60873
|
}
|
|
@@ -60624,7 +60876,7 @@ function signalToExitCode(signal) {
|
|
|
60624
60876
|
async function runBrowserServeProxy(opts) {
|
|
60625
60877
|
const input = opts.input ?? process.stdin;
|
|
60626
60878
|
const output3 = opts.output ?? process.stdout;
|
|
60627
|
-
const child = (0,
|
|
60879
|
+
const child = (0, import_node_child_process16.spawn)(opts.command, opts.args, {
|
|
60628
60880
|
stdio: ["pipe", "pipe", "inherit"],
|
|
60629
60881
|
env: { ...process.env, ...opts.env }
|
|
60630
60882
|
});
|
|
@@ -60671,12 +60923,12 @@ async function runBrowserServeProxy(opts) {
|
|
|
60671
60923
|
}
|
|
60672
60924
|
|
|
60673
60925
|
// src/director-bridge.ts
|
|
60674
|
-
var
|
|
60926
|
+
var import_node_fs27 = __toESM(require("node:fs"), 1);
|
|
60675
60927
|
var import_node_http3 = __toESM(require("node:http"), 1);
|
|
60676
|
-
var
|
|
60677
|
-
var
|
|
60678
|
-
var
|
|
60679
|
-
var
|
|
60928
|
+
var import_node_os21 = __toESM(require("node:os"), 1);
|
|
60929
|
+
var import_node_path42 = __toESM(require("node:path"), 1);
|
|
60930
|
+
var import_node_child_process25 = require("node:child_process");
|
|
60931
|
+
var import_node_crypto21 = __toESM(require("node:crypto"), 1);
|
|
60680
60932
|
|
|
60681
60933
|
// src/turn-replay-buffer.ts
|
|
60682
60934
|
var DEFAULT_MAX_EVENTS = 2e3;
|
|
@@ -61220,17 +61472,17 @@ function createTurnLock() {
|
|
|
61220
61472
|
}
|
|
61221
61473
|
|
|
61222
61474
|
// src/self-update.ts
|
|
61223
|
-
var
|
|
61475
|
+
var import_node_child_process18 = require("node:child_process");
|
|
61224
61476
|
var import_node_crypto12 = require("node:crypto");
|
|
61225
|
-
var
|
|
61226
|
-
var
|
|
61477
|
+
var import_node_fs14 = require("node:fs");
|
|
61478
|
+
var import_node_path23 = __toESM(require("node:path"), 1);
|
|
61227
61479
|
var import_semver3 = __toESM(require_semver2(), 1);
|
|
61228
61480
|
|
|
61229
61481
|
// src/codex-auth-preflight.ts
|
|
61230
|
-
var
|
|
61231
|
-
var
|
|
61232
|
-
var
|
|
61233
|
-
var
|
|
61482
|
+
var import_node_child_process17 = require("node:child_process");
|
|
61483
|
+
var import_node_fs13 = require("node:fs");
|
|
61484
|
+
var import_node_os15 = __toESM(require("node:os"), 1);
|
|
61485
|
+
var import_node_path22 = __toESM(require("node:path"), 1);
|
|
61234
61486
|
var DEFAULT_CODEX_AUTH_MIN_TTL_SECONDS = 15 * 60;
|
|
61235
61487
|
var DEFAULT_CODEX_AUTH_SMOKE_TIMEOUT_MS = 2e4;
|
|
61236
61488
|
var DEFAULT_CODEX_AUTH_SMOKE_MODEL = "gpt-5.4-mini";
|
|
@@ -61249,7 +61501,7 @@ function codexAuthSmokeTimeoutMs(env = process.env) {
|
|
|
61249
61501
|
function resolveCodexAuthPath(opts = {}) {
|
|
61250
61502
|
const env = opts.env ?? process.env;
|
|
61251
61503
|
const codexHome = env.CODEX_HOME?.trim();
|
|
61252
|
-
return
|
|
61504
|
+
return import_node_path22.default.join(codexHome || import_node_path22.default.join(opts.homeDir ?? import_node_os15.default.homedir(), ".codex"), "auth.json");
|
|
61253
61505
|
}
|
|
61254
61506
|
function decodeJwtExpMs(token) {
|
|
61255
61507
|
const parts = token.split(".");
|
|
@@ -61310,7 +61562,7 @@ function runCodexAuthRefreshSmokeForBridgeUpdate(opts = {}) {
|
|
|
61310
61562
|
const configuredExecutable = opts.codexExecutable ?? env.MRRLIN_DIRECTOR_BRIDGE_CODEX_BIN?.trim();
|
|
61311
61563
|
const executable = configuredExecutable || "codex";
|
|
61312
61564
|
const timeoutMs = opts.timeoutMs ?? codexAuthSmokeTimeoutMs(env);
|
|
61313
|
-
const cwd = opts.cwd ??
|
|
61565
|
+
const cwd = opts.cwd ?? import_node_os15.default.tmpdir();
|
|
61314
61566
|
const args = [
|
|
61315
61567
|
"exec",
|
|
61316
61568
|
"--sandbox",
|
|
@@ -61321,9 +61573,9 @@ function runCodexAuthRefreshSmokeForBridgeUpdate(opts = {}) {
|
|
|
61321
61573
|
CODEX_AUTH_SMOKE_PROMPT
|
|
61322
61574
|
];
|
|
61323
61575
|
const command = commandForSmoke(executable, model);
|
|
61324
|
-
const
|
|
61576
|
+
const execFileSync7 = opts.execFileSyncImpl ?? import_node_child_process17.execFileSync;
|
|
61325
61577
|
try {
|
|
61326
|
-
|
|
61578
|
+
execFileSync7(executable, args, {
|
|
61327
61579
|
cwd,
|
|
61328
61580
|
env,
|
|
61329
61581
|
encoding: "utf8",
|
|
@@ -61370,7 +61622,7 @@ function inspectCodexAuthForBridgeUpdate(opts = {}) {
|
|
|
61370
61622
|
const nowMs = opts.nowMs ?? Date.now();
|
|
61371
61623
|
const minTtlSeconds = opts.minTtlSeconds ?? codexAuthMinTtlSeconds(env);
|
|
61372
61624
|
const authPath = resolveCodexAuthPath({ env, homeDir: opts.homeDir });
|
|
61373
|
-
const readFile9 = opts.readFileSyncImpl ?? ((p, encoding) => (0,
|
|
61625
|
+
const readFile9 = opts.readFileSyncImpl ?? ((p, encoding) => (0, import_node_fs13.readFileSync)(p, encoding));
|
|
61374
61626
|
let raw;
|
|
61375
61627
|
try {
|
|
61376
61628
|
raw = readFile9(authPath, "utf8");
|
|
@@ -61484,26 +61736,26 @@ function inspectCodexAuthForBridgeUpdate(opts = {}) {
|
|
|
61484
61736
|
var BIN_NAME = "mrrlin-mcp";
|
|
61485
61737
|
var SELF_UPDATE_AUTH_PREFLIGHT_OFFER_PREFIX = "[bridge:update:auth-preflight]";
|
|
61486
61738
|
function resolveBinPath(opts) {
|
|
61487
|
-
if (opts.argv1 &&
|
|
61739
|
+
if (opts.argv1 && import_node_path23.default.basename(opts.argv1).includes("mrrlin")) {
|
|
61488
61740
|
return { path: opts.argv1, source: "argv" };
|
|
61489
61741
|
}
|
|
61490
61742
|
const whichSync = opts.whichSync ?? ((name) => {
|
|
61491
61743
|
try {
|
|
61492
|
-
return (0,
|
|
61744
|
+
return (0, import_node_child_process18.execFileSync)("which", [name], { encoding: "utf8", timeout: 3e3 }).trim() || null;
|
|
61493
61745
|
} catch {
|
|
61494
61746
|
return null;
|
|
61495
61747
|
}
|
|
61496
61748
|
});
|
|
61497
|
-
const
|
|
61749
|
+
const existsSync6 = opts.existsSync ?? import_node_fs14.existsSync;
|
|
61498
61750
|
const resolved = whichSync(BIN_NAME);
|
|
61499
|
-
if (resolved &&
|
|
61751
|
+
if (resolved && existsSync6(resolved)) {
|
|
61500
61752
|
return { path: resolved, source: "which" };
|
|
61501
61753
|
}
|
|
61502
61754
|
const envPath = (opts.env ?? process.env).PATH ?? "";
|
|
61503
|
-
for (const dir of envPath.split(
|
|
61755
|
+
for (const dir of envPath.split(import_node_path23.default.delimiter)) {
|
|
61504
61756
|
if (!dir) continue;
|
|
61505
|
-
const candidate =
|
|
61506
|
-
if (
|
|
61757
|
+
const candidate = import_node_path23.default.join(dir, BIN_NAME);
|
|
61758
|
+
if (existsSync6(candidate)) {
|
|
61507
61759
|
return { path: candidate, source: "path-walk" };
|
|
61508
61760
|
}
|
|
61509
61761
|
}
|
|
@@ -61533,7 +61785,7 @@ function sha256(buf) {
|
|
|
61533
61785
|
function startSelfUpdate(deps) {
|
|
61534
61786
|
const log = deps.log ?? (() => {
|
|
61535
61787
|
});
|
|
61536
|
-
const readFile9 = deps.readFileSyncImpl ?? ((p) => (0,
|
|
61788
|
+
const readFile9 = deps.readFileSyncImpl ?? ((p) => (0, import_node_fs14.readFileSync)(p));
|
|
61537
61789
|
const setIntervalFn = deps.setIntervalImpl ?? setInterval;
|
|
61538
61790
|
const clearIntervalFn = deps.clearIntervalImpl ?? clearInterval;
|
|
61539
61791
|
const intervalMs = deps.intervalMs ?? readIntervalEnv("MRRLIN_DIRECTOR_BRIDGE_SELF_UPDATE_INTERVAL_MS", DEFAULT_INTERVAL_MS);
|
|
@@ -61820,7 +62072,7 @@ Do NOT derail the current task - if the operator has an in-flight question, answ
|
|
|
61820
62072
|
}
|
|
61821
62073
|
|
|
61822
62074
|
// src/_generated/version.ts
|
|
61823
|
-
var PKG_VERSION = "0.4.
|
|
62075
|
+
var PKG_VERSION = "0.4.118";
|
|
61824
62076
|
|
|
61825
62077
|
// src/receipt-signing.ts
|
|
61826
62078
|
var import_node_crypto13 = __toESM(require("node:crypto"), 1);
|
|
@@ -62704,14 +62956,14 @@ function parseLedger(value) {
|
|
|
62704
62956
|
}
|
|
62705
62957
|
|
|
62706
62958
|
// src/api-base-url-migrate.ts
|
|
62707
|
-
var
|
|
62708
|
-
var
|
|
62709
|
-
var
|
|
62959
|
+
var import_node_fs15 = __toESM(require("node:fs"), 1);
|
|
62960
|
+
var import_node_os16 = __toESM(require("node:os"), 1);
|
|
62961
|
+
var import_node_path25 = __toESM(require("node:path"), 1);
|
|
62710
62962
|
|
|
62711
62963
|
// src/service-paths.ts
|
|
62712
|
-
var
|
|
62964
|
+
var import_node_path24 = __toESM(require("node:path"), 1);
|
|
62713
62965
|
function isWorktreePath(p) {
|
|
62714
|
-
const norm =
|
|
62966
|
+
const norm = import_node_path24.default.normalize(p).split(import_node_path24.default.sep).join("/");
|
|
62715
62967
|
return norm.includes("/.claude/worktrees/");
|
|
62716
62968
|
}
|
|
62717
62969
|
function resolveServiceCwd(opts) {
|
|
@@ -62783,20 +63035,20 @@ ${envLines}
|
|
|
62783
63035
|
|
|
62784
63036
|
// src/api-base-url-migrate.ts
|
|
62785
63037
|
function defaultDeps(deps) {
|
|
62786
|
-
const home = deps.home ?? process.env.HOME ??
|
|
63038
|
+
const home = deps.home ?? process.env.HOME ?? import_node_os16.default.homedir();
|
|
62787
63039
|
return {
|
|
62788
63040
|
home,
|
|
62789
|
-
codexHome: deps.codexHome ?? process.env.CODEX_HOME?.trim() ??
|
|
62790
|
-
readFile: deps.readFile ?? ((p) =>
|
|
63041
|
+
codexHome: deps.codexHome ?? process.env.CODEX_HOME?.trim() ?? import_node_path25.default.join(home, ".codex"),
|
|
63042
|
+
readFile: deps.readFile ?? ((p) => import_node_fs15.default.readFileSync(p, "utf8")),
|
|
62791
63043
|
// Temp-file + atomic rename so a concurrent `serve` and `director-bridge` startup can never
|
|
62792
63044
|
// interleave partial writes into a config the next start has to parse. Note this normalizes the
|
|
62793
63045
|
// file to 0o600 — deliberate, since both files can carry a credential-bearing URL.
|
|
62794
63046
|
writeFile: deps.writeFile ?? ((p, c) => {
|
|
62795
63047
|
const tmp = `${p}.tmp-${process.pid}`;
|
|
62796
|
-
|
|
62797
|
-
|
|
63048
|
+
import_node_fs15.default.writeFileSync(tmp, c, { mode: 384 });
|
|
63049
|
+
import_node_fs15.default.renameSync(tmp, p);
|
|
62798
63050
|
}),
|
|
62799
|
-
exists: deps.exists ?? ((p) =>
|
|
63051
|
+
exists: deps.exists ?? ((p) => import_node_fs15.default.existsSync(p)),
|
|
62800
63052
|
log: deps.log ?? ((m) => process.stderr.write(`${m}
|
|
62801
63053
|
`))
|
|
62802
63054
|
};
|
|
@@ -62835,7 +63087,7 @@ function backupOnce(file2, text, deps) {
|
|
|
62835
63087
|
}
|
|
62836
63088
|
function migrateEcosystemConfig(deps = {}) {
|
|
62837
63089
|
const d = defaultDeps(deps);
|
|
62838
|
-
const file2 =
|
|
63090
|
+
const file2 = import_node_path25.default.join(d.home, ".mrrlin", "ecosystem.config.cjs");
|
|
62839
63091
|
if (!d.exists(file2)) return { file: file2, status: "absent" };
|
|
62840
63092
|
const text = d.readFile(file2);
|
|
62841
63093
|
if (!findRetiredHost(text) && !hasLiveLegacyStagingFlag(text, "js"))
|
|
@@ -62985,7 +63237,7 @@ ${envLines}
|
|
|
62985
63237
|
}
|
|
62986
63238
|
function migrateCodexConfig(deps = {}) {
|
|
62987
63239
|
const d = defaultDeps(deps);
|
|
62988
|
-
const file2 =
|
|
63240
|
+
const file2 = import_node_path25.default.join(d.codexHome, "config.toml");
|
|
62989
63241
|
if (!d.exists(file2)) return { file: file2, status: "absent" };
|
|
62990
63242
|
const text = d.readFile(file2);
|
|
62991
63243
|
const host = findRetiredHost(text);
|
|
@@ -63071,7 +63323,7 @@ $1`
|
|
|
63071
63323
|
}
|
|
63072
63324
|
function migrateClaudeConfig(deps = {}) {
|
|
63073
63325
|
const d = defaultDeps(deps);
|
|
63074
|
-
const file2 =
|
|
63326
|
+
const file2 = import_node_path25.default.join(d.home, ".claude.json");
|
|
63075
63327
|
if (!d.exists(file2)) return { file: file2, status: "absent" };
|
|
63076
63328
|
const text = d.readFile(file2);
|
|
63077
63329
|
let parsed;
|
|
@@ -63121,9 +63373,9 @@ function migrateRetiredApiBaseUrls(deps = {}) {
|
|
|
63121
63373
|
const d = defaultDeps(deps);
|
|
63122
63374
|
const results = [];
|
|
63123
63375
|
const steps = [
|
|
63124
|
-
{ run: migrateEcosystemConfig, file:
|
|
63125
|
-
{ run: migrateCodexConfig, file:
|
|
63126
|
-
{ run: migrateClaudeConfig, file:
|
|
63376
|
+
{ run: migrateEcosystemConfig, file: import_node_path25.default.join(d.home, ".mrrlin", "ecosystem.config.cjs") },
|
|
63377
|
+
{ run: migrateCodexConfig, file: import_node_path25.default.join(d.codexHome, "config.toml") },
|
|
63378
|
+
{ run: migrateClaudeConfig, file: import_node_path25.default.join(d.home, ".claude.json") }
|
|
63127
63379
|
];
|
|
63128
63380
|
for (const step of steps) {
|
|
63129
63381
|
try {
|
|
@@ -63149,8 +63401,8 @@ function migrateRetiredApiBaseUrls(deps = {}) {
|
|
|
63149
63401
|
}
|
|
63150
63402
|
|
|
63151
63403
|
// src/bridge-health.ts
|
|
63152
|
-
var
|
|
63153
|
-
var
|
|
63404
|
+
var import_node_fs16 = require("node:fs");
|
|
63405
|
+
var import_node_path26 = __toESM(require("node:path"), 1);
|
|
63154
63406
|
var SENTINEL_FILE_NAME = "bridge-health-circuit-breaker.json";
|
|
63155
63407
|
var CRASH_WINDOW_MS = 60 * 60 * 1e3;
|
|
63156
63408
|
var MAX_CRASHES_PER_WINDOW = 3;
|
|
@@ -63162,9 +63414,9 @@ function isCrashSentinel(value) {
|
|
|
63162
63414
|
return typeof candidate.crashCount === "number" && Number.isInteger(candidate.crashCount) && candidate.crashCount >= 0 && typeof candidate.windowStartedAt === "string";
|
|
63163
63415
|
}
|
|
63164
63416
|
async function readCrashSentinel(stateDir, now = Date.now) {
|
|
63165
|
-
const sentinelPath =
|
|
63417
|
+
const sentinelPath = import_node_path26.default.join(stateDir, SENTINEL_FILE_NAME);
|
|
63166
63418
|
try {
|
|
63167
|
-
const raw = await
|
|
63419
|
+
const raw = await import_node_fs16.promises.readFile(sentinelPath, "utf8");
|
|
63168
63420
|
const parsed = JSON.parse(raw);
|
|
63169
63421
|
if (isCrashSentinel(parsed)) return parsed;
|
|
63170
63422
|
} catch {
|
|
@@ -63172,11 +63424,11 @@ async function readCrashSentinel(stateDir, now = Date.now) {
|
|
|
63172
63424
|
return { crashCount: 0, windowStartedAt: new Date(now()).toISOString() };
|
|
63173
63425
|
}
|
|
63174
63426
|
async function writeCrashSentinel(stateDir, sentinel) {
|
|
63175
|
-
await
|
|
63176
|
-
const sentinelPath =
|
|
63427
|
+
await import_node_fs16.promises.mkdir(stateDir, { recursive: true });
|
|
63428
|
+
const sentinelPath = import_node_path26.default.join(stateDir, SENTINEL_FILE_NAME);
|
|
63177
63429
|
const tmpPath = `${sentinelPath}.tmp-${process.pid}-${Math.random().toString(36).slice(2)}`;
|
|
63178
|
-
await
|
|
63179
|
-
await
|
|
63430
|
+
await import_node_fs16.promises.writeFile(tmpPath, JSON.stringify(sentinel), "utf8");
|
|
63431
|
+
await import_node_fs16.promises.rename(tmpPath, sentinelPath);
|
|
63180
63432
|
}
|
|
63181
63433
|
function withTimeout(fn, ms = DEFAULT_OPERATION_TIMEOUT_MS) {
|
|
63182
63434
|
const controller = new AbortController();
|
|
@@ -63503,12 +63755,12 @@ function startSchedulerTickLoop(deps) {
|
|
|
63503
63755
|
|
|
63504
63756
|
// src/retention/pruner.ts
|
|
63505
63757
|
var import_promises11 = require("node:fs/promises");
|
|
63506
|
-
var
|
|
63758
|
+
var import_node_path27 = __toESM(require("node:path"), 1);
|
|
63507
63759
|
function protectedDayFloor(protectedSinceMs) {
|
|
63508
63760
|
return new Date(protectedSinceMs).toISOString().slice(0, 10);
|
|
63509
63761
|
}
|
|
63510
63762
|
async function prune(stateDir, bounds) {
|
|
63511
|
-
const logsDir =
|
|
63763
|
+
const logsDir = import_node_path27.default.join(stateDir, "logs");
|
|
63512
63764
|
let entries;
|
|
63513
63765
|
try {
|
|
63514
63766
|
entries = await (0, import_promises11.readdir)(logsDir);
|
|
@@ -63524,7 +63776,7 @@ async function prune(stateDir, bounds) {
|
|
|
63524
63776
|
for (const entry of entries) {
|
|
63525
63777
|
const m = bridgeRe.exec(entry);
|
|
63526
63778
|
if (!m?.[1]) continue;
|
|
63527
|
-
const fullPath =
|
|
63779
|
+
const fullPath = import_node_path27.default.join(logsDir, entry);
|
|
63528
63780
|
const s = await (0, import_promises11.stat)(fullPath);
|
|
63529
63781
|
files.push({ day: m[1], size: s.size, fullPath });
|
|
63530
63782
|
}
|
|
@@ -63533,7 +63785,7 @@ async function prune(stateDir, bounds) {
|
|
|
63533
63785
|
const reasonByDay = {};
|
|
63534
63786
|
let bytesRemoved = 0;
|
|
63535
63787
|
async function isDaySafeToDelete(day) {
|
|
63536
|
-
const telemetryDir =
|
|
63788
|
+
const telemetryDir = import_node_path27.default.join(stateDir, "telemetry");
|
|
63537
63789
|
let telemetryEntries;
|
|
63538
63790
|
try {
|
|
63539
63791
|
telemetryEntries = await (0, import_promises11.readdir)(telemetryDir);
|
|
@@ -63549,7 +63801,7 @@ async function prune(stateDir, bounds) {
|
|
|
63549
63801
|
}
|
|
63550
63802
|
if (projectSlugs.length === 0) return true;
|
|
63551
63803
|
for (const slug of projectSlugs) {
|
|
63552
|
-
const markerPath =
|
|
63804
|
+
const markerPath = import_node_path27.default.join(telemetryDir, `.processed-${slug}-${day}`);
|
|
63553
63805
|
try {
|
|
63554
63806
|
await (0, import_promises11.stat)(markerPath);
|
|
63555
63807
|
} catch (err) {
|
|
@@ -63599,7 +63851,7 @@ async function prune(stateDir, bounds) {
|
|
|
63599
63851
|
const budgetOvershootBytes = Math.max(0, totalSize2 - budgetBytes);
|
|
63600
63852
|
await emitPruneLog(stateDir, daysRemoved, reasonByDay, bytesRemoved, oldestDayRemaining);
|
|
63601
63853
|
if (daysRemoved.length > 0) {
|
|
63602
|
-
const sessionsPath =
|
|
63854
|
+
const sessionsPath = import_node_path27.default.join(logsDir, ".sessions.json");
|
|
63603
63855
|
let sessionsObj = {};
|
|
63604
63856
|
let fileExists = true;
|
|
63605
63857
|
try {
|
|
@@ -63621,8 +63873,8 @@ async function prune(stateDir, bounds) {
|
|
|
63621
63873
|
return { daysRemoved, reasonByDay, bytesRemoved, oldestDayRemaining, budgetOvershootBytes };
|
|
63622
63874
|
}
|
|
63623
63875
|
async function emitPruneLog(stateDir, daysRemoved, reasonByDay, bytesRemoved, oldestDayRemaining) {
|
|
63624
|
-
const logsDir =
|
|
63625
|
-
const logPath =
|
|
63876
|
+
const logsDir = import_node_path27.default.join(stateDir, "logs");
|
|
63877
|
+
const logPath = import_node_path27.default.join(logsDir, ".pruned.jsonl");
|
|
63626
63878
|
await (0, import_promises11.mkdir)(logsDir, { recursive: true });
|
|
63627
63879
|
const record2 = { ts: Date.now(), dir: "logs", daysRemoved, reasonByDay, bytesRemoved, oldestDayRemaining };
|
|
63628
63880
|
await (0, import_promises11.appendFile)(logPath, `${JSON.stringify(record2)}
|
|
@@ -63632,7 +63884,7 @@ async function emitPruneLog(stateDir, daysRemoved, reasonByDay, bytesRemoved, ol
|
|
|
63632
63884
|
// src/telemetry/turn-aggregator.ts
|
|
63633
63885
|
var import_node_crypto14 = require("node:crypto");
|
|
63634
63886
|
var import_promises12 = require("node:fs/promises");
|
|
63635
|
-
var
|
|
63887
|
+
var import_node_path28 = require("node:path");
|
|
63636
63888
|
var BRIDGE_FILE_RE = /^bridge-(\d{4}-\d{2}-\d{2})\.jsonl$/;
|
|
63637
63889
|
var PLUMBING_COUNTER_KEY = {
|
|
63638
63890
|
socket_close: "socketCloses",
|
|
@@ -63661,7 +63913,7 @@ function inheritSlug(seeds, index) {
|
|
|
63661
63913
|
return (preceding ?? following)?.slug;
|
|
63662
63914
|
}
|
|
63663
63915
|
async function foldClosedDays(stateDir, today) {
|
|
63664
|
-
const logsDir = (0,
|
|
63916
|
+
const logsDir = (0, import_node_path28.join)(stateDir, "logs");
|
|
63665
63917
|
let entries;
|
|
63666
63918
|
try {
|
|
63667
63919
|
entries = await (0, import_promises12.readdir)(logsDir);
|
|
@@ -63673,7 +63925,7 @@ async function foldClosedDays(stateDir, today) {
|
|
|
63673
63925
|
if (!m) continue;
|
|
63674
63926
|
const day = m[1];
|
|
63675
63927
|
if (day === today) continue;
|
|
63676
|
-
const raw = await (0, import_promises12.readFile)((0,
|
|
63928
|
+
const raw = await (0, import_promises12.readFile)((0, import_node_path28.join)(logsDir, entry), "utf8");
|
|
63677
63929
|
const groups = /* @__PURE__ */ new Map();
|
|
63678
63930
|
let groupCounter = 0;
|
|
63679
63931
|
for (const line of raw.split("\n")) {
|
|
@@ -63784,10 +64036,10 @@ async function foldClosedDays(stateDir, today) {
|
|
|
63784
64036
|
rowsByProject.set(slug, rows);
|
|
63785
64037
|
}
|
|
63786
64038
|
if (rowsByProject.size === 0) continue;
|
|
63787
|
-
const telemetryDir = (0,
|
|
64039
|
+
const telemetryDir = (0, import_node_path28.join)(stateDir, "telemetry");
|
|
63788
64040
|
await (0, import_promises12.mkdir)(telemetryDir, { recursive: true });
|
|
63789
64041
|
for (const [slug, rows] of rowsByProject) {
|
|
63790
|
-
const finalPath = (0,
|
|
64042
|
+
const finalPath = (0, import_node_path28.join)(telemetryDir, `rows-${slug}-${day}.jsonl`);
|
|
63791
64043
|
const tmpPath = `${finalPath}.tmp-${process.pid}-${(0, import_node_crypto14.randomBytes)(6).toString("hex")}`;
|
|
63792
64044
|
try {
|
|
63793
64045
|
await (0, import_promises12.writeFile)(tmpPath, rows.map((r) => JSON.stringify(r)).join("\n") + "\n", "utf8");
|
|
@@ -63802,27 +64054,27 @@ async function foldClosedDays(stateDir, today) {
|
|
|
63802
64054
|
|
|
63803
64055
|
// src/telemetry/daily-uploader.ts
|
|
63804
64056
|
var import_promises13 = require("node:fs/promises");
|
|
63805
|
-
var
|
|
64057
|
+
var import_node_path30 = require("node:path");
|
|
63806
64058
|
|
|
63807
64059
|
// src/telemetry/installation-id.ts
|
|
63808
64060
|
var import_node_crypto15 = require("node:crypto");
|
|
63809
|
-
var
|
|
63810
|
-
var
|
|
64061
|
+
var import_node_fs17 = require("node:fs");
|
|
64062
|
+
var import_node_path29 = require("node:path");
|
|
63811
64063
|
var FILE_NAME = "installation-id";
|
|
63812
64064
|
var UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;
|
|
63813
64065
|
var cache = /* @__PURE__ */ new Map();
|
|
63814
64066
|
function resolveInstallationId(stateDir) {
|
|
63815
64067
|
const cached2 = cache.get(stateDir);
|
|
63816
64068
|
if (cached2 !== void 0) return cached2;
|
|
63817
|
-
const
|
|
64069
|
+
const path33 = (0, import_node_path29.join)(stateDir, FILE_NAME);
|
|
63818
64070
|
let id;
|
|
63819
64071
|
try {
|
|
63820
|
-
id = (0,
|
|
64072
|
+
id = (0, import_node_fs17.readFileSync)(path33, "utf8").trim();
|
|
63821
64073
|
if (!UUID.test(id)) throw new Error("unusable");
|
|
63822
64074
|
} catch {
|
|
63823
64075
|
id = (0, import_node_crypto15.randomUUID)();
|
|
63824
|
-
(0,
|
|
63825
|
-
(0,
|
|
64076
|
+
(0, import_node_fs17.mkdirSync)((0, import_node_path29.dirname)(path33), { recursive: true });
|
|
64077
|
+
(0, import_node_fs17.writeFileSync)(path33, `${id}
|
|
63826
64078
|
`, "utf8");
|
|
63827
64079
|
}
|
|
63828
64080
|
cache.set(stateDir, id);
|
|
@@ -63839,7 +64091,7 @@ function truncateCause(err) {
|
|
|
63839
64091
|
return `${message.slice(0, MAX_CAUSE_CHARS - 3)}...`;
|
|
63840
64092
|
}
|
|
63841
64093
|
async function uploadPendingDays(stateDir, client, bridgeHealth, gateCtx) {
|
|
63842
|
-
const telemetryDir = (0,
|
|
64094
|
+
const telemetryDir = (0, import_node_path30.join)(stateDir, "telemetry");
|
|
63843
64095
|
let files;
|
|
63844
64096
|
try {
|
|
63845
64097
|
files = await (0, import_promises13.readdir)(telemetryDir);
|
|
@@ -63855,14 +64107,14 @@ async function uploadPendingDays(stateDir, client, bridgeHealth, gateCtx) {
|
|
|
63855
64107
|
const [, projectSlug, day] = match;
|
|
63856
64108
|
const key = `${projectSlug}\0${day}`;
|
|
63857
64109
|
const entry = discovered.get(key) ?? { projectSlug, day, rowsPath: null };
|
|
63858
|
-
if (rowsMatch) entry.rowsPath = (0,
|
|
64110
|
+
if (rowsMatch) entry.rowsPath = (0, import_node_path30.join)(telemetryDir, file2);
|
|
63859
64111
|
discovered.set(key, entry);
|
|
63860
64112
|
}
|
|
63861
64113
|
const today = telemetryDay();
|
|
63862
64114
|
const pending = [];
|
|
63863
64115
|
const deferred = [];
|
|
63864
64116
|
for (const { projectSlug, day, rowsPath } of discovered.values()) {
|
|
63865
|
-
const markerPath = (0,
|
|
64117
|
+
const markerPath = (0, import_node_path30.join)(telemetryDir, `.processed-${projectSlug}-${day}`);
|
|
63866
64118
|
if (rowsPath === null && day >= today) {
|
|
63867
64119
|
try {
|
|
63868
64120
|
await (0, import_promises13.access)(markerPath);
|
|
@@ -63882,7 +64134,7 @@ async function uploadPendingDays(stateDir, client, bridgeHealth, gateCtx) {
|
|
|
63882
64134
|
const fullUnprocessed = [...pending.map((p) => ({ projectSlug: p.projectSlug, day: p.day })), ...deferred];
|
|
63883
64135
|
pending.sort((a, b) => a.day.localeCompare(b.day));
|
|
63884
64136
|
for (const cur of pending) {
|
|
63885
|
-
const failurePath = (0,
|
|
64137
|
+
const failurePath = (0, import_node_path30.join)(telemetryDir, `.failed-${cur.projectSlug}-${cur.day}.json`);
|
|
63886
64138
|
let failureState = null;
|
|
63887
64139
|
try {
|
|
63888
64140
|
const data = await (0, import_promises13.readFile)(failurePath, "utf8");
|
|
@@ -63916,7 +64168,7 @@ async function uploadPendingDays(stateDir, client, bridgeHealth, gateCtx) {
|
|
|
63916
64168
|
}
|
|
63917
64169
|
const gateCalls = [];
|
|
63918
64170
|
try {
|
|
63919
|
-
const rawGate = await (0, import_promises13.readFile)((0,
|
|
64171
|
+
const rawGate = await (0, import_promises13.readFile)((0, import_node_path30.join)(telemetryDir, gateFileName(cur.projectSlug, cur.day)), "utf8");
|
|
63920
64172
|
for (const line of rawGate.split("\n")) {
|
|
63921
64173
|
if (!line.trim()) continue;
|
|
63922
64174
|
try {
|
|
@@ -64118,7 +64370,7 @@ async function collectAgentPoolSnapshot(deps) {
|
|
|
64118
64370
|
}
|
|
64119
64371
|
|
|
64120
64372
|
// src/external-agents-spawn.ts
|
|
64121
|
-
var
|
|
64373
|
+
var import_node_child_process19 = require("node:child_process");
|
|
64122
64374
|
function runExternalAgentsCli(args, opts) {
|
|
64123
64375
|
let command;
|
|
64124
64376
|
let prefixArgs;
|
|
@@ -64149,7 +64401,7 @@ function runExternalAgentsCli(args, opts) {
|
|
|
64149
64401
|
};
|
|
64150
64402
|
let spawned;
|
|
64151
64403
|
try {
|
|
64152
|
-
spawned = (0,
|
|
64404
|
+
spawned = (0, import_node_child_process19.spawn)(command, [...prefixArgs, ...args], { stdio: stdioConfig });
|
|
64153
64405
|
} catch {
|
|
64154
64406
|
done(1);
|
|
64155
64407
|
return;
|
|
@@ -64261,14 +64513,14 @@ function startAgentPoolLoop(deps) {
|
|
|
64261
64513
|
}
|
|
64262
64514
|
|
|
64263
64515
|
// src/provider-readiness-loop.ts
|
|
64264
|
-
var
|
|
64516
|
+
var import_node_child_process20 = require("node:child_process");
|
|
64265
64517
|
var DEFAULT_INTERVAL_MS3 = 6e4;
|
|
64266
64518
|
function providerReadinessLoopDisabled(env = process.env) {
|
|
64267
64519
|
return env["MRRLIN_BRIDGE_PROVIDER_READINESS_DISABLE"] === "1";
|
|
64268
64520
|
}
|
|
64269
64521
|
function defaultRunnerFor(command) {
|
|
64270
64522
|
return (args) => {
|
|
64271
|
-
const r = (0,
|
|
64523
|
+
const r = (0, import_node_child_process20.spawnSync)(command, args, { encoding: "utf8", timeout: 8e3 });
|
|
64272
64524
|
return { status: r.status, stdout: r.stdout ?? "", stderr: r.stderr ?? "" };
|
|
64273
64525
|
};
|
|
64274
64526
|
}
|
|
@@ -64311,9 +64563,9 @@ function startProviderReadinessLoop(deps) {
|
|
|
64311
64563
|
}
|
|
64312
64564
|
|
|
64313
64565
|
// src/execution-consumer.ts
|
|
64314
|
-
var
|
|
64315
|
-
var
|
|
64316
|
-
var
|
|
64566
|
+
var import_node_child_process23 = require("node:child_process");
|
|
64567
|
+
var import_node_crypto18 = __toESM(require("node:crypto"), 1);
|
|
64568
|
+
var import_node_path34 = __toESM(require("node:path"), 1);
|
|
64317
64569
|
var import_node_util2 = require("node:util");
|
|
64318
64570
|
|
|
64319
64571
|
// src/notify-templates.ts
|
|
@@ -65167,19 +65419,19 @@ async function awaitTurnWithDeadline(opts) {
|
|
|
65167
65419
|
}
|
|
65168
65420
|
|
|
65169
65421
|
// src/worktree.ts
|
|
65170
|
-
var
|
|
65422
|
+
var import_node_child_process21 = require("node:child_process");
|
|
65171
65423
|
var import_node_crypto16 = require("node:crypto");
|
|
65172
|
-
var
|
|
65173
|
-
var
|
|
65424
|
+
var import_node_fs19 = require("node:fs");
|
|
65425
|
+
var import_node_path32 = require("node:path");
|
|
65174
65426
|
|
|
65175
65427
|
// src/checkout-lock.ts
|
|
65176
|
-
var
|
|
65177
|
-
var
|
|
65428
|
+
var import_node_fs18 = require("node:fs");
|
|
65429
|
+
var import_node_path31 = require("node:path");
|
|
65178
65430
|
var import_proper_lockfile = __toESM(require_proper_lockfile(), 1);
|
|
65179
65431
|
async function withCheckoutLock(locksDir, slug, fn) {
|
|
65180
|
-
(0,
|
|
65181
|
-
const target = (0,
|
|
65182
|
-
if (!(0,
|
|
65432
|
+
(0, import_node_fs18.mkdirSync)(locksDir, { recursive: true });
|
|
65433
|
+
const target = (0, import_node_path31.join)(locksDir, `${slug}.lock`);
|
|
65434
|
+
if (!(0, import_node_fs18.existsSync)(target)) (0, import_node_fs18.writeFileSync)(target, "");
|
|
65183
65435
|
const release = await import_proper_lockfile.default.lock(target, {
|
|
65184
65436
|
retries: { retries: 600, factor: 1, minTimeout: 100, maxTimeout: 100 },
|
|
65185
65437
|
stale: 5 * 6e4
|
|
@@ -65195,28 +65447,28 @@ async function withCheckoutLock(locksDir, slug, fn) {
|
|
|
65195
65447
|
function worktreeBranch(runId) {
|
|
65196
65448
|
return `mrrlin/run-${runId}`;
|
|
65197
65449
|
}
|
|
65198
|
-
var defaultGitExec = (args, env) => (0,
|
|
65450
|
+
var defaultGitExec = (args, env) => (0, import_node_child_process21.execFileSync)("git", args, { encoding: "utf8", timeout: 3e4, env });
|
|
65199
65451
|
function disabledGitHooksPath(locksDir, scope) {
|
|
65200
65452
|
const scopeKey = (0, import_node_crypto16.createHash)("sha256").update(scope).digest("hex").slice(0, 32);
|
|
65201
|
-
return (0,
|
|
65453
|
+
return (0, import_node_path32.resolve)(locksDir, "..", "disabled-git-hooks", scopeKey);
|
|
65202
65454
|
}
|
|
65203
65455
|
function prepareDisabledGitHooksDir(locksDir, scope) {
|
|
65204
65456
|
const hooksDir = disabledGitHooksPath(locksDir, scope);
|
|
65205
|
-
const hooksRoot = (0,
|
|
65206
|
-
(0,
|
|
65207
|
-
(0,
|
|
65208
|
-
if ((0,
|
|
65457
|
+
const hooksRoot = (0, import_node_path32.resolve)(hooksDir, "..");
|
|
65458
|
+
(0, import_node_fs19.mkdirSync)(hooksRoot, { recursive: true, mode: 448 });
|
|
65459
|
+
(0, import_node_fs19.mkdirSync)(hooksDir, { recursive: true, mode: 320 });
|
|
65460
|
+
if ((0, import_node_fs19.readdirSync)(hooksDir).length > 0) {
|
|
65209
65461
|
throw new Error(`disabled_git_hooks_dir_not_empty: ${hooksDir}`);
|
|
65210
65462
|
}
|
|
65211
65463
|
try {
|
|
65212
|
-
(0,
|
|
65464
|
+
(0, import_node_fs19.chmodSync)(hooksDir, 320);
|
|
65213
65465
|
} catch {
|
|
65214
65466
|
}
|
|
65215
65467
|
return hooksDir;
|
|
65216
65468
|
}
|
|
65217
65469
|
function removeDisabledGitHooksDir(locksDir, scope) {
|
|
65218
65470
|
try {
|
|
65219
|
-
(0,
|
|
65471
|
+
(0, import_node_fs19.rmdirSync)(disabledGitHooksPath(locksDir, scope));
|
|
65220
65472
|
} catch {
|
|
65221
65473
|
}
|
|
65222
65474
|
}
|
|
@@ -65232,20 +65484,21 @@ function withDisabledGitHooksEnv(env, hooksDir) {
|
|
|
65232
65484
|
};
|
|
65233
65485
|
}
|
|
65234
65486
|
function git(checkout, args, hooksDir) {
|
|
65235
|
-
return (0,
|
|
65487
|
+
return (0, import_node_child_process21.execFileSync)("git", ["-C", checkout, "-c", `core.hooksPath=${hooksDir}`, ...args], {
|
|
65236
65488
|
encoding: "utf8",
|
|
65237
65489
|
timeout: 3e4,
|
|
65238
65490
|
env: { ...process.env, GIT_TERMINAL_PROMPT: "0" }
|
|
65239
65491
|
});
|
|
65240
65492
|
}
|
|
65241
65493
|
async function createRunWorktree(opts) {
|
|
65242
|
-
const worktreePath = (0,
|
|
65494
|
+
const worktreePath = (0, import_node_path32.join)(opts.worktreeRoot, opts.slug, opts.runId);
|
|
65243
65495
|
const hooksDir = prepareDisabledGitHooksDir(opts.locksDir, opts.runId);
|
|
65244
65496
|
await withCheckoutLock(opts.locksDir, opts.slug, async () => {
|
|
65245
|
-
(0,
|
|
65497
|
+
(0, import_node_fs19.mkdirSync)(opts.worktreeRoot, { recursive: true });
|
|
65498
|
+
const base = opts.local ? `refs/heads/${opts.defaultBranch}` : `origin/${opts.defaultBranch}`;
|
|
65246
65499
|
try {
|
|
65247
|
-
git(opts.checkout, ["fetch", "origin", opts.defaultBranch], hooksDir);
|
|
65248
|
-
if (!(0,
|
|
65500
|
+
if (!opts.local) git(opts.checkout, ["fetch", "origin", opts.defaultBranch], hooksDir);
|
|
65501
|
+
if (!(0, import_node_fs19.existsSync)(worktreePath)) {
|
|
65249
65502
|
git(opts.checkout, [
|
|
65250
65503
|
"worktree",
|
|
65251
65504
|
"add",
|
|
@@ -65253,27 +65506,27 @@ async function createRunWorktree(opts) {
|
|
|
65253
65506
|
"-b",
|
|
65254
65507
|
worktreeBranch(opts.runId),
|
|
65255
65508
|
worktreePath,
|
|
65256
|
-
|
|
65509
|
+
base
|
|
65257
65510
|
], hooksDir);
|
|
65258
65511
|
}
|
|
65259
65512
|
} catch (error51) {
|
|
65260
65513
|
const detail = error51 instanceof Error ? error51.message : String(error51);
|
|
65261
65514
|
throw new Error(
|
|
65262
|
-
`default_branch_unresolved: could not provision worktree off
|
|
65515
|
+
`default_branch_unresolved: could not provision worktree off ${base} for ${opts.slug}/${opts.runId}: ${detail}`
|
|
65263
65516
|
);
|
|
65264
65517
|
}
|
|
65265
65518
|
});
|
|
65266
65519
|
return worktreePath;
|
|
65267
65520
|
}
|
|
65268
65521
|
async function removeRunWorktree(opts) {
|
|
65269
|
-
const hooksDir = prepareDisabledGitHooksDir(opts.locksDir, (0,
|
|
65522
|
+
const hooksDir = prepareDisabledGitHooksDir(opts.locksDir, (0, import_node_path32.basename)(opts.worktreePath));
|
|
65270
65523
|
await withCheckoutLock(opts.locksDir, opts.slug, async () => {
|
|
65271
65524
|
try {
|
|
65272
65525
|
git(opts.checkout, ["worktree", "remove", "--force", opts.worktreePath], hooksDir);
|
|
65273
65526
|
} catch {
|
|
65274
65527
|
}
|
|
65275
65528
|
git(opts.checkout, ["worktree", "prune"], hooksDir);
|
|
65276
|
-
removeDisabledGitHooksDir(opts.locksDir, (0,
|
|
65529
|
+
removeDisabledGitHooksDir(opts.locksDir, (0, import_node_path32.basename)(opts.worktreePath));
|
|
65277
65530
|
});
|
|
65278
65531
|
}
|
|
65279
65532
|
async function pushRunBranch(opts, execGit = defaultGitExec) {
|
|
@@ -65357,11 +65610,11 @@ async function sweepOrphanWorktrees(opts) {
|
|
|
65357
65610
|
const hooksDir = prepareDisabledGitHooksDir(opts.locksDir, `sweep:${opts.slug}`);
|
|
65358
65611
|
const ownedPrefix = (() => {
|
|
65359
65612
|
try {
|
|
65360
|
-
return (
|
|
65613
|
+
return (import_node_fs19.realpathSync.native ?? import_node_fs19.realpathSync)(opts.worktreeRoot);
|
|
65361
65614
|
} catch {
|
|
65362
65615
|
return opts.worktreeRoot;
|
|
65363
65616
|
}
|
|
65364
|
-
})() +
|
|
65617
|
+
})() + import_node_path32.sep + opts.slug + import_node_path32.sep;
|
|
65365
65618
|
try {
|
|
65366
65619
|
await withCheckoutLock(opts.locksDir, opts.slug, async () => {
|
|
65367
65620
|
const listing = git(opts.checkout, ["worktree", "list", "--porcelain"], hooksDir);
|
|
@@ -65371,18 +65624,18 @@ async function sweepOrphanWorktrees(opts) {
|
|
|
65371
65624
|
if (!wt) continue;
|
|
65372
65625
|
const canonicalWt = (() => {
|
|
65373
65626
|
try {
|
|
65374
|
-
return (
|
|
65627
|
+
return (import_node_fs19.realpathSync.native ?? import_node_fs19.realpathSync)(wt);
|
|
65375
65628
|
} catch {
|
|
65376
65629
|
return wt;
|
|
65377
65630
|
}
|
|
65378
65631
|
})();
|
|
65379
|
-
const normWt = (0,
|
|
65380
|
-
const normPrefix = (0,
|
|
65632
|
+
const normWt = (0, import_node_path32.normalize)(canonicalWt);
|
|
65633
|
+
const normPrefix = (0, import_node_path32.normalize)(ownedPrefix);
|
|
65381
65634
|
const isMatch = process.platform === "win32" ? normWt.toLowerCase().startsWith(normPrefix.toLowerCase()) : normWt.startsWith(normPrefix);
|
|
65382
65635
|
if (isMatch && opts.isReapable(wt)) {
|
|
65383
65636
|
try {
|
|
65384
65637
|
git(opts.checkout, ["worktree", "remove", "--force", wt], hooksDir);
|
|
65385
|
-
removeDisabledGitHooksDir(opts.locksDir, (0,
|
|
65638
|
+
removeDisabledGitHooksDir(opts.locksDir, (0, import_node_path32.basename)(wt));
|
|
65386
65639
|
reaped.push(wt);
|
|
65387
65640
|
} catch {
|
|
65388
65641
|
}
|
|
@@ -65431,6 +65684,159 @@ function buildPullRequestBody(input) {
|
|
|
65431
65684
|
${lines2.join("\n")}`;
|
|
65432
65685
|
}
|
|
65433
65686
|
|
|
65687
|
+
// src/delivery/local-git.ts
|
|
65688
|
+
var import_node_child_process22 = require("node:child_process");
|
|
65689
|
+
var import_node_crypto17 = require("node:crypto");
|
|
65690
|
+
var import_node_fs20 = require("node:fs");
|
|
65691
|
+
var import_node_path33 = __toESM(require("node:path"), 1);
|
|
65692
|
+
function isLocalGitRoute(route) {
|
|
65693
|
+
return Boolean(route && route.serverId === BUILTIN_CAPABILITY_SERVER_ID && route.operations.commit === LOCAL_GIT_TOOL_NAME);
|
|
65694
|
+
}
|
|
65695
|
+
function git2(repo, args) {
|
|
65696
|
+
return (0, import_node_child_process22.execFileSync)("git", ["-C", repo, ...args], {
|
|
65697
|
+
encoding: "utf8",
|
|
65698
|
+
timeout: 3e4,
|
|
65699
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
65700
|
+
env: { ...process.env, GIT_TERMINAL_PROMPT: "0" }
|
|
65701
|
+
}).trim();
|
|
65702
|
+
}
|
|
65703
|
+
function branchExists(repo, branch) {
|
|
65704
|
+
try {
|
|
65705
|
+
git2(repo, ["rev-parse", "--verify", "--quiet", `refs/heads/${branch}`]);
|
|
65706
|
+
return true;
|
|
65707
|
+
} catch {
|
|
65708
|
+
return false;
|
|
65709
|
+
}
|
|
65710
|
+
}
|
|
65711
|
+
function resolveLocalDefaultBranch(checkout) {
|
|
65712
|
+
for (const candidate of ["main", "master"]) {
|
|
65713
|
+
if (branchExists(checkout, candidate)) return candidate;
|
|
65714
|
+
}
|
|
65715
|
+
try {
|
|
65716
|
+
const current2 = git2(checkout, ["symbolic-ref", "--quiet", "--short", "HEAD"]);
|
|
65717
|
+
if (current2 && branchExists(checkout, current2)) return current2;
|
|
65718
|
+
} catch {
|
|
65719
|
+
}
|
|
65720
|
+
throw new Error(`default_branch_unresolved: ${checkout} has no committed branch to branch a run from`);
|
|
65721
|
+
}
|
|
65722
|
+
var NPM_PLACEHOLDER_TEST = /no test specified/i;
|
|
65723
|
+
function detectBuildCommands(worktree) {
|
|
65724
|
+
const pkgPath = import_node_path33.default.join(worktree, "package.json");
|
|
65725
|
+
if ((0, import_node_fs20.existsSync)(pkgPath)) {
|
|
65726
|
+
let scripts = {};
|
|
65727
|
+
let hasDeps = false;
|
|
65728
|
+
try {
|
|
65729
|
+
const pkg = JSON.parse((0, import_node_fs20.readFileSync)(pkgPath, "utf8"));
|
|
65730
|
+
scripts = pkg.scripts ?? {};
|
|
65731
|
+
hasDeps = Boolean(pkg.dependencies || pkg.devDependencies);
|
|
65732
|
+
} catch {
|
|
65733
|
+
return [];
|
|
65734
|
+
}
|
|
65735
|
+
const pm = (0, import_node_fs20.existsSync)(import_node_path33.default.join(worktree, "pnpm-lock.yaml")) ? "pnpm" : (0, import_node_fs20.existsSync)(import_node_path33.default.join(worktree, "yarn.lock")) ? "yarn" : "npm";
|
|
65736
|
+
const commands = [];
|
|
65737
|
+
const wantsBuild = typeof scripts.build === "string" && scripts.build.trim().length > 0;
|
|
65738
|
+
const wantsTest = typeof scripts.test === "string" && scripts.test.trim().length > 0 && !NPM_PLACEHOLDER_TEST.test(scripts.test);
|
|
65739
|
+
if ((wantsBuild || wantsTest) && hasDeps && !(0, import_node_fs20.existsSync)(import_node_path33.default.join(worktree, "node_modules"))) {
|
|
65740
|
+
commands.push({ label: `${pm} install`, file: pm, args: ["install"] });
|
|
65741
|
+
}
|
|
65742
|
+
if (wantsBuild) commands.push({ label: `${pm} run build`, file: pm, args: ["run", "build"] });
|
|
65743
|
+
if (wantsTest) commands.push({ label: `${pm} run test`, file: pm, args: ["run", "test"] });
|
|
65744
|
+
return commands;
|
|
65745
|
+
}
|
|
65746
|
+
const makefile = ["Makefile", "makefile", "GNUmakefile"].map((name) => import_node_path33.default.join(worktree, name)).find(import_node_fs20.existsSync);
|
|
65747
|
+
if (makefile && /^test\s*:/m.test((0, import_node_fs20.readFileSync)(makefile, "utf8"))) {
|
|
65748
|
+
return [{ label: "make test", file: "make", args: ["test"] }];
|
|
65749
|
+
}
|
|
65750
|
+
return [];
|
|
65751
|
+
}
|
|
65752
|
+
var DEFAULT_STEP_TIMEOUT_MS = 15 * 6e4;
|
|
65753
|
+
var defaultStepRunner = (command, cwd) => {
|
|
65754
|
+
const result = (0, import_node_child_process22.spawnSync)(command.file, command.args, {
|
|
65755
|
+
cwd,
|
|
65756
|
+
encoding: "utf8",
|
|
65757
|
+
timeout: DEFAULT_STEP_TIMEOUT_MS,
|
|
65758
|
+
maxBuffer: 64 * 1024 * 1024,
|
|
65759
|
+
env: { ...process.env, CI: "1", GIT_TERMINAL_PROMPT: "0" }
|
|
65760
|
+
});
|
|
65761
|
+
const output3 = `${result.stdout ?? ""}${result.stderr ?? ""}${result.error ? `
|
|
65762
|
+
${result.error.message}` : ""}`;
|
|
65763
|
+
return { exitCode: typeof result.status === "number" ? result.status : 1, output: output3 };
|
|
65764
|
+
};
|
|
65765
|
+
function sha2562(text) {
|
|
65766
|
+
return (0, import_node_crypto17.createHash)("sha256").update(text).digest("hex");
|
|
65767
|
+
}
|
|
65768
|
+
function deliverLocalGit(input) {
|
|
65769
|
+
const branch = `mrrlin/run-${input.runId}`;
|
|
65770
|
+
const currentBranch = git2(input.worktreePath, ["rev-parse", "--abbrev-ref", "HEAD"]);
|
|
65771
|
+
if (currentBranch !== branch) {
|
|
65772
|
+
throw new Error(`local_delivery_branch_mismatch: worktree is on ${currentBranch}, expected ${branch}`);
|
|
65773
|
+
}
|
|
65774
|
+
if (git2(input.worktreePath, ["status", "--porcelain"]).length > 0) {
|
|
65775
|
+
git2(input.worktreePath, ["add", "-A"]);
|
|
65776
|
+
git2(input.worktreePath, [
|
|
65777
|
+
"-c",
|
|
65778
|
+
"user.name=Mrrlin",
|
|
65779
|
+
"-c",
|
|
65780
|
+
"user.email=bridge@mrrlin.local",
|
|
65781
|
+
"commit",
|
|
65782
|
+
"--no-verify",
|
|
65783
|
+
"-m",
|
|
65784
|
+
`mrrlin: ${input.runId} work`
|
|
65785
|
+
]);
|
|
65786
|
+
}
|
|
65787
|
+
const headSha = git2(input.worktreePath, ["rev-parse", "HEAD"]);
|
|
65788
|
+
const commitCount = Number(git2(input.worktreePath, ["rev-list", "--count", `${input.baseSha}..${headSha}`]));
|
|
65789
|
+
if (!Number.isInteger(commitCount) || commitCount < 0) {
|
|
65790
|
+
throw new Error(`local_delivery_commit_count_unreadable: git rev-list returned ${String(commitCount)}`);
|
|
65791
|
+
}
|
|
65792
|
+
const checkoutDigest = sha2562(input.checkoutRealPath);
|
|
65793
|
+
(0, import_node_fs20.mkdirSync)(input.evidenceDir, { recursive: true, mode: 448 });
|
|
65794
|
+
const evidenceFile = import_node_path33.default.join(input.evidenceDir, `${input.runId}.json`);
|
|
65795
|
+
if (!(commitCount > 0)) {
|
|
65796
|
+
(0, import_node_fs20.writeFileSync)(
|
|
65797
|
+
evidenceFile,
|
|
65798
|
+
JSON.stringify({ checkout: input.checkoutRealPath, branch, baseSha: input.baseSha, headSha, commitCount, steps: [] }, null, 2),
|
|
65799
|
+
{ mode: 384 }
|
|
65800
|
+
);
|
|
65801
|
+
return {
|
|
65802
|
+
ok: false,
|
|
65803
|
+
reason: "no_commits",
|
|
65804
|
+
detail: `no_commits_to_deliver: run ${input.runId} has no commits on ${branch} ahead of ${input.baseSha.slice(0, 12)}`,
|
|
65805
|
+
evidence: null,
|
|
65806
|
+
evidenceFile
|
|
65807
|
+
};
|
|
65808
|
+
}
|
|
65809
|
+
const runStep = input.runStep ?? defaultStepRunner;
|
|
65810
|
+
const steps = [];
|
|
65811
|
+
const logs = [];
|
|
65812
|
+
for (const command of detectBuildCommands(input.worktreePath)) {
|
|
65813
|
+
const { exitCode, output: output3 } = runStep(command, input.worktreePath);
|
|
65814
|
+
steps.push({ command: command.label, exitCode, logDigest: sha2562(output3) });
|
|
65815
|
+
logs.push({ command: command.label, exitCode, output: output3.slice(-2e5) });
|
|
65816
|
+
if (exitCode !== 0) break;
|
|
65817
|
+
}
|
|
65818
|
+
const evidence = {
|
|
65819
|
+
branch,
|
|
65820
|
+
baseSha: input.baseSha,
|
|
65821
|
+
headSha,
|
|
65822
|
+
commitCount,
|
|
65823
|
+
steps,
|
|
65824
|
+
noBuildStep: steps.length === 0,
|
|
65825
|
+
checkoutDigest
|
|
65826
|
+
};
|
|
65827
|
+
(0, import_node_fs20.writeFileSync)(evidenceFile, JSON.stringify({ checkout: input.checkoutRealPath, ...evidence, logs }, null, 2), { mode: 384 });
|
|
65828
|
+
const problem = checkLocalBuildEvidence({ type: "build", value: headSha }, evidence);
|
|
65829
|
+
if (problem) {
|
|
65830
|
+
return { ok: false, reason: "build_failed", detail: `local_build_failed: ${problem}`, evidence, evidenceFile };
|
|
65831
|
+
}
|
|
65832
|
+
return {
|
|
65833
|
+
ok: true,
|
|
65834
|
+
evidence,
|
|
65835
|
+
deliveryRef: formatLocalDeliveryRef({ projectSlug: input.projectSlug, branch, headSha }),
|
|
65836
|
+
evidenceFile
|
|
65837
|
+
};
|
|
65838
|
+
}
|
|
65839
|
+
|
|
65434
65840
|
// src/thread-retirement.ts
|
|
65435
65841
|
function decideThreadRetirement(input) {
|
|
65436
65842
|
if (input.disabled) return { retire: false };
|
|
@@ -65879,6 +66285,16 @@ var EXECUTOR_BASE_INSTRUCTIONS = [
|
|
|
65879
66285
|
"commit unverified delegated output. If dispatch fails or the pool is unavailable, do the",
|
|
65880
66286
|
"work yourself \u2014 never block the run on the pool."
|
|
65881
66287
|
].join("\n");
|
|
66288
|
+
var LOCAL_GIT_EXECUTOR_INSTRUCTIONS = [
|
|
66289
|
+
"",
|
|
66290
|
+
"This project's code lives only in a git repository on the operator's own computer; it has no",
|
|
66291
|
+
"remote. Your worktree is on the run branch. Commit your work on THIS branch. Never run `git push`,",
|
|
66292
|
+
"never add a remote, never open a pull request, and never switch to or merge into the default branch.",
|
|
66293
|
+
"When your turn ends, the bridge itself commits anything left uncommitted, runs the project's build",
|
|
66294
|
+
"and tests, and records the result \u2014 you do not need to report a link."
|
|
66295
|
+
].join("\n");
|
|
66296
|
+
var EXECUTOR_LOCAL_GIT_BASE_INSTRUCTIONS = `${EXECUTOR_BASE_INSTRUCTIONS}
|
|
66297
|
+
${LOCAL_GIT_EXECUTOR_INSTRUCTIONS}`;
|
|
65882
66298
|
function artifactKindForEvent(event) {
|
|
65883
66299
|
switch (event.type) {
|
|
65884
66300
|
case "assistant":
|
|
@@ -65914,13 +66330,20 @@ function isBridgeGeneratedArtifact(artifact) {
|
|
|
65914
66330
|
return typeof payload === "object" && payload !== null && "event" in payload;
|
|
65915
66331
|
}
|
|
65916
66332
|
function newArtifactId() {
|
|
65917
|
-
return `EA-${
|
|
66333
|
+
return `EA-${import_node_crypto18.default.randomUUID()}`;
|
|
65918
66334
|
}
|
|
65919
66335
|
var BLAST_RADIUS_FLOOR_PATTERNS = [/^supabase\/migrations\//, /^packages\/db\/src\/schema\.ts$/];
|
|
65920
|
-
function isBlastRadiusFloorPath(
|
|
65921
|
-
return BLAST_RADIUS_FLOOR_PATTERNS.some((re) => re.test(
|
|
66336
|
+
function isBlastRadiusFloorPath(path33) {
|
|
66337
|
+
return BLAST_RADIUS_FLOOR_PATTERNS.some((re) => re.test(path33));
|
|
66338
|
+
}
|
|
66339
|
+
var execFileAsync2 = (0, import_node_util2.promisify)(import_node_child_process23.execFile);
|
|
66340
|
+
async function gitOutput(cwd, args) {
|
|
66341
|
+
const { stdout } = await execFileAsync2("git", ["-C", cwd, ...args], {
|
|
66342
|
+
timeout: 3e4,
|
|
66343
|
+
env: { ...process.env, GIT_TERMINAL_PROMPT: "0" }
|
|
66344
|
+
});
|
|
66345
|
+
return String(stdout).trim();
|
|
65922
66346
|
}
|
|
65923
|
-
var execFileAsync2 = (0, import_node_util2.promisify)(import_node_child_process21.execFile);
|
|
65924
66347
|
async function defaultListRunDiffPaths(opts) {
|
|
65925
66348
|
const parse8 = (stdout) => stdout.split("\n").map((line) => line.trim()).filter((line) => line.length > 0);
|
|
65926
66349
|
try {
|
|
@@ -66165,7 +66588,7 @@ async function driveRun(deps, projectSlug, runId) {
|
|
|
66165
66588
|
if (!claimed) return;
|
|
66166
66589
|
if (!claimed.leaseId) {
|
|
66167
66590
|
await deps.client.createInboxItem(projectSlug, {
|
|
66168
|
-
id: `II-${
|
|
66591
|
+
id: `II-${import_node_crypto18.default.randomUUID()}`,
|
|
66169
66592
|
kind: "handoff",
|
|
66170
66593
|
taskId: claimed.taskId,
|
|
66171
66594
|
body: `Execution run ${runId} was claimed but returned no leaseId. This indicates DB/API corruption and requires operator attention.`
|
|
@@ -66182,6 +66605,7 @@ async function driveRun(deps, projectSlug, runId) {
|
|
|
66182
66605
|
return legacy != null ? Math.min(legacy, remaining) : remaining;
|
|
66183
66606
|
};
|
|
66184
66607
|
const task = await deps.client.getTask(projectSlug, claimed.taskId);
|
|
66608
|
+
let localGitMode = null;
|
|
66185
66609
|
if (task.declaredOutcome != null) {
|
|
66186
66610
|
for (const kind of task.declaredOutcome.requires) {
|
|
66187
66611
|
if (resolveKindCapability(kind) === null) {
|
|
@@ -66214,6 +66638,7 @@ async function driveRun(deps, projectSlug, runId) {
|
|
|
66214
66638
|
);
|
|
66215
66639
|
return;
|
|
66216
66640
|
}
|
|
66641
|
+
if (kind === "code_change") localGitMode = isLocalGitRoute(routeResolution.route);
|
|
66217
66642
|
}
|
|
66218
66643
|
}
|
|
66219
66644
|
const needsBrowser = claimed.prerequisites?.some((p) => p.mcp === "mrrlin-browser") || task.domains?.includes("browser");
|
|
@@ -66479,6 +66904,31 @@ ${renderTaskStateSection(taskState)}`;
|
|
|
66479
66904
|
let codex;
|
|
66480
66905
|
let disposeCodex = () => {
|
|
66481
66906
|
};
|
|
66907
|
+
let localCheckoutRealPath = null;
|
|
66908
|
+
let localBaseSha = null;
|
|
66909
|
+
if (claimed.codeExecution && localGitMode === null) {
|
|
66910
|
+
try {
|
|
66911
|
+
const resolution = await deps.client.resolveArtifactKindRoute(projectSlug, "code_change", projectSlug);
|
|
66912
|
+
localGitMode = resolution.ok ? isLocalGitRoute(resolution.route) : false;
|
|
66913
|
+
} catch {
|
|
66914
|
+
localGitMode = false;
|
|
66915
|
+
}
|
|
66916
|
+
}
|
|
66917
|
+
if (claimed.codeExecution && localGitMode) {
|
|
66918
|
+
await askCodeHostOnce(deps, projectSlug, task.id);
|
|
66919
|
+
}
|
|
66920
|
+
if (claimed.codeExecution && localGitMode && !checkout) {
|
|
66921
|
+
await failRun(
|
|
66922
|
+
deps,
|
|
66923
|
+
projectSlug,
|
|
66924
|
+
task,
|
|
66925
|
+
runId,
|
|
66926
|
+
leaseId,
|
|
66927
|
+
`local_checkout_missing: run ${runId} needs code execution, but project ${projectSlug} keeps its code only on this computer and no project folder is registered for it yet. Explain this to the operator in plain, non-technical language, then ask which folder on their computer holds this project. When they confirm an absolute path, call register_local_checkout({ projectSlug: "${projectSlug}", path: "<absolute path>" }) WITHOUT a repo. If that folder is not a git repository yet, ask their explicit permission before turning it into one. Once a folder is registered, the run can be re-queued.`,
|
|
66928
|
+
"local_checkout_missing"
|
|
66929
|
+
);
|
|
66930
|
+
return;
|
|
66931
|
+
}
|
|
66482
66932
|
if (claimed.codeExecution) {
|
|
66483
66933
|
if (!checkout) {
|
|
66484
66934
|
const reason = `local_checkout_missing: run ${runId} needs code execution, but project ${projectSlug} has no local git checkout registered on this machine, so there is nowhere to make the changes. Explain this to the operator in plain, non-technical language, then proactively help register one:
|
|
@@ -66494,22 +66944,46 @@ ${renderTaskStateSection(taskState)}`;
|
|
|
66494
66944
|
await failRun(deps, projectSlug, task, runId, leaseId, reason);
|
|
66495
66945
|
return;
|
|
66496
66946
|
}
|
|
66947
|
+
if (localGitMode) {
|
|
66948
|
+
const validated = validateLocalCheckoutPath(checkout.path, deps.localCheckoutRules);
|
|
66949
|
+
if (!validated.ok) {
|
|
66950
|
+
await failRun(
|
|
66951
|
+
deps,
|
|
66952
|
+
projectSlug,
|
|
66953
|
+
task,
|
|
66954
|
+
runId,
|
|
66955
|
+
leaseId,
|
|
66956
|
+
`local_checkout_invalid: run ${runId} cannot use the folder registered for project ${projectSlug} (${validated.code}): ${validated.detail}. Ask the operator to confirm the project folder again and re-register it with register_local_checkout.`
|
|
66957
|
+
);
|
|
66958
|
+
return;
|
|
66959
|
+
}
|
|
66960
|
+
localCheckoutRealPath = validated.realPath;
|
|
66961
|
+
}
|
|
66497
66962
|
try {
|
|
66498
66963
|
const createWt = deps.createRunWorktree ?? createRunWorktree;
|
|
66499
|
-
|
|
66500
|
-
|
|
66964
|
+
if (localGitMode && localCheckoutRealPath) {
|
|
66965
|
+
resolvedDefaultBranch = (deps.resolveLocalDefaultBranch ?? resolveLocalDefaultBranch)(localCheckoutRealPath);
|
|
66966
|
+
} else {
|
|
66967
|
+
const getDefaultBranch = deps.getDefaultBranch ?? (async () => "main");
|
|
66968
|
+
resolvedDefaultBranch = await getDefaultBranch(projectSlug);
|
|
66969
|
+
}
|
|
66501
66970
|
worktreePath = await createWt({
|
|
66502
|
-
checkout: checkout.path,
|
|
66971
|
+
checkout: localCheckoutRealPath ?? checkout.path,
|
|
66503
66972
|
worktreeRoot: deps.worktreeRoot ?? "/tmp/mrrlin-worktrees",
|
|
66504
66973
|
locksDir: deps.locksDir ?? "/tmp/mrrlin-locks",
|
|
66505
66974
|
slug: projectSlug,
|
|
66506
66975
|
runId,
|
|
66507
|
-
defaultBranch: resolvedDefaultBranch
|
|
66976
|
+
defaultBranch: resolvedDefaultBranch,
|
|
66977
|
+
...localGitMode ? { local: true } : {}
|
|
66508
66978
|
});
|
|
66979
|
+
if (localGitMode) {
|
|
66980
|
+
localBaseSha = await gitOutput(worktreePath, ["merge-base", "HEAD", `refs/heads/${resolvedDefaultBranch}`]);
|
|
66981
|
+
}
|
|
66509
66982
|
if (!await runHasLease(deps, projectSlug, runId, leaseId)) return;
|
|
66510
66983
|
await deps.client.updateExecutionRun(projectSlug, runId, {
|
|
66511
66984
|
worktreeId: worktreePath,
|
|
66512
|
-
branch: worktreeBranch(runId)
|
|
66985
|
+
branch: worktreeBranch(runId),
|
|
66986
|
+
...localBaseSha ? { baseSha: localBaseSha } : {}
|
|
66513
66987
|
});
|
|
66514
66988
|
sandbox = "danger-full-access";
|
|
66515
66989
|
turnCwd = worktreePath;
|
|
@@ -66578,7 +67052,7 @@ ${renderTaskStateSection(taskState)}`;
|
|
|
66578
67052
|
// write-authorized within its worktree, so it must NOT receive the
|
|
66579
67053
|
// read-only-sandbox claim (which makes a write-authorized model
|
|
66580
67054
|
// self-censor). The read-only path keeps the never-write restriction.
|
|
66581
|
-
baseInstructions: useExecutor ? EXECUTOR_BASE_INSTRUCTIONS : CONSUMER_BASE_INSTRUCTIONS,
|
|
67055
|
+
baseInstructions: useExecutor ? localGitMode ? EXECUTOR_LOCAL_GIT_BASE_INSTRUCTIONS : EXECUTOR_BASE_INSTRUCTIONS : CONSUMER_BASE_INSTRUCTIONS,
|
|
66582
67056
|
developerInstructions: null,
|
|
66583
67057
|
ephemeral: null,
|
|
66584
67058
|
mcpConfig: deps.mcpConfigPath
|
|
@@ -66790,7 +67264,7 @@ Continue executing task ${task.id}. Make the next concrete increment of progress
|
|
|
66790
67264
|
if (!await runHasLease(deps, projectSlug, runId, leaseId)) return;
|
|
66791
67265
|
const hasCommitsFn = deps.hasCommitsToPush ?? hasCommitsToPush;
|
|
66792
67266
|
const defaultBranchForPush = resolvedDefaultBranch ?? "main";
|
|
66793
|
-
if (!await hasCommitsFn({ worktreePath, defaultBranch: defaultBranchForPush })) {
|
|
67267
|
+
if (!localGitMode && !await hasCommitsFn({ worktreePath, defaultBranch: defaultBranchForPush })) {
|
|
66794
67268
|
await failRun(
|
|
66795
67269
|
deps,
|
|
66796
67270
|
projectSlug,
|
|
@@ -66823,6 +67297,18 @@ Continue executing task ${task.id}. Make the next concrete increment of progress
|
|
|
66823
67297
|
} else {
|
|
66824
67298
|
console.warn(JSON.stringify({ event: "self_review_gate_skipped", projectSlug, runId, reason: "no selfReviewTurn dep" }));
|
|
66825
67299
|
}
|
|
67300
|
+
if (localGitMode) {
|
|
67301
|
+
await deliverLocalRun(deps, {
|
|
67302
|
+
projectSlug,
|
|
67303
|
+
task: readiness.task,
|
|
67304
|
+
runId,
|
|
67305
|
+
leaseId,
|
|
67306
|
+
worktreePath,
|
|
67307
|
+
checkoutRealPath: localCheckoutRealPath ?? checkout?.path ?? worktreePath,
|
|
67308
|
+
baseSha: localBaseSha
|
|
67309
|
+
});
|
|
67310
|
+
return;
|
|
67311
|
+
}
|
|
66826
67312
|
const snapshot = await deps.client.getProjectSnapshot(projectSlug);
|
|
66827
67313
|
const expectedRepoFullName = snapshot.github?.repo ?? null;
|
|
66828
67314
|
if (!expectedRepoFullName) {
|
|
@@ -66955,7 +67441,7 @@ Continue executing task ${task.id}. Make the next concrete increment of progress
|
|
|
66955
67441
|
taskId: task.id,
|
|
66956
67442
|
runId,
|
|
66957
67443
|
outcome: "completed",
|
|
66958
|
-
nonce:
|
|
67444
|
+
nonce: import_node_crypto18.default.randomUUID(),
|
|
66959
67445
|
artifacts: []
|
|
66960
67446
|
}
|
|
66961
67447
|
);
|
|
@@ -67443,7 +67929,7 @@ async function driveNonCodeRun(deps, projectSlug, runId, leaseId, task, domain2,
|
|
|
67443
67929
|
taskId: task.id,
|
|
67444
67930
|
runId,
|
|
67445
67931
|
outcome: parsedResult.outcome,
|
|
67446
|
-
nonce:
|
|
67932
|
+
nonce: import_node_crypto18.default.randomUUID(),
|
|
67447
67933
|
artifacts: [
|
|
67448
67934
|
{
|
|
67449
67935
|
artifactId: pageId,
|
|
@@ -67512,6 +67998,162 @@ async function resetWedgedThread(deps, projectSlug, taskId, interruptFailed) {
|
|
|
67512
67998
|
await deps.client.resetDirectorThread(projectSlug, taskId).catch(() => {
|
|
67513
67999
|
});
|
|
67514
68000
|
}
|
|
68001
|
+
function codeHostQuestionId(projectSlug) {
|
|
68002
|
+
return `II-code-host-${projectSlug.replace(/[^A-Za-z0-9._-]/g, "-")}`;
|
|
68003
|
+
}
|
|
68004
|
+
async function askCodeHostOnce(deps, projectSlug, taskId) {
|
|
68005
|
+
try {
|
|
68006
|
+
const snapshot = await deps.client.getProjectSnapshot(projectSlug);
|
|
68007
|
+
if (snapshot.project.codeHost != null) return;
|
|
68008
|
+
await deps.client.createInboxItem(projectSlug, {
|
|
68009
|
+
id: codeHostQuestionId(projectSlug),
|
|
68010
|
+
kind: "question",
|
|
68011
|
+
taskId,
|
|
68012
|
+
body: "Your project's code is being saved on this computer, in your project folder. Should it stay only here, or would you also like a copy on GitHub or GitLab (useful for backups and teammates)?",
|
|
68013
|
+
questionOptions: [
|
|
68014
|
+
{ label: "Keep it on this computer", answer: "local", description: "Nothing is uploaded anywhere.", recommended: true },
|
|
68015
|
+
{ label: "Also put it on GitHub", answer: "github", description: "You will be asked to connect GitHub." },
|
|
68016
|
+
{ label: "Also put it on GitLab", answer: "gitlab", description: "You will be asked to connect GitLab." }
|
|
68017
|
+
]
|
|
68018
|
+
});
|
|
68019
|
+
} catch {
|
|
68020
|
+
}
|
|
68021
|
+
}
|
|
68022
|
+
async function deliverLocalRun(deps, input) {
|
|
68023
|
+
const { projectSlug, task, runId, leaseId } = input;
|
|
68024
|
+
if (!input.baseSha) {
|
|
68025
|
+
await failRun(deps, projectSlug, task, runId, leaseId, `local_delivery_failed: run ${runId} has no recorded base commit.`);
|
|
68026
|
+
return;
|
|
68027
|
+
}
|
|
68028
|
+
if (!deps.localEvidenceDir) {
|
|
68029
|
+
await failRun(
|
|
68030
|
+
deps,
|
|
68031
|
+
projectSlug,
|
|
68032
|
+
task,
|
|
68033
|
+
runId,
|
|
68034
|
+
leaseId,
|
|
68035
|
+
`local_delivery_failed: run ${runId} has no bridge evidence directory configured (localEvidenceDir).`
|
|
68036
|
+
);
|
|
68037
|
+
return;
|
|
68038
|
+
}
|
|
68039
|
+
const evidenceDir = deps.localEvidenceDir;
|
|
68040
|
+
const deliver = deps.deliverLocalGit ?? deliverLocalGit;
|
|
68041
|
+
let outcome;
|
|
68042
|
+
try {
|
|
68043
|
+
outcome = deliver({
|
|
68044
|
+
projectSlug,
|
|
68045
|
+
runId,
|
|
68046
|
+
checkoutRealPath: input.checkoutRealPath,
|
|
68047
|
+
worktreePath: input.worktreePath,
|
|
68048
|
+
baseSha: input.baseSha,
|
|
68049
|
+
evidenceDir
|
|
68050
|
+
});
|
|
68051
|
+
} catch (error51) {
|
|
68052
|
+
await failRun(
|
|
68053
|
+
deps,
|
|
68054
|
+
projectSlug,
|
|
68055
|
+
task,
|
|
68056
|
+
runId,
|
|
68057
|
+
leaseId,
|
|
68058
|
+
`local_delivery_failed: ${error51 instanceof Error ? error51.message : String(error51)}`
|
|
68059
|
+
);
|
|
68060
|
+
return;
|
|
68061
|
+
}
|
|
68062
|
+
if (!outcome.ok) {
|
|
68063
|
+
if (outcome.evidence) {
|
|
68064
|
+
await deps.client.updateExecutionRun(projectSlug, runId, { headSha: outcome.evidence.headSha }).catch(() => {
|
|
68065
|
+
});
|
|
68066
|
+
}
|
|
68067
|
+
await failRun(deps, projectSlug, task, runId, leaseId, outcome.detail);
|
|
68068
|
+
return;
|
|
68069
|
+
}
|
|
68070
|
+
if (!await runHasLease(deps, projectSlug, runId, leaseId)) return;
|
|
68071
|
+
await deps.client.updateExecutionRun(projectSlug, runId, {
|
|
68072
|
+
headSha: outcome.evidence.headSha,
|
|
68073
|
+
deliveryRef: outcome.deliveryRef
|
|
68074
|
+
});
|
|
68075
|
+
const receipt = {
|
|
68076
|
+
...buildReceipt({
|
|
68077
|
+
declaredOutcome: task.declaredOutcome ?? { sentence: task.title, requires: ["code_change"], verification: "machine" },
|
|
68078
|
+
evidenceType: "build",
|
|
68079
|
+
evidenceValue: outcome.evidence.headSha,
|
|
68080
|
+
coveredKinds: ["code_change"]
|
|
68081
|
+
}),
|
|
68082
|
+
localBuild: outcome.evidence
|
|
68083
|
+
};
|
|
68084
|
+
const artifactId = `EA-LG-${runId}-${outcome.evidence.headSha.slice(0, 12)}`;
|
|
68085
|
+
let artifact;
|
|
68086
|
+
try {
|
|
68087
|
+
artifact = await deps.client.appendExecutionArtifact(projectSlug, runId, {
|
|
68088
|
+
id: artifactId,
|
|
68089
|
+
kind: "verification",
|
|
68090
|
+
payload: { [LOCAL_BUILD_RECEIPT_PAYLOAD_KEY]: receipt, deliveryRef: outcome.deliveryRef }
|
|
68091
|
+
});
|
|
68092
|
+
} catch (error51) {
|
|
68093
|
+
const existing = await deps.client.listExecutionArtifacts(projectSlug, runId).catch(() => []);
|
|
68094
|
+
const found = existing.find((candidate) => candidate.id === artifactId);
|
|
68095
|
+
if (!found) {
|
|
68096
|
+
await failRun(
|
|
68097
|
+
deps,
|
|
68098
|
+
projectSlug,
|
|
68099
|
+
task,
|
|
68100
|
+
runId,
|
|
68101
|
+
leaseId,
|
|
68102
|
+
`local_delivery_failed: could not record the build receipt: ${error51 instanceof Error ? error51.message : String(error51)}`
|
|
68103
|
+
);
|
|
68104
|
+
return;
|
|
68105
|
+
}
|
|
68106
|
+
artifact = found;
|
|
68107
|
+
}
|
|
68108
|
+
if (!deps.signingProvider) {
|
|
68109
|
+
await failRun(
|
|
68110
|
+
deps,
|
|
68111
|
+
projectSlug,
|
|
68112
|
+
task,
|
|
68113
|
+
runId,
|
|
68114
|
+
leaseId,
|
|
68115
|
+
`closure_signing_unavailable: run ${runId} delivered ${outcome.deliveryRef} with a green bridge-run build, but this bridge has no receipt signing key (MRRLIN_SIGNING_KEY_ID / MRRLIN_SIGNING_PRIVATE_KEY), so the task cannot be closed. Configure signing and restart the run.`
|
|
68116
|
+
);
|
|
68117
|
+
return;
|
|
68118
|
+
}
|
|
68119
|
+
const stored = artifact?.payload ?? {};
|
|
68120
|
+
const contentHash = String(stored.contentHash ?? stored.content_hash ?? stored.hash ?? "");
|
|
68121
|
+
try {
|
|
68122
|
+
await orchestrateSettlementClosure(
|
|
68123
|
+
{
|
|
68124
|
+
prepareSettlementCandidate: (slug, params) => deps.client.prepareSettlementCandidate(slug, params),
|
|
68125
|
+
signingProvider: deps.signingProvider,
|
|
68126
|
+
finalizeSettlementReceipt: (slug, params) => deps.client.finalizeSettlementReceipt(slug, params)
|
|
68127
|
+
},
|
|
68128
|
+
{
|
|
68129
|
+
projectSlug,
|
|
68130
|
+
taskId: task.id,
|
|
68131
|
+
runId,
|
|
68132
|
+
outcome: "completed",
|
|
68133
|
+
nonce: import_node_crypto18.default.randomUUID(),
|
|
68134
|
+
artifacts: [{ artifactId: artifact?.id ?? artifactId, storageVersion: "1", contentHash, kind: "verification" }]
|
|
68135
|
+
}
|
|
68136
|
+
);
|
|
68137
|
+
} catch (error51) {
|
|
68138
|
+
await failRun(
|
|
68139
|
+
deps,
|
|
68140
|
+
projectSlug,
|
|
68141
|
+
task,
|
|
68142
|
+
runId,
|
|
68143
|
+
leaseId,
|
|
68144
|
+
`local_delivery_settlement_failed: ${error51 instanceof Error ? error51.message : String(error51)}`
|
|
68145
|
+
);
|
|
68146
|
+
return;
|
|
68147
|
+
}
|
|
68148
|
+
const removeWt = deps.removeRunWorktree ?? removeRunWorktree;
|
|
68149
|
+
await removeWt({
|
|
68150
|
+
checkout: input.checkoutRealPath,
|
|
68151
|
+
worktreePath: input.worktreePath,
|
|
68152
|
+
locksDir: deps.locksDir ?? "/tmp/mrrlin-locks",
|
|
68153
|
+
slug: projectSlug
|
|
68154
|
+
}).catch(() => {
|
|
68155
|
+
});
|
|
68156
|
+
}
|
|
67515
68157
|
async function failRun(deps, projectSlug, task, runId, leaseId, reason, reasonCode) {
|
|
67516
68158
|
let currentRun;
|
|
67517
68159
|
try {
|
|
@@ -67673,7 +68315,7 @@ async function reconcileTaskAwaitingMerge(deps, projectSlug, task, runId, reason
|
|
|
67673
68315
|
}
|
|
67674
68316
|
try {
|
|
67675
68317
|
await deps.client.createInboxItem(projectSlug, {
|
|
67676
|
-
id: `II-${
|
|
68318
|
+
id: `II-${import_node_crypto18.default.randomUUID()}`,
|
|
67677
68319
|
kind: "handoff",
|
|
67678
68320
|
taskId: task.id,
|
|
67679
68321
|
body: `Task ${task.id} (${task.title}) still needs operator follow-up: ${reason}. Mrrlin could not move the task back to Handoff needed automatically.`
|
|
@@ -67708,7 +68350,7 @@ async function notifyOperatorHandoff(deps, projectSlug, task, runId, reason) {
|
|
|
67708
68350
|
}
|
|
67709
68351
|
try {
|
|
67710
68352
|
await deps.client.createInboxItem(projectSlug, {
|
|
67711
|
-
id: `II-${
|
|
68353
|
+
id: `II-${import_node_crypto18.default.randomUUID()}`,
|
|
67712
68354
|
kind: "handoff",
|
|
67713
68355
|
taskId: task.id,
|
|
67714
68356
|
body: `Execution run ${runId} for task ${task.id} (${task.title}) needs operator attention: ${reason}`
|
|
@@ -67850,8 +68492,8 @@ async function runBackstopSweep(deps, drive = (slug, id) => driveRun(deps, slug,
|
|
|
67850
68492
|
function isRunRecoverableByThisBridge(run3, worktreeRoot) {
|
|
67851
68493
|
if (!worktreeRoot) return true;
|
|
67852
68494
|
if (!run3.worktreeId) return true;
|
|
67853
|
-
const relative =
|
|
67854
|
-
return relative === "" || relative.length > 0 && !relative.startsWith("..") && !
|
|
68495
|
+
const relative = import_node_path34.default.relative(import_node_path34.default.resolve(worktreeRoot), import_node_path34.default.resolve(run3.worktreeId));
|
|
68496
|
+
return relative === "" || relative.length > 0 && !relative.startsWith("..") && !import_node_path34.default.isAbsolute(relative);
|
|
67855
68497
|
}
|
|
67856
68498
|
async function deployGateHandoff(deps, projectSlug, task, runId, reason, leaseId) {
|
|
67857
68499
|
await deps.client.updateExecutionRun(projectSlug, runId, { status: "failed", finishedAt: (/* @__PURE__ */ new Date()).toISOString(), leaseId: leaseId ?? void 0 }).catch(() => {
|
|
@@ -67869,7 +68511,7 @@ async function deployGateHandoff(deps, projectSlug, task, runId, reason, leaseId
|
|
|
67869
68511
|
}).catch(() => {
|
|
67870
68512
|
});
|
|
67871
68513
|
await deps.client.createInboxItem(projectSlug, {
|
|
67872
|
-
id: `II-${
|
|
68514
|
+
id: `II-${import_node_crypto18.default.randomUUID()}`,
|
|
67873
68515
|
kind: "handoff",
|
|
67874
68516
|
taskId: task.id,
|
|
67875
68517
|
body: `Deploy gate for run ${runId} (task ${task.id} \u2014 ${task.title}) needs operator attention: ${reason}`
|
|
@@ -67888,7 +68530,7 @@ function maxLeaseReclaims() {
|
|
|
67888
68530
|
}
|
|
67889
68531
|
|
|
67890
68532
|
// src/async-job-consumer.ts
|
|
67891
|
-
var
|
|
68533
|
+
var import_node_crypto19 = __toESM(require("node:crypto"), 1);
|
|
67892
68534
|
var ASYNC_JOB_MAX_ATTEMPTS = 2;
|
|
67893
68535
|
function ASYNC_UNOWNED_TTL_DAYS() {
|
|
67894
68536
|
const raw = Number(process.env.MRRLIN_ASYNC_UNOWNED_TTL_DAYS);
|
|
@@ -68013,7 +68655,7 @@ async function driveAsyncJob(deps, projectSlug, jobId) {
|
|
|
68013
68655
|
const delivery = descriptor2.onComplete(outcome, input);
|
|
68014
68656
|
if (!delivery.suppressInbox) {
|
|
68015
68657
|
await deps.client.createInboxItem(projectSlug, {
|
|
68016
|
-
id: delivery.id ?? `II-${
|
|
68658
|
+
id: delivery.id ?? `II-${import_node_crypto19.default.randomUUID()}`,
|
|
68017
68659
|
kind: delivery.kind,
|
|
68018
68660
|
body: delivery.body,
|
|
68019
68661
|
...delivery.taskId ? { taskId: delivery.taskId } : {},
|
|
@@ -68031,13 +68673,13 @@ async function deriveRequestedHash(client, toolName2, input) {
|
|
|
68031
68673
|
if (input.requestedHash) return input.requestedHash;
|
|
68032
68674
|
if (toolName2 === "run_spec_consensus" && input.pageId) {
|
|
68033
68675
|
const page = await client.getWikiPage(input.projectSlug, input.pageId);
|
|
68034
|
-
return page.contentHash ??
|
|
68676
|
+
return page.contentHash ?? import_node_crypto19.default.createHash("sha256").update(page.markdownBody).digest("hex");
|
|
68035
68677
|
}
|
|
68036
68678
|
if (toolName2 === "draft_task_spec" && input.taskId) {
|
|
68037
68679
|
const task = await client.getTask(input.projectSlug, input.taskId);
|
|
68038
|
-
return task.updatedAt ??
|
|
68680
|
+
return task.updatedAt ?? import_node_crypto19.default.createHash("sha256").update(JSON.stringify(task)).digest("hex");
|
|
68039
68681
|
}
|
|
68040
|
-
return
|
|
68682
|
+
return import_node_crypto19.default.createHash("sha256").update(JSON.stringify(input)).digest("hex");
|
|
68041
68683
|
}
|
|
68042
68684
|
async function runAsyncBackstopSweep(deps, drive = (slug, jobId) => driveAsyncJob(deps, slug, jobId)) {
|
|
68043
68685
|
const projects = await deps.client.listProjects();
|
|
@@ -68063,19 +68705,19 @@ async function runAsyncBackstopSweep(deps, drive = (slug, jobId) => driveAsyncJo
|
|
|
68063
68705
|
}
|
|
68064
68706
|
|
|
68065
68707
|
// src/bridge-artifacts.ts
|
|
68066
|
-
var
|
|
68708
|
+
var import_node_fs21 = __toESM(require("node:fs"), 1);
|
|
68067
68709
|
var import_promises14 = __toESM(require("node:fs/promises"), 1);
|
|
68068
|
-
var
|
|
68710
|
+
var import_node_path35 = __toESM(require("node:path"), 1);
|
|
68069
68711
|
var DEFAULT_MAX_ARTIFACTS_BYTES = 500 * 1024 * 1024;
|
|
68070
68712
|
var DEFAULT_MAX_ARTIFACT_AGE_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
68071
68713
|
function resolveArtifactsDir(baseStateDir) {
|
|
68072
68714
|
const stateDir = baseStateDir ?? resolveStateDir();
|
|
68073
|
-
return
|
|
68715
|
+
return import_node_path35.default.join(stateDir, "artifacts");
|
|
68074
68716
|
}
|
|
68075
68717
|
function ensureDir(dir) {
|
|
68076
|
-
|
|
68718
|
+
import_node_fs21.default.mkdirSync(dir, { recursive: true, mode: 448 });
|
|
68077
68719
|
try {
|
|
68078
|
-
|
|
68720
|
+
import_node_fs21.default.chmodSync(dir, 448);
|
|
68079
68721
|
} catch {
|
|
68080
68722
|
}
|
|
68081
68723
|
}
|
|
@@ -68083,7 +68725,7 @@ function safeArtifactPath(artifactsDir, id) {
|
|
|
68083
68725
|
if (!id || typeof id !== "string" || !/^[a-zA-Z0-9_-]+$/.test(id)) {
|
|
68084
68726
|
throw new Error("Invalid artifact id");
|
|
68085
68727
|
}
|
|
68086
|
-
return
|
|
68728
|
+
return import_node_path35.default.join(artifactsDir, `${id}.json`);
|
|
68087
68729
|
}
|
|
68088
68730
|
async function writeLocalArtifact(id, payload, baseStateDir) {
|
|
68089
68731
|
const artifactsDir = resolveArtifactsDir(baseStateDir);
|
|
@@ -68126,7 +68768,7 @@ async function cleanArtifacts(baseStateDir, options) {
|
|
|
68126
68768
|
let deletedBytes = 0;
|
|
68127
68769
|
for (const name of entries) {
|
|
68128
68770
|
if (!name.endsWith(".json")) continue;
|
|
68129
|
-
const filePath =
|
|
68771
|
+
const filePath = import_node_path35.default.join(artifactsDir, name);
|
|
68130
68772
|
try {
|
|
68131
68773
|
const stat3 = await import_promises14.default.stat(filePath);
|
|
68132
68774
|
if (now - stat3.mtimeMs > maxAgeMs) {
|
|
@@ -68353,16 +68995,16 @@ function agentIdleMs(provider) {
|
|
|
68353
68995
|
}
|
|
68354
68996
|
|
|
68355
68997
|
// src/thread-index.ts
|
|
68356
|
-
var
|
|
68357
|
-
var
|
|
68998
|
+
var import_node_fs22 = require("node:fs");
|
|
68999
|
+
var import_node_path36 = __toESM(require("node:path"), 1);
|
|
68358
69000
|
function threadIndexPath(stateDir) {
|
|
68359
|
-
return
|
|
69001
|
+
return import_node_path36.default.join(stateDir, "threads.json");
|
|
68360
69002
|
}
|
|
68361
69003
|
function loadThreadIndex(stateDir, ttlMs, now) {
|
|
68362
69004
|
const result = /* @__PURE__ */ new Map();
|
|
68363
69005
|
let parsed;
|
|
68364
69006
|
try {
|
|
68365
|
-
parsed = JSON.parse((0,
|
|
69007
|
+
parsed = JSON.parse((0, import_node_fs22.readFileSync)(threadIndexPath(stateDir), "utf8"));
|
|
68366
69008
|
} catch {
|
|
68367
69009
|
return result;
|
|
68368
69010
|
}
|
|
@@ -68387,8 +69029,8 @@ function loadThreadIndex(stateDir, ttlMs, now) {
|
|
|
68387
69029
|
return result;
|
|
68388
69030
|
}
|
|
68389
69031
|
function saveThreadIndex(stateDir, entries) {
|
|
68390
|
-
(0,
|
|
68391
|
-
(0,
|
|
69032
|
+
(0, import_node_fs22.mkdirSync)(stateDir, { recursive: true, mode: 448 });
|
|
69033
|
+
(0, import_node_fs22.writeFileSync)(threadIndexPath(stateDir), `${JSON.stringify(Object.fromEntries(entries), null, 2)}
|
|
68392
69034
|
`, {
|
|
68393
69035
|
encoding: "utf8",
|
|
68394
69036
|
mode: 384
|
|
@@ -68524,9 +69166,9 @@ function createToolBusyClock(opts) {
|
|
|
68524
69166
|
|
|
68525
69167
|
// src/remote-phone-relay.ts
|
|
68526
69168
|
var import_node_events3 = require("node:events");
|
|
68527
|
-
var
|
|
68528
|
-
var
|
|
68529
|
-
var
|
|
69169
|
+
var import_node_fs23 = require("node:fs");
|
|
69170
|
+
var import_node_os17 = require("node:os");
|
|
69171
|
+
var import_node_path37 = require("node:path");
|
|
68530
69172
|
|
|
68531
69173
|
// ../../node_modules/.pnpm/@noble+hashes@1.3.3/node_modules/@noble/hashes/esm/cryptoNode.js
|
|
68532
69174
|
var nc = __toESM(require("node:crypto"), 1);
|
|
@@ -68989,7 +69631,7 @@ var SHA256 = class extends SHA2 {
|
|
|
68989
69631
|
this.buffer.fill(0);
|
|
68990
69632
|
}
|
|
68991
69633
|
};
|
|
68992
|
-
var
|
|
69634
|
+
var sha2563 = /* @__PURE__ */ wrapConstructor(() => new SHA256());
|
|
68993
69635
|
|
|
68994
69636
|
// ../../node_modules/.pnpm/@noble+curves@1.3.0/node_modules/@noble/curves/esm/abstract/utils.js
|
|
68995
69637
|
var _0n = BigInt(0);
|
|
@@ -69133,7 +69775,7 @@ function validateObject(object3, validators, optValidators = {}) {
|
|
|
69133
69775
|
// ../../packages/director-e2e/dist/verifier.js
|
|
69134
69776
|
var RELAY_AUTH_LABEL = utf8ToBytes("relay-auth");
|
|
69135
69777
|
function relayAuth(secret) {
|
|
69136
|
-
return hmac(
|
|
69778
|
+
return hmac(sha2563, secret, RELAY_AUTH_LABEL);
|
|
69137
69779
|
}
|
|
69138
69780
|
|
|
69139
69781
|
// ../../node_modules/.pnpm/@noble+hashes@1.3.3/node_modules/@noble/hashes/esm/_u64.js
|
|
@@ -70467,16 +71109,16 @@ var hkdf = (hash3, ikm, salt, info, length) => expand(hash3, extract(hash3, ikm,
|
|
|
70467
71109
|
|
|
70468
71110
|
// ../../packages/director-e2e/dist/kdf.js
|
|
70469
71111
|
function deriveMasterKey(ikm, salt, info) {
|
|
70470
|
-
return hkdf(
|
|
71112
|
+
return hkdf(sha2563, ikm, salt, info, 32);
|
|
70471
71113
|
}
|
|
70472
71114
|
function deriveDirectionKeys(masterKey) {
|
|
70473
71115
|
return {
|
|
70474
|
-
p2a: hkdf(
|
|
70475
|
-
a2p: hkdf(
|
|
71116
|
+
p2a: hkdf(sha2563, masterKey, void 0, utf8ToBytes("dir:phone->agent"), 32),
|
|
71117
|
+
a2p: hkdf(sha2563, masterKey, void 0, utf8ToBytes("dir:agent->phone"), 32)
|
|
70476
71118
|
};
|
|
70477
71119
|
}
|
|
70478
71120
|
function confirmationMac(masterKey, role, transcript) {
|
|
70479
|
-
return hmac(
|
|
71121
|
+
return hmac(sha2563, masterKey, concatBytes(utf8ToBytes(`confirm:${role}`), transcript));
|
|
70480
71122
|
}
|
|
70481
71123
|
|
|
70482
71124
|
// ../../node_modules/.pnpm/@noble+ciphers@0.4.1/node_modules/@noble/ciphers/esm/utils.js
|
|
@@ -72097,9 +72739,9 @@ var DirectorRelay = class {
|
|
|
72097
72739
|
|
|
72098
72740
|
// src/remote-phone-relay.ts
|
|
72099
72741
|
function loadOrCreateAgentDeviceKey() {
|
|
72100
|
-
const
|
|
72742
|
+
const path33 = (0, import_node_path37.join)((0, import_node_os17.homedir)(), ".mrrlin", "agent-device-key");
|
|
72101
72743
|
try {
|
|
72102
|
-
const raw = JSON.parse((0,
|
|
72744
|
+
const raw = JSON.parse((0, import_node_fs23.readFileSync)(path33, "utf8"));
|
|
72103
72745
|
if (typeof raw.priv === "string" && typeof raw.pub === "string") {
|
|
72104
72746
|
return { privateKey: fromBase64Url(raw.priv), publicKey: fromBase64Url(raw.pub) };
|
|
72105
72747
|
}
|
|
@@ -72107,9 +72749,9 @@ function loadOrCreateAgentDeviceKey() {
|
|
|
72107
72749
|
}
|
|
72108
72750
|
const kp = generateIdentityKeyPair();
|
|
72109
72751
|
try {
|
|
72110
|
-
(0,
|
|
72111
|
-
(0,
|
|
72112
|
-
|
|
72752
|
+
(0, import_node_fs23.mkdirSync)((0, import_node_path37.join)((0, import_node_os17.homedir)(), ".mrrlin"), { recursive: true });
|
|
72753
|
+
(0, import_node_fs23.writeFileSync)(
|
|
72754
|
+
path33,
|
|
72113
72755
|
JSON.stringify({ priv: toBase64Url(kp.privateKey), pub: toBase64Url(kp.publicKey) }),
|
|
72114
72756
|
{ mode: 384 }
|
|
72115
72757
|
);
|
|
@@ -72117,10 +72759,10 @@ function loadOrCreateAgentDeviceKey() {
|
|
|
72117
72759
|
}
|
|
72118
72760
|
return kp;
|
|
72119
72761
|
}
|
|
72120
|
-
var AGENT_PAIRING_PATH = (0,
|
|
72762
|
+
var AGENT_PAIRING_PATH = (0, import_node_path37.join)((0, import_node_os17.homedir)(), ".mrrlin", "agent-pairing.json");
|
|
72121
72763
|
function loadAgentPairing() {
|
|
72122
72764
|
try {
|
|
72123
|
-
const raw = JSON.parse((0,
|
|
72765
|
+
const raw = JSON.parse((0, import_node_fs23.readFileSync)(AGENT_PAIRING_PATH, "utf8"));
|
|
72124
72766
|
if (typeof raw.channelId === "string" && typeof raw.agentControlSecret === "string" && typeof raw.relayAuth === "string" && typeof raw.peerIdentityKey === "string") {
|
|
72125
72767
|
return {
|
|
72126
72768
|
channelId: raw.channelId,
|
|
@@ -72135,8 +72777,8 @@ function loadAgentPairing() {
|
|
|
72135
72777
|
}
|
|
72136
72778
|
function saveAgentPairing(record2) {
|
|
72137
72779
|
try {
|
|
72138
|
-
(0,
|
|
72139
|
-
(0,
|
|
72780
|
+
(0, import_node_fs23.mkdirSync)((0, import_node_path37.join)((0, import_node_os17.homedir)(), ".mrrlin"), { recursive: true });
|
|
72781
|
+
(0, import_node_fs23.writeFileSync)(AGENT_PAIRING_PATH, JSON.stringify(record2), { mode: 384 });
|
|
72140
72782
|
} catch {
|
|
72141
72783
|
}
|
|
72142
72784
|
}
|
|
@@ -72314,14 +72956,14 @@ async function renderPairingQrSvg(payload) {
|
|
|
72314
72956
|
}
|
|
72315
72957
|
|
|
72316
72958
|
// src/executor-server.ts
|
|
72317
|
-
var
|
|
72959
|
+
var import_node_child_process24 = require("node:child_process");
|
|
72318
72960
|
function defaultReadinessRunner(provider) {
|
|
72319
72961
|
if (provider !== "codex" && provider !== "claude" && provider !== "agy") {
|
|
72320
72962
|
throw new Error(`unsupported executor provider: ${String(provider)}`);
|
|
72321
72963
|
}
|
|
72322
72964
|
const command = provider === "claude" ? "claude" : provider === "agy" ? "agy" : "codex";
|
|
72323
72965
|
return (args) => {
|
|
72324
|
-
const r = (0,
|
|
72966
|
+
const r = (0, import_node_child_process24.spawnSync)(command, args, { encoding: "utf8", timeout: 8e3, shell: true });
|
|
72325
72967
|
return { status: r.status, stdout: r.stdout ?? "", stderr: r.stderr ?? "" };
|
|
72326
72968
|
};
|
|
72327
72969
|
}
|
|
@@ -72375,7 +73017,7 @@ async function startExecutorServer(opts) {
|
|
|
72375
73017
|
const rawBaseEnv = opts.env ?? (isVerification ? buildVerificationEnv(process.env) : process.env);
|
|
72376
73018
|
const baseEnv = isVerification ? buildVerificationEnv(rawBaseEnv) : { ...rawBaseEnv };
|
|
72377
73019
|
const childEnv = withDisabledGitHooksEnv(baseEnv, opts.disabledGitHooksDir);
|
|
72378
|
-
const baseSpawn = opts.spawn ??
|
|
73020
|
+
const baseSpawn = opts.spawn ?? import_node_child_process24.spawn;
|
|
72379
73021
|
const hasExtraFd = opts.brokerSocket != null || opts.brokerSocketFd != null;
|
|
72380
73022
|
const spawnFn = (cmd, args = [], spawnOpts = {}) => {
|
|
72381
73023
|
const argList = [...args];
|
|
@@ -72519,10 +73161,10 @@ var import_node_http2 = __toESM(require("node:http"), 1);
|
|
|
72519
73161
|
var import_node_https2 = __toESM(require("node:https"), 1);
|
|
72520
73162
|
var import_node_net2 = __toESM(require("node:net"), 1);
|
|
72521
73163
|
var import_node_tls = __toESM(require("node:tls"), 1);
|
|
72522
|
-
var
|
|
72523
|
-
var
|
|
72524
|
-
var
|
|
72525
|
-
var
|
|
73164
|
+
var import_node_fs24 = __toESM(require("node:fs"), 1);
|
|
73165
|
+
var import_node_os18 = __toESM(require("node:os"), 1);
|
|
73166
|
+
var import_node_path38 = __toESM(require("node:path"), 1);
|
|
73167
|
+
var import_node_crypto20 = __toESM(require("node:crypto"), 1);
|
|
72526
73168
|
var import_node_zlib = __toESM(require("node:zlib"), 1);
|
|
72527
73169
|
|
|
72528
73170
|
// src/verification-egress-policy.ts
|
|
@@ -72860,20 +73502,20 @@ function reauthorizeRedirect(params) {
|
|
|
72860
73502
|
// src/verification-broker.ts
|
|
72861
73503
|
var TEST_CONNECT_OVERRIDE_SYMBOL = Symbol.for("mrrlin.test.connectOverride");
|
|
72862
73504
|
async function createVerificationBrokerSession(options) {
|
|
72863
|
-
const nonce =
|
|
73505
|
+
const nonce = import_node_crypto20.default.randomBytes(16).toString("hex");
|
|
72864
73506
|
let createdDir = null;
|
|
72865
73507
|
let socketPath = options.socketPath;
|
|
72866
73508
|
if (!socketPath) {
|
|
72867
|
-
createdDir =
|
|
72868
|
-
|
|
72869
|
-
socketPath =
|
|
73509
|
+
createdDir = import_node_fs24.default.mkdtempSync(import_node_path38.default.join(import_node_os18.default.tmpdir(), "mrrlin-broker-"));
|
|
73510
|
+
import_node_fs24.default.chmodSync(createdDir, 448);
|
|
73511
|
+
socketPath = import_node_path38.default.join(
|
|
72870
73512
|
createdDir,
|
|
72871
73513
|
`broker-${options.runId.replace(/[^a-zA-Z0-9_-]/g, "")}-${nonce}.sock`
|
|
72872
73514
|
);
|
|
72873
73515
|
}
|
|
72874
73516
|
try {
|
|
72875
|
-
if (
|
|
72876
|
-
|
|
73517
|
+
if (import_node_fs24.default.existsSync(socketPath)) {
|
|
73518
|
+
import_node_fs24.default.unlinkSync(socketPath);
|
|
72877
73519
|
}
|
|
72878
73520
|
} catch {
|
|
72879
73521
|
}
|
|
@@ -73161,12 +73803,12 @@ async function createVerificationBrokerSession(options) {
|
|
|
73161
73803
|
} catch (err) {
|
|
73162
73804
|
server.close();
|
|
73163
73805
|
try {
|
|
73164
|
-
if (
|
|
73806
|
+
if (import_node_fs24.default.existsSync(socketPath)) import_node_fs24.default.unlinkSync(socketPath);
|
|
73165
73807
|
} catch (error51) {
|
|
73166
73808
|
}
|
|
73167
73809
|
if (createdDir) {
|
|
73168
73810
|
try {
|
|
73169
|
-
|
|
73811
|
+
import_node_fs24.default.rmSync(createdDir, { recursive: true, force: true });
|
|
73170
73812
|
} catch (error51) {
|
|
73171
73813
|
}
|
|
73172
73814
|
}
|
|
@@ -73194,14 +73836,14 @@ async function createVerificationBrokerSession(options) {
|
|
|
73194
73836
|
server.close(() => resolve2());
|
|
73195
73837
|
});
|
|
73196
73838
|
try {
|
|
73197
|
-
if (
|
|
73198
|
-
|
|
73839
|
+
if (import_node_fs24.default.existsSync(socketPath)) {
|
|
73840
|
+
import_node_fs24.default.unlinkSync(socketPath);
|
|
73199
73841
|
}
|
|
73200
73842
|
} catch {
|
|
73201
73843
|
}
|
|
73202
73844
|
if (createdDir) {
|
|
73203
73845
|
try {
|
|
73204
|
-
|
|
73846
|
+
import_node_fs24.default.rmSync(createdDir, { recursive: true, force: true });
|
|
73205
73847
|
} catch {
|
|
73206
73848
|
}
|
|
73207
73849
|
}
|
|
@@ -73697,9 +74339,9 @@ function extractVerificationSection(markdown) {
|
|
|
73697
74339
|
}
|
|
73698
74340
|
|
|
73699
74341
|
// src/director-reseed.ts
|
|
73700
|
-
var
|
|
74342
|
+
var import_node_fs25 = require("node:fs");
|
|
73701
74343
|
var import_node_readline2 = require("node:readline");
|
|
73702
|
-
var
|
|
74344
|
+
var import_node_path39 = require("node:path");
|
|
73703
74345
|
function estimateTokens(s) {
|
|
73704
74346
|
return Buffer.byteLength(s, "utf8");
|
|
73705
74347
|
}
|
|
@@ -73848,9 +74490,9 @@ async function readSessionRows(logsDir, files, sessionIds) {
|
|
|
73848
74490
|
const lines2 = [];
|
|
73849
74491
|
let missingFiles = 0;
|
|
73850
74492
|
for (const f of files) {
|
|
73851
|
-
const filePath = (0,
|
|
74493
|
+
const filePath = (0, import_node_path39.join)(logsDir, f);
|
|
73852
74494
|
try {
|
|
73853
|
-
const stream = (0,
|
|
74495
|
+
const stream = (0, import_node_fs25.createReadStream)(filePath, { encoding: "utf8" });
|
|
73854
74496
|
const rl = (0, import_node_readline2.createInterface)({ input: stream, crlfDelay: Infinity });
|
|
73855
74497
|
try {
|
|
73856
74498
|
for await (const line of rl) {
|
|
@@ -73874,18 +74516,18 @@ async function readSessionRows(logsDir, files, sessionIds) {
|
|
|
73874
74516
|
}
|
|
73875
74517
|
|
|
73876
74518
|
// src/external-agents-scrub.ts
|
|
73877
|
-
var
|
|
73878
|
-
var
|
|
73879
|
-
var
|
|
74519
|
+
var import_node_fs26 = __toESM(require("node:fs"), 1);
|
|
74520
|
+
var import_node_os19 = __toESM(require("node:os"), 1);
|
|
74521
|
+
var import_node_path40 = __toESM(require("node:path"), 1);
|
|
73880
74522
|
var REDACTION = "[REDACTED]";
|
|
73881
74523
|
var SHORT_VALUE_THRESHOLD = 8;
|
|
73882
|
-
var KEYS_ENV_PATH = () =>
|
|
74524
|
+
var KEYS_ENV_PATH = () => import_node_path40.default.join(import_node_os19.default.homedir(), ".local", "state", "external-agents", "keys.env");
|
|
73883
74525
|
var keysEnvCache = null;
|
|
73884
74526
|
function readKeysEnv() {
|
|
73885
74527
|
const filePath = KEYS_ENV_PATH();
|
|
73886
74528
|
let mtimeMs = 0;
|
|
73887
74529
|
try {
|
|
73888
|
-
mtimeMs =
|
|
74530
|
+
mtimeMs = import_node_fs26.default.statSync(filePath).mtimeMs;
|
|
73889
74531
|
} catch {
|
|
73890
74532
|
mtimeMs = 0;
|
|
73891
74533
|
}
|
|
@@ -73894,7 +74536,7 @@ function readKeysEnv() {
|
|
|
73894
74536
|
}
|
|
73895
74537
|
const map2 = /* @__PURE__ */ new Map();
|
|
73896
74538
|
try {
|
|
73897
|
-
const content =
|
|
74539
|
+
const content = import_node_fs26.default.readFileSync(filePath, "utf8");
|
|
73898
74540
|
for (const rawLine of content.split(/\r?\n/)) {
|
|
73899
74541
|
const line = rawLine.trim();
|
|
73900
74542
|
if (line === "" || line.startsWith("#")) continue;
|
|
@@ -74312,7 +74954,7 @@ function addBridgeModel(target, model) {
|
|
|
74312
74954
|
}
|
|
74313
74955
|
function readTextIfExists(filePath) {
|
|
74314
74956
|
try {
|
|
74315
|
-
return
|
|
74957
|
+
return import_node_fs27.default.readFileSync(filePath, "utf8");
|
|
74316
74958
|
} catch {
|
|
74317
74959
|
return null;
|
|
74318
74960
|
}
|
|
@@ -74323,9 +74965,9 @@ function readKnownGptSlugsFromTomlFile(filePath) {
|
|
|
74323
74965
|
return Array.from(raw.matchAll(/^\s*model\s*=\s*"([^"]+)"/gm)).map((match) => match[1]?.trim() ?? "").filter(isSelectableModelSlug);
|
|
74324
74966
|
}
|
|
74325
74967
|
function readCodexFallbackModels() {
|
|
74326
|
-
const codexHome = process.env.CODEX_HOME?.trim() ||
|
|
74968
|
+
const codexHome = process.env.CODEX_HOME?.trim() || import_node_path42.default.join(import_node_os21.default.homedir(), ".codex");
|
|
74327
74969
|
const models = /* @__PURE__ */ new Map();
|
|
74328
|
-
const cachePath =
|
|
74970
|
+
const cachePath = import_node_path42.default.join(codexHome, "models_cache.json");
|
|
74329
74971
|
const cacheRaw = readTextIfExists(cachePath);
|
|
74330
74972
|
if (cacheRaw) {
|
|
74331
74973
|
try {
|
|
@@ -74375,7 +75017,7 @@ function readCodexFallbackModels() {
|
|
|
74375
75017
|
);
|
|
74376
75018
|
}
|
|
74377
75019
|
}
|
|
74378
|
-
for (const slug of readKnownGptSlugsFromTomlFile(
|
|
75020
|
+
for (const slug of readKnownGptSlugsFromTomlFile(import_node_path42.default.join(codexHome, "config.toml"))) {
|
|
74379
75021
|
addBridgeModel(
|
|
74380
75022
|
models,
|
|
74381
75023
|
mapBridgeModel({
|
|
@@ -74389,11 +75031,11 @@ function readCodexFallbackModels() {
|
|
|
74389
75031
|
})
|
|
74390
75032
|
);
|
|
74391
75033
|
}
|
|
74392
|
-
const automationsDir =
|
|
75034
|
+
const automationsDir = import_node_path42.default.join(codexHome, "automations");
|
|
74393
75035
|
try {
|
|
74394
|
-
for (const entry of
|
|
75036
|
+
for (const entry of import_node_fs27.default.readdirSync(automationsDir, { withFileTypes: true })) {
|
|
74395
75037
|
if (!entry.isDirectory()) continue;
|
|
74396
|
-
for (const slug of readKnownGptSlugsFromTomlFile(
|
|
75038
|
+
for (const slug of readKnownGptSlugsFromTomlFile(import_node_path42.default.join(automationsDir, entry.name, "automation.toml"))) {
|
|
74397
75039
|
addBridgeModel(
|
|
74398
75040
|
models,
|
|
74399
75041
|
mapBridgeModel({
|
|
@@ -74413,18 +75055,18 @@ function readCodexFallbackModels() {
|
|
|
74413
75055
|
return [...models.values()];
|
|
74414
75056
|
}
|
|
74415
75057
|
function selfUpdateInboxItemId(offeredVersion) {
|
|
74416
|
-
if (!offeredVersion) return `II-MCPUPD-${(0,
|
|
75058
|
+
if (!offeredVersion) return `II-MCPUPD-${(0, import_node_crypto21.randomUUID)()}`;
|
|
74417
75059
|
if (/^[A-Za-z0-9._-]+$/.test(offeredVersion)) return `II-MCPUPD-${offeredVersion}`;
|
|
74418
|
-
const hash3 =
|
|
75060
|
+
const hash3 = import_node_crypto21.default.createHash("sha256").update(offeredVersion).digest("hex").slice(0, 10);
|
|
74419
75061
|
return `II-MCPUPD-${offeredVersion.replace(/[^A-Za-z0-9._-]/g, "-")}-${hash3}`;
|
|
74420
75062
|
}
|
|
74421
75063
|
function neutralCheckoutCwd(stateDir) {
|
|
74422
|
-
const dir =
|
|
75064
|
+
const dir = import_node_path42.default.join(stateDir, "no-checkout");
|
|
74423
75065
|
try {
|
|
74424
|
-
|
|
74425
|
-
if (!
|
|
75066
|
+
import_node_fs27.default.mkdirSync(dir, { recursive: true });
|
|
75067
|
+
if (!import_node_fs27.default.existsSync(import_node_path42.default.join(dir, ".git"))) {
|
|
74426
75068
|
try {
|
|
74427
|
-
(0,
|
|
75069
|
+
(0, import_node_child_process25.spawnSync)("git", ["init", "-b", "main"], { cwd: dir, stdio: "ignore" });
|
|
74428
75070
|
} catch {
|
|
74429
75071
|
}
|
|
74430
75072
|
}
|
|
@@ -74457,7 +75099,7 @@ function buildThreadStartParams(msg, config2, desiredModel) {
|
|
|
74457
75099
|
"- Reply in the operator's language for the whole turn (questions, task scopes, summaries).",
|
|
74458
75100
|
"- Keep chat short and human. No code blocks, DDL, terminal output, local filesystem paths, internal job/inbox UUIDs or alert markers in chat \u2014 put long content into a wiki page and link it.",
|
|
74459
75101
|
"- Spec pages in folder Specs must contain `## Acceptance criteria` followed by `- [ ]` items.",
|
|
74460
|
-
"- AGNOSTIC DELIVERY MANDATE: Mrrlin is an Agnostic Delivery Platform decoupled from mandatory GitHub. Delivery is routed strictly by artifact kind: (1) document -> wiki
|
|
75102
|
+
"- AGNOSTIC DELIVERY MANDATE: Mrrlin is an Agnostic Delivery Platform decoupled from mandatory GitHub. Delivery is routed strictly by artifact kind: (1) document -> wiki; (2) page -> publish (web pages, landing pages, interactive HTML previews); (3) file_set -> artifacts (file uploads, bundles, build zips); (4) message -> send (outbound webhooks, Slack, notifications); (5) code_change -> repo_host (GitHub; with no GitHub, a local git repo on the operator's computer: register_local_checkout without repo, init_local_repo only after an explicit yes, record their push choice with set_project_code_host). NEVER stall or refuse non-code tasks by demanding a Git repository. Non-code tasks deliver directly via page (Publish) or document (Wiki).",
|
|
74461
75103
|
"- 3-TIER COMMERCIAL SCOPE GOVERNANCE: Treat tasks by domain governance tier. (1) Tier 1 Core Tech Delivery (backend, frontend, SRE, databases): decompose autonomously into repository code changes (when a repo is bound) or code artifacts. (2) Tier 2 Planning & Content (landing pages, SEO, marketing): create actionable drafts; when details such as a phone number, brand name or copy are missing, do not loop on questions \u2014 create the task, record `## Placeholders: [NEED_INPUT: <item>]` in the Wiki spec, and set `autonomyLevel: 'human_review'`. (3) Tier 3 Guardrailed Advisory (high risk: privacy/GDPR, security/SOC 2, billing, production database migrations, infrastructure): always set `autonomyLevel: 'human_review'`, put the domain's standard safety controls into the spec, and state that irreversible actions need human sign-off.",
|
|
74462
75104
|
"- INBOX QUESTION RETIREMENT MANDATE \u2014 Retiring answered questions: Before creating a task/plan, retire only pending Inbox questions the operator actually answered. Call `decide_inbox_item(itemId: <exact id>, decidedBy: 'director', verdict: 'acknowledged', answer: <actual answer>)`. Use `verdict: 'rejected', reason: ...` only if moot. Never close an unrelated item.",
|
|
74463
75105
|
"- CHAT CLARIFICATIONS ARE IN CHAT ONLY: During synchronous interactive Director chat, ask clarifying questions directly in your chat response. DO NOT call `create_inbox_item(kind: 'question')` for routine conversational clarifications in Turn 1 \u2014 Inbox questions are reserved for autonomous background workers or asynchronous gate pauses that occur while the operator is away.",
|
|
@@ -74945,9 +75587,9 @@ async function runCollectedAgentTurn(handle, prompt, cwd, baseInstructions) {
|
|
|
74945
75587
|
}
|
|
74946
75588
|
function resolveDefaultBranch(checkoutPath) {
|
|
74947
75589
|
if (!checkoutPath) return "main";
|
|
74948
|
-
const
|
|
75590
|
+
const runGit2 = (args) => {
|
|
74949
75591
|
try {
|
|
74950
|
-
return (0,
|
|
75592
|
+
return (0, import_node_child_process25.execFileSync)("git", ["-C", checkoutPath, ...args], {
|
|
74951
75593
|
encoding: "utf8",
|
|
74952
75594
|
stdio: ["ignore", "pipe", "ignore"],
|
|
74953
75595
|
timeout: 15e3,
|
|
@@ -74957,13 +75599,13 @@ function resolveDefaultBranch(checkoutPath) {
|
|
|
74957
75599
|
return null;
|
|
74958
75600
|
}
|
|
74959
75601
|
};
|
|
74960
|
-
const symRef =
|
|
75602
|
+
const symRef = runGit2(["symbolic-ref", "refs/remotes/origin/HEAD"]);
|
|
74961
75603
|
if (symRef) {
|
|
74962
75604
|
const prefix = "refs/remotes/origin/";
|
|
74963
75605
|
const branch = symRef.startsWith(prefix) ? symRef.slice(prefix.length) : symRef;
|
|
74964
75606
|
if (branch) return branch;
|
|
74965
75607
|
}
|
|
74966
|
-
const remoteShow =
|
|
75608
|
+
const remoteShow = runGit2(["remote", "show", "origin"]);
|
|
74967
75609
|
if (remoteShow) {
|
|
74968
75610
|
const match = /HEAD branch:\s*(\S+)/.exec(remoteShow);
|
|
74969
75611
|
const branch = match?.[1];
|
|
@@ -74983,7 +75625,7 @@ async function runOrphanWorktreeSweep(client, opts) {
|
|
|
74983
75625
|
const cutoff = Date.now() - worktreeRetentionMs();
|
|
74984
75626
|
const isReapable = (worktreePath) => {
|
|
74985
75627
|
try {
|
|
74986
|
-
return
|
|
75628
|
+
return import_node_fs27.default.statSync(worktreePath).mtimeMs < cutoff;
|
|
74987
75629
|
} catch {
|
|
74988
75630
|
return false;
|
|
74989
75631
|
}
|
|
@@ -75135,7 +75777,7 @@ function createBridgeRequestListener(opts) {
|
|
|
75135
75777
|
res.end(JSON.stringify({ ok: false, error: "Origin not allowed." }));
|
|
75136
75778
|
return;
|
|
75137
75779
|
}
|
|
75138
|
-
const nonce =
|
|
75780
|
+
const nonce = import_node_crypto21.default.randomBytes(16).toString("base64url");
|
|
75139
75781
|
res.writeHead(200, { "content-type": "application/json" });
|
|
75140
75782
|
const publicHost = host === "0.0.0.0" ? "127.0.0.1" : host;
|
|
75141
75783
|
res.end(JSON.stringify({ ok: true, wsUrl: `ws://${publicHost}:${port}/ws`, token, nonce }));
|
|
@@ -75439,7 +76081,7 @@ function createBridgeMessageHandler(deps) {
|
|
|
75439
76081
|
}
|
|
75440
76082
|
}
|
|
75441
76083
|
socket.on("message", async (data) => {
|
|
75442
|
-
const spanId =
|
|
76084
|
+
const spanId = import_node_crypto21.default.randomUUID();
|
|
75443
76085
|
if (logCtx) {
|
|
75444
76086
|
logCtx.span.id = spanId;
|
|
75445
76087
|
logCtx.span.at = Date.now();
|
|
@@ -75501,7 +76143,7 @@ function createBridgeMessageHandler(deps) {
|
|
|
75501
76143
|
sendForSpan({ type: "checkout-state", ok: false, error: { code: "invalid_input", fields: { projectSlug: "required" } } });
|
|
75502
76144
|
return;
|
|
75503
76145
|
}
|
|
75504
|
-
const state = readCheckoutState(deps.checkoutRegistry, projectSlug,
|
|
76146
|
+
const state = readCheckoutState(deps.checkoutRegistry, projectSlug, import_node_os21.default.hostname());
|
|
75505
76147
|
if (!state) {
|
|
75506
76148
|
sendForSpan({ type: "checkout-state", ok: false, error: { code: "checkout_missing" } });
|
|
75507
76149
|
return;
|
|
@@ -75533,7 +76175,7 @@ function createBridgeMessageHandler(deps) {
|
|
|
75533
76175
|
const result = registerCheckout(
|
|
75534
76176
|
deps.checkoutRegistry,
|
|
75535
76177
|
{ projectSlug, path: typeof msg.path === "string" ? msg.path : "", repo },
|
|
75536
|
-
|
|
76178
|
+
import_node_os21.default.hostname()
|
|
75537
76179
|
);
|
|
75538
76180
|
if (!result.ok) {
|
|
75539
76181
|
sendForSpan({ type: "checkout-register", ok: false, error: { code: result.code, detail: result.detail } });
|
|
@@ -76046,7 +76688,7 @@ function createBridgeMessageHandler(deps) {
|
|
|
76046
76688
|
let desiredInstructionHash = null;
|
|
76047
76689
|
try {
|
|
76048
76690
|
const startParams = deps.buildStartParams(msg, desiredModel);
|
|
76049
|
-
desiredInstructionHash =
|
|
76691
|
+
desiredInstructionHash = import_node_crypto21.default.createHash("sha256").update(startParams.baseInstructions ?? "").digest("hex");
|
|
76050
76692
|
if (!thread) {
|
|
76051
76693
|
const newThread = {
|
|
76052
76694
|
threadId: "",
|
|
@@ -76123,7 +76765,7 @@ function createBridgeMessageHandler(deps) {
|
|
|
76123
76765
|
thread.inFlight = true;
|
|
76124
76766
|
pendingTurnSessions.delete(directorSessionId);
|
|
76125
76767
|
thread.replay = createReplayBuffer({
|
|
76126
|
-
turnId: (0,
|
|
76768
|
+
turnId: (0, import_node_crypto21.randomUUID)(),
|
|
76127
76769
|
spanId,
|
|
76128
76770
|
...deps.retentionMs !== void 0 ? { retentionMs: deps.retentionMs } : {},
|
|
76129
76771
|
...deps.ackLingerMs !== void 0 ? { ackLingerMs: deps.ackLingerMs } : {}
|
|
@@ -76738,7 +77380,7 @@ function parseConfig() {
|
|
|
76738
77380
|
}
|
|
76739
77381
|
function scanForOtherBridges() {
|
|
76740
77382
|
try {
|
|
76741
|
-
const result = (0,
|
|
77383
|
+
const result = (0, import_node_child_process25.spawnSync)("pgrep", ["-f", "mrrlin-mcp director-bridge"], {
|
|
76742
77384
|
encoding: "utf8"
|
|
76743
77385
|
});
|
|
76744
77386
|
if (result.status !== 0) return [];
|
|
@@ -76934,8 +77576,10 @@ async function startDirectorBridge() {
|
|
|
76934
77576
|
codexCwd: config2.codexCwd,
|
|
76935
77577
|
codexExecutable: config2.codexExecutable,
|
|
76936
77578
|
checkoutRegistry,
|
|
76937
|
-
worktreeRoot:
|
|
76938
|
-
locksDir:
|
|
77579
|
+
worktreeRoot: import_node_path42.default.join(config2.stateDir, "worktrees"),
|
|
77580
|
+
locksDir: import_node_path42.default.join(config2.stateDir, "locks"),
|
|
77581
|
+
// local-git-delivery: bridge-local evidence (checkout realpath, build logs) that never leaves this machine.
|
|
77582
|
+
localEvidenceDir: import_node_path42.default.join(config2.stateDir, "local-evidence"),
|
|
76939
77583
|
// Wire the executor server for code-execution runs. Each run gets its own provider process
|
|
76940
77584
|
// (app-server for codex, a resident CLI child for claude) at the run worktree, running
|
|
76941
77585
|
// UNRESTRICTED from the real operator config (owner no-sandbox decision — auth + mrrlin MCP
|
|
@@ -76952,7 +77596,7 @@ async function startDirectorBridge() {
|
|
|
76952
77596
|
// The run's provider process carries exactly its own project (or none), so its Mrrlin MCP
|
|
76953
77597
|
// server is bound to it and never to whatever the bridge's environment names.
|
|
76954
77598
|
env: threadProcessEnv(process.env, directorThreadEnv(projectSlug)),
|
|
76955
|
-
disabledGitHooksDir: prepareDisabledGitHooksDir(
|
|
77599
|
+
disabledGitHooksDir: prepareDisabledGitHooksDir(import_node_path42.default.join(config2.stateDir, "locks"), import_node_path42.default.basename(worktreePath)),
|
|
76956
77600
|
provider: providerId
|
|
76957
77601
|
});
|
|
76958
77602
|
return { handle: executor.handle, dispose: executor.dispose };
|
|
@@ -76983,10 +77627,10 @@ async function startDirectorBridge() {
|
|
|
76983
77627
|
runVerificationTurn: createRunVerificationTurn({
|
|
76984
77628
|
startSandbox: async (egressDomains, providerId, opts) => {
|
|
76985
77629
|
opts?.wrapCommand?.(["node"]);
|
|
76986
|
-
const scratchDir =
|
|
77630
|
+
const scratchDir = import_node_fs27.default.mkdtempSync(import_node_path42.default.join(import_node_os21.default.tmpdir(), "mrrlin-verify-"));
|
|
76987
77631
|
const executor = await startExecutorServer({
|
|
76988
77632
|
worktree: scratchDir,
|
|
76989
|
-
disabledGitHooksDir: prepareDisabledGitHooksDir(
|
|
77633
|
+
disabledGitHooksDir: prepareDisabledGitHooksDir(import_node_path42.default.join(config2.stateDir, "locks"), import_node_path42.default.basename(scratchDir)),
|
|
76990
77634
|
provider: providerId,
|
|
76991
77635
|
wrapCommand: opts?.wrapCommand,
|
|
76992
77636
|
brokerSocket: opts?.brokerSocket,
|
|
@@ -76999,7 +77643,7 @@ async function startDirectorBridge() {
|
|
|
76999
77643
|
dispose: () => {
|
|
77000
77644
|
executor.dispose();
|
|
77001
77645
|
try {
|
|
77002
|
-
|
|
77646
|
+
import_node_fs27.default.rmSync(scratchDir, { recursive: true, force: true });
|
|
77003
77647
|
} catch {
|
|
77004
77648
|
}
|
|
77005
77649
|
},
|
|
@@ -77032,7 +77676,7 @@ async function startDirectorBridge() {
|
|
|
77032
77676
|
};
|
|
77033
77677
|
const sessionSinks = createSessionSinkRegistry();
|
|
77034
77678
|
const tombstones = /* @__PURE__ */ new Map();
|
|
77035
|
-
const bridgeInstanceId = (0,
|
|
77679
|
+
const bridgeInstanceId = (0, import_node_crypto21.randomUUID)();
|
|
77036
77680
|
const asyncConsumerDeps = {
|
|
77037
77681
|
client,
|
|
77038
77682
|
run: wrappedTurnLock.run,
|
|
@@ -77210,7 +77854,7 @@ async function startDirectorBridge() {
|
|
|
77210
77854
|
const files = dayFilesInWindow(/* @__PURE__ */ new Date(), reseedWindowMs);
|
|
77211
77855
|
filesCount = files.length;
|
|
77212
77856
|
const sessionIds = [args.directorSessionId, ...args.priorSessionIds];
|
|
77213
|
-
const { lines: lines2, missingFiles } = await readSessionRows(
|
|
77857
|
+
const { lines: lines2, missingFiles } = await readSessionRows(import_node_path42.default.join(config2.stateDir, "logs"), files, sessionIds);
|
|
77214
77858
|
missingFilesCount = missingFiles;
|
|
77215
77859
|
const extracted = extractItems(lines2, sessionIds);
|
|
77216
77860
|
items = extracted.items;
|
|
@@ -77359,7 +78003,7 @@ async function startDirectorBridge() {
|
|
|
77359
78003
|
const bridgeLogger = createBridgeLogger(config2.stateDir, process.env);
|
|
77360
78004
|
let bridgeBinShaShort = "unknown00000";
|
|
77361
78005
|
try {
|
|
77362
|
-
bridgeBinShaShort =
|
|
78006
|
+
bridgeBinShaShort = import_node_crypto21.default.createHash("sha256").update(import_node_fs27.default.readFileSync(process.argv[1] ?? "")).digest("hex").slice(0, 12);
|
|
77363
78007
|
} catch {
|
|
77364
78008
|
}
|
|
77365
78009
|
attachBridgeWss(server, {
|
|
@@ -77495,8 +78139,8 @@ async function startDirectorBridge() {
|
|
|
77495
78139
|
);
|
|
77496
78140
|
void runOrphanWorktreeSweep(client, {
|
|
77497
78141
|
checkoutRegistry,
|
|
77498
|
-
worktreeRoot:
|
|
77499
|
-
locksDir:
|
|
78142
|
+
worktreeRoot: import_node_path42.default.join(config2.stateDir, "worktrees"),
|
|
78143
|
+
locksDir: import_node_path42.default.join(config2.stateDir, "locks")
|
|
77500
78144
|
});
|
|
77501
78145
|
{
|
|
77502
78146
|
const { retainedBuffers, retainedBytes, tombstonesRemoved } = sweepReplayBuffers(threads, tombstones, {
|
|
@@ -77800,7 +78444,7 @@ function timingSafeTokenEqual(provided, expected) {
|
|
|
77800
78444
|
const a = Buffer.from(provided);
|
|
77801
78445
|
const b = Buffer.from(expected);
|
|
77802
78446
|
if (a.length !== b.length) return false;
|
|
77803
|
-
return
|
|
78447
|
+
return import_node_crypto21.default.timingSafeEqual(a, b);
|
|
77804
78448
|
}
|
|
77805
78449
|
function readDispatchBody(req) {
|
|
77806
78450
|
return new Promise((resolve2, reject) => {
|
|
@@ -77822,15 +78466,15 @@ function readDispatchBody(req) {
|
|
|
77822
78466
|
function readOrCreateBridgeToken(stateDir) {
|
|
77823
78467
|
const explicit = (process.env.MRRLIN_DIRECTOR_BRIDGE_TOKEN ?? "").trim();
|
|
77824
78468
|
if (explicit) return explicit;
|
|
77825
|
-
const tokenPath =
|
|
78469
|
+
const tokenPath = import_node_path42.default.join(stateDir, "token.txt");
|
|
77826
78470
|
try {
|
|
77827
|
-
const existing =
|
|
78471
|
+
const existing = import_node_fs27.default.readFileSync(tokenPath, "utf8").trim();
|
|
77828
78472
|
if (existing) return existing;
|
|
77829
78473
|
} catch {
|
|
77830
78474
|
}
|
|
77831
|
-
|
|
77832
|
-
const token =
|
|
77833
|
-
|
|
78475
|
+
import_node_fs27.default.mkdirSync(stateDir, { recursive: true, mode: 448 });
|
|
78476
|
+
const token = import_node_crypto21.default.randomBytes(32).toString("base64url");
|
|
78477
|
+
import_node_fs27.default.writeFileSync(tokenPath, `${token}
|
|
77834
78478
|
`, { mode: 384 });
|
|
77835
78479
|
return token;
|
|
77836
78480
|
}
|
|
@@ -78738,9 +79382,9 @@ function runSetCredential(args) {
|
|
|
78738
79382
|
}
|
|
78739
79383
|
|
|
78740
79384
|
// src/install-service.ts
|
|
78741
|
-
var
|
|
78742
|
-
var
|
|
78743
|
-
var
|
|
79385
|
+
var import_node_os22 = __toESM(require("node:os"), 1);
|
|
79386
|
+
var import_node_fs28 = require("node:fs");
|
|
79387
|
+
var import_node_path43 = __toESM(require("node:path"), 1);
|
|
78744
79388
|
function parseEnvLine(line, env) {
|
|
78745
79389
|
const trimmed = line.trim();
|
|
78746
79390
|
if (!trimmed || trimmed === "}" || trimmed === "},") return;
|
|
@@ -79129,7 +79773,7 @@ function performConfigBackup(deps, ecoPath, existingText) {
|
|
|
79129
79773
|
deps.log("Service config backup failed.");
|
|
79130
79774
|
return;
|
|
79131
79775
|
}
|
|
79132
|
-
const dir =
|
|
79776
|
+
const dir = import_node_path43.default.dirname(ecoPath);
|
|
79133
79777
|
let files;
|
|
79134
79778
|
try {
|
|
79135
79779
|
files = deps.listDir(dir);
|
|
@@ -79141,7 +79785,7 @@ function performConfigBackup(deps, ecoPath, existingText) {
|
|
|
79141
79785
|
deps.log("Service config backup failed.");
|
|
79142
79786
|
return;
|
|
79143
79787
|
}
|
|
79144
|
-
const base =
|
|
79788
|
+
const base = import_node_path43.default.basename(ecoPath);
|
|
79145
79789
|
const backupRegex = new RegExp(`^${escapeRegex2(base)}\\.bak-\\d{4}-\\d{2}-\\d{2}T\\d{2}-\\d{2}-\\d{2}-\\d{3}Z$`);
|
|
79146
79790
|
const existingBackups = files.filter((f) => backupRegex.test(f));
|
|
79147
79791
|
if (existingBackups.length >= 10) {
|
|
@@ -79176,7 +79820,7 @@ function performConfigBackup(deps, ecoPath, existingText) {
|
|
|
79176
79820
|
var SYSTEM_PATH_DIRS = ["/usr/bin", "/bin", "/usr/sbin", "/sbin"];
|
|
79177
79821
|
function defaultHomeOwnerUid(home) {
|
|
79178
79822
|
try {
|
|
79179
|
-
return (0,
|
|
79823
|
+
return (0, import_node_fs28.statSync)(home).uid;
|
|
79180
79824
|
} catch {
|
|
79181
79825
|
return null;
|
|
79182
79826
|
}
|
|
@@ -79217,11 +79861,11 @@ function installService(deps) {
|
|
|
79217
79861
|
deps.log(resolved.reason);
|
|
79218
79862
|
return { ok: false };
|
|
79219
79863
|
}
|
|
79220
|
-
const home = deps.env.HOME ??
|
|
79864
|
+
const home = deps.env.HOME ?? import_node_os22.default.homedir();
|
|
79221
79865
|
const user = resolveBridgeUser({
|
|
79222
79866
|
env: deps.env,
|
|
79223
79867
|
home,
|
|
79224
|
-
userInfo: deps.userInfo ?? (() =>
|
|
79868
|
+
userInfo: deps.userInfo ?? (() => import_node_os22.default.userInfo()),
|
|
79225
79869
|
homeOwnerUid: deps.homeOwnerUid ?? defaultHomeOwnerUid,
|
|
79226
79870
|
log: deps.log
|
|
79227
79871
|
});
|
|
@@ -79242,12 +79886,12 @@ function installService(deps) {
|
|
|
79242
79886
|
const claudeBin = deps.which("claude");
|
|
79243
79887
|
const agyBin = deps.which("agy");
|
|
79244
79888
|
const resolvedBins = [...bins, claudeBin, agyBin].filter((b) => b !== null);
|
|
79245
|
-
const isWin =
|
|
79246
|
-
const systemDirs = isWin ? (deps.env.PATH || "").split(
|
|
79889
|
+
const isWin = import_node_os22.default.platform() === "win32";
|
|
79890
|
+
const systemDirs = isWin ? (deps.env.PATH || "").split(import_node_path43.default.delimiter).filter(Boolean) : SYSTEM_PATH_DIRS;
|
|
79247
79891
|
const pathEnv = Array.from(
|
|
79248
|
-
/* @__PURE__ */ new Set([...resolvedBins.map((b) =>
|
|
79249
|
-
).join(
|
|
79250
|
-
const ecoPath =
|
|
79892
|
+
/* @__PURE__ */ new Set([...resolvedBins.map((b) => import_node_path43.default.dirname(b)), ...systemDirs])
|
|
79893
|
+
).join(import_node_path43.default.delimiter);
|
|
79894
|
+
const ecoPath = import_node_path43.default.join(home, ".mrrlin", "ecosystem.config.cjs");
|
|
79251
79895
|
const existingText = deps.readFile ? deps.readFile(ecoPath) : null;
|
|
79252
79896
|
const parseResult = parseExistingEcosystemConfig(existingText);
|
|
79253
79897
|
if (parseResult.kind === "rejected") {
|
|
@@ -79325,14 +79969,14 @@ function uninstallService(deps) {
|
|
|
79325
79969
|
|
|
79326
79970
|
// src/uninstall-codex.ts
|
|
79327
79971
|
var import_promises17 = __toESM(require("node:fs/promises"), 1);
|
|
79328
|
-
var
|
|
79329
|
-
var
|
|
79972
|
+
var import_node_os23 = __toESM(require("node:os"), 1);
|
|
79973
|
+
var import_node_path44 = __toESM(require("node:path"), 1);
|
|
79330
79974
|
var toml5 = __toESM(require_toml(), 1);
|
|
79331
79975
|
function resolveCodexHome3(options) {
|
|
79332
79976
|
if (options.codexHome) return options.codexHome;
|
|
79333
|
-
if (options.homeDir) return
|
|
79977
|
+
if (options.homeDir) return import_node_path44.default.join(options.homeDir, ".codex");
|
|
79334
79978
|
if (process.env.CODEX_HOME) return process.env.CODEX_HOME;
|
|
79335
|
-
return
|
|
79979
|
+
return import_node_path44.default.join(import_node_os23.default.homedir(), ".codex");
|
|
79336
79980
|
}
|
|
79337
79981
|
async function pathExists6(target) {
|
|
79338
79982
|
try {
|
|
@@ -79345,7 +79989,7 @@ async function pathExists6(target) {
|
|
|
79345
79989
|
var MRRLIN_BLOCK_RE = /(^|\n)\[mcp_servers\.(?:mrrlin(?:-browser)?|external-agents)(?:\]|\.[^\]\n]*\])[\s\S]*?(?=\n\[|$)/g;
|
|
79346
79990
|
async function uninstallCodex(options = {}) {
|
|
79347
79991
|
const codexHome = resolveCodexHome3(options);
|
|
79348
|
-
const configPath =
|
|
79992
|
+
const configPath = import_node_path44.default.join(codexHome, "config.toml");
|
|
79349
79993
|
const removePrompts = async () => uninstallPrompts(codexHome, options.promptNames ?? []);
|
|
79350
79994
|
if (!await pathExists6(configPath)) {
|
|
79351
79995
|
return { action: "missing", configPath, prompts: await removePrompts() };
|
|
@@ -79373,10 +80017,10 @@ async function uninstallCodex(options = {}) {
|
|
|
79373
80017
|
}
|
|
79374
80018
|
async function uninstallPrompts(codexHome, names) {
|
|
79375
80019
|
if (names.length === 0) return [];
|
|
79376
|
-
const promptsDir =
|
|
80020
|
+
const promptsDir = import_node_path44.default.join(codexHome, "prompts");
|
|
79377
80021
|
const out = [];
|
|
79378
80022
|
for (const name of names) {
|
|
79379
|
-
const promptPath =
|
|
80023
|
+
const promptPath = import_node_path44.default.join(promptsDir, `${name}.md`);
|
|
79380
80024
|
try {
|
|
79381
80025
|
await import_promises17.default.unlink(promptPath);
|
|
79382
80026
|
out.push({ name, action: "removed", promptPath });
|
|
@@ -79394,7 +80038,7 @@ async function uninstallPrompts(codexHome, names) {
|
|
|
79394
80038
|
|
|
79395
80039
|
// src/extract/command.ts
|
|
79396
80040
|
var import_promises18 = require("node:fs/promises");
|
|
79397
|
-
var
|
|
80041
|
+
var import_node_path45 = require("node:path");
|
|
79398
80042
|
function parseArgs(args) {
|
|
79399
80043
|
const map2 = /* @__PURE__ */ new Map();
|
|
79400
80044
|
for (let i = 0; i < args.length; i++) {
|
|
@@ -79431,7 +80075,7 @@ Missing required flag(s): ${missing.join(
|
|
|
79431
80075
|
const days = await findSessionDays(deps.stateDir, sessionId);
|
|
79432
80076
|
const matchingLines = [];
|
|
79433
80077
|
for (const day of days) {
|
|
79434
|
-
const logPath = (0,
|
|
80078
|
+
const logPath = (0, import_node_path45.join)(deps.stateDir, "logs", `bridge-${day}.jsonl`);
|
|
79435
80079
|
let raw;
|
|
79436
80080
|
try {
|
|
79437
80081
|
raw = await (0, import_promises18.readFile)(logPath, "utf8");
|
|
@@ -79519,29 +80163,29 @@ Missing required flag(s): ${missing.join(
|
|
|
79519
80163
|
function augmentProcessPathWithCommonDirs() {
|
|
79520
80164
|
const isWin = process.platform === "win32";
|
|
79521
80165
|
if (isWin) return;
|
|
79522
|
-
const home = process.env.HOME || (0,
|
|
80166
|
+
const home = process.env.HOME || (0, import_node_os24.homedir)();
|
|
79523
80167
|
const candidates = [
|
|
79524
|
-
|
|
79525
|
-
|
|
80168
|
+
import_node_path47.default.join(home, ".local", "bin"),
|
|
80169
|
+
import_node_path47.default.join(home, ".cargo", "bin"),
|
|
79526
80170
|
"/usr/local/bin",
|
|
79527
80171
|
"/opt/homebrew/bin"
|
|
79528
80172
|
];
|
|
79529
|
-
const existing = (process.env.PATH || "").split(
|
|
80173
|
+
const existing = (process.env.PATH || "").split(import_node_path47.default.delimiter).filter(Boolean);
|
|
79530
80174
|
const existingSet = new Set(existing);
|
|
79531
|
-
const toAdd = candidates.filter((d) => !existingSet.has(d) && (0,
|
|
80175
|
+
const toAdd = candidates.filter((d) => !existingSet.has(d) && (0, import_node_fs29.existsSync)(d));
|
|
79532
80176
|
if (toAdd.length > 0) {
|
|
79533
|
-
process.env.PATH = [...existing, ...toAdd].join(
|
|
80177
|
+
process.env.PATH = [...existing, ...toAdd].join(import_node_path47.default.delimiter);
|
|
79534
80178
|
}
|
|
79535
80179
|
}
|
|
79536
80180
|
augmentProcessPathWithCommonDirs();
|
|
79537
80181
|
function pm2Runner(args) {
|
|
79538
|
-
const r = (0,
|
|
80182
|
+
const r = (0, import_node_child_process26.spawnSync)("pm2", args, { encoding: "utf8" });
|
|
79539
80183
|
process.stderr.write(r.stdout ?? "");
|
|
79540
80184
|
process.stderr.write(r.stderr ?? "");
|
|
79541
80185
|
return { code: r.status ?? 1, stdout: r.stdout ?? "" };
|
|
79542
80186
|
}
|
|
79543
80187
|
function whichBin(bin) {
|
|
79544
|
-
const r = (0,
|
|
80188
|
+
const r = (0, import_node_child_process26.spawnSync)("which", [bin], { encoding: "utf8" });
|
|
79545
80189
|
const out = (r.stdout ?? "").trim();
|
|
79546
80190
|
return r.status === 0 && out ? out.split("\n")[0] ?? null : null;
|
|
79547
80191
|
}
|
|
@@ -79549,16 +80193,16 @@ function bootHookStatus() {
|
|
|
79549
80193
|
if (process.platform !== "darwin") return { status: "unknown" };
|
|
79550
80194
|
const uid = process.getuid?.();
|
|
79551
80195
|
if (uid === void 0 || uid === 0) return { status: "unknown" };
|
|
79552
|
-
const home = process.env.HOME ?? (0,
|
|
79553
|
-
const agents =
|
|
80196
|
+
const home = process.env.HOME ?? (0, import_node_os24.homedir)();
|
|
80197
|
+
const agents = import_node_path47.default.join(home, "Library", "LaunchAgents");
|
|
79554
80198
|
const candidates = [
|
|
79555
|
-
{ label: "com.mrrlin.director-bridge", plist:
|
|
79556
|
-
{ label: "com.PM2", plist:
|
|
80199
|
+
{ label: "com.mrrlin.director-bridge", plist: import_node_path47.default.join(agents, "com.mrrlin.director-bridge.plist") },
|
|
80200
|
+
{ label: "com.PM2", plist: import_node_path47.default.join(agents, `pm2.${(0, import_node_os24.userInfo)().username}.plist`) }
|
|
79557
80201
|
];
|
|
79558
80202
|
for (const candidate of candidates) {
|
|
79559
|
-
const printed = (0,
|
|
80203
|
+
const printed = (0, import_node_child_process26.spawnSync)("launchctl", ["print", `gui/${uid}/${candidate.label}`], { encoding: "utf8" });
|
|
79560
80204
|
if (printed.status !== 0) continue;
|
|
79561
|
-
if (!(0,
|
|
80205
|
+
if (!(0, import_node_fs29.existsSync)(candidate.plist)) continue;
|
|
79562
80206
|
const out = printed.stdout ?? "";
|
|
79563
80207
|
const runs = /^\s*runs\s*=\s*(\d+)/m.exec(out);
|
|
79564
80208
|
const exitCode = /^\s*last exit code\s*=\s*(-?\d+)/m.exec(out);
|
|
@@ -79781,7 +80425,7 @@ async function main() {
|
|
|
79781
80425
|
}
|
|
79782
80426
|
case "external-agents-serve": {
|
|
79783
80427
|
const { command: command2, args } = externalAgentsServeArgs();
|
|
79784
|
-
const r = (0,
|
|
80428
|
+
const r = (0, import_node_child_process26.spawnSync)(command2, args, { stdio: "inherit", env: process.env });
|
|
79785
80429
|
process.exitCode = r.status ?? 1;
|
|
79786
80430
|
return;
|
|
79787
80431
|
}
|
|
@@ -79835,8 +80479,8 @@ async function main() {
|
|
|
79835
80479
|
}
|
|
79836
80480
|
}
|
|
79837
80481
|
try {
|
|
79838
|
-
const codexHome = process.env.CODEX_HOME ??
|
|
79839
|
-
(0,
|
|
80482
|
+
const codexHome = process.env.CODEX_HOME ?? import_node_path47.default.join(process.env.HOME ?? (0, import_node_os24.homedir)(), ".codex");
|
|
80483
|
+
(0, import_node_fs29.rmSync)(import_node_path47.default.join(codexHome, "prompts", "report-issue.md"), { force: true });
|
|
79840
80484
|
} catch {
|
|
79841
80485
|
}
|
|
79842
80486
|
const claudeResult = await installClaude({ binPath, force, serveEnv });
|
|
@@ -79858,7 +80502,7 @@ async function main() {
|
|
|
79858
80502
|
);
|
|
79859
80503
|
}
|
|
79860
80504
|
const realProviderRunner = (command2) => (args) => {
|
|
79861
|
-
const r = (0,
|
|
80505
|
+
const r = (0, import_node_child_process26.spawnSync)(command2, args, { encoding: "utf8", timeout: 8e3 });
|
|
79862
80506
|
return { status: r.status, stdout: r.stdout ?? "", stderr: r.stderr ?? "" };
|
|
79863
80507
|
};
|
|
79864
80508
|
for (const provider of ["codex", "claude", "agy"]) {
|
|
@@ -79906,13 +80550,13 @@ async function main() {
|
|
|
79906
80550
|
env: process.env,
|
|
79907
80551
|
cwd: process.cwd(),
|
|
79908
80552
|
writeFile: (p, c) => {
|
|
79909
|
-
(0,
|
|
79910
|
-
(0,
|
|
80553
|
+
(0, import_node_fs29.mkdirSync)(import_node_path47.default.dirname(p), { recursive: true, mode: 448 });
|
|
80554
|
+
(0, import_node_fs29.writeFileSync)(p, c, { mode: 384 });
|
|
79911
80555
|
},
|
|
79912
|
-
writeExclusiveFile: (p, c) => (0,
|
|
80556
|
+
writeExclusiveFile: (p, c) => (0, import_node_fs29.writeFileSync)(p, c, { flag: "wx", mode: 384 }),
|
|
79913
80557
|
listDir: (p) => {
|
|
79914
80558
|
try {
|
|
79915
|
-
return (0,
|
|
80559
|
+
return (0, import_node_fs29.readdirSync)(p);
|
|
79916
80560
|
} catch {
|
|
79917
80561
|
return null;
|
|
79918
80562
|
}
|
|
@@ -79923,7 +80567,7 @@ async function main() {
|
|
|
79923
80567
|
// value", never a failed install. See readExistingTelemetryDefaultProject.
|
|
79924
80568
|
readFile: (p) => {
|
|
79925
80569
|
try {
|
|
79926
|
-
return (0,
|
|
80570
|
+
return (0, import_node_fs29.readFileSync)(p, "utf8");
|
|
79927
80571
|
} catch {
|
|
79928
80572
|
return null;
|
|
79929
80573
|
}
|
|
@@ -79944,35 +80588,35 @@ async function main() {
|
|
|
79944
80588
|
runPm2: (a) => ({ code: pm2Runner(a).code }),
|
|
79945
80589
|
removeFile: (p) => {
|
|
79946
80590
|
try {
|
|
79947
|
-
(0,
|
|
80591
|
+
(0, import_node_fs29.rmSync)(p, { force: true });
|
|
79948
80592
|
} catch {
|
|
79949
80593
|
}
|
|
79950
80594
|
},
|
|
79951
80595
|
purgeSecret: purge,
|
|
79952
80596
|
secretPath: agentCredentialPath(),
|
|
79953
80597
|
tokenPath: operatorTokenPath(),
|
|
79954
|
-
ecoPath:
|
|
80598
|
+
ecoPath: import_node_path47.default.join(process.env.HOME ?? (0, import_node_os24.homedir)(), ".mrrlin", "ecosystem.config.cjs"),
|
|
79955
80599
|
log: (m) => process.stderr.write(`[mrrlin-mcp uninstall-service] ${m}
|
|
79956
80600
|
`)
|
|
79957
80601
|
});
|
|
79958
80602
|
return;
|
|
79959
80603
|
}
|
|
79960
80604
|
case "uninstall": {
|
|
79961
|
-
const home = process.env.HOME ?? (0,
|
|
80605
|
+
const home = process.env.HOME ?? (0, import_node_os24.homedir)();
|
|
79962
80606
|
const log = (m) => process.stderr.write(`[mrrlin-mcp uninstall] ${m}
|
|
79963
80607
|
`);
|
|
79964
80608
|
uninstallService({
|
|
79965
80609
|
runPm2: (a) => ({ code: pm2Runner(a).code }),
|
|
79966
80610
|
removeFile: (p) => {
|
|
79967
80611
|
try {
|
|
79968
|
-
(0,
|
|
80612
|
+
(0, import_node_fs29.rmSync)(p, { force: true });
|
|
79969
80613
|
} catch {
|
|
79970
80614
|
}
|
|
79971
80615
|
},
|
|
79972
80616
|
purgeSecret: true,
|
|
79973
80617
|
secretPath: agentCredentialPath(),
|
|
79974
80618
|
tokenPath: operatorTokenPath(),
|
|
79975
|
-
ecoPath:
|
|
80619
|
+
ecoPath: import_node_path47.default.join(home, ".mrrlin", "ecosystem.config.cjs"),
|
|
79976
80620
|
log
|
|
79977
80621
|
});
|
|
79978
80622
|
let codexOk = true;
|
|
@@ -79992,7 +80636,7 @@ async function main() {
|
|
|
79992
80636
|
log(`codex config NOT modified: ${error51 instanceof Error ? error51.message : String(error51)}`);
|
|
79993
80637
|
}
|
|
79994
80638
|
try {
|
|
79995
|
-
(0,
|
|
80639
|
+
(0, import_node_fs29.rmSync)(import_node_path47.default.join(home, ".mrrlin"), { recursive: true, force: true });
|
|
79996
80640
|
} catch {
|
|
79997
80641
|
}
|
|
79998
80642
|
log("removed ~/.mrrlin");
|
|
@@ -80033,7 +80677,7 @@ ${HELP_TEXT}`);
|
|
|
80033
80677
|
}
|
|
80034
80678
|
}
|
|
80035
80679
|
function resolveSelfBinPath() {
|
|
80036
|
-
return
|
|
80680
|
+
return import_node_path46.default.resolve(process.argv[1] ?? process.execPath);
|
|
80037
80681
|
}
|
|
80038
80682
|
main().catch((error51) => {
|
|
80039
80683
|
process.stderr.write(`mrrlin-mcp fatal error: ${error51 instanceof Error ? error51.message : String(error51)}
|