@mrrlin-dev/mcp 0.4.92 → 0.4.95

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 +1009 -424
  2. package/package.json +5 -4
package/dist/bin.cjs CHANGED
@@ -4230,8 +4230,8 @@ var require_resolve = __commonJS({
4230
4230
  }
4231
4231
  return count2;
4232
4232
  }
4233
- function getFullPath(resolver, id = "", normalize) {
4234
- if (normalize !== false)
4233
+ function getFullPath(resolver, id = "", normalize2) {
4234
+ if (normalize2 !== false)
4235
4235
  id = normalizeId(id);
4236
4236
  const p = resolver.parse(id);
4237
4237
  return _getFullPath(resolver, p);
@@ -5257,8 +5257,8 @@ var require_utils = __commonJS({
5257
5257
  }
5258
5258
  return ind;
5259
5259
  }
5260
- function removeDotSegments(path28) {
5261
- let input = path28;
5260
+ function removeDotSegments(path29) {
5261
+ let input = path29;
5262
5262
  const output3 = [];
5263
5263
  let nextSlash = -1;
5264
5264
  let len = 0;
@@ -5667,8 +5667,8 @@ var require_schemes = __commonJS({
5667
5667
  }
5668
5668
  if (wsComponent.resourceName) {
5669
5669
  const queryIndex = wsComponent.resourceName.indexOf("?");
5670
- const path28 = queryIndex === -1 ? wsComponent.resourceName : wsComponent.resourceName.slice(0, queryIndex);
5671
- wsComponent.path = path28 && path28 !== "/" ? path28 : void 0;
5670
+ const path29 = queryIndex === -1 ? wsComponent.resourceName : wsComponent.resourceName.slice(0, queryIndex);
5671
+ wsComponent.path = path29 && path29 !== "/" ? path29 : void 0;
5672
5672
  wsComponent.query = queryIndex === -1 ? void 0 : wsComponent.resourceName.slice(queryIndex + 1);
5673
5673
  wsComponent.resourceName = void 0;
5674
5674
  }
@@ -5826,7 +5826,7 @@ var require_fast_uri = __commonJS({
5826
5826
  }
5827
5827
  return decodedScheme;
5828
5828
  }
5829
- function normalize(uri, options) {
5829
+ function normalize2(uri, options) {
5830
5830
  if (typeof uri === "string") {
5831
5831
  uri = /** @type {T} */
5832
5832
  normalizeString(uri, options);
@@ -6204,7 +6204,7 @@ var require_fast_uri = __commonJS({
6204
6204
  }
6205
6205
  var fastUri = {
6206
6206
  SCHEMES,
6207
- normalize,
6207
+ normalize: normalize2,
6208
6208
  resolve,
6209
6209
  resolveComponent,
6210
6210
  equal,
@@ -9304,7 +9304,7 @@ var require_windows = __commonJS({
9304
9304
  module2.exports = isexe;
9305
9305
  isexe.sync = sync;
9306
9306
  var fs14 = require("fs");
9307
- function checkPathExt(path28, options) {
9307
+ function checkPathExt(path29, options) {
9308
9308
  var pathext = options.pathExt !== void 0 ? options.pathExt : process.env.PATHEXT;
9309
9309
  if (!pathext) {
9310
9310
  return true;
@@ -9315,25 +9315,25 @@ var require_windows = __commonJS({
9315
9315
  }
9316
9316
  for (var i = 0; i < pathext.length; i++) {
9317
9317
  var p = pathext[i].toLowerCase();
9318
- if (p && path28.substr(-p.length).toLowerCase() === p) {
9318
+ if (p && path29.substr(-p.length).toLowerCase() === p) {
9319
9319
  return true;
9320
9320
  }
9321
9321
  }
9322
9322
  return false;
9323
9323
  }
9324
- function checkStat(stat3, path28, options) {
9324
+ function checkStat(stat3, path29, options) {
9325
9325
  if (!stat3.isSymbolicLink() && !stat3.isFile()) {
9326
9326
  return false;
9327
9327
  }
9328
- return checkPathExt(path28, options);
9328
+ return checkPathExt(path29, options);
9329
9329
  }
9330
- function isexe(path28, options, cb) {
9331
- fs14.stat(path28, function(er, stat3) {
9332
- cb(er, er ? false : checkStat(stat3, path28, options));
9330
+ function isexe(path29, options, cb) {
9331
+ fs14.stat(path29, function(er, stat3) {
9332
+ cb(er, er ? false : checkStat(stat3, path29, options));
9333
9333
  });
9334
9334
  }
9335
- function sync(path28, options) {
9336
- return checkStat(fs14.statSync(path28), path28, options);
9335
+ function sync(path29, options) {
9336
+ return checkStat(fs14.statSync(path29), path29, options);
9337
9337
  }
9338
9338
  }
9339
9339
  });
@@ -9344,13 +9344,13 @@ var require_mode = __commonJS({
9344
9344
  module2.exports = isexe;
9345
9345
  isexe.sync = sync;
9346
9346
  var fs14 = require("fs");
9347
- function isexe(path28, options, cb) {
9348
- fs14.stat(path28, function(er, stat3) {
9347
+ function isexe(path29, options, cb) {
9348
+ fs14.stat(path29, function(er, stat3) {
9349
9349
  cb(er, er ? false : checkStat(stat3, options));
9350
9350
  });
9351
9351
  }
9352
- function sync(path28, options) {
9353
- return checkStat(fs14.statSync(path28), options);
9352
+ function sync(path29, options) {
9353
+ return checkStat(fs14.statSync(path29), options);
9354
9354
  }
9355
9355
  function checkStat(stat3, options) {
9356
9356
  return stat3.isFile() && checkMode(stat3, options);
@@ -9383,7 +9383,7 @@ var require_isexe = __commonJS({
9383
9383
  }
9384
9384
  module2.exports = isexe;
9385
9385
  isexe.sync = sync;
9386
- function isexe(path28, options, cb) {
9386
+ function isexe(path29, options, cb) {
9387
9387
  if (typeof options === "function") {
9388
9388
  cb = options;
9389
9389
  options = {};
@@ -9393,7 +9393,7 @@ var require_isexe = __commonJS({
9393
9393
  throw new TypeError("callback not provided");
9394
9394
  }
9395
9395
  return new Promise(function(resolve, reject) {
9396
- isexe(path28, options || {}, function(er, is) {
9396
+ isexe(path29, options || {}, function(er, is) {
9397
9397
  if (er) {
9398
9398
  reject(er);
9399
9399
  } else {
@@ -9402,7 +9402,7 @@ var require_isexe = __commonJS({
9402
9402
  });
9403
9403
  });
9404
9404
  }
9405
- core(path28, options || {}, function(er, is) {
9405
+ core(path29, options || {}, function(er, is) {
9406
9406
  if (er) {
9407
9407
  if (er.code === "EACCES" || options && options.ignoreErrors) {
9408
9408
  er = null;
@@ -9412,9 +9412,9 @@ var require_isexe = __commonJS({
9412
9412
  cb(er, is);
9413
9413
  });
9414
9414
  }
9415
- function sync(path28, options) {
9415
+ function sync(path29, options) {
9416
9416
  try {
9417
- return core.sync(path28, options || {});
9417
+ return core.sync(path29, options || {});
9418
9418
  } catch (er) {
9419
9419
  if (options && options.ignoreErrors || er.code === "EACCES") {
9420
9420
  return false;
@@ -9430,7 +9430,7 @@ var require_isexe = __commonJS({
9430
9430
  var require_which = __commonJS({
9431
9431
  "../../node_modules/.pnpm/which@2.0.2/node_modules/which/which.js"(exports2, module2) {
9432
9432
  var isWindows = process.platform === "win32" || process.env.OSTYPE === "cygwin" || process.env.OSTYPE === "msys";
9433
- var path28 = require("path");
9433
+ var path29 = require("path");
9434
9434
  var COLON = isWindows ? ";" : ":";
9435
9435
  var isexe = require_isexe();
9436
9436
  var getNotFoundError = (cmd) => Object.assign(new Error(`not found: ${cmd}`), { code: "ENOENT" });
@@ -9468,7 +9468,7 @@ var require_which = __commonJS({
9468
9468
  return opt.all && found.length ? resolve(found) : reject(getNotFoundError(cmd));
9469
9469
  const ppRaw = pathEnv[i];
9470
9470
  const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw;
9471
- const pCmd = path28.join(pathPart, cmd);
9471
+ const pCmd = path29.join(pathPart, cmd);
9472
9472
  const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd;
9473
9473
  resolve(subStep(p, i, 0));
9474
9474
  });
@@ -9495,7 +9495,7 @@ var require_which = __commonJS({
9495
9495
  for (let i = 0; i < pathEnv.length; i++) {
9496
9496
  const ppRaw = pathEnv[i];
9497
9497
  const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw;
9498
- const pCmd = path28.join(pathPart, cmd);
9498
+ const pCmd = path29.join(pathPart, cmd);
9499
9499
  const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd;
9500
9500
  for (let j = 0; j < pathExt.length; j++) {
9501
9501
  const cur = p + pathExt[j];
@@ -9543,7 +9543,7 @@ var require_path_key = __commonJS({
9543
9543
  var require_resolveCommand = __commonJS({
9544
9544
  "../../node_modules/.pnpm/cross-spawn@7.0.6/node_modules/cross-spawn/lib/util/resolveCommand.js"(exports2, module2) {
9545
9545
  "use strict";
9546
- var path28 = require("path");
9546
+ var path29 = require("path");
9547
9547
  var which = require_which();
9548
9548
  var getPathKey = require_path_key();
9549
9549
  function resolveCommandAttempt(parsed, withoutPathExt) {
@@ -9561,7 +9561,7 @@ var require_resolveCommand = __commonJS({
9561
9561
  try {
9562
9562
  resolved = which.sync(parsed.command, {
9563
9563
  path: env[getPathKey({ env })],
9564
- pathExt: withoutPathExt ? path28.delimiter : void 0
9564
+ pathExt: withoutPathExt ? path29.delimiter : void 0
9565
9565
  });
9566
9566
  } catch (e) {
9567
9567
  } finally {
@@ -9570,7 +9570,7 @@ var require_resolveCommand = __commonJS({
9570
9570
  }
9571
9571
  }
9572
9572
  if (resolved) {
9573
- resolved = path28.resolve(hasCustomCwd ? parsed.options.cwd : "", resolved);
9573
+ resolved = path29.resolve(hasCustomCwd ? parsed.options.cwd : "", resolved);
9574
9574
  }
9575
9575
  return resolved;
9576
9576
  }
@@ -9624,8 +9624,8 @@ var require_shebang_command = __commonJS({
9624
9624
  if (!match) {
9625
9625
  return null;
9626
9626
  }
9627
- const [path28, argument] = match[0].replace(/#! ?/, "").split(" ");
9628
- const binary = path28.split("/").pop();
9627
+ const [path29, argument] = match[0].replace(/#! ?/, "").split(" ");
9628
+ const binary = path29.split("/").pop();
9629
9629
  if (binary === "env") {
9630
9630
  return argument;
9631
9631
  }
@@ -9660,7 +9660,7 @@ var require_readShebang = __commonJS({
9660
9660
  var require_parse2 = __commonJS({
9661
9661
  "../../node_modules/.pnpm/cross-spawn@7.0.6/node_modules/cross-spawn/lib/parse.js"(exports2, module2) {
9662
9662
  "use strict";
9663
- var path28 = require("path");
9663
+ var path29 = require("path");
9664
9664
  var resolveCommand = require_resolveCommand();
9665
9665
  var escape2 = require_escape();
9666
9666
  var readShebang = require_readShebang();
@@ -9685,7 +9685,7 @@ var require_parse2 = __commonJS({
9685
9685
  const needsShell = !isExecutableRegExp.test(commandFile);
9686
9686
  if (parsed.options.forceShell || needsShell) {
9687
9687
  const needsDoubleEscapeMetaChars = isCmdShimRegExp.test(commandFile);
9688
- parsed.command = path28.normalize(parsed.command);
9688
+ parsed.command = path29.normalize(parsed.command);
9689
9689
  parsed.command = escape2.command(parsed.command);
9690
9690
  parsed.args = parsed.args.map((arg) => escape2.argument(arg, needsDoubleEscapeMetaChars));
9691
9691
  const shellCommand = [parsed.command].concat(parsed.args).join(" ");
@@ -15499,14 +15499,14 @@ var require_polyfills = __commonJS({
15499
15499
  fs14.fstatSync = statFixSync(fs14.fstatSync);
15500
15500
  fs14.lstatSync = statFixSync(fs14.lstatSync);
15501
15501
  if (fs14.chmod && !fs14.lchmod) {
15502
- fs14.lchmod = function(path28, mode, cb) {
15502
+ fs14.lchmod = function(path29, mode, cb) {
15503
15503
  if (cb) process.nextTick(cb);
15504
15504
  };
15505
15505
  fs14.lchmodSync = function() {
15506
15506
  };
15507
15507
  }
15508
15508
  if (fs14.chown && !fs14.lchown) {
15509
- fs14.lchown = function(path28, uid, gid, cb) {
15509
+ fs14.lchown = function(path29, uid, gid, cb) {
15510
15510
  if (cb) process.nextTick(cb);
15511
15511
  };
15512
15512
  fs14.lchownSync = function() {
@@ -15573,9 +15573,9 @@ var require_polyfills = __commonJS({
15573
15573
  };
15574
15574
  }(fs14.readSync);
15575
15575
  function patchLchmod(fs15) {
15576
- fs15.lchmod = function(path28, mode, callback) {
15576
+ fs15.lchmod = function(path29, mode, callback) {
15577
15577
  fs15.open(
15578
- path28,
15578
+ path29,
15579
15579
  constants2.O_WRONLY | constants2.O_SYMLINK,
15580
15580
  mode,
15581
15581
  function(err, fd) {
@@ -15591,8 +15591,8 @@ var require_polyfills = __commonJS({
15591
15591
  }
15592
15592
  );
15593
15593
  };
15594
- fs15.lchmodSync = function(path28, mode) {
15595
- var fd = fs15.openSync(path28, constants2.O_WRONLY | constants2.O_SYMLINK, mode);
15594
+ fs15.lchmodSync = function(path29, mode) {
15595
+ var fd = fs15.openSync(path29, constants2.O_WRONLY | constants2.O_SYMLINK, mode);
15596
15596
  var threw = true;
15597
15597
  var ret;
15598
15598
  try {
@@ -15613,8 +15613,8 @@ var require_polyfills = __commonJS({
15613
15613
  }
15614
15614
  function patchLutimes(fs15) {
15615
15615
  if (constants2.hasOwnProperty("O_SYMLINK") && fs15.futimes) {
15616
- fs15.lutimes = function(path28, at, mt, cb) {
15617
- fs15.open(path28, constants2.O_SYMLINK, function(er, fd) {
15616
+ fs15.lutimes = function(path29, at, mt, cb) {
15617
+ fs15.open(path29, constants2.O_SYMLINK, function(er, fd) {
15618
15618
  if (er) {
15619
15619
  if (cb) cb(er);
15620
15620
  return;
@@ -15626,8 +15626,8 @@ var require_polyfills = __commonJS({
15626
15626
  });
15627
15627
  });
15628
15628
  };
15629
- fs15.lutimesSync = function(path28, at, mt) {
15630
- var fd = fs15.openSync(path28, constants2.O_SYMLINK);
15629
+ fs15.lutimesSync = function(path29, at, mt) {
15630
+ var fd = fs15.openSync(path29, constants2.O_SYMLINK);
15631
15631
  var ret;
15632
15632
  var threw = true;
15633
15633
  try {
@@ -15745,11 +15745,11 @@ var require_legacy_streams = __commonJS({
15745
15745
  ReadStream,
15746
15746
  WriteStream
15747
15747
  };
15748
- function ReadStream(path28, options) {
15749
- if (!(this instanceof ReadStream)) return new ReadStream(path28, options);
15748
+ function ReadStream(path29, options) {
15749
+ if (!(this instanceof ReadStream)) return new ReadStream(path29, options);
15750
15750
  Stream.call(this);
15751
15751
  var self = this;
15752
- this.path = path28;
15752
+ this.path = path29;
15753
15753
  this.fd = null;
15754
15754
  this.readable = true;
15755
15755
  this.paused = false;
@@ -15794,10 +15794,10 @@ var require_legacy_streams = __commonJS({
15794
15794
  self._read();
15795
15795
  });
15796
15796
  }
15797
- function WriteStream(path28, options) {
15798
- if (!(this instanceof WriteStream)) return new WriteStream(path28, options);
15797
+ function WriteStream(path29, options) {
15798
+ if (!(this instanceof WriteStream)) return new WriteStream(path29, options);
15799
15799
  Stream.call(this);
15800
- this.path = path28;
15800
+ this.path = path29;
15801
15801
  this.fd = null;
15802
15802
  this.writable = true;
15803
15803
  this.flags = "w";
@@ -15940,14 +15940,14 @@ var require_graceful_fs = __commonJS({
15940
15940
  fs15.createWriteStream = createWriteStream;
15941
15941
  var fs$readFile = fs15.readFile;
15942
15942
  fs15.readFile = readFile9;
15943
- function readFile9(path28, options, cb) {
15943
+ function readFile9(path29, options, cb) {
15944
15944
  if (typeof options === "function")
15945
15945
  cb = options, options = null;
15946
- return go$readFile(path28, options, cb);
15947
- function go$readFile(path29, options2, cb2, startTime) {
15948
- return fs$readFile(path29, options2, function(err) {
15946
+ return go$readFile(path29, options, cb);
15947
+ function go$readFile(path30, options2, cb2, startTime) {
15948
+ return fs$readFile(path30, options2, function(err) {
15949
15949
  if (err && (err.code === "EMFILE" || err.code === "ENFILE"))
15950
- enqueue([go$readFile, [path29, options2, cb2], err, startTime || Date.now(), Date.now()]);
15950
+ enqueue([go$readFile, [path30, options2, cb2], err, startTime || Date.now(), Date.now()]);
15951
15951
  else {
15952
15952
  if (typeof cb2 === "function")
15953
15953
  cb2.apply(this, arguments);
@@ -15957,14 +15957,14 @@ var require_graceful_fs = __commonJS({
15957
15957
  }
15958
15958
  var fs$writeFile = fs15.writeFile;
15959
15959
  fs15.writeFile = writeFile5;
15960
- function writeFile5(path28, data, options, cb) {
15960
+ function writeFile5(path29, data, options, cb) {
15961
15961
  if (typeof options === "function")
15962
15962
  cb = options, options = null;
15963
- return go$writeFile(path28, data, options, cb);
15964
- function go$writeFile(path29, data2, options2, cb2, startTime) {
15965
- return fs$writeFile(path29, data2, options2, function(err) {
15963
+ return go$writeFile(path29, data, options, cb);
15964
+ function go$writeFile(path30, data2, options2, cb2, startTime) {
15965
+ return fs$writeFile(path30, data2, options2, function(err) {
15966
15966
  if (err && (err.code === "EMFILE" || err.code === "ENFILE"))
15967
- enqueue([go$writeFile, [path29, data2, options2, cb2], err, startTime || Date.now(), Date.now()]);
15967
+ enqueue([go$writeFile, [path30, data2, options2, cb2], err, startTime || Date.now(), Date.now()]);
15968
15968
  else {
15969
15969
  if (typeof cb2 === "function")
15970
15970
  cb2.apply(this, arguments);
@@ -15975,14 +15975,14 @@ var require_graceful_fs = __commonJS({
15975
15975
  var fs$appendFile = fs15.appendFile;
15976
15976
  if (fs$appendFile)
15977
15977
  fs15.appendFile = appendFile2;
15978
- function appendFile2(path28, data, options, cb) {
15978
+ function appendFile2(path29, data, options, cb) {
15979
15979
  if (typeof options === "function")
15980
15980
  cb = options, options = null;
15981
- return go$appendFile(path28, data, options, cb);
15982
- function go$appendFile(path29, data2, options2, cb2, startTime) {
15983
- return fs$appendFile(path29, data2, options2, function(err) {
15981
+ return go$appendFile(path29, data, options, cb);
15982
+ function go$appendFile(path30, data2, options2, cb2, startTime) {
15983
+ return fs$appendFile(path30, data2, options2, function(err) {
15984
15984
  if (err && (err.code === "EMFILE" || err.code === "ENFILE"))
15985
- enqueue([go$appendFile, [path29, data2, options2, cb2], err, startTime || Date.now(), Date.now()]);
15985
+ enqueue([go$appendFile, [path30, data2, options2, cb2], err, startTime || Date.now(), Date.now()]);
15986
15986
  else {
15987
15987
  if (typeof cb2 === "function")
15988
15988
  cb2.apply(this, arguments);
@@ -16013,31 +16013,31 @@ var require_graceful_fs = __commonJS({
16013
16013
  var fs$readdir = fs15.readdir;
16014
16014
  fs15.readdir = readdir5;
16015
16015
  var noReaddirOptionVersions = /^v[0-5]\./;
16016
- function readdir5(path28, options, cb) {
16016
+ function readdir5(path29, options, cb) {
16017
16017
  if (typeof options === "function")
16018
16018
  cb = options, options = null;
16019
- var go$readdir = noReaddirOptionVersions.test(process.version) ? function go$readdir2(path29, options2, cb2, startTime) {
16020
- return fs$readdir(path29, fs$readdirCallback(
16021
- path29,
16019
+ var go$readdir = noReaddirOptionVersions.test(process.version) ? function go$readdir2(path30, options2, cb2, startTime) {
16020
+ return fs$readdir(path30, fs$readdirCallback(
16021
+ path30,
16022
16022
  options2,
16023
16023
  cb2,
16024
16024
  startTime
16025
16025
  ));
16026
- } : function go$readdir2(path29, options2, cb2, startTime) {
16027
- return fs$readdir(path29, options2, fs$readdirCallback(
16028
- path29,
16026
+ } : function go$readdir2(path30, options2, cb2, startTime) {
16027
+ return fs$readdir(path30, options2, fs$readdirCallback(
16028
+ path30,
16029
16029
  options2,
16030
16030
  cb2,
16031
16031
  startTime
16032
16032
  ));
16033
16033
  };
16034
- return go$readdir(path28, options, cb);
16035
- function fs$readdirCallback(path29, options2, cb2, startTime) {
16034
+ return go$readdir(path29, options, cb);
16035
+ function fs$readdirCallback(path30, options2, cb2, startTime) {
16036
16036
  return function(err, files) {
16037
16037
  if (err && (err.code === "EMFILE" || err.code === "ENFILE"))
16038
16038
  enqueue([
16039
16039
  go$readdir,
16040
- [path29, options2, cb2],
16040
+ [path30, options2, cb2],
16041
16041
  err,
16042
16042
  startTime || Date.now(),
16043
16043
  Date.now()
@@ -16108,7 +16108,7 @@ var require_graceful_fs = __commonJS({
16108
16108
  enumerable: true,
16109
16109
  configurable: true
16110
16110
  });
16111
- function ReadStream(path28, options) {
16111
+ function ReadStream(path29, options) {
16112
16112
  if (this instanceof ReadStream)
16113
16113
  return fs$ReadStream.apply(this, arguments), this;
16114
16114
  else
@@ -16128,7 +16128,7 @@ var require_graceful_fs = __commonJS({
16128
16128
  }
16129
16129
  });
16130
16130
  }
16131
- function WriteStream(path28, options) {
16131
+ function WriteStream(path29, options) {
16132
16132
  if (this instanceof WriteStream)
16133
16133
  return fs$WriteStream.apply(this, arguments), this;
16134
16134
  else
@@ -16146,22 +16146,22 @@ var require_graceful_fs = __commonJS({
16146
16146
  }
16147
16147
  });
16148
16148
  }
16149
- function createReadStream2(path28, options) {
16150
- return new fs15.ReadStream(path28, options);
16149
+ function createReadStream2(path29, options) {
16150
+ return new fs15.ReadStream(path29, options);
16151
16151
  }
16152
- function createWriteStream(path28, options) {
16153
- return new fs15.WriteStream(path28, options);
16152
+ function createWriteStream(path29, options) {
16153
+ return new fs15.WriteStream(path29, options);
16154
16154
  }
16155
16155
  var fs$open = fs15.open;
16156
16156
  fs15.open = open;
16157
- function open(path28, flags, mode, cb) {
16157
+ function open(path29, flags, mode, cb) {
16158
16158
  if (typeof mode === "function")
16159
16159
  cb = mode, mode = null;
16160
- return go$open(path28, flags, mode, cb);
16161
- function go$open(path29, flags2, mode2, cb2, startTime) {
16162
- return fs$open(path29, flags2, mode2, function(err, fd) {
16160
+ return go$open(path29, flags, mode, cb);
16161
+ function go$open(path30, flags2, mode2, cb2, startTime) {
16162
+ return fs$open(path30, flags2, mode2, function(err, fd) {
16163
16163
  if (err && (err.code === "EMFILE" || err.code === "ENFILE"))
16164
- enqueue([go$open, [path29, flags2, mode2, cb2], err, startTime || Date.now(), Date.now()]);
16164
+ enqueue([go$open, [path30, flags2, mode2, cb2], err, startTime || Date.now(), Date.now()]);
16165
16165
  else {
16166
16166
  if (typeof cb2 === "function")
16167
16167
  cb2.apply(this, arguments);
@@ -16690,7 +16690,7 @@ var require_mtime_precision = __commonJS({
16690
16690
  var require_lockfile = __commonJS({
16691
16691
  "../../node_modules/.pnpm/proper-lockfile@4.1.2/node_modules/proper-lockfile/lib/lockfile.js"(exports2, module2) {
16692
16692
  "use strict";
16693
- var path28 = require("path");
16693
+ var path29 = require("path");
16694
16694
  var fs14 = require_graceful_fs();
16695
16695
  var retry = require_retry2();
16696
16696
  var onExit = require_signal_exit();
@@ -16701,7 +16701,7 @@ var require_lockfile = __commonJS({
16701
16701
  }
16702
16702
  function resolveCanonicalPath(file2, options, callback) {
16703
16703
  if (!options.realpath) {
16704
- return callback(null, path28.resolve(file2));
16704
+ return callback(null, path29.resolve(file2));
16705
16705
  }
16706
16706
  options.fs.realpath(file2, callback);
16707
16707
  }
@@ -18565,10 +18565,10 @@ var require_segments = __commonJS({
18565
18565
  const segs = getSegmentsFromString(data, Utils.isKanjiModeEnabled());
18566
18566
  const nodes = buildNodes(segs);
18567
18567
  const graph = buildGraph(nodes, version2);
18568
- const path28 = dijkstra.find_path(graph.map, "start", "end");
18568
+ const path29 = dijkstra.find_path(graph.map, "start", "end");
18569
18569
  const optimizedSegs = [];
18570
- for (let i = 1; i < path28.length - 1; i++) {
18571
- optimizedSegs.push(graph.table[path28[i]].node);
18570
+ for (let i = 1; i < path29.length - 1; i++) {
18571
+ optimizedSegs.push(graph.table[path29[i]].node);
18572
18572
  }
18573
18573
  return exports2.fromArray(mergeSegments(optimizedSegs));
18574
18574
  };
@@ -21045,7 +21045,7 @@ var require_png2 = __commonJS({
21045
21045
  });
21046
21046
  png.pack();
21047
21047
  };
21048
- exports2.renderToFile = function renderToFile(path28, qrData, options, cb) {
21048
+ exports2.renderToFile = function renderToFile(path29, qrData, options, cb) {
21049
21049
  if (typeof cb === "undefined") {
21050
21050
  cb = options;
21051
21051
  options = void 0;
@@ -21056,7 +21056,7 @@ var require_png2 = __commonJS({
21056
21056
  called = true;
21057
21057
  cb.apply(null, args);
21058
21058
  };
21059
- const stream = fs14.createWriteStream(path28);
21059
+ const stream = fs14.createWriteStream(path29);
21060
21060
  stream.on("error", done);
21061
21061
  stream.on("close", done);
21062
21062
  exports2.renderToFileStream(stream, qrData, options);
@@ -21118,14 +21118,14 @@ var require_utf8 = __commonJS({
21118
21118
  }
21119
21119
  return output3;
21120
21120
  };
21121
- exports2.renderToFile = function renderToFile(path28, qrData, options, cb) {
21121
+ exports2.renderToFile = function renderToFile(path29, qrData, options, cb) {
21122
21122
  if (typeof cb === "undefined") {
21123
21123
  cb = options;
21124
21124
  options = void 0;
21125
21125
  }
21126
21126
  const fs14 = require("fs");
21127
21127
  const utf8 = exports2.render(qrData, options);
21128
- fs14.writeFile(path28, utf8, cb);
21128
+ fs14.writeFile(path29, utf8, cb);
21129
21129
  };
21130
21130
  }
21131
21131
  });
@@ -21246,7 +21246,7 @@ var require_svg_tag = __commonJS({
21246
21246
  return str;
21247
21247
  }
21248
21248
  function qrToPath(data, size, margin) {
21249
- let path28 = "";
21249
+ let path29 = "";
21250
21250
  let moveBy = 0;
21251
21251
  let newRow = false;
21252
21252
  let lineLength = 0;
@@ -21257,19 +21257,19 @@ var require_svg_tag = __commonJS({
21257
21257
  if (data[i]) {
21258
21258
  lineLength++;
21259
21259
  if (!(i > 0 && col > 0 && data[i - 1])) {
21260
- path28 += newRow ? svgCmd("M", col + margin, 0.5 + row + margin) : svgCmd("m", moveBy, 0);
21260
+ path29 += newRow ? svgCmd("M", col + margin, 0.5 + row + margin) : svgCmd("m", moveBy, 0);
21261
21261
  moveBy = 0;
21262
21262
  newRow = false;
21263
21263
  }
21264
21264
  if (!(col + 1 < size && data[i + 1])) {
21265
- path28 += svgCmd("h", lineLength);
21265
+ path29 += svgCmd("h", lineLength);
21266
21266
  lineLength = 0;
21267
21267
  }
21268
21268
  } else {
21269
21269
  moveBy++;
21270
21270
  }
21271
21271
  }
21272
- return path28;
21272
+ return path29;
21273
21273
  }
21274
21274
  exports2.render = function render(qrData, options, cb) {
21275
21275
  const opts = Utils.getOptions(options);
@@ -21277,10 +21277,10 @@ var require_svg_tag = __commonJS({
21277
21277
  const data = qrData.modules.data;
21278
21278
  const qrcodesize = size + opts.margin * 2;
21279
21279
  const bg = !opts.color.light.a ? "" : "<path " + getColorAttrib(opts.color.light, "fill") + ' d="M0 0h' + qrcodesize + "v" + qrcodesize + 'H0z"/>';
21280
- const path28 = "<path " + getColorAttrib(opts.color.dark, "stroke") + ' d="' + qrToPath(data, size, opts.margin) + '"/>';
21280
+ const path29 = "<path " + getColorAttrib(opts.color.dark, "stroke") + ' d="' + qrToPath(data, size, opts.margin) + '"/>';
21281
21281
  const viewBox = 'viewBox="0 0 ' + qrcodesize + " " + qrcodesize + '"';
21282
21282
  const width = !opts.width ? "" : 'width="' + opts.width + '" height="' + opts.width + '" ';
21283
- const svgTag = '<svg xmlns="http://www.w3.org/2000/svg" ' + width + viewBox + ' shape-rendering="crispEdges">' + bg + path28 + "</svg>\n";
21283
+ const svgTag = '<svg xmlns="http://www.w3.org/2000/svg" ' + width + viewBox + ' shape-rendering="crispEdges">' + bg + path29 + "</svg>\n";
21284
21284
  if (typeof cb === "function") {
21285
21285
  cb(null, svgTag);
21286
21286
  }
@@ -21294,7 +21294,7 @@ var require_svg = __commonJS({
21294
21294
  "../../node_modules/.pnpm/qrcode@1.5.4/node_modules/qrcode/lib/renderer/svg.js"(exports2) {
21295
21295
  var svgTagRenderer = require_svg_tag();
21296
21296
  exports2.render = svgTagRenderer.render;
21297
- exports2.renderToFile = function renderToFile(path28, qrData, options, cb) {
21297
+ exports2.renderToFile = function renderToFile(path29, qrData, options, cb) {
21298
21298
  if (typeof cb === "undefined") {
21299
21299
  cb = options;
21300
21300
  options = void 0;
@@ -21302,7 +21302,7 @@ var require_svg = __commonJS({
21302
21302
  const fs14 = require("fs");
21303
21303
  const svgTag = exports2.render(qrData, options);
21304
21304
  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;
21305
- fs14.writeFile(path28, xmlStr, cb);
21305
+ fs14.writeFile(path29, xmlStr, cb);
21306
21306
  };
21307
21307
  }
21308
21308
  });
@@ -21460,8 +21460,8 @@ var require_server = __commonJS({
21460
21460
  cb
21461
21461
  };
21462
21462
  }
21463
- function getTypeFromFilename(path28) {
21464
- return path28.slice((path28.lastIndexOf(".") - 1 >>> 0) + 2).toLowerCase();
21463
+ function getTypeFromFilename(path29) {
21464
+ return path29.slice((path29.lastIndexOf(".") - 1 >>> 0) + 2).toLowerCase();
21465
21465
  }
21466
21466
  function getRendererFromType(type) {
21467
21467
  switch (type) {
@@ -21525,17 +21525,17 @@ var require_server = __commonJS({
21525
21525
  const renderer = getRendererFromType(params.opts.type);
21526
21526
  return render(renderer.renderToBuffer, text, params);
21527
21527
  };
21528
- exports2.toFile = function toFile(path28, text, opts, cb) {
21529
- if (typeof path28 !== "string" || !(typeof text === "string" || typeof text === "object")) {
21528
+ exports2.toFile = function toFile(path29, text, opts, cb) {
21529
+ if (typeof path29 !== "string" || !(typeof text === "string" || typeof text === "object")) {
21530
21530
  throw new Error("Invalid argument");
21531
21531
  }
21532
21532
  if (arguments.length < 3 && !canPromise()) {
21533
21533
  throw new Error("Too few arguments provided");
21534
21534
  }
21535
21535
  const params = checkParams(text, opts, cb);
21536
- const type = params.opts.type || getTypeFromFilename(path28);
21536
+ const type = params.opts.type || getTypeFromFilename(path29);
21537
21537
  const renderer = getRendererFromType(type);
21538
- const renderToFile = renderer.renderToFile.bind(null, path28);
21538
+ const renderToFile = renderer.renderToFile.bind(null, path29);
21539
21539
  return render(renderToFile, text, params);
21540
21540
  };
21541
21541
  exports2.toFileStream = function toFileStream(stream, text, opts) {
@@ -21593,7 +21593,7 @@ args = ${JSON.stringify(expected.args)}
21593
21593
  }
21594
21594
  async function installPublicMcpServerToConfigs(serverId, expected) {
21595
21595
  const homeDir = import_node_os16.default.homedir();
21596
- const claudePath = import_node_path36.default.join(homeDir, ".claude.json");
21596
+ const claudePath = import_node_path37.default.join(homeDir, ".claude.json");
21597
21597
  if (await pathExists5(claudePath)) {
21598
21598
  try {
21599
21599
  const content = await import_promises15.default.readFile(claudePath, "utf8");
@@ -21607,7 +21607,7 @@ async function installPublicMcpServerToConfigs(serverId, expected) {
21607
21607
  } else {
21608
21608
  await writeAtomic(claudePath, JSON.stringify({ mcpServers: { [serverId]: expected } }, null, 2) + "\n");
21609
21609
  }
21610
- const codexPath = import_node_path36.default.join(homeDir, ".codex", "config.toml");
21610
+ const codexPath = import_node_path37.default.join(homeDir, ".codex", "config.toml");
21611
21611
  if (await pathExists5(codexPath)) {
21612
21612
  try {
21613
21613
  const content = await import_promises15.default.readFile(codexPath, "utf8");
@@ -21622,11 +21622,11 @@ async function installPublicMcpServerToConfigs(serverId, expected) {
21622
21622
  console.error(`Failed to inject MCP server into ${codexPath}`, e);
21623
21623
  }
21624
21624
  } else {
21625
- await import_promises15.default.mkdir(import_node_path36.default.dirname(codexPath), { recursive: true, mode: 448 }).catch(() => {
21625
+ await import_promises15.default.mkdir(import_node_path37.default.dirname(codexPath), { recursive: true, mode: 448 }).catch(() => {
21626
21626
  });
21627
21627
  await writeAtomic(codexPath, renderTomlBlock(serverId, expected).trim() + "\n");
21628
21628
  }
21629
- const agyPath = import_node_path36.default.join(homeDir, ".gemini", "antigravity", "mcp_config.json");
21629
+ const agyPath = import_node_path37.default.join(homeDir, ".gemini", "antigravity", "mcp_config.json");
21630
21630
  if (await pathExists5(agyPath)) {
21631
21631
  try {
21632
21632
  const content = await import_promises15.default.readFile(agyPath, "utf8");
@@ -21638,28 +21638,28 @@ async function installPublicMcpServerToConfigs(serverId, expected) {
21638
21638
  console.error(`Failed to inject MCP server into ${agyPath}`, e);
21639
21639
  }
21640
21640
  } else {
21641
- await import_promises15.default.mkdir(import_node_path36.default.dirname(agyPath), { recursive: true, mode: 448 }).catch(() => {
21641
+ await import_promises15.default.mkdir(import_node_path37.default.dirname(agyPath), { recursive: true, mode: 448 }).catch(() => {
21642
21642
  });
21643
21643
  await writeAtomic(agyPath, JSON.stringify({ mcpServers: { [serverId]: expected } }, null, 2) + "\n");
21644
21644
  }
21645
21645
  }
21646
- var import_promises15, import_node_os16, import_node_path36, toml4;
21646
+ var import_promises15, import_node_os16, import_node_path37, toml4;
21647
21647
  var init_install_public_mcp = __esm({
21648
21648
  "src/install-public-mcp.ts"() {
21649
21649
  "use strict";
21650
21650
  import_promises15 = __toESM(require("node:fs/promises"), 1);
21651
21651
  import_node_os16 = __toESM(require("node:os"), 1);
21652
- import_node_path36 = __toESM(require("node:path"), 1);
21652
+ import_node_path37 = __toESM(require("node:path"), 1);
21653
21653
  toml4 = __toESM(require_toml(), 1);
21654
21654
  }
21655
21655
  });
21656
21656
 
21657
21657
  // src/bin.ts
21658
- var import_node_path41 = __toESM(require("node:path"), 1);
21659
- var import_node_child_process21 = require("node:child_process");
21658
+ var import_node_path42 = __toESM(require("node:path"), 1);
21659
+ var import_node_child_process22 = require("node:child_process");
21660
21660
  var import_node_fs25 = require("node:fs");
21661
21661
  var import_node_os20 = require("node:os");
21662
- var import_node_path42 = __toESM(require("node:path"), 1);
21662
+ var import_node_path43 = __toESM(require("node:path"), 1);
21663
21663
 
21664
21664
  // src/install-codex.ts
21665
21665
  var import_promises = __toESM(require("node:fs/promises"), 1);
@@ -22314,8 +22314,9 @@ function deriveServeEnvFromProcessEnv(env) {
22314
22314
  }
22315
22315
  function resolveCodexHome(options) {
22316
22316
  if (options.codexHome) return options.codexHome;
22317
+ if (options.homeDir) return import_node_path3.default.join(options.homeDir, ".codex");
22317
22318
  if (process.env.CODEX_HOME) return process.env.CODEX_HOME;
22318
- return import_node_path3.default.join(options.homeDir ?? import_node_os3.default.homedir(), ".codex");
22319
+ return import_node_path3.default.join(import_node_os3.default.homedir(), ".codex");
22319
22320
  }
22320
22321
  function mrrlinTable(binPath, distribution, serveEnv) {
22321
22322
  const base = distribution === "npm" ? { command: "mrrlin-mcp", args: ["serve"] } : { command: "node", args: [binPath, "serve"] };
@@ -22660,12 +22661,12 @@ async function installClaude(options) {
22660
22661
  // src/install-agy.ts
22661
22662
  var import_promises9 = __toESM(require("node:fs/promises"), 1);
22662
22663
  var import_node_os10 = __toESM(require("node:os"), 1);
22663
- var import_node_path17 = __toESM(require("node:path"), 1);
22664
+ var import_node_path18 = __toESM(require("node:path"), 1);
22664
22665
 
22665
22666
  // src/tools.ts
22666
22667
  var import_node_crypto9 = require("node:crypto");
22667
22668
  var import_promises8 = require("node:fs/promises");
22668
- var import_node_path16 = __toESM(require("node:path"), 1);
22669
+ var import_node_path17 = __toESM(require("node:path"), 1);
22669
22670
  var import_node_os9 = __toESM(require("node:os"), 1);
22670
22671
 
22671
22672
  // ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/classic/external.js
@@ -23434,10 +23435,10 @@ function mergeDefs(...defs) {
23434
23435
  function cloneDef(schema) {
23435
23436
  return mergeDefs(schema._zod.def);
23436
23437
  }
23437
- function getElementAtPath(obj, path28) {
23438
- if (!path28)
23438
+ function getElementAtPath(obj, path29) {
23439
+ if (!path29)
23439
23440
  return obj;
23440
- return path28.reduce((acc, key) => acc?.[key], obj);
23441
+ return path29.reduce((acc, key) => acc?.[key], obj);
23441
23442
  }
23442
23443
  function promiseAllObject(promisesObj) {
23443
23444
  const keys = Object.keys(promisesObj);
@@ -23846,11 +23847,11 @@ function explicitlyAborted(x, startIndex = 0) {
23846
23847
  }
23847
23848
  return false;
23848
23849
  }
23849
- function prefixIssues(path28, issues) {
23850
+ function prefixIssues(path29, issues) {
23850
23851
  return issues.map((iss) => {
23851
23852
  var _a3;
23852
23853
  (_a3 = iss).path ?? (_a3.path = []);
23853
- iss.path.unshift(path28);
23854
+ iss.path.unshift(path29);
23854
23855
  return iss;
23855
23856
  });
23856
23857
  }
@@ -23997,16 +23998,16 @@ function flattenError(error51, mapper = (issue2) => issue2.message) {
23997
23998
  }
23998
23999
  function formatError(error51, mapper = (issue2) => issue2.message) {
23999
24000
  const fieldErrors = { _errors: [] };
24000
- const processError = (error52, path28 = []) => {
24001
+ const processError = (error52, path29 = []) => {
24001
24002
  for (const issue2 of error52.issues) {
24002
24003
  if (issue2.code === "invalid_union" && issue2.errors.length) {
24003
- issue2.errors.map((issues) => processError({ issues }, [...path28, ...issue2.path]));
24004
+ issue2.errors.map((issues) => processError({ issues }, [...path29, ...issue2.path]));
24004
24005
  } else if (issue2.code === "invalid_key") {
24005
- processError({ issues: issue2.issues }, [...path28, ...issue2.path]);
24006
+ processError({ issues: issue2.issues }, [...path29, ...issue2.path]);
24006
24007
  } else if (issue2.code === "invalid_element") {
24007
- processError({ issues: issue2.issues }, [...path28, ...issue2.path]);
24008
+ processError({ issues: issue2.issues }, [...path29, ...issue2.path]);
24008
24009
  } else {
24009
- const fullpath = [...path28, ...issue2.path];
24010
+ const fullpath = [...path29, ...issue2.path];
24010
24011
  if (fullpath.length === 0) {
24011
24012
  fieldErrors._errors.push(mapper(issue2));
24012
24013
  } else {
@@ -24033,17 +24034,17 @@ function formatError(error51, mapper = (issue2) => issue2.message) {
24033
24034
  }
24034
24035
  function treeifyError(error51, mapper = (issue2) => issue2.message) {
24035
24036
  const result = { errors: [] };
24036
- const processError = (error52, path28 = []) => {
24037
+ const processError = (error52, path29 = []) => {
24037
24038
  var _a3, _b;
24038
24039
  for (const issue2 of error52.issues) {
24039
24040
  if (issue2.code === "invalid_union" && issue2.errors.length) {
24040
- issue2.errors.map((issues) => processError({ issues }, [...path28, ...issue2.path]));
24041
+ issue2.errors.map((issues) => processError({ issues }, [...path29, ...issue2.path]));
24041
24042
  } else if (issue2.code === "invalid_key") {
24042
- processError({ issues: issue2.issues }, [...path28, ...issue2.path]);
24043
+ processError({ issues: issue2.issues }, [...path29, ...issue2.path]);
24043
24044
  } else if (issue2.code === "invalid_element") {
24044
- processError({ issues: issue2.issues }, [...path28, ...issue2.path]);
24045
+ processError({ issues: issue2.issues }, [...path29, ...issue2.path]);
24045
24046
  } else {
24046
- const fullpath = [...path28, ...issue2.path];
24047
+ const fullpath = [...path29, ...issue2.path];
24047
24048
  if (fullpath.length === 0) {
24048
24049
  result.errors.push(mapper(issue2));
24049
24050
  continue;
@@ -24075,8 +24076,8 @@ function treeifyError(error51, mapper = (issue2) => issue2.message) {
24075
24076
  }
24076
24077
  function toDotPath(_path) {
24077
24078
  const segs = [];
24078
- const path28 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
24079
- for (const seg of path28) {
24079
+ const path29 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
24080
+ for (const seg of path29) {
24080
24081
  if (typeof seg === "number")
24081
24082
  segs.push(`[${seg}]`);
24082
24083
  else if (typeof seg === "symbol")
@@ -36768,13 +36769,13 @@ function resolveRef(ref, ctx) {
36768
36769
  if (!ref.startsWith("#")) {
36769
36770
  throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
36770
36771
  }
36771
- const path28 = ref.slice(1).split("/").filter(Boolean);
36772
- if (path28.length === 0) {
36772
+ const path29 = ref.slice(1).split("/").filter(Boolean);
36773
+ if (path29.length === 0) {
36773
36774
  return ctx.rootSchema;
36774
36775
  }
36775
36776
  const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
36776
- if (path28[0] === defsKey) {
36777
- const key = path28[1];
36777
+ if (path29[0] === defsKey) {
36778
+ const key = path29[1];
36778
36779
  if (!key || !ctx.defs[key]) {
36779
36780
  throw new Error(`Reference not found: ${ref}`);
36780
36781
  }
@@ -38247,6 +38248,8 @@ var mrrlinRunBlockingReasonCodeSchema = external_exports.enum([
38247
38248
  // Slice 9: more than one live address answers for this deliverable, so the receipt cannot name
38248
38249
  // one without guessing. Blocks rather than picking, the same rule `ambiguous_route` follows.
38249
38250
  "publish_address_ambiguous",
38251
+ // workspace-context-isolation (OQ-091): project boundary profile cannot be resolved fail-closed
38252
+ "workspace_boundary_unresolvable",
38250
38253
  "unknown"
38251
38254
  ]);
38252
38255
  var mrrlinExecutionArtifactKindSchema = external_exports.enum([
@@ -38561,7 +38564,11 @@ var mrrlinProjectSummarySchema = external_exports.object({
38561
38564
  unclearCount: external_exports.number().int().nonnegative(),
38562
38565
  judgeVerdictCount: external_exports.number().int().nonnegative()
38563
38566
  }).nullable().optional(),
38564
- ownerEmail: external_exports.string().nullable().optional()
38567
+ ownerEmail: external_exports.string().nullable().optional(),
38568
+ // workspace-context-isolation (OQ-091): explicit client name and scope description
38569
+ // for multi-tenant workspace containment. Output-optional and nullable for backwards compatibility.
38570
+ clientName: external_exports.string().trim().max(80).nullable().optional(),
38571
+ scopeDescription: external_exports.string().trim().max(240).nullable().optional()
38565
38572
  });
38566
38573
  var mrrlinProjectUpsertSchema = mrrlinProjectSummarySchema.omit({
38567
38574
  onboardingKickoffState: true,
@@ -38569,7 +38576,9 @@ var mrrlinProjectUpsertSchema = mrrlinProjectSummarySchema.omit({
38569
38576
  });
38570
38577
  var mrrlinProjectRenameSchema = external_exports.object({
38571
38578
  displayName: external_exports.string().trim().min(1).max(120).optional(),
38572
- intentJudgeEnabled: external_exports.boolean().optional()
38579
+ intentJudgeEnabled: external_exports.boolean().optional(),
38580
+ clientName: external_exports.string().trim().max(80).nullable().optional(),
38581
+ scopeDescription: external_exports.string().trim().max(240).nullable().optional()
38573
38582
  });
38574
38583
  var ONBOARDING_KICKOFF_TRANSITIONS = [
38575
38584
  { from: null, to: "pending" },
@@ -38604,7 +38613,9 @@ var mrrlinProjectSnapshotSchema = external_exports.object({
38604
38613
  defaultDomains: mrrlinTaskDomainsSchema.optional(),
38605
38614
  displayName: external_exports.string().min(1),
38606
38615
  emoji: mrrlinProjectEmojiSchema,
38607
- slug: mrrlinProjectSlugSchema
38616
+ slug: mrrlinProjectSlugSchema,
38617
+ clientName: external_exports.string().trim().max(80).nullable().optional(),
38618
+ scopeDescription: external_exports.string().trim().max(240).nullable().optional()
38608
38619
  }),
38609
38620
  taskDependencies: external_exports.array(mrrlinTaskDependencySchema).default([]),
38610
38621
  taskEvents: external_exports.array(mrrlinTaskEventSchema).default([]),
@@ -39406,6 +39417,7 @@ var mrrlinProjectSchedulerPolicySchema = external_exports.object({
39406
39417
  createdAt: external_exports.string().datetime(),
39407
39418
  // Slice 3 Part E: combined per-UTC-day cap on scheduler-enqueued draft/consensus jobs.
39408
39419
  dailyAutonomousJobBudget: external_exports.number().int().nonnegative(),
39420
+ defaultAutoDeploy: mrrlinAutoDeploySchema,
39409
39421
  eligibleAutonomyLevels: external_exports.array(mrrlinAutonomyLevelSchema).min(1),
39410
39422
  // Slice 3 Part E: cap on concurrently active scheduler-created (ER-SCHED-*) runs.
39411
39423
  maxConcurrentAutonomousRuns: external_exports.number().int().nonnegative(),
@@ -39421,6 +39433,7 @@ var mrrlinProjectSchedulerPolicyUpsertSchema = external_exports.object({
39421
39433
  autoSpecApproval: mrrlinAutoSpecApprovalSchema.optional(),
39422
39434
  cadenceSeconds: external_exports.number().int().positive().nullable().optional(),
39423
39435
  dailyAutonomousJobBudget: external_exports.number().int().nonnegative().optional(),
39436
+ defaultAutoDeploy: mrrlinAutoDeploySchema.optional(),
39424
39437
  eligibleAutonomyLevels: external_exports.array(mrrlinAutonomyLevelSchema).min(1).optional(),
39425
39438
  maxConcurrentAutonomousRuns: external_exports.number().int().nonnegative().optional(),
39426
39439
  prodGraceSeconds: external_exports.number().int().nonnegative().optional(),
@@ -39868,6 +39881,17 @@ var capabilityUseCreateSchema = external_exports.object({
39868
39881
  var deliveryResolutionResponseSchema = external_exports.object({
39869
39882
  data: external_exports.object({ route: CapabilityRouteSchema, verdict: CapabilityGateVerdictSchema })
39870
39883
  });
39884
+ function resolveProjectClientScope(project) {
39885
+ const trimmedClient = project.clientName?.trim();
39886
+ const trimmedDisplay = project.displayName?.trim();
39887
+ const clientName = trimmedClient && trimmedClient.length > 0 ? trimmedClient : trimmedDisplay && trimmedDisplay.length > 0 ? trimmedDisplay : project.slug;
39888
+ const trimmedScope = project.scopeDescription?.trim();
39889
+ const scopeDescription = trimmedScope && trimmedScope.length > 0 ? trimmedScope : null;
39890
+ return {
39891
+ clientName,
39892
+ scopeDescription
39893
+ };
39894
+ }
39871
39895
 
39872
39896
  // ../../packages/client/dist/agent-token-provider.js
39873
39897
  var AgentTokenProviderError = class extends Error {
@@ -39989,18 +40013,18 @@ function createMrrlinClient(config2) {
39989
40013
  const customFetch = config2.fetch ?? globalThis.fetch;
39990
40014
  const baseUrl = config2.baseUrl.replace(/\/$/, "");
39991
40015
  const token = config2.token;
39992
- async function request(path28, init) {
40016
+ async function request(path29, init) {
39993
40017
  const method = init?.method ?? "GET";
39994
40018
  const headers = new Headers(init?.headers ?? {});
39995
40019
  if (token && !headers.has("authorization")) {
39996
40020
  headers.set("authorization", `Bearer ${token}`);
39997
40021
  }
39998
- const response = await customFetch(`${baseUrl}${path28}`, { ...init, headers });
40022
+ const response = await customFetch(`${baseUrl}${path29}`, { ...init, headers });
39999
40023
  if (!response.ok) {
40000
40024
  const body = await response.text();
40001
40025
  let code = `HTTP_${response.status}`;
40002
40026
  let violations = null;
40003
- let message = `Mrrlin API ${method} ${path28} failed: ${response.status}`;
40027
+ let message = `Mrrlin API ${method} ${path29} failed: ${response.status}`;
40004
40028
  try {
40005
40029
  const parsed = JSON.parse(body);
40006
40030
  const violationsParsed = apiViolationsErrorSchema.safeParse(parsed);
@@ -40020,7 +40044,7 @@ function createMrrlinClient(config2) {
40020
40044
  throw new MrrlinApiError({
40021
40045
  code,
40022
40046
  method,
40023
- path: path28,
40047
+ path: path29,
40024
40048
  responseBody: body,
40025
40049
  status: response.status,
40026
40050
  violations,
@@ -40029,18 +40053,18 @@ function createMrrlinClient(config2) {
40029
40053
  }
40030
40054
  return response.json();
40031
40055
  }
40032
- async function requestText(path28, init) {
40056
+ async function requestText(path29, init) {
40033
40057
  const method = init?.method ?? "GET";
40034
40058
  const headers = new Headers(init?.headers ?? {});
40035
40059
  if (token && !headers.has("authorization")) {
40036
40060
  headers.set("authorization", `Bearer ${token}`);
40037
40061
  }
40038
- const response = await customFetch(`${baseUrl}${path28}`, { ...init, headers });
40062
+ const response = await customFetch(`${baseUrl}${path29}`, { ...init, headers });
40039
40063
  if (!response.ok) {
40040
40064
  const body = await response.text();
40041
40065
  let code = `HTTP_${response.status}`;
40042
40066
  let violations = null;
40043
- let message = `Mrrlin API ${method} ${path28} failed: ${response.status}`;
40067
+ let message = `Mrrlin API ${method} ${path29} failed: ${response.status}`;
40044
40068
  try {
40045
40069
  const parsed = JSON.parse(body);
40046
40070
  const violationsParsed = apiViolationsErrorSchema.safeParse(parsed);
@@ -40060,7 +40084,7 @@ function createMrrlinClient(config2) {
40060
40084
  throw new MrrlinApiError({
40061
40085
  code,
40062
40086
  method,
40063
- path: path28,
40087
+ path: path29,
40064
40088
  responseBody: body,
40065
40089
  status: response.status,
40066
40090
  violations,
@@ -40228,16 +40252,16 @@ function createMrrlinClient(config2) {
40228
40252
  // rejected against the first, MrrlinTask[]-only overload) -- the `any` here is contained to
40229
40253
  // this one implementation signature; MrrlinClient's declared overloads keep callers precise.
40230
40254
  async listTasks(projectSlug, filters = {}, options) {
40231
- const path28 = buildTaskListPath(projectSlug, filters, options?.view);
40232
- const body = await request(path28);
40255
+ const path29 = buildTaskListPath(projectSlug, filters, options?.view);
40256
+ const body = await request(path29);
40233
40257
  if (options?.view === "summary") {
40234
40258
  return taskSummaryListResponseSchema.parse(body).data;
40235
40259
  }
40236
40260
  return taskListResponseSchema.parse(body).data;
40237
40261
  },
40238
40262
  async listTaskSummaries(projectSlug, filters = {}) {
40239
- const path28 = buildTaskListPath(projectSlug, filters, "summary");
40240
- const body = await request(path28);
40263
+ const path29 = buildTaskListPath(projectSlug, filters, "summary");
40264
+ const body = await request(path29);
40241
40265
  return taskSummaryListResponseSchema.parse(body).data;
40242
40266
  },
40243
40267
  async listTaxonomy(projectSlug) {
@@ -40245,22 +40269,22 @@ function createMrrlinClient(config2) {
40245
40269
  return taxonomyListResponseSchema.parse(body).data;
40246
40270
  },
40247
40271
  async listWikiPages(projectSlug, filters = {}) {
40248
- const path28 = appendQuery(`${projectPath(projectSlug)}/wiki`, {
40272
+ const path29 = appendQuery(`${projectPath(projectSlug)}/wiki`, {
40249
40273
  folder: filters.folder,
40250
40274
  q: filters.q,
40251
40275
  taskId: filters.taskId
40252
40276
  });
40253
- const body = await request(path28);
40277
+ const body = await request(path29);
40254
40278
  return wikiPageListResponseSchema.parse(body).data;
40255
40279
  },
40256
40280
  async searchWikiPages(projectSlug, query) {
40257
- const path28 = appendQuery(`${projectPath(projectSlug)}/wiki/search`, {
40281
+ const path29 = appendQuery(`${projectPath(projectSlug)}/wiki/search`, {
40258
40282
  folder: query.folder,
40259
40283
  limit: query.limit === void 0 ? void 0 : String(query.limit),
40260
40284
  pathPrefix: query.pathPrefix,
40261
40285
  q: query.q
40262
40286
  });
40263
- const body = await request(path28);
40287
+ const body = await request(path29);
40264
40288
  return wikiPageSearchResponseSchema.parse(body).data;
40265
40289
  },
40266
40290
  async updatePlan(projectSlug, planId, patch) {
@@ -42663,8 +42687,23 @@ var CodexBridgeEventMapper = class {
42663
42687
  // ../../packages/agent-client/dist/providers/codex/render-context-bundle.js
42664
42688
  var DEFAULT_SPEC_BUDGET_CHARS = 6e3;
42665
42689
  var DEFAULT_ARTIFACT_PAYLOAD_BUDGET_CHARS = 400;
42690
+ function renderWorkspaceBoundary(project) {
42691
+ if (!project)
42692
+ return "";
42693
+ const clientName = (project.clientName || project.displayName || "(unspecified)").slice(0, 35);
42694
+ const slug = project.slug.slice(0, 25);
42695
+ const boundary = [
42696
+ "## Workspace Boundary",
42697
+ `Client: ${clientName} (${slug})`,
42698
+ "Strict isolation: cross-client borrowing forbidden."
42699
+ ].join("\n");
42700
+ return boundary.length > 150 ? boundary.slice(0, 150) : boundary;
42701
+ }
42666
42702
  function renderContextBundle(input) {
42667
42703
  const sections = [];
42704
+ if (input.project) {
42705
+ sections.push(renderWorkspaceBoundary(input.project));
42706
+ }
42668
42707
  sections.push(renderTaskSummary(input.task));
42669
42708
  sections.push(renderSpec(input.specMarkdown, input.compact));
42670
42709
  const { keptRuns, keptArtifacts, keptAutonomy, anyHistoricalDropped, droppedHandles } = applyHistoricalBudgetIfNeeded(input);
@@ -43757,8 +43796,11 @@ var AgyBridgeEventMapper = class {
43757
43796
  return [];
43758
43797
  }
43759
43798
  if (step.step_type === "error_message") {
43760
- const message = typeof step.error === "string" ? step.error : typeof step.message === "string" ? step.message : "AGY step error";
43761
- return [{ type: "error", content: message }];
43799
+ const message = typeof step.error === "string" && step.error.trim() || typeof step.message === "string" && step.message.trim() || typeof step.text === "string" && step.text.trim() || typeof step.detail === "string" && step.detail.trim() || typeof step.details === "string" && step.details.trim() || "";
43800
+ if (message) {
43801
+ return [{ type: "error", content: message }];
43802
+ }
43803
+ return [];
43762
43804
  }
43763
43805
  return [];
43764
43806
  }
@@ -44166,9 +44208,15 @@ ${input.prompt}` : input.prompt;
44166
44208
  env: process.env,
44167
44209
  shell: false
44168
44210
  };
44211
+ let spawnCmd = executable;
44212
+ let spawnArgs = args;
44213
+ if (process.platform === "win32" && /\.[mc]?[jt]s$/.test(executable)) {
44214
+ spawnCmd = process.execPath;
44215
+ spawnArgs = [executable, ...args];
44216
+ }
44169
44217
  let child;
44170
44218
  try {
44171
- child = spawn6(executable, args, options);
44219
+ child = spawn6(spawnCmd, spawnArgs, options);
44172
44220
  } catch (err) {
44173
44221
  finish({ ok: false, error: `Failed to spawn codex exec: ${errMessage(err)}` });
44174
44222
  return;
@@ -44247,9 +44295,15 @@ function runClaudeExec(input, deps) {
44247
44295
  env: process.env,
44248
44296
  shell: false
44249
44297
  };
44298
+ let spawnCmd = executable;
44299
+ let spawnArgs = args;
44300
+ if (process.platform === "win32" && /\.[mc]?[jt]s$/.test(executable)) {
44301
+ spawnCmd = process.execPath;
44302
+ spawnArgs = [executable, ...args];
44303
+ }
44250
44304
  let child;
44251
44305
  try {
44252
- child = spawn6(executable, args, options);
44306
+ child = spawn6(spawnCmd, spawnArgs, options);
44253
44307
  } catch (err) {
44254
44308
  finish({ ok: false, error: `Failed to spawn ${executable} exec: ${errMessage2(err)}` });
44255
44309
  return;
@@ -44314,6 +44368,104 @@ function errMessage2(err) {
44314
44368
  return err instanceof Error ? err.message : String(err);
44315
44369
  }
44316
44370
 
44371
+ // ../../packages/agent-client/dist/providers/agy/exec.js
44372
+ var import_node_child_process8 = require("node:child_process");
44373
+ function runAgyExec(input, deps) {
44374
+ const spawn6 = deps?.spawn ?? import_node_child_process8.spawn;
44375
+ const executable = input.codexExecutable ?? "agy";
44376
+ const args = ["--output-format", "json"];
44377
+ if (input.sandbox === "read-only") {
44378
+ args.push("--mode", "plan");
44379
+ } else if (input.sandbox === "workspace-write") {
44380
+ args.push("--mode", "accept-edits");
44381
+ }
44382
+ let prompt = input.prompt;
44383
+ const trimmedInstructions = input.developerInstructions.trim();
44384
+ if (trimmedInstructions) {
44385
+ prompt = trimmedInstructions + "\n\n" + prompt;
44386
+ }
44387
+ if (input.model) {
44388
+ args.push("--model", input.model);
44389
+ }
44390
+ args.push(`--print=${prompt}`);
44391
+ return new Promise((resolve) => {
44392
+ let settled = false;
44393
+ const timerRef = { id: void 0 };
44394
+ const finish = (result) => {
44395
+ if (settled)
44396
+ return;
44397
+ settled = true;
44398
+ if (timerRef.id)
44399
+ clearTimeout(timerRef.id);
44400
+ resolve(result);
44401
+ };
44402
+ const options = {
44403
+ stdio: ["ignore", "pipe", "pipe"],
44404
+ cwd: input.cwd,
44405
+ env: process.env,
44406
+ shell: false
44407
+ };
44408
+ let spawnCmd = executable;
44409
+ let spawnArgs = args;
44410
+ if (process.platform === "win32" && /\.[mc]?[jt]s$/.test(executable)) {
44411
+ spawnCmd = process.execPath;
44412
+ spawnArgs = [executable, ...args];
44413
+ }
44414
+ let child;
44415
+ try {
44416
+ child = spawn6(spawnCmd, spawnArgs, options);
44417
+ } catch (err) {
44418
+ finish({ ok: false, error: `Failed to spawn ${executable} exec: ${err instanceof Error ? err.message : String(err)}` });
44419
+ return;
44420
+ }
44421
+ let stdout = "";
44422
+ let timedOut = false;
44423
+ timerRef.id = setTimeout(() => {
44424
+ timedOut = true;
44425
+ child.kill("SIGKILL");
44426
+ finish({ ok: false, error: `${executable} exec timed out after ${input.timeoutMs}ms` });
44427
+ }, input.timeoutMs);
44428
+ child.stdout?.on("data", (chunk) => {
44429
+ stdout += chunk.toString();
44430
+ });
44431
+ child.stderr?.on("data", () => {
44432
+ });
44433
+ child.on("error", (err) => {
44434
+ finish({ ok: false, error: `${executable} exec process error: ${err.message}` });
44435
+ });
44436
+ child.on("close", (code) => {
44437
+ if (timedOut)
44438
+ return;
44439
+ if (code !== 0) {
44440
+ finish({ ok: false, error: `${executable} exec exited with code ${code ?? "null"}` });
44441
+ return;
44442
+ }
44443
+ finish(extractOneShotResult2(stdout));
44444
+ });
44445
+ });
44446
+ }
44447
+ function extractOneShotResult2(stdout) {
44448
+ let parsed;
44449
+ try {
44450
+ parsed = JSON.parse(stdout);
44451
+ } catch {
44452
+ return { ok: false, error: "agy exec produced no parseable JSON output" };
44453
+ }
44454
+ if (parsed.status !== "SUCCESS" || typeof parsed.response !== "string") {
44455
+ return { ok: false, error: `agy exec failed or returned invalid response format: ${JSON.stringify(parsed)}` };
44456
+ }
44457
+ return {
44458
+ ok: true,
44459
+ text: parsed.response,
44460
+ usage: {
44461
+ inputTokens: parsed.usage?.input_tokens ?? 0,
44462
+ outputTokens: parsed.usage?.output_tokens ?? 0,
44463
+ cachedInputTokens: parsed.usage?.cache_read_tokens ?? 0,
44464
+ cacheWriteInputTokens: 0
44465
+ }
44466
+ };
44467
+ }
44468
+
44317
44469
  // ../../packages/agent-client/dist/run-agent-exec.js
44318
44470
  function runAgentExec(input, deps, persistedProvider) {
44319
44471
  const provider = resolveProvider(process.env, persistedProvider);
@@ -44323,6 +44475,9 @@ function runAgentExec(input, deps, persistedProvider) {
44323
44475
  if (provider.id === "claude") {
44324
44476
  return runClaudeExec(input, deps);
44325
44477
  }
44478
+ if (provider.id === "agy") {
44479
+ return runAgyExec(input, deps);
44480
+ }
44326
44481
  throw new Error(`not-yet-wired: ${provider.id}`);
44327
44482
  }
44328
44483
 
@@ -44566,7 +44721,7 @@ function sterileCwd() {
44566
44721
  }
44567
44722
 
44568
44723
  // src/consensus/code-gate-git.ts
44569
- var import_node_child_process8 = require("node:child_process");
44724
+ var import_node_child_process9 = require("node:child_process");
44570
44725
  var DIFF_MAX_BYTES = 2e5;
44571
44726
  var FASTGATE_OUTPUT_MAX_BYTES = 16e3;
44572
44727
  var GIT_TIMEOUT_MS = 6e4;
@@ -44582,7 +44737,7 @@ var defaultRunCmd = (cmd, args, opts) => new Promise((resolve) => {
44582
44737
  };
44583
44738
  let child;
44584
44739
  try {
44585
- child = (0, import_node_child_process8.spawn)(cmd, args, {
44740
+ child = (0, import_node_child_process9.spawn)(cmd, args, {
44586
44741
  cwd: opts.cwd,
44587
44742
  env: process.env,
44588
44743
  shell: false,
@@ -45391,7 +45546,7 @@ You revise a deliverable to address the accepted issues so it satisfies the acce
45391
45546
  }
45392
45547
 
45393
45548
  // src/consensus/multi-llm-head.ts
45394
- var import_node_child_process10 = require("node:child_process");
45549
+ var import_node_child_process11 = require("node:child_process");
45395
45550
 
45396
45551
  // src/external-agents-bin.ts
45397
45552
  function resolveExternalAgentsCliInvocation(override) {
@@ -45407,7 +45562,7 @@ function resolveExternalAgentsCliInvocation(override) {
45407
45562
  }
45408
45563
 
45409
45564
  // src/consensus/provider-limits.ts
45410
- var import_node_child_process9 = require("node:child_process");
45565
+ var import_node_child_process10 = require("node:child_process");
45411
45566
  var DEFAULT_STATUS_TIMEOUT_MS = 1e4;
45412
45567
  function errMessage3(err) {
45413
45568
  return err instanceof Error ? err.message : String(err);
@@ -45449,7 +45604,7 @@ function runExternalAgentsStatus(bin, args, timeoutMs, spawn6) {
45449
45604
  });
45450
45605
  }
45451
45606
  async function fetchRegistrySnapshot(deps) {
45452
- const spawn6 = deps?.spawn ?? import_node_child_process9.spawn;
45607
+ const spawn6 = deps?.spawn ?? import_node_child_process10.spawn;
45453
45608
  const { command, prefixArgs } = resolveExternalAgentsCliInvocation(deps?.externalAgentsBin);
45454
45609
  const { stdout, error: error51 } = await runExternalAgentsStatus(
45455
45610
  command,
@@ -45537,7 +45692,7 @@ function runExternalAgents(bin, args, label, timeoutMs, spawn6) {
45537
45692
  });
45538
45693
  }
45539
45694
  async function pickPanel(input, deps) {
45540
- const spawn6 = deps?.spawn ?? import_node_child_process10.spawn;
45695
+ const spawn6 = deps?.spawn ?? import_node_child_process11.spawn;
45541
45696
  const { command, prefixArgs } = resolveExternalAgentsCliInvocation(deps?.externalAgentsBin);
45542
45697
  const args = [
45543
45698
  "pick",
@@ -45584,7 +45739,7 @@ function parseDispatch(agentId, stdout, exitCode) {
45584
45739
  return { ok: true, text: parsed.text, usage };
45585
45740
  }
45586
45741
  async function dispatchHead(agentId, prompt, timeoutMs, deps) {
45587
- const spawn6 = deps?.spawn ?? import_node_child_process10.spawn;
45742
+ const spawn6 = deps?.spawn ?? import_node_child_process11.spawn;
45588
45743
  const { command, prefixArgs } = resolveExternalAgentsCliInvocation(deps?.externalAgentsBin);
45589
45744
  const args = ["dispatch", agentId, "--json", prompt];
45590
45745
  const r = await runExternalAgents(command, [...prefixArgs, ...args], "dispatch", timeoutMs, spawn6);
@@ -53804,8 +53959,8 @@ async function findSessionDays(stateDir, sessionId) {
53804
53959
  function isRecord5(v) {
53805
53960
  return v !== null && typeof v === "object";
53806
53961
  }
53807
- function resolvePath(root, path28) {
53808
- const parts = path28.split(".");
53962
+ function resolvePath(root, path29) {
53963
+ const parts = path29.split(".");
53809
53964
  let cur = root;
53810
53965
  for (let i = 0; i < parts.length - 1; i += 1) {
53811
53966
  const part = parts[i];
@@ -53873,9 +54028,9 @@ async function gate(artifact, prose, ctx) {
53873
54028
  return { ok: true, gated: true, artifact: withheldExcerptClone(artifact) };
53874
54029
  }
53875
54030
  const maskedClone = typeof structuredClone === "function" ? structuredClone(artifact) : JSON.parse(JSON.stringify(artifact));
53876
- for (const { path: path28, masked } of fields) {
53877
- const target = resolvePath(maskedClone, path28);
53878
- if (!target) throw new Error(`pii-gate: path "${path28}" failed to resolve on the clone after validating on the original`);
54031
+ for (const { path: path29, masked } of fields) {
54032
+ const target = resolvePath(maskedClone, path29);
54033
+ if (!target) throw new Error(`pii-gate: path "${path29}" failed to resolve on the clone after validating on the original`);
53879
54034
  target.parent[target.key] = masked;
53880
54035
  }
53881
54036
  return { ok: true, gated: false, artifact: maskedClone };
@@ -54082,9 +54237,9 @@ var CheckoutRegistry = class {
54082
54237
  get(slug) {
54083
54238
  return this.read()[slug] ?? null;
54084
54239
  }
54085
- confirm(slug, path28, now) {
54240
+ confirm(slug, path29, now) {
54086
54241
  const all = this.read();
54087
- all[slug] = { path: path28, confirmedAt: now };
54242
+ all[slug] = { path: path29, confirmedAt: now };
54088
54243
  (0, import_node_fs6.writeFileSync)(this.file, JSON.stringify(all, null, 2));
54089
54244
  }
54090
54245
  /**
@@ -54125,8 +54280,9 @@ var CheckoutRegistry = class {
54125
54280
  };
54126
54281
 
54127
54282
  // src/checkout-handlers.ts
54128
- var import_node_child_process11 = require("node:child_process");
54283
+ var import_node_child_process12 = require("node:child_process");
54129
54284
  var import_node_fs7 = require("node:fs");
54285
+ var import_node_path14 = __toESM(require("node:path"), 1);
54130
54286
 
54131
54287
  // src/git-remote-match.ts
54132
54288
  function normalizeRemote(url2) {
@@ -54152,7 +54308,7 @@ function remoteMatchesRepo(remoteUrl, repoFullName) {
54152
54308
  // src/checkout-handlers.ts
54153
54309
  function validateCheckoutPath(checkoutPath, repo) {
54154
54310
  const trimmedPath = checkoutPath.trim();
54155
- if (!trimmedPath.startsWith("/")) {
54311
+ if (!import_node_path14.default.isAbsolute(trimmedPath)) {
54156
54312
  return {
54157
54313
  ok: false,
54158
54314
  code: "not_absolute",
@@ -54161,7 +54317,7 @@ function validateCheckoutPath(checkoutPath, repo) {
54161
54317
  }
54162
54318
  let resolvedPath;
54163
54319
  try {
54164
- resolvedPath = (0, import_node_fs7.realpathSync)(trimmedPath);
54320
+ resolvedPath = (import_node_fs7.realpathSync.native ?? import_node_fs7.realpathSync)(trimmedPath);
54165
54321
  } catch {
54166
54322
  return {
54167
54323
  ok: false,
@@ -54171,7 +54327,7 @@ function validateCheckoutPath(checkoutPath, repo) {
54171
54327
  }
54172
54328
  let remoteUrl;
54173
54329
  try {
54174
- remoteUrl = (0, import_node_child_process11.execFileSync)("git", ["-C", resolvedPath, "remote", "get-url", "origin"], {
54330
+ remoteUrl = (0, import_node_child_process12.execFileSync)("git", ["-C", resolvedPath, "remote", "get-url", "origin"], {
54175
54331
  encoding: "utf8",
54176
54332
  stdio: ["ignore", "pipe", "ignore"],
54177
54333
  timeout: 15e3,
@@ -54224,13 +54380,13 @@ function checkoutStateData(projectSlug, entry, machineLabel) {
54224
54380
  // src/operator-token.ts
54225
54381
  var import_node_fs8 = require("node:fs");
54226
54382
  var import_node_os7 = __toESM(require("node:os"), 1);
54227
- var import_node_path14 = __toESM(require("node:path"), 1);
54383
+ var import_node_path15 = __toESM(require("node:path"), 1);
54228
54384
  function operatorDir() {
54229
- const base = process.env.CODEX_HOME ? import_node_path14.default.join(process.env.CODEX_HOME, "mrrlin") : import_node_path14.default.join(import_node_os7.default.homedir(), ".mrrlin");
54385
+ const base = process.env.CODEX_HOME ? import_node_path15.default.join(process.env.CODEX_HOME, "mrrlin") : import_node_path15.default.join(import_node_os7.default.homedir(), ".mrrlin");
54230
54386
  return base;
54231
54387
  }
54232
54388
  function operatorTokenPath() {
54233
- return import_node_path14.default.join(operatorDir(), "operator-token");
54389
+ return import_node_path15.default.join(operatorDir(), "operator-token");
54234
54390
  }
54235
54391
  function readOperatorToken() {
54236
54392
  try {
@@ -54247,7 +54403,7 @@ function persistOperatorToken(token) {
54247
54403
  `, { encoding: "utf8", mode: 384 });
54248
54404
  }
54249
54405
  function agentCredentialPath() {
54250
- return import_node_path14.default.join(operatorDir(), "agent-credential");
54406
+ return import_node_path15.default.join(operatorDir(), "agent-credential");
54251
54407
  }
54252
54408
  function persistAgentSecret(secret) {
54253
54409
  const dir = operatorDir();
@@ -54270,7 +54426,7 @@ function readAgentSecret() {
54270
54426
  var import_node_crypto8 = require("node:crypto");
54271
54427
  var import_node_fs9 = require("node:fs");
54272
54428
  var import_node_os8 = __toESM(require("node:os"), 1);
54273
- var import_node_path15 = __toESM(require("node:path"), 1);
54429
+ var import_node_path16 = __toESM(require("node:path"), 1);
54274
54430
  var DEFAULT_WORKER_PORT = 8792;
54275
54431
  function workerPort() {
54276
54432
  const raw = process.env.MRRLIN_WORKER_PORT;
@@ -54279,11 +54435,11 @@ function workerPort() {
54279
54435
  return Number.isFinite(parsed) && parsed > 0 ? parsed : DEFAULT_WORKER_PORT;
54280
54436
  }
54281
54437
  function workerDir() {
54282
- const base = process.env.CODEX_HOME ? import_node_path15.default.join(process.env.CODEX_HOME, "mrrlin") : import_node_path15.default.join(import_node_os8.default.homedir(), ".mrrlin");
54283
- return import_node_path15.default.join(base, "worker");
54438
+ const base = process.env.CODEX_HOME ? import_node_path16.default.join(process.env.CODEX_HOME, "mrrlin") : import_node_path16.default.join(import_node_os8.default.homedir(), ".mrrlin");
54439
+ return import_node_path16.default.join(base, "worker");
54284
54440
  }
54285
54441
  function workerTokenPath() {
54286
- return import_node_path15.default.join(workerDir(), "token");
54442
+ return import_node_path16.default.join(workerDir(), "token");
54287
54443
  }
54288
54444
  function readWorkerToken() {
54289
54445
  try {
@@ -55435,76 +55591,136 @@ async function getAgentProviderForPanel(client, opts = {}) {
55435
55591
  }
55436
55592
  function createMrrlinTools(options) {
55437
55593
  const client = createMrrlinClient(withAuth(options));
55594
+ let boundSlug = options.activeProjectSlug ?? (process.env.MRRLIN_PROJECT_SLUG?.trim() || void 0);
55595
+ let sessionResolved = false;
55596
+ async function resolveBoundSlug() {
55597
+ if (boundSlug !== void 0) return boundSlug;
55598
+ if (sessionResolved) return boundSlug;
55599
+ try {
55600
+ const settings = await client.getOperatorSettings();
55601
+ if (settings?.activeProjectSlug) {
55602
+ boundSlug = settings.activeProjectSlug;
55603
+ }
55604
+ } catch {
55605
+ }
55606
+ sessionResolved = true;
55607
+ return boundSlug;
55608
+ }
55609
+ async function checkTenantBoundary(targetSlug, resourceName) {
55610
+ const active = await resolveBoundSlug();
55611
+ if (!active) {
55612
+ throw new McpToolCodedError(
55613
+ "TENANT_BOUNDARY_VIOLATION",
55614
+ `Tenant boundary violation: no active workspace bound; cannot access ${resourceName} of project "${targetSlug}".`
55615
+ );
55616
+ }
55617
+ if (active !== targetSlug) {
55618
+ throw new McpToolCodedError(
55619
+ "TENANT_BOUNDARY_VIOLATION",
55620
+ `Tenant boundary violation: active workspace "${active}" cannot access ${resourceName} of project "${targetSlug}".`
55621
+ );
55622
+ }
55623
+ }
55438
55624
  return {
55439
55625
  [mcpToolNames.archivePlan]: makeTool(
55440
55626
  client,
55441
55627
  mcpToolNames.archivePlan,
55442
55628
  "PLAN_ARCHIVE_FAILED",
55443
55629
  "Unable to archive plan.",
55444
- async (c, { projectSlug, planId }) => await c.updatePlan(projectSlug, planId, { status: "archived" })
55630
+ async (c, { projectSlug, planId }) => {
55631
+ await checkTenantBoundary(projectSlug, "plan");
55632
+ return await c.updatePlan(projectSlug, planId, { status: "archived" });
55633
+ }
55445
55634
  ),
55446
55635
  [mcpToolNames.createPlan]: makeTool(
55447
55636
  client,
55448
55637
  mcpToolNames.createPlan,
55449
55638
  "PLAN_CREATE_FAILED",
55450
55639
  "Unable to create plan.",
55451
- async (c, { projectSlug, ...input }) => await c.createPlan(projectSlug, input)
55640
+ async (c, { projectSlug, ...input }) => {
55641
+ await checkTenantBoundary(projectSlug, "plan");
55642
+ return await c.createPlan(projectSlug, input);
55643
+ }
55452
55644
  ),
55453
55645
  [mcpToolNames.createTaskDependency]: makeTool(
55454
55646
  client,
55455
55647
  mcpToolNames.createTaskDependency,
55456
55648
  "TASK_DEPENDENCY_CREATE_FAILED",
55457
55649
  "Unable to create task dependency.",
55458
- async (c, { projectSlug, ...input }) => await c.createTaskDependency(projectSlug, input)
55650
+ async (c, { projectSlug, ...input }) => {
55651
+ await checkTenantBoundary(projectSlug, "task dependency");
55652
+ return await c.createTaskDependency(projectSlug, input);
55653
+ }
55459
55654
  ),
55460
55655
  [mcpToolNames.createTaxonomyEntry]: makeTool(
55461
55656
  client,
55462
55657
  mcpToolNames.createTaxonomyEntry,
55463
55658
  "TAXONOMY_CREATE_FAILED",
55464
55659
  "Unable to create taxonomy entry.",
55465
- async (c, { projectSlug, ...input }) => await c.createTaxonomyEntry(projectSlug, input)
55660
+ async (c, { projectSlug, ...input }) => {
55661
+ await checkTenantBoundary(projectSlug, "taxonomy");
55662
+ return await c.createTaxonomyEntry(projectSlug, input);
55663
+ }
55466
55664
  ),
55467
55665
  [mcpToolNames.renameTaxonomyEntry]: makeTool(
55468
55666
  client,
55469
55667
  mcpToolNames.renameTaxonomyEntry,
55470
55668
  "TAXONOMY_RENAME_FAILED",
55471
55669
  "Unable to rename taxonomy entry.",
55472
- async (c, { projectSlug, ...input }) => await c.renameTaxonomyEntry(projectSlug, input)
55670
+ async (c, { projectSlug, ...input }) => {
55671
+ await checkTenantBoundary(projectSlug, "taxonomy");
55672
+ return await c.renameTaxonomyEntry(projectSlug, input);
55673
+ }
55473
55674
  ),
55474
55675
  [mcpToolNames.deleteTaxonomyEntry]: makeTool(
55475
55676
  client,
55476
55677
  mcpToolNames.deleteTaxonomyEntry,
55477
55678
  "TAXONOMY_DELETE_FAILED",
55478
55679
  "Unable to delete taxonomy entry.",
55479
- async (c, { projectSlug, ...input }) => await c.deleteTaxonomyEntry(projectSlug, input)
55680
+ async (c, { projectSlug, ...input }) => {
55681
+ await checkTenantBoundary(projectSlug, "taxonomy");
55682
+ return await c.deleteTaxonomyEntry(projectSlug, input);
55683
+ }
55480
55684
  ),
55481
55685
  [mcpToolNames.listProjectMembers]: makeTool(
55482
55686
  client,
55483
55687
  mcpToolNames.listProjectMembers,
55484
55688
  "PROJECT_MEMBER_LIST_FAILED",
55485
55689
  "Unable to list project members.",
55486
- async (c, { projectSlug }) => await c.listProjectMembers(projectSlug)
55690
+ async (c, { projectSlug }) => {
55691
+ await checkTenantBoundary(projectSlug, "project members");
55692
+ return await c.listProjectMembers(projectSlug);
55693
+ }
55487
55694
  ),
55488
55695
  [mcpToolNames.addProjectMember]: makeTool(
55489
55696
  client,
55490
55697
  mcpToolNames.addProjectMember,
55491
55698
  "PROJECT_MEMBER_ADD_FAILED",
55492
55699
  "Unable to add project member.",
55493
- async (c, { projectSlug, ...input }) => await c.addProjectMember(projectSlug, input)
55700
+ async (c, { projectSlug, ...input }) => {
55701
+ await checkTenantBoundary(projectSlug, "project member");
55702
+ return await c.addProjectMember(projectSlug, input);
55703
+ }
55494
55704
  ),
55495
55705
  [mcpToolNames.removeProjectMember]: makeTool(
55496
55706
  client,
55497
55707
  mcpToolNames.removeProjectMember,
55498
55708
  "PROJECT_MEMBER_REMOVE_FAILED",
55499
55709
  "Unable to remove project member.",
55500
- async (c, { projectSlug, ...input }) => await c.removeProjectMember(projectSlug, input)
55710
+ async (c, { projectSlug, ...input }) => {
55711
+ await checkTenantBoundary(projectSlug, "project member");
55712
+ return await c.removeProjectMember(projectSlug, input);
55713
+ }
55501
55714
  ),
55502
55715
  [mcpToolNames.appendTaskEvent]: makeTool(
55503
55716
  client,
55504
55717
  mcpToolNames.appendTaskEvent,
55505
55718
  "TASK_EVENT_APPEND_FAILED",
55506
55719
  "Unable to append task event.",
55507
- async (c, { projectSlug, taskId, ...input }) => await c.appendTaskEvent(projectSlug, taskId, input)
55720
+ async (c, { projectSlug, taskId, ...input }) => {
55721
+ await checkTenantBoundary(projectSlug, "task event");
55722
+ return await c.appendTaskEvent(projectSlug, taskId, input);
55723
+ }
55508
55724
  ),
55509
55725
  // Task 8.2: routed through deliverBuiltIn, not c.createWikiPage directly.
55510
55726
  [mcpToolNames.createWikiPage]: makeTool(
@@ -55512,41 +55728,60 @@ function createMrrlinTools(options) {
55512
55728
  mcpToolNames.createWikiPage,
55513
55729
  "WIKI_PAGE_CREATE_FAILED",
55514
55730
  "Unable to create wiki page.",
55515
- async (c, { projectSlug, ...input }) => await deliverBuiltIn(
55516
- c,
55517
- projectSlug,
55518
- "document",
55519
- { operation: "create", page: input },
55520
- { mcpConfigPath: options.mcpConfigPath }
55521
- )
55731
+ async (c, { projectSlug, ...input }) => {
55732
+ await checkTenantBoundary(projectSlug, "wiki page");
55733
+ const pageInput = {
55734
+ ...input,
55735
+ folder: input.folder?.trim().toLowerCase() === "specs" ? "Specs" : input.folder
55736
+ };
55737
+ return await deliverBuiltIn(
55738
+ c,
55739
+ projectSlug,
55740
+ "document",
55741
+ { operation: "create", page: pageInput },
55742
+ { mcpConfigPath: options.mcpConfigPath }
55743
+ );
55744
+ }
55522
55745
  ),
55523
55746
  [mcpToolNames.deleteTaskDependency]: makeTool(
55524
55747
  client,
55525
55748
  mcpToolNames.deleteTaskDependency,
55526
55749
  "TASK_DEPENDENCY_DELETE_FAILED",
55527
55750
  "Unable to delete task dependency.",
55528
- async (c, { projectSlug, ...input }) => await c.deleteTaskDependency(projectSlug, input)
55751
+ async (c, { projectSlug, ...input }) => {
55752
+ await checkTenantBoundary(projectSlug, "task dependency");
55753
+ return await c.deleteTaskDependency(projectSlug, input);
55754
+ }
55529
55755
  ),
55530
55756
  [mcpToolNames.createTask]: makeTool(
55531
55757
  client,
55532
55758
  mcpToolNames.createTask,
55533
55759
  "TASK_CREATE_FAILED",
55534
55760
  "Unable to create task.",
55535
- async (c, { projectSlug, ...input }) => await c.createTask(projectSlug, input)
55761
+ async (c, { projectSlug, ...input }) => {
55762
+ await checkTenantBoundary(projectSlug, "task");
55763
+ return await c.createTask(projectSlug, input);
55764
+ }
55536
55765
  ),
55537
55766
  [mcpToolNames.getProject]: makeTool(
55538
55767
  client,
55539
55768
  mcpToolNames.getProject,
55540
55769
  "PROJECT_READ_FAILED",
55541
55770
  "Unable to read project.",
55542
- async (c, { projectSlug }) => await c.getProject(projectSlug)
55771
+ async (c, { projectSlug }) => {
55772
+ await checkTenantBoundary(projectSlug, "project");
55773
+ return await c.getProject(projectSlug);
55774
+ }
55543
55775
  ),
55544
55776
  [mcpToolNames.getProjectSnapshot]: makeReadTool(
55545
55777
  client,
55546
55778
  mcpToolNames.getProjectSnapshot,
55547
55779
  "PROJECT_SNAPSHOT_READ_FAILED",
55548
55780
  "Unable to read project snapshot.",
55549
- async (c, { projectSlug }) => await c.getProjectSnapshot(projectSlug),
55781
+ async (c, { projectSlug }) => {
55782
+ await checkTenantBoundary(projectSlug, "project snapshot");
55783
+ return await c.getProjectSnapshot(projectSlug);
55784
+ },
55550
55785
  ({ projectSlug }) => projectSlug
55551
55786
  ),
55552
55787
  [mcpToolNames.getTask]: makeTool(
@@ -55554,42 +55789,61 @@ function createMrrlinTools(options) {
55554
55789
  mcpToolNames.getTask,
55555
55790
  "TASK_READ_FAILED",
55556
55791
  "Unable to read task.",
55557
- async (c, { projectSlug, taskId }) => await c.getTask(projectSlug, taskId)
55792
+ async (c, { projectSlug, taskId }) => {
55793
+ await checkTenantBoundary(projectSlug, "task");
55794
+ return await c.getTask(projectSlug, taskId);
55795
+ }
55558
55796
  ),
55559
55797
  [mcpToolNames.getWikiPage]: makeTool(
55560
55798
  client,
55561
55799
  mcpToolNames.getWikiPage,
55562
55800
  "WIKI_PAGE_READ_FAILED",
55563
55801
  "Unable to read wiki page.",
55564
- async (c, { projectSlug, pageId }) => await c.getWikiPage(projectSlug, pageId)
55802
+ async (c, { projectSlug, pageId }) => {
55803
+ await checkTenantBoundary(projectSlug, "wiki page");
55804
+ return await c.getWikiPage(projectSlug, pageId);
55805
+ }
55565
55806
  ),
55566
55807
  [mcpToolNames.listProjects]: makeTool(
55567
55808
  client,
55568
55809
  mcpToolNames.listProjects,
55569
55810
  "PROJECT_LIST_FAILED",
55570
55811
  "Unable to list projects.",
55571
- async (c) => await c.listProjects()
55812
+ async (c) => {
55813
+ const active = await resolveBoundSlug();
55814
+ const projects = await c.listProjects();
55815
+ return active ? projects.filter((p) => p.slug === active) : [];
55816
+ }
55572
55817
  ),
55573
55818
  [mcpToolNames.listPlans]: makeTool(
55574
55819
  client,
55575
55820
  mcpToolNames.listPlans,
55576
55821
  "PLAN_LIST_FAILED",
55577
55822
  "Unable to list plans.",
55578
- async (c, { projectSlug }) => await c.listPlans(projectSlug)
55823
+ async (c, { projectSlug }) => {
55824
+ await checkTenantBoundary(projectSlug, "plans");
55825
+ return await c.listPlans(projectSlug);
55826
+ }
55579
55827
  ),
55580
55828
  [mcpToolNames.listTaskDependencies]: makeTool(
55581
55829
  client,
55582
55830
  mcpToolNames.listTaskDependencies,
55583
55831
  "TASK_DEPENDENCY_LIST_FAILED",
55584
55832
  "Unable to list task dependencies.",
55585
- async (c, { projectSlug }) => await c.listTaskDependencies(projectSlug)
55833
+ async (c, { projectSlug }) => {
55834
+ await checkTenantBoundary(projectSlug, "task dependencies");
55835
+ return await c.listTaskDependencies(projectSlug);
55836
+ }
55586
55837
  ),
55587
55838
  [mcpToolNames.listTaskEvents]: makeReadTool(
55588
55839
  client,
55589
55840
  mcpToolNames.listTaskEvents,
55590
55841
  "TASK_EVENT_LIST_FAILED",
55591
55842
  "Unable to list task events.",
55592
- async (c, { projectSlug, taskId }) => await c.listTaskEvents(projectSlug, taskId),
55843
+ async (c, { projectSlug, taskId }) => {
55844
+ await checkTenantBoundary(projectSlug, "task events");
55845
+ return await c.listTaskEvents(projectSlug, taskId);
55846
+ },
55593
55847
  ({ projectSlug }) => projectSlug,
55594
55848
  ({ taskId }) => taskId
55595
55849
  ),
@@ -55598,7 +55852,10 @@ function createMrrlinTools(options) {
55598
55852
  mcpToolNames.listTasks,
55599
55853
  "TASK_LIST_FAILED",
55600
55854
  "Unable to list tasks.",
55601
- async (c, { projectSlug, ...filters }) => await c.listTasks(projectSlug, filters),
55855
+ async (c, { projectSlug, ...filters }) => {
55856
+ await checkTenantBoundary(projectSlug, "tasks");
55857
+ return await c.listTasks(projectSlug, filters);
55858
+ },
55602
55859
  ({ projectSlug }) => projectSlug
55603
55860
  ),
55604
55861
  [mcpToolNames.listTaxonomy]: makeTool(
@@ -55606,14 +55863,20 @@ function createMrrlinTools(options) {
55606
55863
  mcpToolNames.listTaxonomy,
55607
55864
  "TAXONOMY_LIST_FAILED",
55608
55865
  "Unable to list taxonomy.",
55609
- async (c, { projectSlug }) => await c.listTaxonomy(projectSlug)
55866
+ async (c, { projectSlug }) => {
55867
+ await checkTenantBoundary(projectSlug, "taxonomy");
55868
+ return await c.listTaxonomy(projectSlug);
55869
+ }
55610
55870
  ),
55611
55871
  [mcpToolNames.listWikiPages]: makeReadTool(
55612
55872
  client,
55613
55873
  mcpToolNames.listWikiPages,
55614
55874
  "WIKI_PAGE_LIST_FAILED",
55615
55875
  "Unable to list wiki pages.",
55616
- async (c, { projectSlug, ...filters }) => await c.listWikiPages(projectSlug, filters),
55876
+ async (c, { projectSlug, ...filters }) => {
55877
+ await checkTenantBoundary(projectSlug, "wiki pages");
55878
+ return await c.listWikiPages(projectSlug, filters);
55879
+ },
55617
55880
  ({ projectSlug }) => projectSlug
55618
55881
  ),
55619
55882
  [mcpToolNames.searchWikiPages]: makeReadTool(
@@ -55621,7 +55884,10 @@ function createMrrlinTools(options) {
55621
55884
  mcpToolNames.searchWikiPages,
55622
55885
  "WIKI_PAGE_SEARCH_FAILED",
55623
55886
  "Unable to search wiki pages.",
55624
- async (c, { projectSlug, ...query }) => await c.searchWikiPages(projectSlug, query),
55887
+ async (c, { projectSlug, ...query }) => {
55888
+ await checkTenantBoundary(projectSlug, "wiki pages");
55889
+ return await c.searchWikiPages(projectSlug, query);
55890
+ },
55625
55891
  ({ projectSlug }) => projectSlug
55626
55892
  ),
55627
55893
  [mcpToolNames.searchKnowledge]: makeTool(
@@ -55636,49 +55902,70 @@ function createMrrlinTools(options) {
55636
55902
  mcpToolNames.updatePlan,
55637
55903
  "PLAN_UPDATE_FAILED",
55638
55904
  "Unable to update plan.",
55639
- async (c, { projectSlug, planId, ...patch }) => await c.updatePlan(projectSlug, planId, patch)
55905
+ async (c, { projectSlug, planId, ...patch }) => {
55906
+ await checkTenantBoundary(projectSlug, "plan");
55907
+ return await c.updatePlan(projectSlug, planId, patch);
55908
+ }
55640
55909
  ),
55641
55910
  [mcpToolNames.updateTask]: makeTool(
55642
55911
  client,
55643
55912
  mcpToolNames.updateTask,
55644
55913
  "TASK_UPDATE_FAILED",
55645
55914
  "Unable to update task.",
55646
- async (c, { projectSlug, taskId, ...patch }) => await c.updateTask(projectSlug, taskId, patch)
55915
+ async (c, { projectSlug, taskId, ...patch }) => {
55916
+ await checkTenantBoundary(projectSlug, "task");
55917
+ return await c.updateTask(projectSlug, taskId, patch);
55918
+ }
55647
55919
  ),
55648
55920
  [mcpToolNames.resetDirectorThread]: makeTool(
55649
55921
  client,
55650
55922
  mcpToolNames.resetDirectorThread,
55651
55923
  "DIRECTOR_THREAD_RESET_FAILED",
55652
55924
  "Unable to reset director thread.",
55653
- async (c, { projectSlug, taskId }) => await c.resetDirectorThread(projectSlug, taskId)
55925
+ async (c, { projectSlug, taskId }) => {
55926
+ await checkTenantBoundary(projectSlug, "director thread");
55927
+ return await c.resetDirectorThread(projectSlug, taskId);
55928
+ }
55654
55929
  ),
55655
55930
  [mcpToolNames.archiveTask]: makeTool(
55656
55931
  client,
55657
55932
  mcpToolNames.archiveTask,
55658
55933
  "TASK_ARCHIVE_FAILED",
55659
55934
  "Unable to archive task.",
55660
- async (c, { projectSlug, taskId }) => await c.archiveTask(projectSlug, taskId)
55935
+ async (c, { projectSlug, taskId }) => {
55936
+ await checkTenantBoundary(projectSlug, "task");
55937
+ return await c.archiveTask(projectSlug, taskId);
55938
+ }
55661
55939
  ),
55662
55940
  [mcpToolNames.unarchiveTask]: makeTool(
55663
55941
  client,
55664
55942
  mcpToolNames.unarchiveTask,
55665
55943
  "TASK_UNARCHIVE_FAILED",
55666
55944
  "Unable to unarchive task.",
55667
- async (c, { projectSlug, taskId }) => await c.unarchiveTask(projectSlug, taskId)
55945
+ async (c, { projectSlug, taskId }) => {
55946
+ await checkTenantBoundary(projectSlug, "task");
55947
+ return await c.unarchiveTask(projectSlug, taskId);
55948
+ }
55668
55949
  ),
55669
55950
  [mcpToolNames.takeOverTask]: makeTool(
55670
55951
  client,
55671
55952
  mcpToolNames.takeOverTask,
55672
55953
  "TASK_TAKE_OVER_FAILED",
55673
55954
  "Unable to take over task.",
55674
- async (c, { projectSlug, taskId, assignee }) => await c.takeOverTask(projectSlug, taskId, assignee)
55955
+ async (c, { projectSlug, taskId, assignee }) => {
55956
+ await checkTenantBoundary(projectSlug, "task");
55957
+ return await c.takeOverTask(projectSlug, taskId, assignee);
55958
+ }
55675
55959
  ),
55676
55960
  [mcpToolNames.closeTaskAsWontDo]: makeTool(
55677
55961
  client,
55678
55962
  mcpToolNames.closeTaskAsWontDo,
55679
55963
  "TASK_CLOSE_AS_WONT_DO_FAILED",
55680
55964
  "Unable to close task as won't-do.",
55681
- async (c, { projectSlug, taskId, reason }) => await c.closeTaskAsWontDo(projectSlug, taskId, reason)
55965
+ async (c, { projectSlug, taskId, reason }) => {
55966
+ await checkTenantBoundary(projectSlug, "task");
55967
+ return await c.closeTaskAsWontDo(projectSlug, taskId, reason);
55968
+ }
55682
55969
  ),
55683
55970
  // Task 8.2: routed through deliverBuiltIn, not c.updateWikiPage directly.
55684
55971
  [mcpToolNames.updateWikiPage]: makeTool(
@@ -55686,13 +55973,20 @@ function createMrrlinTools(options) {
55686
55973
  mcpToolNames.updateWikiPage,
55687
55974
  "WIKI_PAGE_UPDATE_FAILED",
55688
55975
  "Unable to update wiki page.",
55689
- async (c, { projectSlug, pageId, ...patch }) => await deliverBuiltIn(
55690
- c,
55691
- projectSlug,
55692
- "document",
55693
- { operation: "update", pageId, patch },
55694
- { mcpConfigPath: options.mcpConfigPath }
55695
- )
55976
+ async (c, { projectSlug, pageId, ...patch }) => {
55977
+ await checkTenantBoundary(projectSlug, "wiki page");
55978
+ const patchInput = {
55979
+ ...patch,
55980
+ ...patch.folder !== void 0 ? { folder: patch.folder.trim().toLowerCase() === "specs" ? "Specs" : patch.folder } : {}
55981
+ };
55982
+ return await deliverBuiltIn(
55983
+ c,
55984
+ projectSlug,
55985
+ "document",
55986
+ { operation: "update", pageId, patch: patchInput },
55987
+ { mcpConfigPath: options.mcpConfigPath }
55988
+ );
55989
+ }
55696
55990
  ),
55697
55991
  [mcpToolNames.markSpecReady]: makeTool(
55698
55992
  client,
@@ -55705,6 +55999,7 @@ function createMrrlinTools(options) {
55705
55999
  // only path to mark_spec_ready in the MVP. DB/API-side enforcement is a documented
55706
56000
  // follow-up (see Task D2d notes).
55707
56001
  async (c, { projectSlug, pageId, ready }) => {
56002
+ await checkTenantBoundary(projectSlug, "spec");
55708
56003
  if (ready !== true) return await c.markSpecReady({ projectSlug, pageId, ready });
55709
56004
  const config2 = await c.getConsensusConfig(projectSlug);
55710
56005
  if (!config2.consensusEnabled) {
@@ -55758,6 +56053,7 @@ function createMrrlinTools(options) {
55758
56053
  "SPEC_CONSENSUS_FAILED",
55759
56054
  "Unable to enqueue spec consensus.",
55760
56055
  async (c, { projectSlug, pageId, extraHeads }) => {
56056
+ await checkTenantBoundary(projectSlug, "spec consensus");
55761
56057
  const result = await enqueueAsyncTool(c, consensusDescriptor, { projectSlug, pageId, extraHeads });
55762
56058
  if (result.status === "queued") pingAsyncWorkerDispatch(projectSlug, result.jobId);
55763
56059
  return result;
@@ -55773,13 +56069,18 @@ function createMrrlinTools(options) {
55773
56069
  // tools.ts is an allowed provider mint site (eslint.config.mjs); decision-consensus.ts is
55774
56070
  // deliberately not, so the seat and the persisted provider are minted HERE and threaded down.
55775
56071
  // mintSeat stays a thunk so the anchor-only path never mints a seat it has no use for.
55776
- async (_c, input) => runDecisionConsensus(
55777
- { ...input, cwd: process.cwd() },
55778
- {
55779
- persistedProvider: getSelectedProvider(),
55780
- mintSeat: () => mintResolvedSeat(resolveProvider(process.env, getSelectedProvider()))
56072
+ async (_c, input) => {
56073
+ if (input.projectSlug) {
56074
+ await checkTenantBoundary(input.projectSlug, "decision consensus");
55781
56075
  }
55782
- )
56076
+ return runDecisionConsensus(
56077
+ { ...input, cwd: process.cwd() },
56078
+ {
56079
+ persistedProvider: getSelectedProvider(),
56080
+ mintSeat: () => mintResolvedSeat(resolveProvider(process.env, getSelectedProvider()))
56081
+ }
56082
+ );
56083
+ }
55783
56084
  ),
55784
56085
  [mcpToolNames.runCodeReviewerGate]: makeTool(
55785
56086
  client,
@@ -55787,6 +56088,7 @@ function createMrrlinTools(options) {
55787
56088
  "CODE_GATE_FAILED",
55788
56089
  "Unable to run the code reviewer gate.",
55789
56090
  async (c, { projectSlug, baseRef, extraHeads }) => {
56091
+ await checkTenantBoundary(projectSlug, "code reviewer gate");
55790
56092
  const deps = buildCodeGateDeps({
55791
56093
  client: c,
55792
56094
  projectSlug,
@@ -55831,7 +56133,10 @@ function createMrrlinTools(options) {
55831
56133
  mcpToolNames.listExecutionRuns,
55832
56134
  "EXECUTION_RUNS_LIST_FAILED",
55833
56135
  "Unable to list execution runs.",
55834
- async (c, { projectSlug, ...filters }) => await c.listExecutionRuns(projectSlug, filters)
56136
+ async (c, { projectSlug, ...filters }) => {
56137
+ await checkTenantBoundary(projectSlug, "execution runs");
56138
+ return await c.listExecutionRuns(projectSlug, filters);
56139
+ }
55835
56140
  ),
55836
56141
  [mcpToolNames.createExecutionRun]: makeTool(
55837
56142
  client,
@@ -55839,6 +56144,7 @@ function createMrrlinTools(options) {
55839
56144
  "EXECUTION_RUN_CREATE_FAILED",
55840
56145
  "Unable to create execution run.",
55841
56146
  async (c, { projectSlug, ...input }) => {
56147
+ await checkTenantBoundary(projectSlug, "execution run");
55842
56148
  const run3 = await c.createExecutionRun(projectSlug, input);
55843
56149
  pingWorkerDispatch(projectSlug, run3.id);
55844
56150
  return run3;
@@ -55849,21 +56155,30 @@ function createMrrlinTools(options) {
55849
56155
  mcpToolNames.getExecutionRun,
55850
56156
  "EXECUTION_RUN_FETCH_FAILED",
55851
56157
  "Unable to fetch execution run.",
55852
- async (c, { projectSlug, runId }) => await c.getExecutionRun(projectSlug, runId)
56158
+ async (c, { projectSlug, runId }) => {
56159
+ await checkTenantBoundary(projectSlug, "execution run");
56160
+ return await c.getExecutionRun(projectSlug, runId);
56161
+ }
55853
56162
  ),
55854
56163
  [mcpToolNames.updateExecutionRun]: makeTool(
55855
56164
  client,
55856
56165
  mcpToolNames.updateExecutionRun,
55857
56166
  "EXECUTION_RUN_UPDATE_FAILED",
55858
56167
  "Unable to update execution run.",
55859
- async (c, { projectSlug, runId, ...patch }) => await c.updateExecutionRun(projectSlug, runId, patch)
56168
+ async (c, { projectSlug, runId, ...patch }) => {
56169
+ await checkTenantBoundary(projectSlug, "execution run");
56170
+ return await c.updateExecutionRun(projectSlug, runId, patch);
56171
+ }
55860
56172
  ),
55861
56173
  [mcpToolNames.listExecutionArtifacts]: makeReadTool(
55862
56174
  client,
55863
56175
  mcpToolNames.listExecutionArtifacts,
55864
56176
  "EXECUTION_ARTIFACTS_LIST_FAILED",
55865
56177
  "Unable to list execution artifacts.",
55866
- async (c, { projectSlug, runId }) => await c.listExecutionArtifacts(projectSlug, runId),
56178
+ async (c, { projectSlug, runId }) => {
56179
+ await checkTenantBoundary(projectSlug, "execution artifacts");
56180
+ return await c.listExecutionArtifacts(projectSlug, runId);
56181
+ },
55867
56182
  ({ projectSlug }) => projectSlug
55868
56183
  ),
55869
56184
  [mcpToolNames.appendExecutionArtifact]: makeTool(
@@ -55871,14 +56186,20 @@ function createMrrlinTools(options) {
55871
56186
  mcpToolNames.appendExecutionArtifact,
55872
56187
  "EXECUTION_ARTIFACT_APPEND_FAILED",
55873
56188
  "Unable to append execution artifact.",
55874
- async (c, { projectSlug, runId, ...input }) => await c.appendExecutionArtifact(projectSlug, runId, input)
56189
+ async (c, { projectSlug, runId, ...input }) => {
56190
+ await checkTenantBoundary(projectSlug, "execution artifact");
56191
+ return await c.appendExecutionArtifact(projectSlug, runId, input);
56192
+ }
55875
56193
  ),
55876
56194
  [mcpToolNames.updateTaskState]: makeTool(
55877
56195
  client,
55878
56196
  mcpToolNames.updateTaskState,
55879
56197
  "TASK_STATE_REPORT_FAILED",
55880
56198
  "Unable to record task state.",
55881
- async (c, { projectSlug, runId, ...report }) => await c.reportTaskState(projectSlug, runId, report)
56199
+ async (c, { projectSlug, runId, ...report }) => {
56200
+ await checkTenantBoundary(projectSlug, "task state");
56201
+ return await c.reportTaskState(projectSlug, runId, report);
56202
+ }
55882
56203
  ),
55883
56204
  [mcpToolNames.recordProducedUrl]: makeTool(
55884
56205
  client,
@@ -55886,6 +56207,7 @@ function createMrrlinTools(options) {
55886
56207
  "PRODUCED_URL_RECORD_FAILED",
55887
56208
  "Unable to record produced URL.",
55888
56209
  async (c, { projectSlug, runId, url: url2, label }) => {
56210
+ await checkTenantBoundary(projectSlug, "produced url");
55889
56211
  const id = `EA-pu-${(0, import_node_crypto9.randomBytes)(4).toString("hex")}`;
55890
56212
  const payload = label ? { url: url2, label } : { url: url2 };
55891
56213
  return await c.appendExecutionArtifact(projectSlug, runId, {
@@ -55900,14 +56222,20 @@ function createMrrlinTools(options) {
55900
56222
  mcpToolNames.getProjectSchedulerPolicy,
55901
56223
  "SCHEDULER_POLICY_FETCH_FAILED",
55902
56224
  "Unable to fetch project scheduler policy.",
55903
- async (c, { projectSlug }) => await c.getProjectSchedulerPolicy(projectSlug)
56225
+ async (c, { projectSlug }) => {
56226
+ await checkTenantBoundary(projectSlug, "scheduler policy");
56227
+ return await c.getProjectSchedulerPolicy(projectSlug);
56228
+ }
55904
56229
  ),
55905
56230
  [mcpToolNames.upsertProjectSchedulerPolicy]: makeTool(
55906
56231
  client,
55907
56232
  mcpToolNames.upsertProjectSchedulerPolicy,
55908
56233
  "SCHEDULER_POLICY_UPSERT_FAILED",
55909
56234
  "Unable to upsert project scheduler policy.",
55910
- async (c, { projectSlug, ...input }) => await c.upsertProjectSchedulerPolicy(projectSlug, input)
56235
+ async (c, { projectSlug, ...input }) => {
56236
+ await checkTenantBoundary(projectSlug, "scheduler policy");
56237
+ return await c.upsertProjectSchedulerPolicy(projectSlug, input);
56238
+ }
55911
56239
  ),
55912
56240
  [mcpToolNames.getSchedulerPendingTasks]: makeTool(
55913
56241
  client,
@@ -55915,6 +56243,7 @@ function createMrrlinTools(options) {
55915
56243
  "SCHEDULER_PENDING_FETCH_FAILED",
55916
56244
  "Unable to fetch scheduler pending tasks.",
55917
56245
  async (c, { projectSlug }) => {
56246
+ await checkTenantBoundary(projectSlug, "scheduler pending tasks");
55918
56247
  const result = await c.getSchedulerPendingTasks(projectSlug);
55919
56248
  return result;
55920
56249
  }
@@ -55924,28 +56253,40 @@ function createMrrlinTools(options) {
55924
56253
  mcpToolNames.wakeDirector,
55925
56254
  "DIRECTOR_WAKE_FAILED",
55926
56255
  "Unable to wake Director.",
55927
- async (c, { projectSlug, ...input }) => await c.wakeDirector(projectSlug, input)
56256
+ async (c, { projectSlug, ...input }) => {
56257
+ await checkTenantBoundary(projectSlug, "director wake");
56258
+ return await c.wakeDirector(projectSlug, input);
56259
+ }
55928
56260
  ),
55929
56261
  [mcpToolNames.listInboxItems]: makeTool(
55930
56262
  client,
55931
56263
  mcpToolNames.listInboxItems,
55932
56264
  "INBOX_ITEMS_LIST_FAILED",
55933
56265
  "Unable to list inbox items.",
55934
- async (c, { projectSlug, ...filters }) => await c.listInboxItems(projectSlug, filters)
56266
+ async (c, { projectSlug, ...filters }) => {
56267
+ await checkTenantBoundary(projectSlug, "inbox items");
56268
+ return await c.listInboxItems(projectSlug, filters);
56269
+ }
55935
56270
  ),
55936
56271
  [mcpToolNames.createInboxItem]: makeTool(
55937
56272
  client,
55938
56273
  mcpToolNames.createInboxItem,
55939
56274
  "INBOX_ITEM_CREATE_FAILED",
55940
56275
  "Unable to create inbox item.",
55941
- async (c, { projectSlug, ...input }) => await c.createInboxItem(projectSlug, input)
56276
+ async (c, { projectSlug, ...input }) => {
56277
+ await checkTenantBoundary(projectSlug, "inbox item");
56278
+ return await c.createInboxItem(projectSlug, input);
56279
+ }
55942
56280
  ),
55943
56281
  [mcpToolNames.decideInboxItem]: makeTool(
55944
56282
  client,
55945
56283
  mcpToolNames.decideInboxItem,
55946
56284
  "INBOX_ITEM_DECIDE_FAILED",
55947
56285
  "Unable to decide inbox item.",
55948
- async (c, { projectSlug, itemId, ...decision }) => await c.decideInboxItem(projectSlug, itemId, decision)
56286
+ async (c, { projectSlug, itemId, ...decision }) => {
56287
+ await checkTenantBoundary(projectSlug, "inbox item");
56288
+ return await c.decideInboxItem(projectSlug, itemId, decision);
56289
+ }
55949
56290
  ),
55950
56291
  [mcpToolNames.uploadArtifact]: makeTool(
55951
56292
  client,
@@ -55953,7 +56294,8 @@ function createMrrlinTools(options) {
55953
56294
  "ARTIFACT_FILE_UPLOAD_FAILED",
55954
56295
  "Unable to upload artifact file.",
55955
56296
  async (c, { projectSlug, path: filePath, class: artifactClass, taskId, runId, description }) => {
55956
- const extension2 = import_node_path16.default.extname(filePath).toLowerCase();
56297
+ await checkTenantBoundary(projectSlug, "artifact upload");
56298
+ const extension2 = import_node_path17.default.extname(filePath).toLowerCase();
55957
56299
  const contentType2 = ARTIFACT_EXTENSION_TYPES[extension2];
55958
56300
  if (!contentType2) {
55959
56301
  throw new McpToolCodedError(
@@ -55981,7 +56323,7 @@ function createMrrlinTools(options) {
55981
56323
  "Artifact exceeds 5MB; split or summarize instead."
55982
56324
  );
55983
56325
  }
55984
- const filename = import_node_path16.default.basename(filePath);
56326
+ const filename = import_node_path17.default.basename(filePath);
55985
56327
  return deliverBuiltIn(
55986
56328
  c,
55987
56329
  projectSlug,
@@ -55997,13 +56339,14 @@ function createMrrlinTools(options) {
55997
56339
  "ARTIFACT_FILE_UPLOAD_FAILED",
55998
56340
  "Unable to deliver artifact file.",
55999
56341
  async (c, { projectSlug, filename, content, class: artifactClass, taskId, runId, description }) => {
56342
+ await checkTenantBoundary(projectSlug, "artifact file");
56000
56343
  if (filename.includes("/") || filename.includes("\\") || filename.includes("..")) {
56001
56344
  throw new McpToolCodedError(
56002
56345
  "ARTIFACT_FILE_NAME_INVALID",
56003
56346
  `Invalid filename '${filename}'; provide a bare filename with no path separators or '..'.`
56004
56347
  );
56005
56348
  }
56006
- const extension2 = import_node_path16.default.extname(filename).toLowerCase();
56349
+ const extension2 = import_node_path17.default.extname(filename).toLowerCase();
56007
56350
  const contentType2 = ARTIFACT_EXTENSION_TYPES[extension2];
56008
56351
  if (!contentType2) {
56009
56352
  throw new McpToolCodedError(
@@ -56038,35 +56381,50 @@ function createMrrlinTools(options) {
56038
56381
  mcpToolNames.listArtifactFiles,
56039
56382
  "ARTIFACT_FILE_LIST_FAILED",
56040
56383
  "Unable to list artifact files.",
56041
- async (c, { projectSlug, taskId, runId }) => await c.listArtifactFiles(projectSlug, { runId, taskId })
56384
+ async (c, { projectSlug, taskId, runId }) => {
56385
+ await checkTenantBoundary(projectSlug, "artifact files");
56386
+ return await c.listArtifactFiles(projectSlug, { runId, taskId });
56387
+ }
56042
56388
  ),
56043
56389
  [mcpToolNames.reclaimExecutionRunLease]: makeTool(
56044
56390
  client,
56045
56391
  mcpToolNames.reclaimExecutionRunLease,
56046
56392
  "EXECUTION_RUN_RECLAIM_FAILED",
56047
56393
  "Unable to reclaim the execution run lease.",
56048
- async (c, { projectSlug, runId, staleSeconds }) => await c.reclaimExecutionRunLease(projectSlug, runId, staleSeconds)
56394
+ async (c, { projectSlug, runId, staleSeconds }) => {
56395
+ await checkTenantBoundary(projectSlug, "execution run lease");
56396
+ return await c.reclaimExecutionRunLease(projectSlug, runId, staleSeconds);
56397
+ }
56049
56398
  ),
56050
56399
  [mcpToolNames.restartExecutionRun]: makeTool(
56051
56400
  client,
56052
56401
  mcpToolNames.restartExecutionRun,
56053
56402
  "EXECUTION_RUN_RESTART_FAILED",
56054
56403
  "Unable to restart the execution run.",
56055
- async (c, { projectSlug, runId, ...input }) => await c.restartExecutionRun(projectSlug, runId, input)
56404
+ async (c, { projectSlug, runId, ...input }) => {
56405
+ await checkTenantBoundary(projectSlug, "execution run restart");
56406
+ return await c.restartExecutionRun(projectSlug, runId, input);
56407
+ }
56056
56408
  ),
56057
56409
  [mcpToolNames.stopExecutionRun]: makeTool(
56058
56410
  client,
56059
56411
  mcpToolNames.stopExecutionRun,
56060
56412
  "EXECUTION_RUN_STOP_FAILED",
56061
56413
  "Unable to stop the execution run.",
56062
- async (c, { projectSlug, runId }) => await c.stopExecutionRun(projectSlug, runId)
56414
+ async (c, { projectSlug, runId }) => {
56415
+ await checkTenantBoundary(projectSlug, "execution run stop");
56416
+ return await c.stopExecutionRun(projectSlug, runId);
56417
+ }
56063
56418
  ),
56064
56419
  [mcpToolNames.resolveHandoff]: makeTool(
56065
56420
  client,
56066
56421
  mcpToolNames.resolveHandoff,
56067
56422
  "HANDOFF_RESOLVE_FAILED",
56068
56423
  "Unable to resolve handoff.",
56069
- async (c, { projectSlug, runId, ...input }) => await c.resolveHandoff(projectSlug, runId, input)
56424
+ async (c, { projectSlug, runId, ...input }) => {
56425
+ await checkTenantBoundary(projectSlug, "handoff resolve");
56426
+ return await c.resolveHandoff(projectSlug, runId, input);
56427
+ }
56070
56428
  ),
56071
56429
  [mcpToolNames.registerLocalCheckout]: makeTool(
56072
56430
  client,
@@ -56074,6 +56432,7 @@ function createMrrlinTools(options) {
56074
56432
  "LOCAL_CHECKOUT_REGISTER_FAILED",
56075
56433
  "Unable to register local checkout.",
56076
56434
  async (_c, { projectSlug, path: checkoutPath, repo }) => {
56435
+ await checkTenantBoundary(projectSlug, "local checkout");
56077
56436
  const registry3 = new CheckoutRegistry(resolveStateDir());
56078
56437
  const result = registerCheckout(registry3, { projectSlug, path: checkoutPath, repo }, import_node_os9.default.hostname());
56079
56438
  if (!result.ok) {
@@ -56101,6 +56460,7 @@ function createMrrlinTools(options) {
56101
56460
  `Unrecognized mrrlin:// handle: ${handle}. Valid kinds: task | wiki | project/{slug}/snapshot | project/{slug}/tasks | run/{slug}/{runId} | run/{slug}/{runId}/artifacts.`
56102
56461
  );
56103
56462
  }
56463
+ await checkTenantBoundary(parsed.projectSlug, "context handle");
56104
56464
  return await dispatchHandle(c, parsed);
56105
56465
  }
56106
56466
  )
@@ -56175,20 +56535,20 @@ function allAgyGrantStrings() {
56175
56535
  }
56176
56536
  function resolveAgyConfigPath(options) {
56177
56537
  if (options.agyConfigPath) return options.agyConfigPath;
56178
- return import_node_path17.default.join(options.homeDir ?? import_node_os10.default.homedir(), ".gemini", "config", "mcp_config.json");
56538
+ return import_node_path18.default.join(options.homeDir ?? import_node_os10.default.homedir(), ".gemini", "config", "mcp_config.json");
56179
56539
  }
56180
56540
  function resolveConfigJsonPath(options) {
56181
56541
  if (options.configJsonPath) return options.configJsonPath;
56182
- return import_node_path17.default.join(options.homeDir ?? import_node_os10.default.homedir(), ".gemini", "config", "config.json");
56542
+ return import_node_path18.default.join(options.homeDir ?? import_node_os10.default.homedir(), ".gemini", "config", "config.json");
56183
56543
  }
56184
56544
  async function detectInstallDistribution3(options) {
56185
56545
  if (options.distribution && options.distribution !== "auto") return options.distribution;
56186
- let current2 = import_node_path17.default.dirname(options.binPath);
56546
+ let current2 = import_node_path18.default.dirname(options.binPath);
56187
56547
  while (true) {
56188
- if (await pathExists4(import_node_path17.default.join(current2, "pnpm-workspace.yaml"))) {
56548
+ if (await pathExists4(import_node_path18.default.join(current2, "pnpm-workspace.yaml"))) {
56189
56549
  return "local";
56190
56550
  }
56191
- const parent = import_node_path17.default.dirname(current2);
56551
+ const parent = import_node_path18.default.dirname(current2);
56192
56552
  if (parent === current2) break;
56193
56553
  current2 = parent;
56194
56554
  }
@@ -56230,8 +56590,8 @@ async function installAgy(options) {
56230
56590
  const configJsonPath = resolveConfigJsonPath(options);
56231
56591
  const distribution = await detectInstallDistribution3(options);
56232
56592
  const entries = managedEntries2(options, distribution);
56233
- await import_promises9.default.mkdir(import_node_path17.default.dirname(configPath), { recursive: true });
56234
- await import_promises9.default.mkdir(import_node_path17.default.dirname(configJsonPath), { recursive: true });
56593
+ await import_promises9.default.mkdir(import_node_path18.default.dirname(configPath), { recursive: true });
56594
+ await import_promises9.default.mkdir(import_node_path18.default.dirname(configJsonPath), { recursive: true });
56235
56595
  let action = "noop";
56236
56596
  const preservedEnvBlocks = [];
56237
56597
  if (!await pathExists4(configPath)) {
@@ -56349,12 +56709,12 @@ async function installAgy(options) {
56349
56709
  var import_promises10 = require("node:fs/promises");
56350
56710
  var import_node_fs10 = require("node:fs");
56351
56711
  var import_node_os11 = __toESM(require("node:os"), 1);
56352
- var import_node_path18 = __toESM(require("node:path"), 1);
56712
+ var import_node_path19 = __toESM(require("node:path"), 1);
56353
56713
  var import_semver2 = __toESM(require_semver2(), 1);
56354
56714
  var toml3 = __toESM(require_toml(), 1);
56355
56715
 
56356
56716
  // src/agent-version.ts
56357
- var import_node_child_process12 = require("node:child_process");
56717
+ var import_node_child_process13 = require("node:child_process");
56358
56718
  var import_semver = __toESM(require_semver2(), 1);
56359
56719
  var SEMVER_RE = /\b\d+\.\d+\.\d+(?:-[A-Za-z0-9.-]+)?\b/;
56360
56720
  var CODEX_PACKAGE = process.env.MRRLIN_CODEX_PACKAGE?.trim() || "@openai/codex";
@@ -56364,7 +56724,7 @@ function parseCodexVersion(raw) {
56364
56724
  return m ? m[0] : null;
56365
56725
  }
56366
56726
  var defaultRun = (args) => {
56367
- const r = (0, import_node_child_process12.spawnSync)("codex", args, { encoding: "utf8", timeout: 8e3, shell: true });
56727
+ const r = (0, import_node_child_process13.spawnSync)("codex", args, { encoding: "utf8", timeout: 8e3, shell: true });
56368
56728
  return { status: r.status, stdout: r.stdout ?? "", stderr: r.stderr ?? "" };
56369
56729
  };
56370
56730
  function getInstalledAgentVersion(provider, run3) {
@@ -56440,12 +56800,13 @@ function startCodexProbe(deps = {}) {
56440
56800
  // src/provider-readiness.ts
56441
56801
  function resolveCodexHome2(opts) {
56442
56802
  if (opts.codexHome) return opts.codexHome;
56803
+ if (opts.homeDir) return import_node_path19.default.join(opts.homeDir, ".codex");
56443
56804
  if (process.env.CODEX_HOME) return process.env.CODEX_HOME;
56444
- return import_node_path18.default.join(opts.homeDir ?? import_node_os11.default.homedir(), ".codex");
56805
+ return import_node_path19.default.join(import_node_os11.default.homedir(), ".codex");
56445
56806
  }
56446
56807
  function resolveClaudeConfigPath2(opts) {
56447
56808
  if (opts.claudeConfigPath) return opts.claudeConfigPath;
56448
- return import_node_path18.default.join(opts.homeDir ?? import_node_os11.default.homedir(), ".claude.json");
56809
+ return import_node_path19.default.join(opts.homeDir ?? import_node_os11.default.homedir(), ".claude.json");
56449
56810
  }
56450
56811
  function isExternalAgentsWrapper(table) {
56451
56812
  if (!table) return false;
@@ -56514,7 +56875,7 @@ async function verifyProviderReadiness(provider, run3, opts = {}) {
56514
56875
  if (!checks.version) details.push(`version: ${version2 ?? "unparseable"} is below the required 2.1.232`);
56515
56876
  }
56516
56877
  if (provider === "codex") {
56517
- const authPath = import_node_path18.default.join(resolveCodexHome2(opts), "auth.json");
56878
+ const authPath = import_node_path19.default.join(resolveCodexHome2(opts), "auth.json");
56518
56879
  try {
56519
56880
  await (0, import_promises10.access)(authPath, import_node_fs10.constants.F_OK);
56520
56881
  checks.auth = true;
@@ -56531,7 +56892,7 @@ async function verifyProviderReadiness(provider, run3, opts = {}) {
56531
56892
  if (!checks.auth) details.push("auth: `claude auth status` failed");
56532
56893
  }
56533
56894
  if (provider === "codex") {
56534
- const configPath = import_node_path18.default.join(resolveCodexHome2(opts), "config.toml");
56895
+ const configPath = import_node_path19.default.join(resolveCodexHome2(opts), "config.toml");
56535
56896
  try {
56536
56897
  const raw = await (0, import_promises10.readFile)(configPath, "utf8");
56537
56898
  const parsed = toml3.parse(raw);
@@ -56585,8 +56946,8 @@ async function verifyProviderReadiness(provider, run3, opts = {}) {
56585
56946
  var import_node_fs23 = __toESM(require("node:fs"), 1);
56586
56947
  var import_node_http = __toESM(require("node:http"), 1);
56587
56948
  var import_node_os17 = __toESM(require("node:os"), 1);
56588
- var import_node_path37 = __toESM(require("node:path"), 1);
56589
- var import_node_child_process20 = require("node:child_process");
56949
+ var import_node_path38 = __toESM(require("node:path"), 1);
56950
+ var import_node_child_process21 = require("node:child_process");
56590
56951
  var import_node_crypto15 = __toESM(require("node:crypto"), 1);
56591
56952
 
56592
56953
  // src/turn-replay-buffer.ts
@@ -57131,17 +57492,17 @@ function createTurnLock() {
57131
57492
  }
57132
57493
 
57133
57494
  // src/self-update.ts
57134
- var import_node_child_process14 = require("node:child_process");
57495
+ var import_node_child_process15 = require("node:child_process");
57135
57496
  var import_node_crypto10 = require("node:crypto");
57136
57497
  var import_node_fs12 = require("node:fs");
57137
- var import_node_path20 = __toESM(require("node:path"), 1);
57498
+ var import_node_path21 = __toESM(require("node:path"), 1);
57138
57499
  var import_semver3 = __toESM(require_semver2(), 1);
57139
57500
 
57140
57501
  // src/codex-auth-preflight.ts
57141
- var import_node_child_process13 = require("node:child_process");
57502
+ var import_node_child_process14 = require("node:child_process");
57142
57503
  var import_node_fs11 = require("node:fs");
57143
57504
  var import_node_os12 = __toESM(require("node:os"), 1);
57144
- var import_node_path19 = __toESM(require("node:path"), 1);
57505
+ var import_node_path20 = __toESM(require("node:path"), 1);
57145
57506
  var DEFAULT_CODEX_AUTH_MIN_TTL_SECONDS = 15 * 60;
57146
57507
  var DEFAULT_CODEX_AUTH_SMOKE_TIMEOUT_MS = 2e4;
57147
57508
  var DEFAULT_CODEX_AUTH_SMOKE_MODEL = "gpt-5.4-mini";
@@ -57160,7 +57521,7 @@ function codexAuthSmokeTimeoutMs(env = process.env) {
57160
57521
  function resolveCodexAuthPath(opts = {}) {
57161
57522
  const env = opts.env ?? process.env;
57162
57523
  const codexHome = env.CODEX_HOME?.trim();
57163
- return import_node_path19.default.join(codexHome || import_node_path19.default.join(opts.homeDir ?? import_node_os12.default.homedir(), ".codex"), "auth.json");
57524
+ return import_node_path20.default.join(codexHome || import_node_path20.default.join(opts.homeDir ?? import_node_os12.default.homedir(), ".codex"), "auth.json");
57164
57525
  }
57165
57526
  function decodeJwtExpMs(token) {
57166
57527
  const parts = token.split(".");
@@ -57229,7 +57590,7 @@ function runCodexAuthRefreshSmokeForBridgeUpdate(opts = {}) {
57229
57590
  CODEX_AUTH_SMOKE_PROMPT
57230
57591
  ];
57231
57592
  const command = commandForSmoke(executable, model);
57232
- const execFileSync5 = opts.execFileSyncImpl ?? import_node_child_process13.execFileSync;
57593
+ const execFileSync5 = opts.execFileSyncImpl ?? import_node_child_process14.execFileSync;
57233
57594
  try {
57234
57595
  execFileSync5(executable, args, {
57235
57596
  cwd,
@@ -57380,12 +57741,12 @@ function inspectCodexAuthForBridgeUpdate(opts = {}) {
57380
57741
  var BIN_NAME = "mrrlin-mcp";
57381
57742
  var SELF_UPDATE_AUTH_PREFLIGHT_OFFER_PREFIX = "[bridge:update:auth-preflight]";
57382
57743
  function resolveBinPath(opts) {
57383
- if (opts.argv1 && import_node_path20.default.basename(opts.argv1).includes("mrrlin")) {
57744
+ if (opts.argv1 && import_node_path21.default.basename(opts.argv1).includes("mrrlin")) {
57384
57745
  return { path: opts.argv1, source: "argv" };
57385
57746
  }
57386
57747
  const whichSync = opts.whichSync ?? ((name) => {
57387
57748
  try {
57388
- return (0, import_node_child_process14.execFileSync)("which", [name], { encoding: "utf8", timeout: 3e3 }).trim() || null;
57749
+ return (0, import_node_child_process15.execFileSync)("which", [name], { encoding: "utf8", timeout: 3e3 }).trim() || null;
57389
57750
  } catch {
57390
57751
  return null;
57391
57752
  }
@@ -57396,9 +57757,9 @@ function resolveBinPath(opts) {
57396
57757
  return { path: resolved, source: "which" };
57397
57758
  }
57398
57759
  const envPath = (opts.env ?? process.env).PATH ?? "";
57399
- for (const dir of envPath.split(import_node_path20.default.delimiter)) {
57760
+ for (const dir of envPath.split(import_node_path21.default.delimiter)) {
57400
57761
  if (!dir) continue;
57401
- const candidate = import_node_path20.default.join(dir, BIN_NAME);
57762
+ const candidate = import_node_path21.default.join(dir, BIN_NAME);
57402
57763
  if (existsSync5(candidate)) {
57403
57764
  return { path: candidate, source: "path-walk" };
57404
57765
  }
@@ -57716,17 +58077,17 @@ Do NOT derail the current task - if the operator has an in-flight question, answ
57716
58077
  }
57717
58078
 
57718
58079
  // src/_generated/version.ts
57719
- var PKG_VERSION = "0.4.92";
58080
+ var PKG_VERSION = "0.4.95";
57720
58081
 
57721
58082
  // src/api-base-url-migrate.ts
57722
58083
  var import_node_fs13 = __toESM(require("node:fs"), 1);
57723
58084
  var import_node_os13 = __toESM(require("node:os"), 1);
57724
- var import_node_path22 = __toESM(require("node:path"), 1);
58085
+ var import_node_path23 = __toESM(require("node:path"), 1);
57725
58086
 
57726
58087
  // src/service-paths.ts
57727
- var import_node_path21 = __toESM(require("node:path"), 1);
58088
+ var import_node_path22 = __toESM(require("node:path"), 1);
57728
58089
  function isWorktreePath(p) {
57729
- const norm = import_node_path21.default.normalize(p).split(import_node_path21.default.sep).join("/");
58090
+ const norm = import_node_path22.default.normalize(p).split(import_node_path22.default.sep).join("/");
57730
58091
  return norm.includes("/.claude/worktrees/");
57731
58092
  }
57732
58093
  function resolveServiceCwd(opts) {
@@ -57801,7 +58162,7 @@ function defaultDeps(deps) {
57801
58162
  const home = deps.home ?? process.env.HOME ?? import_node_os13.default.homedir();
57802
58163
  return {
57803
58164
  home,
57804
- codexHome: deps.codexHome ?? process.env.CODEX_HOME?.trim() ?? import_node_path22.default.join(home, ".codex"),
58165
+ codexHome: deps.codexHome ?? process.env.CODEX_HOME?.trim() ?? import_node_path23.default.join(home, ".codex"),
57805
58166
  readFile: deps.readFile ?? ((p) => import_node_fs13.default.readFileSync(p, "utf8")),
57806
58167
  // Temp-file + atomic rename so a concurrent `serve` and `director-bridge` startup can never
57807
58168
  // interleave partial writes into a config the next start has to parse. Note this normalizes the
@@ -57850,7 +58211,7 @@ function backupOnce(file2, text, deps) {
57850
58211
  }
57851
58212
  function migrateEcosystemConfig(deps = {}) {
57852
58213
  const d = defaultDeps(deps);
57853
- const file2 = import_node_path22.default.join(d.home, ".mrrlin", "ecosystem.config.cjs");
58214
+ const file2 = import_node_path23.default.join(d.home, ".mrrlin", "ecosystem.config.cjs");
57854
58215
  if (!d.exists(file2)) return { file: file2, status: "absent" };
57855
58216
  const text = d.readFile(file2);
57856
58217
  if (!findRetiredHost(text) && !hasLiveLegacyStagingFlag(text, "js"))
@@ -58000,7 +58361,7 @@ ${envLines}
58000
58361
  }
58001
58362
  function migrateCodexConfig(deps = {}) {
58002
58363
  const d = defaultDeps(deps);
58003
- const file2 = import_node_path22.default.join(d.codexHome, "config.toml");
58364
+ const file2 = import_node_path23.default.join(d.codexHome, "config.toml");
58004
58365
  if (!d.exists(file2)) return { file: file2, status: "absent" };
58005
58366
  const text = d.readFile(file2);
58006
58367
  const host = findRetiredHost(text);
@@ -58086,7 +58447,7 @@ $1`
58086
58447
  }
58087
58448
  function migrateClaudeConfig(deps = {}) {
58088
58449
  const d = defaultDeps(deps);
58089
- const file2 = import_node_path22.default.join(d.home, ".claude.json");
58450
+ const file2 = import_node_path23.default.join(d.home, ".claude.json");
58090
58451
  if (!d.exists(file2)) return { file: file2, status: "absent" };
58091
58452
  const text = d.readFile(file2);
58092
58453
  let parsed;
@@ -58136,9 +58497,9 @@ function migrateRetiredApiBaseUrls(deps = {}) {
58136
58497
  const d = defaultDeps(deps);
58137
58498
  const results = [];
58138
58499
  const steps = [
58139
- { run: migrateEcosystemConfig, file: import_node_path22.default.join(d.home, ".mrrlin", "ecosystem.config.cjs") },
58140
- { run: migrateCodexConfig, file: import_node_path22.default.join(d.codexHome, "config.toml") },
58141
- { run: migrateClaudeConfig, file: import_node_path22.default.join(d.home, ".claude.json") }
58500
+ { run: migrateEcosystemConfig, file: import_node_path23.default.join(d.home, ".mrrlin", "ecosystem.config.cjs") },
58501
+ { run: migrateCodexConfig, file: import_node_path23.default.join(d.codexHome, "config.toml") },
58502
+ { run: migrateClaudeConfig, file: import_node_path23.default.join(d.home, ".claude.json") }
58142
58503
  ];
58143
58504
  for (const step of steps) {
58144
58505
  try {
@@ -58165,7 +58526,7 @@ function migrateRetiredApiBaseUrls(deps = {}) {
58165
58526
 
58166
58527
  // src/bridge-health.ts
58167
58528
  var import_node_fs14 = require("node:fs");
58168
- var import_node_path23 = __toESM(require("node:path"), 1);
58529
+ var import_node_path24 = __toESM(require("node:path"), 1);
58169
58530
  var SENTINEL_FILE_NAME = "bridge-health-circuit-breaker.json";
58170
58531
  var CRASH_WINDOW_MS = 60 * 60 * 1e3;
58171
58532
  var MAX_CRASHES_PER_WINDOW = 3;
@@ -58177,7 +58538,7 @@ function isCrashSentinel(value) {
58177
58538
  return typeof candidate.crashCount === "number" && Number.isInteger(candidate.crashCount) && candidate.crashCount >= 0 && typeof candidate.windowStartedAt === "string";
58178
58539
  }
58179
58540
  async function readCrashSentinel(stateDir, now = Date.now) {
58180
- const sentinelPath = import_node_path23.default.join(stateDir, SENTINEL_FILE_NAME);
58541
+ const sentinelPath = import_node_path24.default.join(stateDir, SENTINEL_FILE_NAME);
58181
58542
  try {
58182
58543
  const raw = await import_node_fs14.promises.readFile(sentinelPath, "utf8");
58183
58544
  const parsed = JSON.parse(raw);
@@ -58188,7 +58549,7 @@ async function readCrashSentinel(stateDir, now = Date.now) {
58188
58549
  }
58189
58550
  async function writeCrashSentinel(stateDir, sentinel) {
58190
58551
  await import_node_fs14.promises.mkdir(stateDir, { recursive: true });
58191
- const sentinelPath = import_node_path23.default.join(stateDir, SENTINEL_FILE_NAME);
58552
+ const sentinelPath = import_node_path24.default.join(stateDir, SENTINEL_FILE_NAME);
58192
58553
  const tmpPath = `${sentinelPath}.tmp-${process.pid}-${Math.random().toString(36).slice(2)}`;
58193
58554
  await import_node_fs14.promises.writeFile(tmpPath, JSON.stringify(sentinel), "utf8");
58194
58555
  await import_node_fs14.promises.rename(tmpPath, sentinelPath);
@@ -58518,12 +58879,12 @@ function startSchedulerTickLoop(deps) {
58518
58879
 
58519
58880
  // src/retention/pruner.ts
58520
58881
  var import_promises11 = require("node:fs/promises");
58521
- var import_node_path24 = __toESM(require("node:path"), 1);
58882
+ var import_node_path25 = __toESM(require("node:path"), 1);
58522
58883
  function protectedDayFloor(protectedSinceMs) {
58523
58884
  return new Date(protectedSinceMs).toISOString().slice(0, 10);
58524
58885
  }
58525
58886
  async function prune(stateDir, bounds) {
58526
- const logsDir = import_node_path24.default.join(stateDir, "logs");
58887
+ const logsDir = import_node_path25.default.join(stateDir, "logs");
58527
58888
  let entries;
58528
58889
  try {
58529
58890
  entries = await (0, import_promises11.readdir)(logsDir);
@@ -58539,7 +58900,7 @@ async function prune(stateDir, bounds) {
58539
58900
  for (const entry of entries) {
58540
58901
  const m = bridgeRe.exec(entry);
58541
58902
  if (!m?.[1]) continue;
58542
- const fullPath = import_node_path24.default.join(logsDir, entry);
58903
+ const fullPath = import_node_path25.default.join(logsDir, entry);
58543
58904
  const s = await (0, import_promises11.stat)(fullPath);
58544
58905
  files.push({ day: m[1], size: s.size, fullPath });
58545
58906
  }
@@ -58548,7 +58909,7 @@ async function prune(stateDir, bounds) {
58548
58909
  const reasonByDay = {};
58549
58910
  let bytesRemoved = 0;
58550
58911
  async function isDaySafeToDelete(day) {
58551
- const telemetryDir = import_node_path24.default.join(stateDir, "telemetry");
58912
+ const telemetryDir = import_node_path25.default.join(stateDir, "telemetry");
58552
58913
  let telemetryEntries;
58553
58914
  try {
58554
58915
  telemetryEntries = await (0, import_promises11.readdir)(telemetryDir);
@@ -58564,7 +58925,7 @@ async function prune(stateDir, bounds) {
58564
58925
  }
58565
58926
  if (projectSlugs.length === 0) return true;
58566
58927
  for (const slug of projectSlugs) {
58567
- const markerPath = import_node_path24.default.join(telemetryDir, `.processed-${slug}-${day}`);
58928
+ const markerPath = import_node_path25.default.join(telemetryDir, `.processed-${slug}-${day}`);
58568
58929
  try {
58569
58930
  await (0, import_promises11.stat)(markerPath);
58570
58931
  } catch (err) {
@@ -58614,7 +58975,7 @@ async function prune(stateDir, bounds) {
58614
58975
  const budgetOvershootBytes = Math.max(0, totalSize2 - budgetBytes);
58615
58976
  await emitPruneLog(stateDir, daysRemoved, reasonByDay, bytesRemoved, oldestDayRemaining);
58616
58977
  if (daysRemoved.length > 0) {
58617
- const sessionsPath = import_node_path24.default.join(logsDir, ".sessions.json");
58978
+ const sessionsPath = import_node_path25.default.join(logsDir, ".sessions.json");
58618
58979
  let sessionsObj = {};
58619
58980
  let fileExists = true;
58620
58981
  try {
@@ -58636,8 +58997,8 @@ async function prune(stateDir, bounds) {
58636
58997
  return { daysRemoved, reasonByDay, bytesRemoved, oldestDayRemaining, budgetOvershootBytes };
58637
58998
  }
58638
58999
  async function emitPruneLog(stateDir, daysRemoved, reasonByDay, bytesRemoved, oldestDayRemaining) {
58639
- const logsDir = import_node_path24.default.join(stateDir, "logs");
58640
- const logPath = import_node_path24.default.join(logsDir, ".pruned.jsonl");
59000
+ const logsDir = import_node_path25.default.join(stateDir, "logs");
59001
+ const logPath = import_node_path25.default.join(logsDir, ".pruned.jsonl");
58641
59002
  await (0, import_promises11.mkdir)(logsDir, { recursive: true });
58642
59003
  const record2 = { ts: Date.now(), dir: "logs", daysRemoved, reasonByDay, bytesRemoved, oldestDayRemaining };
58643
59004
  await (0, import_promises11.appendFile)(logPath, `${JSON.stringify(record2)}
@@ -58647,7 +59008,7 @@ async function emitPruneLog(stateDir, daysRemoved, reasonByDay, bytesRemoved, ol
58647
59008
  // src/telemetry/turn-aggregator.ts
58648
59009
  var import_node_crypto11 = require("node:crypto");
58649
59010
  var import_promises12 = require("node:fs/promises");
58650
- var import_node_path25 = require("node:path");
59011
+ var import_node_path26 = require("node:path");
58651
59012
  var BRIDGE_FILE_RE = /^bridge-(\d{4}-\d{2}-\d{2})\.jsonl$/;
58652
59013
  var PLUMBING_COUNTER_KEY = {
58653
59014
  socket_close: "socketCloses",
@@ -58676,7 +59037,7 @@ function inheritSlug(seeds, index) {
58676
59037
  return (preceding ?? following)?.slug;
58677
59038
  }
58678
59039
  async function foldClosedDays(stateDir, today) {
58679
- const logsDir = (0, import_node_path25.join)(stateDir, "logs");
59040
+ const logsDir = (0, import_node_path26.join)(stateDir, "logs");
58680
59041
  let entries;
58681
59042
  try {
58682
59043
  entries = await (0, import_promises12.readdir)(logsDir);
@@ -58688,7 +59049,7 @@ async function foldClosedDays(stateDir, today) {
58688
59049
  if (!m) continue;
58689
59050
  const day = m[1];
58690
59051
  if (day === today) continue;
58691
- const raw = await (0, import_promises12.readFile)((0, import_node_path25.join)(logsDir, entry), "utf8");
59052
+ const raw = await (0, import_promises12.readFile)((0, import_node_path26.join)(logsDir, entry), "utf8");
58692
59053
  const groups = /* @__PURE__ */ new Map();
58693
59054
  let groupCounter = 0;
58694
59055
  for (const line of raw.split("\n")) {
@@ -58799,10 +59160,10 @@ async function foldClosedDays(stateDir, today) {
58799
59160
  rowsByProject.set(slug, rows);
58800
59161
  }
58801
59162
  if (rowsByProject.size === 0) continue;
58802
- const telemetryDir = (0, import_node_path25.join)(stateDir, "telemetry");
59163
+ const telemetryDir = (0, import_node_path26.join)(stateDir, "telemetry");
58803
59164
  await (0, import_promises12.mkdir)(telemetryDir, { recursive: true });
58804
59165
  for (const [slug, rows] of rowsByProject) {
58805
- const finalPath = (0, import_node_path25.join)(telemetryDir, `rows-${slug}-${day}.jsonl`);
59166
+ const finalPath = (0, import_node_path26.join)(telemetryDir, `rows-${slug}-${day}.jsonl`);
58806
59167
  const tmpPath = `${finalPath}.tmp-${process.pid}-${(0, import_node_crypto11.randomBytes)(6).toString("hex")}`;
58807
59168
  try {
58808
59169
  await (0, import_promises12.writeFile)(tmpPath, rows.map((r) => JSON.stringify(r)).join("\n") + "\n", "utf8");
@@ -58817,27 +59178,27 @@ async function foldClosedDays(stateDir, today) {
58817
59178
 
58818
59179
  // src/telemetry/daily-uploader.ts
58819
59180
  var import_promises13 = require("node:fs/promises");
58820
- var import_node_path27 = require("node:path");
59181
+ var import_node_path28 = require("node:path");
58821
59182
 
58822
59183
  // src/telemetry/installation-id.ts
58823
59184
  var import_node_crypto12 = require("node:crypto");
58824
59185
  var import_node_fs15 = require("node:fs");
58825
- var import_node_path26 = require("node:path");
59186
+ var import_node_path27 = require("node:path");
58826
59187
  var FILE_NAME = "installation-id";
58827
59188
  var UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;
58828
59189
  var cache = /* @__PURE__ */ new Map();
58829
59190
  function resolveInstallationId(stateDir) {
58830
59191
  const cached2 = cache.get(stateDir);
58831
59192
  if (cached2 !== void 0) return cached2;
58832
- const path28 = (0, import_node_path26.join)(stateDir, FILE_NAME);
59193
+ const path29 = (0, import_node_path27.join)(stateDir, FILE_NAME);
58833
59194
  let id;
58834
59195
  try {
58835
- id = (0, import_node_fs15.readFileSync)(path28, "utf8").trim();
59196
+ id = (0, import_node_fs15.readFileSync)(path29, "utf8").trim();
58836
59197
  if (!UUID.test(id)) throw new Error("unusable");
58837
59198
  } catch {
58838
59199
  id = (0, import_node_crypto12.randomUUID)();
58839
- (0, import_node_fs15.mkdirSync)((0, import_node_path26.dirname)(path28), { recursive: true });
58840
- (0, import_node_fs15.writeFileSync)(path28, `${id}
59200
+ (0, import_node_fs15.mkdirSync)((0, import_node_path27.dirname)(path29), { recursive: true });
59201
+ (0, import_node_fs15.writeFileSync)(path29, `${id}
58841
59202
  `, "utf8");
58842
59203
  }
58843
59204
  cache.set(stateDir, id);
@@ -58854,7 +59215,7 @@ function truncateCause(err) {
58854
59215
  return `${message.slice(0, MAX_CAUSE_CHARS - 3)}...`;
58855
59216
  }
58856
59217
  async function uploadPendingDays(stateDir, client, bridgeHealth, gateCtx) {
58857
- const telemetryDir = (0, import_node_path27.join)(stateDir, "telemetry");
59218
+ const telemetryDir = (0, import_node_path28.join)(stateDir, "telemetry");
58858
59219
  let files;
58859
59220
  try {
58860
59221
  files = await (0, import_promises13.readdir)(telemetryDir);
@@ -58870,14 +59231,14 @@ async function uploadPendingDays(stateDir, client, bridgeHealth, gateCtx) {
58870
59231
  const [, projectSlug, day] = match;
58871
59232
  const key = `${projectSlug}\0${day}`;
58872
59233
  const entry = discovered.get(key) ?? { projectSlug, day, rowsPath: null };
58873
- if (rowsMatch) entry.rowsPath = (0, import_node_path27.join)(telemetryDir, file2);
59234
+ if (rowsMatch) entry.rowsPath = (0, import_node_path28.join)(telemetryDir, file2);
58874
59235
  discovered.set(key, entry);
58875
59236
  }
58876
59237
  const today = telemetryDay();
58877
59238
  const pending = [];
58878
59239
  const deferred = [];
58879
59240
  for (const { projectSlug, day, rowsPath } of discovered.values()) {
58880
- const markerPath = (0, import_node_path27.join)(telemetryDir, `.processed-${projectSlug}-${day}`);
59241
+ const markerPath = (0, import_node_path28.join)(telemetryDir, `.processed-${projectSlug}-${day}`);
58881
59242
  if (rowsPath === null && day >= today) {
58882
59243
  try {
58883
59244
  await (0, import_promises13.access)(markerPath);
@@ -58897,7 +59258,7 @@ async function uploadPendingDays(stateDir, client, bridgeHealth, gateCtx) {
58897
59258
  const fullUnprocessed = [...pending.map((p) => ({ projectSlug: p.projectSlug, day: p.day })), ...deferred];
58898
59259
  pending.sort((a, b) => a.day.localeCompare(b.day));
58899
59260
  for (const cur of pending) {
58900
- const failurePath = (0, import_node_path27.join)(telemetryDir, `.failed-${cur.projectSlug}-${cur.day}.json`);
59261
+ const failurePath = (0, import_node_path28.join)(telemetryDir, `.failed-${cur.projectSlug}-${cur.day}.json`);
58901
59262
  let failureState = null;
58902
59263
  try {
58903
59264
  const data = await (0, import_promises13.readFile)(failurePath, "utf8");
@@ -58931,7 +59292,7 @@ async function uploadPendingDays(stateDir, client, bridgeHealth, gateCtx) {
58931
59292
  }
58932
59293
  const gateCalls = [];
58933
59294
  try {
58934
- const rawGate = await (0, import_promises13.readFile)((0, import_node_path27.join)(telemetryDir, gateFileName(cur.projectSlug, cur.day)), "utf8");
59295
+ const rawGate = await (0, import_promises13.readFile)((0, import_node_path28.join)(telemetryDir, gateFileName(cur.projectSlug, cur.day)), "utf8");
58935
59296
  for (const line of rawGate.split("\n")) {
58936
59297
  if (!line.trim()) continue;
58937
59298
  try {
@@ -59133,7 +59494,7 @@ async function collectAgentPoolSnapshot(deps) {
59133
59494
  }
59134
59495
 
59135
59496
  // src/external-agents-spawn.ts
59136
- var import_node_child_process15 = require("node:child_process");
59497
+ var import_node_child_process16 = require("node:child_process");
59137
59498
  function runExternalAgentsCli(args, opts) {
59138
59499
  let command;
59139
59500
  let prefixArgs;
@@ -59164,7 +59525,7 @@ function runExternalAgentsCli(args, opts) {
59164
59525
  };
59165
59526
  let spawned;
59166
59527
  try {
59167
- spawned = (0, import_node_child_process15.spawn)(command, [...prefixArgs, ...args], { stdio: stdioConfig });
59528
+ spawned = (0, import_node_child_process16.spawn)(command, [...prefixArgs, ...args], { stdio: stdioConfig });
59168
59529
  } catch {
59169
59530
  done(1);
59170
59531
  return;
@@ -59276,14 +59637,14 @@ function startAgentPoolLoop(deps) {
59276
59637
  }
59277
59638
 
59278
59639
  // src/provider-readiness-loop.ts
59279
- var import_node_child_process16 = require("node:child_process");
59640
+ var import_node_child_process17 = require("node:child_process");
59280
59641
  var DEFAULT_INTERVAL_MS3 = 6e4;
59281
59642
  function providerReadinessLoopDisabled(env = process.env) {
59282
59643
  return env["MRRLIN_BRIDGE_PROVIDER_READINESS_DISABLE"] === "1";
59283
59644
  }
59284
59645
  function defaultRunnerFor(command) {
59285
59646
  return (args) => {
59286
- const r = (0, import_node_child_process16.spawnSync)(command, args, { encoding: "utf8", timeout: 8e3 });
59647
+ const r = (0, import_node_child_process17.spawnSync)(command, args, { encoding: "utf8", timeout: 8e3 });
59287
59648
  return { status: r.status, stdout: r.stdout ?? "", stderr: r.stderr ?? "" };
59288
59649
  };
59289
59650
  }
@@ -59326,9 +59687,9 @@ function startProviderReadinessLoop(deps) {
59326
59687
  }
59327
59688
 
59328
59689
  // src/execution-consumer.ts
59329
- var import_node_child_process18 = require("node:child_process");
59690
+ var import_node_child_process19 = require("node:child_process");
59330
59691
  var import_node_crypto13 = __toESM(require("node:crypto"), 1);
59331
- var import_node_path30 = __toESM(require("node:path"), 1);
59692
+ var import_node_path31 = __toESM(require("node:path"), 1);
59332
59693
  var import_node_util2 = require("node:util");
59333
59694
 
59334
59695
  // src/notify-templates.ts
@@ -60182,17 +60543,17 @@ async function awaitTurnWithDeadline(opts) {
60182
60543
  }
60183
60544
 
60184
60545
  // src/worktree.ts
60185
- var import_node_child_process17 = require("node:child_process");
60546
+ var import_node_child_process18 = require("node:child_process");
60186
60547
  var import_node_fs17 = require("node:fs");
60187
- var import_node_path29 = require("node:path");
60548
+ var import_node_path30 = require("node:path");
60188
60549
 
60189
60550
  // src/checkout-lock.ts
60190
60551
  var import_node_fs16 = require("node:fs");
60191
- var import_node_path28 = require("node:path");
60552
+ var import_node_path29 = require("node:path");
60192
60553
  var import_proper_lockfile = __toESM(require_proper_lockfile(), 1);
60193
60554
  async function withCheckoutLock(locksDir, slug, fn) {
60194
60555
  (0, import_node_fs16.mkdirSync)(locksDir, { recursive: true });
60195
- const target = (0, import_node_path28.join)(locksDir, `${slug}.lock`);
60556
+ const target = (0, import_node_path29.join)(locksDir, `${slug}.lock`);
60196
60557
  if (!(0, import_node_fs16.existsSync)(target)) (0, import_node_fs16.writeFileSync)(target, "");
60197
60558
  const release = await import_proper_lockfile.default.lock(target, {
60198
60559
  retries: { retries: 600, factor: 1, minTimeout: 100, maxTimeout: 100 },
@@ -60209,16 +60570,16 @@ async function withCheckoutLock(locksDir, slug, fn) {
60209
60570
  function worktreeBranch(runId) {
60210
60571
  return `mrrlin/run-${runId}`;
60211
60572
  }
60212
- var defaultGitExec = (args, env) => (0, import_node_child_process17.execFileSync)("git", args, { encoding: "utf8", timeout: 3e4, env });
60573
+ var defaultGitExec = (args, env) => (0, import_node_child_process18.execFileSync)("git", args, { encoding: "utf8", timeout: 3e4, env });
60213
60574
  function git(checkout, args) {
60214
- return (0, import_node_child_process17.execFileSync)("git", ["-C", checkout, ...args], {
60575
+ return (0, import_node_child_process18.execFileSync)("git", ["-C", checkout, ...args], {
60215
60576
  encoding: "utf8",
60216
60577
  timeout: 3e4,
60217
60578
  env: { ...process.env, GIT_TERMINAL_PROMPT: "0" }
60218
60579
  });
60219
60580
  }
60220
60581
  async function createRunWorktree(opts) {
60221
- const worktreePath = (0, import_node_path29.join)(opts.worktreeRoot, opts.slug, opts.runId);
60582
+ const worktreePath = (0, import_node_path30.join)(opts.worktreeRoot, opts.slug, opts.runId);
60222
60583
  await withCheckoutLock(opts.locksDir, opts.slug, async () => {
60223
60584
  (0, import_node_fs17.mkdirSync)(opts.worktreeRoot, { recursive: true });
60224
60585
  try {
@@ -60331,17 +60692,28 @@ async function sweepOrphanWorktrees(opts) {
60331
60692
  const reaped = [];
60332
60693
  const ownedPrefix = (() => {
60333
60694
  try {
60334
- return (0, import_node_fs17.realpathSync)(opts.worktreeRoot);
60695
+ return (import_node_fs17.realpathSync.native ?? import_node_fs17.realpathSync)(opts.worktreeRoot);
60335
60696
  } catch {
60336
60697
  return opts.worktreeRoot;
60337
60698
  }
60338
- })() + import_node_path29.sep + opts.slug + import_node_path29.sep;
60699
+ })() + import_node_path30.sep + opts.slug + import_node_path30.sep;
60339
60700
  await withCheckoutLock(opts.locksDir, opts.slug, async () => {
60340
60701
  const listing = git(opts.checkout, ["worktree", "list", "--porcelain"]);
60341
60702
  for (const block of listing.split("\n\n")) {
60342
60703
  const m = /^worktree (.+)$/m.exec(block);
60343
- const wt = m?.[1];
60344
- if (wt && wt.startsWith(ownedPrefix) && opts.isReapable(wt)) {
60704
+ const wt = m?.[1]?.trim();
60705
+ if (!wt) continue;
60706
+ const canonicalWt = (() => {
60707
+ try {
60708
+ return (import_node_fs17.realpathSync.native ?? import_node_fs17.realpathSync)(wt);
60709
+ } catch {
60710
+ return wt;
60711
+ }
60712
+ })();
60713
+ const normWt = (0, import_node_path30.normalize)(canonicalWt);
60714
+ const normPrefix = (0, import_node_path30.normalize)(ownedPrefix);
60715
+ const isMatch = process.platform === "win32" ? normWt.toLowerCase().startsWith(normPrefix.toLowerCase()) : normWt.startsWith(normPrefix);
60716
+ if (isMatch && opts.isReapable(wt)) {
60345
60717
  try {
60346
60718
  git(opts.checkout, ["worktree", "remove", "--force", wt]);
60347
60719
  reaped.push(wt);
@@ -60509,6 +60881,13 @@ async function notifyPinRetirementIfRetired(seat, opts) {
60509
60881
  }
60510
60882
 
60511
60883
  // src/execution-consumer.ts
60884
+ var WorkspaceBoundaryError = class extends Error {
60885
+ code = "workspace_boundary_unresolvable";
60886
+ constructor(message, options) {
60887
+ super(message, options);
60888
+ this.name = "WorkspaceBoundaryError";
60889
+ }
60890
+ };
60512
60891
  var DEFAULT_STALE_SECONDS = 300;
60513
60892
  var DEFAULT_MAX_LEASE_RECLAIMS = 3;
60514
60893
  var DEFAULT_TOUCH_INTERVAL_MS = 6e4;
@@ -60646,6 +61025,13 @@ var BASE_INSTRUCTIONS_PREFIX = [
60646
61025
  "Durable truth lives in execution artifacts and task events, not in this thread \u2014 record",
60647
61026
  "concrete progress via MCP tools rather than only narrating it.",
60648
61027
  "",
61028
+ "Workspace boundary and client isolation (OQ-091):",
61029
+ "- You are strictly isolated to the active client and project identified in the Workspace Boundary header.",
61030
+ "- Never borrow, adapt, or reference styling, design, components, or domain logic from other clients or projects.",
61031
+ "- If specifications, assets, or requirements for the current client are missing or ambiguous, do NOT guess",
61032
+ ' or borrow from another client. Instead, file an inbox question (`create_inbox_item` kind="question") to request',
61033
+ " clarification from the operator, and halt execution rather than contaminating the client workspace.",
61034
+ "",
60649
61035
  "Completion contract (the run is gated on this):",
60650
61036
  "- Act now, in this turn, whenever the tools to do the work are in reach, the work does not",
60651
61037
  " depend on waiting for external state, and any irreversible outward action it takes is already",
@@ -60861,10 +61247,10 @@ function newArtifactId() {
60861
61247
  return `EA-${import_node_crypto13.default.randomUUID()}`;
60862
61248
  }
60863
61249
  var BLAST_RADIUS_FLOOR_PATTERNS = [/^supabase\/migrations\//, /^packages\/db\/src\/schema\.ts$/];
60864
- function isBlastRadiusFloorPath(path28) {
60865
- return BLAST_RADIUS_FLOOR_PATTERNS.some((re) => re.test(path28));
61250
+ function isBlastRadiusFloorPath(path29) {
61251
+ return BLAST_RADIUS_FLOOR_PATTERNS.some((re) => re.test(path29));
60866
61252
  }
60867
- var execFileAsync2 = (0, import_node_util2.promisify)(import_node_child_process18.execFile);
61253
+ var execFileAsync2 = (0, import_node_util2.promisify)(import_node_child_process19.execFile);
60868
61254
  async function defaultListRunDiffPaths(opts) {
60869
61255
  const parse8 = (stdout) => stdout.split("\n").map((line) => line.trim()).filter((line) => line.length > 0);
60870
61256
  try {
@@ -60902,7 +61288,31 @@ async function resolveEffectiveRisk(deps, worktreePath, projectSlug, review) {
60902
61288
  }
60903
61289
  return { risk, reason };
60904
61290
  }
60905
- async function gatherContext(client, projectSlug, task, openRunId) {
61291
+ async function gatherContext(client, projectSlug, task, openRunId, rawProjectInput) {
61292
+ let rawProject = rawProjectInput;
61293
+ if (!rawProject) {
61294
+ try {
61295
+ rawProject = await client.getProject(projectSlug);
61296
+ if (!rawProject) {
61297
+ throw new WorkspaceBoundaryError(`Project profile for slug "${projectSlug}" was not found.`);
61298
+ }
61299
+ } catch (error51) {
61300
+ if (error51 instanceof WorkspaceBoundaryError) {
61301
+ throw error51;
61302
+ }
61303
+ throw new WorkspaceBoundaryError(
61304
+ `Failed to retrieve project profile for slug "${projectSlug}": ${error51?.message ?? error51}`,
61305
+ { cause: error51 }
61306
+ );
61307
+ }
61308
+ }
61309
+ const scope = resolveProjectClientScope(rawProject);
61310
+ const projectBoundary = {
61311
+ slug: rawProject.slug,
61312
+ displayName: rawProject.displayName,
61313
+ clientName: scope.clientName,
61314
+ scopeDescription: scope.scopeDescription
61315
+ };
60906
61316
  const runs = (await client.listExecutionRuns(projectSlug, { taskId: task.id })).sort(
60907
61317
  (a, b) => a.createdAt.localeCompare(b.createdAt)
60908
61318
  );
@@ -60925,6 +61335,7 @@ async function gatherContext(client, projectSlug, task, openRunId) {
60925
61335
  }
60926
61336
  }
60927
61337
  return {
61338
+ project: projectBoundary,
60928
61339
  task: {
60929
61340
  id: task.id,
60930
61341
  title: task.title,
@@ -61254,15 +61665,50 @@ async function driveRun(deps, projectSlug, runId) {
61254
61665
  }
61255
61666
  }
61256
61667
  }
61668
+ let rawProject;
61669
+ try {
61670
+ rawProject = await deps.client.getProject(projectSlug);
61671
+ if (!rawProject) {
61672
+ throw new WorkspaceBoundaryError(`Project profile for slug "${projectSlug}" was not found.`);
61673
+ }
61674
+ } catch (error51) {
61675
+ await failRun(
61676
+ deps,
61677
+ projectSlug,
61678
+ task,
61679
+ runId,
61680
+ leaseId,
61681
+ `workspace_boundary_unresolvable: ${error51?.message ?? error51}`,
61682
+ "workspace_boundary_unresolvable"
61683
+ );
61684
+ return;
61685
+ }
61257
61686
  const runDomains = Array.isArray(task.domains) ? task.domains : [task.domains ?? "code"];
61258
61687
  const isPureCode = runDomains.length === 1 && runDomains[0] === "code";
61259
61688
  if (!isPureCode) {
61260
61689
  const runDomain = runDomains[0] ?? "code";
61261
- await driveNonCodeRun(deps, projectSlug, runId, leaseId, task, runDomain);
61690
+ await driveNonCodeRun(deps, projectSlug, runId, leaseId, task, runDomain, rawProject);
61262
61691
  return;
61263
61692
  }
61264
61693
  const compactEnabled = (process.env.MRRLIN_MCP_COMPACT_DISABLE ?? "").trim() !== "1";
61265
- const context = await gatherContext(deps.client, projectSlug, task, runId);
61694
+ let context;
61695
+ try {
61696
+ context = await gatherContext(deps.client, projectSlug, task, runId, rawProject);
61697
+ } catch (error51) {
61698
+ if (error51 instanceof WorkspaceBoundaryError) {
61699
+ await failRun(
61700
+ deps,
61701
+ projectSlug,
61702
+ task,
61703
+ runId,
61704
+ leaseId,
61705
+ `workspace_boundary_unresolvable: ${error51.message}`,
61706
+ "workspace_boundary_unresolvable"
61707
+ );
61708
+ return;
61709
+ }
61710
+ throw error51;
61711
+ }
61266
61712
  let bundle = renderContextBundle(
61267
61713
  compactEnabled ? {
61268
61714
  ...context,
@@ -61931,10 +62377,18 @@ function parseNonCodeResultEnvelope(stdout) {
61931
62377
  }
61932
62378
  return { outcome, resultSummary, markdownBody };
61933
62379
  }
61934
- function buildDeliverableAuthorPrompt(task, specMarkdown) {
62380
+ function buildDeliverableAuthorPrompt(task, specMarkdown, project) {
61935
62381
  return [
61936
62382
  `Produce the deliverable for the task below. Write the FULL deliverable content as markdown.`,
61937
62383
  ``,
62384
+ ...project ? [
62385
+ `--- WORKSPACE BOUNDARY ---`,
62386
+ `client: ${project.clientName || "(unspecified)"}`,
62387
+ `project: ${project.displayName} (${project.slug})`,
62388
+ ...project.scopeDescription ? [`scope: ${project.scopeDescription}`] : [],
62389
+ `boundary rule: All authored artifacts must belong exclusively to this workspace. Do not mix with or reference external clients.`,
62390
+ ``
62391
+ ] : [],
61938
62392
  `--- TASK ---`,
61939
62393
  `id: ${task.id}`,
61940
62394
  `title: ${task.title}`,
@@ -62042,7 +62496,34 @@ async function writeNegativeResultEvidencePage(client, projectSlug, task, input)
62042
62496
  }
62043
62497
  throw new Error(`could not allocate negative-result evidence page for ${task.id} (last conflict: ${lastConflict})`);
62044
62498
  }
62045
- async function driveNonCodeRun(deps, projectSlug, runId, leaseId, task, domain2) {
62499
+ async function driveNonCodeRun(deps, projectSlug, runId, leaseId, task, domain2, project) {
62500
+ let rawProject = project;
62501
+ if (!rawProject) {
62502
+ try {
62503
+ rawProject = await deps.client.getProject(projectSlug);
62504
+ if (!rawProject) {
62505
+ throw new WorkspaceBoundaryError(`Project profile for slug "${projectSlug}" was not found.`);
62506
+ }
62507
+ } catch (error51) {
62508
+ await failRun(
62509
+ deps,
62510
+ projectSlug,
62511
+ task,
62512
+ runId,
62513
+ leaseId,
62514
+ `workspace_boundary_unresolvable: ${error51?.message ?? error51}`,
62515
+ "workspace_boundary_unresolvable"
62516
+ );
62517
+ return;
62518
+ }
62519
+ }
62520
+ const scope = resolveProjectClientScope(rawProject);
62521
+ const projectBoundary = {
62522
+ slug: rawProject.slug,
62523
+ displayName: rawProject.displayName,
62524
+ clientName: scope.clientName,
62525
+ scopeDescription: scope.scopeDescription
62526
+ };
62046
62527
  const personaName = resolveProducerPersona(domain2);
62047
62528
  if (!personaName) {
62048
62529
  await failRun(
@@ -62104,7 +62585,7 @@ async function driveNonCodeRun(deps, projectSlug, runId, leaseId, task, domain2)
62104
62585
  let parsedResult;
62105
62586
  try {
62106
62587
  const exec = await runExec({
62107
- prompt: buildDeliverableAuthorPrompt(task, specMarkdown),
62588
+ prompt: buildDeliverableAuthorPrompt(task, specMarkdown, projectBoundary),
62108
62589
  developerInstructions: persona,
62109
62590
  cwd: deps.codexCwd ?? process.cwd(),
62110
62591
  timeoutMs: DELIVERABLE_AUTHOR_TIMEOUT_MS,
@@ -62598,8 +63079,8 @@ async function runBackstopSweep(deps, drive = (slug, id) => driveRun(deps, slug,
62598
63079
  function isRunRecoverableByThisBridge(run3, worktreeRoot) {
62599
63080
  if (!worktreeRoot) return true;
62600
63081
  if (!run3.worktreeId) return true;
62601
- const relative = import_node_path30.default.relative(import_node_path30.default.resolve(worktreeRoot), import_node_path30.default.resolve(run3.worktreeId));
62602
- return relative === "" || relative.length > 0 && !relative.startsWith("..") && !import_node_path30.default.isAbsolute(relative);
63082
+ const relative = import_node_path31.default.relative(import_node_path31.default.resolve(worktreeRoot), import_node_path31.default.resolve(run3.worktreeId));
63083
+ return relative === "" || relative.length > 0 && !relative.startsWith("..") && !import_node_path31.default.isAbsolute(relative);
62603
63084
  }
62604
63085
  async function deployGateHandoff(deps, projectSlug, task, runId, reason, leaseId) {
62605
63086
  await deps.client.updateExecutionRun(projectSlug, runId, { status: "failed", finishedAt: (/* @__PURE__ */ new Date()).toISOString(), leaseId: leaseId ?? void 0 }).catch(() => {
@@ -62804,12 +63285,12 @@ async function runAsyncBackstopSweep(deps, drive = (slug, jobId) => driveAsyncJo
62804
63285
  // src/bridge-artifacts.ts
62805
63286
  var import_node_fs18 = __toESM(require("node:fs"), 1);
62806
63287
  var import_promises14 = __toESM(require("node:fs/promises"), 1);
62807
- var import_node_path31 = __toESM(require("node:path"), 1);
63288
+ var import_node_path32 = __toESM(require("node:path"), 1);
62808
63289
  var DEFAULT_MAX_ARTIFACTS_BYTES = 500 * 1024 * 1024;
62809
63290
  var DEFAULT_MAX_ARTIFACT_AGE_MS = 7 * 24 * 60 * 60 * 1e3;
62810
63291
  function resolveArtifactsDir(baseStateDir) {
62811
63292
  const stateDir = baseStateDir ?? resolveStateDir();
62812
- return import_node_path31.default.join(stateDir, "artifacts");
63293
+ return import_node_path32.default.join(stateDir, "artifacts");
62813
63294
  }
62814
63295
  function ensureDir(dir) {
62815
63296
  import_node_fs18.default.mkdirSync(dir, { recursive: true, mode: 448 });
@@ -62822,7 +63303,7 @@ function safeArtifactPath(artifactsDir, id) {
62822
63303
  if (!id || typeof id !== "string" || !/^[a-zA-Z0-9_-]+$/.test(id)) {
62823
63304
  throw new Error("Invalid artifact id");
62824
63305
  }
62825
- return import_node_path31.default.join(artifactsDir, `${id}.json`);
63306
+ return import_node_path32.default.join(artifactsDir, `${id}.json`);
62826
63307
  }
62827
63308
  async function writeLocalArtifact(id, payload, baseStateDir) {
62828
63309
  const artifactsDir = resolveArtifactsDir(baseStateDir);
@@ -62865,7 +63346,7 @@ async function cleanArtifacts(baseStateDir, options) {
62865
63346
  let deletedBytes = 0;
62866
63347
  for (const name of entries) {
62867
63348
  if (!name.endsWith(".json")) continue;
62868
- const filePath = import_node_path31.default.join(artifactsDir, name);
63349
+ const filePath = import_node_path32.default.join(artifactsDir, name);
62869
63350
  try {
62870
63351
  const stat3 = await import_promises14.default.stat(filePath);
62871
63352
  if (now - stat3.mtimeMs > maxAgeMs) {
@@ -63093,9 +63574,9 @@ function agentIdleMs(provider) {
63093
63574
 
63094
63575
  // src/thread-index.ts
63095
63576
  var import_node_fs19 = require("node:fs");
63096
- var import_node_path32 = __toESM(require("node:path"), 1);
63577
+ var import_node_path33 = __toESM(require("node:path"), 1);
63097
63578
  function threadIndexPath(stateDir) {
63098
- return import_node_path32.default.join(stateDir, "threads.json");
63579
+ return import_node_path33.default.join(stateDir, "threads.json");
63099
63580
  }
63100
63581
  function loadThreadIndex(stateDir, ttlMs, now) {
63101
63582
  const result = /* @__PURE__ */ new Map();
@@ -63263,7 +63744,7 @@ function createToolBusyClock(opts) {
63263
63744
  var import_node_events3 = require("node:events");
63264
63745
  var import_node_fs20 = require("node:fs");
63265
63746
  var import_node_os14 = require("node:os");
63266
- var import_node_path33 = require("node:path");
63747
+ var import_node_path34 = require("node:path");
63267
63748
 
63268
63749
  // ../../node_modules/.pnpm/@noble+hashes@1.3.3/node_modules/@noble/hashes/esm/cryptoNode.js
63269
63750
  var nc = __toESM(require("node:crypto"), 1);
@@ -66834,9 +67315,9 @@ var DirectorRelay = class {
66834
67315
 
66835
67316
  // src/remote-phone-relay.ts
66836
67317
  function loadOrCreateAgentDeviceKey() {
66837
- const path28 = (0, import_node_path33.join)((0, import_node_os14.homedir)(), ".mrrlin", "agent-device-key");
67318
+ const path29 = (0, import_node_path34.join)((0, import_node_os14.homedir)(), ".mrrlin", "agent-device-key");
66838
67319
  try {
66839
- const raw = JSON.parse((0, import_node_fs20.readFileSync)(path28, "utf8"));
67320
+ const raw = JSON.parse((0, import_node_fs20.readFileSync)(path29, "utf8"));
66840
67321
  if (typeof raw.priv === "string" && typeof raw.pub === "string") {
66841
67322
  return { privateKey: fromBase64Url(raw.priv), publicKey: fromBase64Url(raw.pub) };
66842
67323
  }
@@ -66844,9 +67325,9 @@ function loadOrCreateAgentDeviceKey() {
66844
67325
  }
66845
67326
  const kp = generateIdentityKeyPair();
66846
67327
  try {
66847
- (0, import_node_fs20.mkdirSync)((0, import_node_path33.join)((0, import_node_os14.homedir)(), ".mrrlin"), { recursive: true });
67328
+ (0, import_node_fs20.mkdirSync)((0, import_node_path34.join)((0, import_node_os14.homedir)(), ".mrrlin"), { recursive: true });
66848
67329
  (0, import_node_fs20.writeFileSync)(
66849
- path28,
67330
+ path29,
66850
67331
  JSON.stringify({ priv: toBase64Url(kp.privateKey), pub: toBase64Url(kp.publicKey) }),
66851
67332
  { mode: 384 }
66852
67333
  );
@@ -66854,7 +67335,7 @@ function loadOrCreateAgentDeviceKey() {
66854
67335
  }
66855
67336
  return kp;
66856
67337
  }
66857
- var AGENT_PAIRING_PATH = (0, import_node_path33.join)((0, import_node_os14.homedir)(), ".mrrlin", "agent-pairing.json");
67338
+ var AGENT_PAIRING_PATH = (0, import_node_path34.join)((0, import_node_os14.homedir)(), ".mrrlin", "agent-pairing.json");
66858
67339
  function loadAgentPairing() {
66859
67340
  try {
66860
67341
  const raw = JSON.parse((0, import_node_fs20.readFileSync)(AGENT_PAIRING_PATH, "utf8"));
@@ -66872,7 +67353,7 @@ function loadAgentPairing() {
66872
67353
  }
66873
67354
  function saveAgentPairing(record2) {
66874
67355
  try {
66875
- (0, import_node_fs20.mkdirSync)((0, import_node_path33.join)((0, import_node_os14.homedir)(), ".mrrlin"), { recursive: true });
67356
+ (0, import_node_fs20.mkdirSync)((0, import_node_path34.join)((0, import_node_os14.homedir)(), ".mrrlin"), { recursive: true });
66876
67357
  (0, import_node_fs20.writeFileSync)(AGENT_PAIRING_PATH, JSON.stringify(record2), { mode: 384 });
66877
67358
  } catch {
66878
67359
  }
@@ -67051,11 +67532,11 @@ async function renderPairingQrSvg(payload) {
67051
67532
  }
67052
67533
 
67053
67534
  // src/executor-server.ts
67054
- var import_node_child_process19 = require("node:child_process");
67535
+ var import_node_child_process20 = require("node:child_process");
67055
67536
  function defaultReadinessRunner(provider) {
67056
67537
  const command = provider === "claude" ? "claude" : "codex";
67057
67538
  return (args) => {
67058
- const r = (0, import_node_child_process19.spawnSync)(command, args, { encoding: "utf8", timeout: 8e3, shell: true });
67539
+ const r = (0, import_node_child_process20.spawnSync)(command, args, { encoding: "utf8", timeout: 8e3, shell: true });
67059
67540
  return { status: r.status, stdout: r.stdout ?? "", stderr: r.stderr ?? "" };
67060
67541
  };
67061
67542
  }
@@ -67180,7 +67661,7 @@ function createSelfReviewTurn(deps) {
67180
67661
  // src/director-reseed.ts
67181
67662
  var import_node_fs21 = require("node:fs");
67182
67663
  var import_node_readline = require("node:readline");
67183
- var import_node_path34 = require("node:path");
67664
+ var import_node_path35 = require("node:path");
67184
67665
  function estimateTokens(s) {
67185
67666
  return Buffer.byteLength(s, "utf8");
67186
67667
  }
@@ -67329,7 +67810,7 @@ async function readSessionRows(logsDir, files, sessionIds) {
67329
67810
  const lines2 = [];
67330
67811
  let missingFiles = 0;
67331
67812
  for (const f of files) {
67332
- const filePath = (0, import_node_path34.join)(logsDir, f);
67813
+ const filePath = (0, import_node_path35.join)(logsDir, f);
67333
67814
  try {
67334
67815
  const stream = (0, import_node_fs21.createReadStream)(filePath, { encoding: "utf8" });
67335
67816
  const rl = (0, import_node_readline.createInterface)({ input: stream, crlfDelay: Infinity });
@@ -67357,10 +67838,10 @@ async function readSessionRows(logsDir, files, sessionIds) {
67357
67838
  // src/external-agents-scrub.ts
67358
67839
  var import_node_fs22 = __toESM(require("node:fs"), 1);
67359
67840
  var import_node_os15 = __toESM(require("node:os"), 1);
67360
- var import_node_path35 = __toESM(require("node:path"), 1);
67841
+ var import_node_path36 = __toESM(require("node:path"), 1);
67361
67842
  var REDACTION = "[REDACTED]";
67362
67843
  var SHORT_VALUE_THRESHOLD = 8;
67363
- var KEYS_ENV_PATH = () => import_node_path35.default.join(import_node_os15.default.homedir(), ".local", "state", "external-agents", "keys.env");
67844
+ var KEYS_ENV_PATH = () => import_node_path36.default.join(import_node_os15.default.homedir(), ".local", "state", "external-agents", "keys.env");
67364
67845
  var keysEnvCache = null;
67365
67846
  function readKeysEnv() {
67366
67847
  const filePath = KEYS_ENV_PATH();
@@ -67804,9 +68285,9 @@ function readKnownGptSlugsFromTomlFile(filePath) {
67804
68285
  return Array.from(raw.matchAll(/^\s*model\s*=\s*"([^"]+)"/gm)).map((match) => match[1]?.trim() ?? "").filter(isSelectableModelSlug);
67805
68286
  }
67806
68287
  function readCodexFallbackModels() {
67807
- const codexHome = process.env.CODEX_HOME?.trim() || import_node_path37.default.join(import_node_os17.default.homedir(), ".codex");
68288
+ const codexHome = process.env.CODEX_HOME?.trim() || import_node_path38.default.join(import_node_os17.default.homedir(), ".codex");
67808
68289
  const models = /* @__PURE__ */ new Map();
67809
- const cachePath = import_node_path37.default.join(codexHome, "models_cache.json");
68290
+ const cachePath = import_node_path38.default.join(codexHome, "models_cache.json");
67810
68291
  const cacheRaw = readTextIfExists(cachePath);
67811
68292
  if (cacheRaw) {
67812
68293
  try {
@@ -67856,7 +68337,7 @@ function readCodexFallbackModels() {
67856
68337
  );
67857
68338
  }
67858
68339
  }
67859
- for (const slug of readKnownGptSlugsFromTomlFile(import_node_path37.default.join(codexHome, "config.toml"))) {
68340
+ for (const slug of readKnownGptSlugsFromTomlFile(import_node_path38.default.join(codexHome, "config.toml"))) {
67860
68341
  addBridgeModel(
67861
68342
  models,
67862
68343
  mapBridgeModel({
@@ -67870,11 +68351,11 @@ function readCodexFallbackModels() {
67870
68351
  })
67871
68352
  );
67872
68353
  }
67873
- const automationsDir = import_node_path37.default.join(codexHome, "automations");
68354
+ const automationsDir = import_node_path38.default.join(codexHome, "automations");
67874
68355
  try {
67875
68356
  for (const entry of import_node_fs23.default.readdirSync(automationsDir, { withFileTypes: true })) {
67876
68357
  if (!entry.isDirectory()) continue;
67877
- for (const slug of readKnownGptSlugsFromTomlFile(import_node_path37.default.join(automationsDir, entry.name, "automation.toml"))) {
68358
+ for (const slug of readKnownGptSlugsFromTomlFile(import_node_path38.default.join(automationsDir, entry.name, "automation.toml"))) {
67878
68359
  addBridgeModel(
67879
68360
  models,
67880
68361
  mapBridgeModel({
@@ -67900,9 +68381,15 @@ function selfUpdateInboxItemId(offeredVersion) {
67900
68381
  return `II-MCPUPD-${offeredVersion.replace(/[^A-Za-z0-9._-]/g, "-")}-${hash3}`;
67901
68382
  }
67902
68383
  function neutralCheckoutCwd(stateDir) {
67903
- const dir = import_node_path37.default.join(stateDir, "no-checkout");
68384
+ const dir = import_node_path38.default.join(stateDir, "no-checkout");
67904
68385
  try {
67905
68386
  import_node_fs23.default.mkdirSync(dir, { recursive: true });
68387
+ if (!import_node_fs23.default.existsSync(import_node_path38.default.join(dir, ".git"))) {
68388
+ try {
68389
+ (0, import_node_child_process21.spawnSync)("git", ["init", "-b", "main"], { cwd: dir, stdio: "ignore" });
68390
+ } catch {
68391
+ }
68392
+ }
67906
68393
  } catch {
67907
68394
  }
67908
68395
  return dir;
@@ -68005,6 +68492,12 @@ function buildThreadStartParams(msg, config2, desiredModel) {
68005
68492
  "turn with one sentence restating your understanding, then at most 3 scope-level questions, and",
68006
68493
  "do NOT create the task yet. Create it after the operator replies.",
68007
68494
  "",
68495
+ "Once the operator replies and clarifies or confirms the scope (or if scope was already clear),",
68496
+ "you MUST materialize the work onto the board: create the plan (if needed) and call `create_task`",
68497
+ "in the same turn so actionable task cards appear on `/tasks` immediately. Never leave the board",
68498
+ "empty with 0 tasks after agreeing on scope. Never claim tasks are created, queued, or ready unless",
68499
+ "`create_task` was actually invoked and returned the task ID.",
68500
+ "",
68008
68501
  "Set operatorSeedRequest to the operator's OWN WORDS, verbatim. Select every message in this",
68009
68502
  "conversation that forms part of the request \u2014 not only the last one \u2014 and concatenate them in",
68010
68503
  "order, separated by a blank line. Do NOT paraphrase, summarise, or rewrite any of it, and do",
@@ -68382,7 +68875,7 @@ function resolveDefaultBranch(checkoutPath) {
68382
68875
  if (!checkoutPath) return "main";
68383
68876
  const runGit = (args) => {
68384
68877
  try {
68385
- return (0, import_node_child_process20.execFileSync)("git", ["-C", checkoutPath, ...args], {
68878
+ return (0, import_node_child_process21.execFileSync)("git", ["-C", checkoutPath, ...args], {
68386
68879
  encoding: "utf8",
68387
68880
  stdio: ["ignore", "pipe", "ignore"],
68388
68881
  timeout: 15e3,
@@ -69579,7 +70072,77 @@ function createBridgeMessageHandler(deps) {
69579
70072
  } catch {
69580
70073
  }
69581
70074
  }
69582
- const contextPrefix = renderContextPrefix({ ...msg.context, answeredQuestions, directorSessionId });
70075
+ if (!contextProjectSlug) {
70076
+ sendForSpan({
70077
+ type: "error",
70078
+ directorSessionId,
70079
+ code: "workspace_boundary_unresolvable",
70080
+ error: "Workspace boundary unresolvable: turn context must include projectSlug."
70081
+ });
70082
+ thread.inFlight = false;
70083
+ deps.releaseCodex(turnSeat.id);
70084
+ return;
70085
+ }
70086
+ if (!deps.getProject) {
70087
+ sendForSpan({
70088
+ type: "error",
70089
+ directorSessionId,
70090
+ code: "workspace_boundary_unresolvable",
70091
+ error: "Workspace boundary unresolvable: deps.getProject is not wired."
70092
+ });
70093
+ thread.inFlight = false;
70094
+ deps.releaseCodex(turnSeat.id);
70095
+ return;
70096
+ }
70097
+ let projectContext = msg.context?.project;
70098
+ if (projectContext && projectContext.slug !== contextProjectSlug) {
70099
+ sendForSpan({
70100
+ type: "error",
70101
+ directorSessionId,
70102
+ code: "workspace_boundary_unresolvable",
70103
+ error: `Workspace boundary mismatch: provided project slug "${projectContext.slug}" does not match context project slug "${contextProjectSlug}".`
70104
+ });
70105
+ thread.inFlight = false;
70106
+ deps.releaseCodex(turnSeat.id);
70107
+ return;
70108
+ }
70109
+ try {
70110
+ const rawProject = await deps.getProject(contextProjectSlug);
70111
+ if (!rawProject) {
70112
+ sendForSpan({
70113
+ type: "error",
70114
+ directorSessionId,
70115
+ code: "workspace_boundary_unresolvable",
70116
+ error: `Workspace boundary unresolvable: project profile for "${contextProjectSlug}" was not found.`
70117
+ });
70118
+ thread.inFlight = false;
70119
+ deps.releaseCodex(turnSeat.id);
70120
+ return;
70121
+ }
70122
+ const scope = resolveProjectClientScope(rawProject);
70123
+ projectContext = {
70124
+ slug: rawProject.slug,
70125
+ displayName: rawProject.displayName,
70126
+ clientName: scope.clientName,
70127
+ scopeDescription: scope.scopeDescription
70128
+ };
70129
+ } catch (err) {
70130
+ sendForSpan({
70131
+ type: "error",
70132
+ directorSessionId,
70133
+ code: "workspace_boundary_unresolvable",
70134
+ error: `Workspace boundary unresolvable: failed to retrieve project profile for "${contextProjectSlug}": ${err?.message ?? err}`
70135
+ });
70136
+ thread.inFlight = false;
70137
+ deps.releaseCodex(turnSeat.id);
70138
+ return;
70139
+ }
70140
+ const contextPrefix = renderContextPrefix({
70141
+ ...msg.context,
70142
+ project: projectContext,
70143
+ answeredQuestions,
70144
+ directorSessionId
70145
+ });
69583
70146
  const sendInTurn = (msg2) => {
69584
70147
  const buf = thread.replay;
69585
70148
  if (!buf) {
@@ -69972,7 +70535,7 @@ function parseConfig() {
69972
70535
  }
69973
70536
  function scanForOtherBridges() {
69974
70537
  try {
69975
- const result = (0, import_node_child_process20.spawnSync)("pgrep", ["-f", "mrrlin-mcp director-bridge"], {
70538
+ const result = (0, import_node_child_process21.spawnSync)("pgrep", ["-f", "mrrlin-mcp director-bridge"], {
69976
70539
  encoding: "utf8"
69977
70540
  });
69978
70541
  if (result.status !== 0) return [];
@@ -70148,8 +70711,8 @@ async function startDirectorBridge() {
70148
70711
  codexCwd: config2.codexCwd,
70149
70712
  codexExecutable: config2.codexExecutable,
70150
70713
  checkoutRegistry,
70151
- worktreeRoot: import_node_path37.default.join(config2.stateDir, "worktrees"),
70152
- locksDir: import_node_path37.default.join(config2.stateDir, "locks"),
70714
+ worktreeRoot: import_node_path38.default.join(config2.stateDir, "worktrees"),
70715
+ locksDir: import_node_path38.default.join(config2.stateDir, "locks"),
70153
70716
  // Wire the executor server for code-execution runs. Each run gets its own provider process
70154
70717
  // (app-server for codex, a resident CLI child for claude) at the run worktree, running
70155
70718
  // UNRESTRICTED from the real operator config (owner no-sandbox decision — auth + mrrlin MCP
@@ -70375,7 +70938,7 @@ async function startDirectorBridge() {
70375
70938
  const files = dayFilesInWindow(/* @__PURE__ */ new Date(), reseedWindowMs);
70376
70939
  filesCount = files.length;
70377
70940
  const sessionIds = [args.directorSessionId, ...args.priorSessionIds];
70378
- const { lines: lines2, missingFiles } = await readSessionRows(import_node_path37.default.join(config2.stateDir, "logs"), files, sessionIds);
70941
+ const { lines: lines2, missingFiles } = await readSessionRows(import_node_path38.default.join(config2.stateDir, "logs"), files, sessionIds);
70379
70942
  missingFilesCount = missingFiles;
70380
70943
  const extracted = extractItems(lines2, sessionIds);
70381
70944
  items = extracted.items;
@@ -70474,6 +71037,7 @@ async function startDirectorBridge() {
70474
71037
  }
70475
71038
  },
70476
71039
  listAnsweredQuestions: (projectSlug, taskId) => client.listInboxItems(projectSlug, { status: "acknowledged", kind: "question", taskId }),
71040
+ getProject: (projectSlug) => client.getProject(projectSlug),
70477
71041
  // External-agents control plane: the real spawn runner, with the EXTERNAL_AGENTS_CLI operator
70478
71042
  // escape hatch bound here (the handlers stay spawn-free and this is the only production seam).
70479
71043
  runExternalAgentsCli: (args, opts) => runExternalAgentsCli(args, { ...opts, envCliPath: process.env["EXTERNAL_AGENTS_CLI"] }),
@@ -70630,8 +71194,8 @@ async function startDirectorBridge() {
70630
71194
  );
70631
71195
  void runOrphanWorktreeSweep(client, {
70632
71196
  checkoutRegistry,
70633
- worktreeRoot: import_node_path37.default.join(config2.stateDir, "worktrees"),
70634
- locksDir: import_node_path37.default.join(config2.stateDir, "locks")
71197
+ worktreeRoot: import_node_path38.default.join(config2.stateDir, "worktrees"),
71198
+ locksDir: import_node_path38.default.join(config2.stateDir, "locks")
70635
71199
  });
70636
71200
  {
70637
71201
  const { retainedBuffers, retainedBytes, tombstonesRemoved } = sweepReplayBuffers(threads, tombstones, {
@@ -70957,7 +71521,7 @@ function readDispatchBody(req) {
70957
71521
  function readOrCreateBridgeToken(stateDir) {
70958
71522
  const explicit = (process.env.MRRLIN_DIRECTOR_BRIDGE_TOKEN ?? "").trim();
70959
71523
  if (explicit) return explicit;
70960
- const tokenPath = import_node_path37.default.join(stateDir, "token.txt");
71524
+ const tokenPath = import_node_path38.default.join(stateDir, "token.txt");
70961
71525
  try {
70962
71526
  const existing = import_node_fs23.default.readFileSync(tokenPath, "utf8").trim();
70963
71527
  if (existing) return existing;
@@ -70976,6 +71540,22 @@ function isBridgeTokenAccepted(request, token) {
70976
71540
  return parts.includes(token);
70977
71541
  }
70978
71542
  function renderContextPrefix(context) {
71543
+ const parts = [];
71544
+ if (context?.project) {
71545
+ const { slug, displayName, clientName, scopeDescription } = context.project;
71546
+ const boundaryLines = [
71547
+ "[ACTIVE WORKSPACE CONTEXT]",
71548
+ `Project: "${displayName}" (Slug: ${slug})`,
71549
+ `Client: "${clientName}"`
71550
+ ];
71551
+ if (scopeDescription) {
71552
+ boundaryLines.push(`Scope: ${scopeDescription}`);
71553
+ }
71554
+ boundaryLines.push(
71555
+ "BOUNDARY DIRECTIVE: You are strictly isolated to this project and client. You MUST NOT reference, reuse, or adapt components, designs, or assets from other clients or projects."
71556
+ );
71557
+ parts.push(boundaryLines.join("\n"));
71558
+ }
70979
71559
  const projectSlug = context?.projectSlug?.trim() ? context.projectSlug.trim() : void 0;
70980
71560
  const urlPath = context?.urlPath?.trim() ? context.urlPath.trim() : void 0;
70981
71561
  const focusTaskId = context?.focusTaskId?.trim() ? context.focusTaskId.trim() : void 0;
@@ -70992,8 +71572,10 @@ function renderContextPrefix(context) {
70992
71572
  if (contextMessages?.length) payload.contextMessages = contextMessages;
70993
71573
  if (answeredQuestions) payload.answeredQuestions = answeredQuestions;
70994
71574
  const keys = Object.keys(payload);
70995
- if (keys.length === 0) return "";
70996
- return `Context (JSON): ${JSON.stringify(payload)}`;
71575
+ if (keys.length > 0) {
71576
+ parts.push(`Context (JSON): ${JSON.stringify(payload)}`);
71577
+ }
71578
+ return parts.join("\n\n");
70997
71579
  }
70998
71580
 
70999
71581
  // ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.30.0_zod@4.4.3/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/server.js
@@ -71666,7 +72248,9 @@ function resolveServerOptions(input = {}) {
71666
72248
  // Deliberately do NOT bake process.env.MRRLIN_TOKEN in here: withAuth (tools.ts) resolves
71667
72249
  // env + the bridge-persisted operator-token file lazily per request, so long-lived MCP
71668
72250
  // processes pick up token rotation. An explicit input.token still wins when provided.
71669
- token: input.token
72251
+ token: input.token,
72252
+ activeProjectSlug: input.activeProjectSlug ?? (process.env.MRRLIN_PROJECT_SLUG?.trim() || void 0),
72253
+ mcpConfigPath: input.mcpConfigPath
71670
72254
  };
71671
72255
  }
71672
72256
  function readZodObjectShape(schema) {
@@ -71825,7 +72409,7 @@ function runSetCredential(args) {
71825
72409
  // src/install-service.ts
71826
72410
  var import_node_os18 = __toESM(require("node:os"), 1);
71827
72411
  var import_node_fs24 = require("node:fs");
71828
- var import_node_path38 = __toESM(require("node:path"), 1);
72412
+ var import_node_path39 = __toESM(require("node:path"), 1);
71829
72413
  function parseEnvLine(line, env) {
71830
72414
  const trimmed = line.trim();
71831
72415
  if (!trimmed || trimmed === "}" || trimmed === "},") return;
@@ -72214,7 +72798,7 @@ function performConfigBackup(deps, ecoPath, existingText) {
72214
72798
  deps.log("Service config backup failed.");
72215
72799
  return;
72216
72800
  }
72217
- const dir = import_node_path38.default.dirname(ecoPath);
72801
+ const dir = import_node_path39.default.dirname(ecoPath);
72218
72802
  let files;
72219
72803
  try {
72220
72804
  files = deps.listDir(dir);
@@ -72226,7 +72810,7 @@ function performConfigBackup(deps, ecoPath, existingText) {
72226
72810
  deps.log("Service config backup failed.");
72227
72811
  return;
72228
72812
  }
72229
- const base = import_node_path38.default.basename(ecoPath);
72813
+ const base = import_node_path39.default.basename(ecoPath);
72230
72814
  const backupRegex = new RegExp(`^${escapeRegex2(base)}\\.bak-\\d{4}-\\d{2}-\\d{2}T\\d{2}-\\d{2}-\\d{2}-\\d{3}Z$`);
72231
72815
  const existingBackups = files.filter((f) => backupRegex.test(f));
72232
72816
  if (existingBackups.length >= 10) {
@@ -72327,11 +72911,11 @@ function installService(deps) {
72327
72911
  const claudeBin = deps.which("claude");
72328
72912
  const resolvedBins = [...bins, claudeBin].filter((b) => b !== null);
72329
72913
  const isWin = import_node_os18.default.platform() === "win32";
72330
- const systemDirs = isWin ? (deps.env.PATH || "").split(import_node_path38.default.delimiter).filter(Boolean) : SYSTEM_PATH_DIRS;
72914
+ const systemDirs = isWin ? (deps.env.PATH || "").split(import_node_path39.default.delimiter).filter(Boolean) : SYSTEM_PATH_DIRS;
72331
72915
  const pathEnv = Array.from(
72332
- /* @__PURE__ */ new Set([...resolvedBins.map((b) => import_node_path38.default.dirname(b)), ...systemDirs])
72333
- ).join(import_node_path38.default.delimiter);
72334
- const ecoPath = import_node_path38.default.join(home, ".mrrlin", "ecosystem.config.cjs");
72916
+ /* @__PURE__ */ new Set([...resolvedBins.map((b) => import_node_path39.default.dirname(b)), ...systemDirs])
72917
+ ).join(import_node_path39.default.delimiter);
72918
+ const ecoPath = import_node_path39.default.join(home, ".mrrlin", "ecosystem.config.cjs");
72335
72919
  const existingText = deps.readFile ? deps.readFile(ecoPath) : null;
72336
72920
  const parseResult = parseExistingEcosystemConfig(existingText);
72337
72921
  if (parseResult.kind === "rejected") {
@@ -72410,12 +72994,13 @@ function uninstallService(deps) {
72410
72994
  // src/uninstall-codex.ts
72411
72995
  var import_promises16 = __toESM(require("node:fs/promises"), 1);
72412
72996
  var import_node_os19 = __toESM(require("node:os"), 1);
72413
- var import_node_path39 = __toESM(require("node:path"), 1);
72997
+ var import_node_path40 = __toESM(require("node:path"), 1);
72414
72998
  var toml5 = __toESM(require_toml(), 1);
72415
72999
  function resolveCodexHome3(options) {
72416
73000
  if (options.codexHome) return options.codexHome;
73001
+ if (options.homeDir) return import_node_path40.default.join(options.homeDir, ".codex");
72417
73002
  if (process.env.CODEX_HOME) return process.env.CODEX_HOME;
72418
- return import_node_path39.default.join(options.homeDir ?? import_node_os19.default.homedir(), ".codex");
73003
+ return import_node_path40.default.join(import_node_os19.default.homedir(), ".codex");
72419
73004
  }
72420
73005
  async function pathExists6(target) {
72421
73006
  try {
@@ -72428,7 +73013,7 @@ async function pathExists6(target) {
72428
73013
  var MRRLIN_BLOCK_RE = /(^|\n)\[mcp_servers\.(?:mrrlin(?:-browser)?|external-agents)(?:\]|\.[^\]\n]*\])[\s\S]*?(?=\n\[|$)/g;
72429
73014
  async function uninstallCodex(options = {}) {
72430
73015
  const codexHome = resolveCodexHome3(options);
72431
- const configPath = import_node_path39.default.join(codexHome, "config.toml");
73016
+ const configPath = import_node_path40.default.join(codexHome, "config.toml");
72432
73017
  const removePrompts = async () => uninstallPrompts(codexHome, options.promptNames ?? []);
72433
73018
  if (!await pathExists6(configPath)) {
72434
73019
  return { action: "missing", configPath, prompts: await removePrompts() };
@@ -72456,10 +73041,10 @@ async function uninstallCodex(options = {}) {
72456
73041
  }
72457
73042
  async function uninstallPrompts(codexHome, names) {
72458
73043
  if (names.length === 0) return [];
72459
- const promptsDir = import_node_path39.default.join(codexHome, "prompts");
73044
+ const promptsDir = import_node_path40.default.join(codexHome, "prompts");
72460
73045
  const out = [];
72461
73046
  for (const name of names) {
72462
- const promptPath = import_node_path39.default.join(promptsDir, `${name}.md`);
73047
+ const promptPath = import_node_path40.default.join(promptsDir, `${name}.md`);
72463
73048
  try {
72464
73049
  await import_promises16.default.unlink(promptPath);
72465
73050
  out.push({ name, action: "removed", promptPath });
@@ -72477,7 +73062,7 @@ async function uninstallPrompts(codexHome, names) {
72477
73062
 
72478
73063
  // src/extract/command.ts
72479
73064
  var import_promises17 = require("node:fs/promises");
72480
- var import_node_path40 = require("node:path");
73065
+ var import_node_path41 = require("node:path");
72481
73066
  function parseArgs(args) {
72482
73067
  const map2 = /* @__PURE__ */ new Map();
72483
73068
  for (let i = 0; i < args.length; i++) {
@@ -72514,7 +73099,7 @@ Missing required flag(s): ${missing.join(
72514
73099
  const days = await findSessionDays(deps.stateDir, sessionId);
72515
73100
  const matchingLines = [];
72516
73101
  for (const day of days) {
72517
- const logPath = (0, import_node_path40.join)(deps.stateDir, "logs", `bridge-${day}.jsonl`);
73102
+ const logPath = (0, import_node_path41.join)(deps.stateDir, "logs", `bridge-${day}.jsonl`);
72518
73103
  let raw;
72519
73104
  try {
72520
73105
  raw = await (0, import_promises17.readFile)(logPath, "utf8");
@@ -72600,13 +73185,13 @@ Missing required flag(s): ${missing.join(
72600
73185
 
72601
73186
  // src/bin.ts
72602
73187
  function pm2Runner(args) {
72603
- const r = (0, import_node_child_process21.spawnSync)("pm2", args, { encoding: "utf8" });
73188
+ const r = (0, import_node_child_process22.spawnSync)("pm2", args, { encoding: "utf8" });
72604
73189
  process.stderr.write(r.stdout ?? "");
72605
73190
  process.stderr.write(r.stderr ?? "");
72606
73191
  return { code: r.status ?? 1, stdout: r.stdout ?? "" };
72607
73192
  }
72608
73193
  function whichBin(bin) {
72609
- const r = (0, import_node_child_process21.spawnSync)("which", [bin], { encoding: "utf8" });
73194
+ const r = (0, import_node_child_process22.spawnSync)("which", [bin], { encoding: "utf8" });
72610
73195
  const out = (r.stdout ?? "").trim();
72611
73196
  return r.status === 0 && out ? out.split("\n")[0] ?? null : null;
72612
73197
  }
@@ -72615,13 +73200,13 @@ function bootHookStatus() {
72615
73200
  const uid = process.getuid?.();
72616
73201
  if (uid === void 0 || uid === 0) return { status: "unknown" };
72617
73202
  const home = process.env.HOME ?? (0, import_node_os20.homedir)();
72618
- const agents = import_node_path42.default.join(home, "Library", "LaunchAgents");
73203
+ const agents = import_node_path43.default.join(home, "Library", "LaunchAgents");
72619
73204
  const candidates = [
72620
- { label: "com.mrrlin.director-bridge", plist: import_node_path42.default.join(agents, "com.mrrlin.director-bridge.plist") },
72621
- { label: "com.PM2", plist: import_node_path42.default.join(agents, `pm2.${(0, import_node_os20.userInfo)().username}.plist`) }
73205
+ { label: "com.mrrlin.director-bridge", plist: import_node_path43.default.join(agents, "com.mrrlin.director-bridge.plist") },
73206
+ { label: "com.PM2", plist: import_node_path43.default.join(agents, `pm2.${(0, import_node_os20.userInfo)().username}.plist`) }
72622
73207
  ];
72623
73208
  for (const candidate of candidates) {
72624
- const printed = (0, import_node_child_process21.spawnSync)("launchctl", ["print", `gui/${uid}/${candidate.label}`], { encoding: "utf8" });
73209
+ const printed = (0, import_node_child_process22.spawnSync)("launchctl", ["print", `gui/${uid}/${candidate.label}`], { encoding: "utf8" });
72625
73210
  if (printed.status !== 0) continue;
72626
73211
  if (!(0, import_node_fs25.existsSync)(candidate.plist)) continue;
72627
73212
  const out = printed.stdout ?? "";
@@ -72835,7 +73420,7 @@ async function main() {
72835
73420
  );
72836
73421
  }
72837
73422
  const { command: command2, args, env } = browserServeArgs();
72838
- const r = (0, import_node_child_process21.spawnSync)(command2, args, { stdio: "inherit", env: { ...process.env, ...env } });
73423
+ const r = (0, import_node_child_process22.spawnSync)(command2, args, { stdio: "inherit", env: { ...process.env, ...env } });
72839
73424
  process.exitCode = r.status ?? 1;
72840
73425
  return;
72841
73426
  }
@@ -72846,7 +73431,7 @@ async function main() {
72846
73431
  }
72847
73432
  case "external-agents-serve": {
72848
73433
  const { command: command2, args } = externalAgentsServeArgs();
72849
- const r = (0, import_node_child_process21.spawnSync)(command2, args, { stdio: "inherit", env: process.env });
73434
+ const r = (0, import_node_child_process22.spawnSync)(command2, args, { stdio: "inherit", env: process.env });
72850
73435
  process.exitCode = r.status ?? 1;
72851
73436
  return;
72852
73437
  }
@@ -72900,8 +73485,8 @@ async function main() {
72900
73485
  }
72901
73486
  }
72902
73487
  try {
72903
- const codexHome = process.env.CODEX_HOME ?? import_node_path42.default.join(process.env.HOME ?? (0, import_node_os20.homedir)(), ".codex");
72904
- (0, import_node_fs25.rmSync)(import_node_path42.default.join(codexHome, "prompts", "report-issue.md"), { force: true });
73488
+ const codexHome = process.env.CODEX_HOME ?? import_node_path43.default.join(process.env.HOME ?? (0, import_node_os20.homedir)(), ".codex");
73489
+ (0, import_node_fs25.rmSync)(import_node_path43.default.join(codexHome, "prompts", "report-issue.md"), { force: true });
72905
73490
  } catch {
72906
73491
  }
72907
73492
  const claudeResult = await installClaude({ binPath, force, serveEnv });
@@ -72923,7 +73508,7 @@ async function main() {
72923
73508
  );
72924
73509
  }
72925
73510
  const realProviderRunner = (command2) => (args) => {
72926
- const r = (0, import_node_child_process21.spawnSync)(command2, args, { encoding: "utf8", timeout: 8e3 });
73511
+ const r = (0, import_node_child_process22.spawnSync)(command2, args, { encoding: "utf8", timeout: 8e3 });
72927
73512
  return { status: r.status, stdout: r.stdout ?? "", stderr: r.stderr ?? "" };
72928
73513
  };
72929
73514
  for (const provider of ["codex", "claude", "agy"]) {
@@ -72971,7 +73556,7 @@ async function main() {
72971
73556
  env: process.env,
72972
73557
  cwd: process.cwd(),
72973
73558
  writeFile: (p, c) => {
72974
- (0, import_node_fs25.mkdirSync)(import_node_path42.default.dirname(p), { recursive: true, mode: 448 });
73559
+ (0, import_node_fs25.mkdirSync)(import_node_path43.default.dirname(p), { recursive: true, mode: 448 });
72975
73560
  (0, import_node_fs25.writeFileSync)(p, c, { mode: 384 });
72976
73561
  },
72977
73562
  writeExclusiveFile: (p, c) => (0, import_node_fs25.writeFileSync)(p, c, { flag: "wx", mode: 384 }),
@@ -73016,7 +73601,7 @@ async function main() {
73016
73601
  purgeSecret: purge,
73017
73602
  secretPath: agentCredentialPath(),
73018
73603
  tokenPath: operatorTokenPath(),
73019
- ecoPath: import_node_path42.default.join(process.env.HOME ?? (0, import_node_os20.homedir)(), ".mrrlin", "ecosystem.config.cjs"),
73604
+ ecoPath: import_node_path43.default.join(process.env.HOME ?? (0, import_node_os20.homedir)(), ".mrrlin", "ecosystem.config.cjs"),
73020
73605
  log: (m) => process.stderr.write(`[mrrlin-mcp uninstall-service] ${m}
73021
73606
  `)
73022
73607
  });
@@ -73037,7 +73622,7 @@ async function main() {
73037
73622
  purgeSecret: true,
73038
73623
  secretPath: agentCredentialPath(),
73039
73624
  tokenPath: operatorTokenPath(),
73040
- ecoPath: import_node_path42.default.join(home, ".mrrlin", "ecosystem.config.cjs"),
73625
+ ecoPath: import_node_path43.default.join(home, ".mrrlin", "ecosystem.config.cjs"),
73041
73626
  log
73042
73627
  });
73043
73628
  let codexOk = true;
@@ -73057,7 +73642,7 @@ async function main() {
73057
73642
  log(`codex config NOT modified: ${error51 instanceof Error ? error51.message : String(error51)}`);
73058
73643
  }
73059
73644
  try {
73060
- (0, import_node_fs25.rmSync)(import_node_path42.default.join(home, ".mrrlin"), { recursive: true, force: true });
73645
+ (0, import_node_fs25.rmSync)(import_node_path43.default.join(home, ".mrrlin"), { recursive: true, force: true });
73061
73646
  } catch {
73062
73647
  }
73063
73648
  log("removed ~/.mrrlin");
@@ -73098,7 +73683,7 @@ ${HELP_TEXT}`);
73098
73683
  }
73099
73684
  }
73100
73685
  function resolveSelfBinPath() {
73101
- return import_node_path41.default.resolve(process.argv[1] ?? process.execPath);
73686
+ return import_node_path42.default.resolve(process.argv[1] ?? process.execPath);
73102
73687
  }
73103
73688
  main().catch((error51) => {
73104
73689
  process.stderr.write(`mrrlin-mcp fatal error: ${error51 instanceof Error ? error51.message : String(error51)}