@mrrlin-dev/mcp 0.4.97 → 0.4.98
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin.cjs +273 -204
- package/package.json +1 -1
package/dist/bin.cjs
CHANGED
|
@@ -1647,20 +1647,20 @@ var require_parse_async = __commonJS({
|
|
|
1647
1647
|
const index = 0;
|
|
1648
1648
|
const blocksize = opts.blocksize || 40960;
|
|
1649
1649
|
const parser = new TOMLParser();
|
|
1650
|
-
return new Promise((
|
|
1651
|
-
setImmediate(parseAsyncNext, index, blocksize,
|
|
1650
|
+
return new Promise((resolve2, reject) => {
|
|
1651
|
+
setImmediate(parseAsyncNext, index, blocksize, resolve2, reject);
|
|
1652
1652
|
});
|
|
1653
|
-
function parseAsyncNext(index2, blocksize2,
|
|
1653
|
+
function parseAsyncNext(index2, blocksize2, resolve2, reject) {
|
|
1654
1654
|
if (index2 >= str.length) {
|
|
1655
1655
|
try {
|
|
1656
|
-
return
|
|
1656
|
+
return resolve2(parser.finish());
|
|
1657
1657
|
} catch (err) {
|
|
1658
1658
|
return reject(prettyError(err, str));
|
|
1659
1659
|
}
|
|
1660
1660
|
}
|
|
1661
1661
|
try {
|
|
1662
1662
|
parser.parse(str.slice(index2, index2 + blocksize2));
|
|
1663
|
-
setImmediate(parseAsyncNext, index2 + blocksize2, blocksize2,
|
|
1663
|
+
setImmediate(parseAsyncNext, index2 + blocksize2, blocksize2, resolve2, reject);
|
|
1664
1664
|
} catch (err) {
|
|
1665
1665
|
reject(prettyError(err, str));
|
|
1666
1666
|
}
|
|
@@ -1686,7 +1686,7 @@ var require_parse_stream = __commonJS({
|
|
|
1686
1686
|
function parseReadable(stm) {
|
|
1687
1687
|
const parser = new TOMLParser();
|
|
1688
1688
|
stm.setEncoding("utf8");
|
|
1689
|
-
return new Promise((
|
|
1689
|
+
return new Promise((resolve2, reject) => {
|
|
1690
1690
|
let readable;
|
|
1691
1691
|
let ended = false;
|
|
1692
1692
|
let errored = false;
|
|
@@ -1694,7 +1694,7 @@ var require_parse_stream = __commonJS({
|
|
|
1694
1694
|
ended = true;
|
|
1695
1695
|
if (readable) return;
|
|
1696
1696
|
try {
|
|
1697
|
-
|
|
1697
|
+
resolve2(parser.finish());
|
|
1698
1698
|
} catch (err) {
|
|
1699
1699
|
reject(err);
|
|
1700
1700
|
}
|
|
@@ -4980,7 +4980,7 @@ var require_compile = __commonJS({
|
|
|
4980
4980
|
const schOrFunc = root.refs[ref];
|
|
4981
4981
|
if (schOrFunc)
|
|
4982
4982
|
return schOrFunc;
|
|
4983
|
-
let _sch =
|
|
4983
|
+
let _sch = resolve2.call(this, root, ref);
|
|
4984
4984
|
if (_sch === void 0) {
|
|
4985
4985
|
const schema = (_a3 = root.localRefs) === null || _a3 === void 0 ? void 0 : _a3[ref];
|
|
4986
4986
|
const { schemaId } = this.opts;
|
|
@@ -5007,7 +5007,7 @@ var require_compile = __commonJS({
|
|
|
5007
5007
|
function sameSchemaEnv(s1, s2) {
|
|
5008
5008
|
return s1.schema === s2.schema && s1.root === s2.root && s1.baseId === s2.baseId;
|
|
5009
5009
|
}
|
|
5010
|
-
function
|
|
5010
|
+
function resolve2(root, ref) {
|
|
5011
5011
|
let sch;
|
|
5012
5012
|
while (typeof (sch = this.refs[ref]) == "string")
|
|
5013
5013
|
ref = sch;
|
|
@@ -5837,7 +5837,7 @@ var require_fast_uri = __commonJS({
|
|
|
5837
5837
|
}
|
|
5838
5838
|
return uri;
|
|
5839
5839
|
}
|
|
5840
|
-
function
|
|
5840
|
+
function resolve2(baseURI, relativeURI, options) {
|
|
5841
5841
|
const schemelessOptions = options ? Object.assign({ scheme: "null" }, options) : { scheme: "null" };
|
|
5842
5842
|
const {
|
|
5843
5843
|
parsed: baseParsed,
|
|
@@ -6206,7 +6206,7 @@ var require_fast_uri = __commonJS({
|
|
|
6206
6206
|
var fastUri = {
|
|
6207
6207
|
SCHEMES,
|
|
6208
6208
|
normalize: normalize2,
|
|
6209
|
-
resolve,
|
|
6209
|
+
resolve: resolve2,
|
|
6210
6210
|
resolveComponent,
|
|
6211
6211
|
equal,
|
|
6212
6212
|
serialize,
|
|
@@ -9393,12 +9393,12 @@ var require_isexe = __commonJS({
|
|
|
9393
9393
|
if (typeof Promise !== "function") {
|
|
9394
9394
|
throw new TypeError("callback not provided");
|
|
9395
9395
|
}
|
|
9396
|
-
return new Promise(function(
|
|
9396
|
+
return new Promise(function(resolve2, reject) {
|
|
9397
9397
|
isexe(path29, options || {}, function(er, is) {
|
|
9398
9398
|
if (er) {
|
|
9399
9399
|
reject(er);
|
|
9400
9400
|
} else {
|
|
9401
|
-
|
|
9401
|
+
resolve2(is);
|
|
9402
9402
|
}
|
|
9403
9403
|
});
|
|
9404
9404
|
});
|
|
@@ -9464,27 +9464,27 @@ var require_which = __commonJS({
|
|
|
9464
9464
|
opt = {};
|
|
9465
9465
|
const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt);
|
|
9466
9466
|
const found = [];
|
|
9467
|
-
const step = (i) => new Promise((
|
|
9467
|
+
const step = (i) => new Promise((resolve2, reject) => {
|
|
9468
9468
|
if (i === pathEnv.length)
|
|
9469
|
-
return opt.all && found.length ?
|
|
9469
|
+
return opt.all && found.length ? resolve2(found) : reject(getNotFoundError(cmd));
|
|
9470
9470
|
const ppRaw = pathEnv[i];
|
|
9471
9471
|
const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw;
|
|
9472
9472
|
const pCmd = path29.join(pathPart, cmd);
|
|
9473
9473
|
const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd;
|
|
9474
|
-
|
|
9474
|
+
resolve2(subStep(p, i, 0));
|
|
9475
9475
|
});
|
|
9476
|
-
const subStep = (p, i, ii) => new Promise((
|
|
9476
|
+
const subStep = (p, i, ii) => new Promise((resolve2, reject) => {
|
|
9477
9477
|
if (ii === pathExt.length)
|
|
9478
|
-
return
|
|
9478
|
+
return resolve2(step(i + 1));
|
|
9479
9479
|
const ext = pathExt[ii];
|
|
9480
9480
|
isexe(p + ext, { pathExt: pathExtExe }, (er, is) => {
|
|
9481
9481
|
if (!er && is) {
|
|
9482
9482
|
if (opt.all)
|
|
9483
9483
|
found.push(p + ext);
|
|
9484
9484
|
else
|
|
9485
|
-
return
|
|
9485
|
+
return resolve2(p + ext);
|
|
9486
9486
|
}
|
|
9487
|
-
return
|
|
9487
|
+
return resolve2(subStep(p, i, ii + 1));
|
|
9488
9488
|
});
|
|
9489
9489
|
});
|
|
9490
9490
|
return cb ? step(0).then((res) => cb(null, res), cb) : step(0);
|
|
@@ -14017,7 +14017,7 @@ var require_websocket = __commonJS({
|
|
|
14017
14017
|
var http2 = require("http");
|
|
14018
14018
|
var net = require("net");
|
|
14019
14019
|
var tls = require("tls");
|
|
14020
|
-
var { randomBytes: randomBytes5, createHash:
|
|
14020
|
+
var { randomBytes: randomBytes5, createHash: createHash6 } = require("crypto");
|
|
14021
14021
|
var { Duplex, Readable } = require("stream");
|
|
14022
14022
|
var { URL: URL2 } = require("url");
|
|
14023
14023
|
var PerMessageDeflate2 = require_permessage_deflate();
|
|
@@ -14685,7 +14685,7 @@ var require_websocket = __commonJS({
|
|
|
14685
14685
|
abortHandshake(websocket, socket, "Invalid Upgrade header");
|
|
14686
14686
|
return;
|
|
14687
14687
|
}
|
|
14688
|
-
const digest =
|
|
14688
|
+
const digest = createHash6("sha1").update(key + GUID).digest("base64");
|
|
14689
14689
|
if (res.headers["sec-websocket-accept"] !== digest) {
|
|
14690
14690
|
abortHandshake(websocket, socket, "Invalid Sec-WebSocket-Accept header");
|
|
14691
14691
|
return;
|
|
@@ -15054,7 +15054,7 @@ var require_websocket_server = __commonJS({
|
|
|
15054
15054
|
var EventEmitter3 = require("events");
|
|
15055
15055
|
var http2 = require("http");
|
|
15056
15056
|
var { Duplex } = require("stream");
|
|
15057
|
-
var { createHash:
|
|
15057
|
+
var { createHash: createHash6 } = require("crypto");
|
|
15058
15058
|
var extension2 = require_extension();
|
|
15059
15059
|
var PerMessageDeflate2 = require_permessage_deflate();
|
|
15060
15060
|
var subprotocol2 = require_subprotocol();
|
|
@@ -15361,7 +15361,7 @@ var require_websocket_server = __commonJS({
|
|
|
15361
15361
|
);
|
|
15362
15362
|
}
|
|
15363
15363
|
if (this._state > RUNNING) return abortHandshake(socket, 503);
|
|
15364
|
-
const digest =
|
|
15364
|
+
const digest = createHash6("sha1").update(key + GUID).digest("base64");
|
|
15365
15365
|
const headers = [
|
|
15366
15366
|
"HTTP/1.1 101 Switching Protocols",
|
|
15367
15367
|
"Upgrade: websocket",
|
|
@@ -16947,12 +16947,12 @@ var require_adapter = __commonJS({
|
|
|
16947
16947
|
return newFs;
|
|
16948
16948
|
}
|
|
16949
16949
|
function toPromise(method) {
|
|
16950
|
-
return (...args) => new Promise((
|
|
16950
|
+
return (...args) => new Promise((resolve2, reject) => {
|
|
16951
16951
|
args.push((err, result) => {
|
|
16952
16952
|
if (err) {
|
|
16953
16953
|
reject(err);
|
|
16954
16954
|
} else {
|
|
16955
|
-
|
|
16955
|
+
resolve2(result);
|
|
16956
16956
|
}
|
|
16957
16957
|
});
|
|
16958
16958
|
method(...args);
|
|
@@ -21406,10 +21406,10 @@ var require_browser = __commonJS({
|
|
|
21406
21406
|
text = canvas;
|
|
21407
21407
|
canvas = void 0;
|
|
21408
21408
|
}
|
|
21409
|
-
return new Promise(function(
|
|
21409
|
+
return new Promise(function(resolve2, reject) {
|
|
21410
21410
|
try {
|
|
21411
21411
|
const data = QRCode2.create(text, opts);
|
|
21412
|
-
|
|
21412
|
+
resolve2(renderFunc(data, canvas, opts));
|
|
21413
21413
|
} catch (e) {
|
|
21414
21414
|
reject(e);
|
|
21415
21415
|
}
|
|
@@ -21490,11 +21490,11 @@ var require_server = __commonJS({
|
|
|
21490
21490
|
}
|
|
21491
21491
|
function render(renderFunc, text, params) {
|
|
21492
21492
|
if (!params.cb) {
|
|
21493
|
-
return new Promise(function(
|
|
21493
|
+
return new Promise(function(resolve2, reject) {
|
|
21494
21494
|
try {
|
|
21495
21495
|
const data = QRCode2.create(text, params.opts);
|
|
21496
21496
|
return renderFunc(data, params.opts, function(err, data2) {
|
|
21497
|
-
return err ? reject(err) :
|
|
21497
|
+
return err ? reject(err) : resolve2(data2);
|
|
21498
21498
|
});
|
|
21499
21499
|
} catch (e) {
|
|
21500
21500
|
reject(e);
|
|
@@ -41493,7 +41493,7 @@ function createBoundedSemaphore(slots) {
|
|
|
41493
41493
|
let available = slots;
|
|
41494
41494
|
const queue = [];
|
|
41495
41495
|
return {
|
|
41496
|
-
acquire: () => available > 0 ? (available -= 1, Promise.resolve()) : new Promise((
|
|
41496
|
+
acquire: () => available > 0 ? (available -= 1, Promise.resolve()) : new Promise((resolve2) => queue.push(resolve2)),
|
|
41497
41497
|
release: () => {
|
|
41498
41498
|
const next = queue.shift();
|
|
41499
41499
|
if (next) next();
|
|
@@ -42524,22 +42524,22 @@ var CodexJsonRpcClient = class {
|
|
|
42524
42524
|
const payload = { jsonrpc: "2.0", id, method, params };
|
|
42525
42525
|
const line = `${JSON.stringify(payload)}
|
|
42526
42526
|
`;
|
|
42527
|
-
const resultPromise = new Promise((
|
|
42527
|
+
const resultPromise = new Promise((resolve2, reject) => {
|
|
42528
42528
|
const onResponse = (response) => {
|
|
42529
42529
|
if (response.error) {
|
|
42530
42530
|
reject(new Error(response.error.message ?? "Codex JSON-RPC error"));
|
|
42531
42531
|
return;
|
|
42532
42532
|
}
|
|
42533
|
-
|
|
42533
|
+
resolve2(response.result);
|
|
42534
42534
|
};
|
|
42535
42535
|
this.emitter.once(`response:${id}`, onResponse);
|
|
42536
42536
|
});
|
|
42537
|
-
await new Promise((
|
|
42537
|
+
await new Promise((resolve2, reject) => {
|
|
42538
42538
|
this.writeStream.write(line, (error51) => {
|
|
42539
42539
|
if (error51)
|
|
42540
42540
|
reject(error51);
|
|
42541
42541
|
else
|
|
42542
|
-
|
|
42542
|
+
resolve2();
|
|
42543
42543
|
});
|
|
42544
42544
|
});
|
|
42545
42545
|
return await resultPromise;
|
|
@@ -42702,11 +42702,11 @@ var CodexServerManager = class {
|
|
|
42702
42702
|
env: config2?.env ?? process.env,
|
|
42703
42703
|
shell: true
|
|
42704
42704
|
});
|
|
42705
|
-
await new Promise((
|
|
42705
|
+
await new Promise((resolve2, reject) => {
|
|
42706
42706
|
child.on("error", (err) => {
|
|
42707
42707
|
reject(new Error(`Failed to spawn codex app-server: ${err.message}`));
|
|
42708
42708
|
});
|
|
42709
|
-
child.on("spawn", () =>
|
|
42709
|
+
child.on("spawn", () => resolve2());
|
|
42710
42710
|
});
|
|
42711
42711
|
if (!child.stdin || !child.stdout) {
|
|
42712
42712
|
child.kill();
|
|
@@ -43485,7 +43485,7 @@ var ClaudeProcess = class {
|
|
|
43485
43485
|
cwd: options.cwd?.trim() || void 0,
|
|
43486
43486
|
// Inherit the operator's env so the CLI picks up their own ~/.claude.json tool registry —
|
|
43487
43487
|
// unless an explicit mcpConfig was provided in options.
|
|
43488
|
-
env: process.env,
|
|
43488
|
+
env: options.env ?? process.env,
|
|
43489
43489
|
stdio: ["pipe", "pipe", "pipe"]
|
|
43490
43490
|
});
|
|
43491
43491
|
this.child.stdout.setEncoding("utf8");
|
|
@@ -43580,15 +43580,15 @@ var ClaudeProcess = class {
|
|
|
43580
43580
|
return Promise.resolve();
|
|
43581
43581
|
}
|
|
43582
43582
|
if (this.disposed) {
|
|
43583
|
-
return new Promise((
|
|
43583
|
+
return new Promise((resolve2) => {
|
|
43584
43584
|
const off = this.onExit(() => {
|
|
43585
43585
|
off();
|
|
43586
|
-
|
|
43586
|
+
resolve2();
|
|
43587
43587
|
});
|
|
43588
43588
|
});
|
|
43589
43589
|
}
|
|
43590
43590
|
this.disposed = true;
|
|
43591
|
-
return new Promise((
|
|
43591
|
+
return new Promise((resolve2) => {
|
|
43592
43592
|
const forceKill = setTimeout(() => {
|
|
43593
43593
|
if (!this.exited)
|
|
43594
43594
|
this.child.kill("SIGKILL");
|
|
@@ -43597,7 +43597,7 @@ var ClaudeProcess = class {
|
|
|
43597
43597
|
const off = this.onExit(() => {
|
|
43598
43598
|
clearTimeout(forceKill);
|
|
43599
43599
|
off();
|
|
43600
|
-
|
|
43600
|
+
resolve2();
|
|
43601
43601
|
});
|
|
43602
43602
|
this.child.kill("SIGTERM");
|
|
43603
43603
|
});
|
|
@@ -43797,11 +43797,16 @@ function permissionModeFor(sandbox) {
|
|
|
43797
43797
|
return { permissionMode: "bypassPermissions" };
|
|
43798
43798
|
}
|
|
43799
43799
|
var ClaudeAgentHandle = class {
|
|
43800
|
+
childEnv;
|
|
43800
43801
|
// One resident child + one mapper per thread — mirrors ClaudeProcess's own per-thread residency
|
|
43801
43802
|
// and ClaudeBridgeEventMapper's documented "fresh instance per thread" contract (its tool-use
|
|
43802
43803
|
// dedup sets must not leak across threads).
|
|
43803
43804
|
processes = /* @__PURE__ */ new Map();
|
|
43804
43805
|
mappers = /* @__PURE__ */ new Map();
|
|
43806
|
+
/** Exact complete environment passed unchanged to every process this handle spawns. */
|
|
43807
|
+
constructor(childEnv) {
|
|
43808
|
+
this.childEnv = childEnv;
|
|
43809
|
+
}
|
|
43805
43810
|
async startThread(params) {
|
|
43806
43811
|
const { permissionMode, disallowedTools } = permissionModeFor(params.sandbox);
|
|
43807
43812
|
const child = new ClaudeProcess({
|
|
@@ -43811,7 +43816,8 @@ var ClaudeAgentHandle = class {
|
|
|
43811
43816
|
model: params.model,
|
|
43812
43817
|
cwd: params.cwd,
|
|
43813
43818
|
mcpConfig: params.mcpConfig,
|
|
43814
|
-
appendSystemPrompt: params.baseInstructions
|
|
43819
|
+
appendSystemPrompt: params.baseInstructions,
|
|
43820
|
+
...this.childEnv === void 0 ? {} : { env: this.childEnv }
|
|
43815
43821
|
});
|
|
43816
43822
|
this.processes.set(child.sessionId, child);
|
|
43817
43823
|
this.mappers.set(child.sessionId, new ClaudeBridgeEventMapper());
|
|
@@ -43826,7 +43832,8 @@ var ClaudeAgentHandle = class {
|
|
|
43826
43832
|
model: params.model,
|
|
43827
43833
|
cwd: params.cwd,
|
|
43828
43834
|
mcpConfig: params.mcpConfig,
|
|
43829
|
-
appendSystemPrompt: params.baseInstructions
|
|
43835
|
+
appendSystemPrompt: params.baseInstructions,
|
|
43836
|
+
...this.childEnv === void 0 ? {} : { env: this.childEnv }
|
|
43830
43837
|
});
|
|
43831
43838
|
this.processes.set(threadId, child);
|
|
43832
43839
|
this.mappers.set(threadId, new ClaudeBridgeEventMapper());
|
|
@@ -43986,7 +43993,7 @@ var AgyProcess = class _AgyProcess {
|
|
|
43986
43993
|
const cwd = options.cwd?.trim() || void 0;
|
|
43987
43994
|
this.child = (0, import_node_child_process4.spawn)(executable, args, {
|
|
43988
43995
|
cwd,
|
|
43989
|
-
env: process.env,
|
|
43996
|
+
env: options.env ?? process.env,
|
|
43990
43997
|
stdio: ["pipe", "pipe", "pipe"]
|
|
43991
43998
|
});
|
|
43992
43999
|
activeProcesses.add(this.child);
|
|
@@ -44298,16 +44305,22 @@ function permissionModeFor2(sandbox, approvalPolicy) {
|
|
|
44298
44305
|
return { permissionMode: "acceptEdits" };
|
|
44299
44306
|
}
|
|
44300
44307
|
var AgyAgentHandle = class {
|
|
44308
|
+
childEnv;
|
|
44301
44309
|
processes = /* @__PURE__ */ new Map();
|
|
44302
44310
|
mappers = /* @__PURE__ */ new Map();
|
|
44303
44311
|
baseInstructions = /* @__PURE__ */ new Map();
|
|
44312
|
+
/** Exact complete environment passed unchanged to every process this handle spawns. */
|
|
44313
|
+
constructor(childEnv) {
|
|
44314
|
+
this.childEnv = childEnv;
|
|
44315
|
+
}
|
|
44304
44316
|
async startThread(params) {
|
|
44305
44317
|
const { permissionMode } = permissionModeFor2(params.sandbox, params.approvalPolicy);
|
|
44306
44318
|
const child = new AgyProcess({
|
|
44307
44319
|
mode: { kind: "new" },
|
|
44308
44320
|
permissionMode,
|
|
44309
44321
|
model: params.model,
|
|
44310
|
-
cwd: params.cwd
|
|
44322
|
+
cwd: params.cwd,
|
|
44323
|
+
...this.childEnv === void 0 ? {} : { env: this.childEnv }
|
|
44311
44324
|
});
|
|
44312
44325
|
this.processes.set(child.sessionId, child);
|
|
44313
44326
|
this.mappers.set(child.sessionId, new AgyBridgeEventMapper());
|
|
@@ -44327,7 +44340,8 @@ var AgyAgentHandle = class {
|
|
|
44327
44340
|
mode: { kind: "resume", resumeId: threadId },
|
|
44328
44341
|
permissionMode,
|
|
44329
44342
|
model: params.model,
|
|
44330
|
-
cwd: params.cwd
|
|
44343
|
+
cwd: params.cwd,
|
|
44344
|
+
...this.childEnv === void 0 ? {} : { env: this.childEnv }
|
|
44331
44345
|
});
|
|
44332
44346
|
this.processes.set(threadId, child);
|
|
44333
44347
|
this.mappers.set(threadId, new AgyBridgeEventMapper());
|
|
@@ -44383,6 +44397,14 @@ ${text}`;
|
|
|
44383
44397
|
async readRateLimits() {
|
|
44384
44398
|
return null;
|
|
44385
44399
|
}
|
|
44400
|
+
disposeAll() {
|
|
44401
|
+
for (const child of this.processes.values())
|
|
44402
|
+
void child.dispose().catch(() => {
|
|
44403
|
+
});
|
|
44404
|
+
this.processes.clear();
|
|
44405
|
+
this.mappers.clear();
|
|
44406
|
+
this.baseInstructions.clear();
|
|
44407
|
+
}
|
|
44386
44408
|
requireProcess(threadId) {
|
|
44387
44409
|
const child = this.processes.get(threadId);
|
|
44388
44410
|
if (!child)
|
|
@@ -44555,7 +44577,7 @@ ${input.prompt}` : input.prompt;
|
|
|
44555
44577
|
args.push("-m", input.model);
|
|
44556
44578
|
}
|
|
44557
44579
|
args.push(fullPrompt);
|
|
44558
|
-
return new Promise((
|
|
44580
|
+
return new Promise((resolve2) => {
|
|
44559
44581
|
let settled = false;
|
|
44560
44582
|
const timerRef = { id: void 0 };
|
|
44561
44583
|
const finish = (result) => {
|
|
@@ -44564,7 +44586,7 @@ ${input.prompt}` : input.prompt;
|
|
|
44564
44586
|
settled = true;
|
|
44565
44587
|
if (timerRef.id)
|
|
44566
44588
|
clearTimeout(timerRef.id);
|
|
44567
|
-
|
|
44589
|
+
resolve2(result);
|
|
44568
44590
|
};
|
|
44569
44591
|
const options = {
|
|
44570
44592
|
stdio: ["ignore", "pipe", "pipe"],
|
|
@@ -44642,7 +44664,7 @@ function runClaudeExec(input, deps) {
|
|
|
44642
44664
|
args.push("--model", input.model);
|
|
44643
44665
|
}
|
|
44644
44666
|
args.push(input.prompt);
|
|
44645
|
-
return new Promise((
|
|
44667
|
+
return new Promise((resolve2) => {
|
|
44646
44668
|
let settled = false;
|
|
44647
44669
|
const timerRef = { id: void 0 };
|
|
44648
44670
|
const finish = (result) => {
|
|
@@ -44651,7 +44673,7 @@ function runClaudeExec(input, deps) {
|
|
|
44651
44673
|
settled = true;
|
|
44652
44674
|
if (timerRef.id)
|
|
44653
44675
|
clearTimeout(timerRef.id);
|
|
44654
|
-
|
|
44676
|
+
resolve2(result);
|
|
44655
44677
|
};
|
|
44656
44678
|
const options = {
|
|
44657
44679
|
stdio: ["ignore", "pipe", "pipe"],
|
|
@@ -44763,7 +44785,7 @@ function runAgyExec(input, deps) {
|
|
|
44763
44785
|
}
|
|
44764
44786
|
}
|
|
44765
44787
|
args.push(`--print=${prompt}`);
|
|
44766
|
-
return new Promise((
|
|
44788
|
+
return new Promise((resolve2) => {
|
|
44767
44789
|
let settled = false;
|
|
44768
44790
|
const timerRef = { id: void 0 };
|
|
44769
44791
|
const finish = (result) => {
|
|
@@ -44772,7 +44794,7 @@ function runAgyExec(input, deps) {
|
|
|
44772
44794
|
settled = true;
|
|
44773
44795
|
if (timerRef.id)
|
|
44774
44796
|
clearTimeout(timerRef.id);
|
|
44775
|
-
|
|
44797
|
+
resolve2(result);
|
|
44776
44798
|
};
|
|
44777
44799
|
const options = {
|
|
44778
44800
|
stdio: ["ignore", "pipe", "pipe"],
|
|
@@ -45112,14 +45134,14 @@ var DIFF_MAX_BYTES = 2e5;
|
|
|
45112
45134
|
var FASTGATE_OUTPUT_MAX_BYTES = 16e3;
|
|
45113
45135
|
var GIT_TIMEOUT_MS = 6e4;
|
|
45114
45136
|
var FASTGATE_TIMEOUT_MS = 3e5;
|
|
45115
|
-
var defaultRunCmd = (cmd, args, opts) => new Promise((
|
|
45137
|
+
var defaultRunCmd = (cmd, args, opts) => new Promise((resolve2) => {
|
|
45116
45138
|
let settled = false;
|
|
45117
45139
|
const timerRef = { id: void 0 };
|
|
45118
45140
|
const finish = (result) => {
|
|
45119
45141
|
if (settled) return;
|
|
45120
45142
|
settled = true;
|
|
45121
45143
|
if (timerRef.id) clearTimeout(timerRef.id);
|
|
45122
|
-
|
|
45144
|
+
resolve2(result);
|
|
45123
45145
|
};
|
|
45124
45146
|
let child;
|
|
45125
45147
|
try {
|
|
@@ -46037,14 +46059,14 @@ function errMessage3(err) {
|
|
|
46037
46059
|
return err instanceof Error ? err.message : String(err);
|
|
46038
46060
|
}
|
|
46039
46061
|
function runExternalAgentsStatus(bin, args, timeoutMs, spawn6) {
|
|
46040
|
-
return new Promise((
|
|
46062
|
+
return new Promise((resolve2) => {
|
|
46041
46063
|
let settled = false;
|
|
46042
46064
|
const timerRef = { id: void 0 };
|
|
46043
46065
|
const finish = (r) => {
|
|
46044
46066
|
if (settled) return;
|
|
46045
46067
|
settled = true;
|
|
46046
46068
|
if (timerRef.id) clearTimeout(timerRef.id);
|
|
46047
|
-
|
|
46069
|
+
resolve2(r);
|
|
46048
46070
|
};
|
|
46049
46071
|
const options = { stdio: ["ignore", "pipe", "pipe"], env: process.env, shell: false };
|
|
46050
46072
|
let child;
|
|
@@ -46124,14 +46146,14 @@ function errMessage4(err) {
|
|
|
46124
46146
|
return err instanceof Error ? err.message : String(err);
|
|
46125
46147
|
}
|
|
46126
46148
|
function runExternalAgents(bin, args, label, timeoutMs, spawn6) {
|
|
46127
|
-
return new Promise((
|
|
46149
|
+
return new Promise((resolve2) => {
|
|
46128
46150
|
let settled = false;
|
|
46129
46151
|
const timerRef = { id: void 0 };
|
|
46130
46152
|
const finish = (r) => {
|
|
46131
46153
|
if (settled) return;
|
|
46132
46154
|
settled = true;
|
|
46133
46155
|
if (timerRef.id) clearTimeout(timerRef.id);
|
|
46134
|
-
|
|
46156
|
+
resolve2(r);
|
|
46135
46157
|
};
|
|
46136
46158
|
const options = {
|
|
46137
46159
|
stdio: ["ignore", "pipe", "pipe"],
|
|
@@ -48630,7 +48652,7 @@ var Protocol = class {
|
|
|
48630
48652
|
return;
|
|
48631
48653
|
}
|
|
48632
48654
|
const pollInterval = task2.pollInterval ?? this._options?.defaultTaskPollInterval ?? 1e3;
|
|
48633
|
-
await new Promise((
|
|
48655
|
+
await new Promise((resolve2) => setTimeout(resolve2, pollInterval));
|
|
48634
48656
|
options?.signal?.throwIfAborted();
|
|
48635
48657
|
}
|
|
48636
48658
|
} catch (error51) {
|
|
@@ -48647,7 +48669,7 @@ var Protocol = class {
|
|
|
48647
48669
|
*/
|
|
48648
48670
|
request(request, resultSchema, options) {
|
|
48649
48671
|
const { relatedRequestId, resumptionToken, onresumptiontoken, task, relatedTask } = options ?? {};
|
|
48650
|
-
return new Promise((
|
|
48672
|
+
return new Promise((resolve2, reject) => {
|
|
48651
48673
|
const earlyReject = (error51) => {
|
|
48652
48674
|
reject(error51);
|
|
48653
48675
|
};
|
|
@@ -48725,7 +48747,7 @@ var Protocol = class {
|
|
|
48725
48747
|
if (!parseResult.success) {
|
|
48726
48748
|
reject(parseResult.error);
|
|
48727
48749
|
} else {
|
|
48728
|
-
|
|
48750
|
+
resolve2(parseResult.data);
|
|
48729
48751
|
}
|
|
48730
48752
|
} catch (error51) {
|
|
48731
48753
|
reject(error51);
|
|
@@ -48986,12 +49008,12 @@ var Protocol = class {
|
|
|
48986
49008
|
}
|
|
48987
49009
|
} catch {
|
|
48988
49010
|
}
|
|
48989
|
-
return new Promise((
|
|
49011
|
+
return new Promise((resolve2, reject) => {
|
|
48990
49012
|
if (signal.aborted) {
|
|
48991
49013
|
reject(new McpError(ErrorCode.InvalidRequest, "Request cancelled"));
|
|
48992
49014
|
return;
|
|
48993
49015
|
}
|
|
48994
|
-
const timeoutId = setTimeout(
|
|
49016
|
+
const timeoutId = setTimeout(resolve2, interval);
|
|
48995
49017
|
signal.addEventListener("abort", () => {
|
|
48996
49018
|
clearTimeout(timeoutId);
|
|
48997
49019
|
reject(new McpError(ErrorCode.InvalidRequest, "Request cancelled"));
|
|
@@ -51427,7 +51449,7 @@ var StdioClientTransport = class {
|
|
|
51427
51449
|
if (this._process) {
|
|
51428
51450
|
throw new Error("StdioClientTransport already started! If using Client class, note that connect() calls start() automatically.");
|
|
51429
51451
|
}
|
|
51430
|
-
return new Promise((
|
|
51452
|
+
return new Promise((resolve2, reject) => {
|
|
51431
51453
|
this._process = (0, import_cross_spawn.default)(this._serverParams.command, this._serverParams.args ?? [], {
|
|
51432
51454
|
// merge default env with server env because mcp server needs some env vars
|
|
51433
51455
|
env: {
|
|
@@ -51444,7 +51466,7 @@ var StdioClientTransport = class {
|
|
|
51444
51466
|
this.onerror?.(error51);
|
|
51445
51467
|
});
|
|
51446
51468
|
this._process.on("spawn", () => {
|
|
51447
|
-
|
|
51469
|
+
resolve2();
|
|
51448
51470
|
});
|
|
51449
51471
|
this._process.on("close", (_code) => {
|
|
51450
51472
|
this._process = void 0;
|
|
@@ -51509,22 +51531,22 @@ var StdioClientTransport = class {
|
|
|
51509
51531
|
if (this._process) {
|
|
51510
51532
|
const processToClose = this._process;
|
|
51511
51533
|
this._process = void 0;
|
|
51512
|
-
const closePromise = new Promise((
|
|
51534
|
+
const closePromise = new Promise((resolve2) => {
|
|
51513
51535
|
processToClose.once("close", () => {
|
|
51514
|
-
|
|
51536
|
+
resolve2();
|
|
51515
51537
|
});
|
|
51516
51538
|
});
|
|
51517
51539
|
try {
|
|
51518
51540
|
processToClose.stdin?.end();
|
|
51519
51541
|
} catch {
|
|
51520
51542
|
}
|
|
51521
|
-
await Promise.race([closePromise, new Promise((
|
|
51543
|
+
await Promise.race([closePromise, new Promise((resolve2) => setTimeout(resolve2, 2e3).unref())]);
|
|
51522
51544
|
if (processToClose.exitCode === null) {
|
|
51523
51545
|
try {
|
|
51524
51546
|
processToClose.kill("SIGTERM");
|
|
51525
51547
|
} catch {
|
|
51526
51548
|
}
|
|
51527
|
-
await Promise.race([closePromise, new Promise((
|
|
51549
|
+
await Promise.race([closePromise, new Promise((resolve2) => setTimeout(resolve2, 2e3).unref())]);
|
|
51528
51550
|
}
|
|
51529
51551
|
if (processToClose.exitCode === null) {
|
|
51530
51552
|
try {
|
|
@@ -51536,15 +51558,15 @@ var StdioClientTransport = class {
|
|
|
51536
51558
|
this._readBuffer.clear();
|
|
51537
51559
|
}
|
|
51538
51560
|
send(message) {
|
|
51539
|
-
return new Promise((
|
|
51561
|
+
return new Promise((resolve2) => {
|
|
51540
51562
|
if (!this._process?.stdin) {
|
|
51541
51563
|
throw new Error("Not connected");
|
|
51542
51564
|
}
|
|
51543
51565
|
const json2 = serializeMessage(message);
|
|
51544
51566
|
if (this._process.stdin.write(json2)) {
|
|
51545
|
-
|
|
51567
|
+
resolve2();
|
|
51546
51568
|
} else {
|
|
51547
|
-
this._process.stdin.once("drain",
|
|
51569
|
+
this._process.stdin.once("drain", resolve2);
|
|
51548
51570
|
}
|
|
51549
51571
|
});
|
|
51550
51572
|
}
|
|
@@ -53380,7 +53402,7 @@ var DRAFT_SPEC_TLDR_MAX_CHARS = 300;
|
|
|
53380
53402
|
var DRAFT_SPEC_PERSONA = "spec-author";
|
|
53381
53403
|
var PAGE_ID_MAX_ATTEMPTS = 5;
|
|
53382
53404
|
function defaultSleep(ms) {
|
|
53383
|
-
return new Promise((
|
|
53405
|
+
return new Promise((resolve2) => setTimeout(resolve2, ms));
|
|
53384
53406
|
}
|
|
53385
53407
|
function enforceSpecOutputContract(markdown, taskId, title) {
|
|
53386
53408
|
let body = normalizeAcceptanceCriteria(markdown.trim());
|
|
@@ -56195,22 +56217,6 @@ function createMrrlinTools(options) {
|
|
|
56195
56217
|
);
|
|
56196
56218
|
}
|
|
56197
56219
|
}
|
|
56198
|
-
async function autoRetirePendingScopeQuestions(c, projectSlug, resolutionContext) {
|
|
56199
|
-
try {
|
|
56200
|
-
const pendingQuestions = await c.listInboxItems(projectSlug, { status: "pending", kind: "question" });
|
|
56201
|
-
for (const item of pendingQuestions) {
|
|
56202
|
-
if (!item.taskId) {
|
|
56203
|
-
await c.decideInboxItem(projectSlug, item.id, {
|
|
56204
|
-
decidedBy: "director",
|
|
56205
|
-
verdict: "acknowledged",
|
|
56206
|
-
answer: `Addressed in materialized plan/tasks (${resolutionContext})`
|
|
56207
|
-
}).catch(() => {
|
|
56208
|
-
});
|
|
56209
|
-
}
|
|
56210
|
-
}
|
|
56211
|
-
} catch {
|
|
56212
|
-
}
|
|
56213
|
-
}
|
|
56214
56220
|
return {
|
|
56215
56221
|
[mcpToolNames.archivePlan]: makeTool(
|
|
56216
56222
|
client,
|
|
@@ -56229,9 +56235,7 @@ function createMrrlinTools(options) {
|
|
|
56229
56235
|
"Unable to create plan.",
|
|
56230
56236
|
async (c, { projectSlug, ...input }) => {
|
|
56231
56237
|
await checkTenantBoundary(projectSlug, "plan");
|
|
56232
|
-
|
|
56233
|
-
await autoRetirePendingScopeQuestions(c, projectSlug, `Plan ${plan.id}: ${plan.name}`);
|
|
56234
|
-
return plan;
|
|
56238
|
+
return await c.createPlan(projectSlug, input);
|
|
56235
56239
|
}
|
|
56236
56240
|
),
|
|
56237
56241
|
[mcpToolNames.createTaskDependency]: makeTool(
|
|
@@ -56360,9 +56364,7 @@ function createMrrlinTools(options) {
|
|
|
56360
56364
|
async (c, { projectSlug, ...input }) => {
|
|
56361
56365
|
await checkTenantBoundary(projectSlug, "task");
|
|
56362
56366
|
const status = input.status ?? "todo";
|
|
56363
|
-
|
|
56364
|
-
await autoRetirePendingScopeQuestions(c, projectSlug, `Task ${task.id}: ${task.title}`);
|
|
56365
|
-
return task;
|
|
56367
|
+
return await c.createTask(projectSlug, { ...input, status });
|
|
56366
56368
|
}
|
|
56367
56369
|
),
|
|
56368
56370
|
[mcpToolNames.getProject]: makeTool(
|
|
@@ -57564,7 +57566,7 @@ var import_node_http = __toESM(require("node:http"), 1);
|
|
|
57564
57566
|
var import_node_os17 = __toESM(require("node:os"), 1);
|
|
57565
57567
|
var import_node_path38 = __toESM(require("node:path"), 1);
|
|
57566
57568
|
var import_node_child_process21 = require("node:child_process");
|
|
57567
|
-
var
|
|
57569
|
+
var import_node_crypto16 = __toESM(require("node:crypto"), 1);
|
|
57568
57570
|
|
|
57569
57571
|
// src/turn-replay-buffer.ts
|
|
57570
57572
|
var DEFAULT_MAX_EVENTS = 2e3;
|
|
@@ -58083,7 +58085,7 @@ function createTurnLock() {
|
|
|
58083
58085
|
} else {
|
|
58084
58086
|
autonomousTotalActive += 1;
|
|
58085
58087
|
}
|
|
58086
|
-
return new Promise((
|
|
58088
|
+
return new Promise((resolve2, reject) => {
|
|
58087
58089
|
const start = () => {
|
|
58088
58090
|
let bodyPromise;
|
|
58089
58091
|
try {
|
|
@@ -58091,7 +58093,7 @@ function createTurnLock() {
|
|
|
58091
58093
|
} catch (e) {
|
|
58092
58094
|
bodyPromise = Promise.reject(e);
|
|
58093
58095
|
}
|
|
58094
|
-
bodyPromise.then((v) =>
|
|
58096
|
+
bodyPromise.then((v) => resolve2(v)).catch((e) => reject(e)).finally(() => {
|
|
58095
58097
|
if (lane === "chat") {
|
|
58096
58098
|
chatTotalActive -= 1;
|
|
58097
58099
|
} else {
|
|
@@ -58693,7 +58695,7 @@ Do NOT derail the current task - if the operator has an in-flight question, answ
|
|
|
58693
58695
|
}
|
|
58694
58696
|
|
|
58695
58697
|
// src/_generated/version.ts
|
|
58696
|
-
var PKG_VERSION = "0.4.
|
|
58698
|
+
var PKG_VERSION = "0.4.98";
|
|
58697
58699
|
|
|
58698
58700
|
// src/director-closure.ts
|
|
58699
58701
|
var CLOSURE_SNAPSHOT_TIMEOUT_MS = 2e3;
|
|
@@ -58952,7 +58954,6 @@ function closureFor(input) {
|
|
|
58952
58954
|
var LEDGER_MAX_ITEMS = 20;
|
|
58953
58955
|
var LEDGER_MAX_QUESTIONS_PER_TURN = 5;
|
|
58954
58956
|
var LEDGER_MAX_EXTRACTED_QUESTIONS = 50;
|
|
58955
|
-
var LEDGER_REASK_JACCARD = 0.6;
|
|
58956
58957
|
var LEDGER_MAX_QUESTION_CHARS = 300;
|
|
58957
58958
|
function emptyLedger() {
|
|
58958
58959
|
return { turn: 0, items: [] };
|
|
@@ -59043,13 +59044,12 @@ function tokenMatches(a, b) {
|
|
|
59043
59044
|
}
|
|
59044
59045
|
return false;
|
|
59045
59046
|
}
|
|
59047
|
+
function normalizeQuestionIdentity(value) {
|
|
59048
|
+
return value.normalize("NFKC").toLowerCase().replace(/\s+/gu, " ").trim();
|
|
59049
|
+
}
|
|
59046
59050
|
function isSameQuestion(a, b) {
|
|
59047
|
-
const
|
|
59048
|
-
|
|
59049
|
-
if (ta.size === 0 || tb.size === 0) return false;
|
|
59050
|
-
let shared = 0;
|
|
59051
|
-
for (const token of ta) if (tb.has(token)) shared += 1;
|
|
59052
|
-
return shared / (ta.size + tb.size - shared) >= LEDGER_REASK_JACCARD;
|
|
59051
|
+
const left = normalizeQuestionIdentity(a);
|
|
59052
|
+
return /[\p{L}\p{N}]/u.test(left) && left === normalizeQuestionIdentity(b);
|
|
59053
59053
|
}
|
|
59054
59054
|
function isAffirmativeResolutionForQuestion(question, text, otherQuestions) {
|
|
59055
59055
|
if (!text || !RESOLUTION_MARKER_RE.test(text)) return false;
|
|
@@ -59884,7 +59884,7 @@ async function writeCrashSentinel(stateDir, sentinel) {
|
|
|
59884
59884
|
}
|
|
59885
59885
|
function withTimeout(fn, ms = DEFAULT_OPERATION_TIMEOUT_MS) {
|
|
59886
59886
|
const controller = new AbortController();
|
|
59887
|
-
return new Promise((
|
|
59887
|
+
return new Promise((resolve2, reject) => {
|
|
59888
59888
|
const timer = setTimeout(() => {
|
|
59889
59889
|
controller.abort();
|
|
59890
59890
|
const timeoutError = new Error(`operation timed out after ${ms}ms`);
|
|
@@ -59894,7 +59894,7 @@ function withTimeout(fn, ms = DEFAULT_OPERATION_TIMEOUT_MS) {
|
|
|
59894
59894
|
fn(controller.signal).then(
|
|
59895
59895
|
(value) => {
|
|
59896
59896
|
clearTimeout(timer);
|
|
59897
|
-
|
|
59897
|
+
resolve2(value);
|
|
59898
59898
|
},
|
|
59899
59899
|
(error51) => {
|
|
59900
59900
|
clearTimeout(timer);
|
|
@@ -60840,7 +60840,7 @@ function runExternalAgentsCli(args, opts) {
|
|
|
60840
60840
|
}
|
|
60841
60841
|
const useStdin = opts.stdinValue !== void 0;
|
|
60842
60842
|
const stdioConfig = useStdin ? ["pipe", "pipe", "pipe"] : ["ignore", "pipe", "pipe"];
|
|
60843
|
-
return new Promise((
|
|
60843
|
+
return new Promise((resolve2) => {
|
|
60844
60844
|
let stdout = "";
|
|
60845
60845
|
let stderr = "";
|
|
60846
60846
|
let settled = false;
|
|
@@ -60848,7 +60848,7 @@ function runExternalAgentsCli(args, opts) {
|
|
|
60848
60848
|
const done = (code) => {
|
|
60849
60849
|
if (!settled) {
|
|
60850
60850
|
settled = true;
|
|
60851
|
-
|
|
60851
|
+
resolve2({ stdout, stderr, code, timedOut, source, triedPath });
|
|
60852
60852
|
}
|
|
60853
60853
|
};
|
|
60854
60854
|
let spawned;
|
|
@@ -61016,7 +61016,7 @@ function startProviderReadinessLoop(deps) {
|
|
|
61016
61016
|
|
|
61017
61017
|
// src/execution-consumer.ts
|
|
61018
61018
|
var import_node_child_process19 = require("node:child_process");
|
|
61019
|
-
var
|
|
61019
|
+
var import_node_crypto14 = __toESM(require("node:crypto"), 1);
|
|
61020
61020
|
var import_node_path31 = __toESM(require("node:path"), 1);
|
|
61021
61021
|
var import_node_util2 = require("node:util");
|
|
61022
61022
|
|
|
@@ -61872,6 +61872,7 @@ async function awaitTurnWithDeadline(opts) {
|
|
|
61872
61872
|
|
|
61873
61873
|
// src/worktree.ts
|
|
61874
61874
|
var import_node_child_process18 = require("node:child_process");
|
|
61875
|
+
var import_node_crypto13 = require("node:crypto");
|
|
61875
61876
|
var import_node_fs17 = require("node:fs");
|
|
61876
61877
|
var import_node_path30 = require("node:path");
|
|
61877
61878
|
|
|
@@ -61899,8 +61900,43 @@ function worktreeBranch(runId) {
|
|
|
61899
61900
|
return `mrrlin/run-${runId}`;
|
|
61900
61901
|
}
|
|
61901
61902
|
var defaultGitExec = (args, env) => (0, import_node_child_process18.execFileSync)("git", args, { encoding: "utf8", timeout: 3e4, env });
|
|
61902
|
-
function
|
|
61903
|
-
|
|
61903
|
+
function disabledGitHooksPath(locksDir, scope) {
|
|
61904
|
+
const scopeKey = (0, import_node_crypto13.createHash)("sha256").update(scope).digest("hex").slice(0, 32);
|
|
61905
|
+
return (0, import_node_path30.resolve)(locksDir, "..", "disabled-git-hooks", scopeKey);
|
|
61906
|
+
}
|
|
61907
|
+
function prepareDisabledGitHooksDir(locksDir, scope) {
|
|
61908
|
+
const hooksDir = disabledGitHooksPath(locksDir, scope);
|
|
61909
|
+
const hooksRoot = (0, import_node_path30.resolve)(hooksDir, "..");
|
|
61910
|
+
(0, import_node_fs17.mkdirSync)(hooksRoot, { recursive: true, mode: 448 });
|
|
61911
|
+
(0, import_node_fs17.mkdirSync)(hooksDir, { recursive: true, mode: 320 });
|
|
61912
|
+
if ((0, import_node_fs17.readdirSync)(hooksDir).length > 0) {
|
|
61913
|
+
throw new Error(`disabled_git_hooks_dir_not_empty: ${hooksDir}`);
|
|
61914
|
+
}
|
|
61915
|
+
try {
|
|
61916
|
+
(0, import_node_fs17.chmodSync)(hooksDir, 320);
|
|
61917
|
+
} catch {
|
|
61918
|
+
}
|
|
61919
|
+
return hooksDir;
|
|
61920
|
+
}
|
|
61921
|
+
function removeDisabledGitHooksDir(locksDir, scope) {
|
|
61922
|
+
try {
|
|
61923
|
+
(0, import_node_fs17.rmdirSync)(disabledGitHooksPath(locksDir, scope));
|
|
61924
|
+
} catch {
|
|
61925
|
+
}
|
|
61926
|
+
}
|
|
61927
|
+
function withDisabledGitHooksEnv(env, hooksDir) {
|
|
61928
|
+
const rawCount = env.GIT_CONFIG_COUNT;
|
|
61929
|
+
const parsedCount = rawCount === void 0 ? 0 : Number(rawCount);
|
|
61930
|
+
const count2 = Number.isSafeInteger(parsedCount) && parsedCount >= 0 ? parsedCount : 0;
|
|
61931
|
+
return {
|
|
61932
|
+
...env,
|
|
61933
|
+
GIT_CONFIG_COUNT: String(count2 + 1),
|
|
61934
|
+
[`GIT_CONFIG_KEY_${count2}`]: "core.hooksPath",
|
|
61935
|
+
[`GIT_CONFIG_VALUE_${count2}`]: hooksDir
|
|
61936
|
+
};
|
|
61937
|
+
}
|
|
61938
|
+
function git(checkout, args, hooksDir) {
|
|
61939
|
+
return (0, import_node_child_process18.execFileSync)("git", ["-C", checkout, "-c", `core.hooksPath=${hooksDir}`, ...args], {
|
|
61904
61940
|
encoding: "utf8",
|
|
61905
61941
|
timeout: 3e4,
|
|
61906
61942
|
env: { ...process.env, GIT_TERMINAL_PROMPT: "0" }
|
|
@@ -61908,20 +61944,21 @@ function git(checkout, args) {
|
|
|
61908
61944
|
}
|
|
61909
61945
|
async function createRunWorktree(opts) {
|
|
61910
61946
|
const worktreePath = (0, import_node_path30.join)(opts.worktreeRoot, opts.slug, opts.runId);
|
|
61947
|
+
const hooksDir = prepareDisabledGitHooksDir(opts.locksDir, opts.runId);
|
|
61911
61948
|
await withCheckoutLock(opts.locksDir, opts.slug, async () => {
|
|
61912
61949
|
(0, import_node_fs17.mkdirSync)(opts.worktreeRoot, { recursive: true });
|
|
61913
61950
|
try {
|
|
61914
|
-
git(opts.checkout, ["fetch", "origin", opts.defaultBranch]);
|
|
61951
|
+
git(opts.checkout, ["fetch", "origin", opts.defaultBranch], hooksDir);
|
|
61915
61952
|
if (!(0, import_node_fs17.existsSync)(worktreePath)) {
|
|
61916
61953
|
git(opts.checkout, [
|
|
61917
61954
|
"worktree",
|
|
61918
61955
|
"add",
|
|
61956
|
+
"--no-track",
|
|
61919
61957
|
"-b",
|
|
61920
61958
|
worktreeBranch(opts.runId),
|
|
61921
61959
|
worktreePath,
|
|
61922
61960
|
`origin/${opts.defaultBranch}`
|
|
61923
|
-
]);
|
|
61924
|
-
git(worktreePath, ["config", "core.hooksPath", "/dev/null"]);
|
|
61961
|
+
], hooksDir);
|
|
61925
61962
|
}
|
|
61926
61963
|
} catch (error51) {
|
|
61927
61964
|
const detail = error51 instanceof Error ? error51.message : String(error51);
|
|
@@ -61933,12 +61970,14 @@ async function createRunWorktree(opts) {
|
|
|
61933
61970
|
return worktreePath;
|
|
61934
61971
|
}
|
|
61935
61972
|
async function removeRunWorktree(opts) {
|
|
61973
|
+
const hooksDir = prepareDisabledGitHooksDir(opts.locksDir, (0, import_node_path30.basename)(opts.worktreePath));
|
|
61936
61974
|
await withCheckoutLock(opts.locksDir, opts.slug, async () => {
|
|
61937
61975
|
try {
|
|
61938
|
-
git(opts.checkout, ["worktree", "remove", "--force", opts.worktreePath]);
|
|
61976
|
+
git(opts.checkout, ["worktree", "remove", "--force", opts.worktreePath], hooksDir);
|
|
61939
61977
|
} catch {
|
|
61940
61978
|
}
|
|
61941
|
-
git(opts.checkout, ["worktree", "prune"]);
|
|
61979
|
+
git(opts.checkout, ["worktree", "prune"], hooksDir);
|
|
61980
|
+
removeDisabledGitHooksDir(opts.locksDir, (0, import_node_path30.basename)(opts.worktreePath));
|
|
61942
61981
|
});
|
|
61943
61982
|
}
|
|
61944
61983
|
async function pushRunBranch(opts, execGit = defaultGitExec) {
|
|
@@ -61961,6 +62000,7 @@ async function hasCommitsToPush(opts, execGit = defaultGitExec) {
|
|
|
61961
62000
|
}
|
|
61962
62001
|
async function doPushRunBranch(opts, execGit) {
|
|
61963
62002
|
const branch = worktreeBranch(opts.runId);
|
|
62003
|
+
const hooksDir = prepareDisabledGitHooksDir(opts.locksDir, opts.runId);
|
|
61964
62004
|
const pushEnv = {
|
|
61965
62005
|
PATH: process.env.PATH ?? "",
|
|
61966
62006
|
...process.env.HOME !== void 0 ? { HOME: process.env.HOME } : {},
|
|
@@ -62006,7 +62046,7 @@ async function doPushRunBranch(opts, execGit) {
|
|
|
62006
62046
|
"-C",
|
|
62007
62047
|
opts.worktreePath,
|
|
62008
62048
|
"-c",
|
|
62009
|
-
|
|
62049
|
+
`core.hooksPath=${hooksDir}`,
|
|
62010
62050
|
"push",
|
|
62011
62051
|
"--no-verify",
|
|
62012
62052
|
"origin",
|
|
@@ -62018,6 +62058,7 @@ async function doPushRunBranch(opts, execGit) {
|
|
|
62018
62058
|
}
|
|
62019
62059
|
async function sweepOrphanWorktrees(opts) {
|
|
62020
62060
|
const reaped = [];
|
|
62061
|
+
const hooksDir = prepareDisabledGitHooksDir(opts.locksDir, `sweep:${opts.slug}`);
|
|
62021
62062
|
const ownedPrefix = (() => {
|
|
62022
62063
|
try {
|
|
62023
62064
|
return (import_node_fs17.realpathSync.native ?? import_node_fs17.realpathSync)(opts.worktreeRoot);
|
|
@@ -62025,32 +62066,37 @@ async function sweepOrphanWorktrees(opts) {
|
|
|
62025
62066
|
return opts.worktreeRoot;
|
|
62026
62067
|
}
|
|
62027
62068
|
})() + import_node_path30.sep + opts.slug + import_node_path30.sep;
|
|
62028
|
-
|
|
62029
|
-
|
|
62030
|
-
|
|
62031
|
-
const
|
|
62032
|
-
|
|
62033
|
-
|
|
62034
|
-
|
|
62035
|
-
|
|
62036
|
-
|
|
62037
|
-
|
|
62038
|
-
|
|
62039
|
-
|
|
62040
|
-
|
|
62041
|
-
|
|
62042
|
-
|
|
62043
|
-
|
|
62044
|
-
|
|
62045
|
-
|
|
62046
|
-
|
|
62047
|
-
|
|
62048
|
-
|
|
62069
|
+
try {
|
|
62070
|
+
await withCheckoutLock(opts.locksDir, opts.slug, async () => {
|
|
62071
|
+
const listing = git(opts.checkout, ["worktree", "list", "--porcelain"], hooksDir);
|
|
62072
|
+
for (const block of listing.split("\n\n")) {
|
|
62073
|
+
const m = /^worktree (.+)$/m.exec(block);
|
|
62074
|
+
const wt = m?.[1]?.trim();
|
|
62075
|
+
if (!wt) continue;
|
|
62076
|
+
const canonicalWt = (() => {
|
|
62077
|
+
try {
|
|
62078
|
+
return (import_node_fs17.realpathSync.native ?? import_node_fs17.realpathSync)(wt);
|
|
62079
|
+
} catch {
|
|
62080
|
+
return wt;
|
|
62081
|
+
}
|
|
62082
|
+
})();
|
|
62083
|
+
const normWt = (0, import_node_path30.normalize)(canonicalWt);
|
|
62084
|
+
const normPrefix = (0, import_node_path30.normalize)(ownedPrefix);
|
|
62085
|
+
const isMatch = process.platform === "win32" ? normWt.toLowerCase().startsWith(normPrefix.toLowerCase()) : normWt.startsWith(normPrefix);
|
|
62086
|
+
if (isMatch && opts.isReapable(wt)) {
|
|
62087
|
+
try {
|
|
62088
|
+
git(opts.checkout, ["worktree", "remove", "--force", wt], hooksDir);
|
|
62089
|
+
removeDisabledGitHooksDir(opts.locksDir, (0, import_node_path30.basename)(wt));
|
|
62090
|
+
reaped.push(wt);
|
|
62091
|
+
} catch {
|
|
62092
|
+
}
|
|
62049
62093
|
}
|
|
62050
62094
|
}
|
|
62051
|
-
|
|
62052
|
-
|
|
62053
|
-
}
|
|
62095
|
+
git(opts.checkout, ["worktree", "prune"], hooksDir);
|
|
62096
|
+
});
|
|
62097
|
+
} finally {
|
|
62098
|
+
removeDisabledGitHooksDir(opts.locksDir, `sweep:${opts.slug}`);
|
|
62099
|
+
}
|
|
62054
62100
|
return reaped;
|
|
62055
62101
|
}
|
|
62056
62102
|
|
|
@@ -62244,7 +62290,7 @@ function readPositiveIntEnv(name, fallback) {
|
|
|
62244
62290
|
return Number.isInteger(parsed) && parsed > 0 ? parsed : fallback;
|
|
62245
62291
|
}
|
|
62246
62292
|
function delayMs(ms) {
|
|
62247
|
-
return new Promise((
|
|
62293
|
+
return new Promise((resolve2) => setTimeout(resolve2, ms));
|
|
62248
62294
|
}
|
|
62249
62295
|
function executionBundleBudget() {
|
|
62250
62296
|
if ((process.env.MRRLIN_RETRIEVAL_BUDGET_DISABLE ?? "").trim() === "1") return void 0;
|
|
@@ -62572,7 +62618,7 @@ function isBridgeGeneratedArtifact(artifact) {
|
|
|
62572
62618
|
return typeof payload === "object" && payload !== null && "event" in payload;
|
|
62573
62619
|
}
|
|
62574
62620
|
function newArtifactId() {
|
|
62575
|
-
return `EA-${
|
|
62621
|
+
return `EA-${import_node_crypto14.default.randomUUID()}`;
|
|
62576
62622
|
}
|
|
62577
62623
|
var BLAST_RADIUS_FLOOR_PATTERNS = [/^supabase\/migrations\//, /^packages\/db\/src\/schema\.ts$/];
|
|
62578
62624
|
function isBlastRadiusFloorPath(path29) {
|
|
@@ -62741,8 +62787,8 @@ async function driveTurn(deps, codex, projectSlug, runId, leaseId, threadId, inp
|
|
|
62741
62787
|
return deps.run("exec", async () => {
|
|
62742
62788
|
const pending = [];
|
|
62743
62789
|
let resolveTurnEnded = null;
|
|
62744
|
-
const turnEnded = new Promise((
|
|
62745
|
-
resolveTurnEnded =
|
|
62790
|
+
const turnEnded = new Promise((resolve2) => {
|
|
62791
|
+
resolveTurnEnded = resolve2;
|
|
62746
62792
|
});
|
|
62747
62793
|
let acceptedTurnId = null;
|
|
62748
62794
|
const unsubActivity = codex.onActivity(threadId, () => {
|
|
@@ -62823,7 +62869,7 @@ async function driveRun(deps, projectSlug, runId) {
|
|
|
62823
62869
|
if (!claimed) return;
|
|
62824
62870
|
if (!claimed.leaseId) {
|
|
62825
62871
|
await deps.client.createInboxItem(projectSlug, {
|
|
62826
|
-
id: `II-${
|
|
62872
|
+
id: `II-${import_node_crypto14.default.randomUUID()}`,
|
|
62827
62873
|
kind: "handoff",
|
|
62828
62874
|
taskId: claimed.taskId,
|
|
62829
62875
|
body: `Execution run ${runId} was claimed but returned no leaseId. This indicates DB/API corruption and requires operator attention.`
|
|
@@ -64274,7 +64320,7 @@ async function reconcileTaskAwaitingMerge(deps, projectSlug, task, runId, reason
|
|
|
64274
64320
|
}
|
|
64275
64321
|
try {
|
|
64276
64322
|
await deps.client.createInboxItem(projectSlug, {
|
|
64277
|
-
id: `II-${
|
|
64323
|
+
id: `II-${import_node_crypto14.default.randomUUID()}`,
|
|
64278
64324
|
kind: "handoff",
|
|
64279
64325
|
taskId: task.id,
|
|
64280
64326
|
body: `Task ${task.id} (${task.title}) still needs operator follow-up: ${reason}. Mrrlin could not move the task back to Handoff needed automatically.`
|
|
@@ -64309,7 +64355,7 @@ async function notifyOperatorHandoff(deps, projectSlug, task, runId, reason) {
|
|
|
64309
64355
|
}
|
|
64310
64356
|
try {
|
|
64311
64357
|
await deps.client.createInboxItem(projectSlug, {
|
|
64312
|
-
id: `II-${
|
|
64358
|
+
id: `II-${import_node_crypto14.default.randomUUID()}`,
|
|
64313
64359
|
kind: "handoff",
|
|
64314
64360
|
taskId: task.id,
|
|
64315
64361
|
body: `Execution run ${runId} for task ${task.id} (${task.title}) needs operator attention: ${reason}`
|
|
@@ -64470,7 +64516,7 @@ async function deployGateHandoff(deps, projectSlug, task, runId, reason, leaseId
|
|
|
64470
64516
|
}).catch(() => {
|
|
64471
64517
|
});
|
|
64472
64518
|
await deps.client.createInboxItem(projectSlug, {
|
|
64473
|
-
id: `II-${
|
|
64519
|
+
id: `II-${import_node_crypto14.default.randomUUID()}`,
|
|
64474
64520
|
kind: "handoff",
|
|
64475
64521
|
taskId: task.id,
|
|
64476
64522
|
body: `Deploy gate for run ${runId} (task ${task.id} \u2014 ${task.title}) needs operator attention: ${reason}`
|
|
@@ -64489,7 +64535,7 @@ function maxLeaseReclaims() {
|
|
|
64489
64535
|
}
|
|
64490
64536
|
|
|
64491
64537
|
// src/async-job-consumer.ts
|
|
64492
|
-
var
|
|
64538
|
+
var import_node_crypto15 = __toESM(require("node:crypto"), 1);
|
|
64493
64539
|
var ASYNC_JOB_MAX_ATTEMPTS = 2;
|
|
64494
64540
|
function ASYNC_UNOWNED_TTL_DAYS() {
|
|
64495
64541
|
const raw = Number(process.env.MRRLIN_ASYNC_UNOWNED_TTL_DAYS);
|
|
@@ -64614,7 +64660,7 @@ async function driveAsyncJob(deps, projectSlug, jobId) {
|
|
|
64614
64660
|
const delivery = descriptor2.onComplete(outcome, input);
|
|
64615
64661
|
if (!delivery.suppressInbox) {
|
|
64616
64662
|
await deps.client.createInboxItem(projectSlug, {
|
|
64617
|
-
id: delivery.id ?? `II-${
|
|
64663
|
+
id: delivery.id ?? `II-${import_node_crypto15.default.randomUUID()}`,
|
|
64618
64664
|
kind: delivery.kind,
|
|
64619
64665
|
body: delivery.body,
|
|
64620
64666
|
...delivery.taskId ? { taskId: delivery.taskId } : {},
|
|
@@ -64632,13 +64678,13 @@ async function deriveRequestedHash(client, toolName, input) {
|
|
|
64632
64678
|
if (input.requestedHash) return input.requestedHash;
|
|
64633
64679
|
if (toolName === "run_spec_consensus" && input.pageId) {
|
|
64634
64680
|
const page = await client.getWikiPage(input.projectSlug, input.pageId);
|
|
64635
|
-
return page.contentHash ??
|
|
64681
|
+
return page.contentHash ?? import_node_crypto15.default.createHash("sha256").update(page.markdownBody).digest("hex");
|
|
64636
64682
|
}
|
|
64637
64683
|
if (toolName === "draft_task_spec" && input.taskId) {
|
|
64638
64684
|
const task = await client.getTask(input.projectSlug, input.taskId);
|
|
64639
|
-
return task.updatedAt ??
|
|
64685
|
+
return task.updatedAt ?? import_node_crypto15.default.createHash("sha256").update(JSON.stringify(task)).digest("hex");
|
|
64640
64686
|
}
|
|
64641
|
-
return
|
|
64687
|
+
return import_node_crypto15.default.createHash("sha256").update(JSON.stringify(input)).digest("hex");
|
|
64642
64688
|
}
|
|
64643
64689
|
async function runAsyncBackstopSweep(deps, drive = (slug, jobId) => driveAsyncJob(deps, slug, jobId)) {
|
|
64644
64690
|
const projects = await deps.client.listProjects();
|
|
@@ -68742,7 +68788,7 @@ function saveAgentPairing(record2) {
|
|
|
68742
68788
|
}
|
|
68743
68789
|
}
|
|
68744
68790
|
function runPhoneTurn(handler, directorSessionId, text, emit) {
|
|
68745
|
-
return new Promise((
|
|
68791
|
+
return new Promise((resolve2) => {
|
|
68746
68792
|
const emitter = new import_node_events3.EventEmitter();
|
|
68747
68793
|
const fakeSocket = {
|
|
68748
68794
|
on: (event, cb) => {
|
|
@@ -68757,7 +68803,7 @@ function runPhoneTurn(handler, directorSessionId, text, emit) {
|
|
|
68757
68803
|
settled = true;
|
|
68758
68804
|
if (timer) clearTimeout(timer);
|
|
68759
68805
|
emitter.removeAllListeners();
|
|
68760
|
-
|
|
68806
|
+
resolve2();
|
|
68761
68807
|
};
|
|
68762
68808
|
const send = (msg) => {
|
|
68763
68809
|
if (msg.type === "error") {
|
|
@@ -68917,13 +68963,19 @@ async function renderPairingQrSvg(payload) {
|
|
|
68917
68963
|
// src/executor-server.ts
|
|
68918
68964
|
var import_node_child_process20 = require("node:child_process");
|
|
68919
68965
|
function defaultReadinessRunner(provider) {
|
|
68920
|
-
|
|
68966
|
+
if (provider !== "codex" && provider !== "claude" && provider !== "agy") {
|
|
68967
|
+
throw new Error(`unsupported executor provider: ${String(provider)}`);
|
|
68968
|
+
}
|
|
68969
|
+
const command = provider === "claude" ? "claude" : provider === "agy" ? "agy" : "codex";
|
|
68921
68970
|
return (args) => {
|
|
68922
68971
|
const r = (0, import_node_child_process20.spawnSync)(command, args, { encoding: "utf8", timeout: 8e3, shell: true });
|
|
68923
68972
|
return { status: r.status, stdout: r.stdout ?? "", stderr: r.stderr ?? "" };
|
|
68924
68973
|
};
|
|
68925
68974
|
}
|
|
68926
68975
|
async function startExecutorServer(opts) {
|
|
68976
|
+
if (opts.provider !== "codex" && opts.provider !== "claude" && opts.provider !== "agy") {
|
|
68977
|
+
throw new Error(`unsupported executor provider: ${String(opts.provider)}`);
|
|
68978
|
+
}
|
|
68927
68979
|
const verify = opts.verifyReadiness ?? verifyProviderReadiness;
|
|
68928
68980
|
const runner = opts.readinessRunner ?? defaultReadinessRunner(opts.provider);
|
|
68929
68981
|
const readiness = await verify(opts.provider, runner);
|
|
@@ -68936,8 +68988,37 @@ async function startExecutorServer(opts) {
|
|
|
68936
68988
|
error51.details = readiness.details;
|
|
68937
68989
|
throw error51;
|
|
68938
68990
|
}
|
|
68991
|
+
const baseEnv = { ...opts.env ?? process.env };
|
|
68992
|
+
const childEnv = withDisabledGitHooksEnv(baseEnv, opts.disabledGitHooksDir);
|
|
68993
|
+
if (opts.provider === "codex") {
|
|
68994
|
+
const manager = new CodexServerManager();
|
|
68995
|
+
try {
|
|
68996
|
+
const client = await manager.acquire({
|
|
68997
|
+
cwd: opts.worktree,
|
|
68998
|
+
approvalPolicy: "never",
|
|
68999
|
+
env: childEnv,
|
|
69000
|
+
...opts.spawn ? { spawn: opts.spawn } : {}
|
|
69001
|
+
});
|
|
69002
|
+
let disposed = false;
|
|
69003
|
+
const dispose = () => {
|
|
69004
|
+
if (disposed) return;
|
|
69005
|
+
disposed = true;
|
|
69006
|
+
try {
|
|
69007
|
+
manager.shutdown();
|
|
69008
|
+
} catch {
|
|
69009
|
+
}
|
|
69010
|
+
};
|
|
69011
|
+
return { handle: createCodexAgentHandle(client), dispose };
|
|
69012
|
+
} catch (error51) {
|
|
69013
|
+
try {
|
|
69014
|
+
manager.shutdown();
|
|
69015
|
+
} catch {
|
|
69016
|
+
}
|
|
69017
|
+
throw error51;
|
|
69018
|
+
}
|
|
69019
|
+
}
|
|
68939
69020
|
if (opts.provider === "claude") {
|
|
68940
|
-
const handle = new ClaudeAgentHandle();
|
|
69021
|
+
const handle = new ClaudeAgentHandle(childEnv);
|
|
68941
69022
|
let disposed = false;
|
|
68942
69023
|
const dispose = () => {
|
|
68943
69024
|
if (disposed) return;
|
|
@@ -68946,30 +69027,17 @@ async function startExecutorServer(opts) {
|
|
|
68946
69027
|
};
|
|
68947
69028
|
return { handle, dispose };
|
|
68948
69029
|
}
|
|
68949
|
-
|
|
68950
|
-
|
|
68951
|
-
const client = await manager.acquire({
|
|
68952
|
-
cwd: opts.worktree,
|
|
68953
|
-
approvalPolicy: "never",
|
|
68954
|
-
...opts.spawn ? { spawn: opts.spawn } : {}
|
|
68955
|
-
});
|
|
69030
|
+
if (opts.provider === "agy") {
|
|
69031
|
+
const handle = new AgyAgentHandle(childEnv);
|
|
68956
69032
|
let disposed = false;
|
|
68957
69033
|
const dispose = () => {
|
|
68958
69034
|
if (disposed) return;
|
|
68959
69035
|
disposed = true;
|
|
68960
|
-
|
|
68961
|
-
manager.shutdown();
|
|
68962
|
-
} catch {
|
|
68963
|
-
}
|
|
69036
|
+
handle.disposeAll();
|
|
68964
69037
|
};
|
|
68965
|
-
return { handle
|
|
68966
|
-
} catch (error51) {
|
|
68967
|
-
try {
|
|
68968
|
-
manager.shutdown();
|
|
68969
|
-
} catch {
|
|
68970
|
-
}
|
|
68971
|
-
throw error51;
|
|
69038
|
+
return { handle, dispose };
|
|
68972
69039
|
}
|
|
69040
|
+
throw new Error(`unsupported executor provider: ${String(opts.provider)}`);
|
|
68973
69041
|
}
|
|
68974
69042
|
|
|
68975
69043
|
// src/self-review.ts
|
|
@@ -69758,9 +69826,9 @@ function readCodexFallbackModels() {
|
|
|
69758
69826
|
return [...models.values()];
|
|
69759
69827
|
}
|
|
69760
69828
|
function selfUpdateInboxItemId(offeredVersion) {
|
|
69761
|
-
if (!offeredVersion) return `II-MCPUPD-${(0,
|
|
69829
|
+
if (!offeredVersion) return `II-MCPUPD-${(0, import_node_crypto16.randomUUID)()}`;
|
|
69762
69830
|
if (/^[A-Za-z0-9._-]+$/.test(offeredVersion)) return `II-MCPUPD-${offeredVersion}`;
|
|
69763
|
-
const hash3 =
|
|
69831
|
+
const hash3 = import_node_crypto16.default.createHash("sha256").update(offeredVersion).digest("hex").slice(0, 10);
|
|
69764
69832
|
return `II-MCPUPD-${offeredVersion.replace(/[^A-Za-z0-9._-]/g, "-")}-${hash3}`;
|
|
69765
69833
|
}
|
|
69766
69834
|
function neutralCheckoutCwd(stateDir) {
|
|
@@ -69797,7 +69865,7 @@ function buildThreadStartParams(msg, config2, desiredModel) {
|
|
|
69797
69865
|
"- Spec pages in folder Specs must contain `## Acceptance criteria` followed by `- [ ]` items.",
|
|
69798
69866
|
"- AGNOSTIC DELIVERY MANDATE: Mrrlin is an Agnostic Delivery Platform decoupled from mandatory GitHub. Delivery is routed strictly by artifact kind: (1) document -> wiki (specs, policies, legal compliance playbooks, project documentation); (2) page -> publish (web pages, landing pages, interactive HTML previews); (3) file_set -> artifacts (file uploads, bundles, build zips); (4) message -> send (outbound webhooks, Slack, notifications); (5) code_change -> repo_host (git / GitHub ONLY when modifying source repository code). NEVER stall or refuse non-code tasks (such as marketing landing pages, GDPR checklists, or legal compliance playbooks) by demanding a Git repository. Non-code tasks deliver directly via page (Publish) or document (Wiki).",
|
|
69799
69867
|
"- 3-TIER COMMERCIAL SCOPE GOVERNANCE: Treat tasks by domain governance tier. (1) Tier 1 Core Tech Delivery (backend, frontend, SRE, databases): decompose autonomously into repository code changes (when a repo is bound) or code artifacts. (2) Tier 2 Planning & Content (landing pages, SEO, marketing): create actionable drafts; when details such as a phone number, brand name or copy are missing, do not loop on questions \u2014 create the task, record `## Placeholders: [NEED_INPUT: <item>]` in the Wiki spec, and set `autonomyLevel: 'human_review'`. (3) Tier 3 Guardrailed Advisory (high risk: privacy/GDPR, security/SOC 2, billing, production database migrations, infrastructure): always set `autonomyLevel: 'human_review'`, put the domain's standard safety controls into the spec, and state that irreversible actions need human sign-off.",
|
|
69800
|
-
"- INBOX QUESTION RETIREMENT MANDATE
|
|
69868
|
+
"- INBOX QUESTION RETIREMENT MANDATE \u2014 Retiring answered questions: Before creating a task/plan, retire only pending Inbox questions the operator actually answered. Call `decide_inbox_item(itemId: <exact id>, decidedBy: 'director', verdict: 'acknowledged', answer: <actual answer>)`. Use `verdict: 'rejected', reason: ...` only if moot. Never close an unrelated item.",
|
|
69801
69869
|
"- CHAT CLARIFICATIONS ARE IN CHAT ONLY: During synchronous interactive Director chat, ask clarifying questions directly in your chat response. DO NOT call `create_inbox_item(kind: 'question')` for routine conversational clarifications in Turn 1 \u2014 Inbox questions are reserved for autonomous background workers or asynchronous gate pauses that occur while the operator is away.",
|
|
69802
69870
|
"- AUTOPILOT PRESENCE FENCE TRANSPARENCY: Autopilot requires operator web app presence to trigger execution ticks (`operator_absent`). When the operator asks about autopilot starting, remind them that keeping the web tab open allows the scheduler to advance the queue automatically.",
|
|
69803
69871
|
"",
|
|
@@ -70142,7 +70210,7 @@ function buildThreadStartParams(msg, config2, desiredModel) {
|
|
|
70142
70210
|
'- In synchronous live Director chat (Turn 1 scoping), ask your questions directly in your chat reply without creating Inbox items. Only bank questions in Inbox (`create_inbox_item` with `kind="question"`, `taskId` set, `directorSessionId` from Context JSON, `questionOptions` = 2-3 concrete answer options) when an autonomous background task pauses, when a task requires operator decision while the operator is away, or when explicitly requested. Each banked option MUST include a short `label`, a concise `description`, and a self-contained durable `answer`; you MAY mark at most one option as `recommended` when you explicitly prefer a path.',
|
|
70143
70211
|
'- When the operator answers in chat, write the answer into the Specs/{taskId} Clarifications section, and if an Inbox question was previously open, `decide_inbox_item` with `verdict="acknowledged"` and `answer` = the resolved answer.',
|
|
70144
70212
|
"- Project-level ambiguity (scope or direction not yet tied to a specific task) in live chat stays in chat; for genuine asynchronous pauses it MAY be banked with `taskId` OMITTED. Reserve taskless Inbox questions for genuine project-level scope.",
|
|
70145
|
-
"-
|
|
70213
|
+
"- When the operator answers a banked question, immediately call `decide_inbox_item` with its exact `itemId`, `decidedBy='director'`, `verdict='acknowledged'`, and the actual `answer` before any `create_task`. Never close another pending question.",
|
|
70146
70214
|
"- Binding taskless answers to a task: WHEN you create a task out of project-level scoping,",
|
|
70147
70215
|
" call `list_inbox_items` (kind=question), fold any relevant `acknowledged` TASKLESS answer",
|
|
70148
70216
|
" into the new task's Specs/{id} Clarifications, and `reject` (with a reason) any taskless",
|
|
@@ -70248,8 +70316,8 @@ async function runCollectedAgentTurn(handle, prompt, cwd, baseInstructions) {
|
|
|
70248
70316
|
let acceptedTurnId;
|
|
70249
70317
|
let turnError = null;
|
|
70250
70318
|
let resolveTurnEnded = null;
|
|
70251
|
-
const turnEnded = new Promise((
|
|
70252
|
-
resolveTurnEnded =
|
|
70319
|
+
const turnEnded = new Promise((resolve2) => {
|
|
70320
|
+
resolveTurnEnded = resolve2;
|
|
70253
70321
|
});
|
|
70254
70322
|
const unsub = handle.onEvent(threadId, (event) => {
|
|
70255
70323
|
if (event.type === "assistant") chunks.push(event.content);
|
|
@@ -70468,7 +70536,7 @@ function createBridgeRequestListener(opts) {
|
|
|
70468
70536
|
res.end(JSON.stringify({ ok: false, error: "Origin not allowed." }));
|
|
70469
70537
|
return;
|
|
70470
70538
|
}
|
|
70471
|
-
const nonce =
|
|
70539
|
+
const nonce = import_node_crypto16.default.randomBytes(16).toString("base64url");
|
|
70472
70540
|
res.writeHead(200, { "content-type": "application/json" });
|
|
70473
70541
|
const publicHost = host === "0.0.0.0" ? "127.0.0.1" : host;
|
|
70474
70542
|
res.end(JSON.stringify({ ok: true, wsUrl: `ws://${publicHost}:${port}/ws`, token, nonce }));
|
|
@@ -70772,7 +70840,7 @@ function createBridgeMessageHandler(deps) {
|
|
|
70772
70840
|
}
|
|
70773
70841
|
}
|
|
70774
70842
|
socket.on("message", async (data) => {
|
|
70775
|
-
const spanId =
|
|
70843
|
+
const spanId = import_node_crypto16.default.randomUUID();
|
|
70776
70844
|
if (logCtx) {
|
|
70777
70845
|
logCtx.span.id = spanId;
|
|
70778
70846
|
logCtx.span.at = Date.now();
|
|
@@ -71379,7 +71447,7 @@ function createBridgeMessageHandler(deps) {
|
|
|
71379
71447
|
let desiredInstructionHash = null;
|
|
71380
71448
|
try {
|
|
71381
71449
|
const startParams = deps.buildStartParams(msg, desiredModel);
|
|
71382
|
-
desiredInstructionHash =
|
|
71450
|
+
desiredInstructionHash = import_node_crypto16.default.createHash("sha256").update(startParams.baseInstructions ?? "").digest("hex");
|
|
71383
71451
|
if (!thread) {
|
|
71384
71452
|
const newThread = {
|
|
71385
71453
|
threadId: "",
|
|
@@ -71456,7 +71524,7 @@ function createBridgeMessageHandler(deps) {
|
|
|
71456
71524
|
thread.inFlight = true;
|
|
71457
71525
|
pendingTurnSessions.delete(directorSessionId);
|
|
71458
71526
|
thread.replay = createReplayBuffer({
|
|
71459
|
-
turnId: (0,
|
|
71527
|
+
turnId: (0, import_node_crypto16.randomUUID)(),
|
|
71460
71528
|
spanId,
|
|
71461
71529
|
...deps.retentionMs !== void 0 ? { retentionMs: deps.retentionMs } : {},
|
|
71462
71530
|
...deps.ackLingerMs !== void 0 ? { ackLingerMs: deps.ackLingerMs } : {}
|
|
@@ -71609,8 +71677,8 @@ function createBridgeMessageHandler(deps) {
|
|
|
71609
71677
|
}
|
|
71610
71678
|
let resolveTurn = null;
|
|
71611
71679
|
let rejectTurn = null;
|
|
71612
|
-
const turnFinished = new Promise((
|
|
71613
|
-
resolveTurn =
|
|
71680
|
+
const turnFinished = new Promise((resolve2, reject) => {
|
|
71681
|
+
resolveTurn = resolve2;
|
|
71614
71682
|
rejectTurn = (error51) => reject(error51);
|
|
71615
71683
|
});
|
|
71616
71684
|
let outputEvents = 0;
|
|
@@ -72239,6 +72307,7 @@ async function startDirectorBridge() {
|
|
|
72239
72307
|
acquireExecutorAgent: async (worktreePath, providerId) => {
|
|
72240
72308
|
const executor = await startExecutorServer({
|
|
72241
72309
|
worktree: worktreePath,
|
|
72310
|
+
disabledGitHooksDir: prepareDisabledGitHooksDir(import_node_path38.default.join(config2.stateDir, "locks"), import_node_path38.default.basename(worktreePath)),
|
|
72242
72311
|
provider: providerId
|
|
72243
72312
|
});
|
|
72244
72313
|
return { handle: executor.handle, dispose: executor.dispose };
|
|
@@ -72277,7 +72346,7 @@ async function startDirectorBridge() {
|
|
|
72277
72346
|
};
|
|
72278
72347
|
const sessionSinks = createSessionSinkRegistry();
|
|
72279
72348
|
const tombstones = /* @__PURE__ */ new Map();
|
|
72280
|
-
const bridgeInstanceId = (0,
|
|
72349
|
+
const bridgeInstanceId = (0, import_node_crypto16.randomUUID)();
|
|
72281
72350
|
const asyncConsumerDeps = {
|
|
72282
72351
|
client,
|
|
72283
72352
|
run: wrappedTurnLock.run,
|
|
@@ -72604,7 +72673,7 @@ async function startDirectorBridge() {
|
|
|
72604
72673
|
const bridgeLogger = createBridgeLogger(config2.stateDir, process.env);
|
|
72605
72674
|
let bridgeBinShaShort = "unknown00000";
|
|
72606
72675
|
try {
|
|
72607
|
-
bridgeBinShaShort =
|
|
72676
|
+
bridgeBinShaShort = import_node_crypto16.default.createHash("sha256").update(import_node_fs23.default.readFileSync(process.argv[1] ?? "")).digest("hex").slice(0, 12);
|
|
72608
72677
|
} catch {
|
|
72609
72678
|
}
|
|
72610
72679
|
attachBridgeWss(server, {
|
|
@@ -72695,9 +72764,9 @@ async function startDirectorBridge() {
|
|
|
72695
72764
|
res.writeHead(400).end();
|
|
72696
72765
|
});
|
|
72697
72766
|
});
|
|
72698
|
-
await new Promise((
|
|
72767
|
+
await new Promise((resolve2, reject) => {
|
|
72699
72768
|
dispatchServer.on("error", reject);
|
|
72700
|
-
dispatchServer.listen(workerPort(), "127.0.0.1", () =>
|
|
72769
|
+
dispatchServer.listen(workerPort(), "127.0.0.1", () => resolve2());
|
|
72701
72770
|
});
|
|
72702
72771
|
const bridgeHealth = new BridgeHealthTracker({
|
|
72703
72772
|
stateDir: config2.stateDir,
|
|
@@ -72888,7 +72957,7 @@ async function startDirectorBridge() {
|
|
|
72888
72957
|
)
|
|
72889
72958
|
});
|
|
72890
72959
|
}
|
|
72891
|
-
await new Promise((
|
|
72960
|
+
await new Promise((resolve2, reject) => {
|
|
72892
72961
|
server.on("error", (err) => {
|
|
72893
72962
|
if (err.code === "EADDRINUSE") {
|
|
72894
72963
|
const conflictingPids = scanForOtherBridges();
|
|
@@ -72904,7 +72973,7 @@ async function startDirectorBridge() {
|
|
|
72904
72973
|
}
|
|
72905
72974
|
reject(err);
|
|
72906
72975
|
});
|
|
72907
|
-
server.listen(config2.port, config2.host, () =>
|
|
72976
|
+
server.listen(config2.port, config2.host, () => resolve2());
|
|
72908
72977
|
});
|
|
72909
72978
|
const orphans = scanForOtherBridges();
|
|
72910
72979
|
if (orphans.length > 0) {
|
|
@@ -73045,10 +73114,10 @@ function timingSafeTokenEqual(provided, expected) {
|
|
|
73045
73114
|
const a = Buffer.from(provided);
|
|
73046
73115
|
const b = Buffer.from(expected);
|
|
73047
73116
|
if (a.length !== b.length) return false;
|
|
73048
|
-
return
|
|
73117
|
+
return import_node_crypto16.default.timingSafeEqual(a, b);
|
|
73049
73118
|
}
|
|
73050
73119
|
function readDispatchBody(req) {
|
|
73051
|
-
return new Promise((
|
|
73120
|
+
return new Promise((resolve2, reject) => {
|
|
73052
73121
|
const chunks = [];
|
|
73053
73122
|
let size = 0;
|
|
73054
73123
|
req.on("data", (chunk) => {
|
|
@@ -73060,7 +73129,7 @@ function readDispatchBody(req) {
|
|
|
73060
73129
|
}
|
|
73061
73130
|
chunks.push(chunk);
|
|
73062
73131
|
});
|
|
73063
|
-
req.on("end", () =>
|
|
73132
|
+
req.on("end", () => resolve2(Buffer.concat(chunks).toString("utf8")));
|
|
73064
73133
|
req.on("error", reject);
|
|
73065
73134
|
});
|
|
73066
73135
|
}
|
|
@@ -73074,7 +73143,7 @@ function readOrCreateBridgeToken(stateDir) {
|
|
|
73074
73143
|
} catch {
|
|
73075
73144
|
}
|
|
73076
73145
|
import_node_fs23.default.mkdirSync(stateDir, { recursive: true, mode: 448 });
|
|
73077
|
-
const token =
|
|
73146
|
+
const token = import_node_crypto16.default.randomBytes(32).toString("base64url");
|
|
73078
73147
|
import_node_fs23.default.writeFileSync(tokenPath, `${token}
|
|
73079
73148
|
`, { mode: 384 });
|
|
73080
73149
|
return token;
|
|
@@ -73772,12 +73841,12 @@ var StdioServerTransport = class {
|
|
|
73772
73841
|
this.onclose?.();
|
|
73773
73842
|
}
|
|
73774
73843
|
send(message) {
|
|
73775
|
-
return new Promise((
|
|
73844
|
+
return new Promise((resolve2) => {
|
|
73776
73845
|
const json2 = serializeMessage(message);
|
|
73777
73846
|
if (this._stdout.write(json2)) {
|
|
73778
|
-
|
|
73847
|
+
resolve2();
|
|
73779
73848
|
} else {
|
|
73780
|
-
this._stdout.once("drain",
|
|
73849
|
+
this._stdout.once("drain", resolve2);
|
|
73781
73850
|
}
|
|
73782
73851
|
});
|
|
73783
73852
|
}
|