@mrrlin-dev/mcp 0.3.5 → 0.3.7

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.
Files changed (2) hide show
  1. package/dist/bin.cjs +320 -628
  2. 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: randomBytes3, createHash: createHash3 } = require("crypto");
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 = randomBytes3(16).toString("base64");
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 platform2 = process.env.GRACEFUL_FS_PLATFORM || process.platform;
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(path16, mode, cb) {
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(path16, uid, gid, cb) {
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 (platform2 === "win32") {
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(path16, mode, callback) {
7806
+ fs8.lchmod = function(path15, mode, callback) {
7807
7807
  fs8.open(
7808
- path16,
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(path16, mode) {
7825
- var fd = fs8.openSync(path16, constants.O_WRONLY | constants.O_SYMLINK, mode);
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(path16, at, mt, cb) {
7847
- fs8.open(path16, constants.O_SYMLINK, function(er, fd) {
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(path16, at, mt) {
7860
- var fd = fs8.openSync(path16, constants.O_SYMLINK);
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(path16, options) {
7979
- if (!(this instanceof ReadStream)) return new ReadStream(path16, options);
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 = path16;
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(path16, options) {
8028
- if (!(this instanceof WriteStream)) return new WriteStream(path16, options);
8027
+ function WriteStream(path15, options) {
8028
+ if (!(this instanceof WriteStream)) return new WriteStream(path15, options);
8029
8029
  Stream.call(this);
8030
- this.path = path16;
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(path16, options, cb) {
8173
+ function readFile2(path15, options, cb) {
8174
8174
  if (typeof options === "function")
8175
8175
  cb = options, options = null;
8176
- return go$readFile(path16, options, cb);
8177
- function go$readFile(path17, options2, cb2, startTime) {
8178
- return fs$readFile(path17, options2, function(err) {
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, [path17, options2, cb2], err, startTime || Date.now(), Date.now()]);
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(path16, data, options, cb) {
8190
+ function writeFile(path15, data, options, cb) {
8191
8191
  if (typeof options === "function")
8192
8192
  cb = options, options = null;
8193
- return go$writeFile(path16, data, options, cb);
8194
- function go$writeFile(path17, data2, options2, cb2, startTime) {
8195
- return fs$writeFile(path17, data2, options2, function(err) {
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, [path17, data2, options2, cb2], err, startTime || Date.now(), Date.now()]);
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(path16, data, options, cb) {
8208
+ function appendFile(path15, data, options, cb) {
8209
8209
  if (typeof options === "function")
8210
8210
  cb = options, options = null;
8211
- return go$appendFile(path16, data, options, cb);
8212
- function go$appendFile(path17, data2, options2, cb2, startTime) {
8213
- return fs$appendFile(path17, data2, options2, function(err) {
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, [path17, data2, options2, cb2], err, startTime || Date.now(), Date.now()]);
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(path16, options, cb) {
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(path17, options2, cb2, startTime) {
8250
- return fs$readdir(path17, fs$readdirCallback(
8251
- path17,
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(path17, options2, cb2, startTime) {
8257
- return fs$readdir(path17, options2, fs$readdirCallback(
8258
- path17,
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(path16, options, cb);
8265
- function fs$readdirCallback(path17, options2, cb2, startTime) {
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
- [path17, options2, cb2],
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(path16, options) {
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(path16, options) {
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(path16, options) {
8380
- return new fs8.ReadStream(path16, options);
8379
+ function createReadStream(path15, options) {
8380
+ return new fs8.ReadStream(path15, options);
8381
8381
  }
8382
- function createWriteStream(path16, options) {
8383
- return new fs8.WriteStream(path16, options);
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(path16, flags, mode, cb) {
8387
+ function open(path15, flags, mode, cb) {
8388
8388
  if (typeof mode === "function")
8389
8389
  cb = mode, mode = null;
8390
- return go$open(path16, flags, mode, cb);
8391
- function go$open(path17, flags2, mode2, cb2, startTime) {
8392
- return fs$open(path17, flags2, mode2, function(err, fd) {
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, [path17, flags2, mode2, cb2], err, startTime || Date.now(), Date.now()]);
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 path16 = require("path");
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, path16.resolve(file2));
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 path16 = dijkstra.find_path(graph.map, "start", "end");
10798
+ const path15 = dijkstra.find_path(graph.map, "start", "end");
10799
10799
  const optimizedSegs = [];
10800
- for (let i = 1; i < path16.length - 1; i++) {
10801
- optimizedSegs.push(graph.table[path16[i]].node);
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(path16, qrData, options, cb) {
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(path16);
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(path16, qrData, options, cb) {
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(path16, utf8, cb);
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 path16 = "";
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
- path16 += newRow ? svgCmd("M", col + margin, 0.5 + row + margin) : svgCmd("m", moveBy, 0);
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
- path16 += svgCmd("h", lineLength);
13495
+ path15 += svgCmd("h", lineLength);
13496
13496
  lineLength = 0;
13497
13497
  }
13498
13498
  } else {
13499
13499
  moveBy++;
13500
13500
  }
13501
13501
  }
13502
- return path16;
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 path16 = "<path " + getColorAttrib(opts.color.dark, "stroke") + ' d="' + qrToPath(data, size, opts.margin) + '"/>';
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 + path16 + "</svg>\n";
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(path16, qrData, options, cb) {
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(path16, xmlStr, cb);
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(path16) {
13694
- return path16.slice((path16.lastIndexOf(".") - 1 >>> 0) + 2).toLowerCase();
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(path16, text, opts, cb) {
13759
- if (typeof path16 !== "string" || !(typeof text === "string" || typeof text === "object")) {
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(path16);
13766
+ const type = params.opts.type || getTypeFromFilename(path15);
13767
13767
  const renderer = getRendererFromType(type);
13768
- const renderToFile = renderer.renderToFile.bind(null, path16);
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(path16) {
16987
- let input = path16;
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 [path16, query] = wsComponent.resourceName.split("?");
17240
- wsComponent.path = path16 && path16 !== "/" ? path16 : void 0;
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);
@@ -20915,11 +20915,11 @@ ${block}`;
20915
20915
  }
20916
20916
 
20917
20917
  // src/director-bridge.ts
20918
- var import_node_fs12 = __toESM(require("node:fs"), 1);
20918
+ var import_node_fs11 = __toESM(require("node:fs"), 1);
20919
20919
  var import_node_http = __toESM(require("node:http"), 1);
20920
- var import_node_os9 = __toESM(require("node:os"), 1);
20921
- var import_node_path13 = __toESM(require("node:path"), 1);
20922
- var import_node_child_process5 = require("node:child_process");
20920
+ var import_node_os8 = __toESM(require("node:os"), 1);
20921
+ var import_node_path12 = __toESM(require("node:path"), 1);
20922
+ var import_node_child_process4 = require("node:child_process");
20923
20923
  var import_node_crypto5 = __toESM(require("node:crypto"), 1);
20924
20924
 
20925
20925
  // src/turn-replay-buffer.ts
@@ -22421,10 +22421,10 @@ function mergeDefs(...defs) {
22421
22421
  function cloneDef(schema) {
22422
22422
  return mergeDefs(schema._zod.def);
22423
22423
  }
22424
- function getElementAtPath(obj, path16) {
22425
- if (!path16)
22424
+ function getElementAtPath(obj, path15) {
22425
+ if (!path15)
22426
22426
  return obj;
22427
- return path16.reduce((acc, key) => acc?.[key], obj);
22427
+ return path15.reduce((acc, key) => acc?.[key], obj);
22428
22428
  }
22429
22429
  function promiseAllObject(promisesObj) {
22430
22430
  const keys = Object.keys(promisesObj);
@@ -22833,11 +22833,11 @@ function explicitlyAborted(x, startIndex = 0) {
22833
22833
  }
22834
22834
  return false;
22835
22835
  }
22836
- function prefixIssues(path16, issues) {
22836
+ function prefixIssues(path15, issues) {
22837
22837
  return issues.map((iss) => {
22838
22838
  var _a3;
22839
22839
  (_a3 = iss).path ?? (_a3.path = []);
22840
- iss.path.unshift(path16);
22840
+ iss.path.unshift(path15);
22841
22841
  return iss;
22842
22842
  });
22843
22843
  }
@@ -22984,16 +22984,16 @@ function flattenError(error51, mapper = (issue2) => issue2.message) {
22984
22984
  }
22985
22985
  function formatError(error51, mapper = (issue2) => issue2.message) {
22986
22986
  const fieldErrors = { _errors: [] };
22987
- const processError = (error52, path16 = []) => {
22987
+ const processError = (error52, path15 = []) => {
22988
22988
  for (const issue2 of error52.issues) {
22989
22989
  if (issue2.code === "invalid_union" && issue2.errors.length) {
22990
- issue2.errors.map((issues) => processError({ issues }, [...path16, ...issue2.path]));
22990
+ issue2.errors.map((issues) => processError({ issues }, [...path15, ...issue2.path]));
22991
22991
  } else if (issue2.code === "invalid_key") {
22992
- processError({ issues: issue2.issues }, [...path16, ...issue2.path]);
22992
+ processError({ issues: issue2.issues }, [...path15, ...issue2.path]);
22993
22993
  } else if (issue2.code === "invalid_element") {
22994
- processError({ issues: issue2.issues }, [...path16, ...issue2.path]);
22994
+ processError({ issues: issue2.issues }, [...path15, ...issue2.path]);
22995
22995
  } else {
22996
- const fullpath = [...path16, ...issue2.path];
22996
+ const fullpath = [...path15, ...issue2.path];
22997
22997
  if (fullpath.length === 0) {
22998
22998
  fieldErrors._errors.push(mapper(issue2));
22999
22999
  } else {
@@ -23020,17 +23020,17 @@ function formatError(error51, mapper = (issue2) => issue2.message) {
23020
23020
  }
23021
23021
  function treeifyError(error51, mapper = (issue2) => issue2.message) {
23022
23022
  const result = { errors: [] };
23023
- const processError = (error52, path16 = []) => {
23023
+ const processError = (error52, path15 = []) => {
23024
23024
  var _a3, _b;
23025
23025
  for (const issue2 of error52.issues) {
23026
23026
  if (issue2.code === "invalid_union" && issue2.errors.length) {
23027
- issue2.errors.map((issues) => processError({ issues }, [...path16, ...issue2.path]));
23027
+ issue2.errors.map((issues) => processError({ issues }, [...path15, ...issue2.path]));
23028
23028
  } else if (issue2.code === "invalid_key") {
23029
- processError({ issues: issue2.issues }, [...path16, ...issue2.path]);
23029
+ processError({ issues: issue2.issues }, [...path15, ...issue2.path]);
23030
23030
  } else if (issue2.code === "invalid_element") {
23031
- processError({ issues: issue2.issues }, [...path16, ...issue2.path]);
23031
+ processError({ issues: issue2.issues }, [...path15, ...issue2.path]);
23032
23032
  } else {
23033
- const fullpath = [...path16, ...issue2.path];
23033
+ const fullpath = [...path15, ...issue2.path];
23034
23034
  if (fullpath.length === 0) {
23035
23035
  result.errors.push(mapper(issue2));
23036
23036
  continue;
@@ -23062,8 +23062,8 @@ function treeifyError(error51, mapper = (issue2) => issue2.message) {
23062
23062
  }
23063
23063
  function toDotPath(_path) {
23064
23064
  const segs = [];
23065
- const path16 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
23066
- for (const seg of path16) {
23065
+ const path15 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
23066
+ for (const seg of path15) {
23067
23067
  if (typeof seg === "number")
23068
23068
  segs.push(`[${seg}]`);
23069
23069
  else if (typeof seg === "symbol")
@@ -35755,13 +35755,13 @@ function resolveRef(ref, ctx) {
35755
35755
  if (!ref.startsWith("#")) {
35756
35756
  throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
35757
35757
  }
35758
- const path16 = ref.slice(1).split("/").filter(Boolean);
35759
- if (path16.length === 0) {
35758
+ const path15 = ref.slice(1).split("/").filter(Boolean);
35759
+ if (path15.length === 0) {
35760
35760
  return ctx.rootSchema;
35761
35761
  }
35762
35762
  const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
35763
- if (path16[0] === defsKey) {
35764
- const key = path16[1];
35763
+ if (path15[0] === defsKey) {
35764
+ const key = path15[1];
35765
35765
  if (!key || !ctx.defs[key]) {
35766
35766
  throw new Error(`Reference not found: ${ref}`);
35767
35767
  }
@@ -36264,7 +36264,8 @@ var openApiOperationIds = {
36264
36264
  updateWikiPageCas: "updateWikiPageCas",
36265
36265
  promoteSpecReadyCas: "promoteSpecReadyCas",
36266
36266
  recordSpecConsensusReview: "recordSpecConsensusReview",
36267
- getSpecConsensusReview: "getSpecConsensusReview"
36267
+ getSpecConsensusReview: "getSpecConsensusReview",
36268
+ onboardingKickoffTransition: "onboardingKickoffTransition"
36268
36269
  };
36269
36270
 
36270
36271
  // ../../packages/schemas/dist/session.js
@@ -36459,6 +36460,7 @@ var mrrlinExecutionArtifactKindSchema = external_exports.enum([
36459
36460
  "handoff_judgement",
36460
36461
  "file",
36461
36462
  "verification",
36463
+ "produced_url",
36462
36464
  "resume_spec"
36463
36465
  ]);
36464
36466
  var mrrlinDeployAttemptPayloadSchema = external_exports.object({
@@ -36474,6 +36476,11 @@ var mrrlinVerificationPayloadSchema = external_exports.object({
36474
36476
  checks: external_exports.array(external_exports.unknown()).optional(),
36475
36477
  turnRef: external_exports.string().nullable()
36476
36478
  });
36479
+ var producedUrlSafeString = external_exports.string().regex(/^[^\x00-\x1F\x7F]+$/, "control chars are not allowed");
36480
+ var mrrlinProducedUrlPayloadSchema = external_exports.object({
36481
+ 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 /"),
36482
+ label: producedUrlSafeString.min(1).max(40).optional()
36483
+ });
36477
36484
  var taxonomyCategorySchema = external_exports.string().min(1).regex(/^[a-z][a-z0-9-]*$/);
36478
36485
  var taxonomySubcategorySchema = external_exports.string().min(1).regex(/^[a-z][a-z0-9-]*$/);
36479
36486
  var mrrlinTaskAssigneeSchema = external_exports.union([external_exports.string().regex(/^@/), external_exports.string().email()]).nullable();
@@ -36596,14 +36603,28 @@ var mrrlinProjectSummarySchema = external_exports.object({
36596
36603
  displayName: external_exports.string().min(1),
36597
36604
  emoji: mrrlinProjectEmojiSchema,
36598
36605
  github: mrrlinGithubBindingSchema,
36606
+ onboardingKickoffState: external_exports.enum(["pending", "sent"]).nullable().optional(),
36599
36607
  slug: mrrlinProjectSlugSchema
36600
36608
  });
36601
36609
  var mrrlinProjectUpsertSchema = mrrlinProjectSummarySchema.omit({
36610
+ onboardingKickoffState: true,
36602
36611
  slug: true
36603
36612
  });
36604
36613
  var mrrlinProjectRenameSchema = external_exports.object({
36605
36614
  displayName: external_exports.string().trim().min(1).max(120)
36606
36615
  });
36616
+ var ONBOARDING_KICKOFF_TRANSITIONS = [
36617
+ { from: null, to: "pending" },
36618
+ { from: "pending", to: "sent" },
36619
+ { from: "sent", to: "pending" }
36620
+ ];
36621
+ var mrrlinOnboardingKickoffTransitionSchema = external_exports.object({
36622
+ from: external_exports.enum(["pending", "sent"]).nullable(),
36623
+ to: external_exports.enum(["pending", "sent"])
36624
+ }).refine((value) => ONBOARDING_KICKOFF_TRANSITIONS.some((t) => t.from === value.from && t.to === value.to), { message: "Unsupported onboarding kickoff transition" });
36625
+ var mrrlinOnboardingKickoffTransitionResponseSchema = external_exports.object({
36626
+ data: external_exports.object({ applied: external_exports.boolean() })
36627
+ });
36607
36628
  var mrrlinProjectMemberSchema = external_exports.object({
36608
36629
  email: external_exports.string().email(),
36609
36630
  githubLogin: external_exports.string().nullable(),
@@ -37430,18 +37451,18 @@ function createMrrlinClient(config2) {
37430
37451
  const customFetch = config2.fetch ?? globalThis.fetch;
37431
37452
  const baseUrl = config2.baseUrl.replace(/\/$/, "");
37432
37453
  const token = config2.token;
37433
- async function request(path16, init) {
37454
+ async function request(path15, init) {
37434
37455
  const method = init?.method ?? "GET";
37435
37456
  const headers = new Headers(init?.headers ?? {});
37436
37457
  if (token && !headers.has("authorization")) {
37437
37458
  headers.set("authorization", `Bearer ${token}`);
37438
37459
  }
37439
- const response = await customFetch(`${baseUrl}${path16}`, { ...init, headers });
37460
+ const response = await customFetch(`${baseUrl}${path15}`, { ...init, headers });
37440
37461
  if (!response.ok) {
37441
37462
  const body = await response.text();
37442
37463
  let code = `HTTP_${response.status}`;
37443
37464
  let violations = null;
37444
- let message = `Mrrlin API ${method} ${path16} failed: ${response.status}`;
37465
+ let message = `Mrrlin API ${method} ${path15} failed: ${response.status}`;
37445
37466
  try {
37446
37467
  const parsed = JSON.parse(body);
37447
37468
  const violationsParsed = apiViolationsErrorSchema.safeParse(parsed);
@@ -37461,7 +37482,7 @@ function createMrrlinClient(config2) {
37461
37482
  throw new MrrlinApiError({
37462
37483
  code,
37463
37484
  method,
37464
- path: path16,
37485
+ path: path15,
37465
37486
  responseBody: body,
37466
37487
  status: response.status,
37467
37488
  violations,
@@ -37549,6 +37570,14 @@ function createMrrlinClient(config2) {
37549
37570
  });
37550
37571
  return projectSummaryResponseSchema.parse(body).data;
37551
37572
  },
37573
+ async transitionOnboardingKickoff(projectSlug, input) {
37574
+ const body = await request(`${projectPath(projectSlug)}/onboarding-kickoff`, {
37575
+ body: JSON.stringify(mrrlinOnboardingKickoffTransitionSchema.parse(input)),
37576
+ headers: { "content-type": "application/json" },
37577
+ method: "PATCH"
37578
+ });
37579
+ return mrrlinOnboardingKickoffTransitionResponseSchema.parse(body).data.applied;
37580
+ },
37552
37581
  async createTaskDependency(projectSlug, input) {
37553
37582
  const body = await request(`${projectPath(projectSlug)}/task-dependencies`, {
37554
37583
  body: JSON.stringify(input),
@@ -37708,7 +37737,7 @@ function createMrrlinClient(config2) {
37708
37737
  return taskEventListResponseSchema.parse(body).data;
37709
37738
  },
37710
37739
  async listTasks(projectSlug, filters = {}) {
37711
- const path16 = appendQuery(`${projectPath(projectSlug)}/tasks`, {
37740
+ const path15 = appendQuery(`${projectPath(projectSlug)}/tasks`, {
37712
37741
  assignee: filters.assignee,
37713
37742
  autonomyLevel: filters.autonomyLevel,
37714
37743
  blockedBy: filters.blockedBy,
@@ -37720,7 +37749,7 @@ function createMrrlinClient(config2) {
37720
37749
  subcategory: filters.subcategory,
37721
37750
  type: filters.type
37722
37751
  });
37723
- const body = await request(path16);
37752
+ const body = await request(path15);
37724
37753
  return taskListResponseSchema.parse(body).data;
37725
37754
  },
37726
37755
  async listTaxonomy(projectSlug) {
@@ -37728,22 +37757,22 @@ function createMrrlinClient(config2) {
37728
37757
  return taxonomyListResponseSchema.parse(body).data;
37729
37758
  },
37730
37759
  async listWikiPages(projectSlug, filters = {}) {
37731
- const path16 = appendQuery(`${projectPath(projectSlug)}/wiki`, {
37760
+ const path15 = appendQuery(`${projectPath(projectSlug)}/wiki`, {
37732
37761
  folder: filters.folder,
37733
37762
  q: filters.q,
37734
37763
  taskId: filters.taskId
37735
37764
  });
37736
- const body = await request(path16);
37765
+ const body = await request(path15);
37737
37766
  return wikiPageListResponseSchema.parse(body).data;
37738
37767
  },
37739
37768
  async searchWikiPages(projectSlug, query) {
37740
- const path16 = appendQuery(`${projectPath(projectSlug)}/wiki/search`, {
37769
+ const path15 = appendQuery(`${projectPath(projectSlug)}/wiki/search`, {
37741
37770
  folder: query.folder,
37742
37771
  limit: query.limit === void 0 ? void 0 : String(query.limit),
37743
37772
  pathPrefix: query.pathPrefix,
37744
37773
  q: query.q
37745
37774
  });
37746
- const body = await request(path16);
37775
+ const body = await request(path15);
37747
37776
  return wikiPageSearchResponseSchema.parse(body).data;
37748
37777
  },
37749
37778
  async updatePlan(projectSlug, planId, patch) {
@@ -38460,7 +38489,7 @@ Do NOT derail the current task \u2014 if the operator has an in-flight question,
38460
38489
  }
38461
38490
 
38462
38491
  // src/_generated/version.ts
38463
- var PKG_VERSION = "0.3.5";
38492
+ var PKG_VERSION = "0.3.7";
38464
38493
 
38465
38494
  // src/api-base-url.ts
38466
38495
  var DEFAULT_API_BASE_URL = "http://127.0.0.1:8787";
@@ -38844,6 +38873,41 @@ async function sweepOrphanWorktrees(opts) {
38844
38873
  return reaped;
38845
38874
  }
38846
38875
 
38876
+ // src/pr-body.ts
38877
+ function isSafeAbsoluteUrl(url2) {
38878
+ try {
38879
+ const protocol = new URL(url2).protocol;
38880
+ return protocol === "http:" || protocol === "https:";
38881
+ } catch {
38882
+ return false;
38883
+ }
38884
+ }
38885
+ function escapeMarkdown(text) {
38886
+ return text.replace(/([\\`[\]])/g, "\\$1");
38887
+ }
38888
+ function buildPullRequestBody(input) {
38889
+ const plain = `Automated change for run \`${input.runId}\` (task ${input.taskId}).`;
38890
+ const seen = /* @__PURE__ */ new Set();
38891
+ const lines2 = [];
38892
+ for (const { url: url2, label } of input.producedUrls) {
38893
+ if (seen.has(url2)) continue;
38894
+ seen.add(url2);
38895
+ if (url2.startsWith("/")) {
38896
+ const note = label ? `${escapeMarkdown(label)} \u2014 ` : "";
38897
+ lines2.push(`- ${note}\`${escapeMarkdown(url2)}\` (deploy-relative)`);
38898
+ continue;
38899
+ }
38900
+ if (!isSafeAbsoluteUrl(url2)) continue;
38901
+ const text = escapeMarkdown(label ?? "Page");
38902
+ lines2.push(`- [${text}](${url2})`);
38903
+ }
38904
+ if (lines2.length === 0) return plain;
38905
+ return `${plain}
38906
+
38907
+ ## Produced pages
38908
+ ${lines2.join("\n")}`;
38909
+ }
38910
+
38847
38911
  // src/execution-consumer.ts
38848
38912
  var DEFAULT_STALE_SECONDS = 300;
38849
38913
  var DEFAULT_TOUCH_INTERVAL_MS = 6e4;
@@ -38886,6 +38950,16 @@ var BASE_INSTRUCTIONS_PREFIX = [
38886
38950
  " or evidence page will reference (180 days). Always pass taskId/runId when known.",
38887
38951
  "- Anything user-facing delivered as a file MUST be uploaded. Files are capped at 5MB \u2014",
38888
38952
  " split or summarize larger outputs.",
38953
+ "",
38954
+ "Browser tools (when the run needs to drive a browser):",
38955
+ "- Use tools from the `mrrlin-browser` MCP server ONLY \u2014 browser_navigate, browser_click,",
38956
+ " browser_snapshot, browser_type, etc. Never invoke the same-named tools from any other",
38957
+ " browser MCP (`playwright`, `chrome-devtools`, `puppeteer`, ...) that may also be connected.",
38958
+ "- Only `mrrlin-browser` uses this project's dedicated, version-pinned Chromium + persistent",
38959
+ " operator profile (`~/.mrrlin/browser/profile`). Others share the default Playwright profile",
38960
+ " and lose login/cookie state across runs.",
38961
+ "- If tool listings show duplicate names across servers, prefer the `mrrlin-browser` one",
38962
+ " unconditionally. Do not switch mid-run.",
38889
38963
  ""
38890
38964
  ];
38891
38965
  var CONSUMER_BASE_INSTRUCTIONS = [
@@ -39218,8 +39292,19 @@ Continue executing task ${task.id}. Make the next concrete increment of progress
39218
39292
  }
39219
39293
  return m;
39220
39294
  });
39295
+ const producedUrls = await (async () => {
39296
+ try {
39297
+ const artifacts = await deps.client.listExecutionArtifacts(projectSlug, runId);
39298
+ return artifacts.filter((a) => a.kind === "produced_url").flatMap((a) => {
39299
+ const parsed = mrrlinProducedUrlPayloadSchema.safeParse(a.payload);
39300
+ return parsed.success ? [parsed.data] : [];
39301
+ });
39302
+ } catch {
39303
+ return [];
39304
+ }
39305
+ })();
39221
39306
  const pr = await deps.client.createGithubPullRequest(projectSlug, {
39222
- body: `Automated change for run \`${runId}\` (task ${readiness.task.id}).`,
39307
+ body: buildPullRequestBody({ runId, taskId: readiness.task.id, producedUrls }),
39223
39308
  draft: true,
39224
39309
  headBranch: minted.branch,
39225
39310
  title: `[mrrlin] ${readiness.task.title}`
@@ -41032,7 +41117,7 @@ function validateOpts(curve) {
41032
41117
  }
41033
41118
  function twistedEdwards(curveDef) {
41034
41119
  const CURVE = validateOpts(curveDef);
41035
- const { Fp: Fp2, n: CURVE_ORDER, prehash, hash: cHash, randomBytes: randomBytes3, nByteLength, h: cofactor } = CURVE;
41120
+ const { Fp: Fp2, n: CURVE_ORDER, prehash, hash: cHash, randomBytes: randomBytes4, nByteLength, h: cofactor } = CURVE;
41036
41121
  const MASK = _2n3 << BigInt(nByteLength * 8) - _1n4;
41037
41122
  const modP = Fp2.create;
41038
41123
  const uvRatio2 = CURVE.uvRatio || ((u, v) => {
@@ -41371,7 +41456,7 @@ function twistedEdwards(curveDef) {
41371
41456
  const utils = {
41372
41457
  getExtendedPublicKey,
41373
41458
  // ed25519 private keys are uniform 32b. No need to check for modulo bias, like in secp256k1.
41374
- randomPrivateKey: () => randomBytes3(Fp2.BYTES),
41459
+ randomPrivateKey: () => randomBytes4(Fp2.BYTES),
41375
41460
  /**
41376
41461
  * We're doing scalar multiplication (used in getPublicKey etc) with precomputed BASE_POINT
41377
41462
  * values. This slows down first getPublicKey() by milliseconds (see Speed section),
@@ -43334,9 +43419,9 @@ var DirectorRelay = class {
43334
43419
 
43335
43420
  // src/remote-phone-relay.ts
43336
43421
  function loadOrCreateAgentDeviceKey() {
43337
- const path16 = (0, import_node_path8.join)((0, import_node_os6.homedir)(), ".mrrlin", "agent-device-key");
43422
+ const path15 = (0, import_node_path8.join)((0, import_node_os6.homedir)(), ".mrrlin", "agent-device-key");
43338
43423
  try {
43339
- const raw = JSON.parse((0, import_node_fs7.readFileSync)(path16, "utf8"));
43424
+ const raw = JSON.parse((0, import_node_fs7.readFileSync)(path15, "utf8"));
43340
43425
  if (typeof raw.priv === "string" && typeof raw.pub === "string") {
43341
43426
  return { privateKey: fromBase64Url(raw.priv), publicKey: fromBase64Url(raw.pub) };
43342
43427
  }
@@ -43346,7 +43431,7 @@ function loadOrCreateAgentDeviceKey() {
43346
43431
  try {
43347
43432
  (0, import_node_fs7.mkdirSync)((0, import_node_path8.join)((0, import_node_os6.homedir)(), ".mrrlin"), { recursive: true });
43348
43433
  (0, import_node_fs7.writeFileSync)(
43349
- path16,
43434
+ path15,
43350
43435
  JSON.stringify({ priv: toBase64Url(kp.privateKey), pub: toBase64Url(kp.publicKey) }),
43351
43436
  { mode: 384 }
43352
43437
  );
@@ -43569,9 +43654,9 @@ var CheckoutRegistry = class {
43569
43654
  get(slug) {
43570
43655
  return this.read()[slug] ?? null;
43571
43656
  }
43572
- confirm(slug, path16, now) {
43657
+ confirm(slug, path15, now) {
43573
43658
  const all = this.read();
43574
- all[slug] = { path: path16, confirmedAt: now };
43659
+ all[slug] = { path: path15, confirmedAt: now };
43575
43660
  (0, import_node_fs8.writeFileSync)(this.file, JSON.stringify(all, null, 2));
43576
43661
  }
43577
43662
  };
@@ -43987,336 +44072,6 @@ function createBridgeLogger(stateDir, env = process.env) {
43987
44072
  };
43988
44073
  }
43989
44074
 
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
44075
  // src/director-bridge.ts
44321
44076
  var DEFAULT_DIRECTOR_BRIDGE_ALLOWED_ORIGINS = [
44322
44077
  "http://localhost:*",
@@ -44338,46 +44093,10 @@ function normalizeModel(value) {
44338
44093
  const trimmed = value.trim();
44339
44094
  return trimmed ? trimmed : null;
44340
44095
  }
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
44096
  function neutralCheckoutCwd(stateDir) {
44378
- const dir = import_node_path13.default.join(stateDir, "no-checkout");
44097
+ const dir = import_node_path12.default.join(stateDir, "no-checkout");
44379
44098
  try {
44380
- import_node_fs12.default.mkdirSync(dir, { recursive: true });
44099
+ import_node_fs11.default.mkdirSync(dir, { recursive: true });
44381
44100
  } catch {
44382
44101
  }
44383
44102
  return dir;
@@ -44409,6 +44128,7 @@ function buildThreadStartParams(msg, config2, desiredModel) {
44409
44128
  "- Apply this format ONLY to Specs/{id} pages; do not retro-fit it onto other wiki page types.",
44410
44129
  "- 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
44130
  '- 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.',
44131
+ "- 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
44132
  "",
44413
44133
  'Research playbook \u2014 when the user asks about a topic, an area, or "what do we have on X":',
44414
44134
  "- Tasks are the source of truth. Start with `list_tasks` using `q=<keyword>`; the filter is a",
@@ -44585,7 +44305,7 @@ function resolveDefaultBranch(checkoutPath) {
44585
44305
  if (!checkoutPath) return "main";
44586
44306
  const runGit = (args) => {
44587
44307
  try {
44588
- return (0, import_node_child_process5.execFileSync)("git", ["-C", checkoutPath, ...args], {
44308
+ return (0, import_node_child_process4.execFileSync)("git", ["-C", checkoutPath, ...args], {
44589
44309
  encoding: "utf8",
44590
44310
  stdio: ["ignore", "pipe", "ignore"],
44591
44311
  timeout: 15e3,
@@ -44617,7 +44337,7 @@ async function runOrphanWorktreeSweep(client, opts) {
44617
44337
  const cutoff = Date.now() - worktreeRetentionMs();
44618
44338
  const isReapable = (worktreePath) => {
44619
44339
  try {
44620
- return import_node_fs12.default.statSync(worktreePath).mtimeMs < cutoff;
44340
+ return import_node_fs11.default.statSync(worktreePath).mtimeMs < cutoff;
44621
44341
  } catch {
44622
44342
  return false;
44623
44343
  }
@@ -44654,8 +44374,8 @@ async function runOrphanWorktreeSweep(client, opts) {
44654
44374
  }
44655
44375
  }
44656
44376
  function readStateDir() {
44657
- if (process.env.CODEX_HOME) return import_node_path13.default.join(process.env.CODEX_HOME, "mrrlin", "director-bridge");
44658
- return import_node_path13.default.join(import_node_os9.default.homedir(), ".mrrlin", "director-bridge");
44377
+ if (process.env.CODEX_HOME) return import_node_path12.default.join(process.env.CODEX_HOME, "mrrlin", "director-bridge");
44378
+ return import_node_path12.default.join(import_node_os8.default.homedir(), ".mrrlin", "director-bridge");
44659
44379
  }
44660
44380
  function readAllowedOrigins() {
44661
44381
  const raw = (process.env.MRRLIN_DIRECTOR_BRIDGE_ALLOWED_ORIGINS ?? "").trim();
@@ -45004,54 +44724,6 @@ function createBridgeMessageHandler(deps) {
45004
44724
  handleResumeRequest(msg, sendForSpan);
45005
44725
  return;
45006
44726
  }
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
44727
  if (msg.type === "interrupt") {
45056
44728
  const directorSessionId2 = (msg.directorSessionId ?? "").trim();
45057
44729
  const existing = directorSessionId2 ? deps.threads.get(directorSessionId2) : void 0;
@@ -45435,7 +45107,7 @@ function parseConfig() {
45435
45107
  }
45436
45108
  function scanForOtherBridges() {
45437
45109
  try {
45438
- const result = (0, import_node_child_process5.spawnSync)("pgrep", ["-f", "mrrlin-mcp director-bridge"], {
45110
+ const result = (0, import_node_child_process4.spawnSync)("pgrep", ["-f", "mrrlin-mcp director-bridge"], {
45439
45111
  encoding: "utf8"
45440
45112
  });
45441
45113
  if (result.status !== 0) return [];
@@ -45567,8 +45239,8 @@ async function startDirectorBridge() {
45567
45239
  codexCwd: config2.codexCwd,
45568
45240
  codexExecutable: config2.codexExecutable,
45569
45241
  checkoutRegistry,
45570
- worktreeRoot: import_node_path13.default.join(config2.stateDir, "worktrees"),
45571
- locksDir: import_node_path13.default.join(config2.stateDir, "locks"),
45242
+ worktreeRoot: import_node_path12.default.join(config2.stateDir, "worktrees"),
45243
+ locksDir: import_node_path12.default.join(config2.stateDir, "locks"),
45572
45244
  // Wire the profile-enforced executor server for code-execution runs. Each run gets its own
45573
45245
  // sandboxed Codex instance (scrubbed env, scratch CODEX_HOME, deny-read, egress allowlist).
45574
45246
  // The returned handle's dispose() shuts down the spawned app-server CHILD (manager.shutdown(),
@@ -45601,13 +45273,13 @@ async function startDirectorBridge() {
45601
45273
  },
45602
45274
  runVerificationTurn: createRunVerificationTurn({
45603
45275
  startSandbox: async (egressDomains) => {
45604
- const cwd = import_node_fs12.default.mkdtempSync(import_node_path13.default.join(import_node_os9.default.tmpdir(), "mrrlin-verify-"));
45276
+ const cwd = import_node_fs11.default.mkdtempSync(import_node_path12.default.join(import_node_os8.default.tmpdir(), "mrrlin-verify-"));
45605
45277
  let handle;
45606
45278
  try {
45607
45279
  handle = await startExecutorServer({ worktree: cwd, egressDomains });
45608
45280
  } catch (error51) {
45609
45281
  try {
45610
- import_node_fs12.default.rmSync(cwd, { recursive: true, force: true });
45282
+ import_node_fs11.default.rmSync(cwd, { recursive: true, force: true });
45611
45283
  } catch {
45612
45284
  }
45613
45285
  throw error51;
@@ -45618,7 +45290,7 @@ async function startDirectorBridge() {
45618
45290
  dispose: () => {
45619
45291
  handle.dispose();
45620
45292
  try {
45621
- import_node_fs12.default.rmSync(cwd, { recursive: true, force: true });
45293
+ import_node_fs11.default.rmSync(cwd, { recursive: true, force: true });
45622
45294
  } catch {
45623
45295
  }
45624
45296
  }
@@ -45758,7 +45430,7 @@ async function startDirectorBridge() {
45758
45430
  const bridgeLogger = createBridgeLogger(config2.stateDir, process.env);
45759
45431
  let bridgeBinShaShort = "unknown00000";
45760
45432
  try {
45761
- bridgeBinShaShort = import_node_crypto5.default.createHash("sha256").update(import_node_fs12.default.readFileSync(process.argv[1] ?? "")).digest("hex").slice(0, 12);
45433
+ bridgeBinShaShort = import_node_crypto5.default.createHash("sha256").update(import_node_fs11.default.readFileSync(process.argv[1] ?? "")).digest("hex").slice(0, 12);
45762
45434
  } catch {
45763
45435
  }
45764
45436
  attachBridgeWss(server, {
@@ -45867,8 +45539,8 @@ async function startDirectorBridge() {
45867
45539
  enqueueRun(
45868
45540
  () => runOrphanWorktreeSweep(client, {
45869
45541
  checkoutRegistry,
45870
- worktreeRoot: import_node_path13.default.join(config2.stateDir, "worktrees"),
45871
- locksDir: import_node_path13.default.join(config2.stateDir, "locks")
45542
+ worktreeRoot: import_node_path12.default.join(config2.stateDir, "worktrees"),
45543
+ locksDir: import_node_path12.default.join(config2.stateDir, "locks")
45872
45544
  })
45873
45545
  );
45874
45546
  enqueueRun(async () => {
@@ -46080,15 +45752,15 @@ function readDispatchBody(req) {
46080
45752
  function readOrCreateBridgeToken(stateDir) {
46081
45753
  const explicit = (process.env.MRRLIN_DIRECTOR_BRIDGE_TOKEN ?? "").trim();
46082
45754
  if (explicit) return explicit;
46083
- const tokenPath = import_node_path13.default.join(stateDir, "token.txt");
45755
+ const tokenPath = import_node_path12.default.join(stateDir, "token.txt");
46084
45756
  try {
46085
- const existing = import_node_fs12.default.readFileSync(tokenPath, "utf8").trim();
45757
+ const existing = import_node_fs11.default.readFileSync(tokenPath, "utf8").trim();
46086
45758
  if (existing) return existing;
46087
45759
  } catch {
46088
45760
  }
46089
- import_node_fs12.default.mkdirSync(stateDir, { recursive: true, mode: 448 });
45761
+ import_node_fs11.default.mkdirSync(stateDir, { recursive: true, mode: 448 });
46090
45762
  const token = import_node_crypto5.default.randomBytes(32).toString("base64url");
46091
- import_node_fs12.default.writeFileSync(tokenPath, `${token}
45763
+ import_node_fs11.default.writeFileSync(tokenPath, `${token}
46092
45764
  `, { mode: 384 });
46093
45765
  return token;
46094
45766
  }
@@ -49470,18 +49142,19 @@ var StdioServerTransport = class {
49470
49142
  };
49471
49143
 
49472
49144
  // src/tools.ts
49145
+ var import_node_crypto8 = require("node:crypto");
49473
49146
  var import_promises3 = require("node:fs/promises");
49474
- var import_node_fs14 = require("node:fs");
49475
- var import_node_path16 = __toESM(require("node:path"), 1);
49476
- var import_node_os10 = __toESM(require("node:os"), 1);
49477
- var import_node_child_process8 = require("node:child_process");
49147
+ var import_node_fs13 = require("node:fs");
49148
+ var import_node_path15 = __toESM(require("node:path"), 1);
49149
+ var import_node_os9 = __toESM(require("node:os"), 1);
49150
+ var import_node_child_process7 = require("node:child_process");
49478
49151
 
49479
49152
  // ../../packages/wiki/dist/index.js
49480
49153
  var import_promises2 = __toESM(require("node:fs/promises"), 1);
49481
- var import_node_path14 = __toESM(require("node:path"), 1);
49154
+ var import_node_path13 = __toESM(require("node:path"), 1);
49482
49155
  var INCLUDED_DOC_FOLDERS = /* @__PURE__ */ new Set(["_meta", "explanation", "how-to", "reference", "sdd", "tutorials"]);
49483
49156
  function toPosixPath(input) {
49484
- return input.split(import_node_path14.default.sep).join("/");
49157
+ return input.split(import_node_path13.default.sep).join("/");
49485
49158
  }
49486
49159
  function slugifyWikiSegment(input) {
49487
49160
  return input.trim().toLowerCase().replace(/`/g, "").replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
@@ -49495,12 +49168,12 @@ async function pathExists2(input) {
49495
49168
  }
49496
49169
  }
49497
49170
  async function findWorkspaceRoot(start = process.cwd()) {
49498
- let current = import_node_path14.default.resolve(start);
49171
+ let current = import_node_path13.default.resolve(start);
49499
49172
  while (true) {
49500
- if (await pathExists2(import_node_path14.default.join(current, "pnpm-workspace.yaml")) && await pathExists2(import_node_path14.default.join(current, "docs"))) {
49173
+ if (await pathExists2(import_node_path13.default.join(current, "pnpm-workspace.yaml")) && await pathExists2(import_node_path13.default.join(current, "docs"))) {
49501
49174
  return current;
49502
49175
  }
49503
- const parent = import_node_path14.default.dirname(current);
49176
+ const parent = import_node_path13.default.dirname(current);
49504
49177
  if (parent === current) {
49505
49178
  throw new Error(`Unable to find Mrrlin workspace root from ${start}`);
49506
49179
  }
@@ -49509,28 +49182,28 @@ async function findWorkspaceRoot(start = process.cwd()) {
49509
49182
  }
49510
49183
  async function resolveDocsRoot(input) {
49511
49184
  if (input) {
49512
- return import_node_path14.default.resolve(input);
49185
+ return import_node_path13.default.resolve(input);
49513
49186
  }
49514
49187
  if (process.env.MRRLIN_DOCS_ROOT) {
49515
- return import_node_path14.default.resolve(process.env.MRRLIN_DOCS_ROOT);
49188
+ return import_node_path13.default.resolve(process.env.MRRLIN_DOCS_ROOT);
49516
49189
  }
49517
- return import_node_path14.default.join(await findWorkspaceRoot(), "docs");
49190
+ return import_node_path13.default.join(await findWorkspaceRoot(), "docs");
49518
49191
  }
49519
49192
  async function resolveIndexPath(input) {
49520
49193
  if (input) {
49521
- return import_node_path14.default.resolve(input);
49194
+ return import_node_path13.default.resolve(input);
49522
49195
  }
49523
49196
  if (process.env.MRRLIN_WIKI_INDEX_PATH) {
49524
- return import_node_path14.default.resolve(process.env.MRRLIN_WIKI_INDEX_PATH);
49197
+ return import_node_path13.default.resolve(process.env.MRRLIN_WIKI_INDEX_PATH);
49525
49198
  }
49526
49199
  const workspaceRoot = await findWorkspaceRoot();
49527
- return import_node_path14.default.join(workspaceRoot, "apps", "web", "public", "wiki-index.json");
49200
+ return import_node_path13.default.join(workspaceRoot, "apps", "web", "public", "wiki-index.json");
49528
49201
  }
49529
49202
  async function walkMarkdownFiles(root, dir = root) {
49530
49203
  const entries = await import_promises2.default.readdir(dir, { withFileTypes: true });
49531
49204
  const files = [];
49532
49205
  for (const entry of entries) {
49533
- const absolute = import_node_path14.default.join(dir, entry.name);
49206
+ const absolute = import_node_path13.default.join(dir, entry.name);
49534
49207
  if (entry.isDirectory()) {
49535
49208
  files.push(...await walkMarkdownFiles(root, absolute));
49536
49209
  continue;
@@ -49549,7 +49222,7 @@ function parseTitle(markdown, sourcePath) {
49549
49222
  return title;
49550
49223
  }
49551
49224
  function documentFromFile(docsRoot, absolutePath, markdown) {
49552
- const relativePath = toPosixPath(import_node_path14.default.relative(docsRoot, absolutePath));
49225
+ const relativePath = toPosixPath(import_node_path13.default.relative(docsRoot, absolutePath));
49553
49226
  const [section, fileName] = relativePath.split("/");
49554
49227
  if (!section || !fileName || !INCLUDED_DOC_FOLDERS.has(section)) {
49555
49228
  return null;
@@ -49986,7 +49659,7 @@ async function runCodeGate(_target, deps) {
49986
49659
  }
49987
49660
 
49988
49661
  // src/consensus/codex-exec.ts
49989
- var import_node_child_process6 = require("node:child_process");
49662
+ var import_node_child_process5 = require("node:child_process");
49990
49663
  function extractFinalMessage(stdout) {
49991
49664
  let last = null;
49992
49665
  for (const rawLine of stdout.split(/\r?\n/)) {
@@ -50031,7 +49704,7 @@ function firstString(...values) {
50031
49704
  return null;
50032
49705
  }
50033
49706
  function runCodexExec(input, deps) {
50034
- const spawn2 = deps?.spawn ?? import_node_child_process6.spawn;
49707
+ const spawn2 = deps?.spawn ?? import_node_child_process5.spawn;
50035
49708
  const executable = input.codexExecutable ?? "codex";
50036
49709
  const sandbox = input.sandbox ?? "read-only";
50037
49710
  const fullPrompt = input.developerInstructions.trim() ? `${input.developerInstructions.trim()}
@@ -50103,12 +49776,12 @@ function errMessage(err) {
50103
49776
  }
50104
49777
 
50105
49778
  // src/consensus/wiring.ts
50106
- var import_node_fs13 = __toESM(require("node:fs"), 1);
50107
- var import_node_path15 = __toESM(require("node:path"), 1);
49779
+ var import_node_fs12 = __toESM(require("node:fs"), 1);
49780
+ var import_node_path14 = __toESM(require("node:path"), 1);
50108
49781
  var import_node_url2 = require("node:url");
50109
49782
 
50110
49783
  // src/consensus/code-gate-git.ts
50111
- var import_node_child_process7 = require("node:child_process");
49784
+ var import_node_child_process6 = require("node:child_process");
50112
49785
  var DIFF_MAX_BYTES = 2e5;
50113
49786
  var FASTGATE_OUTPUT_MAX_BYTES = 16e3;
50114
49787
  var GIT_TIMEOUT_MS = 6e4;
@@ -50124,7 +49797,7 @@ var defaultRunCmd = (cmd, args, opts) => new Promise((resolve) => {
50124
49797
  };
50125
49798
  let child;
50126
49799
  try {
50127
- child = (0, import_node_child_process7.spawn)(cmd, args, {
49800
+ child = (0, import_node_child_process6.spawn)(cmd, args, {
50128
49801
  cwd: opts.cwd,
50129
49802
  env: process.env,
50130
49803
  shell: false,
@@ -50339,15 +50012,15 @@ ${res.stdout}${res.stderr}`);
50339
50012
  var import_meta2 = {};
50340
50013
  function getPersonasDir() {
50341
50014
  if (typeof __dirname !== "undefined") {
50342
- return import_node_path15.default.join(__dirname, "consensus", "personas");
50015
+ return import_node_path14.default.join(__dirname, "consensus", "personas");
50343
50016
  }
50344
- return import_node_path15.default.join(import_node_path15.default.dirname((0, import_node_url2.fileURLToPath)(import_meta2.url)), "personas");
50017
+ return import_node_path14.default.join(import_node_path14.default.dirname((0, import_node_url2.fileURLToPath)(import_meta2.url)), "personas");
50345
50018
  }
50346
50019
  var personaCache = /* @__PURE__ */ new Map();
50347
50020
  function loadPersona(name) {
50348
50021
  const cached2 = personaCache.get(name);
50349
50022
  if (cached2 !== void 0) return cached2;
50350
- const content = import_node_fs13.default.readFileSync(import_node_path15.default.join(getPersonasDir(), `${name}.md`), "utf8");
50023
+ const content = import_node_fs12.default.readFileSync(import_node_path14.default.join(getPersonasDir(), `${name}.md`), "utf8");
50351
50024
  personaCache.set(name, content);
50352
50025
  return content;
50353
50026
  }
@@ -50811,6 +50484,7 @@ var mcpToolNames = {
50811
50484
  uploadArtifact: "upload_artifact",
50812
50485
  listArtifactFiles: "list_artifact_files",
50813
50486
  resolveHandoff: "resolve_handoff",
50487
+ recordProducedUrl: "record_produced_url",
50814
50488
  registerLocalCheckout: "register_local_checkout",
50815
50489
  /** Compact-context retrieval: rehydrate a mrrlin:// handle into the canonical full record. */
50816
50490
  retrieveContext: "retrieve_context"
@@ -51372,6 +51046,7 @@ var getExecutionRunInputSchema = runScopedSchema;
51372
51046
  var updateExecutionRunInputSchema = runScopedSchema.merge(mrrlinExecutionRunUpdateSchema);
51373
51047
  var listExecutionArtifactsInputSchema = runScopedSchema;
51374
51048
  var appendExecutionArtifactInputSchema = runScopedSchema.merge(mrrlinExecutionArtifactCreateSchema);
51049
+ var recordProducedUrlInputSchema = runScopedSchema.merge(mrrlinProducedUrlPayloadSchema);
51375
51050
  var getProjectSchedulerPolicyInputSchema = projectScopedSchema;
51376
51051
  var upsertProjectSchedulerPolicyInputSchema = projectScopedSchema.merge(mrrlinProjectSchedulerPolicyUpsertSchema);
51377
51052
  var getSchedulerPendingTasksInputSchema = projectScopedSchema;
@@ -51469,6 +51144,7 @@ var mcpToolInputSchemas = {
51469
51144
  [mcpToolNames.uploadArtifact]: uploadArtifactInputSchema,
51470
51145
  [mcpToolNames.listArtifactFiles]: listArtifactFilesInputSchema,
51471
51146
  [mcpToolNames.resolveHandoff]: resolveHandoffInputSchema,
51147
+ [mcpToolNames.recordProducedUrl]: recordProducedUrlInputSchema,
51472
51148
  [mcpToolNames.registerLocalCheckout]: registerLocalCheckoutInputSchema,
51473
51149
  [mcpToolNames.retrieveContext]: retrieveContextInputSchema
51474
51150
  };
@@ -51572,7 +51248,8 @@ var mcpToolDescriptions = {
51572
51248
  [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
51249
  [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
51250
  [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.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".',
51251
+ [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.',
51252
+ [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
51253
  [mcpToolNames.getExecutionRun]: "Fetch a single execution run by id.",
51577
51254
  [mcpToolNames.listExecutionArtifacts]: "List artifacts captured during an execution run, in chronological order.",
51578
51255
  [mcpToolNames.listExecutionRuns]: "List execution runs for a project. Optional filters: taskId, status.",
@@ -52130,6 +51807,21 @@ function createMrrlinTools(options) {
52130
51807
  "Unable to append execution artifact.",
52131
51808
  async (c, { projectSlug, runId, ...input }) => await c.appendExecutionArtifact(projectSlug, runId, input)
52132
51809
  ),
51810
+ [mcpToolNames.recordProducedUrl]: makeTool(
51811
+ client,
51812
+ mcpToolNames.recordProducedUrl,
51813
+ "PRODUCED_URL_RECORD_FAILED",
51814
+ "Unable to record produced URL.",
51815
+ async (c, { projectSlug, runId, url: url2, label }) => {
51816
+ const id = `EA-pu-${(0, import_node_crypto8.randomBytes)(4).toString("hex")}`;
51817
+ const payload = label ? { url: url2, label } : { url: url2 };
51818
+ return await c.appendExecutionArtifact(projectSlug, runId, {
51819
+ id,
51820
+ kind: "produced_url",
51821
+ payload
51822
+ });
51823
+ }
51824
+ ),
52133
51825
  [mcpToolNames.getProjectSchedulerPolicy]: makeTool(
52134
51826
  client,
52135
51827
  mcpToolNames.getProjectSchedulerPolicy,
@@ -52188,7 +51880,7 @@ function createMrrlinTools(options) {
52188
51880
  "ARTIFACT_FILE_UPLOAD_FAILED",
52189
51881
  "Unable to upload artifact file.",
52190
51882
  async (c, { projectSlug, path: filePath, class: artifactClass, taskId, runId, description }) => {
52191
- const extension2 = import_node_path16.default.extname(filePath).toLowerCase();
51883
+ const extension2 = import_node_path15.default.extname(filePath).toLowerCase();
52192
51884
  const contentType = ARTIFACT_EXTENSION_TYPES[extension2];
52193
51885
  if (!contentType) {
52194
51886
  throw new McpToolCodedError(
@@ -52216,7 +51908,7 @@ function createMrrlinTools(options) {
52216
51908
  "Artifact exceeds 5MB; split or summarize instead."
52217
51909
  );
52218
51910
  }
52219
- const filename = import_node_path16.default.basename(filePath);
51911
+ const filename = import_node_path15.default.basename(filePath);
52220
51912
  const created = await c.createArtifactFile(projectSlug, {
52221
51913
  class: artifactClass,
52222
51914
  contentType,
@@ -52299,7 +51991,7 @@ function createMrrlinTools(options) {
52299
51991
  "Unable to register local checkout.",
52300
51992
  async (_c, { projectSlug, path: checkoutPath, repo }) => {
52301
51993
  const trimmedPath = checkoutPath.trim();
52302
- if (!import_node_path16.default.isAbsolute(trimmedPath)) {
51994
+ if (!import_node_path15.default.isAbsolute(trimmedPath)) {
52303
51995
  throw new McpToolCodedError(
52304
51996
  "LOCAL_CHECKOUT_PATH_NOT_ABSOLUTE",
52305
51997
  `Path must be absolute, got: ${trimmedPath}`
@@ -52307,7 +51999,7 @@ function createMrrlinTools(options) {
52307
51999
  }
52308
52000
  let resolvedPath;
52309
52001
  try {
52310
- resolvedPath = (0, import_node_fs14.realpathSync)(trimmedPath);
52002
+ resolvedPath = (0, import_node_fs13.realpathSync)(trimmedPath);
52311
52003
  } catch {
52312
52004
  throw new McpToolCodedError(
52313
52005
  "LOCAL_CHECKOUT_PATH_NOT_FOUND",
@@ -52316,7 +52008,7 @@ function createMrrlinTools(options) {
52316
52008
  }
52317
52009
  let remoteUrl;
52318
52010
  try {
52319
- remoteUrl = (0, import_node_child_process8.execFileSync)("git", ["-C", resolvedPath, "remote", "get-url", "origin"], {
52011
+ remoteUrl = (0, import_node_child_process7.execFileSync)("git", ["-C", resolvedPath, "remote", "get-url", "origin"], {
52320
52012
  encoding: "utf8",
52321
52013
  stdio: ["ignore", "pipe", "ignore"],
52322
52014
  timeout: 15e3,
@@ -52334,7 +52026,7 @@ function createMrrlinTools(options) {
52334
52026
  `Origin remote ${remoteUrl} does not match repo ${repo}.`
52335
52027
  );
52336
52028
  }
52337
- const stateDir = process.env.CODEX_HOME ? import_node_path16.default.join(process.env.CODEX_HOME, "mrrlin", "director-bridge") : import_node_path16.default.join(import_node_os10.default.homedir(), ".mrrlin", "director-bridge");
52029
+ 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
52030
  const registry3 = new CheckoutRegistry(stateDir);
52339
52031
  const confirmedAt = (/* @__PURE__ */ new Date()).toISOString();
52340
52032
  registry3.confirm(projectSlug, resolvedPath, confirmedAt);
@@ -52541,13 +52233,13 @@ function runSetCredential(args) {
52541
52233
  }
52542
52234
 
52543
52235
  // src/install-service.ts
52544
- var import_node_os11 = __toESM(require("node:os"), 1);
52545
- var import_node_path18 = __toESM(require("node:path"), 1);
52236
+ var import_node_os10 = __toESM(require("node:os"), 1);
52237
+ var import_node_path17 = __toESM(require("node:path"), 1);
52546
52238
 
52547
52239
  // src/service-paths.ts
52548
- var import_node_path17 = __toESM(require("node:path"), 1);
52240
+ var import_node_path16 = __toESM(require("node:path"), 1);
52549
52241
  function isWorktreePath(p) {
52550
- const norm = import_node_path17.default.normalize(p).split(import_node_path17.default.sep).join("/");
52242
+ const norm = import_node_path16.default.normalize(p).split(import_node_path16.default.sep).join("/");
52551
52243
  return norm.includes("/.claude/worktrees/");
52552
52244
  }
52553
52245
  function resolveServiceCwd(opts) {
@@ -52601,7 +52293,7 @@ function installService(deps) {
52601
52293
  deps.log(resolved.reason);
52602
52294
  return { ok: false };
52603
52295
  }
52604
- const home = deps.env.HOME ?? import_node_os11.default.homedir();
52296
+ const home = deps.env.HOME ?? import_node_os10.default.homedir();
52605
52297
  const bins = ["node", "codex", "mrrlin-mcp"].map((b) => deps.which(b));
52606
52298
  if (bins.some((b) => !b)) {
52607
52299
  deps.log("Could not resolve absolute paths for node/codex/mrrlin-mcp on PATH. Install them or fix PATH.");
@@ -52612,7 +52304,7 @@ function installService(deps) {
52612
52304
  return { ok: false };
52613
52305
  }
52614
52306
  const resolvedBins = bins.filter((b) => b !== null);
52615
- const pathEnv = Array.from(new Set(resolvedBins.map((b) => import_node_path18.default.dirname(b)))).join(":");
52307
+ const pathEnv = Array.from(new Set(resolvedBins.map((b) => import_node_path17.default.dirname(b)))).join(":");
52616
52308
  const text = renderEcosystemConfig({
52617
52309
  cwd: resolved.cwd,
52618
52310
  home,
@@ -52621,7 +52313,7 @@ function installService(deps) {
52621
52313
  staging: deps.env.MRRLIN_STAGING === "1",
52622
52314
  apiBaseUrl: deps.env.MRRLIN_API_BASE_URL?.trim() || void 0
52623
52315
  });
52624
- const ecoPath = import_node_path18.default.join(home, ".mrrlin", "ecosystem.config.cjs");
52316
+ const ecoPath = import_node_path17.default.join(home, ".mrrlin", "ecosystem.config.cjs");
52625
52317
  deps.writeFile(ecoPath, text);
52626
52318
  const start = deps.runPm2(["startOrReload", ecoPath]);
52627
52319
  if (start.code !== 0) {
@@ -52652,13 +52344,13 @@ function uninstallService(deps) {
52652
52344
 
52653
52345
  // src/uninstall-codex.ts
52654
52346
  var import_promises4 = __toESM(require("node:fs/promises"), 1);
52655
- var import_node_os12 = __toESM(require("node:os"), 1);
52656
- var import_node_path19 = __toESM(require("node:path"), 1);
52347
+ var import_node_os11 = __toESM(require("node:os"), 1);
52348
+ var import_node_path18 = __toESM(require("node:path"), 1);
52657
52349
  var toml2 = __toESM(require_toml(), 1);
52658
52350
  function resolveCodexHome2(options) {
52659
52351
  if (options.codexHome) return options.codexHome;
52660
52352
  if (process.env.CODEX_HOME) return process.env.CODEX_HOME;
52661
- return import_node_path19.default.join(options.homeDir ?? import_node_os12.default.homedir(), ".codex");
52353
+ return import_node_path18.default.join(options.homeDir ?? import_node_os11.default.homedir(), ".codex");
52662
52354
  }
52663
52355
  async function pathExists3(target) {
52664
52356
  try {
@@ -52671,7 +52363,7 @@ async function pathExists3(target) {
52671
52363
  var MRRLIN_BLOCK_RE = /(^|\n)\[mcp_servers\.mrrlin(?:-browser)?(?:\]|\.[^\]\n]*\])[\s\S]*?(?=\n\[|$)/g;
52672
52364
  async function uninstallCodex(options = {}) {
52673
52365
  const codexHome = resolveCodexHome2(options);
52674
- const configPath = import_node_path19.default.join(codexHome, "config.toml");
52366
+ const configPath = import_node_path18.default.join(codexHome, "config.toml");
52675
52367
  const removePrompts = async () => uninstallPrompts(codexHome, options.promptNames ?? []);
52676
52368
  if (!await pathExists3(configPath)) {
52677
52369
  return { action: "missing", configPath, prompts: await removePrompts() };
@@ -52699,10 +52391,10 @@ async function uninstallCodex(options = {}) {
52699
52391
  }
52700
52392
  async function uninstallPrompts(codexHome, names) {
52701
52393
  if (names.length === 0) return [];
52702
- const promptsDir2 = import_node_path19.default.join(codexHome, "prompts");
52394
+ const promptsDir2 = import_node_path18.default.join(codexHome, "prompts");
52703
52395
  const out = [];
52704
52396
  for (const name of names) {
52705
- const promptPath = import_node_path19.default.join(promptsDir2, `${name}.md`);
52397
+ const promptPath = import_node_path18.default.join(promptsDir2, `${name}.md`);
52706
52398
  try {
52707
52399
  await import_promises4.default.unlink(promptPath);
52708
52400
  out.push({ name, action: "removed", promptPath });
@@ -52719,27 +52411,27 @@ async function uninstallPrompts(codexHome, names) {
52719
52411
  }
52720
52412
 
52721
52413
  // src/report-issue-prompt.ts
52722
- var import_node_fs15 = __toESM(require("node:fs"), 1);
52723
- var import_node_path20 = __toESM(require("node:path"), 1);
52414
+ var import_node_fs14 = __toESM(require("node:fs"), 1);
52415
+ var import_node_path19 = __toESM(require("node:path"), 1);
52724
52416
  var import_node_url3 = require("node:url");
52725
52417
  var import_meta3 = {};
52726
52418
  function promptsDir() {
52727
- if (typeof __dirname !== "undefined") return import_node_path20.default.join(__dirname, "prompts");
52728
- return import_node_path20.default.join(import_node_path20.default.dirname((0, import_node_url3.fileURLToPath)(import_meta3.url)), "prompts");
52419
+ if (typeof __dirname !== "undefined") return import_node_path19.default.join(__dirname, "prompts");
52420
+ return import_node_path19.default.join(import_node_path19.default.dirname((0, import_node_url3.fileURLToPath)(import_meta3.url)), "prompts");
52729
52421
  }
52730
52422
  function readReportIssuePrompt() {
52731
- return import_node_fs15.default.readFileSync(import_node_path20.default.join(promptsDir(), "report-issue.md"), "utf8");
52423
+ return import_node_fs14.default.readFileSync(import_node_path19.default.join(promptsDir(), "report-issue.md"), "utf8");
52732
52424
  }
52733
52425
 
52734
52426
  // src/bin.ts
52735
52427
  function pm2Runner(args) {
52736
- const r = (0, import_node_child_process9.spawnSync)("pm2", args, { encoding: "utf8" });
52428
+ const r = (0, import_node_child_process8.spawnSync)("pm2", args, { encoding: "utf8" });
52737
52429
  process.stderr.write(r.stdout ?? "");
52738
52430
  process.stderr.write(r.stderr ?? "");
52739
52431
  return { code: r.status ?? 1, stdout: r.stdout ?? "" };
52740
52432
  }
52741
52433
  function whichBin(bin) {
52742
- const r = (0, import_node_child_process9.spawnSync)("which", [bin], { encoding: "utf8" });
52434
+ const r = (0, import_node_child_process8.spawnSync)("which", [bin], { encoding: "utf8" });
52743
52435
  const out = (r.stdout ?? "").trim();
52744
52436
  return r.status === 0 && out ? out.split("\n")[0] ?? null : null;
52745
52437
  }
@@ -52905,7 +52597,7 @@ async function main() {
52905
52597
  }
52906
52598
  case "browser-serve": {
52907
52599
  const { command: command2, args, env } = browserServeArgs();
52908
- const r = (0, import_node_child_process9.spawnSync)(command2, args, { stdio: "inherit", env: { ...process.env, ...env } });
52600
+ const r = (0, import_node_child_process8.spawnSync)(command2, args, { stdio: "inherit", env: { ...process.env, ...env } });
52909
52601
  process.exitCode = r.status ?? 1;
52910
52602
  return;
52911
52603
  }
@@ -52973,8 +52665,8 @@ async function main() {
52973
52665
  env: process.env,
52974
52666
  cwd: process.cwd(),
52975
52667
  writeFile: (p, c) => {
52976
- (0, import_node_fs16.mkdirSync)(import_node_path22.default.dirname(p), { recursive: true, mode: 448 });
52977
- (0, import_node_fs16.writeFileSync)(p, c, { mode: 384 });
52668
+ (0, import_node_fs15.mkdirSync)(import_node_path21.default.dirname(p), { recursive: true, mode: 448 });
52669
+ (0, import_node_fs15.writeFileSync)(p, c, { mode: 384 });
52978
52670
  },
52979
52671
  runPm2: pm2Runner,
52980
52672
  which: whichBin,
@@ -52991,35 +52683,35 @@ async function main() {
52991
52683
  runPm2: (a) => ({ code: pm2Runner(a).code }),
52992
52684
  removeFile: (p) => {
52993
52685
  try {
52994
- (0, import_node_fs16.rmSync)(p, { force: true });
52686
+ (0, import_node_fs15.rmSync)(p, { force: true });
52995
52687
  } catch {
52996
52688
  }
52997
52689
  },
52998
52690
  purgeSecret: purge,
52999
52691
  secretPath: agentCredentialPath(),
53000
52692
  tokenPath: operatorTokenPath(),
53001
- ecoPath: import_node_path22.default.join(process.env.HOME ?? (0, import_node_os13.homedir)(), ".mrrlin", "ecosystem.config.cjs"),
52693
+ ecoPath: import_node_path21.default.join(process.env.HOME ?? (0, import_node_os12.homedir)(), ".mrrlin", "ecosystem.config.cjs"),
53002
52694
  log: (m) => process.stderr.write(`[mrrlin-mcp uninstall-service] ${m}
53003
52695
  `)
53004
52696
  });
53005
52697
  return;
53006
52698
  }
53007
52699
  case "uninstall": {
53008
- const home = process.env.HOME ?? (0, import_node_os13.homedir)();
52700
+ const home = process.env.HOME ?? (0, import_node_os12.homedir)();
53009
52701
  const log = (m) => process.stderr.write(`[mrrlin-mcp uninstall] ${m}
53010
52702
  `);
53011
52703
  uninstallService({
53012
52704
  runPm2: (a) => ({ code: pm2Runner(a).code }),
53013
52705
  removeFile: (p) => {
53014
52706
  try {
53015
- (0, import_node_fs16.rmSync)(p, { force: true });
52707
+ (0, import_node_fs15.rmSync)(p, { force: true });
53016
52708
  } catch {
53017
52709
  }
53018
52710
  },
53019
52711
  purgeSecret: true,
53020
52712
  secretPath: agentCredentialPath(),
53021
52713
  tokenPath: operatorTokenPath(),
53022
- ecoPath: import_node_path22.default.join(home, ".mrrlin", "ecosystem.config.cjs"),
52714
+ ecoPath: import_node_path21.default.join(home, ".mrrlin", "ecosystem.config.cjs"),
53023
52715
  log
53024
52716
  });
53025
52717
  let codexOk = true;
@@ -53039,7 +52731,7 @@ async function main() {
53039
52731
  log(`codex config NOT modified: ${error51 instanceof Error ? error51.message : String(error51)}`);
53040
52732
  }
53041
52733
  try {
53042
- (0, import_node_fs16.rmSync)(import_node_path22.default.join(home, ".mrrlin"), { recursive: true, force: true });
52734
+ (0, import_node_fs15.rmSync)(import_node_path21.default.join(home, ".mrrlin"), { recursive: true, force: true });
53043
52735
  } catch {
53044
52736
  }
53045
52737
  log("removed ~/.mrrlin");
@@ -53080,7 +52772,7 @@ ${HELP_TEXT}`);
53080
52772
  }
53081
52773
  }
53082
52774
  function resolveSelfBinPath() {
53083
- return import_node_path21.default.resolve(process.argv[1] ?? process.execPath);
52775
+ return import_node_path20.default.resolve(process.argv[1] ?? process.execPath);
53084
52776
  }
53085
52777
  main().catch((error51) => {
53086
52778
  process.stderr.write(`mrrlin-mcp fatal error: ${error51 instanceof Error ? error51.message : String(error51)}