@mrrlin-dev/mcp 0.3.5 → 0.3.8
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 +357 -632
- package/package.json +5 -5
package/dist/bin.cjs
CHANGED
|
@@ -4273,7 +4273,7 @@ var require_websocket = __commonJS({
|
|
|
4273
4273
|
var http2 = require("http");
|
|
4274
4274
|
var net = require("net");
|
|
4275
4275
|
var tls = require("tls");
|
|
4276
|
-
var { randomBytes:
|
|
4276
|
+
var { randomBytes: randomBytes4, createHash: createHash3 } = require("crypto");
|
|
4277
4277
|
var { Duplex, Readable } = require("stream");
|
|
4278
4278
|
var { URL: URL2 } = require("url");
|
|
4279
4279
|
var PerMessageDeflate2 = require_permessage_deflate();
|
|
@@ -4811,7 +4811,7 @@ var require_websocket = __commonJS({
|
|
|
4811
4811
|
}
|
|
4812
4812
|
}
|
|
4813
4813
|
const defaultPort = isSecure ? 443 : 80;
|
|
4814
|
-
const key =
|
|
4814
|
+
const key = randomBytes4(16).toString("base64");
|
|
4815
4815
|
const request = isSecure ? https.request : http2.request;
|
|
4816
4816
|
const protocolSet = /* @__PURE__ */ new Set();
|
|
4817
4817
|
let perMessageDeflate;
|
|
@@ -7683,7 +7683,7 @@ var require_polyfills = __commonJS({
|
|
|
7683
7683
|
var constants = require("constants");
|
|
7684
7684
|
var origCwd = process.cwd;
|
|
7685
7685
|
var cwd = null;
|
|
7686
|
-
var
|
|
7686
|
+
var platform = process.env.GRACEFUL_FS_PLATFORM || process.platform;
|
|
7687
7687
|
process.cwd = function() {
|
|
7688
7688
|
if (!cwd)
|
|
7689
7689
|
cwd = origCwd.call(process);
|
|
@@ -7729,20 +7729,20 @@ var require_polyfills = __commonJS({
|
|
|
7729
7729
|
fs7.fstatSync = statFixSync(fs7.fstatSync);
|
|
7730
7730
|
fs7.lstatSync = statFixSync(fs7.lstatSync);
|
|
7731
7731
|
if (fs7.chmod && !fs7.lchmod) {
|
|
7732
|
-
fs7.lchmod = function(
|
|
7732
|
+
fs7.lchmod = function(path15, mode, cb) {
|
|
7733
7733
|
if (cb) process.nextTick(cb);
|
|
7734
7734
|
};
|
|
7735
7735
|
fs7.lchmodSync = function() {
|
|
7736
7736
|
};
|
|
7737
7737
|
}
|
|
7738
7738
|
if (fs7.chown && !fs7.lchown) {
|
|
7739
|
-
fs7.lchown = function(
|
|
7739
|
+
fs7.lchown = function(path15, uid, gid, cb) {
|
|
7740
7740
|
if (cb) process.nextTick(cb);
|
|
7741
7741
|
};
|
|
7742
7742
|
fs7.lchownSync = function() {
|
|
7743
7743
|
};
|
|
7744
7744
|
}
|
|
7745
|
-
if (
|
|
7745
|
+
if (platform === "win32") {
|
|
7746
7746
|
fs7.rename = typeof fs7.rename !== "function" ? fs7.rename : function(fs$rename) {
|
|
7747
7747
|
function rename(from, to, cb) {
|
|
7748
7748
|
var start = Date.now();
|
|
@@ -7803,9 +7803,9 @@ var require_polyfills = __commonJS({
|
|
|
7803
7803
|
};
|
|
7804
7804
|
}(fs7.readSync);
|
|
7805
7805
|
function patchLchmod(fs8) {
|
|
7806
|
-
fs8.lchmod = function(
|
|
7806
|
+
fs8.lchmod = function(path15, mode, callback) {
|
|
7807
7807
|
fs8.open(
|
|
7808
|
-
|
|
7808
|
+
path15,
|
|
7809
7809
|
constants.O_WRONLY | constants.O_SYMLINK,
|
|
7810
7810
|
mode,
|
|
7811
7811
|
function(err, fd) {
|
|
@@ -7821,8 +7821,8 @@ var require_polyfills = __commonJS({
|
|
|
7821
7821
|
}
|
|
7822
7822
|
);
|
|
7823
7823
|
};
|
|
7824
|
-
fs8.lchmodSync = function(
|
|
7825
|
-
var fd = fs8.openSync(
|
|
7824
|
+
fs8.lchmodSync = function(path15, mode) {
|
|
7825
|
+
var fd = fs8.openSync(path15, constants.O_WRONLY | constants.O_SYMLINK, mode);
|
|
7826
7826
|
var threw = true;
|
|
7827
7827
|
var ret;
|
|
7828
7828
|
try {
|
|
@@ -7843,8 +7843,8 @@ var require_polyfills = __commonJS({
|
|
|
7843
7843
|
}
|
|
7844
7844
|
function patchLutimes(fs8) {
|
|
7845
7845
|
if (constants.hasOwnProperty("O_SYMLINK") && fs8.futimes) {
|
|
7846
|
-
fs8.lutimes = function(
|
|
7847
|
-
fs8.open(
|
|
7846
|
+
fs8.lutimes = function(path15, at, mt, cb) {
|
|
7847
|
+
fs8.open(path15, constants.O_SYMLINK, function(er, fd) {
|
|
7848
7848
|
if (er) {
|
|
7849
7849
|
if (cb) cb(er);
|
|
7850
7850
|
return;
|
|
@@ -7856,8 +7856,8 @@ var require_polyfills = __commonJS({
|
|
|
7856
7856
|
});
|
|
7857
7857
|
});
|
|
7858
7858
|
};
|
|
7859
|
-
fs8.lutimesSync = function(
|
|
7860
|
-
var fd = fs8.openSync(
|
|
7859
|
+
fs8.lutimesSync = function(path15, at, mt) {
|
|
7860
|
+
var fd = fs8.openSync(path15, constants.O_SYMLINK);
|
|
7861
7861
|
var ret;
|
|
7862
7862
|
var threw = true;
|
|
7863
7863
|
try {
|
|
@@ -7975,11 +7975,11 @@ var require_legacy_streams = __commonJS({
|
|
|
7975
7975
|
ReadStream,
|
|
7976
7976
|
WriteStream
|
|
7977
7977
|
};
|
|
7978
|
-
function ReadStream(
|
|
7979
|
-
if (!(this instanceof ReadStream)) return new ReadStream(
|
|
7978
|
+
function ReadStream(path15, options) {
|
|
7979
|
+
if (!(this instanceof ReadStream)) return new ReadStream(path15, options);
|
|
7980
7980
|
Stream.call(this);
|
|
7981
7981
|
var self = this;
|
|
7982
|
-
this.path =
|
|
7982
|
+
this.path = path15;
|
|
7983
7983
|
this.fd = null;
|
|
7984
7984
|
this.readable = true;
|
|
7985
7985
|
this.paused = false;
|
|
@@ -8024,10 +8024,10 @@ var require_legacy_streams = __commonJS({
|
|
|
8024
8024
|
self._read();
|
|
8025
8025
|
});
|
|
8026
8026
|
}
|
|
8027
|
-
function WriteStream(
|
|
8028
|
-
if (!(this instanceof WriteStream)) return new WriteStream(
|
|
8027
|
+
function WriteStream(path15, options) {
|
|
8028
|
+
if (!(this instanceof WriteStream)) return new WriteStream(path15, options);
|
|
8029
8029
|
Stream.call(this);
|
|
8030
|
-
this.path =
|
|
8030
|
+
this.path = path15;
|
|
8031
8031
|
this.fd = null;
|
|
8032
8032
|
this.writable = true;
|
|
8033
8033
|
this.flags = "w";
|
|
@@ -8170,14 +8170,14 @@ var require_graceful_fs = __commonJS({
|
|
|
8170
8170
|
fs8.createWriteStream = createWriteStream;
|
|
8171
8171
|
var fs$readFile = fs8.readFile;
|
|
8172
8172
|
fs8.readFile = readFile2;
|
|
8173
|
-
function readFile2(
|
|
8173
|
+
function readFile2(path15, options, cb) {
|
|
8174
8174
|
if (typeof options === "function")
|
|
8175
8175
|
cb = options, options = null;
|
|
8176
|
-
return go$readFile(
|
|
8177
|
-
function go$readFile(
|
|
8178
|
-
return fs$readFile(
|
|
8176
|
+
return go$readFile(path15, options, cb);
|
|
8177
|
+
function go$readFile(path16, options2, cb2, startTime) {
|
|
8178
|
+
return fs$readFile(path16, options2, function(err) {
|
|
8179
8179
|
if (err && (err.code === "EMFILE" || err.code === "ENFILE"))
|
|
8180
|
-
enqueue([go$readFile, [
|
|
8180
|
+
enqueue([go$readFile, [path16, options2, cb2], err, startTime || Date.now(), Date.now()]);
|
|
8181
8181
|
else {
|
|
8182
8182
|
if (typeof cb2 === "function")
|
|
8183
8183
|
cb2.apply(this, arguments);
|
|
@@ -8187,14 +8187,14 @@ var require_graceful_fs = __commonJS({
|
|
|
8187
8187
|
}
|
|
8188
8188
|
var fs$writeFile = fs8.writeFile;
|
|
8189
8189
|
fs8.writeFile = writeFile;
|
|
8190
|
-
function writeFile(
|
|
8190
|
+
function writeFile(path15, data, options, cb) {
|
|
8191
8191
|
if (typeof options === "function")
|
|
8192
8192
|
cb = options, options = null;
|
|
8193
|
-
return go$writeFile(
|
|
8194
|
-
function go$writeFile(
|
|
8195
|
-
return fs$writeFile(
|
|
8193
|
+
return go$writeFile(path15, data, options, cb);
|
|
8194
|
+
function go$writeFile(path16, data2, options2, cb2, startTime) {
|
|
8195
|
+
return fs$writeFile(path16, data2, options2, function(err) {
|
|
8196
8196
|
if (err && (err.code === "EMFILE" || err.code === "ENFILE"))
|
|
8197
|
-
enqueue([go$writeFile, [
|
|
8197
|
+
enqueue([go$writeFile, [path16, data2, options2, cb2], err, startTime || Date.now(), Date.now()]);
|
|
8198
8198
|
else {
|
|
8199
8199
|
if (typeof cb2 === "function")
|
|
8200
8200
|
cb2.apply(this, arguments);
|
|
@@ -8205,14 +8205,14 @@ var require_graceful_fs = __commonJS({
|
|
|
8205
8205
|
var fs$appendFile = fs8.appendFile;
|
|
8206
8206
|
if (fs$appendFile)
|
|
8207
8207
|
fs8.appendFile = appendFile;
|
|
8208
|
-
function appendFile(
|
|
8208
|
+
function appendFile(path15, data, options, cb) {
|
|
8209
8209
|
if (typeof options === "function")
|
|
8210
8210
|
cb = options, options = null;
|
|
8211
|
-
return go$appendFile(
|
|
8212
|
-
function go$appendFile(
|
|
8213
|
-
return fs$appendFile(
|
|
8211
|
+
return go$appendFile(path15, data, options, cb);
|
|
8212
|
+
function go$appendFile(path16, data2, options2, cb2, startTime) {
|
|
8213
|
+
return fs$appendFile(path16, data2, options2, function(err) {
|
|
8214
8214
|
if (err && (err.code === "EMFILE" || err.code === "ENFILE"))
|
|
8215
|
-
enqueue([go$appendFile, [
|
|
8215
|
+
enqueue([go$appendFile, [path16, data2, options2, cb2], err, startTime || Date.now(), Date.now()]);
|
|
8216
8216
|
else {
|
|
8217
8217
|
if (typeof cb2 === "function")
|
|
8218
8218
|
cb2.apply(this, arguments);
|
|
@@ -8243,31 +8243,31 @@ var require_graceful_fs = __commonJS({
|
|
|
8243
8243
|
var fs$readdir = fs8.readdir;
|
|
8244
8244
|
fs8.readdir = readdir2;
|
|
8245
8245
|
var noReaddirOptionVersions = /^v[0-5]\./;
|
|
8246
|
-
function readdir2(
|
|
8246
|
+
function readdir2(path15, options, cb) {
|
|
8247
8247
|
if (typeof options === "function")
|
|
8248
8248
|
cb = options, options = null;
|
|
8249
|
-
var go$readdir = noReaddirOptionVersions.test(process.version) ? function go$readdir2(
|
|
8250
|
-
return fs$readdir(
|
|
8251
|
-
|
|
8249
|
+
var go$readdir = noReaddirOptionVersions.test(process.version) ? function go$readdir2(path16, options2, cb2, startTime) {
|
|
8250
|
+
return fs$readdir(path16, fs$readdirCallback(
|
|
8251
|
+
path16,
|
|
8252
8252
|
options2,
|
|
8253
8253
|
cb2,
|
|
8254
8254
|
startTime
|
|
8255
8255
|
));
|
|
8256
|
-
} : function go$readdir2(
|
|
8257
|
-
return fs$readdir(
|
|
8258
|
-
|
|
8256
|
+
} : function go$readdir2(path16, options2, cb2, startTime) {
|
|
8257
|
+
return fs$readdir(path16, options2, fs$readdirCallback(
|
|
8258
|
+
path16,
|
|
8259
8259
|
options2,
|
|
8260
8260
|
cb2,
|
|
8261
8261
|
startTime
|
|
8262
8262
|
));
|
|
8263
8263
|
};
|
|
8264
|
-
return go$readdir(
|
|
8265
|
-
function fs$readdirCallback(
|
|
8264
|
+
return go$readdir(path15, options, cb);
|
|
8265
|
+
function fs$readdirCallback(path16, options2, cb2, startTime) {
|
|
8266
8266
|
return function(err, files) {
|
|
8267
8267
|
if (err && (err.code === "EMFILE" || err.code === "ENFILE"))
|
|
8268
8268
|
enqueue([
|
|
8269
8269
|
go$readdir,
|
|
8270
|
-
[
|
|
8270
|
+
[path16, options2, cb2],
|
|
8271
8271
|
err,
|
|
8272
8272
|
startTime || Date.now(),
|
|
8273
8273
|
Date.now()
|
|
@@ -8338,7 +8338,7 @@ var require_graceful_fs = __commonJS({
|
|
|
8338
8338
|
enumerable: true,
|
|
8339
8339
|
configurable: true
|
|
8340
8340
|
});
|
|
8341
|
-
function ReadStream(
|
|
8341
|
+
function ReadStream(path15, options) {
|
|
8342
8342
|
if (this instanceof ReadStream)
|
|
8343
8343
|
return fs$ReadStream.apply(this, arguments), this;
|
|
8344
8344
|
else
|
|
@@ -8358,7 +8358,7 @@ var require_graceful_fs = __commonJS({
|
|
|
8358
8358
|
}
|
|
8359
8359
|
});
|
|
8360
8360
|
}
|
|
8361
|
-
function WriteStream(
|
|
8361
|
+
function WriteStream(path15, options) {
|
|
8362
8362
|
if (this instanceof WriteStream)
|
|
8363
8363
|
return fs$WriteStream.apply(this, arguments), this;
|
|
8364
8364
|
else
|
|
@@ -8376,22 +8376,22 @@ var require_graceful_fs = __commonJS({
|
|
|
8376
8376
|
}
|
|
8377
8377
|
});
|
|
8378
8378
|
}
|
|
8379
|
-
function createReadStream(
|
|
8380
|
-
return new fs8.ReadStream(
|
|
8379
|
+
function createReadStream(path15, options) {
|
|
8380
|
+
return new fs8.ReadStream(path15, options);
|
|
8381
8381
|
}
|
|
8382
|
-
function createWriteStream(
|
|
8383
|
-
return new fs8.WriteStream(
|
|
8382
|
+
function createWriteStream(path15, options) {
|
|
8383
|
+
return new fs8.WriteStream(path15, options);
|
|
8384
8384
|
}
|
|
8385
8385
|
var fs$open = fs8.open;
|
|
8386
8386
|
fs8.open = open;
|
|
8387
|
-
function open(
|
|
8387
|
+
function open(path15, flags, mode, cb) {
|
|
8388
8388
|
if (typeof mode === "function")
|
|
8389
8389
|
cb = mode, mode = null;
|
|
8390
|
-
return go$open(
|
|
8391
|
-
function go$open(
|
|
8392
|
-
return fs$open(
|
|
8390
|
+
return go$open(path15, flags, mode, cb);
|
|
8391
|
+
function go$open(path16, flags2, mode2, cb2, startTime) {
|
|
8392
|
+
return fs$open(path16, flags2, mode2, function(err, fd) {
|
|
8393
8393
|
if (err && (err.code === "EMFILE" || err.code === "ENFILE"))
|
|
8394
|
-
enqueue([go$open, [
|
|
8394
|
+
enqueue([go$open, [path16, flags2, mode2, cb2], err, startTime || Date.now(), Date.now()]);
|
|
8395
8395
|
else {
|
|
8396
8396
|
if (typeof cb2 === "function")
|
|
8397
8397
|
cb2.apply(this, arguments);
|
|
@@ -8920,7 +8920,7 @@ var require_mtime_precision = __commonJS({
|
|
|
8920
8920
|
var require_lockfile = __commonJS({
|
|
8921
8921
|
"../../node_modules/.pnpm/proper-lockfile@4.1.2/node_modules/proper-lockfile/lib/lockfile.js"(exports2, module2) {
|
|
8922
8922
|
"use strict";
|
|
8923
|
-
var
|
|
8923
|
+
var path15 = require("path");
|
|
8924
8924
|
var fs7 = require_graceful_fs();
|
|
8925
8925
|
var retry = require_retry2();
|
|
8926
8926
|
var onExit = require_signal_exit();
|
|
@@ -8931,7 +8931,7 @@ var require_lockfile = __commonJS({
|
|
|
8931
8931
|
}
|
|
8932
8932
|
function resolveCanonicalPath(file2, options, callback) {
|
|
8933
8933
|
if (!options.realpath) {
|
|
8934
|
-
return callback(null,
|
|
8934
|
+
return callback(null, path15.resolve(file2));
|
|
8935
8935
|
}
|
|
8936
8936
|
options.fs.realpath(file2, callback);
|
|
8937
8937
|
}
|
|
@@ -10795,10 +10795,10 @@ var require_segments = __commonJS({
|
|
|
10795
10795
|
const segs = getSegmentsFromString(data, Utils.isKanjiModeEnabled());
|
|
10796
10796
|
const nodes = buildNodes(segs);
|
|
10797
10797
|
const graph = buildGraph(nodes, version2);
|
|
10798
|
-
const
|
|
10798
|
+
const path15 = dijkstra.find_path(graph.map, "start", "end");
|
|
10799
10799
|
const optimizedSegs = [];
|
|
10800
|
-
for (let i = 1; i <
|
|
10801
|
-
optimizedSegs.push(graph.table[
|
|
10800
|
+
for (let i = 1; i < path15.length - 1; i++) {
|
|
10801
|
+
optimizedSegs.push(graph.table[path15[i]].node);
|
|
10802
10802
|
}
|
|
10803
10803
|
return exports2.fromArray(mergeSegments(optimizedSegs));
|
|
10804
10804
|
};
|
|
@@ -13275,7 +13275,7 @@ var require_png2 = __commonJS({
|
|
|
13275
13275
|
});
|
|
13276
13276
|
png.pack();
|
|
13277
13277
|
};
|
|
13278
|
-
exports2.renderToFile = function renderToFile(
|
|
13278
|
+
exports2.renderToFile = function renderToFile(path15, qrData, options, cb) {
|
|
13279
13279
|
if (typeof cb === "undefined") {
|
|
13280
13280
|
cb = options;
|
|
13281
13281
|
options = void 0;
|
|
@@ -13286,7 +13286,7 @@ var require_png2 = __commonJS({
|
|
|
13286
13286
|
called = true;
|
|
13287
13287
|
cb.apply(null, args);
|
|
13288
13288
|
};
|
|
13289
|
-
const stream = fs7.createWriteStream(
|
|
13289
|
+
const stream = fs7.createWriteStream(path15);
|
|
13290
13290
|
stream.on("error", done);
|
|
13291
13291
|
stream.on("close", done);
|
|
13292
13292
|
exports2.renderToFileStream(stream, qrData, options);
|
|
@@ -13348,14 +13348,14 @@ var require_utf8 = __commonJS({
|
|
|
13348
13348
|
}
|
|
13349
13349
|
return output3;
|
|
13350
13350
|
};
|
|
13351
|
-
exports2.renderToFile = function renderToFile(
|
|
13351
|
+
exports2.renderToFile = function renderToFile(path15, qrData, options, cb) {
|
|
13352
13352
|
if (typeof cb === "undefined") {
|
|
13353
13353
|
cb = options;
|
|
13354
13354
|
options = void 0;
|
|
13355
13355
|
}
|
|
13356
13356
|
const fs7 = require("fs");
|
|
13357
13357
|
const utf8 = exports2.render(qrData, options);
|
|
13358
|
-
fs7.writeFile(
|
|
13358
|
+
fs7.writeFile(path15, utf8, cb);
|
|
13359
13359
|
};
|
|
13360
13360
|
}
|
|
13361
13361
|
});
|
|
@@ -13476,7 +13476,7 @@ var require_svg_tag = __commonJS({
|
|
|
13476
13476
|
return str;
|
|
13477
13477
|
}
|
|
13478
13478
|
function qrToPath(data, size, margin) {
|
|
13479
|
-
let
|
|
13479
|
+
let path15 = "";
|
|
13480
13480
|
let moveBy = 0;
|
|
13481
13481
|
let newRow = false;
|
|
13482
13482
|
let lineLength = 0;
|
|
@@ -13487,19 +13487,19 @@ var require_svg_tag = __commonJS({
|
|
|
13487
13487
|
if (data[i]) {
|
|
13488
13488
|
lineLength++;
|
|
13489
13489
|
if (!(i > 0 && col > 0 && data[i - 1])) {
|
|
13490
|
-
|
|
13490
|
+
path15 += newRow ? svgCmd("M", col + margin, 0.5 + row + margin) : svgCmd("m", moveBy, 0);
|
|
13491
13491
|
moveBy = 0;
|
|
13492
13492
|
newRow = false;
|
|
13493
13493
|
}
|
|
13494
13494
|
if (!(col + 1 < size && data[i + 1])) {
|
|
13495
|
-
|
|
13495
|
+
path15 += svgCmd("h", lineLength);
|
|
13496
13496
|
lineLength = 0;
|
|
13497
13497
|
}
|
|
13498
13498
|
} else {
|
|
13499
13499
|
moveBy++;
|
|
13500
13500
|
}
|
|
13501
13501
|
}
|
|
13502
|
-
return
|
|
13502
|
+
return path15;
|
|
13503
13503
|
}
|
|
13504
13504
|
exports2.render = function render(qrData, options, cb) {
|
|
13505
13505
|
const opts = Utils.getOptions(options);
|
|
@@ -13507,10 +13507,10 @@ var require_svg_tag = __commonJS({
|
|
|
13507
13507
|
const data = qrData.modules.data;
|
|
13508
13508
|
const qrcodesize = size + opts.margin * 2;
|
|
13509
13509
|
const bg = !opts.color.light.a ? "" : "<path " + getColorAttrib(opts.color.light, "fill") + ' d="M0 0h' + qrcodesize + "v" + qrcodesize + 'H0z"/>';
|
|
13510
|
-
const
|
|
13510
|
+
const path15 = "<path " + getColorAttrib(opts.color.dark, "stroke") + ' d="' + qrToPath(data, size, opts.margin) + '"/>';
|
|
13511
13511
|
const viewBox = 'viewBox="0 0 ' + qrcodesize + " " + qrcodesize + '"';
|
|
13512
13512
|
const width = !opts.width ? "" : 'width="' + opts.width + '" height="' + opts.width + '" ';
|
|
13513
|
-
const svgTag = '<svg xmlns="http://www.w3.org/2000/svg" ' + width + viewBox + ' shape-rendering="crispEdges">' + bg +
|
|
13513
|
+
const svgTag = '<svg xmlns="http://www.w3.org/2000/svg" ' + width + viewBox + ' shape-rendering="crispEdges">' + bg + path15 + "</svg>\n";
|
|
13514
13514
|
if (typeof cb === "function") {
|
|
13515
13515
|
cb(null, svgTag);
|
|
13516
13516
|
}
|
|
@@ -13524,7 +13524,7 @@ var require_svg = __commonJS({
|
|
|
13524
13524
|
"../../node_modules/.pnpm/qrcode@1.5.4/node_modules/qrcode/lib/renderer/svg.js"(exports2) {
|
|
13525
13525
|
var svgTagRenderer = require_svg_tag();
|
|
13526
13526
|
exports2.render = svgTagRenderer.render;
|
|
13527
|
-
exports2.renderToFile = function renderToFile(
|
|
13527
|
+
exports2.renderToFile = function renderToFile(path15, qrData, options, cb) {
|
|
13528
13528
|
if (typeof cb === "undefined") {
|
|
13529
13529
|
cb = options;
|
|
13530
13530
|
options = void 0;
|
|
@@ -13532,7 +13532,7 @@ var require_svg = __commonJS({
|
|
|
13532
13532
|
const fs7 = require("fs");
|
|
13533
13533
|
const svgTag = exports2.render(qrData, options);
|
|
13534
13534
|
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;
|
|
13535
|
-
fs7.writeFile(
|
|
13535
|
+
fs7.writeFile(path15, xmlStr, cb);
|
|
13536
13536
|
};
|
|
13537
13537
|
}
|
|
13538
13538
|
});
|
|
@@ -13690,8 +13690,8 @@ var require_server = __commonJS({
|
|
|
13690
13690
|
cb
|
|
13691
13691
|
};
|
|
13692
13692
|
}
|
|
13693
|
-
function getTypeFromFilename(
|
|
13694
|
-
return
|
|
13693
|
+
function getTypeFromFilename(path15) {
|
|
13694
|
+
return path15.slice((path15.lastIndexOf(".") - 1 >>> 0) + 2).toLowerCase();
|
|
13695
13695
|
}
|
|
13696
13696
|
function getRendererFromType(type) {
|
|
13697
13697
|
switch (type) {
|
|
@@ -13755,17 +13755,17 @@ var require_server = __commonJS({
|
|
|
13755
13755
|
const renderer = getRendererFromType(params.opts.type);
|
|
13756
13756
|
return render(renderer.renderToBuffer, text, params);
|
|
13757
13757
|
};
|
|
13758
|
-
exports2.toFile = function toFile(
|
|
13759
|
-
if (typeof
|
|
13758
|
+
exports2.toFile = function toFile(path15, text, opts, cb) {
|
|
13759
|
+
if (typeof path15 !== "string" || !(typeof text === "string" || typeof text === "object")) {
|
|
13760
13760
|
throw new Error("Invalid argument");
|
|
13761
13761
|
}
|
|
13762
13762
|
if (arguments.length < 3 && !canPromise()) {
|
|
13763
13763
|
throw new Error("Too few arguments provided");
|
|
13764
13764
|
}
|
|
13765
13765
|
const params = checkParams(text, opts, cb);
|
|
13766
|
-
const type = params.opts.type || getTypeFromFilename(
|
|
13766
|
+
const type = params.opts.type || getTypeFromFilename(path15);
|
|
13767
13767
|
const renderer = getRendererFromType(type);
|
|
13768
|
-
const renderToFile = renderer.renderToFile.bind(null,
|
|
13768
|
+
const renderToFile = renderer.renderToFile.bind(null, path15);
|
|
13769
13769
|
return render(renderToFile, text, params);
|
|
13770
13770
|
};
|
|
13771
13771
|
exports2.toFileStream = function toFileStream(stream, text, opts) {
|
|
@@ -16983,8 +16983,8 @@ var require_utils3 = __commonJS({
|
|
|
16983
16983
|
}
|
|
16984
16984
|
return ind;
|
|
16985
16985
|
}
|
|
16986
|
-
function removeDotSegments(
|
|
16987
|
-
let input =
|
|
16986
|
+
function removeDotSegments(path15) {
|
|
16987
|
+
let input = path15;
|
|
16988
16988
|
const output3 = [];
|
|
16989
16989
|
let nextSlash = -1;
|
|
16990
16990
|
let len = 0;
|
|
@@ -17236,8 +17236,8 @@ var require_schemes = __commonJS({
|
|
|
17236
17236
|
wsComponent.secure = void 0;
|
|
17237
17237
|
}
|
|
17238
17238
|
if (wsComponent.resourceName) {
|
|
17239
|
-
const [
|
|
17240
|
-
wsComponent.path =
|
|
17239
|
+
const [path15, query] = wsComponent.resourceName.split("?");
|
|
17240
|
+
wsComponent.path = path15 && path15 !== "/" ? path15 : void 0;
|
|
17241
17241
|
wsComponent.query = query;
|
|
17242
17242
|
wsComponent.resourceName = void 0;
|
|
17243
17243
|
}
|
|
@@ -20644,11 +20644,11 @@ var require_dist = __commonJS({
|
|
|
20644
20644
|
});
|
|
20645
20645
|
|
|
20646
20646
|
// src/bin.ts
|
|
20647
|
+
var import_node_path20 = __toESM(require("node:path"), 1);
|
|
20648
|
+
var import_node_child_process8 = require("node:child_process");
|
|
20649
|
+
var import_node_fs15 = require("node:fs");
|
|
20650
|
+
var import_node_os12 = require("node:os");
|
|
20647
20651
|
var import_node_path21 = __toESM(require("node:path"), 1);
|
|
20648
|
-
var import_node_child_process9 = require("node:child_process");
|
|
20649
|
-
var import_node_fs16 = require("node:fs");
|
|
20650
|
-
var import_node_os13 = require("node:os");
|
|
20651
|
-
var import_node_path22 = __toESM(require("node:path"), 1);
|
|
20652
20652
|
|
|
20653
20653
|
// src/install-codex.ts
|
|
20654
20654
|
var import_promises = __toESM(require("node:fs/promises"), 1);
|
|
@@ -20724,14 +20724,28 @@ async function installBrowser(opts = {}) {
|
|
|
20724
20724
|
}
|
|
20725
20725
|
|
|
20726
20726
|
// src/install-codex.ts
|
|
20727
|
+
function deriveServeEnvFromProcessEnv(env) {
|
|
20728
|
+
const out = {};
|
|
20729
|
+
const apiUrl = env.MRRLIN_API_BASE_URL?.trim();
|
|
20730
|
+
if (apiUrl) {
|
|
20731
|
+
out.MRRLIN_API_BASE_URL = apiUrl;
|
|
20732
|
+
if (env.MRRLIN_API_ALLOW_REMOTE === "1") out.MRRLIN_API_ALLOW_REMOTE = "1";
|
|
20733
|
+
} else if (env.MRRLIN_STAGING === "1") {
|
|
20734
|
+
out.MRRLIN_STAGING = "1";
|
|
20735
|
+
}
|
|
20736
|
+
return Object.keys(out).length > 0 ? out : void 0;
|
|
20737
|
+
}
|
|
20727
20738
|
function resolveCodexHome(options) {
|
|
20728
20739
|
if (options.codexHome) return options.codexHome;
|
|
20729
20740
|
if (process.env.CODEX_HOME) return process.env.CODEX_HOME;
|
|
20730
20741
|
return import_node_path2.default.join(options.homeDir ?? import_node_os2.default.homedir(), ".codex");
|
|
20731
20742
|
}
|
|
20732
|
-
function mrrlinTable(binPath, distribution) {
|
|
20733
|
-
|
|
20734
|
-
|
|
20743
|
+
function mrrlinTable(binPath, distribution, serveEnv) {
|
|
20744
|
+
const base = distribution === "npm" ? { command: "mrrlin-mcp", args: ["serve"] } : { command: "node", args: [binPath, "serve"] };
|
|
20745
|
+
if (serveEnv && Object.keys(serveEnv).length > 0) {
|
|
20746
|
+
return { ...base, startup_timeout_sec: 30, env: serveEnv };
|
|
20747
|
+
}
|
|
20748
|
+
return { ...base, startup_timeout_sec: 30 };
|
|
20735
20749
|
}
|
|
20736
20750
|
function browserTable(binPath, distribution, homeDir) {
|
|
20737
20751
|
const base = distribution === "npm" ? { command: "mrrlin-mcp", args: ["browser-serve"] } : { command: "node", args: [binPath, "browser-serve"] };
|
|
@@ -20744,7 +20758,11 @@ function blockRegex(id) {
|
|
|
20744
20758
|
function managedBlocks(options, distribution) {
|
|
20745
20759
|
const homeDir = options.homeDir ?? import_node_os2.default.homedir();
|
|
20746
20760
|
return [
|
|
20747
|
-
{
|
|
20761
|
+
{
|
|
20762
|
+
id: "mrrlin",
|
|
20763
|
+
expected: mrrlinTable(options.binPath, distribution, options.serveEnv),
|
|
20764
|
+
blockRe: blockRegex("mrrlin")
|
|
20765
|
+
},
|
|
20748
20766
|
{
|
|
20749
20767
|
id: "mrrlin-browser",
|
|
20750
20768
|
expected: browserTable(options.binPath, distribution, homeDir),
|
|
@@ -20915,11 +20933,11 @@ ${block}`;
|
|
|
20915
20933
|
}
|
|
20916
20934
|
|
|
20917
20935
|
// src/director-bridge.ts
|
|
20918
|
-
var
|
|
20936
|
+
var import_node_fs11 = __toESM(require("node:fs"), 1);
|
|
20919
20937
|
var import_node_http = __toESM(require("node:http"), 1);
|
|
20920
|
-
var
|
|
20921
|
-
var
|
|
20922
|
-
var
|
|
20938
|
+
var import_node_os8 = __toESM(require("node:os"), 1);
|
|
20939
|
+
var import_node_path12 = __toESM(require("node:path"), 1);
|
|
20940
|
+
var import_node_child_process4 = require("node:child_process");
|
|
20923
20941
|
var import_node_crypto5 = __toESM(require("node:crypto"), 1);
|
|
20924
20942
|
|
|
20925
20943
|
// src/turn-replay-buffer.ts
|
|
@@ -22421,10 +22439,10 @@ function mergeDefs(...defs) {
|
|
|
22421
22439
|
function cloneDef(schema) {
|
|
22422
22440
|
return mergeDefs(schema._zod.def);
|
|
22423
22441
|
}
|
|
22424
|
-
function getElementAtPath(obj,
|
|
22425
|
-
if (!
|
|
22442
|
+
function getElementAtPath(obj, path15) {
|
|
22443
|
+
if (!path15)
|
|
22426
22444
|
return obj;
|
|
22427
|
-
return
|
|
22445
|
+
return path15.reduce((acc, key) => acc?.[key], obj);
|
|
22428
22446
|
}
|
|
22429
22447
|
function promiseAllObject(promisesObj) {
|
|
22430
22448
|
const keys = Object.keys(promisesObj);
|
|
@@ -22833,11 +22851,11 @@ function explicitlyAborted(x, startIndex = 0) {
|
|
|
22833
22851
|
}
|
|
22834
22852
|
return false;
|
|
22835
22853
|
}
|
|
22836
|
-
function prefixIssues(
|
|
22854
|
+
function prefixIssues(path15, issues) {
|
|
22837
22855
|
return issues.map((iss) => {
|
|
22838
22856
|
var _a3;
|
|
22839
22857
|
(_a3 = iss).path ?? (_a3.path = []);
|
|
22840
|
-
iss.path.unshift(
|
|
22858
|
+
iss.path.unshift(path15);
|
|
22841
22859
|
return iss;
|
|
22842
22860
|
});
|
|
22843
22861
|
}
|
|
@@ -22984,16 +23002,16 @@ function flattenError(error51, mapper = (issue2) => issue2.message) {
|
|
|
22984
23002
|
}
|
|
22985
23003
|
function formatError(error51, mapper = (issue2) => issue2.message) {
|
|
22986
23004
|
const fieldErrors = { _errors: [] };
|
|
22987
|
-
const processError = (error52,
|
|
23005
|
+
const processError = (error52, path15 = []) => {
|
|
22988
23006
|
for (const issue2 of error52.issues) {
|
|
22989
23007
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
22990
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
23008
|
+
issue2.errors.map((issues) => processError({ issues }, [...path15, ...issue2.path]));
|
|
22991
23009
|
} else if (issue2.code === "invalid_key") {
|
|
22992
|
-
processError({ issues: issue2.issues }, [...
|
|
23010
|
+
processError({ issues: issue2.issues }, [...path15, ...issue2.path]);
|
|
22993
23011
|
} else if (issue2.code === "invalid_element") {
|
|
22994
|
-
processError({ issues: issue2.issues }, [...
|
|
23012
|
+
processError({ issues: issue2.issues }, [...path15, ...issue2.path]);
|
|
22995
23013
|
} else {
|
|
22996
|
-
const fullpath = [...
|
|
23014
|
+
const fullpath = [...path15, ...issue2.path];
|
|
22997
23015
|
if (fullpath.length === 0) {
|
|
22998
23016
|
fieldErrors._errors.push(mapper(issue2));
|
|
22999
23017
|
} else {
|
|
@@ -23020,17 +23038,17 @@ function formatError(error51, mapper = (issue2) => issue2.message) {
|
|
|
23020
23038
|
}
|
|
23021
23039
|
function treeifyError(error51, mapper = (issue2) => issue2.message) {
|
|
23022
23040
|
const result = { errors: [] };
|
|
23023
|
-
const processError = (error52,
|
|
23041
|
+
const processError = (error52, path15 = []) => {
|
|
23024
23042
|
var _a3, _b;
|
|
23025
23043
|
for (const issue2 of error52.issues) {
|
|
23026
23044
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
23027
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
23045
|
+
issue2.errors.map((issues) => processError({ issues }, [...path15, ...issue2.path]));
|
|
23028
23046
|
} else if (issue2.code === "invalid_key") {
|
|
23029
|
-
processError({ issues: issue2.issues }, [...
|
|
23047
|
+
processError({ issues: issue2.issues }, [...path15, ...issue2.path]);
|
|
23030
23048
|
} else if (issue2.code === "invalid_element") {
|
|
23031
|
-
processError({ issues: issue2.issues }, [...
|
|
23049
|
+
processError({ issues: issue2.issues }, [...path15, ...issue2.path]);
|
|
23032
23050
|
} else {
|
|
23033
|
-
const fullpath = [...
|
|
23051
|
+
const fullpath = [...path15, ...issue2.path];
|
|
23034
23052
|
if (fullpath.length === 0) {
|
|
23035
23053
|
result.errors.push(mapper(issue2));
|
|
23036
23054
|
continue;
|
|
@@ -23062,8 +23080,8 @@ function treeifyError(error51, mapper = (issue2) => issue2.message) {
|
|
|
23062
23080
|
}
|
|
23063
23081
|
function toDotPath(_path) {
|
|
23064
23082
|
const segs = [];
|
|
23065
|
-
const
|
|
23066
|
-
for (const seg of
|
|
23083
|
+
const path15 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
|
|
23084
|
+
for (const seg of path15) {
|
|
23067
23085
|
if (typeof seg === "number")
|
|
23068
23086
|
segs.push(`[${seg}]`);
|
|
23069
23087
|
else if (typeof seg === "symbol")
|
|
@@ -35755,13 +35773,13 @@ function resolveRef(ref, ctx) {
|
|
|
35755
35773
|
if (!ref.startsWith("#")) {
|
|
35756
35774
|
throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
|
|
35757
35775
|
}
|
|
35758
|
-
const
|
|
35759
|
-
if (
|
|
35776
|
+
const path15 = ref.slice(1).split("/").filter(Boolean);
|
|
35777
|
+
if (path15.length === 0) {
|
|
35760
35778
|
return ctx.rootSchema;
|
|
35761
35779
|
}
|
|
35762
35780
|
const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
|
|
35763
|
-
if (
|
|
35764
|
-
const key =
|
|
35781
|
+
if (path15[0] === defsKey) {
|
|
35782
|
+
const key = path15[1];
|
|
35765
35783
|
if (!key || !ctx.defs[key]) {
|
|
35766
35784
|
throw new Error(`Reference not found: ${ref}`);
|
|
35767
35785
|
}
|
|
@@ -36264,7 +36282,8 @@ var openApiOperationIds = {
|
|
|
36264
36282
|
updateWikiPageCas: "updateWikiPageCas",
|
|
36265
36283
|
promoteSpecReadyCas: "promoteSpecReadyCas",
|
|
36266
36284
|
recordSpecConsensusReview: "recordSpecConsensusReview",
|
|
36267
|
-
getSpecConsensusReview: "getSpecConsensusReview"
|
|
36285
|
+
getSpecConsensusReview: "getSpecConsensusReview",
|
|
36286
|
+
onboardingKickoffTransition: "onboardingKickoffTransition"
|
|
36268
36287
|
};
|
|
36269
36288
|
|
|
36270
36289
|
// ../../packages/schemas/dist/session.js
|
|
@@ -36459,6 +36478,7 @@ var mrrlinExecutionArtifactKindSchema = external_exports.enum([
|
|
|
36459
36478
|
"handoff_judgement",
|
|
36460
36479
|
"file",
|
|
36461
36480
|
"verification",
|
|
36481
|
+
"produced_url",
|
|
36462
36482
|
"resume_spec"
|
|
36463
36483
|
]);
|
|
36464
36484
|
var mrrlinDeployAttemptPayloadSchema = external_exports.object({
|
|
@@ -36474,6 +36494,11 @@ var mrrlinVerificationPayloadSchema = external_exports.object({
|
|
|
36474
36494
|
checks: external_exports.array(external_exports.unknown()).optional(),
|
|
36475
36495
|
turnRef: external_exports.string().nullable()
|
|
36476
36496
|
});
|
|
36497
|
+
var producedUrlSafeString = external_exports.string().regex(/^[^\x00-\x1F\x7F]+$/, "control chars are not allowed");
|
|
36498
|
+
var mrrlinProducedUrlPayloadSchema = external_exports.object({
|
|
36499
|
+
url: producedUrlSafeString.min(1).max(2048).refine((v) => v.startsWith("/") || /^https?:\/\//.test(v), "must be an absolute http(s) URL or a path starting with /"),
|
|
36500
|
+
label: producedUrlSafeString.min(1).max(40).optional()
|
|
36501
|
+
});
|
|
36477
36502
|
var taxonomyCategorySchema = external_exports.string().min(1).regex(/^[a-z][a-z0-9-]*$/);
|
|
36478
36503
|
var taxonomySubcategorySchema = external_exports.string().min(1).regex(/^[a-z][a-z0-9-]*$/);
|
|
36479
36504
|
var mrrlinTaskAssigneeSchema = external_exports.union([external_exports.string().regex(/^@/), external_exports.string().email()]).nullable();
|
|
@@ -36596,14 +36621,28 @@ var mrrlinProjectSummarySchema = external_exports.object({
|
|
|
36596
36621
|
displayName: external_exports.string().min(1),
|
|
36597
36622
|
emoji: mrrlinProjectEmojiSchema,
|
|
36598
36623
|
github: mrrlinGithubBindingSchema,
|
|
36624
|
+
onboardingKickoffState: external_exports.enum(["pending", "sent"]).nullable().optional(),
|
|
36599
36625
|
slug: mrrlinProjectSlugSchema
|
|
36600
36626
|
});
|
|
36601
36627
|
var mrrlinProjectUpsertSchema = mrrlinProjectSummarySchema.omit({
|
|
36628
|
+
onboardingKickoffState: true,
|
|
36602
36629
|
slug: true
|
|
36603
36630
|
});
|
|
36604
36631
|
var mrrlinProjectRenameSchema = external_exports.object({
|
|
36605
36632
|
displayName: external_exports.string().trim().min(1).max(120)
|
|
36606
36633
|
});
|
|
36634
|
+
var ONBOARDING_KICKOFF_TRANSITIONS = [
|
|
36635
|
+
{ from: null, to: "pending" },
|
|
36636
|
+
{ from: "pending", to: "sent" },
|
|
36637
|
+
{ from: "sent", to: "pending" }
|
|
36638
|
+
];
|
|
36639
|
+
var mrrlinOnboardingKickoffTransitionSchema = external_exports.object({
|
|
36640
|
+
from: external_exports.enum(["pending", "sent"]).nullable(),
|
|
36641
|
+
to: external_exports.enum(["pending", "sent"])
|
|
36642
|
+
}).refine((value) => ONBOARDING_KICKOFF_TRANSITIONS.some((t) => t.from === value.from && t.to === value.to), { message: "Unsupported onboarding kickoff transition" });
|
|
36643
|
+
var mrrlinOnboardingKickoffTransitionResponseSchema = external_exports.object({
|
|
36644
|
+
data: external_exports.object({ applied: external_exports.boolean() })
|
|
36645
|
+
});
|
|
36607
36646
|
var mrrlinProjectMemberSchema = external_exports.object({
|
|
36608
36647
|
email: external_exports.string().email(),
|
|
36609
36648
|
githubLogin: external_exports.string().nullable(),
|
|
@@ -37430,18 +37469,18 @@ function createMrrlinClient(config2) {
|
|
|
37430
37469
|
const customFetch = config2.fetch ?? globalThis.fetch;
|
|
37431
37470
|
const baseUrl = config2.baseUrl.replace(/\/$/, "");
|
|
37432
37471
|
const token = config2.token;
|
|
37433
|
-
async function request(
|
|
37472
|
+
async function request(path15, init) {
|
|
37434
37473
|
const method = init?.method ?? "GET";
|
|
37435
37474
|
const headers = new Headers(init?.headers ?? {});
|
|
37436
37475
|
if (token && !headers.has("authorization")) {
|
|
37437
37476
|
headers.set("authorization", `Bearer ${token}`);
|
|
37438
37477
|
}
|
|
37439
|
-
const response = await customFetch(`${baseUrl}${
|
|
37478
|
+
const response = await customFetch(`${baseUrl}${path15}`, { ...init, headers });
|
|
37440
37479
|
if (!response.ok) {
|
|
37441
37480
|
const body = await response.text();
|
|
37442
37481
|
let code = `HTTP_${response.status}`;
|
|
37443
37482
|
let violations = null;
|
|
37444
|
-
let message = `Mrrlin API ${method} ${
|
|
37483
|
+
let message = `Mrrlin API ${method} ${path15} failed: ${response.status}`;
|
|
37445
37484
|
try {
|
|
37446
37485
|
const parsed = JSON.parse(body);
|
|
37447
37486
|
const violationsParsed = apiViolationsErrorSchema.safeParse(parsed);
|
|
@@ -37461,7 +37500,7 @@ function createMrrlinClient(config2) {
|
|
|
37461
37500
|
throw new MrrlinApiError({
|
|
37462
37501
|
code,
|
|
37463
37502
|
method,
|
|
37464
|
-
path:
|
|
37503
|
+
path: path15,
|
|
37465
37504
|
responseBody: body,
|
|
37466
37505
|
status: response.status,
|
|
37467
37506
|
violations,
|
|
@@ -37549,6 +37588,14 @@ function createMrrlinClient(config2) {
|
|
|
37549
37588
|
});
|
|
37550
37589
|
return projectSummaryResponseSchema.parse(body).data;
|
|
37551
37590
|
},
|
|
37591
|
+
async transitionOnboardingKickoff(projectSlug, input) {
|
|
37592
|
+
const body = await request(`${projectPath(projectSlug)}/onboarding-kickoff`, {
|
|
37593
|
+
body: JSON.stringify(mrrlinOnboardingKickoffTransitionSchema.parse(input)),
|
|
37594
|
+
headers: { "content-type": "application/json" },
|
|
37595
|
+
method: "PATCH"
|
|
37596
|
+
});
|
|
37597
|
+
return mrrlinOnboardingKickoffTransitionResponseSchema.parse(body).data.applied;
|
|
37598
|
+
},
|
|
37552
37599
|
async createTaskDependency(projectSlug, input) {
|
|
37553
37600
|
const body = await request(`${projectPath(projectSlug)}/task-dependencies`, {
|
|
37554
37601
|
body: JSON.stringify(input),
|
|
@@ -37708,7 +37755,7 @@ function createMrrlinClient(config2) {
|
|
|
37708
37755
|
return taskEventListResponseSchema.parse(body).data;
|
|
37709
37756
|
},
|
|
37710
37757
|
async listTasks(projectSlug, filters = {}) {
|
|
37711
|
-
const
|
|
37758
|
+
const path15 = appendQuery(`${projectPath(projectSlug)}/tasks`, {
|
|
37712
37759
|
assignee: filters.assignee,
|
|
37713
37760
|
autonomyLevel: filters.autonomyLevel,
|
|
37714
37761
|
blockedBy: filters.blockedBy,
|
|
@@ -37720,7 +37767,7 @@ function createMrrlinClient(config2) {
|
|
|
37720
37767
|
subcategory: filters.subcategory,
|
|
37721
37768
|
type: filters.type
|
|
37722
37769
|
});
|
|
37723
|
-
const body = await request(
|
|
37770
|
+
const body = await request(path15);
|
|
37724
37771
|
return taskListResponseSchema.parse(body).data;
|
|
37725
37772
|
},
|
|
37726
37773
|
async listTaxonomy(projectSlug) {
|
|
@@ -37728,22 +37775,22 @@ function createMrrlinClient(config2) {
|
|
|
37728
37775
|
return taxonomyListResponseSchema.parse(body).data;
|
|
37729
37776
|
},
|
|
37730
37777
|
async listWikiPages(projectSlug, filters = {}) {
|
|
37731
|
-
const
|
|
37778
|
+
const path15 = appendQuery(`${projectPath(projectSlug)}/wiki`, {
|
|
37732
37779
|
folder: filters.folder,
|
|
37733
37780
|
q: filters.q,
|
|
37734
37781
|
taskId: filters.taskId
|
|
37735
37782
|
});
|
|
37736
|
-
const body = await request(
|
|
37783
|
+
const body = await request(path15);
|
|
37737
37784
|
return wikiPageListResponseSchema.parse(body).data;
|
|
37738
37785
|
},
|
|
37739
37786
|
async searchWikiPages(projectSlug, query) {
|
|
37740
|
-
const
|
|
37787
|
+
const path15 = appendQuery(`${projectPath(projectSlug)}/wiki/search`, {
|
|
37741
37788
|
folder: query.folder,
|
|
37742
37789
|
limit: query.limit === void 0 ? void 0 : String(query.limit),
|
|
37743
37790
|
pathPrefix: query.pathPrefix,
|
|
37744
37791
|
q: query.q
|
|
37745
37792
|
});
|
|
37746
|
-
const body = await request(
|
|
37793
|
+
const body = await request(path15);
|
|
37747
37794
|
return wikiPageSearchResponseSchema.parse(body).data;
|
|
37748
37795
|
},
|
|
37749
37796
|
async updatePlan(projectSlug, planId, patch) {
|
|
@@ -38460,7 +38507,7 @@ Do NOT derail the current task \u2014 if the operator has an in-flight question,
|
|
|
38460
38507
|
}
|
|
38461
38508
|
|
|
38462
38509
|
// src/_generated/version.ts
|
|
38463
|
-
var PKG_VERSION = "0.3.
|
|
38510
|
+
var PKG_VERSION = "0.3.8";
|
|
38464
38511
|
|
|
38465
38512
|
// src/api-base-url.ts
|
|
38466
38513
|
var DEFAULT_API_BASE_URL = "http://127.0.0.1:8787";
|
|
@@ -38844,6 +38891,41 @@ async function sweepOrphanWorktrees(opts) {
|
|
|
38844
38891
|
return reaped;
|
|
38845
38892
|
}
|
|
38846
38893
|
|
|
38894
|
+
// src/pr-body.ts
|
|
38895
|
+
function isSafeAbsoluteUrl(url2) {
|
|
38896
|
+
try {
|
|
38897
|
+
const protocol = new URL(url2).protocol;
|
|
38898
|
+
return protocol === "http:" || protocol === "https:";
|
|
38899
|
+
} catch {
|
|
38900
|
+
return false;
|
|
38901
|
+
}
|
|
38902
|
+
}
|
|
38903
|
+
function escapeMarkdown(text) {
|
|
38904
|
+
return text.replace(/([\\`[\]])/g, "\\$1");
|
|
38905
|
+
}
|
|
38906
|
+
function buildPullRequestBody(input) {
|
|
38907
|
+
const plain = `Automated change for run \`${input.runId}\` (task ${input.taskId}).`;
|
|
38908
|
+
const seen = /* @__PURE__ */ new Set();
|
|
38909
|
+
const lines2 = [];
|
|
38910
|
+
for (const { url: url2, label } of input.producedUrls) {
|
|
38911
|
+
if (seen.has(url2)) continue;
|
|
38912
|
+
seen.add(url2);
|
|
38913
|
+
if (url2.startsWith("/")) {
|
|
38914
|
+
const note = label ? `${escapeMarkdown(label)} \u2014 ` : "";
|
|
38915
|
+
lines2.push(`- ${note}\`${escapeMarkdown(url2)}\` (deploy-relative)`);
|
|
38916
|
+
continue;
|
|
38917
|
+
}
|
|
38918
|
+
if (!isSafeAbsoluteUrl(url2)) continue;
|
|
38919
|
+
const text = escapeMarkdown(label ?? "Page");
|
|
38920
|
+
lines2.push(`- [${text}](${url2})`);
|
|
38921
|
+
}
|
|
38922
|
+
if (lines2.length === 0) return plain;
|
|
38923
|
+
return `${plain}
|
|
38924
|
+
|
|
38925
|
+
## Produced pages
|
|
38926
|
+
${lines2.join("\n")}`;
|
|
38927
|
+
}
|
|
38928
|
+
|
|
38847
38929
|
// src/execution-consumer.ts
|
|
38848
38930
|
var DEFAULT_STALE_SECONDS = 300;
|
|
38849
38931
|
var DEFAULT_TOUCH_INTERVAL_MS = 6e4;
|
|
@@ -38886,6 +38968,16 @@ var BASE_INSTRUCTIONS_PREFIX = [
|
|
|
38886
38968
|
" or evidence page will reference (180 days). Always pass taskId/runId when known.",
|
|
38887
38969
|
"- Anything user-facing delivered as a file MUST be uploaded. Files are capped at 5MB \u2014",
|
|
38888
38970
|
" split or summarize larger outputs.",
|
|
38971
|
+
"",
|
|
38972
|
+
"Browser tools (when the run needs to drive a browser):",
|
|
38973
|
+
"- Use tools from the `mrrlin-browser` MCP server ONLY \u2014 browser_navigate, browser_click,",
|
|
38974
|
+
" browser_snapshot, browser_type, etc. Never invoke the same-named tools from any other",
|
|
38975
|
+
" browser MCP (`playwright`, `chrome-devtools`, `puppeteer`, ...) that may also be connected.",
|
|
38976
|
+
"- Only `mrrlin-browser` uses this project's dedicated, version-pinned Chromium + persistent",
|
|
38977
|
+
" operator profile (`~/.mrrlin/browser/profile`). Others share the default Playwright profile",
|
|
38978
|
+
" and lose login/cookie state across runs.",
|
|
38979
|
+
"- If tool listings show duplicate names across servers, prefer the `mrrlin-browser` one",
|
|
38980
|
+
" unconditionally. Do not switch mid-run.",
|
|
38889
38981
|
""
|
|
38890
38982
|
];
|
|
38891
38983
|
var CONSUMER_BASE_INSTRUCTIONS = [
|
|
@@ -39218,8 +39310,19 @@ Continue executing task ${task.id}. Make the next concrete increment of progress
|
|
|
39218
39310
|
}
|
|
39219
39311
|
return m;
|
|
39220
39312
|
});
|
|
39313
|
+
const producedUrls = await (async () => {
|
|
39314
|
+
try {
|
|
39315
|
+
const artifacts = await deps.client.listExecutionArtifacts(projectSlug, runId);
|
|
39316
|
+
return artifacts.filter((a) => a.kind === "produced_url").flatMap((a) => {
|
|
39317
|
+
const parsed = mrrlinProducedUrlPayloadSchema.safeParse(a.payload);
|
|
39318
|
+
return parsed.success ? [parsed.data] : [];
|
|
39319
|
+
});
|
|
39320
|
+
} catch {
|
|
39321
|
+
return [];
|
|
39322
|
+
}
|
|
39323
|
+
})();
|
|
39221
39324
|
const pr = await deps.client.createGithubPullRequest(projectSlug, {
|
|
39222
|
-
body:
|
|
39325
|
+
body: buildPullRequestBody({ runId, taskId: readiness.task.id, producedUrls }),
|
|
39223
39326
|
draft: true,
|
|
39224
39327
|
headBranch: minted.branch,
|
|
39225
39328
|
title: `[mrrlin] ${readiness.task.title}`
|
|
@@ -41032,7 +41135,7 @@ function validateOpts(curve) {
|
|
|
41032
41135
|
}
|
|
41033
41136
|
function twistedEdwards(curveDef) {
|
|
41034
41137
|
const CURVE = validateOpts(curveDef);
|
|
41035
|
-
const { Fp: Fp2, n: CURVE_ORDER, prehash, hash: cHash, randomBytes:
|
|
41138
|
+
const { Fp: Fp2, n: CURVE_ORDER, prehash, hash: cHash, randomBytes: randomBytes4, nByteLength, h: cofactor } = CURVE;
|
|
41036
41139
|
const MASK = _2n3 << BigInt(nByteLength * 8) - _1n4;
|
|
41037
41140
|
const modP = Fp2.create;
|
|
41038
41141
|
const uvRatio2 = CURVE.uvRatio || ((u, v) => {
|
|
@@ -41371,7 +41474,7 @@ function twistedEdwards(curveDef) {
|
|
|
41371
41474
|
const utils = {
|
|
41372
41475
|
getExtendedPublicKey,
|
|
41373
41476
|
// ed25519 private keys are uniform 32b. No need to check for modulo bias, like in secp256k1.
|
|
41374
|
-
randomPrivateKey: () =>
|
|
41477
|
+
randomPrivateKey: () => randomBytes4(Fp2.BYTES),
|
|
41375
41478
|
/**
|
|
41376
41479
|
* We're doing scalar multiplication (used in getPublicKey etc) with precomputed BASE_POINT
|
|
41377
41480
|
* values. This slows down first getPublicKey() by milliseconds (see Speed section),
|
|
@@ -43334,9 +43437,9 @@ var DirectorRelay = class {
|
|
|
43334
43437
|
|
|
43335
43438
|
// src/remote-phone-relay.ts
|
|
43336
43439
|
function loadOrCreateAgentDeviceKey() {
|
|
43337
|
-
const
|
|
43440
|
+
const path15 = (0, import_node_path8.join)((0, import_node_os6.homedir)(), ".mrrlin", "agent-device-key");
|
|
43338
43441
|
try {
|
|
43339
|
-
const raw = JSON.parse((0, import_node_fs7.readFileSync)(
|
|
43442
|
+
const raw = JSON.parse((0, import_node_fs7.readFileSync)(path15, "utf8"));
|
|
43340
43443
|
if (typeof raw.priv === "string" && typeof raw.pub === "string") {
|
|
43341
43444
|
return { privateKey: fromBase64Url(raw.priv), publicKey: fromBase64Url(raw.pub) };
|
|
43342
43445
|
}
|
|
@@ -43346,7 +43449,7 @@ function loadOrCreateAgentDeviceKey() {
|
|
|
43346
43449
|
try {
|
|
43347
43450
|
(0, import_node_fs7.mkdirSync)((0, import_node_path8.join)((0, import_node_os6.homedir)(), ".mrrlin"), { recursive: true });
|
|
43348
43451
|
(0, import_node_fs7.writeFileSync)(
|
|
43349
|
-
|
|
43452
|
+
path15,
|
|
43350
43453
|
JSON.stringify({ priv: toBase64Url(kp.privateKey), pub: toBase64Url(kp.publicKey) }),
|
|
43351
43454
|
{ mode: 384 }
|
|
43352
43455
|
);
|
|
@@ -43569,9 +43672,9 @@ var CheckoutRegistry = class {
|
|
|
43569
43672
|
get(slug) {
|
|
43570
43673
|
return this.read()[slug] ?? null;
|
|
43571
43674
|
}
|
|
43572
|
-
confirm(slug,
|
|
43675
|
+
confirm(slug, path15, now) {
|
|
43573
43676
|
const all = this.read();
|
|
43574
|
-
all[slug] = { path:
|
|
43677
|
+
all[slug] = { path: path15, confirmedAt: now };
|
|
43575
43678
|
(0, import_node_fs8.writeFileSync)(this.file, JSON.stringify(all, null, 2));
|
|
43576
43679
|
}
|
|
43577
43680
|
};
|
|
@@ -43987,336 +44090,6 @@ function createBridgeLogger(stateDir, env = process.env) {
|
|
|
43987
44090
|
};
|
|
43988
44091
|
}
|
|
43989
44092
|
|
|
43990
|
-
// src/issue-report.ts
|
|
43991
|
-
var import_node_fs11 = require("node:fs");
|
|
43992
|
-
var import_node_os8 = require("node:os");
|
|
43993
|
-
var import_node_path12 = __toESM(require("node:path"), 1);
|
|
43994
|
-
var import_node_child_process4 = require("node:child_process");
|
|
43995
|
-
var TELEGRAM_BOT_TOKEN = "8506614214:AAGyhO1phWb7ah2aN6_gAX2Co7OXNN3zb0A";
|
|
43996
|
-
var TELEGRAM_CHAT_ID = "-5373779177";
|
|
43997
|
-
function summarizeTranscript(entries = []) {
|
|
43998
|
-
const normalized = entries.map((entry) => ({
|
|
43999
|
-
kind: entry.kind,
|
|
44000
|
-
content: squashWhitespace(entry.content)
|
|
44001
|
-
})).filter((entry) => entry.content.length > 0);
|
|
44002
|
-
if (normalized.length <= 20) return normalized;
|
|
44003
|
-
return normalized.slice(normalized.length - 20);
|
|
44004
|
-
}
|
|
44005
|
-
function squashWhitespace(value) {
|
|
44006
|
-
return value.replace(/\s+/g, " ").trim();
|
|
44007
|
-
}
|
|
44008
|
-
function clip(value, maxChars) {
|
|
44009
|
-
if (value.length <= maxChars) return value;
|
|
44010
|
-
return `${value.slice(0, Math.max(0, maxChars - 1))}\u2026`;
|
|
44011
|
-
}
|
|
44012
|
-
function firstSentence(value) {
|
|
44013
|
-
const trimmed = squashWhitespace(value);
|
|
44014
|
-
if (!trimmed) return "";
|
|
44015
|
-
const match = trimmed.match(/^(.{1,120}?[.!?])(?:\s|$)/);
|
|
44016
|
-
return match?.[1] ? squashWhitespace(match[1]) : clip(trimmed, 120);
|
|
44017
|
-
}
|
|
44018
|
-
function describePayload(payload) {
|
|
44019
|
-
if (typeof payload === "string") return payload;
|
|
44020
|
-
try {
|
|
44021
|
-
return JSON.stringify(payload);
|
|
44022
|
-
} catch {
|
|
44023
|
-
return String(payload);
|
|
44024
|
-
}
|
|
44025
|
-
}
|
|
44026
|
-
function resolveLogDir() {
|
|
44027
|
-
const codexHome = process.env.CODEX_HOME?.trim();
|
|
44028
|
-
if (codexHome) {
|
|
44029
|
-
const candidate = import_node_path12.default.join(codexHome, "mrrlin", "director-bridge", "logs");
|
|
44030
|
-
if (existsDir(candidate)) return candidate;
|
|
44031
|
-
}
|
|
44032
|
-
const fallback = import_node_path12.default.join((0, import_node_os8.homedir)(), ".mrrlin", "director-bridge", "logs");
|
|
44033
|
-
return fallback;
|
|
44034
|
-
}
|
|
44035
|
-
function existsDir(candidate) {
|
|
44036
|
-
try {
|
|
44037
|
-
return (0, import_node_fs11.statSync)(candidate).isDirectory();
|
|
44038
|
-
} catch {
|
|
44039
|
-
return false;
|
|
44040
|
-
}
|
|
44041
|
-
}
|
|
44042
|
-
function listRecentLogFiles(logDir) {
|
|
44043
|
-
if (!existsDir(logDir)) return [];
|
|
44044
|
-
return (0, import_node_fs11.readdirSync)(logDir).filter((name) => /^bridge-\d{4}-\d{2}-\d{2}\.jsonl$/.test(name)).sort((a, b) => b.localeCompare(a)).slice(0, 3).map((name) => import_node_path12.default.join(logDir, name));
|
|
44045
|
-
}
|
|
44046
|
-
function parseLogFile(file2) {
|
|
44047
|
-
const lines2 = (0, import_node_fs11.readFileSync)(file2, "utf8").split(/\r?\n/).filter(Boolean);
|
|
44048
|
-
const parsed = [];
|
|
44049
|
-
for (const rawLine of lines2) {
|
|
44050
|
-
try {
|
|
44051
|
-
const raw = JSON.parse(rawLine);
|
|
44052
|
-
if (typeof raw.ts !== "string" || typeof raw.type !== "string" || typeof raw.spanId !== "string") continue;
|
|
44053
|
-
parsed.push({
|
|
44054
|
-
ts: raw.ts,
|
|
44055
|
-
dir: raw.dir === "in" ? "in" : "out",
|
|
44056
|
-
spanId: raw.spanId,
|
|
44057
|
-
sessionId: typeof raw.sessionId === "string" ? raw.sessionId : null,
|
|
44058
|
-
type: raw.type,
|
|
44059
|
-
ms: typeof raw.ms === "number" ? raw.ms : void 0,
|
|
44060
|
-
payload: raw.payload,
|
|
44061
|
-
rawLine,
|
|
44062
|
-
file: file2
|
|
44063
|
-
});
|
|
44064
|
-
} catch {
|
|
44065
|
-
}
|
|
44066
|
-
}
|
|
44067
|
-
return parsed;
|
|
44068
|
-
}
|
|
44069
|
-
function looksLikeError(record2) {
|
|
44070
|
-
if (record2.type === "error" || record2.type === "<parse-error>") return true;
|
|
44071
|
-
const text = `${record2.type} ${describePayload(record2.payload)}`.toLowerCase();
|
|
44072
|
-
return /(^|[^a-z])(error|failed|failure|timed out|timeout|unauthorized|forbidden|invalid|closed before returning a reply)([^a-z]|$)/.test(
|
|
44073
|
-
text
|
|
44074
|
-
);
|
|
44075
|
-
}
|
|
44076
|
-
function buildKeywordSet(input) {
|
|
44077
|
-
return Array.from(
|
|
44078
|
-
new Set(
|
|
44079
|
-
input.toLowerCase().split(/[^a-z0-9_:-]+/).map((part) => part.trim()).filter((part) => part.length >= 4)
|
|
44080
|
-
)
|
|
44081
|
-
).slice(0, 8);
|
|
44082
|
-
}
|
|
44083
|
-
function pickCluster(records, index) {
|
|
44084
|
-
const from = Math.max(0, index - 10);
|
|
44085
|
-
const to = Math.min(records.length, index + 31);
|
|
44086
|
-
return records.slice(from, to);
|
|
44087
|
-
}
|
|
44088
|
-
function findRelevantLogWindow(request, opts = {}) {
|
|
44089
|
-
const logDir = opts.logDir ?? resolveLogDir();
|
|
44090
|
-
const files = listRecentLogFiles(logDir);
|
|
44091
|
-
if (files.length === 0) {
|
|
44092
|
-
return { strategy: "no-log", matchedOn: "(log directory missing or empty)", records: [], file: null };
|
|
44093
|
-
}
|
|
44094
|
-
const allRecords = files.flatMap((file2) => parseLogFile(file2));
|
|
44095
|
-
if (allRecords.length === 0) {
|
|
44096
|
-
return { strategy: "no-log", matchedOn: "(no readable JSONL records)", records: [], file: files[0] ?? null };
|
|
44097
|
-
}
|
|
44098
|
-
const directorSessionId = request.directorSessionId?.trim() || "";
|
|
44099
|
-
if (directorSessionId) {
|
|
44100
|
-
const sessionRecords = allRecords.filter((record2) => record2.sessionId === directorSessionId);
|
|
44101
|
-
if (sessionRecords.length > 0) {
|
|
44102
|
-
for (let index = sessionRecords.length - 1; index >= 0; index -= 1) {
|
|
44103
|
-
const record2 = sessionRecords[index];
|
|
44104
|
-
if (!record2 || !looksLikeError(record2)) continue;
|
|
44105
|
-
const cluster = pickCluster(sessionRecords, index);
|
|
44106
|
-
return {
|
|
44107
|
-
strategy: "session-error-cluster",
|
|
44108
|
-
matchedOn: clip(record2.rawLine, 160),
|
|
44109
|
-
records: cluster,
|
|
44110
|
-
file: record2.file
|
|
44111
|
-
};
|
|
44112
|
-
}
|
|
44113
|
-
return {
|
|
44114
|
-
strategy: "session-tail",
|
|
44115
|
-
matchedOn: `directorSessionId=${directorSessionId}`,
|
|
44116
|
-
records: sessionRecords.slice(Math.max(0, sessionRecords.length - 30)),
|
|
44117
|
-
file: sessionRecords.at(-1)?.file ?? null
|
|
44118
|
-
};
|
|
44119
|
-
}
|
|
44120
|
-
}
|
|
44121
|
-
const description = request.customerDescription.trim();
|
|
44122
|
-
const keywords = buildKeywordSet(description);
|
|
44123
|
-
if (keywords.length > 0) {
|
|
44124
|
-
for (let index = allRecords.length - 1; index >= 0; index -= 1) {
|
|
44125
|
-
const record2 = allRecords[index];
|
|
44126
|
-
if (!record2) continue;
|
|
44127
|
-
const haystack = `${record2.type} ${describePayload(record2.payload)}`.toLowerCase();
|
|
44128
|
-
if (!keywords.some((keyword) => haystack.includes(keyword))) continue;
|
|
44129
|
-
return {
|
|
44130
|
-
strategy: "hint-cluster",
|
|
44131
|
-
matchedOn: clip(record2.rawLine, 160),
|
|
44132
|
-
records: pickCluster(allRecords, index),
|
|
44133
|
-
file: record2.file
|
|
44134
|
-
};
|
|
44135
|
-
}
|
|
44136
|
-
}
|
|
44137
|
-
for (let index = allRecords.length - 1; index >= 0; index -= 1) {
|
|
44138
|
-
const record2 = allRecords[index];
|
|
44139
|
-
if (!record2 || !looksLikeError(record2)) continue;
|
|
44140
|
-
return {
|
|
44141
|
-
strategy: "global-error-tail",
|
|
44142
|
-
matchedOn: clip(record2.rawLine, 160),
|
|
44143
|
-
records: pickCluster(allRecords, index),
|
|
44144
|
-
file: record2.file
|
|
44145
|
-
};
|
|
44146
|
-
}
|
|
44147
|
-
const tail2 = allRecords.slice(Math.max(0, allRecords.length - 30));
|
|
44148
|
-
return {
|
|
44149
|
-
strategy: "global-error-tail",
|
|
44150
|
-
matchedOn: "(no error cluster; using global tail)",
|
|
44151
|
-
records: tail2,
|
|
44152
|
-
file: tail2.at(-1)?.file ?? null
|
|
44153
|
-
};
|
|
44154
|
-
}
|
|
44155
|
-
function formatTranscript(entries) {
|
|
44156
|
-
if (entries.length === 0) return "(no transcript context)";
|
|
44157
|
-
return entries.map((entry) => `- ${entry.kind}: ${clip(redact(entry.content), 400)}`).join("\n");
|
|
44158
|
-
}
|
|
44159
|
-
function formatLogWindow(window) {
|
|
44160
|
-
if (window.records.length === 0) return "(no relevant bridge log lines found)";
|
|
44161
|
-
const preferred = window.records.filter((record2) => looksLikeError(record2)).concat(window.records.filter((record2) => !looksLikeError(record2)));
|
|
44162
|
-
const unique = preferred.filter((record2, index, array2) => array2.findIndex((item) => item.rawLine === record2.rawLine) === index);
|
|
44163
|
-
return clip(
|
|
44164
|
-
unique.map((record2) => {
|
|
44165
|
-
const payload = clip(redact(describePayload(record2.payload)), 360);
|
|
44166
|
-
return `${record2.ts} ${record2.dir} ${record2.type} span=${record2.spanId}${record2.sessionId ? ` session=${record2.sessionId}` : ""} ${payload}`;
|
|
44167
|
-
}).join("\n"),
|
|
44168
|
-
5e3
|
|
44169
|
-
);
|
|
44170
|
-
}
|
|
44171
|
-
function titlePrefix(source) {
|
|
44172
|
-
return source === "shell-menu" ? "[Web]" : "[Director]";
|
|
44173
|
-
}
|
|
44174
|
-
function plainTitle(title) {
|
|
44175
|
-
return title.replace(/^\[[^\]]+\]\s*/, "").trim();
|
|
44176
|
-
}
|
|
44177
|
-
function buildIssueDraft(request, logWindow) {
|
|
44178
|
-
const customerDescription = clip(redact(request.customerDescription.trim() || "(not provided)"), 4e3);
|
|
44179
|
-
const titleStem = firstSentence(customerDescription) || firstSentence(logWindow.records.find((record2) => looksLikeError(record2))?.rawLine ?? "") || "Issue report";
|
|
44180
|
-
const title = clip(`${titlePrefix(request.source)} ${titleStem}`, 96);
|
|
44181
|
-
const transcript = summarizeTranscript(request.transcript ?? []);
|
|
44182
|
-
const screenshotLines = request.screenshots && request.screenshots.length > 0 ? request.screenshots.map((shot) => `- [${shot.filename}](${shot.url})`).join("\n") : "(no screenshots)";
|
|
44183
|
-
const environment = [
|
|
44184
|
-
`- Created at (UTC): ${(/* @__PURE__ */ new Date()).toISOString()}`,
|
|
44185
|
-
`- Source: ${request.source}`,
|
|
44186
|
-
`- Project: ${request.projectSlug?.trim() || "(unknown)"}`,
|
|
44187
|
-
`- Route: ${request.urlPath?.trim() || "(unknown)"}`,
|
|
44188
|
-
`- Director session: ${request.directorSessionId?.trim() || "(none)"}`,
|
|
44189
|
-
`- @mrrlin-dev/mcp: ${PKG_VERSION}`,
|
|
44190
|
-
`- OS: ${(0, import_node_os8.platform)()}`,
|
|
44191
|
-
`- Node: ${process.version}`
|
|
44192
|
-
].join("\n");
|
|
44193
|
-
const logLabel = logWindow.file ? import_node_path12.default.basename(logWindow.file) : "(none)";
|
|
44194
|
-
const body = [
|
|
44195
|
-
"## Summary",
|
|
44196
|
-
`${titlePrefix(request.source)} issue report generated from local Mrrlin evidence.`,
|
|
44197
|
-
"",
|
|
44198
|
-
"## Customer report",
|
|
44199
|
-
customerDescription,
|
|
44200
|
-
"",
|
|
44201
|
-
"## Observed behavior",
|
|
44202
|
-
`- Log search strategy: ${logWindow.strategy}`,
|
|
44203
|
-
`- Matched on: ${redact(logWindow.matchedOn)}`,
|
|
44204
|
-
"",
|
|
44205
|
-
"## Director / shell context",
|
|
44206
|
-
environment,
|
|
44207
|
-
"",
|
|
44208
|
-
`## Bridge log excerpt (${logLabel})`,
|
|
44209
|
-
"```text",
|
|
44210
|
-
formatLogWindow(logWindow),
|
|
44211
|
-
"```",
|
|
44212
|
-
"",
|
|
44213
|
-
"## Transcript excerpt",
|
|
44214
|
-
"```text",
|
|
44215
|
-
formatTranscript(transcript),
|
|
44216
|
-
"```",
|
|
44217
|
-
"",
|
|
44218
|
-
"## Screenshots",
|
|
44219
|
-
screenshotLines
|
|
44220
|
-
].join("\n");
|
|
44221
|
-
return { title, body, labels: ["bug"] };
|
|
44222
|
-
}
|
|
44223
|
-
function buildTelegramAnnouncement(request, draft, issueUrl) {
|
|
44224
|
-
const summary = firstSentence(redact(request.customerDescription.trim())) || firstSentence(plainTitle(draft.title)) || "\u043D\u0435\u0432\u0456\u0434\u0442\u0432\u043E\u0440\u0435\u043D\u0430 \u043F\u0440\u043E\u0431\u043B\u0435\u043C\u0430";
|
|
44225
|
-
return `\u0437\u0430\u0440\u0435\u043F\u043E\u0440\u0447\u0435\u043D\u043E \u043D\u043E\u0432\u0438\u0439 \u0431\u0430\u0433, \u043A\u043E\u0440\u043E\u0442\u043A\u043E: ${clip(summary, 280)}
|
|
44226
|
-
${issueUrl}`;
|
|
44227
|
-
}
|
|
44228
|
-
function ensureGhReady() {
|
|
44229
|
-
const auth = (0, import_node_child_process4.spawnSync)("gh", ["auth", "status", "-h", "github.com"], { encoding: "utf8" });
|
|
44230
|
-
if (auth.status !== 0) {
|
|
44231
|
-
const detail = (auth.stderr || auth.stdout || "gh auth status failed").trim();
|
|
44232
|
-
throw new Error(`GitHub CLI is not ready: ${detail}`);
|
|
44233
|
-
}
|
|
44234
|
-
}
|
|
44235
|
-
function createGithubIssue(draft) {
|
|
44236
|
-
ensureGhReady();
|
|
44237
|
-
const tmpDir = (0, import_node_fs11.mkdtempSync)(import_node_path12.default.join((0, import_node_os8.tmpdir)(), "mrrlin-issue-"));
|
|
44238
|
-
const bodyFile = import_node_path12.default.join(tmpDir, "issue-body.md");
|
|
44239
|
-
try {
|
|
44240
|
-
(0, import_node_fs11.writeFileSync)(bodyFile, draft.body, "utf8");
|
|
44241
|
-
const args = ["issue", "create", "--repo", "fnnzzz/mrrlin", "--title", draft.title, "--body-file", bodyFile];
|
|
44242
|
-
for (const label of draft.labels) args.push("--label", label);
|
|
44243
|
-
const result = (0, import_node_child_process4.spawnSync)("gh", args, { encoding: "utf8" });
|
|
44244
|
-
if (result.status !== 0) {
|
|
44245
|
-
const detail = (result.stderr || result.stdout || "gh issue create failed").trim();
|
|
44246
|
-
throw new Error(detail);
|
|
44247
|
-
}
|
|
44248
|
-
const url2 = (result.stdout || "").trim().split(/\s+/).at(-1) ?? "";
|
|
44249
|
-
if (!/^https?:\/\//.test(url2)) {
|
|
44250
|
-
throw new Error(`Issue created but URL could not be parsed from gh output: ${result.stdout.trim()}`);
|
|
44251
|
-
}
|
|
44252
|
-
const numberMatch = url2.match(/\/issues\/(\d+)$/);
|
|
44253
|
-
return { issueNumber: numberMatch ? Number(numberMatch[1]) : null, url: url2 };
|
|
44254
|
-
} finally {
|
|
44255
|
-
(0, import_node_fs11.rmSync)(tmpDir, { recursive: true, force: true });
|
|
44256
|
-
}
|
|
44257
|
-
}
|
|
44258
|
-
function sendTelegramAnnouncement(text) {
|
|
44259
|
-
const tmpDir = (0, import_node_fs11.mkdtempSync)(import_node_path12.default.join((0, import_node_os8.tmpdir)(), "mrrlin-issue-telegram-"));
|
|
44260
|
-
const bodyFile = import_node_path12.default.join(tmpDir, "telegram-body.json");
|
|
44261
|
-
try {
|
|
44262
|
-
(0, import_node_fs11.writeFileSync)(
|
|
44263
|
-
bodyFile,
|
|
44264
|
-
JSON.stringify({
|
|
44265
|
-
chat_id: TELEGRAM_CHAT_ID,
|
|
44266
|
-
text,
|
|
44267
|
-
disable_web_page_preview: true
|
|
44268
|
-
}),
|
|
44269
|
-
"utf8"
|
|
44270
|
-
);
|
|
44271
|
-
const result = (0, import_node_child_process4.spawnSync)(
|
|
44272
|
-
"curl",
|
|
44273
|
-
[
|
|
44274
|
-
"-sS",
|
|
44275
|
-
"-X",
|
|
44276
|
-
"POST",
|
|
44277
|
-
`https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/sendMessage`,
|
|
44278
|
-
"-H",
|
|
44279
|
-
"Content-Type: application/json",
|
|
44280
|
-
"--data-binary",
|
|
44281
|
-
`@${bodyFile}`
|
|
44282
|
-
],
|
|
44283
|
-
{ encoding: "utf8" }
|
|
44284
|
-
);
|
|
44285
|
-
if (result.error) {
|
|
44286
|
-
return `Telegram announce failed: ${result.error.message}`;
|
|
44287
|
-
}
|
|
44288
|
-
if (result.status !== 0) {
|
|
44289
|
-
const detail = (result.stderr || result.stdout || "curl failed").trim();
|
|
44290
|
-
return `Telegram announce failed: ${detail}`;
|
|
44291
|
-
}
|
|
44292
|
-
let parsed = null;
|
|
44293
|
-
try {
|
|
44294
|
-
parsed = JSON.parse(result.stdout || "{}");
|
|
44295
|
-
} catch {
|
|
44296
|
-
return `Telegram announce failed: could not parse response: ${result.stdout.trim()}`;
|
|
44297
|
-
}
|
|
44298
|
-
if (!parsed?.ok) {
|
|
44299
|
-
return `Telegram announce failed: ${parsed?.description || "unknown Telegram error"}`;
|
|
44300
|
-
}
|
|
44301
|
-
return null;
|
|
44302
|
-
} finally {
|
|
44303
|
-
(0, import_node_fs11.rmSync)(tmpDir, { recursive: true, force: true });
|
|
44304
|
-
}
|
|
44305
|
-
}
|
|
44306
|
-
function fileIssueReport(request, opts = {}) {
|
|
44307
|
-
const logWindow = findRelevantLogWindow(request, opts);
|
|
44308
|
-
const draft = buildIssueDraft(request, logWindow);
|
|
44309
|
-
const created = createGithubIssue(draft);
|
|
44310
|
-
const telegramWarning = sendTelegramAnnouncement(buildTelegramAnnouncement(request, draft, created.url));
|
|
44311
|
-
return {
|
|
44312
|
-
issueNumber: created.issueNumber,
|
|
44313
|
-
title: draft.title,
|
|
44314
|
-
url: created.url,
|
|
44315
|
-
telegramDelivered: telegramWarning === null,
|
|
44316
|
-
telegramWarning
|
|
44317
|
-
};
|
|
44318
|
-
}
|
|
44319
|
-
|
|
44320
44093
|
// src/director-bridge.ts
|
|
44321
44094
|
var DEFAULT_DIRECTOR_BRIDGE_ALLOWED_ORIGINS = [
|
|
44322
44095
|
"http://localhost:*",
|
|
@@ -44338,46 +44111,10 @@ function normalizeModel(value) {
|
|
|
44338
44111
|
const trimmed = value.trim();
|
|
44339
44112
|
return trimmed ? trimmed : null;
|
|
44340
44113
|
}
|
|
44341
|
-
function normalizeIssueTranscript(value) {
|
|
44342
|
-
if (value === void 0 || value === null) return [];
|
|
44343
|
-
if (!Array.isArray(value)) return { error: "transcript must be an array." };
|
|
44344
|
-
const transcript = [];
|
|
44345
|
-
for (const entry of value.slice(0, 20)) {
|
|
44346
|
-
if (!entry || typeof entry !== "object") return { error: "transcript entries must be objects." };
|
|
44347
|
-
const kind = entry.kind;
|
|
44348
|
-
const content = entry.content;
|
|
44349
|
-
if (kind !== "user" && kind !== "assistant" && kind !== "error" && kind !== "tool") {
|
|
44350
|
-
return { error: "transcript entry kind is invalid." };
|
|
44351
|
-
}
|
|
44352
|
-
if (typeof content !== "string") return { error: "transcript entry content must be a string." };
|
|
44353
|
-
const trimmed = content.trim();
|
|
44354
|
-
if (!trimmed) continue;
|
|
44355
|
-
transcript.push({ kind, content: trimmed });
|
|
44356
|
-
}
|
|
44357
|
-
return transcript;
|
|
44358
|
-
}
|
|
44359
|
-
function normalizeIssueScreenshots(value) {
|
|
44360
|
-
if (value === void 0 || value === null) return [];
|
|
44361
|
-
if (!Array.isArray(value)) return { error: "screenshots must be an array." };
|
|
44362
|
-
const screenshots = [];
|
|
44363
|
-
for (const entry of value.slice(0, 3)) {
|
|
44364
|
-
if (!entry || typeof entry !== "object") return { error: "screenshots entries must be objects." };
|
|
44365
|
-
const filename = entry.filename;
|
|
44366
|
-
const url2 = entry.url;
|
|
44367
|
-
if (typeof filename !== "string" || !filename.trim()) {
|
|
44368
|
-
return { error: "screenshot filename is required." };
|
|
44369
|
-
}
|
|
44370
|
-
if (typeof url2 !== "string" || !/^https?:\/\//.test(url2)) {
|
|
44371
|
-
return { error: "screenshot url must be an absolute http(s) URL." };
|
|
44372
|
-
}
|
|
44373
|
-
screenshots.push({ filename: filename.trim(), url: url2.trim() });
|
|
44374
|
-
}
|
|
44375
|
-
return screenshots;
|
|
44376
|
-
}
|
|
44377
44114
|
function neutralCheckoutCwd(stateDir) {
|
|
44378
|
-
const dir =
|
|
44115
|
+
const dir = import_node_path12.default.join(stateDir, "no-checkout");
|
|
44379
44116
|
try {
|
|
44380
|
-
|
|
44117
|
+
import_node_fs11.default.mkdirSync(dir, { recursive: true });
|
|
44381
44118
|
} catch {
|
|
44382
44119
|
}
|
|
44383
44120
|
return dir;
|
|
@@ -44409,6 +44146,7 @@ function buildThreadStartParams(msg, config2, desiredModel) {
|
|
|
44409
44146
|
"- Apply this format ONLY to Specs/{id} pages; do not retro-fit it onto other wiki page types.",
|
|
44410
44147
|
"- Spec consensus runs ASYNCHRONOUSLY. Call `run_spec_consensus` for a `Specs/{id}` page; it returns IMMEDIATELY. On `already_converged`, the spec is already marked ready \u2014 proceed straight to `create_execution_run`; do NOT call `mark_spec_ready` and do NOT re-run consensus. On `queued` or `already_running`, tell the user it was launched and END your turn \u2014 do NOT poll or call it again; the result arrives in the inbox (an `info` item on CONVERGED, a `handoff` item if it was blocked/failed). When a consensus `info` item says CONVERGED, proceed to `create_execution_run`. When a `handoff` says it was blocked, address the recorded issues in the spec (any edit re-arms the gate) and call `run_spec_consensus` once more.",
|
|
44411
44148
|
'- When a task needs a browser (login flows, UI verification/clicks, scraping), pass `prerequisites:[{mcp:"mrrlin-browser",reason:"..."}]` to `create_execution_run`. If that run later fails into a handoff, the operator gets a one-click "Launch browser & resume" that brings up the dedicated browser as the turn starts.',
|
|
44149
|
+
"- When you actually drive a browser (calling `browser_navigate`, `browser_click`, `browser_snapshot`, `browser_type`, etc.), invoke those tools from the **`mrrlin-browser`** MCP server ONLY. Do NOT use tools from any other browser MCP (`playwright`, `chrome-devtools`, `puppeteer`, etc.) even if they are also connected on this operator's box \u2014 those use a shared/default Playwright profile that is fragile across runs. Only `mrrlin-browser` uses this project's dedicated Chromium + persistent operator profile (`~/.mrrlin/browser/profile`). If your host exposes multiple browser MCPs with overlapping tool names, prefer the `mrrlin-browser` server unconditionally.",
|
|
44412
44150
|
"",
|
|
44413
44151
|
'Research playbook \u2014 when the user asks about a topic, an area, or "what do we have on X":',
|
|
44414
44152
|
"- Tasks are the source of truth. Start with `list_tasks` using `q=<keyword>`; the filter is a",
|
|
@@ -44585,7 +44323,7 @@ function resolveDefaultBranch(checkoutPath) {
|
|
|
44585
44323
|
if (!checkoutPath) return "main";
|
|
44586
44324
|
const runGit = (args) => {
|
|
44587
44325
|
try {
|
|
44588
|
-
return (0,
|
|
44326
|
+
return (0, import_node_child_process4.execFileSync)("git", ["-C", checkoutPath, ...args], {
|
|
44589
44327
|
encoding: "utf8",
|
|
44590
44328
|
stdio: ["ignore", "pipe", "ignore"],
|
|
44591
44329
|
timeout: 15e3,
|
|
@@ -44617,7 +44355,7 @@ async function runOrphanWorktreeSweep(client, opts) {
|
|
|
44617
44355
|
const cutoff = Date.now() - worktreeRetentionMs();
|
|
44618
44356
|
const isReapable = (worktreePath) => {
|
|
44619
44357
|
try {
|
|
44620
|
-
return
|
|
44358
|
+
return import_node_fs11.default.statSync(worktreePath).mtimeMs < cutoff;
|
|
44621
44359
|
} catch {
|
|
44622
44360
|
return false;
|
|
44623
44361
|
}
|
|
@@ -44654,8 +44392,8 @@ async function runOrphanWorktreeSweep(client, opts) {
|
|
|
44654
44392
|
}
|
|
44655
44393
|
}
|
|
44656
44394
|
function readStateDir() {
|
|
44657
|
-
if (process.env.CODEX_HOME) return
|
|
44658
|
-
return
|
|
44395
|
+
if (process.env.CODEX_HOME) return import_node_path12.default.join(process.env.CODEX_HOME, "mrrlin", "director-bridge");
|
|
44396
|
+
return import_node_path12.default.join(import_node_os8.default.homedir(), ".mrrlin", "director-bridge");
|
|
44659
44397
|
}
|
|
44660
44398
|
function readAllowedOrigins() {
|
|
44661
44399
|
const raw = (process.env.MRRLIN_DIRECTOR_BRIDGE_ALLOWED_ORIGINS ?? "").trim();
|
|
@@ -45004,54 +44742,6 @@ function createBridgeMessageHandler(deps) {
|
|
|
45004
44742
|
handleResumeRequest(msg, sendForSpan);
|
|
45005
44743
|
return;
|
|
45006
44744
|
}
|
|
45007
|
-
if (msg.type === "report_issue") {
|
|
45008
|
-
if (msg.source !== "director-chat" && msg.source !== "director-panel" && msg.source !== "shell-menu") {
|
|
45009
|
-
sendForSpan({ type: "report-issue-result", status: "error", error: "report source is invalid." });
|
|
45010
|
-
return;
|
|
45011
|
-
}
|
|
45012
|
-
const customerDescription = typeof msg.customerDescription === "string" ? msg.customerDescription.trim() : "";
|
|
45013
|
-
if (!customerDescription) {
|
|
45014
|
-
sendForSpan({ type: "report-issue-result", status: "error", error: "customerDescription is required." });
|
|
45015
|
-
return;
|
|
45016
|
-
}
|
|
45017
|
-
const transcript = normalizeIssueTranscript(msg.transcript);
|
|
45018
|
-
if ("error" in transcript) {
|
|
45019
|
-
sendForSpan({ type: "report-issue-result", status: "error", error: transcript.error });
|
|
45020
|
-
return;
|
|
45021
|
-
}
|
|
45022
|
-
const screenshots = normalizeIssueScreenshots(msg.screenshots);
|
|
45023
|
-
if ("error" in screenshots) {
|
|
45024
|
-
sendForSpan({ type: "report-issue-result", status: "error", error: screenshots.error });
|
|
45025
|
-
return;
|
|
45026
|
-
}
|
|
45027
|
-
try {
|
|
45028
|
-
const result = fileIssueReport({
|
|
45029
|
-
source: msg.source,
|
|
45030
|
-
customerDescription,
|
|
45031
|
-
directorSessionId: typeof msg.directorSessionId === "string" ? msg.directorSessionId.trim() || null : null,
|
|
45032
|
-
projectSlug: typeof msg.projectSlug === "string" ? msg.projectSlug.trim() || null : null,
|
|
45033
|
-
urlPath: typeof msg.urlPath === "string" ? msg.urlPath.trim() || null : null,
|
|
45034
|
-
transcript,
|
|
45035
|
-
screenshots
|
|
45036
|
-
});
|
|
45037
|
-
sendForSpan({
|
|
45038
|
-
type: "report-issue-result",
|
|
45039
|
-
status: "ok",
|
|
45040
|
-
issueNumber: result.issueNumber,
|
|
45041
|
-
title: result.title,
|
|
45042
|
-
url: result.url,
|
|
45043
|
-
telegramDelivered: result.telegramDelivered,
|
|
45044
|
-
telegramWarning: result.telegramWarning
|
|
45045
|
-
});
|
|
45046
|
-
} catch (error51) {
|
|
45047
|
-
sendForSpan({
|
|
45048
|
-
type: "report-issue-result",
|
|
45049
|
-
status: "error",
|
|
45050
|
-
error: error51 instanceof Error ? error51.message : String(error51)
|
|
45051
|
-
});
|
|
45052
|
-
}
|
|
45053
|
-
return;
|
|
45054
|
-
}
|
|
45055
44745
|
if (msg.type === "interrupt") {
|
|
45056
44746
|
const directorSessionId2 = (msg.directorSessionId ?? "").trim();
|
|
45057
44747
|
const existing = directorSessionId2 ? deps.threads.get(directorSessionId2) : void 0;
|
|
@@ -45435,7 +45125,7 @@ function parseConfig() {
|
|
|
45435
45125
|
}
|
|
45436
45126
|
function scanForOtherBridges() {
|
|
45437
45127
|
try {
|
|
45438
|
-
const result = (0,
|
|
45128
|
+
const result = (0, import_node_child_process4.spawnSync)("pgrep", ["-f", "mrrlin-mcp director-bridge"], {
|
|
45439
45129
|
encoding: "utf8"
|
|
45440
45130
|
});
|
|
45441
45131
|
if (result.status !== 0) return [];
|
|
@@ -45567,8 +45257,8 @@ async function startDirectorBridge() {
|
|
|
45567
45257
|
codexCwd: config2.codexCwd,
|
|
45568
45258
|
codexExecutable: config2.codexExecutable,
|
|
45569
45259
|
checkoutRegistry,
|
|
45570
|
-
worktreeRoot:
|
|
45571
|
-
locksDir:
|
|
45260
|
+
worktreeRoot: import_node_path12.default.join(config2.stateDir, "worktrees"),
|
|
45261
|
+
locksDir: import_node_path12.default.join(config2.stateDir, "locks"),
|
|
45572
45262
|
// Wire the profile-enforced executor server for code-execution runs. Each run gets its own
|
|
45573
45263
|
// sandboxed Codex instance (scrubbed env, scratch CODEX_HOME, deny-read, egress allowlist).
|
|
45574
45264
|
// The returned handle's dispose() shuts down the spawned app-server CHILD (manager.shutdown(),
|
|
@@ -45601,13 +45291,13 @@ async function startDirectorBridge() {
|
|
|
45601
45291
|
},
|
|
45602
45292
|
runVerificationTurn: createRunVerificationTurn({
|
|
45603
45293
|
startSandbox: async (egressDomains) => {
|
|
45604
|
-
const cwd =
|
|
45294
|
+
const cwd = import_node_fs11.default.mkdtempSync(import_node_path12.default.join(import_node_os8.default.tmpdir(), "mrrlin-verify-"));
|
|
45605
45295
|
let handle;
|
|
45606
45296
|
try {
|
|
45607
45297
|
handle = await startExecutorServer({ worktree: cwd, egressDomains });
|
|
45608
45298
|
} catch (error51) {
|
|
45609
45299
|
try {
|
|
45610
|
-
|
|
45300
|
+
import_node_fs11.default.rmSync(cwd, { recursive: true, force: true });
|
|
45611
45301
|
} catch {
|
|
45612
45302
|
}
|
|
45613
45303
|
throw error51;
|
|
@@ -45618,7 +45308,7 @@ async function startDirectorBridge() {
|
|
|
45618
45308
|
dispose: () => {
|
|
45619
45309
|
handle.dispose();
|
|
45620
45310
|
try {
|
|
45621
|
-
|
|
45311
|
+
import_node_fs11.default.rmSync(cwd, { recursive: true, force: true });
|
|
45622
45312
|
} catch {
|
|
45623
45313
|
}
|
|
45624
45314
|
}
|
|
@@ -45758,7 +45448,7 @@ async function startDirectorBridge() {
|
|
|
45758
45448
|
const bridgeLogger = createBridgeLogger(config2.stateDir, process.env);
|
|
45759
45449
|
let bridgeBinShaShort = "unknown00000";
|
|
45760
45450
|
try {
|
|
45761
|
-
bridgeBinShaShort = import_node_crypto5.default.createHash("sha256").update(
|
|
45451
|
+
bridgeBinShaShort = import_node_crypto5.default.createHash("sha256").update(import_node_fs11.default.readFileSync(process.argv[1] ?? "")).digest("hex").slice(0, 12);
|
|
45762
45452
|
} catch {
|
|
45763
45453
|
}
|
|
45764
45454
|
attachBridgeWss(server, {
|
|
@@ -45867,8 +45557,8 @@ async function startDirectorBridge() {
|
|
|
45867
45557
|
enqueueRun(
|
|
45868
45558
|
() => runOrphanWorktreeSweep(client, {
|
|
45869
45559
|
checkoutRegistry,
|
|
45870
|
-
worktreeRoot:
|
|
45871
|
-
locksDir:
|
|
45560
|
+
worktreeRoot: import_node_path12.default.join(config2.stateDir, "worktrees"),
|
|
45561
|
+
locksDir: import_node_path12.default.join(config2.stateDir, "locks")
|
|
45872
45562
|
})
|
|
45873
45563
|
);
|
|
45874
45564
|
enqueueRun(async () => {
|
|
@@ -46080,15 +45770,15 @@ function readDispatchBody(req) {
|
|
|
46080
45770
|
function readOrCreateBridgeToken(stateDir) {
|
|
46081
45771
|
const explicit = (process.env.MRRLIN_DIRECTOR_BRIDGE_TOKEN ?? "").trim();
|
|
46082
45772
|
if (explicit) return explicit;
|
|
46083
|
-
const tokenPath =
|
|
45773
|
+
const tokenPath = import_node_path12.default.join(stateDir, "token.txt");
|
|
46084
45774
|
try {
|
|
46085
|
-
const existing =
|
|
45775
|
+
const existing = import_node_fs11.default.readFileSync(tokenPath, "utf8").trim();
|
|
46086
45776
|
if (existing) return existing;
|
|
46087
45777
|
} catch {
|
|
46088
45778
|
}
|
|
46089
|
-
|
|
45779
|
+
import_node_fs11.default.mkdirSync(stateDir, { recursive: true, mode: 448 });
|
|
46090
45780
|
const token = import_node_crypto5.default.randomBytes(32).toString("base64url");
|
|
46091
|
-
|
|
45781
|
+
import_node_fs11.default.writeFileSync(tokenPath, `${token}
|
|
46092
45782
|
`, { mode: 384 });
|
|
46093
45783
|
return token;
|
|
46094
45784
|
}
|
|
@@ -49470,18 +49160,19 @@ var StdioServerTransport = class {
|
|
|
49470
49160
|
};
|
|
49471
49161
|
|
|
49472
49162
|
// src/tools.ts
|
|
49163
|
+
var import_node_crypto8 = require("node:crypto");
|
|
49473
49164
|
var import_promises3 = require("node:fs/promises");
|
|
49474
|
-
var
|
|
49475
|
-
var
|
|
49476
|
-
var
|
|
49477
|
-
var
|
|
49165
|
+
var import_node_fs13 = require("node:fs");
|
|
49166
|
+
var import_node_path15 = __toESM(require("node:path"), 1);
|
|
49167
|
+
var import_node_os9 = __toESM(require("node:os"), 1);
|
|
49168
|
+
var import_node_child_process7 = require("node:child_process");
|
|
49478
49169
|
|
|
49479
49170
|
// ../../packages/wiki/dist/index.js
|
|
49480
49171
|
var import_promises2 = __toESM(require("node:fs/promises"), 1);
|
|
49481
|
-
var
|
|
49172
|
+
var import_node_path13 = __toESM(require("node:path"), 1);
|
|
49482
49173
|
var INCLUDED_DOC_FOLDERS = /* @__PURE__ */ new Set(["_meta", "explanation", "how-to", "reference", "sdd", "tutorials"]);
|
|
49483
49174
|
function toPosixPath(input) {
|
|
49484
|
-
return input.split(
|
|
49175
|
+
return input.split(import_node_path13.default.sep).join("/");
|
|
49485
49176
|
}
|
|
49486
49177
|
function slugifyWikiSegment(input) {
|
|
49487
49178
|
return input.trim().toLowerCase().replace(/`/g, "").replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
@@ -49495,12 +49186,12 @@ async function pathExists2(input) {
|
|
|
49495
49186
|
}
|
|
49496
49187
|
}
|
|
49497
49188
|
async function findWorkspaceRoot(start = process.cwd()) {
|
|
49498
|
-
let current =
|
|
49189
|
+
let current = import_node_path13.default.resolve(start);
|
|
49499
49190
|
while (true) {
|
|
49500
|
-
if (await pathExists2(
|
|
49191
|
+
if (await pathExists2(import_node_path13.default.join(current, "pnpm-workspace.yaml")) && await pathExists2(import_node_path13.default.join(current, "docs"))) {
|
|
49501
49192
|
return current;
|
|
49502
49193
|
}
|
|
49503
|
-
const parent =
|
|
49194
|
+
const parent = import_node_path13.default.dirname(current);
|
|
49504
49195
|
if (parent === current) {
|
|
49505
49196
|
throw new Error(`Unable to find Mrrlin workspace root from ${start}`);
|
|
49506
49197
|
}
|
|
@@ -49509,28 +49200,28 @@ async function findWorkspaceRoot(start = process.cwd()) {
|
|
|
49509
49200
|
}
|
|
49510
49201
|
async function resolveDocsRoot(input) {
|
|
49511
49202
|
if (input) {
|
|
49512
|
-
return
|
|
49203
|
+
return import_node_path13.default.resolve(input);
|
|
49513
49204
|
}
|
|
49514
49205
|
if (process.env.MRRLIN_DOCS_ROOT) {
|
|
49515
|
-
return
|
|
49206
|
+
return import_node_path13.default.resolve(process.env.MRRLIN_DOCS_ROOT);
|
|
49516
49207
|
}
|
|
49517
|
-
return
|
|
49208
|
+
return import_node_path13.default.join(await findWorkspaceRoot(), "docs");
|
|
49518
49209
|
}
|
|
49519
49210
|
async function resolveIndexPath(input) {
|
|
49520
49211
|
if (input) {
|
|
49521
|
-
return
|
|
49212
|
+
return import_node_path13.default.resolve(input);
|
|
49522
49213
|
}
|
|
49523
49214
|
if (process.env.MRRLIN_WIKI_INDEX_PATH) {
|
|
49524
|
-
return
|
|
49215
|
+
return import_node_path13.default.resolve(process.env.MRRLIN_WIKI_INDEX_PATH);
|
|
49525
49216
|
}
|
|
49526
49217
|
const workspaceRoot = await findWorkspaceRoot();
|
|
49527
|
-
return
|
|
49218
|
+
return import_node_path13.default.join(workspaceRoot, "apps", "web", "public", "wiki-index.json");
|
|
49528
49219
|
}
|
|
49529
49220
|
async function walkMarkdownFiles(root, dir = root) {
|
|
49530
49221
|
const entries = await import_promises2.default.readdir(dir, { withFileTypes: true });
|
|
49531
49222
|
const files = [];
|
|
49532
49223
|
for (const entry of entries) {
|
|
49533
|
-
const absolute =
|
|
49224
|
+
const absolute = import_node_path13.default.join(dir, entry.name);
|
|
49534
49225
|
if (entry.isDirectory()) {
|
|
49535
49226
|
files.push(...await walkMarkdownFiles(root, absolute));
|
|
49536
49227
|
continue;
|
|
@@ -49549,7 +49240,7 @@ function parseTitle(markdown, sourcePath) {
|
|
|
49549
49240
|
return title;
|
|
49550
49241
|
}
|
|
49551
49242
|
function documentFromFile(docsRoot, absolutePath, markdown) {
|
|
49552
|
-
const relativePath = toPosixPath(
|
|
49243
|
+
const relativePath = toPosixPath(import_node_path13.default.relative(docsRoot, absolutePath));
|
|
49553
49244
|
const [section, fileName] = relativePath.split("/");
|
|
49554
49245
|
if (!section || !fileName || !INCLUDED_DOC_FOLDERS.has(section)) {
|
|
49555
49246
|
return null;
|
|
@@ -49986,7 +49677,7 @@ async function runCodeGate(_target, deps) {
|
|
|
49986
49677
|
}
|
|
49987
49678
|
|
|
49988
49679
|
// src/consensus/codex-exec.ts
|
|
49989
|
-
var
|
|
49680
|
+
var import_node_child_process5 = require("node:child_process");
|
|
49990
49681
|
function extractFinalMessage(stdout) {
|
|
49991
49682
|
let last = null;
|
|
49992
49683
|
for (const rawLine of stdout.split(/\r?\n/)) {
|
|
@@ -50031,7 +49722,7 @@ function firstString(...values) {
|
|
|
50031
49722
|
return null;
|
|
50032
49723
|
}
|
|
50033
49724
|
function runCodexExec(input, deps) {
|
|
50034
|
-
const spawn2 = deps?.spawn ??
|
|
49725
|
+
const spawn2 = deps?.spawn ?? import_node_child_process5.spawn;
|
|
50035
49726
|
const executable = input.codexExecutable ?? "codex";
|
|
50036
49727
|
const sandbox = input.sandbox ?? "read-only";
|
|
50037
49728
|
const fullPrompt = input.developerInstructions.trim() ? `${input.developerInstructions.trim()}
|
|
@@ -50103,12 +49794,12 @@ function errMessage(err) {
|
|
|
50103
49794
|
}
|
|
50104
49795
|
|
|
50105
49796
|
// src/consensus/wiring.ts
|
|
50106
|
-
var
|
|
50107
|
-
var
|
|
49797
|
+
var import_node_fs12 = __toESM(require("node:fs"), 1);
|
|
49798
|
+
var import_node_path14 = __toESM(require("node:path"), 1);
|
|
50108
49799
|
var import_node_url2 = require("node:url");
|
|
50109
49800
|
|
|
50110
49801
|
// src/consensus/code-gate-git.ts
|
|
50111
|
-
var
|
|
49802
|
+
var import_node_child_process6 = require("node:child_process");
|
|
50112
49803
|
var DIFF_MAX_BYTES = 2e5;
|
|
50113
49804
|
var FASTGATE_OUTPUT_MAX_BYTES = 16e3;
|
|
50114
49805
|
var GIT_TIMEOUT_MS = 6e4;
|
|
@@ -50124,7 +49815,7 @@ var defaultRunCmd = (cmd, args, opts) => new Promise((resolve) => {
|
|
|
50124
49815
|
};
|
|
50125
49816
|
let child;
|
|
50126
49817
|
try {
|
|
50127
|
-
child = (0,
|
|
49818
|
+
child = (0, import_node_child_process6.spawn)(cmd, args, {
|
|
50128
49819
|
cwd: opts.cwd,
|
|
50129
49820
|
env: process.env,
|
|
50130
49821
|
shell: false,
|
|
@@ -50339,15 +50030,15 @@ ${res.stdout}${res.stderr}`);
|
|
|
50339
50030
|
var import_meta2 = {};
|
|
50340
50031
|
function getPersonasDir() {
|
|
50341
50032
|
if (typeof __dirname !== "undefined") {
|
|
50342
|
-
return
|
|
50033
|
+
return import_node_path14.default.join(__dirname, "consensus", "personas");
|
|
50343
50034
|
}
|
|
50344
|
-
return
|
|
50035
|
+
return import_node_path14.default.join(import_node_path14.default.dirname((0, import_node_url2.fileURLToPath)(import_meta2.url)), "personas");
|
|
50345
50036
|
}
|
|
50346
50037
|
var personaCache = /* @__PURE__ */ new Map();
|
|
50347
50038
|
function loadPersona(name) {
|
|
50348
50039
|
const cached2 = personaCache.get(name);
|
|
50349
50040
|
if (cached2 !== void 0) return cached2;
|
|
50350
|
-
const content =
|
|
50041
|
+
const content = import_node_fs12.default.readFileSync(import_node_path14.default.join(getPersonasDir(), `${name}.md`), "utf8");
|
|
50351
50042
|
personaCache.set(name, content);
|
|
50352
50043
|
return content;
|
|
50353
50044
|
}
|
|
@@ -50811,6 +50502,7 @@ var mcpToolNames = {
|
|
|
50811
50502
|
uploadArtifact: "upload_artifact",
|
|
50812
50503
|
listArtifactFiles: "list_artifact_files",
|
|
50813
50504
|
resolveHandoff: "resolve_handoff",
|
|
50505
|
+
recordProducedUrl: "record_produced_url",
|
|
50814
50506
|
registerLocalCheckout: "register_local_checkout",
|
|
50815
50507
|
/** Compact-context retrieval: rehydrate a mrrlin:// handle into the canonical full record. */
|
|
50816
50508
|
retrieveContext: "retrieve_context"
|
|
@@ -51372,6 +51064,7 @@ var getExecutionRunInputSchema = runScopedSchema;
|
|
|
51372
51064
|
var updateExecutionRunInputSchema = runScopedSchema.merge(mrrlinExecutionRunUpdateSchema);
|
|
51373
51065
|
var listExecutionArtifactsInputSchema = runScopedSchema;
|
|
51374
51066
|
var appendExecutionArtifactInputSchema = runScopedSchema.merge(mrrlinExecutionArtifactCreateSchema);
|
|
51067
|
+
var recordProducedUrlInputSchema = runScopedSchema.merge(mrrlinProducedUrlPayloadSchema);
|
|
51375
51068
|
var getProjectSchedulerPolicyInputSchema = projectScopedSchema;
|
|
51376
51069
|
var upsertProjectSchedulerPolicyInputSchema = projectScopedSchema.merge(mrrlinProjectSchedulerPolicyUpsertSchema);
|
|
51377
51070
|
var getSchedulerPendingTasksInputSchema = projectScopedSchema;
|
|
@@ -51469,6 +51162,7 @@ var mcpToolInputSchemas = {
|
|
|
51469
51162
|
[mcpToolNames.uploadArtifact]: uploadArtifactInputSchema,
|
|
51470
51163
|
[mcpToolNames.listArtifactFiles]: listArtifactFilesInputSchema,
|
|
51471
51164
|
[mcpToolNames.resolveHandoff]: resolveHandoffInputSchema,
|
|
51165
|
+
[mcpToolNames.recordProducedUrl]: recordProducedUrlInputSchema,
|
|
51472
51166
|
[mcpToolNames.registerLocalCheckout]: registerLocalCheckoutInputSchema,
|
|
51473
51167
|
[mcpToolNames.retrieveContext]: retrieveContextInputSchema
|
|
51474
51168
|
};
|
|
@@ -51572,7 +51266,8 @@ var mcpToolDescriptions = {
|
|
|
51572
51266
|
[mcpToolNames.runSpecConsensus]: 'Enqueue the consensus review gate over a Specs/{id} page. Returns IMMEDIATELY with one of: already_converged (a CONVERGED review already exists for the current content \u2014 proceed straight to create_execution_run, do NOT call mark_spec_ready, it is already set), already_reviewed (a terminal CONSENSUS_BLOCKED for this content), already_running (a consensus job is in flight), or queued (a new job was launched). The review runs in the background; its result/blocker arrives in the inbox (info on CONVERGED, handoff on failure) and is surfaced into the open chat. Do NOT call again for the same spec and do NOT poll. On queued/already_running, tell the user it was launched and end the turn. Pass extraHeads: ["researcher"] for specs referencing external libraries/APIs, or ["debugger"] for root-cause/investigation specs to add opt-in specialist reviewers on top of the fixed four.',
|
|
51573
51267
|
[mcpToolNames.runCodeReviewerGate]: `Review the current branch's code diff (vs baseRef) with a Code Reviewer gate \u2014 independent reviewers iterate review\u2192fix\u2192re-check (checkpoint, scope-limited reviser edits, typecheck/build fast-gate, rollback) until the diff converges or is blocked. Run before opening a PR. Pass extraHeads: ["security-analyst"] for sensitive diffs (auth, secrets, input handling, new endpoints).`,
|
|
51574
51268
|
[mcpToolNames.appendExecutionArtifact]: "Append a durable artifact (plan, checkpoint, command output, test result, diff summary, self-review, error, deploy attempt, or handoff judgement) to an execution run.",
|
|
51575
|
-
[mcpToolNames.
|
|
51269
|
+
[mcpToolNames.recordProducedUrl]: 'Call this after publishing each web page produced by the task, so the UI link opens the page itself instead of the deployed site root. Pass the page\'s full https URL (for external pages, e.g. "https://dev.to/<slug>") OR a path starting with "/" for the deploy environment (e.g. "/blog/<slug>") \u2014 paths are resolved against the run\'s deployed env URL at render time. Optional `label` (\u226440 chars) is shown next to the link; omit and the UI defaults to the page title. Call once per page; multiple calls dedupe by resolved URL in the UI.',
|
|
51270
|
+
[mcpToolNames.createExecutionRun]: 'Create a durable Director execution run for a task. Persists status, branch/SHA, workflow ids, and checkpoint cursor outside the chat transcript. For tasks that require a browser (login flows, UI verification, scraping), set prerequisites:[{mcp:"mrrlin-browser",reason:"<why a browser is needed>"}] so any resulting handoff offers a one-click "Launch browser & resume". When actually driving the browser inside the run, invoke tools from the `mrrlin-browser` MCP server ONLY (browser_navigate/browser_click/browser_snapshot/browser_type/etc.) \u2014 never from `playwright`, `chrome-devtools`, `puppeteer`, or any other browser MCP that may also be connected on the operator\'s box. Only `mrrlin-browser` uses the dedicated Chromium + persistent operator profile.',
|
|
51576
51271
|
[mcpToolNames.getExecutionRun]: "Fetch a single execution run by id.",
|
|
51577
51272
|
[mcpToolNames.listExecutionArtifacts]: "List artifacts captured during an execution run, in chronological order.",
|
|
51578
51273
|
[mcpToolNames.listExecutionRuns]: "List execution runs for a project. Optional filters: taskId, status.",
|
|
@@ -52130,6 +51825,21 @@ function createMrrlinTools(options) {
|
|
|
52130
51825
|
"Unable to append execution artifact.",
|
|
52131
51826
|
async (c, { projectSlug, runId, ...input }) => await c.appendExecutionArtifact(projectSlug, runId, input)
|
|
52132
51827
|
),
|
|
51828
|
+
[mcpToolNames.recordProducedUrl]: makeTool(
|
|
51829
|
+
client,
|
|
51830
|
+
mcpToolNames.recordProducedUrl,
|
|
51831
|
+
"PRODUCED_URL_RECORD_FAILED",
|
|
51832
|
+
"Unable to record produced URL.",
|
|
51833
|
+
async (c, { projectSlug, runId, url: url2, label }) => {
|
|
51834
|
+
const id = `EA-pu-${(0, import_node_crypto8.randomBytes)(4).toString("hex")}`;
|
|
51835
|
+
const payload = label ? { url: url2, label } : { url: url2 };
|
|
51836
|
+
return await c.appendExecutionArtifact(projectSlug, runId, {
|
|
51837
|
+
id,
|
|
51838
|
+
kind: "produced_url",
|
|
51839
|
+
payload
|
|
51840
|
+
});
|
|
51841
|
+
}
|
|
51842
|
+
),
|
|
52133
51843
|
[mcpToolNames.getProjectSchedulerPolicy]: makeTool(
|
|
52134
51844
|
client,
|
|
52135
51845
|
mcpToolNames.getProjectSchedulerPolicy,
|
|
@@ -52188,7 +51898,7 @@ function createMrrlinTools(options) {
|
|
|
52188
51898
|
"ARTIFACT_FILE_UPLOAD_FAILED",
|
|
52189
51899
|
"Unable to upload artifact file.",
|
|
52190
51900
|
async (c, { projectSlug, path: filePath, class: artifactClass, taskId, runId, description }) => {
|
|
52191
|
-
const extension2 =
|
|
51901
|
+
const extension2 = import_node_path15.default.extname(filePath).toLowerCase();
|
|
52192
51902
|
const contentType = ARTIFACT_EXTENSION_TYPES[extension2];
|
|
52193
51903
|
if (!contentType) {
|
|
52194
51904
|
throw new McpToolCodedError(
|
|
@@ -52216,7 +51926,7 @@ function createMrrlinTools(options) {
|
|
|
52216
51926
|
"Artifact exceeds 5MB; split or summarize instead."
|
|
52217
51927
|
);
|
|
52218
51928
|
}
|
|
52219
|
-
const filename =
|
|
51929
|
+
const filename = import_node_path15.default.basename(filePath);
|
|
52220
51930
|
const created = await c.createArtifactFile(projectSlug, {
|
|
52221
51931
|
class: artifactClass,
|
|
52222
51932
|
contentType,
|
|
@@ -52299,7 +52009,7 @@ function createMrrlinTools(options) {
|
|
|
52299
52009
|
"Unable to register local checkout.",
|
|
52300
52010
|
async (_c, { projectSlug, path: checkoutPath, repo }) => {
|
|
52301
52011
|
const trimmedPath = checkoutPath.trim();
|
|
52302
|
-
if (!
|
|
52012
|
+
if (!import_node_path15.default.isAbsolute(trimmedPath)) {
|
|
52303
52013
|
throw new McpToolCodedError(
|
|
52304
52014
|
"LOCAL_CHECKOUT_PATH_NOT_ABSOLUTE",
|
|
52305
52015
|
`Path must be absolute, got: ${trimmedPath}`
|
|
@@ -52307,7 +52017,7 @@ function createMrrlinTools(options) {
|
|
|
52307
52017
|
}
|
|
52308
52018
|
let resolvedPath;
|
|
52309
52019
|
try {
|
|
52310
|
-
resolvedPath = (0,
|
|
52020
|
+
resolvedPath = (0, import_node_fs13.realpathSync)(trimmedPath);
|
|
52311
52021
|
} catch {
|
|
52312
52022
|
throw new McpToolCodedError(
|
|
52313
52023
|
"LOCAL_CHECKOUT_PATH_NOT_FOUND",
|
|
@@ -52316,7 +52026,7 @@ function createMrrlinTools(options) {
|
|
|
52316
52026
|
}
|
|
52317
52027
|
let remoteUrl;
|
|
52318
52028
|
try {
|
|
52319
|
-
remoteUrl = (0,
|
|
52029
|
+
remoteUrl = (0, import_node_child_process7.execFileSync)("git", ["-C", resolvedPath, "remote", "get-url", "origin"], {
|
|
52320
52030
|
encoding: "utf8",
|
|
52321
52031
|
stdio: ["ignore", "pipe", "ignore"],
|
|
52322
52032
|
timeout: 15e3,
|
|
@@ -52334,7 +52044,7 @@ function createMrrlinTools(options) {
|
|
|
52334
52044
|
`Origin remote ${remoteUrl} does not match repo ${repo}.`
|
|
52335
52045
|
);
|
|
52336
52046
|
}
|
|
52337
|
-
const stateDir = process.env.CODEX_HOME ?
|
|
52047
|
+
const stateDir = process.env.CODEX_HOME ? import_node_path15.default.join(process.env.CODEX_HOME, "mrrlin", "director-bridge") : import_node_path15.default.join(import_node_os9.default.homedir(), ".mrrlin", "director-bridge");
|
|
52338
52048
|
const registry3 = new CheckoutRegistry(stateDir);
|
|
52339
52049
|
const confirmedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
52340
52050
|
registry3.confirm(projectSlug, resolvedPath, confirmedAt);
|
|
@@ -52541,13 +52251,13 @@ function runSetCredential(args) {
|
|
|
52541
52251
|
}
|
|
52542
52252
|
|
|
52543
52253
|
// src/install-service.ts
|
|
52544
|
-
var
|
|
52545
|
-
var
|
|
52254
|
+
var import_node_os10 = __toESM(require("node:os"), 1);
|
|
52255
|
+
var import_node_path17 = __toESM(require("node:path"), 1);
|
|
52546
52256
|
|
|
52547
52257
|
// src/service-paths.ts
|
|
52548
|
-
var
|
|
52258
|
+
var import_node_path16 = __toESM(require("node:path"), 1);
|
|
52549
52259
|
function isWorktreePath(p) {
|
|
52550
|
-
const norm =
|
|
52260
|
+
const norm = import_node_path16.default.normalize(p).split(import_node_path16.default.sep).join("/");
|
|
52551
52261
|
return norm.includes("/.claude/worktrees/");
|
|
52552
52262
|
}
|
|
52553
52263
|
function resolveServiceCwd(opts) {
|
|
@@ -52601,7 +52311,7 @@ function installService(deps) {
|
|
|
52601
52311
|
deps.log(resolved.reason);
|
|
52602
52312
|
return { ok: false };
|
|
52603
52313
|
}
|
|
52604
|
-
const home = deps.env.HOME ??
|
|
52314
|
+
const home = deps.env.HOME ?? import_node_os10.default.homedir();
|
|
52605
52315
|
const bins = ["node", "codex", "mrrlin-mcp"].map((b) => deps.which(b));
|
|
52606
52316
|
if (bins.some((b) => !b)) {
|
|
52607
52317
|
deps.log("Could not resolve absolute paths for node/codex/mrrlin-mcp on PATH. Install them or fix PATH.");
|
|
@@ -52612,7 +52322,7 @@ function installService(deps) {
|
|
|
52612
52322
|
return { ok: false };
|
|
52613
52323
|
}
|
|
52614
52324
|
const resolvedBins = bins.filter((b) => b !== null);
|
|
52615
|
-
const pathEnv = Array.from(new Set(resolvedBins.map((b) =>
|
|
52325
|
+
const pathEnv = Array.from(new Set(resolvedBins.map((b) => import_node_path17.default.dirname(b)))).join(":");
|
|
52616
52326
|
const text = renderEcosystemConfig({
|
|
52617
52327
|
cwd: resolved.cwd,
|
|
52618
52328
|
home,
|
|
@@ -52621,7 +52331,7 @@ function installService(deps) {
|
|
|
52621
52331
|
staging: deps.env.MRRLIN_STAGING === "1",
|
|
52622
52332
|
apiBaseUrl: deps.env.MRRLIN_API_BASE_URL?.trim() || void 0
|
|
52623
52333
|
});
|
|
52624
|
-
const ecoPath =
|
|
52334
|
+
const ecoPath = import_node_path17.default.join(home, ".mrrlin", "ecosystem.config.cjs");
|
|
52625
52335
|
deps.writeFile(ecoPath, text);
|
|
52626
52336
|
const start = deps.runPm2(["startOrReload", ecoPath]);
|
|
52627
52337
|
if (start.code !== 0) {
|
|
@@ -52652,13 +52362,13 @@ function uninstallService(deps) {
|
|
|
52652
52362
|
|
|
52653
52363
|
// src/uninstall-codex.ts
|
|
52654
52364
|
var import_promises4 = __toESM(require("node:fs/promises"), 1);
|
|
52655
|
-
var
|
|
52656
|
-
var
|
|
52365
|
+
var import_node_os11 = __toESM(require("node:os"), 1);
|
|
52366
|
+
var import_node_path18 = __toESM(require("node:path"), 1);
|
|
52657
52367
|
var toml2 = __toESM(require_toml(), 1);
|
|
52658
52368
|
function resolveCodexHome2(options) {
|
|
52659
52369
|
if (options.codexHome) return options.codexHome;
|
|
52660
52370
|
if (process.env.CODEX_HOME) return process.env.CODEX_HOME;
|
|
52661
|
-
return
|
|
52371
|
+
return import_node_path18.default.join(options.homeDir ?? import_node_os11.default.homedir(), ".codex");
|
|
52662
52372
|
}
|
|
52663
52373
|
async function pathExists3(target) {
|
|
52664
52374
|
try {
|
|
@@ -52671,7 +52381,7 @@ async function pathExists3(target) {
|
|
|
52671
52381
|
var MRRLIN_BLOCK_RE = /(^|\n)\[mcp_servers\.mrrlin(?:-browser)?(?:\]|\.[^\]\n]*\])[\s\S]*?(?=\n\[|$)/g;
|
|
52672
52382
|
async function uninstallCodex(options = {}) {
|
|
52673
52383
|
const codexHome = resolveCodexHome2(options);
|
|
52674
|
-
const configPath =
|
|
52384
|
+
const configPath = import_node_path18.default.join(codexHome, "config.toml");
|
|
52675
52385
|
const removePrompts = async () => uninstallPrompts(codexHome, options.promptNames ?? []);
|
|
52676
52386
|
if (!await pathExists3(configPath)) {
|
|
52677
52387
|
return { action: "missing", configPath, prompts: await removePrompts() };
|
|
@@ -52699,10 +52409,10 @@ async function uninstallCodex(options = {}) {
|
|
|
52699
52409
|
}
|
|
52700
52410
|
async function uninstallPrompts(codexHome, names) {
|
|
52701
52411
|
if (names.length === 0) return [];
|
|
52702
|
-
const promptsDir2 =
|
|
52412
|
+
const promptsDir2 = import_node_path18.default.join(codexHome, "prompts");
|
|
52703
52413
|
const out = [];
|
|
52704
52414
|
for (const name of names) {
|
|
52705
|
-
const promptPath =
|
|
52415
|
+
const promptPath = import_node_path18.default.join(promptsDir2, `${name}.md`);
|
|
52706
52416
|
try {
|
|
52707
52417
|
await import_promises4.default.unlink(promptPath);
|
|
52708
52418
|
out.push({ name, action: "removed", promptPath });
|
|
@@ -52719,27 +52429,27 @@ async function uninstallPrompts(codexHome, names) {
|
|
|
52719
52429
|
}
|
|
52720
52430
|
|
|
52721
52431
|
// src/report-issue-prompt.ts
|
|
52722
|
-
var
|
|
52723
|
-
var
|
|
52432
|
+
var import_node_fs14 = __toESM(require("node:fs"), 1);
|
|
52433
|
+
var import_node_path19 = __toESM(require("node:path"), 1);
|
|
52724
52434
|
var import_node_url3 = require("node:url");
|
|
52725
52435
|
var import_meta3 = {};
|
|
52726
52436
|
function promptsDir() {
|
|
52727
|
-
if (typeof __dirname !== "undefined") return
|
|
52728
|
-
return
|
|
52437
|
+
if (typeof __dirname !== "undefined") return import_node_path19.default.join(__dirname, "prompts");
|
|
52438
|
+
return import_node_path19.default.join(import_node_path19.default.dirname((0, import_node_url3.fileURLToPath)(import_meta3.url)), "prompts");
|
|
52729
52439
|
}
|
|
52730
52440
|
function readReportIssuePrompt() {
|
|
52731
|
-
return
|
|
52441
|
+
return import_node_fs14.default.readFileSync(import_node_path19.default.join(promptsDir(), "report-issue.md"), "utf8");
|
|
52732
52442
|
}
|
|
52733
52443
|
|
|
52734
52444
|
// src/bin.ts
|
|
52735
52445
|
function pm2Runner(args) {
|
|
52736
|
-
const r = (0,
|
|
52446
|
+
const r = (0, import_node_child_process8.spawnSync)("pm2", args, { encoding: "utf8" });
|
|
52737
52447
|
process.stderr.write(r.stdout ?? "");
|
|
52738
52448
|
process.stderr.write(r.stderr ?? "");
|
|
52739
52449
|
return { code: r.status ?? 1, stdout: r.stdout ?? "" };
|
|
52740
52450
|
}
|
|
52741
52451
|
function whichBin(bin) {
|
|
52742
|
-
const r = (0,
|
|
52452
|
+
const r = (0, import_node_child_process8.spawnSync)("which", [bin], { encoding: "utf8" });
|
|
52743
52453
|
const out = (r.stdout ?? "").trim();
|
|
52744
52454
|
return r.status === 0 && out ? out.split("\n")[0] ?? null : null;
|
|
52745
52455
|
}
|
|
@@ -52772,6 +52482,19 @@ Usage:
|
|
|
52772
52482
|
checkouts register the local dist/bin.cjs;
|
|
52773
52483
|
published npm installs register
|
|
52774
52484
|
\`mrrlin-mcp serve\`.
|
|
52485
|
+
Bakes API-target env vars into the block as an
|
|
52486
|
+
inline env table so \`serve\` boots even when the
|
|
52487
|
+
local 127.0.0.1:8787 is not running. Setup guide:
|
|
52488
|
+
MRRLIN_STAGING=1 mrrlin-mcp install-codex
|
|
52489
|
+
is the canonical path (staging alias + remote-
|
|
52490
|
+
allow gate in one flag). For a non-staging remote,
|
|
52491
|
+
pass BOTH the URL AND the allow gate:
|
|
52492
|
+
MRRLIN_API_BASE_URL=https://... \\
|
|
52493
|
+
MRRLIN_API_ALLOW_REMOTE=1 mrrlin-mcp install-codex
|
|
52494
|
+
Without an allow gate, \`serve\` still refuses any
|
|
52495
|
+
non-loopback URL (see \`mrrlin-mcp serve\` above).
|
|
52496
|
+
URL and MRRLIN_STAGING are mutually exclusive at
|
|
52497
|
+
bake time \u2014 URL wins, mirrors serve's resolver.
|
|
52775
52498
|
--force replaces an existing conflicting block.
|
|
52776
52499
|
--force-prompts overwrites prompt files that
|
|
52777
52500
|
already exist with different content. WITHOUT it,
|
|
@@ -52905,7 +52628,7 @@ async function main() {
|
|
|
52905
52628
|
}
|
|
52906
52629
|
case "browser-serve": {
|
|
52907
52630
|
const { command: command2, args, env } = browserServeArgs();
|
|
52908
|
-
const r = (0,
|
|
52631
|
+
const r = (0, import_node_child_process8.spawnSync)(command2, args, { stdio: "inherit", env: { ...process.env, ...env } });
|
|
52909
52632
|
process.exitCode = r.status ?? 1;
|
|
52910
52633
|
return;
|
|
52911
52634
|
}
|
|
@@ -52924,10 +52647,12 @@ async function main() {
|
|
|
52924
52647
|
);
|
|
52925
52648
|
process.exit(2);
|
|
52926
52649
|
}
|
|
52650
|
+
const serveEnv = deriveServeEnvFromProcessEnv(process.env);
|
|
52927
52651
|
const result = await installCodex({
|
|
52928
52652
|
binPath,
|
|
52929
52653
|
force,
|
|
52930
52654
|
forcePrompts,
|
|
52655
|
+
serveEnv,
|
|
52931
52656
|
prompts: [{ name: "report-issue", content: readReportIssuePrompt() }]
|
|
52932
52657
|
});
|
|
52933
52658
|
process.stderr.write(`[mrrlin-mcp install-codex] ${result.action} ${result.configPath}
|
|
@@ -52973,8 +52698,8 @@ async function main() {
|
|
|
52973
52698
|
env: process.env,
|
|
52974
52699
|
cwd: process.cwd(),
|
|
52975
52700
|
writeFile: (p, c) => {
|
|
52976
|
-
(0,
|
|
52977
|
-
(0,
|
|
52701
|
+
(0, import_node_fs15.mkdirSync)(import_node_path21.default.dirname(p), { recursive: true, mode: 448 });
|
|
52702
|
+
(0, import_node_fs15.writeFileSync)(p, c, { mode: 384 });
|
|
52978
52703
|
},
|
|
52979
52704
|
runPm2: pm2Runner,
|
|
52980
52705
|
which: whichBin,
|
|
@@ -52991,35 +52716,35 @@ async function main() {
|
|
|
52991
52716
|
runPm2: (a) => ({ code: pm2Runner(a).code }),
|
|
52992
52717
|
removeFile: (p) => {
|
|
52993
52718
|
try {
|
|
52994
|
-
(0,
|
|
52719
|
+
(0, import_node_fs15.rmSync)(p, { force: true });
|
|
52995
52720
|
} catch {
|
|
52996
52721
|
}
|
|
52997
52722
|
},
|
|
52998
52723
|
purgeSecret: purge,
|
|
52999
52724
|
secretPath: agentCredentialPath(),
|
|
53000
52725
|
tokenPath: operatorTokenPath(),
|
|
53001
|
-
ecoPath:
|
|
52726
|
+
ecoPath: import_node_path21.default.join(process.env.HOME ?? (0, import_node_os12.homedir)(), ".mrrlin", "ecosystem.config.cjs"),
|
|
53002
52727
|
log: (m) => process.stderr.write(`[mrrlin-mcp uninstall-service] ${m}
|
|
53003
52728
|
`)
|
|
53004
52729
|
});
|
|
53005
52730
|
return;
|
|
53006
52731
|
}
|
|
53007
52732
|
case "uninstall": {
|
|
53008
|
-
const home = process.env.HOME ?? (0,
|
|
52733
|
+
const home = process.env.HOME ?? (0, import_node_os12.homedir)();
|
|
53009
52734
|
const log = (m) => process.stderr.write(`[mrrlin-mcp uninstall] ${m}
|
|
53010
52735
|
`);
|
|
53011
52736
|
uninstallService({
|
|
53012
52737
|
runPm2: (a) => ({ code: pm2Runner(a).code }),
|
|
53013
52738
|
removeFile: (p) => {
|
|
53014
52739
|
try {
|
|
53015
|
-
(0,
|
|
52740
|
+
(0, import_node_fs15.rmSync)(p, { force: true });
|
|
53016
52741
|
} catch {
|
|
53017
52742
|
}
|
|
53018
52743
|
},
|
|
53019
52744
|
purgeSecret: true,
|
|
53020
52745
|
secretPath: agentCredentialPath(),
|
|
53021
52746
|
tokenPath: operatorTokenPath(),
|
|
53022
|
-
ecoPath:
|
|
52747
|
+
ecoPath: import_node_path21.default.join(home, ".mrrlin", "ecosystem.config.cjs"),
|
|
53023
52748
|
log
|
|
53024
52749
|
});
|
|
53025
52750
|
let codexOk = true;
|
|
@@ -53039,7 +52764,7 @@ async function main() {
|
|
|
53039
52764
|
log(`codex config NOT modified: ${error51 instanceof Error ? error51.message : String(error51)}`);
|
|
53040
52765
|
}
|
|
53041
52766
|
try {
|
|
53042
|
-
(0,
|
|
52767
|
+
(0, import_node_fs15.rmSync)(import_node_path21.default.join(home, ".mrrlin"), { recursive: true, force: true });
|
|
53043
52768
|
} catch {
|
|
53044
52769
|
}
|
|
53045
52770
|
log("removed ~/.mrrlin");
|
|
@@ -53080,7 +52805,7 @@ ${HELP_TEXT}`);
|
|
|
53080
52805
|
}
|
|
53081
52806
|
}
|
|
53082
52807
|
function resolveSelfBinPath() {
|
|
53083
|
-
return
|
|
52808
|
+
return import_node_path20.default.resolve(process.argv[1] ?? process.execPath);
|
|
53084
52809
|
}
|
|
53085
52810
|
main().catch((error51) => {
|
|
53086
52811
|
process.stderr.write(`mrrlin-mcp fatal error: ${error51 instanceof Error ? error51.message : String(error51)}
|