@mrrlin-dev/mcp 0.4.41 → 0.4.42

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 +544 -265
  2. package/package.json +4 -4
package/dist/bin.cjs CHANGED
@@ -3008,7 +3008,7 @@ var require_range = __commonJS({
3008
3008
  parseRange(range) {
3009
3009
  const memoOpts = (this.options.includePrerelease && FLAG_INCLUDE_PRERELEASE) | (this.options.loose && FLAG_LOOSE);
3010
3010
  const memoKey = memoOpts + ":" + range;
3011
- const cached2 = cache.get(memoKey);
3011
+ const cached2 = cache2.get(memoKey);
3012
3012
  if (cached2) {
3013
3013
  return cached2;
3014
3014
  }
@@ -3042,7 +3042,7 @@ var require_range = __commonJS({
3042
3042
  rangeMap.delete("");
3043
3043
  }
3044
3044
  const result = [...rangeMap.values()];
3045
- cache.set(memoKey, result);
3045
+ cache2.set(memoKey, result);
3046
3046
  return result;
3047
3047
  }
3048
3048
  intersects(range, options) {
@@ -3081,7 +3081,7 @@ var require_range = __commonJS({
3081
3081
  };
3082
3082
  module2.exports = Range;
3083
3083
  var LRU = require_lrucache();
3084
- var cache = new LRU();
3084
+ var cache2 = new LRU();
3085
3085
  var parseOptions = require_parse_options();
3086
3086
  var Comparator = require_comparator();
3087
3087
  var debug = require_debug();
@@ -20644,11 +20644,11 @@ var require_dist = __commonJS({
20644
20644
  });
20645
20645
 
20646
20646
  // src/bin.ts
20647
- var import_node_path31 = __toESM(require("node:path"), 1);
20647
+ var import_node_path34 = __toESM(require("node:path"), 1);
20648
20648
  var import_node_child_process18 = require("node:child_process");
20649
- var import_node_fs19 = require("node:fs");
20650
- var import_node_os15 = require("node:os");
20651
- var import_node_path32 = __toESM(require("node:path"), 1);
20649
+ var import_node_fs22 = require("node:fs");
20650
+ var import_node_os16 = require("node:os");
20651
+ var import_node_path35 = __toESM(require("node:path"), 1);
20652
20652
 
20653
20653
  // src/install-codex.ts
20654
20654
  var import_promises = __toESM(require("node:fs/promises"), 1);
@@ -21554,12 +21554,12 @@ async function verifyProviderReadiness(provider, run3, opts = {}) {
21554
21554
  }
21555
21555
 
21556
21556
  // src/director-bridge.ts
21557
- var import_node_fs17 = __toESM(require("node:fs"), 1);
21557
+ var import_node_fs20 = __toESM(require("node:fs"), 1);
21558
21558
  var import_node_http = __toESM(require("node:http"), 1);
21559
- var import_node_os11 = __toESM(require("node:os"), 1);
21560
- var import_node_path24 = __toESM(require("node:path"), 1);
21559
+ var import_node_os12 = __toESM(require("node:os"), 1);
21560
+ var import_node_path27 = __toESM(require("node:path"), 1);
21561
21561
  var import_node_child_process15 = require("node:child_process");
21562
- var import_node_crypto10 = __toESM(require("node:crypto"), 1);
21562
+ var import_node_crypto11 = __toESM(require("node:crypto"), 1);
21563
21563
 
21564
21564
  // src/turn-replay-buffer.ts
21565
21565
  var DEFAULT_MAX_EVENTS = 2e3;
@@ -37206,7 +37206,7 @@ var mrrlinAsyncJobRequeueSchema = external_exports.object({
37206
37206
  });
37207
37207
 
37208
37208
  // ../../packages/schemas/dist/telemetry.js
37209
- var LOG_PROJECTION_KINDS = ["tool_use", "tool_result", "turn_lifecycle", "plumbing"];
37209
+ var LOG_PROJECTION_KINDS = ["tool_use", "tool_result", "turn_lifecycle", "plumbing", "gate_call"];
37210
37210
  var PLUMBING_KINDS = [
37211
37211
  "socket_close",
37212
37212
  "ready",
@@ -37272,14 +37272,60 @@ var telemetryRowSchema = external_exports.object({
37272
37272
  projectionFailures: external_exports.number(),
37273
37273
  gateMarker: external_exports.enum(GATE_MARKERS)
37274
37274
  });
37275
+ var GATE_KINDS = ["spec", "code", "deliverable"];
37276
+ var GATE_CALL_ROLES = ["head", "arbiter", "reviser", "findings"];
37277
+ var gateCallRecordSchema = external_exports.object({
37278
+ day: external_exports.string(),
37279
+ gate: external_exports.enum(GATE_KINDS),
37280
+ /**
37281
+ * The gate's own round, 1-based. Zero is legal and means "outside the loop": spec-gate.ts makes
37282
+ * one reviser call BEFORE runConsensus is ever entered, and labelling it round 1 would put a
37283
+ * pre-loop call inside a round that had not started.
37284
+ */
37285
+ round: external_exports.number(),
37286
+ role: external_exports.enum(GATE_CALL_ROLES),
37287
+ /** The persona file driving the call, or null for a role that loads none (the revisers). */
37288
+ persona: external_exports.string().nullable(),
37289
+ /** Null where the call site minted no seat and therefore genuinely does not know — a guessed
37290
+ * provider on a cost record is worse than an absent one. */
37291
+ provider: external_exports.string().nullable(),
37292
+ agentId: external_exports.string().nullable(),
37293
+ inputTokens: external_exports.number().nullable(),
37294
+ cachedInputTokens: external_exports.number().nullable(),
37295
+ cacheWriteInputTokens: external_exports.number().nullable(),
37296
+ outputTokens: external_exports.number().nullable(),
37297
+ durationMs: external_exports.number()
37298
+ });
37275
37299
  var telemetryBatchSchema = external_exports.object({
37276
37300
  day: external_exports.string(),
37277
37301
  bridgeVersion: external_exports.string(),
37302
+ /**
37303
+ * Which installation produced this batch. OPTIONAL on the wire on purpose: a bridge that has not
37304
+ * restarted after deploy still posts batches, and rejecting them would turn a rollout window into
37305
+ * data loss. The API resolves a missing value to the literal installation `legacy`, which is
37306
+ * exactly today's behaviour — one shared slot — so nothing regresses while everything that does
37307
+ * send an id gains its own.
37308
+ */
37309
+ installationId: external_exports.string().optional(),
37278
37310
  knownCrashCount: external_exports.number(),
37279
37311
  // pairs still lacking .processed-* after this run completes; a project that never uploads at
37280
37312
  // all cannot report its own gap this way — silence is not coverage.
37281
37313
  unprocessedPartitions: external_exports.array(external_exports.object({ projectSlug: external_exports.string(), day: external_exports.string() })),
37282
- rows: external_exports.array(telemetryRowSchema)
37314
+ rows: external_exports.array(telemetryRowSchema),
37315
+ /**
37316
+ * Consensus-gate provider calls for this day. Optional, exactly like `installationId` above and
37317
+ * for the same reason: a bridge that makes no gate call, and every uploader built before this
37318
+ * field existed, must keep producing a valid batch — a rollout window is not allowed to become
37319
+ * data loss.
37320
+ *
37321
+ * `.optional()` rather than `.default([])`, which was tried first. A Zod default splits the
37322
+ * schema's input type from its output type, so the parsed batch would carry a REQUIRED
37323
+ * `gateCalls` while producers do not — and every construction site (the uploader, the store
37324
+ * tests, the ingest tests) would then have to name a field it has no opinion about. An absent
37325
+ * array and an empty one mean the same thing to every reader here, so the split buys nothing and
37326
+ * costs a trap.
37327
+ */
37328
+ gateCalls: external_exports.array(gateCallRecordSchema).optional()
37283
37329
  });
37284
37330
  var evidenceStepSchema = external_exports.object({
37285
37331
  toolName: external_exports.string(),
@@ -40044,6 +40090,68 @@ function resolveProvider(env, persisted) {
40044
40090
 
40045
40091
  // ../../packages/agent-client/dist/providers/codex/exec.js
40046
40092
  var import_node_child_process5 = require("node:child_process");
40093
+
40094
+ // ../../packages/agent-client/dist/exec-usage.js
40095
+ function readCount2(source, ...keys) {
40096
+ for (const key of keys) {
40097
+ const value = source[key];
40098
+ if (typeof value === "number" && Number.isFinite(value))
40099
+ return value;
40100
+ }
40101
+ return null;
40102
+ }
40103
+ function fromBlock(block) {
40104
+ const usage = {
40105
+ inputTokens: readCount2(block, "input_tokens", "inputTokens"),
40106
+ cachedInputTokens: readCount2(block, "cached_input_tokens", "cache_read_input_tokens", "cachedInputTokens"),
40107
+ cacheWriteInputTokens: readCount2(block, "cache_write_input_tokens", "cache_creation_input_tokens", "cacheWriteInputTokens"),
40108
+ outputTokens: readCount2(block, "output_tokens", "outputTokens")
40109
+ };
40110
+ const measuredNothing = usage.inputTokens === null && usage.cachedInputTokens === null && usage.cacheWriteInputTokens === null && usage.outputTokens === null;
40111
+ return measuredNothing ? null : usage;
40112
+ }
40113
+ function extractCodexExecUsage(stdout) {
40114
+ let last = null;
40115
+ for (const rawLine of stdout.split(/\r?\n/)) {
40116
+ const line = rawLine.trim();
40117
+ if (!line || line[0] !== "{")
40118
+ continue;
40119
+ let event;
40120
+ try {
40121
+ event = JSON.parse(line);
40122
+ } catch {
40123
+ continue;
40124
+ }
40125
+ if (typeof event !== "object" || event === null)
40126
+ continue;
40127
+ const usage = event.usage;
40128
+ if (typeof usage !== "object" || usage === null)
40129
+ continue;
40130
+ const parsed = fromBlock(usage);
40131
+ if (parsed !== null)
40132
+ last = parsed;
40133
+ }
40134
+ return last;
40135
+ }
40136
+ function extractClaudeExecUsage(parsed) {
40137
+ if (!Array.isArray(parsed))
40138
+ return null;
40139
+ for (let i = parsed.length - 1; i >= 0; i -= 1) {
40140
+ const element = parsed[i];
40141
+ if (typeof element !== "object" || element === null)
40142
+ continue;
40143
+ const record2 = element;
40144
+ if (record2.type !== "result")
40145
+ continue;
40146
+ const usage = record2.usage;
40147
+ if (typeof usage !== "object" || usage === null)
40148
+ return null;
40149
+ return fromBlock(usage);
40150
+ }
40151
+ return null;
40152
+ }
40153
+
40154
+ // ../../packages/agent-client/dist/providers/codex/exec.js
40047
40155
  function extractFinalMessage(stdout) {
40048
40156
  let last = null;
40049
40157
  for (const rawLine of stdout.split(/\r?\n/)) {
@@ -40164,7 +40272,7 @@ ${input.prompt}` : input.prompt;
40164
40272
  finish({ ok: false, error: "codex exec produced no parseable assistant message" });
40165
40273
  return;
40166
40274
  }
40167
- finish({ ok: true, text });
40275
+ finish({ ok: true, text, usage: extractCodexExecUsage(stdout) });
40168
40276
  });
40169
40277
  });
40170
40278
  }
@@ -40269,7 +40377,7 @@ function extractOneShotResult(stdout) {
40269
40377
  if (typeof resultEvent.result !== "string") {
40270
40378
  return { ok: false, error: "claude exec's 'result' event had no string result field" };
40271
40379
  }
40272
- return { ok: true, text: resultEvent.result };
40380
+ return { ok: true, text: resultEvent.result, usage: extractClaudeExecUsage(parsed) };
40273
40381
  }
40274
40382
  function errMessage2(err) {
40275
40383
  return err instanceof Error ? err.message : String(err);
@@ -42080,7 +42188,7 @@ Do NOT derail the current task - if the operator has an in-flight question, answ
42080
42188
  }
42081
42189
 
42082
42190
  // src/_generated/version.ts
42083
- var PKG_VERSION = "0.4.41";
42191
+ var PKG_VERSION = "0.4.42";
42084
42192
 
42085
42193
  // src/api-base-url-migrate.ts
42086
42194
  var import_node_fs3 = __toESM(require("node:fs"), 1);
@@ -42983,14 +43091,37 @@ async function foldClosedDays(stateDir, today) {
42983
43091
 
42984
43092
  // src/telemetry/daily-uploader.ts
42985
43093
  var import_promises6 = require("node:fs/promises");
42986
- var import_node_path12 = require("node:path");
43094
+ var import_node_path15 = require("node:path");
42987
43095
 
42988
43096
  // src/consensus/wiring.ts
42989
43097
  var import_node_crypto4 = __toESM(require("node:crypto"), 1);
42990
- var import_node_fs5 = __toESM(require("node:fs"), 1);
42991
- var import_node_path11 = __toESM(require("node:path"), 1);
43098
+ var import_node_fs7 = __toESM(require("node:fs"), 1);
43099
+ var import_node_path13 = __toESM(require("node:path"), 1);
42992
43100
  var import_node_url2 = require("node:url");
42993
43101
 
43102
+ // src/consensus/gate-usage-log.ts
43103
+ var import_node_fs5 = require("node:fs");
43104
+ var import_node_path11 = require("node:path");
43105
+ function recordGateCall(stateDir, projectSlug, record2) {
43106
+ try {
43107
+ const dir = (0, import_node_path11.join)(stateDir, "telemetry");
43108
+ (0, import_node_fs5.mkdirSync)(dir, { recursive: true });
43109
+ (0, import_node_fs5.appendFileSync)((0, import_node_path11.join)(dir, gateFileName(projectSlug, record2.day)), `${JSON.stringify(record2)}
43110
+ `, "utf8");
43111
+ } catch {
43112
+ }
43113
+ }
43114
+ var SAFE_SLUG = /^[A-Za-z0-9][A-Za-z0-9_-]*$/;
43115
+ function gateFileName(projectSlug, day) {
43116
+ if (!SAFE_SLUG.test(projectSlug)) {
43117
+ throw new Error(`refusing to build a telemetry partition name from an unsafe project slug: ${JSON.stringify(projectSlug)}`);
43118
+ }
43119
+ return `gate-${projectSlug}-${day}.jsonl`;
43120
+ }
43121
+ function telemetryDay(now = /* @__PURE__ */ new Date()) {
43122
+ return now.toISOString().slice(0, 10);
43123
+ }
43124
+
42994
43125
  // src/consensus/verdict.ts
42995
43126
  var CATEGORIES = [
42996
43127
  "correctness",
@@ -43840,6 +43971,16 @@ ${issuesBlock}`,
43840
43971
  }
43841
43972
  }
43842
43973
 
43974
+ // src/consensus/sterile-cwd.ts
43975
+ var import_node_fs6 = require("node:fs");
43976
+ var import_node_os6 = require("node:os");
43977
+ var import_node_path12 = require("node:path");
43978
+ var sterileDir = null;
43979
+ function sterileCwd() {
43980
+ sterileDir ??= (0, import_node_fs6.mkdtempSync)((0, import_node_path12.join)((0, import_node_os6.tmpdir)(), "mrrlin-gate-"));
43981
+ return sterileDir;
43982
+ }
43983
+
43843
43984
  // src/consensus/code-gate-git.ts
43844
43985
  var import_node_child_process8 = require("node:child_process");
43845
43986
  var DIFF_MAX_BYTES = 2e5;
@@ -44072,15 +44213,15 @@ ${res.stdout}${res.stderr}`);
44072
44213
  var import_meta2 = {};
44073
44214
  function getPersonasDir() {
44074
44215
  if (typeof __dirname !== "undefined") {
44075
- return import_node_path11.default.join(__dirname, "consensus", "personas");
44216
+ return import_node_path13.default.join(__dirname, "consensus", "personas");
44076
44217
  }
44077
- return import_node_path11.default.join(import_node_path11.default.dirname((0, import_node_url2.fileURLToPath)(import_meta2.url)), "personas");
44218
+ return import_node_path13.default.join(import_node_path13.default.dirname((0, import_node_url2.fileURLToPath)(import_meta2.url)), "personas");
44078
44219
  }
44079
44220
  var personaCache = /* @__PURE__ */ new Map();
44080
44221
  function loadPersona(name) {
44081
44222
  const cached2 = personaCache.get(name);
44082
44223
  if (cached2 !== void 0) return cached2;
44083
- const content = import_node_fs5.default.readFileSync(import_node_path11.default.join(getPersonasDir(), `${name}.md`), "utf8");
44224
+ const content = import_node_fs7.default.readFileSync(import_node_path13.default.join(getPersonasDir(), `${name}.md`), "utf8");
44084
44225
  personaCache.set(name, content);
44085
44226
  return content;
44086
44227
  }
@@ -44118,8 +44259,36 @@ function reviserIdentityInstructions(taskId, title) {
44118
44259
  ` : "";
44119
44260
  return `${lock}You revise a spec to address accepted issues. Return ONLY the full revised markdown, no commentary.`;
44120
44261
  }
44262
+ function gateCallRecorder(args) {
44263
+ let round = 0;
44264
+ let headSinceArbiter = false;
44265
+ return function record2(role, persona, agentId, startedAt, result) {
44266
+ if (role === "head" && !headSinceArbiter) {
44267
+ round += 1;
44268
+ headSinceArbiter = true;
44269
+ }
44270
+ if (role === "arbiter") headSinceArbiter = false;
44271
+ if (args.stateDir === void 0) return;
44272
+ const usage = "usage" in result ? result.usage : null;
44273
+ recordGateCall(args.stateDir, args.projectSlug, {
44274
+ day: telemetryDay(),
44275
+ gate: args.gate,
44276
+ round,
44277
+ role,
44278
+ persona,
44279
+ agentId,
44280
+ provider: args.provider,
44281
+ inputTokens: usage?.inputTokens ?? null,
44282
+ cachedInputTokens: usage?.cachedInputTokens ?? null,
44283
+ cacheWriteInputTokens: usage?.cacheWriteInputTokens ?? null,
44284
+ outputTokens: usage?.outputTokens ?? null,
44285
+ durationMs: Date.now() - startedAt
44286
+ });
44287
+ };
44288
+ }
44121
44289
  function buildSpecGateDeps(args) {
44122
- const { client, projectSlug, specPageId, cwd, codexExecutable, extraHeadCount = 0, seat } = args;
44290
+ const { client, projectSlug, specPageId, codexExecutable, extraHeadCount = 0, seat, stateDir } = args;
44291
+ const recordCost = gateCallRecorder({ stateDir, projectSlug, gate: "spec", provider: seat?.id ?? null });
44123
44292
  const rounds = Number(process.env["MRRLIN_CONSENSUS_ROUNDS"] ?? 5);
44124
44293
  const maxHeadCalls = 2 * rounds * (MAX_DOMAIN_HEADS + extraHeadCount + 2);
44125
44294
  const timeoutMs = Number(process.env["MRRLIN_CONSENSUS_HEAD_TIMEOUT_MS"] ?? 15e4);
@@ -44194,7 +44363,8 @@ function buildSpecGateDeps(args) {
44194
44363
  const persona = loadPersona(personaName);
44195
44364
  const { taskId, title, seed, impact, adjudicated } = await loadIntent();
44196
44365
  const intentBlock = specHeadIntentBlock(taskId, title, seed, impact, adjudicated);
44197
- return runAgentExec(
44366
+ const startedAt = Date.now();
44367
+ const result = await runAgentExec(
44198
44368
  {
44199
44369
  prompt: `Review this spec against the operator's intent.
44200
44370
 
@@ -44203,19 +44373,26 @@ ${dismissed}
44203
44373
  ${intentBlock}--- SPEC ---
44204
44374
  ${artifact}`,
44205
44375
  developerInstructions: persona,
44206
- cwd,
44376
+ // Every provider call in this factory runs from the empty per-process directory rather
44377
+ // than the caller's repository — see sterile-cwd.ts for the measurement and the accepted
44378
+ // risk. Nothing in a spec review reads the repository: the artifact and the operator
44379
+ // intent are both in the prompt above.
44380
+ cwd: sterileCwd(),
44207
44381
  timeoutMs,
44208
44382
  sandbox: "read-only",
44209
44383
  codexExecutable
44210
44384
  }
44211
44385
  );
44386
+ recordCost("head", personaName, null, startedAt, result);
44387
+ return result;
44212
44388
  },
44213
44389
  async runArbiter(prompt) {
44214
- return runAgentExec(
44390
+ const startedAt = Date.now();
44391
+ const result = await runAgentExec(
44215
44392
  {
44216
44393
  prompt,
44217
44394
  developerInstructions: loadPersona("arbiter"),
44218
- cwd,
44395
+ cwd: sterileCwd(),
44219
44396
  timeoutMs,
44220
44397
  sandbox: "read-only",
44221
44398
  codexExecutable,
@@ -44224,11 +44401,14 @@ ${artifact}`,
44224
44401
  model: seat?.models.strong
44225
44402
  }
44226
44403
  );
44404
+ recordCost("arbiter", "arbiter", seat?.models.strong ?? null, startedAt, result);
44405
+ return result;
44227
44406
  },
44228
44407
  async runReviser(artifact, accepted) {
44229
44408
  const acceptedList = accepted.map((a) => `- (${a.category}) ${a.text}`).join("\n");
44230
44409
  const { taskId, title } = await loadIntent();
44231
- return runAgentExec(
44410
+ const startedAt = Date.now();
44411
+ const result = await runAgentExec(
44232
44412
  {
44233
44413
  prompt: `Accepted issues:
44234
44414
  ${acceptedList}
@@ -44236,12 +44416,16 @@ ${acceptedList}
44236
44416
  --- SPEC ---
44237
44417
  ${artifact}`,
44238
44418
  developerInstructions: reviserIdentityInstructions(taskId, title),
44239
- cwd,
44419
+ // Sterile like the rest of this factory: the spec reviser rewrites the markdown it is
44420
+ // handed and returns it, so unlike the CODE gate's reviser it never touches a worktree.
44421
+ cwd: sterileCwd(),
44240
44422
  timeoutMs,
44241
44423
  sandbox: "read-only",
44242
44424
  codexExecutable
44243
44425
  }
44244
44426
  );
44427
+ recordCost("reviser", null, null, startedAt, result);
44428
+ return result;
44245
44429
  },
44246
44430
  async casUpdateSpec(markdownBody, expectedHash) {
44247
44431
  try {
@@ -44288,9 +44472,17 @@ ${artifact}`,
44288
44472
  const rounds2 = r["rounds"];
44289
44473
  const history = r["history"];
44290
44474
  const highlights = await curateFindings(Array.isArray(history) ? history : [], {
44291
- runCodexExec: runAgentExec,
44475
+ // Wrapped, not passed raw: this is the one gate provider call that does NOT go through a
44476
+ // `deps.run*` function, so without this the post-gate findings pass would be the single
44477
+ // call the cost record silently omits.
44478
+ runCodexExec: async (input) => {
44479
+ const startedAt = Date.now();
44480
+ const result = await runAgentExec(input);
44481
+ recordCost("findings", "findings-writer", null, startedAt, result);
44482
+ return result;
44483
+ },
44292
44484
  loadPersona,
44293
- cwd,
44485
+ cwd: sterileCwd(),
44294
44486
  timeoutMs,
44295
44487
  codexExecutable
44296
44488
  });
@@ -44313,7 +44505,8 @@ ${artifact}`,
44313
44505
  };
44314
44506
  }
44315
44507
  function buildCodeGateDeps(args) {
44316
- const { client, projectSlug, baseRef, cwd, codexExecutable, extraHeads, seat } = args;
44508
+ const { client, projectSlug, baseRef, cwd, codexExecutable, extraHeads, seat, stateDir } = args;
44509
+ const recordCost = gateCallRecorder({ stateDir, projectSlug, gate: "code", provider: seat?.id ?? null });
44317
44510
  const rounds = Number(process.env["MRRLIN_CONSENSUS_ROUNDS"] ?? 5);
44318
44511
  const heads = ["code-reviewer", ...extraHeads ?? []];
44319
44512
  const maxHeadCalls = 2 * rounds * (heads.length + 2);
@@ -44336,7 +44529,8 @@ function buildCodeGateDeps(args) {
44336
44529
  },
44337
44530
  async runHead(personaName, artifact, dismissed) {
44338
44531
  const persona = loadPersona(personaName);
44339
- return runAgentExec({
44532
+ const startedAt = Date.now();
44533
+ const result = await runAgentExec({
44340
44534
  prompt: `Review this code diff.
44341
44535
 
44342
44536
  ${dismissed}
@@ -44344,17 +44538,23 @@ ${dismissed}
44344
44538
  --- DIFF ---
44345
44539
  ${artifact}`,
44346
44540
  developerInstructions: persona,
44347
- cwd,
44541
+ // Read-only review of a diff that is entirely in the prompt — sterile, per sterile-cwd.ts.
44542
+ // This factory is the ONE that stays mixed: runReviser below keeps the real `cwd` because
44543
+ // it edits the branch, and the git helpers keep it because they are not provider calls.
44544
+ cwd: sterileCwd(),
44348
44545
  timeoutMs: headTimeoutMs,
44349
44546
  sandbox: "read-only",
44350
44547
  codexExecutable
44351
44548
  });
44549
+ recordCost("head", personaName, null, startedAt, result);
44550
+ return result;
44352
44551
  },
44353
44552
  async runArbiter(prompt) {
44354
- return runAgentExec({
44553
+ const startedAt = Date.now();
44554
+ const result = await runAgentExec({
44355
44555
  prompt,
44356
44556
  developerInstructions: loadPersona("arbiter"),
44357
- cwd,
44557
+ cwd: sterileCwd(),
44358
44558
  timeoutMs: headTimeoutMs,
44359
44559
  sandbox: "read-only",
44360
44560
  codexExecutable,
@@ -44362,21 +44562,30 @@ ${artifact}`,
44362
44562
  // strongest model.
44363
44563
  model: seat?.models.strong
44364
44564
  });
44565
+ recordCost("arbiter", "arbiter", seat?.models.strong ?? null, startedAt, result);
44566
+ return result;
44365
44567
  },
44366
44568
  async runReviser(artifact, accepted) {
44367
44569
  const acceptedList = accepted.map((a) => `- (${a.category}) ${a.text}`).join("\n");
44368
- return runAgentExec({
44570
+ const startedAt = Date.now();
44571
+ const result = await runAgentExec({
44369
44572
  prompt: `Accepted issues to fix:
44370
44573
  ${acceptedList}
44371
44574
 
44372
44575
  --- DIFF ---
44373
44576
  ${artifact}`,
44374
44577
  developerInstructions: "You are fixing code review issues. Edit ONLY files already changed in this branch's diff; make the minimal change to resolve each accepted issue. Do not refactor unrelated code. Do not edit files outside the diff.",
44578
+ // The real repository root, NOT sterileCwd(): this is the one gate call that runs
44579
+ // `workspace-write` and edits the branch, so a sterile cwd would point the sandbox at an
44580
+ // empty directory and the revision would silently apply to nothing — the gate would keep
44581
+ // reporting rounds while fixing no code at all.
44375
44582
  cwd,
44376
44583
  timeoutMs: reviserTimeoutMs,
44377
44584
  sandbox: "workspace-write",
44378
44585
  codexExecutable
44379
44586
  });
44587
+ recordCost("reviser", null, null, startedAt, result);
44588
+ return result;
44380
44589
  },
44381
44590
  checkpoint() {
44382
44591
  return checkpoint(gitArgs);
@@ -44397,7 +44606,8 @@ function renderCriteriaBlock(criteria) {
44397
44606
  return criteria.map((c, i) => `${i + 1}. [ ] ${c}`).join("\n");
44398
44607
  }
44399
44608
  async function buildDeliverableGateDeps(args) {
44400
- const { client, projectSlug, deliverablePageId, attemptOutcome, cwd, codexExecutable, runId, seat } = args;
44609
+ const { client, projectSlug, deliverablePageId, attemptOutcome, codexExecutable, runId, seat, stateDir } = args;
44610
+ const recordCost = gateCallRecorder({ stateDir, projectSlug, gate: "deliverable", provider: seat?.id ?? null });
44401
44611
  const rounds = Number(process.env["MRRLIN_CONSENSUS_ROUNDS"] ?? 5);
44402
44612
  const timeoutMs = Number(process.env["MRRLIN_CONSENSUS_HEAD_TIMEOUT_MS"] ?? 15e4);
44403
44613
  const page = await client.getWikiPage(projectSlug, deliverablePageId);
@@ -44443,7 +44653,8 @@ async function buildDeliverableGateDeps(args) {
44443
44653
  },
44444
44654
  async runHead(personaName, artifact, dismissed) {
44445
44655
  const persona = loadPersona(personaName);
44446
- return runAgentExec({
44656
+ const startedAt = Date.now();
44657
+ const result = await runAgentExec({
44447
44658
  prompt: `Score this deliverable ITEM BY ITEM against the acceptance criteria below. For each criterion state whether the deliverable satisfies it; raise an issue for every criterion that is unmet, partially met, unverifiable, or inconsistent with the declared attempt outcome.
44448
44659
 
44449
44660
  ${dismissed}
@@ -44458,17 +44669,23 @@ ${artifact}`,
44458
44669
  developerInstructions: `${DELIVERABLE_ANTIINJECTION_INSTRUCTION}
44459
44670
 
44460
44671
  ${persona}`,
44461
- cwd,
44672
+ // Sterile, like every other provider call in this factory — see sterile-cwd.ts. It also
44673
+ // narrows the anti-injection surface: a deliverable that tries to talk the head into
44674
+ // reading files now has no repository under it to read.
44675
+ cwd: sterileCwd(),
44462
44676
  timeoutMs,
44463
44677
  sandbox: "read-only",
44464
44678
  codexExecutable
44465
44679
  });
44680
+ recordCost("head", personaName, null, startedAt, result);
44681
+ return result;
44466
44682
  },
44467
44683
  async runArbiter(prompt) {
44468
- return runAgentExec({
44684
+ const startedAt = Date.now();
44685
+ const result = await runAgentExec({
44469
44686
  prompt,
44470
44687
  developerInstructions: loadPersona("arbiter"),
44471
- cwd,
44688
+ cwd: sterileCwd(),
44472
44689
  timeoutMs,
44473
44690
  sandbox: "read-only",
44474
44691
  codexExecutable,
@@ -44476,10 +44693,13 @@ ${persona}`,
44476
44693
  // strongest model.
44477
44694
  model: seat?.models.strong
44478
44695
  });
44696
+ recordCost("arbiter", "arbiter", seat?.models.strong ?? null, startedAt, result);
44697
+ return result;
44479
44698
  },
44480
44699
  async runReviser(artifact, accepted) {
44481
44700
  const acceptedList = accepted.map((a) => `- (${a.category}) ${a.text}`).join("\n");
44482
- return runAgentExec({
44701
+ const startedAt = Date.now();
44702
+ const result = await runAgentExec({
44483
44703
  prompt: `Accepted issues to fix (each maps to an unmet acceptance criterion):
44484
44704
  ${acceptedList}
44485
44705
 
@@ -44491,11 +44711,13 @@ ${artifact}`,
44491
44711
  developerInstructions: `${DELIVERABLE_ANTIINJECTION_INSTRUCTION}
44492
44712
 
44493
44713
  You revise a deliverable to address the accepted issues so it satisfies the acceptance criteria and stays consistent with the declared outcome${attemptOutcome ? ` (${attemptOutcome})` : ""}. Return ONLY the full revised markdown, no commentary. Do not invent facts; keep the deliverable's format and do not change the declared outcome.`,
44494
- cwd,
44714
+ cwd: sterileCwd(),
44495
44715
  timeoutMs,
44496
44716
  sandbox: "read-only",
44497
44717
  codexExecutable
44498
44718
  });
44719
+ recordCost("reviser", null, null, startedAt, result);
44720
+ return result;
44499
44721
  },
44500
44722
  async casUpdateDeliverable(markdownBody, expectedHash) {
44501
44723
  try {
@@ -44526,7 +44748,7 @@ You revise a deliverable to address the accepted issues so it satisfies the acce
44526
44748
  const highlights = await curateFindings(Array.isArray(history) ? history : [], {
44527
44749
  runCodexExec: runAgentExec,
44528
44750
  loadPersona,
44529
- cwd,
44751
+ cwd: sterileCwd(),
44530
44752
  timeoutMs,
44531
44753
  codexExecutable
44532
44754
  });
@@ -44649,10 +44871,35 @@ async function gate(artifact, prose, ctx) {
44649
44871
  return { ok: true, gated: false, artifact: maskedClone };
44650
44872
  }
44651
44873
 
44874
+ // src/telemetry/installation-id.ts
44875
+ var import_node_crypto5 = require("node:crypto");
44876
+ var import_node_fs8 = require("node:fs");
44877
+ var import_node_path14 = require("node:path");
44878
+ var FILE_NAME = "installation-id";
44879
+ var UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;
44880
+ var cache = /* @__PURE__ */ new Map();
44881
+ function resolveInstallationId(stateDir) {
44882
+ const cached2 = cache.get(stateDir);
44883
+ if (cached2 !== void 0) return cached2;
44884
+ const path22 = (0, import_node_path14.join)(stateDir, FILE_NAME);
44885
+ let id;
44886
+ try {
44887
+ id = (0, import_node_fs8.readFileSync)(path22, "utf8").trim();
44888
+ if (!UUID.test(id)) throw new Error("unusable");
44889
+ } catch {
44890
+ id = (0, import_node_crypto5.randomUUID)();
44891
+ (0, import_node_fs8.mkdirSync)((0, import_node_path14.dirname)(path22), { recursive: true });
44892
+ (0, import_node_fs8.writeFileSync)(path22, `${id}
44893
+ `, "utf8");
44894
+ }
44895
+ cache.set(stateDir, id);
44896
+ return id;
44897
+ }
44898
+
44652
44899
  // src/telemetry/daily-uploader.ts
44653
44900
  var ROWS_FILE_RE = /^rows-(.+)-(\d{4}-\d{2}-\d{2})\.jsonl$/;
44654
44901
  async function uploadPendingDays(stateDir, client, bridgeHealth, gateCtx) {
44655
- const telemetryDir = (0, import_node_path12.join)(stateDir, "telemetry");
44902
+ const telemetryDir = (0, import_node_path15.join)(stateDir, "telemetry");
44656
44903
  let files;
44657
44904
  try {
44658
44905
  files = await (0, import_promises6.readdir)(telemetryDir);
@@ -44665,11 +44912,11 @@ async function uploadPendingDays(stateDir, client, bridgeHealth, gateCtx) {
44665
44912
  const match = ROWS_FILE_RE.exec(file2);
44666
44913
  if (!match) continue;
44667
44914
  const [, projectSlug, day] = match;
44668
- const markerPath = (0, import_node_path12.join)(telemetryDir, `.processed-${projectSlug}-${day}`);
44915
+ const markerPath = (0, import_node_path15.join)(telemetryDir, `.processed-${projectSlug}-${day}`);
44669
44916
  try {
44670
44917
  await (0, import_promises6.access)(markerPath);
44671
44918
  } catch {
44672
- pending.push({ projectSlug, day, rowsPath: (0, import_node_path12.join)(telemetryDir, file2), markerPath });
44919
+ pending.push({ projectSlug, day, rowsPath: (0, import_node_path15.join)(telemetryDir, file2), markerPath });
44673
44920
  }
44674
44921
  }
44675
44922
  if (pending.length === 0) return;
@@ -44677,7 +44924,7 @@ async function uploadPendingDays(stateDir, client, bridgeHealth, gateCtx) {
44677
44924
  const fullUnprocessed = pending.map((p) => ({ projectSlug: p.projectSlug, day: p.day }));
44678
44925
  pending.sort((a, b) => a.day.localeCompare(b.day));
44679
44926
  for (const cur of pending) {
44680
- const failurePath = (0, import_node_path12.join)(telemetryDir, `.failed-${cur.projectSlug}-${cur.day}.json`);
44927
+ const failurePath = (0, import_node_path15.join)(telemetryDir, `.failed-${cur.projectSlug}-${cur.day}.json`);
44681
44928
  let failureState = null;
44682
44929
  try {
44683
44930
  const data = await (0, import_promises6.readFile)(failurePath, "utf8");
@@ -44706,14 +44953,31 @@ async function uploadPendingDays(stateDir, client, bridgeHealth, gateCtx) {
44706
44953
  } catch {
44707
44954
  }
44708
44955
  }
44956
+ const gateCalls = [];
44957
+ try {
44958
+ const rawGate = await (0, import_promises6.readFile)((0, import_node_path15.join)(telemetryDir, gateFileName(cur.projectSlug, cur.day)), "utf8");
44959
+ for (const line of rawGate.split("\n")) {
44960
+ if (!line.trim()) continue;
44961
+ try {
44962
+ gateCalls.push(JSON.parse(line));
44963
+ } catch {
44964
+ }
44965
+ }
44966
+ } catch {
44967
+ }
44709
44968
  const batch = {
44710
44969
  day: cur.day,
44711
44970
  bridgeVersion: PKG_VERSION,
44971
+ installationId: resolveInstallationId(stateDir),
44712
44972
  knownCrashCount,
44713
44973
  unprocessedPartitions: fullUnprocessed.filter(
44714
44974
  (p) => !(p.projectSlug === cur.projectSlug && p.day === cur.day)
44715
44975
  ),
44716
- rows
44976
+ rows,
44977
+ // Omitted entirely when empty: an absent array and an empty one mean the same thing to
44978
+ // every reader, and not sending the key keeps a gate-free day's batch byte-identical to
44979
+ // what every uploader before this change produced.
44980
+ ...gateCalls.length > 0 ? { gateCalls } : {}
44717
44981
  };
44718
44982
  const gateResult = await gate(batch, [], gateCtx);
44719
44983
  const gateMarker = gateResult.gated ? "gated" : "projection-only";
@@ -45107,8 +45371,8 @@ function setSelectedProvider(value) {
45107
45371
 
45108
45372
  // src/execution-consumer.ts
45109
45373
  var import_node_child_process12 = require("node:child_process");
45110
- var import_node_crypto6 = __toESM(require("node:crypto"), 1);
45111
- var import_node_path15 = __toESM(require("node:path"), 1);
45374
+ var import_node_crypto7 = __toESM(require("node:crypto"), 1);
45375
+ var import_node_path18 = __toESM(require("node:path"), 1);
45112
45376
  var import_node_util = require("node:util");
45113
45377
 
45114
45378
  // src/consensus/deliverable-gate-outcome.ts
@@ -45178,7 +45442,7 @@ function mapDeliverableGateResult(result) {
45178
45442
  }
45179
45443
 
45180
45444
  // src/async-tools/draft-spec.ts
45181
- var import_node_crypto5 = require("node:crypto");
45445
+ var import_node_crypto6 = require("node:crypto");
45182
45446
  var DRAFT_SPEC_TOOL_NAME = "draft_task_spec";
45183
45447
  var SPECS_FOLDER = "Specs";
45184
45448
  var DRAFT_SPEC_TLDR_MAX_CHARS = 300;
@@ -45673,7 +45937,7 @@ function onComplete(outcome, input) {
45673
45937
  };
45674
45938
  }
45675
45939
  const summary = outcome.error;
45676
- const hash3 = (0, import_node_crypto5.createHash)("sha256").update(summary).digest("hex").slice(0, 10);
45940
+ const hash3 = (0, import_node_crypto6.createHash)("sha256").update(summary).digest("hex").slice(0, 10);
45677
45941
  return {
45678
45942
  kind: "info",
45679
45943
  id: `II-sched-draft-failed-${input.taskId}-${hash3}`,
@@ -46404,18 +46668,18 @@ async function awaitTurnWithDeadline(opts) {
46404
46668
 
46405
46669
  // src/worktree.ts
46406
46670
  var import_node_child_process11 = require("node:child_process");
46407
- var import_node_fs7 = require("node:fs");
46408
- var import_node_os6 = require("node:os");
46409
- var import_node_path14 = require("node:path");
46671
+ var import_node_fs10 = require("node:fs");
46672
+ var import_node_os7 = require("node:os");
46673
+ var import_node_path17 = require("node:path");
46410
46674
 
46411
46675
  // src/checkout-lock.ts
46412
- var import_node_fs6 = require("node:fs");
46413
- var import_node_path13 = require("node:path");
46676
+ var import_node_fs9 = require("node:fs");
46677
+ var import_node_path16 = require("node:path");
46414
46678
  var import_proper_lockfile = __toESM(require_proper_lockfile(), 1);
46415
46679
  async function withCheckoutLock(locksDir, slug, fn) {
46416
- (0, import_node_fs6.mkdirSync)(locksDir, { recursive: true });
46417
- const target = (0, import_node_path13.join)(locksDir, `${slug}.lock`);
46418
- if (!(0, import_node_fs6.existsSync)(target)) (0, import_node_fs6.writeFileSync)(target, "");
46680
+ (0, import_node_fs9.mkdirSync)(locksDir, { recursive: true });
46681
+ const target = (0, import_node_path16.join)(locksDir, `${slug}.lock`);
46682
+ if (!(0, import_node_fs9.existsSync)(target)) (0, import_node_fs9.writeFileSync)(target, "");
46419
46683
  const release = await import_proper_lockfile.default.lock(target, {
46420
46684
  retries: { retries: 600, factor: 1, minTimeout: 100, maxTimeout: 100 },
46421
46685
  stale: 5 * 6e4
@@ -46440,12 +46704,12 @@ function git(checkout, args) {
46440
46704
  });
46441
46705
  }
46442
46706
  async function createRunWorktree(opts) {
46443
- const worktreePath = (0, import_node_path14.join)(opts.worktreeRoot, opts.slug, opts.runId);
46707
+ const worktreePath = (0, import_node_path17.join)(opts.worktreeRoot, opts.slug, opts.runId);
46444
46708
  await withCheckoutLock(opts.locksDir, opts.slug, async () => {
46445
- (0, import_node_fs7.mkdirSync)(opts.worktreeRoot, { recursive: true });
46709
+ (0, import_node_fs10.mkdirSync)(opts.worktreeRoot, { recursive: true });
46446
46710
  try {
46447
46711
  git(opts.checkout, ["fetch", "origin", opts.defaultBranch]);
46448
- if (!(0, import_node_fs7.existsSync)(worktreePath)) {
46712
+ if (!(0, import_node_fs10.existsSync)(worktreePath)) {
46449
46713
  git(opts.checkout, [
46450
46714
  "worktree",
46451
46715
  "add",
@@ -46517,15 +46781,15 @@ async function doPushRunBranch(opts, execGit) {
46517
46781
  if (localConfig.trim()) {
46518
46782
  throw new Error(`push aborted: agent-controlled git config present in worktree: ${localConfig.trim().split("\n")[0]}`);
46519
46783
  }
46520
- const dir = (0, import_node_fs7.mkdtempSync)((0, import_node_path14.join)((0, import_node_os6.tmpdir)(), "mrrlin-push-"));
46521
- const askpass = (0, import_node_path14.join)(dir, "askpass");
46784
+ const dir = (0, import_node_fs10.mkdtempSync)((0, import_node_path17.join)((0, import_node_os7.tmpdir)(), "mrrlin-push-"));
46785
+ const askpass = (0, import_node_path17.join)(dir, "askpass");
46522
46786
  try {
46523
- (0, import_node_fs7.writeFileSync)(
46787
+ (0, import_node_fs10.writeFileSync)(
46524
46788
  askpass,
46525
46789
  '#!/bin/sh\ncase "$1" in *[Uu]sername*) printf %s "x-access-token" ;; *) printf %s "$MRRLIN_PUSH_TOKEN" ;; esac\n',
46526
46790
  { mode: 320 }
46527
46791
  );
46528
- (0, import_node_fs7.chmodSync)(askpass, 320);
46792
+ (0, import_node_fs10.chmodSync)(askpass, 320);
46529
46793
  execGit(
46530
46794
  [
46531
46795
  "-C",
@@ -46544,18 +46808,18 @@ async function doPushRunBranch(opts, execGit) {
46544
46808
  );
46545
46809
  return { pushedSha: localSha };
46546
46810
  } finally {
46547
- (0, import_node_fs7.rmSync)(dir, { recursive: true, force: true });
46811
+ (0, import_node_fs10.rmSync)(dir, { recursive: true, force: true });
46548
46812
  }
46549
46813
  }
46550
46814
  async function sweepOrphanWorktrees(opts) {
46551
46815
  const reaped = [];
46552
46816
  const ownedPrefix = (() => {
46553
46817
  try {
46554
- return (0, import_node_fs7.realpathSync)(opts.worktreeRoot);
46818
+ return (0, import_node_fs10.realpathSync)(opts.worktreeRoot);
46555
46819
  } catch {
46556
46820
  return opts.worktreeRoot;
46557
46821
  }
46558
- })() + import_node_path14.sep + opts.slug + import_node_path14.sep;
46822
+ })() + import_node_path17.sep + opts.slug + import_node_path17.sep;
46559
46823
  await withCheckoutLock(opts.locksDir, opts.slug, async () => {
46560
46824
  const listing = git(opts.checkout, ["worktree", "list", "--porcelain"]);
46561
46825
  for (const block of listing.split("\n\n")) {
@@ -47075,7 +47339,7 @@ function isBridgeGeneratedArtifact(artifact) {
47075
47339
  return typeof payload === "object" && payload !== null && "event" in payload;
47076
47340
  }
47077
47341
  function newArtifactId() {
47078
- return `EA-${import_node_crypto6.default.randomUUID()}`;
47342
+ return `EA-${import_node_crypto7.default.randomUUID()}`;
47079
47343
  }
47080
47344
  var BLAST_RADIUS_FLOOR_PATTERNS = [/^supabase\/migrations\//, /^packages\/db\/src\/schema\.ts$/];
47081
47345
  function isBlastRadiusFloorPath(path22) {
@@ -47317,7 +47581,7 @@ async function driveRun(deps, projectSlug, runId) {
47317
47581
  if (!claimed) return;
47318
47582
  if (!claimed.leaseId) {
47319
47583
  await deps.client.createInboxItem(projectSlug, {
47320
- id: `II-${import_node_crypto6.default.randomUUID()}`,
47584
+ id: `II-${import_node_crypto7.default.randomUUID()}`,
47321
47585
  kind: "handoff",
47322
47586
  taskId: claimed.taskId,
47323
47587
  body: `Execution run ${runId} was claimed but returned no leaseId. This indicates DB/API corruption and requires operator attention.`
@@ -48494,7 +48758,7 @@ async function reconcileTaskAwaitingMerge(deps, projectSlug, task, runId, reason
48494
48758
  }
48495
48759
  try {
48496
48760
  await deps.client.createInboxItem(projectSlug, {
48497
- id: `II-${import_node_crypto6.default.randomUUID()}`,
48761
+ id: `II-${import_node_crypto7.default.randomUUID()}`,
48498
48762
  kind: "handoff",
48499
48763
  taskId: task.id,
48500
48764
  body: `Task ${task.id} (${task.title}) still needs operator follow-up: ${reason}. Mrrlin could not move the task back to Handoff needed automatically.`
@@ -48529,7 +48793,7 @@ async function notifyOperatorHandoff(deps, projectSlug, task, runId, reason) {
48529
48793
  }
48530
48794
  try {
48531
48795
  await deps.client.createInboxItem(projectSlug, {
48532
- id: `II-${import_node_crypto6.default.randomUUID()}`,
48796
+ id: `II-${import_node_crypto7.default.randomUUID()}`,
48533
48797
  kind: "handoff",
48534
48798
  taskId: task.id,
48535
48799
  body: `Execution run ${runId} for task ${task.id} (${task.title}) needs operator attention: ${reason}`
@@ -48669,8 +48933,8 @@ async function runBackstopSweep(deps, drive = (slug, id) => driveRun(deps, slug,
48669
48933
  function isRunRecoverableByThisBridge(run3, worktreeRoot) {
48670
48934
  if (!worktreeRoot) return true;
48671
48935
  if (!run3.worktreeId) return false;
48672
- const relative = import_node_path15.default.relative(import_node_path15.default.resolve(worktreeRoot), import_node_path15.default.resolve(run3.worktreeId));
48673
- return relative === "" || relative.length > 0 && !relative.startsWith("..") && !import_node_path15.default.isAbsolute(relative);
48936
+ const relative = import_node_path18.default.relative(import_node_path18.default.resolve(worktreeRoot), import_node_path18.default.resolve(run3.worktreeId));
48937
+ return relative === "" || relative.length > 0 && !relative.startsWith("..") && !import_node_path18.default.isAbsolute(relative);
48674
48938
  }
48675
48939
  async function deployGateHandoff(deps, projectSlug, task, runId, reason, leaseId) {
48676
48940
  await deps.client.updateExecutionRun(projectSlug, runId, { status: "failed", finishedAt: (/* @__PURE__ */ new Date()).toISOString(), leaseId: leaseId ?? void 0 }).catch(() => {
@@ -48688,7 +48952,7 @@ async function deployGateHandoff(deps, projectSlug, task, runId, reason, leaseId
48688
48952
  }).catch(() => {
48689
48953
  });
48690
48954
  await deps.client.createInboxItem(projectSlug, {
48691
- id: `II-${import_node_crypto6.default.randomUUID()}`,
48955
+ id: `II-${import_node_crypto7.default.randomUUID()}`,
48692
48956
  kind: "handoff",
48693
48957
  taskId: task.id,
48694
48958
  body: `Deploy gate for run ${runId} (task ${task.id} \u2014 ${task.title}) needs operator attention: ${reason}`
@@ -48707,7 +48971,7 @@ function maxLeaseReclaims() {
48707
48971
  }
48708
48972
 
48709
48973
  // src/async-job-consumer.ts
48710
- var import_node_crypto8 = __toESM(require("node:crypto"), 1);
48974
+ var import_node_crypto9 = __toESM(require("node:crypto"), 1);
48711
48975
 
48712
48976
  // src/async-tools/registry.ts
48713
48977
  var registry2 = /* @__PURE__ */ new Map();
@@ -48719,9 +48983,9 @@ function getAsyncToolDescriptor(toolName) {
48719
48983
  }
48720
48984
 
48721
48985
  // src/bridge-log.ts
48722
- var import_node_fs8 = require("node:fs");
48986
+ var import_node_fs11 = require("node:fs");
48723
48987
  var import_promises7 = require("node:fs/promises");
48724
- var import_node_path16 = require("node:path");
48988
+ var import_node_path19 = require("node:path");
48725
48989
 
48726
48990
  // src/redact.ts
48727
48991
  var REDACTED = "[REDACTED]";
@@ -48746,7 +49010,7 @@ function redact(input) {
48746
49010
  }
48747
49011
 
48748
49012
  // src/telemetry/projector.ts
48749
- var import_node_crypto7 = require("node:crypto");
49013
+ var import_node_crypto8 = require("node:crypto");
48750
49014
  function isRecord2(x) {
48751
49015
  return typeof x === "object" && x !== null;
48752
49016
  }
@@ -48787,7 +49051,7 @@ function buildProjection(payload, type, ms, telemetry) {
48787
49051
  if (typeof exitCode === "number") proj.exitCode = exitCode;
48788
49052
  const status = tool.status;
48789
49053
  if (typeof status === "string" && status.trim() !== "") {
48790
- proj.statusHash = (0, import_node_crypto7.createHash)("sha256").update(status.trim().toLowerCase()).digest("hex").slice(0, 8);
49054
+ proj.statusHash = (0, import_node_crypto8.createHash)("sha256").update(status.trim().toLowerCase()).digest("hex").slice(0, 8);
48791
49055
  }
48792
49056
  return proj;
48793
49057
  }
@@ -48997,14 +49261,14 @@ function resolvePromptsEnabled(env = process.env) {
48997
49261
  }
48998
49262
  function createBridgeLogger(stateDir, env = process.env) {
48999
49263
  if (!resolveBridgeLogEnabled(env)) return NOOP_LOGGER;
49000
- const logsDir = (0, import_node_path16.join)(stateDir, "logs");
49264
+ const logsDir = (0, import_node_path19.join)(stateDir, "logs");
49001
49265
  try {
49002
- (0, import_node_fs8.mkdirSync)(logsDir, { recursive: true });
49266
+ (0, import_node_fs11.mkdirSync)(logsDir, { recursive: true });
49003
49267
  } catch {
49004
49268
  return NOOP_LOGGER;
49005
49269
  }
49006
49270
  const includePrompts = resolvePromptsEnabled(env);
49007
- const fileFor = () => (0, import_node_path16.join)(logsDir, `bridge-${(/* @__PURE__ */ new Date()).toISOString().slice(0, 10)}.jsonl`);
49271
+ const fileFor = () => (0, import_node_path19.join)(logsDir, `bridge-${(/* @__PURE__ */ new Date()).toISOString().slice(0, 10)}.jsonl`);
49008
49272
  const MAX_TRACKED_SESSIONS = 64;
49009
49273
  const contextSlugBySession = /* @__PURE__ */ new Map();
49010
49274
  const rememberContextSlug = (sessionId, payload) => {
@@ -49045,10 +49309,10 @@ function createBridgeLogger(stateDir, env = process.env) {
49045
49309
  return { isGap, isNewTurn };
49046
49310
  };
49047
49311
  const gainDay = (sessionId) => {
49048
- const sessionsPath = (0, import_node_path16.join)(logsDir, ".sessions.json");
49312
+ const sessionsPath = (0, import_node_path19.join)(logsDir, ".sessions.json");
49049
49313
  let sessionsObj = {};
49050
49314
  try {
49051
- const parsed = JSON.parse((0, import_node_fs8.readFileSync)(sessionsPath, "utf8"));
49315
+ const parsed = JSON.parse((0, import_node_fs11.readFileSync)(sessionsPath, "utf8"));
49052
49316
  if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) sessionsObj = parsed;
49053
49317
  } catch {
49054
49318
  sessionsObj = {};
@@ -49058,8 +49322,8 @@ function createBridgeLogger(stateDir, env = process.env) {
49058
49322
  if (idsToday.includes(sessionId)) return;
49059
49323
  sessionsObj[day] = [...idsToday, sessionId];
49060
49324
  const tmpPath = `${sessionsPath}.tmp`;
49061
- (0, import_node_fs8.writeFileSync)(tmpPath, JSON.stringify(sessionsObj));
49062
- (0, import_node_fs8.renameSync)(tmpPath, sessionsPath);
49325
+ (0, import_node_fs11.writeFileSync)(tmpPath, JSON.stringify(sessionsObj));
49326
+ (0, import_node_fs11.renameSync)(tmpPath, sessionsPath);
49063
49327
  };
49064
49328
  const write = (dir, rec) => {
49065
49329
  try {
@@ -49150,7 +49414,7 @@ function createBridgeLogger(stateDir, env = process.env) {
49150
49414
  ...recordingObligationUnresolved ? { recordingObligationUnresolved } : {},
49151
49415
  ...recordingObligationMultiResolve ? { recordingObligationMultiResolve } : {}
49152
49416
  }) + "\n";
49153
- (0, import_node_fs8.appendFileSync)(fileFor(), line);
49417
+ (0, import_node_fs11.appendFileSync)(fileFor(), line);
49154
49418
  if (rec.sessionId !== null) gainDay(rec.sessionId);
49155
49419
  } catch {
49156
49420
  }
@@ -49163,7 +49427,7 @@ function createBridgeLogger(stateDir, env = process.env) {
49163
49427
  };
49164
49428
  }
49165
49429
  async function findSessionDays(stateDir, sessionId) {
49166
- const sessionsPath = (0, import_node_path16.join)(stateDir, "logs", ".sessions.json");
49430
+ const sessionsPath = (0, import_node_path19.join)(stateDir, "logs", ".sessions.json");
49167
49431
  let sessionsObj;
49168
49432
  try {
49169
49433
  const parsed = JSON.parse(await (0, import_promises7.readFile)(sessionsPath, "utf8"));
@@ -49295,7 +49559,7 @@ async function driveAsyncJob(deps, projectSlug, jobId) {
49295
49559
  const delivery = descriptor2.onComplete(outcome, input);
49296
49560
  if (!delivery.suppressInbox) {
49297
49561
  await deps.client.createInboxItem(projectSlug, {
49298
- id: delivery.id ?? `II-${import_node_crypto8.default.randomUUID()}`,
49562
+ id: delivery.id ?? `II-${import_node_crypto9.default.randomUUID()}`,
49299
49563
  kind: delivery.kind,
49300
49564
  body: delivery.body,
49301
49565
  ...delivery.taskId ? { taskId: delivery.taskId } : {},
@@ -49313,13 +49577,13 @@ async function deriveRequestedHash(client, toolName, input) {
49313
49577
  if (input.requestedHash) return input.requestedHash;
49314
49578
  if (toolName === "run_spec_consensus" && input.pageId) {
49315
49579
  const page = await client.getWikiPage(input.projectSlug, input.pageId);
49316
- return page.contentHash ?? import_node_crypto8.default.createHash("sha256").update(page.markdownBody).digest("hex");
49580
+ return page.contentHash ?? import_node_crypto9.default.createHash("sha256").update(page.markdownBody).digest("hex");
49317
49581
  }
49318
49582
  if (toolName === "draft_task_spec" && input.taskId) {
49319
49583
  const task = await client.getTask(input.projectSlug, input.taskId);
49320
- return task.updatedAt ?? import_node_crypto8.default.createHash("sha256").update(JSON.stringify(task)).digest("hex");
49584
+ return task.updatedAt ?? import_node_crypto9.default.createHash("sha256").update(JSON.stringify(task)).digest("hex");
49321
49585
  }
49322
- return import_node_crypto8.default.createHash("sha256").update(JSON.stringify(input)).digest("hex");
49586
+ return import_node_crypto9.default.createHash("sha256").update(JSON.stringify(input)).digest("hex");
49323
49587
  }
49324
49588
  async function runAsyncBackstopSweep(deps, drive = (slug, jobId) => driveAsyncJob(deps, slug, jobId)) {
49325
49589
  const projects = await deps.client.listProjects();
@@ -49597,19 +49861,19 @@ function agentIdleMs(provider) {
49597
49861
  }
49598
49862
 
49599
49863
  // src/operator-token.ts
49600
- var import_node_fs9 = require("node:fs");
49601
- var import_node_os7 = __toESM(require("node:os"), 1);
49602
- var import_node_path17 = __toESM(require("node:path"), 1);
49864
+ var import_node_fs12 = require("node:fs");
49865
+ var import_node_os8 = __toESM(require("node:os"), 1);
49866
+ var import_node_path20 = __toESM(require("node:path"), 1);
49603
49867
  function operatorDir() {
49604
- const base = process.env.CODEX_HOME ? import_node_path17.default.join(process.env.CODEX_HOME, "mrrlin") : import_node_path17.default.join(import_node_os7.default.homedir(), ".mrrlin");
49868
+ const base = process.env.CODEX_HOME ? import_node_path20.default.join(process.env.CODEX_HOME, "mrrlin") : import_node_path20.default.join(import_node_os8.default.homedir(), ".mrrlin");
49605
49869
  return base;
49606
49870
  }
49607
49871
  function operatorTokenPath() {
49608
- return import_node_path17.default.join(operatorDir(), "operator-token");
49872
+ return import_node_path20.default.join(operatorDir(), "operator-token");
49609
49873
  }
49610
49874
  function readOperatorToken() {
49611
49875
  try {
49612
- const token = (0, import_node_fs9.readFileSync)(operatorTokenPath(), "utf8").trim();
49876
+ const token = (0, import_node_fs12.readFileSync)(operatorTokenPath(), "utf8").trim();
49613
49877
  return token.length > 0 ? token : null;
49614
49878
  } catch {
49615
49879
  return null;
@@ -49617,24 +49881,24 @@ function readOperatorToken() {
49617
49881
  }
49618
49882
  function persistOperatorToken(token) {
49619
49883
  const dir = operatorDir();
49620
- (0, import_node_fs9.mkdirSync)(dir, { recursive: true, mode: 448 });
49621
- (0, import_node_fs9.writeFileSync)(operatorTokenPath(), `${token.trim()}
49884
+ (0, import_node_fs12.mkdirSync)(dir, { recursive: true, mode: 448 });
49885
+ (0, import_node_fs12.writeFileSync)(operatorTokenPath(), `${token.trim()}
49622
49886
  `, { encoding: "utf8", mode: 384 });
49623
49887
  }
49624
49888
  function agentCredentialPath() {
49625
- return import_node_path17.default.join(operatorDir(), "agent-credential");
49889
+ return import_node_path20.default.join(operatorDir(), "agent-credential");
49626
49890
  }
49627
49891
  function persistAgentSecret(secret) {
49628
49892
  const dir = operatorDir();
49629
- (0, import_node_fs9.mkdirSync)(dir, { recursive: true, mode: 448 });
49630
- (0, import_node_fs9.writeFileSync)(agentCredentialPath(), `${secret.trim()}
49893
+ (0, import_node_fs12.mkdirSync)(dir, { recursive: true, mode: 448 });
49894
+ (0, import_node_fs12.writeFileSync)(agentCredentialPath(), `${secret.trim()}
49631
49895
  `, { encoding: "utf8", mode: 384 });
49632
49896
  }
49633
49897
  function readAgentSecret() {
49634
49898
  const fromEnv = process.env.MRRLIN_AGENT_SECRET?.trim();
49635
49899
  if (fromEnv) return fromEnv;
49636
49900
  try {
49637
- const raw = (0, import_node_fs9.readFileSync)(agentCredentialPath(), "utf8").trim();
49901
+ const raw = (0, import_node_fs12.readFileSync)(agentCredentialPath(), "utf8").trim();
49638
49902
  return raw || void 0;
49639
49903
  } catch {
49640
49904
  return void 0;
@@ -49642,16 +49906,16 @@ function readAgentSecret() {
49642
49906
  }
49643
49907
 
49644
49908
  // src/thread-index.ts
49645
- var import_node_fs10 = require("node:fs");
49646
- var import_node_path18 = __toESM(require("node:path"), 1);
49909
+ var import_node_fs13 = require("node:fs");
49910
+ var import_node_path21 = __toESM(require("node:path"), 1);
49647
49911
  function threadIndexPath(stateDir) {
49648
- return import_node_path18.default.join(stateDir, "threads.json");
49912
+ return import_node_path21.default.join(stateDir, "threads.json");
49649
49913
  }
49650
49914
  function loadThreadIndex(stateDir, ttlMs, now) {
49651
49915
  const result = /* @__PURE__ */ new Map();
49652
49916
  let parsed;
49653
49917
  try {
49654
- parsed = JSON.parse((0, import_node_fs10.readFileSync)(threadIndexPath(stateDir), "utf8"));
49918
+ parsed = JSON.parse((0, import_node_fs13.readFileSync)(threadIndexPath(stateDir), "utf8"));
49655
49919
  } catch {
49656
49920
  return result;
49657
49921
  }
@@ -49674,8 +49938,8 @@ function loadThreadIndex(stateDir, ttlMs, now) {
49674
49938
  return result;
49675
49939
  }
49676
49940
  function saveThreadIndex(stateDir, entries) {
49677
- (0, import_node_fs10.mkdirSync)(stateDir, { recursive: true, mode: 448 });
49678
- (0, import_node_fs10.writeFileSync)(threadIndexPath(stateDir), `${JSON.stringify(Object.fromEntries(entries), null, 2)}
49941
+ (0, import_node_fs13.mkdirSync)(stateDir, { recursive: true, mode: 448 });
49942
+ (0, import_node_fs13.writeFileSync)(threadIndexPath(stateDir), `${JSON.stringify(Object.fromEntries(entries), null, 2)}
49679
49943
  `, {
49680
49944
  encoding: "utf8",
49681
49945
  mode: 384
@@ -49810,10 +50074,10 @@ function createToolBusyClock(opts) {
49810
50074
  }
49811
50075
 
49812
50076
  // src/worker-token.ts
49813
- var import_node_crypto9 = require("node:crypto");
49814
- var import_node_fs11 = require("node:fs");
49815
- var import_node_os8 = __toESM(require("node:os"), 1);
49816
- var import_node_path19 = __toESM(require("node:path"), 1);
50077
+ var import_node_crypto10 = require("node:crypto");
50078
+ var import_node_fs14 = require("node:fs");
50079
+ var import_node_os9 = __toESM(require("node:os"), 1);
50080
+ var import_node_path22 = __toESM(require("node:path"), 1);
49817
50081
  var DEFAULT_WORKER_PORT = 8792;
49818
50082
  function workerPort() {
49819
50083
  const raw = process.env.MRRLIN_WORKER_PORT;
@@ -49822,15 +50086,15 @@ function workerPort() {
49822
50086
  return Number.isFinite(parsed) && parsed > 0 ? parsed : DEFAULT_WORKER_PORT;
49823
50087
  }
49824
50088
  function workerDir() {
49825
- const base = process.env.CODEX_HOME ? import_node_path19.default.join(process.env.CODEX_HOME, "mrrlin") : import_node_path19.default.join(import_node_os8.default.homedir(), ".mrrlin");
49826
- return import_node_path19.default.join(base, "worker");
50089
+ const base = process.env.CODEX_HOME ? import_node_path22.default.join(process.env.CODEX_HOME, "mrrlin") : import_node_path22.default.join(import_node_os9.default.homedir(), ".mrrlin");
50090
+ return import_node_path22.default.join(base, "worker");
49827
50091
  }
49828
50092
  function workerTokenPath() {
49829
- return import_node_path19.default.join(workerDir(), "token");
50093
+ return import_node_path22.default.join(workerDir(), "token");
49830
50094
  }
49831
50095
  function readWorkerToken() {
49832
50096
  try {
49833
- const token = (0, import_node_fs11.readFileSync)(workerTokenPath(), "utf8").trim();
50097
+ const token = (0, import_node_fs14.readFileSync)(workerTokenPath(), "utf8").trim();
49834
50098
  return token.length > 0 ? token : null;
49835
50099
  } catch {
49836
50100
  return null;
@@ -49840,18 +50104,18 @@ function readOrCreateWorkerToken() {
49840
50104
  const existing = readWorkerToken();
49841
50105
  if (existing) return existing;
49842
50106
  const dir = workerDir();
49843
- (0, import_node_fs11.mkdirSync)(dir, { recursive: true, mode: 448 });
49844
- const token = (0, import_node_crypto9.randomBytes)(32).toString("hex");
49845
- (0, import_node_fs11.writeFileSync)(workerTokenPath(), `${token}
50107
+ (0, import_node_fs14.mkdirSync)(dir, { recursive: true, mode: 448 });
50108
+ const token = (0, import_node_crypto10.randomBytes)(32).toString("hex");
50109
+ (0, import_node_fs14.writeFileSync)(workerTokenPath(), `${token}
49846
50110
  `, { encoding: "utf8", mode: 384 });
49847
50111
  return token;
49848
50112
  }
49849
50113
 
49850
50114
  // src/remote-phone-relay.ts
49851
50115
  var import_node_events2 = require("node:events");
49852
- var import_node_fs12 = require("node:fs");
49853
- var import_node_os9 = require("node:os");
49854
- var import_node_path20 = require("node:path");
50116
+ var import_node_fs15 = require("node:fs");
50117
+ var import_node_os10 = require("node:os");
50118
+ var import_node_path23 = require("node:path");
49855
50119
 
49856
50120
  // ../../node_modules/.pnpm/@noble+hashes@1.3.3/node_modules/@noble/hashes/esm/cryptoNode.js
49857
50121
  var nc = __toESM(require("node:crypto"), 1);
@@ -53422,9 +53686,9 @@ var DirectorRelay = class {
53422
53686
 
53423
53687
  // src/remote-phone-relay.ts
53424
53688
  function loadOrCreateAgentDeviceKey() {
53425
- const path22 = (0, import_node_path20.join)((0, import_node_os9.homedir)(), ".mrrlin", "agent-device-key");
53689
+ const path22 = (0, import_node_path23.join)((0, import_node_os10.homedir)(), ".mrrlin", "agent-device-key");
53426
53690
  try {
53427
- const raw = JSON.parse((0, import_node_fs12.readFileSync)(path22, "utf8"));
53691
+ const raw = JSON.parse((0, import_node_fs15.readFileSync)(path22, "utf8"));
53428
53692
  if (typeof raw.priv === "string" && typeof raw.pub === "string") {
53429
53693
  return { privateKey: fromBase64Url(raw.priv), publicKey: fromBase64Url(raw.pub) };
53430
53694
  }
@@ -53432,8 +53696,8 @@ function loadOrCreateAgentDeviceKey() {
53432
53696
  }
53433
53697
  const kp = generateIdentityKeyPair();
53434
53698
  try {
53435
- (0, import_node_fs12.mkdirSync)((0, import_node_path20.join)((0, import_node_os9.homedir)(), ".mrrlin"), { recursive: true });
53436
- (0, import_node_fs12.writeFileSync)(
53699
+ (0, import_node_fs15.mkdirSync)((0, import_node_path23.join)((0, import_node_os10.homedir)(), ".mrrlin"), { recursive: true });
53700
+ (0, import_node_fs15.writeFileSync)(
53437
53701
  path22,
53438
53702
  JSON.stringify({ priv: toBase64Url(kp.privateKey), pub: toBase64Url(kp.publicKey) }),
53439
53703
  { mode: 384 }
@@ -53442,10 +53706,10 @@ function loadOrCreateAgentDeviceKey() {
53442
53706
  }
53443
53707
  return kp;
53444
53708
  }
53445
- var AGENT_PAIRING_PATH = (0, import_node_path20.join)((0, import_node_os9.homedir)(), ".mrrlin", "agent-pairing.json");
53709
+ var AGENT_PAIRING_PATH = (0, import_node_path23.join)((0, import_node_os10.homedir)(), ".mrrlin", "agent-pairing.json");
53446
53710
  function loadAgentPairing() {
53447
53711
  try {
53448
- const raw = JSON.parse((0, import_node_fs12.readFileSync)(AGENT_PAIRING_PATH, "utf8"));
53712
+ const raw = JSON.parse((0, import_node_fs15.readFileSync)(AGENT_PAIRING_PATH, "utf8"));
53449
53713
  if (typeof raw.channelId === "string" && typeof raw.agentControlSecret === "string" && typeof raw.relayAuth === "string" && typeof raw.peerIdentityKey === "string") {
53450
53714
  return {
53451
53715
  channelId: raw.channelId,
@@ -53460,8 +53724,8 @@ function loadAgentPairing() {
53460
53724
  }
53461
53725
  function saveAgentPairing(record2) {
53462
53726
  try {
53463
- (0, import_node_fs12.mkdirSync)((0, import_node_path20.join)((0, import_node_os9.homedir)(), ".mrrlin"), { recursive: true });
53464
- (0, import_node_fs12.writeFileSync)(AGENT_PAIRING_PATH, JSON.stringify(record2), { mode: 384 });
53727
+ (0, import_node_fs15.mkdirSync)((0, import_node_path23.join)((0, import_node_os10.homedir)(), ".mrrlin"), { recursive: true });
53728
+ (0, import_node_fs15.writeFileSync)(AGENT_PAIRING_PATH, JSON.stringify(record2), { mode: 384 });
53465
53729
  } catch {
53466
53730
  }
53467
53731
  }
@@ -53639,18 +53903,18 @@ async function renderPairingQrSvg(payload) {
53639
53903
  }
53640
53904
 
53641
53905
  // src/checkout-registry.ts
53642
- var import_node_fs13 = require("node:fs");
53643
- var import_node_path21 = require("node:path");
53906
+ var import_node_fs16 = require("node:fs");
53907
+ var import_node_path24 = require("node:path");
53644
53908
  var CheckoutRegistry = class {
53645
53909
  file;
53646
53910
  constructor(stateDir) {
53647
- this.file = (0, import_node_path21.join)(stateDir, "checkouts.json");
53648
- (0, import_node_fs13.mkdirSync)(stateDir, { recursive: true });
53911
+ this.file = (0, import_node_path24.join)(stateDir, "checkouts.json");
53912
+ (0, import_node_fs16.mkdirSync)(stateDir, { recursive: true });
53649
53913
  }
53650
53914
  read() {
53651
- if (!(0, import_node_fs13.existsSync)(this.file)) return {};
53915
+ if (!(0, import_node_fs16.existsSync)(this.file)) return {};
53652
53916
  try {
53653
- return JSON.parse((0, import_node_fs13.readFileSync)(this.file, "utf8"));
53917
+ return JSON.parse((0, import_node_fs16.readFileSync)(this.file, "utf8"));
53654
53918
  } catch {
53655
53919
  return {};
53656
53920
  }
@@ -53661,13 +53925,13 @@ var CheckoutRegistry = class {
53661
53925
  confirm(slug, path22, now) {
53662
53926
  const all = this.read();
53663
53927
  all[slug] = { path: path22, confirmedAt: now };
53664
- (0, import_node_fs13.writeFileSync)(this.file, JSON.stringify(all, null, 2));
53928
+ (0, import_node_fs16.writeFileSync)(this.file, JSON.stringify(all, null, 2));
53665
53929
  }
53666
53930
  };
53667
53931
 
53668
53932
  // src/checkout-handlers.ts
53669
53933
  var import_node_child_process13 = require("node:child_process");
53670
- var import_node_fs14 = require("node:fs");
53934
+ var import_node_fs17 = require("node:fs");
53671
53935
 
53672
53936
  // src/git-remote-match.ts
53673
53937
  function normalizeRemote(url2) {
@@ -53702,7 +53966,7 @@ function validateCheckoutPath(checkoutPath, repo) {
53702
53966
  }
53703
53967
  let resolvedPath;
53704
53968
  try {
53705
- resolvedPath = (0, import_node_fs14.realpathSync)(trimmedPath);
53969
+ resolvedPath = (0, import_node_fs17.realpathSync)(trimmedPath);
53706
53970
  } catch {
53707
53971
  return {
53708
53972
  ok: false,
@@ -54008,9 +54272,9 @@ function extractVerificationSection(markdown) {
54008
54272
  }
54009
54273
 
54010
54274
  // src/director-reseed.ts
54011
- var import_node_fs15 = require("node:fs");
54275
+ var import_node_fs18 = require("node:fs");
54012
54276
  var import_node_readline = require("node:readline");
54013
- var import_node_path22 = require("node:path");
54277
+ var import_node_path25 = require("node:path");
54014
54278
  function estimateTokens(s) {
54015
54279
  return Buffer.byteLength(s, "utf8");
54016
54280
  }
@@ -54142,9 +54406,9 @@ async function readSessionRows(logsDir, files, sessionIds) {
54142
54406
  const lines2 = [];
54143
54407
  let missingFiles = 0;
54144
54408
  for (const f of files) {
54145
- const filePath = (0, import_node_path22.join)(logsDir, f);
54409
+ const filePath = (0, import_node_path25.join)(logsDir, f);
54146
54410
  try {
54147
- const stream = (0, import_node_fs15.createReadStream)(filePath, { encoding: "utf8" });
54411
+ const stream = (0, import_node_fs18.createReadStream)(filePath, { encoding: "utf8" });
54148
54412
  const rl = (0, import_node_readline.createInterface)({ input: stream, crlfDelay: Infinity });
54149
54413
  try {
54150
54414
  for await (const line of rl) {
@@ -54168,18 +54432,18 @@ async function readSessionRows(logsDir, files, sessionIds) {
54168
54432
  }
54169
54433
 
54170
54434
  // src/external-agents-scrub.ts
54171
- var import_node_fs16 = __toESM(require("node:fs"), 1);
54172
- var import_node_os10 = __toESM(require("node:os"), 1);
54173
- var import_node_path23 = __toESM(require("node:path"), 1);
54435
+ var import_node_fs19 = __toESM(require("node:fs"), 1);
54436
+ var import_node_os11 = __toESM(require("node:os"), 1);
54437
+ var import_node_path26 = __toESM(require("node:path"), 1);
54174
54438
  var REDACTION = "[REDACTED]";
54175
54439
  var SHORT_VALUE_THRESHOLD = 8;
54176
- var KEYS_ENV_PATH = () => import_node_path23.default.join(import_node_os10.default.homedir(), ".local", "state", "external-agents", "keys.env");
54440
+ var KEYS_ENV_PATH = () => import_node_path26.default.join(import_node_os11.default.homedir(), ".local", "state", "external-agents", "keys.env");
54177
54441
  var keysEnvCache = null;
54178
54442
  function readKeysEnv() {
54179
54443
  const filePath = KEYS_ENV_PATH();
54180
54444
  let mtimeMs = 0;
54181
54445
  try {
54182
- mtimeMs = import_node_fs16.default.statSync(filePath).mtimeMs;
54446
+ mtimeMs = import_node_fs19.default.statSync(filePath).mtimeMs;
54183
54447
  } catch {
54184
54448
  mtimeMs = 0;
54185
54449
  }
@@ -54188,7 +54452,7 @@ function readKeysEnv() {
54188
54452
  }
54189
54453
  const map2 = /* @__PURE__ */ new Map();
54190
54454
  try {
54191
- const content = import_node_fs16.default.readFileSync(filePath, "utf8");
54455
+ const content = import_node_fs19.default.readFileSync(filePath, "utf8");
54192
54456
  for (const rawLine of content.split(/\r?\n/)) {
54193
54457
  const line = rawLine.trim();
54194
54458
  if (line === "" || line.startsWith("#")) continue;
@@ -54606,7 +54870,7 @@ function addBridgeModel(target, model) {
54606
54870
  }
54607
54871
  function readTextIfExists(filePath) {
54608
54872
  try {
54609
- return import_node_fs17.default.readFileSync(filePath, "utf8");
54873
+ return import_node_fs20.default.readFileSync(filePath, "utf8");
54610
54874
  } catch {
54611
54875
  return null;
54612
54876
  }
@@ -54617,9 +54881,9 @@ function readKnownGptSlugsFromTomlFile(filePath) {
54617
54881
  return Array.from(raw.matchAll(/^\s*model\s*=\s*"([^"]+)"/gm)).map((match) => match[1]?.trim() ?? "").filter(isSelectableModelSlug);
54618
54882
  }
54619
54883
  function readCodexFallbackModels() {
54620
- const codexHome = process.env.CODEX_HOME?.trim() || import_node_path24.default.join(import_node_os11.default.homedir(), ".codex");
54884
+ const codexHome = process.env.CODEX_HOME?.trim() || import_node_path27.default.join(import_node_os12.default.homedir(), ".codex");
54621
54885
  const models = /* @__PURE__ */ new Map();
54622
- const cachePath = import_node_path24.default.join(codexHome, "models_cache.json");
54886
+ const cachePath = import_node_path27.default.join(codexHome, "models_cache.json");
54623
54887
  const cacheRaw = readTextIfExists(cachePath);
54624
54888
  if (cacheRaw) {
54625
54889
  try {
@@ -54669,7 +54933,7 @@ function readCodexFallbackModels() {
54669
54933
  );
54670
54934
  }
54671
54935
  }
54672
- for (const slug of readKnownGptSlugsFromTomlFile(import_node_path24.default.join(codexHome, "config.toml"))) {
54936
+ for (const slug of readKnownGptSlugsFromTomlFile(import_node_path27.default.join(codexHome, "config.toml"))) {
54673
54937
  addBridgeModel(
54674
54938
  models,
54675
54939
  mapBridgeModel({
@@ -54683,11 +54947,11 @@ function readCodexFallbackModels() {
54683
54947
  })
54684
54948
  );
54685
54949
  }
54686
- const automationsDir = import_node_path24.default.join(codexHome, "automations");
54950
+ const automationsDir = import_node_path27.default.join(codexHome, "automations");
54687
54951
  try {
54688
- for (const entry of import_node_fs17.default.readdirSync(automationsDir, { withFileTypes: true })) {
54952
+ for (const entry of import_node_fs20.default.readdirSync(automationsDir, { withFileTypes: true })) {
54689
54953
  if (!entry.isDirectory()) continue;
54690
- for (const slug of readKnownGptSlugsFromTomlFile(import_node_path24.default.join(automationsDir, entry.name, "automation.toml"))) {
54954
+ for (const slug of readKnownGptSlugsFromTomlFile(import_node_path27.default.join(automationsDir, entry.name, "automation.toml"))) {
54691
54955
  addBridgeModel(
54692
54956
  models,
54693
54957
  mapBridgeModel({
@@ -54707,15 +54971,15 @@ function readCodexFallbackModels() {
54707
54971
  return [...models.values()];
54708
54972
  }
54709
54973
  function selfUpdateInboxItemId(offeredVersion) {
54710
- if (!offeredVersion) return `II-MCPUPD-${(0, import_node_crypto10.randomUUID)()}`;
54974
+ if (!offeredVersion) return `II-MCPUPD-${(0, import_node_crypto11.randomUUID)()}`;
54711
54975
  if (/^[A-Za-z0-9._-]+$/.test(offeredVersion)) return `II-MCPUPD-${offeredVersion}`;
54712
- const hash3 = import_node_crypto10.default.createHash("sha256").update(offeredVersion).digest("hex").slice(0, 10);
54976
+ const hash3 = import_node_crypto11.default.createHash("sha256").update(offeredVersion).digest("hex").slice(0, 10);
54713
54977
  return `II-MCPUPD-${offeredVersion.replace(/[^A-Za-z0-9._-]/g, "-")}-${hash3}`;
54714
54978
  }
54715
54979
  function neutralCheckoutCwd(stateDir) {
54716
- const dir = import_node_path24.default.join(stateDir, "no-checkout");
54980
+ const dir = import_node_path27.default.join(stateDir, "no-checkout");
54717
54981
  try {
54718
- import_node_fs17.default.mkdirSync(dir, { recursive: true });
54982
+ import_node_fs20.default.mkdirSync(dir, { recursive: true });
54719
54983
  } catch {
54720
54984
  }
54721
54985
  return dir;
@@ -55225,7 +55489,7 @@ async function runOrphanWorktreeSweep(client, opts) {
55225
55489
  const cutoff = Date.now() - worktreeRetentionMs();
55226
55490
  const isReapable = (worktreePath) => {
55227
55491
  try {
55228
- return import_node_fs17.default.statSync(worktreePath).mtimeMs < cutoff;
55492
+ return import_node_fs20.default.statSync(worktreePath).mtimeMs < cutoff;
55229
55493
  } catch {
55230
55494
  return false;
55231
55495
  }
@@ -55263,8 +55527,8 @@ async function runOrphanWorktreeSweep(client, opts) {
55263
55527
  }
55264
55528
  }
55265
55529
  function readStateDir() {
55266
- if (process.env.CODEX_HOME) return import_node_path24.default.join(process.env.CODEX_HOME, "mrrlin", "director-bridge");
55267
- return import_node_path24.default.join(import_node_os11.default.homedir(), ".mrrlin", "director-bridge");
55530
+ if (process.env.CODEX_HOME) return import_node_path27.default.join(process.env.CODEX_HOME, "mrrlin", "director-bridge");
55531
+ return import_node_path27.default.join(import_node_os12.default.homedir(), ".mrrlin", "director-bridge");
55268
55532
  }
55269
55533
  function readAllowedOrigins() {
55270
55534
  const raw = (process.env.MRRLIN_DIRECTOR_BRIDGE_ALLOWED_ORIGINS ?? "").trim();
@@ -55339,7 +55603,7 @@ function createBridgeRequestListener(opts) {
55339
55603
  res.end(JSON.stringify({ ok: false, error: "Origin not allowed." }));
55340
55604
  return;
55341
55605
  }
55342
- const nonce = import_node_crypto10.default.randomBytes(16).toString("base64url");
55606
+ const nonce = import_node_crypto11.default.randomBytes(16).toString("base64url");
55343
55607
  res.writeHead(200, { "content-type": "application/json" });
55344
55608
  res.end(JSON.stringify({ ok: true, wsUrl: `ws://${host}:${port}/ws`, token, nonce }));
55345
55609
  return;
@@ -55638,7 +55902,7 @@ function createBridgeMessageHandler(deps) {
55638
55902
  }
55639
55903
  }
55640
55904
  socket.on("message", async (data) => {
55641
- const spanId = import_node_crypto10.default.randomUUID();
55905
+ const spanId = import_node_crypto11.default.randomUUID();
55642
55906
  if (logCtx) {
55643
55907
  logCtx.span.id = spanId;
55644
55908
  logCtx.span.at = Date.now();
@@ -55700,7 +55964,7 @@ function createBridgeMessageHandler(deps) {
55700
55964
  sendForSpan({ type: "checkout-state", ok: false, error: { code: "invalid_input", fields: { projectSlug: "required" } } });
55701
55965
  return;
55702
55966
  }
55703
- const state = readCheckoutState(deps.checkoutRegistry, projectSlug, import_node_os11.default.hostname());
55967
+ const state = readCheckoutState(deps.checkoutRegistry, projectSlug, import_node_os12.default.hostname());
55704
55968
  if (!state) {
55705
55969
  sendForSpan({ type: "checkout-state", ok: false, error: { code: "checkout_missing" } });
55706
55970
  return;
@@ -55732,7 +55996,7 @@ function createBridgeMessageHandler(deps) {
55732
55996
  const result = registerCheckout(
55733
55997
  deps.checkoutRegistry,
55734
55998
  { projectSlug, path: typeof msg.path === "string" ? msg.path : "", repo },
55735
- import_node_os11.default.hostname()
55999
+ import_node_os12.default.hostname()
55736
56000
  );
55737
56001
  if (!result.ok) {
55738
56002
  sendForSpan({ type: "checkout-register", ok: false, error: { code: result.code, detail: result.detail } });
@@ -56218,7 +56482,7 @@ function createBridgeMessageHandler(deps) {
56218
56482
  thread.inFlight = true;
56219
56483
  pendingTurnSessions.delete(directorSessionId);
56220
56484
  thread.replay = createReplayBuffer({
56221
- turnId: (0, import_node_crypto10.randomUUID)(),
56485
+ turnId: (0, import_node_crypto11.randomUUID)(),
56222
56486
  spanId,
56223
56487
  ...deps.retentionMs !== void 0 ? { retentionMs: deps.retentionMs } : {},
56224
56488
  ...deps.ackLingerMs !== void 0 ? { ackLingerMs: deps.ackLingerMs } : {}
@@ -56799,8 +57063,8 @@ async function startDirectorBridge() {
56799
57063
  codexCwd: config2.codexCwd,
56800
57064
  codexExecutable: config2.codexExecutable,
56801
57065
  checkoutRegistry,
56802
- worktreeRoot: import_node_path24.default.join(config2.stateDir, "worktrees"),
56803
- locksDir: import_node_path24.default.join(config2.stateDir, "locks"),
57066
+ worktreeRoot: import_node_path27.default.join(config2.stateDir, "worktrees"),
57067
+ locksDir: import_node_path27.default.join(config2.stateDir, "locks"),
56804
57068
  // Wire the executor server for code-execution runs. Each run gets its own provider process
56805
57069
  // (app-server for codex, a resident CLI child for claude) at the run worktree, running
56806
57070
  // UNRESTRICTED from the real operator config (owner no-sandbox decision — auth + mrrlin MCP
@@ -56844,13 +57108,13 @@ async function startDirectorBridge() {
56844
57108
  // egressDomains is retained in the seam signature (verification-turn.ts still computes the
56845
57109
  // env host) but no longer constrains anything — the executor is unrestricted.
56846
57110
  startSandbox: async (_egressDomains, providerId) => {
56847
- const cwd = import_node_fs17.default.mkdtempSync(import_node_path24.default.join(import_node_os11.default.tmpdir(), "mrrlin-verify-"));
57111
+ const cwd = import_node_fs20.default.mkdtempSync(import_node_path27.default.join(import_node_os12.default.tmpdir(), "mrrlin-verify-"));
56848
57112
  let executor;
56849
57113
  try {
56850
57114
  executor = await startExecutorServer({ worktree: cwd, provider: providerId });
56851
57115
  } catch (error51) {
56852
57116
  try {
56853
- import_node_fs17.default.rmSync(cwd, { recursive: true, force: true });
57117
+ import_node_fs20.default.rmSync(cwd, { recursive: true, force: true });
56854
57118
  } catch {
56855
57119
  }
56856
57120
  throw error51;
@@ -56861,7 +57125,7 @@ async function startDirectorBridge() {
56861
57125
  dispose: () => {
56862
57126
  executor.dispose();
56863
57127
  try {
56864
- import_node_fs17.default.rmSync(cwd, { recursive: true, force: true });
57128
+ import_node_fs20.default.rmSync(cwd, { recursive: true, force: true });
56865
57129
  } catch {
56866
57130
  }
56867
57131
  }
@@ -56890,7 +57154,7 @@ async function startDirectorBridge() {
56890
57154
  };
56891
57155
  const sessionSinks = createSessionSinkRegistry();
56892
57156
  const tombstones = /* @__PURE__ */ new Map();
56893
- const bridgeInstanceId = (0, import_node_crypto10.randomUUID)();
57157
+ const bridgeInstanceId = (0, import_node_crypto11.randomUUID)();
56894
57158
  const asyncConsumerDeps = {
56895
57159
  client,
56896
57160
  run: wrappedTurnLock.run,
@@ -57068,7 +57332,7 @@ async function startDirectorBridge() {
57068
57332
  }
57069
57333
  const files = dayFilesInWindow(/* @__PURE__ */ new Date(), reseedWindowMs);
57070
57334
  const sessionIds = [args.directorSessionId, ...args.priorSessionIds];
57071
- const { lines: lines2, missingFiles } = await readSessionRows(import_node_path24.default.join(config2.stateDir, "logs"), files, sessionIds);
57335
+ const { lines: lines2, missingFiles } = await readSessionRows(import_node_path27.default.join(config2.stateDir, "logs"), files, sessionIds);
57072
57336
  const { items, skipped: skipped2 } = extractItems(lines2, sessionIds);
57073
57337
  if (items.length === 0) return refuse("no-rows");
57074
57338
  const budget = Math.max(0, Math.min(config2.reseedMaxTokens, config2.turnMaxTokens - args.otherBytes));
@@ -57165,7 +57429,7 @@ async function startDirectorBridge() {
57165
57429
  const bridgeLogger = createBridgeLogger(config2.stateDir, process.env);
57166
57430
  let bridgeBinShaShort = "unknown00000";
57167
57431
  try {
57168
- bridgeBinShaShort = import_node_crypto10.default.createHash("sha256").update(import_node_fs17.default.readFileSync(process.argv[1] ?? "")).digest("hex").slice(0, 12);
57432
+ bridgeBinShaShort = import_node_crypto11.default.createHash("sha256").update(import_node_fs20.default.readFileSync(process.argv[1] ?? "")).digest("hex").slice(0, 12);
57169
57433
  } catch {
57170
57434
  }
57171
57435
  attachBridgeWss(server, {
@@ -57301,8 +57565,8 @@ async function startDirectorBridge() {
57301
57565
  );
57302
57566
  void runOrphanWorktreeSweep(client, {
57303
57567
  checkoutRegistry,
57304
- worktreeRoot: import_node_path24.default.join(config2.stateDir, "worktrees"),
57305
- locksDir: import_node_path24.default.join(config2.stateDir, "locks")
57568
+ worktreeRoot: import_node_path27.default.join(config2.stateDir, "worktrees"),
57569
+ locksDir: import_node_path27.default.join(config2.stateDir, "locks")
57306
57570
  });
57307
57571
  {
57308
57572
  const { retainedBuffers, retainedBytes, tombstonesRemoved } = sweepReplayBuffers(threads, tombstones, {
@@ -57610,7 +57874,7 @@ function timingSafeTokenEqual(provided, expected) {
57610
57874
  const a = Buffer.from(provided);
57611
57875
  const b = Buffer.from(expected);
57612
57876
  if (a.length !== b.length) return false;
57613
- return import_node_crypto10.default.timingSafeEqual(a, b);
57877
+ return import_node_crypto11.default.timingSafeEqual(a, b);
57614
57878
  }
57615
57879
  function readDispatchBody(req) {
57616
57880
  return new Promise((resolve, reject) => {
@@ -57632,15 +57896,15 @@ function readDispatchBody(req) {
57632
57896
  function readOrCreateBridgeToken(stateDir) {
57633
57897
  const explicit = (process.env.MRRLIN_DIRECTOR_BRIDGE_TOKEN ?? "").trim();
57634
57898
  if (explicit) return explicit;
57635
- const tokenPath = import_node_path24.default.join(stateDir, "token.txt");
57899
+ const tokenPath = import_node_path27.default.join(stateDir, "token.txt");
57636
57900
  try {
57637
- const existing = import_node_fs17.default.readFileSync(tokenPath, "utf8").trim();
57901
+ const existing = import_node_fs20.default.readFileSync(tokenPath, "utf8").trim();
57638
57902
  if (existing) return existing;
57639
57903
  } catch {
57640
57904
  }
57641
- import_node_fs17.default.mkdirSync(stateDir, { recursive: true, mode: 448 });
57642
- const token = import_node_crypto10.default.randomBytes(32).toString("base64url");
57643
- import_node_fs17.default.writeFileSync(tokenPath, `${token}
57905
+ import_node_fs20.default.mkdirSync(stateDir, { recursive: true, mode: 448 });
57906
+ const token = import_node_crypto11.default.randomBytes(32).toString("base64url");
57907
+ import_node_fs20.default.writeFileSync(tokenPath, `${token}
57644
57908
  `, { mode: 384 });
57645
57909
  return token;
57646
57910
  }
@@ -61028,17 +61292,17 @@ var StdioServerTransport = class {
61028
61292
  };
61029
61293
 
61030
61294
  // src/tools.ts
61031
- var import_node_crypto13 = require("node:crypto");
61295
+ var import_node_crypto14 = require("node:crypto");
61032
61296
  var import_promises10 = require("node:fs/promises");
61033
- var import_node_path27 = __toESM(require("node:path"), 1);
61034
- var import_node_os12 = __toESM(require("node:os"), 1);
61297
+ var import_node_path30 = __toESM(require("node:path"), 1);
61298
+ var import_node_os13 = __toESM(require("node:os"), 1);
61035
61299
 
61036
61300
  // ../../packages/wiki/dist/index.js
61037
61301
  var import_promises8 = __toESM(require("node:fs/promises"), 1);
61038
- var import_node_path25 = __toESM(require("node:path"), 1);
61302
+ var import_node_path28 = __toESM(require("node:path"), 1);
61039
61303
  var INCLUDED_DOC_FOLDERS = /* @__PURE__ */ new Set(["_meta", "explanation", "how-to", "reference", "sdd", "tutorials"]);
61040
61304
  function toPosixPath(input) {
61041
- return input.split(import_node_path25.default.sep).join("/");
61305
+ return input.split(import_node_path28.default.sep).join("/");
61042
61306
  }
61043
61307
  function slugifyWikiSegment(input) {
61044
61308
  return input.trim().toLowerCase().replace(/`/g, "").replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
@@ -61052,12 +61316,12 @@ async function pathExists3(input) {
61052
61316
  }
61053
61317
  }
61054
61318
  async function findWorkspaceRoot(start = process.cwd()) {
61055
- let current2 = import_node_path25.default.resolve(start);
61319
+ let current2 = import_node_path28.default.resolve(start);
61056
61320
  while (true) {
61057
- if (await pathExists3(import_node_path25.default.join(current2, "pnpm-workspace.yaml")) && await pathExists3(import_node_path25.default.join(current2, "docs"))) {
61321
+ if (await pathExists3(import_node_path28.default.join(current2, "pnpm-workspace.yaml")) && await pathExists3(import_node_path28.default.join(current2, "docs"))) {
61058
61322
  return current2;
61059
61323
  }
61060
- const parent = import_node_path25.default.dirname(current2);
61324
+ const parent = import_node_path28.default.dirname(current2);
61061
61325
  if (parent === current2) {
61062
61326
  throw new Error(`Unable to find Mrrlin workspace root from ${start}`);
61063
61327
  }
@@ -61066,28 +61330,28 @@ async function findWorkspaceRoot(start = process.cwd()) {
61066
61330
  }
61067
61331
  async function resolveDocsRoot(input) {
61068
61332
  if (input) {
61069
- return import_node_path25.default.resolve(input);
61333
+ return import_node_path28.default.resolve(input);
61070
61334
  }
61071
61335
  if (process.env.MRRLIN_DOCS_ROOT) {
61072
- return import_node_path25.default.resolve(process.env.MRRLIN_DOCS_ROOT);
61336
+ return import_node_path28.default.resolve(process.env.MRRLIN_DOCS_ROOT);
61073
61337
  }
61074
- return import_node_path25.default.join(await findWorkspaceRoot(), "docs");
61338
+ return import_node_path28.default.join(await findWorkspaceRoot(), "docs");
61075
61339
  }
61076
61340
  async function resolveIndexPath(input) {
61077
61341
  if (input) {
61078
- return import_node_path25.default.resolve(input);
61342
+ return import_node_path28.default.resolve(input);
61079
61343
  }
61080
61344
  if (process.env.MRRLIN_WIKI_INDEX_PATH) {
61081
- return import_node_path25.default.resolve(process.env.MRRLIN_WIKI_INDEX_PATH);
61345
+ return import_node_path28.default.resolve(process.env.MRRLIN_WIKI_INDEX_PATH);
61082
61346
  }
61083
61347
  const workspaceRoot = await findWorkspaceRoot();
61084
- return import_node_path25.default.join(workspaceRoot, "apps", "web", "public", "wiki-index.json");
61348
+ return import_node_path28.default.join(workspaceRoot, "apps", "web", "public", "wiki-index.json");
61085
61349
  }
61086
61350
  async function walkMarkdownFiles(root, dir = root) {
61087
61351
  const entries = await import_promises8.default.readdir(dir, { withFileTypes: true });
61088
61352
  const files = [];
61089
61353
  for (const entry of entries) {
61090
- const absolute = import_node_path25.default.join(dir, entry.name);
61354
+ const absolute = import_node_path28.default.join(dir, entry.name);
61091
61355
  if (entry.isDirectory()) {
61092
61356
  files.push(...await walkMarkdownFiles(root, absolute));
61093
61357
  continue;
@@ -61106,7 +61370,7 @@ function parseTitle(markdown, sourcePath) {
61106
61370
  return title;
61107
61371
  }
61108
61372
  function documentFromFile(docsRoot, absolutePath, markdown) {
61109
- const relativePath = toPosixPath(import_node_path25.default.relative(docsRoot, absolutePath));
61373
+ const relativePath = toPosixPath(import_node_path28.default.relative(docsRoot, absolutePath));
61110
61374
  const [section, fileName] = relativePath.split("/");
61111
61375
  if (!section || !fileName || !INCLUDED_DOC_FOLDERS.has(section)) {
61112
61376
  return null;
@@ -61457,15 +61721,17 @@ async function pickPanel(input, deps) {
61457
61721
  const agents = r.stdout.split(/\r?\n/).map((l) => l.trim()).filter(Boolean);
61458
61722
  return { ok: true, agents };
61459
61723
  }
61460
- async function dispatchHead(agentId, prompt, timeoutMs, deps) {
61461
- const spawn4 = deps?.spawn ?? import_node_child_process17.spawn;
61462
- const { command, prefixArgs } = resolveExternalAgentsCliInvocation(deps?.externalAgentsBin);
61463
- const args = ["dispatch", agentId, "--json", prompt];
61464
- const r = await runExternalAgents(command, [...prefixArgs, ...args], "dispatch", timeoutMs, spawn4);
61465
- if (r.error) return { ok: false, error: r.error };
61466
- const lines2 = r.stdout.split(/\r?\n/).map((l) => l.trim()).filter(Boolean);
61724
+ function dispatchUsage(parsed) {
61725
+ const readCount3 = (value) => typeof value === "number" && Number.isFinite(value) ? value : null;
61726
+ const inputTokens = readCount3(parsed.tokens_in);
61727
+ const outputTokens = readCount3(parsed.tokens_out);
61728
+ if (inputTokens === null && outputTokens === null) return null;
61729
+ return { inputTokens, cachedInputTokens: null, cacheWriteInputTokens: null, outputTokens };
61730
+ }
61731
+ function parseDispatch(agentId, stdout, exitCode) {
61732
+ const lines2 = stdout.split(/\r?\n/).map((l) => l.trim()).filter(Boolean);
61467
61733
  const jsonLine = [...lines2].reverse().find((l) => l[0] === "{");
61468
- if (!jsonLine) return { ok: false, error: `dispatch ${agentId}: no JSON on stdout (exit ${r.code})` };
61734
+ if (!jsonLine) return { ok: false, error: `dispatch ${agentId}: no JSON on stdout (exit ${exitCode})` };
61469
61735
  let parsed;
61470
61736
  try {
61471
61737
  parsed = JSON.parse(jsonLine);
@@ -61478,7 +61744,16 @@ async function dispatchHead(agentId, prompt, timeoutMs, deps) {
61478
61744
  if (typeof parsed.text !== "string" || parsed.text.trim() === "") {
61479
61745
  return { ok: false, error: `dispatch ${agentId}: empty text on success` };
61480
61746
  }
61481
- return { ok: true, text: parsed.text };
61747
+ const usage = dispatchUsage(parsed);
61748
+ return { ok: true, text: parsed.text, usage };
61749
+ }
61750
+ async function dispatchHead(agentId, prompt, timeoutMs, deps) {
61751
+ const spawn4 = deps?.spawn ?? import_node_child_process17.spawn;
61752
+ const { command, prefixArgs } = resolveExternalAgentsCliInvocation(deps?.externalAgentsBin);
61753
+ const args = ["dispatch", agentId, "--json", prompt];
61754
+ const r = await runExternalAgents(command, [...prefixArgs, ...args], "dispatch", timeoutMs, spawn4);
61755
+ if (r.error) return { ok: false, error: r.error };
61756
+ return parseDispatch(agentId, r.stdout, r.code);
61482
61757
  }
61483
61758
  async function buildMultiHeadRunner(input, deps) {
61484
61759
  const pickOnce = () => pickPanel(
@@ -61863,7 +62138,7 @@ async function runDecisionConsensus(input, deps) {
61863
62138
  }
61864
62139
 
61865
62140
  // src/async-tools/consensus.ts
61866
- var import_node_crypto11 = require("node:crypto");
62141
+ var import_node_crypto12 = require("node:crypto");
61867
62142
 
61868
62143
  // src/consensus/question-similarity.ts
61869
62144
  var SUPPRESSION_SIMILARITY_THRESHOLD = 0.6;
@@ -62059,6 +62334,10 @@ async function runNativeSpecGate(ctx, input, builders = defaultNativeSpecGateBui
62059
62334
  specPageId: input.pageId,
62060
62335
  cwd: ctx.cwd,
62061
62336
  codexExecutable: ctx.codexExecutable,
62337
+ // Where the gate records what each of its provider calls cost. This is the only one of the
62338
+ // four gate-deps call sites that holds a stateDir today; without it the recorder is a no-op,
62339
+ // so the spec gate is the one whose cost is actually observable.
62340
+ stateDir: ctx.stateDir,
62062
62341
  extraHeadCount: input.extraHeads?.length ?? 0,
62063
62342
  // model-tier-planning-and-arbiter task 1.21: the seat minted at the async-job claim.
62064
62343
  seat: ctx.seat
@@ -62139,9 +62418,9 @@ async function handleConsensusBlocked(result, ctx, input, resolvedTaskId) {
62139
62418
  }
62140
62419
  if (taskId) {
62141
62420
  const scopeId = taskId;
62142
- const groupId = toFile.length > 1 ? `II-${scopeId}-gate-group-${(0, import_node_crypto11.createHash)("sha256").update(toFile.map((c) => c.rawQuestion).sort().join("\n")).digest("hex").slice(0, 10)}` : void 0;
62421
+ const groupId = toFile.length > 1 ? `II-${scopeId}-gate-group-${(0, import_node_crypto12.createHash)("sha256").update(toFile.map((c) => c.rawQuestion).sort().join("\n")).digest("hex").slice(0, 10)}` : void 0;
62143
62422
  for (const clarification of toFile) {
62144
- const id = `II-${scopeId}-gate-${(0, import_node_crypto11.createHash)("sha256").update(clarification.rawQuestion).digest("hex").slice(0, 10)}`;
62423
+ const id = `II-${scopeId}-gate-${(0, import_node_crypto12.createHash)("sha256").update(clarification.rawQuestion).digest("hex").slice(0, 10)}`;
62145
62424
  try {
62146
62425
  const questionOptions = buildGateQuestionOptions(clarification.rawQuestion, clarification.category);
62147
62426
  await ctx.client.createInboxItem(input.projectSlug, {
@@ -62159,9 +62438,9 @@ async function handleConsensusBlocked(result, ctx, input, resolvedTaskId) {
62159
62438
  filedQuestionCount = toFile.length;
62160
62439
  } else if (planId) {
62161
62440
  const scopeId = planId;
62162
- const groupId = toFile.length > 1 ? `II-${scopeId}-gate-group-${(0, import_node_crypto11.createHash)("sha256").update(toFile.map((c) => c.rawQuestion).sort().join("\n")).digest("hex").slice(0, 10)}` : void 0;
62441
+ const groupId = toFile.length > 1 ? `II-${scopeId}-gate-group-${(0, import_node_crypto12.createHash)("sha256").update(toFile.map((c) => c.rawQuestion).sort().join("\n")).digest("hex").slice(0, 10)}` : void 0;
62163
62442
  for (const clarification of toFile) {
62164
- const id = `II-${scopeId}-gate-${(0, import_node_crypto11.createHash)("sha256").update(clarification.rawQuestion).digest("hex").slice(0, 10)}`;
62443
+ const id = `II-${scopeId}-gate-${(0, import_node_crypto12.createHash)("sha256").update(clarification.rawQuestion).digest("hex").slice(0, 10)}`;
62165
62444
  try {
62166
62445
  const questionOptions = buildGateQuestionOptions(clarification.rawQuestion, clarification.category);
62167
62446
  await ctx.client.createInboxItem(input.projectSlug, {
@@ -62185,7 +62464,7 @@ async function handleConsensusBlocked(result, ctx, input, resolvedTaskId) {
62185
62464
  taskId: page.taskId ?? null
62186
62465
  });
62187
62466
  const reviewHash = domainScopedReviewHash2(page.contentHash, domain2);
62188
- const baseBlockItemId = `II-${taskId}-gateblock-${(0, import_node_crypto11.createHash)("sha256").update(reviewHash).digest("hex").slice(0, 10)}`;
62467
+ const baseBlockItemId = `II-${taskId}-gateblock-${(0, import_node_crypto12.createHash)("sha256").update(reviewHash).digest("hex").slice(0, 10)}`;
62189
62468
  const reviewAgainAvailable = !taskInboxItems.some(
62190
62469
  (item) => item.id === baseBlockItemId && item.status !== "pending" && item.answer === REVIEW_AGAIN_ANSWER
62191
62470
  );
@@ -62757,7 +63036,7 @@ var intentCheckDescriptor = createIntentCheckDescriptor();
62757
63036
 
62758
63037
  // src/evidence/assembler.ts
62759
63038
  var import_promises9 = require("node:fs/promises");
62760
- var import_node_path26 = require("node:path");
63039
+ var import_node_path29 = require("node:path");
62761
63040
  function evidenceDedupKey(sessionId, reportId) {
62762
63041
  return `${sessionId}:${reportId}`;
62763
63042
  }
@@ -62767,7 +63046,7 @@ function isRecord4(v) {
62767
63046
  async function readDayLines(stateDir, day, sessionId) {
62768
63047
  let raw;
62769
63048
  try {
62770
- raw = await (0, import_promises9.readFile)((0, import_node_path26.join)(stateDir, "logs", `bridge-${day}.jsonl`), "utf8");
63049
+ raw = await (0, import_promises9.readFile)((0, import_node_path29.join)(stateDir, "logs", `bridge-${day}.jsonl`), "utf8");
62771
63050
  } catch {
62772
63051
  return [];
62773
63052
  }
@@ -62841,7 +63120,7 @@ async function assembleEvidence(stateDir, sessionId, reportId, gateCtx) {
62841
63120
  }
62842
63121
  let windowPruned = false;
62843
63122
  try {
62844
- const raw = await (0, import_promises9.readFile)((0, import_node_path26.join)(stateDir, "logs", ".pruned.jsonl"), "utf8");
63123
+ const raw = await (0, import_promises9.readFile)((0, import_node_path29.join)(stateDir, "logs", ".pruned.jsonl"), "utf8");
62845
63124
  outer: for (const line of raw.split("\n")) {
62846
63125
  if (!line.trim()) continue;
62847
63126
  let rec;
@@ -62907,7 +63186,7 @@ function createReportEvidenceDescriptor() {
62907
63186
  var reportEvidenceDescriptor = createReportEvidenceDescriptor();
62908
63187
 
62909
63188
  // src/async-tools/enqueue.ts
62910
- var import_node_crypto12 = __toESM(require("node:crypto"), 1);
63189
+ var import_node_crypto13 = __toESM(require("node:crypto"), 1);
62911
63190
  async function enqueueAsyncTool(client, descriptor2, input) {
62912
63191
  if (descriptor2.cachedResult) {
62913
63192
  const cached2 = await descriptor2.cachedResult(client, input);
@@ -62920,7 +63199,7 @@ async function enqueueAsyncTool(client, descriptor2, input) {
62920
63199
  if (active) {
62921
63200
  return { status: "already_running", jobId: active.id, message: "Already running; will notify in inbox." };
62922
63201
  }
62923
- const jobId = `AJ-${import_node_crypto12.default.randomUUID()}`;
63202
+ const jobId = `AJ-${import_node_crypto13.default.randomUUID()}`;
62924
63203
  try {
62925
63204
  await client.createAsyncJob(input.projectSlug, {
62926
63205
  id: jobId,
@@ -64580,7 +64859,7 @@ function createMrrlinTools(options) {
64580
64859
  "PRODUCED_URL_RECORD_FAILED",
64581
64860
  "Unable to record produced URL.",
64582
64861
  async (c, { projectSlug, runId, url: url2, label }) => {
64583
- const id = `EA-pu-${(0, import_node_crypto13.randomBytes)(4).toString("hex")}`;
64862
+ const id = `EA-pu-${(0, import_node_crypto14.randomBytes)(4).toString("hex")}`;
64584
64863
  const payload = label ? { url: url2, label } : { url: url2 };
64585
64864
  return await c.appendExecutionArtifact(projectSlug, runId, {
64586
64865
  id,
@@ -64654,7 +64933,7 @@ function createMrrlinTools(options) {
64654
64933
  "ARTIFACT_FILE_UPLOAD_FAILED",
64655
64934
  "Unable to upload artifact file.",
64656
64935
  async (c, { projectSlug, path: filePath, class: artifactClass, taskId, runId, description }) => {
64657
- const extension2 = import_node_path27.default.extname(filePath).toLowerCase();
64936
+ const extension2 = import_node_path30.default.extname(filePath).toLowerCase();
64658
64937
  const contentType = ARTIFACT_EXTENSION_TYPES[extension2];
64659
64938
  if (!contentType) {
64660
64939
  throw new McpToolCodedError(
@@ -64682,7 +64961,7 @@ function createMrrlinTools(options) {
64682
64961
  "Artifact exceeds 5MB; split or summarize instead."
64683
64962
  );
64684
64963
  }
64685
- const filename = import_node_path27.default.basename(filePath);
64964
+ const filename = import_node_path30.default.basename(filePath);
64686
64965
  return uploadArtifactBytes(c, {
64687
64966
  bytes: bytes3,
64688
64967
  class: artifactClass,
@@ -64707,7 +64986,7 @@ function createMrrlinTools(options) {
64707
64986
  `Invalid filename '${filename}'; provide a bare filename with no path separators or '..'.`
64708
64987
  );
64709
64988
  }
64710
- const extension2 = import_node_path27.default.extname(filename).toLowerCase();
64989
+ const extension2 = import_node_path30.default.extname(filename).toLowerCase();
64711
64990
  const contentType = ARTIFACT_EXTENSION_TYPES[extension2];
64712
64991
  if (!contentType) {
64713
64992
  throw new McpToolCodedError(
@@ -64781,9 +65060,9 @@ function createMrrlinTools(options) {
64781
65060
  "LOCAL_CHECKOUT_REGISTER_FAILED",
64782
65061
  "Unable to register local checkout.",
64783
65062
  async (_c, { projectSlug, path: checkoutPath, repo }) => {
64784
- const stateDir = process.env.CODEX_HOME ? import_node_path27.default.join(process.env.CODEX_HOME, "mrrlin", "director-bridge") : import_node_path27.default.join(import_node_os12.default.homedir(), ".mrrlin", "director-bridge");
65063
+ const stateDir = process.env.CODEX_HOME ? import_node_path30.default.join(process.env.CODEX_HOME, "mrrlin", "director-bridge") : import_node_path30.default.join(import_node_os13.default.homedir(), ".mrrlin", "director-bridge");
64785
65064
  const registry3 = new CheckoutRegistry(stateDir);
64786
- const result = registerCheckout(registry3, { projectSlug, path: checkoutPath, repo }, import_node_os12.default.hostname());
65065
+ const result = registerCheckout(registry3, { projectSlug, path: checkoutPath, repo }, import_node_os13.default.hostname());
64787
65066
  if (!result.ok) {
64788
65067
  const codeMap = {
64789
65068
  not_absolute: "LOCAL_CHECKOUT_PATH_NOT_ABSOLUTE",
@@ -65020,13 +65299,13 @@ function runSetCredential(args) {
65020
65299
  }
65021
65300
 
65022
65301
  // src/install-service.ts
65023
- var import_node_os13 = __toESM(require("node:os"), 1);
65024
- var import_node_fs18 = require("node:fs");
65025
- var import_node_path28 = __toESM(require("node:path"), 1);
65302
+ var import_node_os14 = __toESM(require("node:os"), 1);
65303
+ var import_node_fs21 = require("node:fs");
65304
+ var import_node_path31 = __toESM(require("node:path"), 1);
65026
65305
  var SYSTEM_PATH_DIRS = ["/usr/bin", "/bin", "/usr/sbin", "/sbin"];
65027
65306
  function defaultHomeOwnerUid(home) {
65028
65307
  try {
65029
- return (0, import_node_fs18.statSync)(home).uid;
65308
+ return (0, import_node_fs21.statSync)(home).uid;
65030
65309
  } catch {
65031
65310
  return null;
65032
65311
  }
@@ -65067,11 +65346,11 @@ function installService(deps) {
65067
65346
  deps.log(resolved.reason);
65068
65347
  return { ok: false };
65069
65348
  }
65070
- const home = deps.env.HOME ?? import_node_os13.default.homedir();
65349
+ const home = deps.env.HOME ?? import_node_os14.default.homedir();
65071
65350
  const user = resolveBridgeUser({
65072
65351
  env: deps.env,
65073
65352
  home,
65074
- userInfo: deps.userInfo ?? (() => import_node_os13.default.userInfo()),
65353
+ userInfo: deps.userInfo ?? (() => import_node_os14.default.userInfo()),
65075
65354
  homeOwnerUid: deps.homeOwnerUid ?? defaultHomeOwnerUid,
65076
65355
  log: deps.log
65077
65356
  });
@@ -65087,7 +65366,7 @@ function installService(deps) {
65087
65366
  const claudeBin = deps.which("claude");
65088
65367
  const resolvedBins = [...bins, claudeBin].filter((b) => b !== null);
65089
65368
  const pathEnv = Array.from(
65090
- /* @__PURE__ */ new Set([...resolvedBins.map((b) => import_node_path28.default.dirname(b)), ...SYSTEM_PATH_DIRS])
65369
+ /* @__PURE__ */ new Set([...resolvedBins.map((b) => import_node_path31.default.dirname(b)), ...SYSTEM_PATH_DIRS])
65091
65370
  ).join(":");
65092
65371
  const apiBaseUrl = deps.env.MRRLIN_API_BASE_URL?.trim() || void 0;
65093
65372
  const staging = deps.env.MRRLIN_STAGING === "1" || !apiBaseUrl && bridgeUrlImpliesStaging(deps.env.MRRLIN_BRIDGE_URL);
@@ -65100,7 +65379,7 @@ function installService(deps) {
65100
65379
  staging,
65101
65380
  apiBaseUrl
65102
65381
  });
65103
- const ecoPath = import_node_path28.default.join(home, ".mrrlin", "ecosystem.config.cjs");
65382
+ const ecoPath = import_node_path31.default.join(home, ".mrrlin", "ecosystem.config.cjs");
65104
65383
  deps.writeFile(ecoPath, text);
65105
65384
  const start = deps.runPm2(["startOrReload", ecoPath]);
65106
65385
  if (start.code !== 0) {
@@ -65152,13 +65431,13 @@ function uninstallService(deps) {
65152
65431
 
65153
65432
  // src/uninstall-codex.ts
65154
65433
  var import_promises11 = __toESM(require("node:fs/promises"), 1);
65155
- var import_node_os14 = __toESM(require("node:os"), 1);
65156
- var import_node_path29 = __toESM(require("node:path"), 1);
65434
+ var import_node_os15 = __toESM(require("node:os"), 1);
65435
+ var import_node_path32 = __toESM(require("node:path"), 1);
65157
65436
  var toml3 = __toESM(require_toml(), 1);
65158
65437
  function resolveCodexHome3(options) {
65159
65438
  if (options.codexHome) return options.codexHome;
65160
65439
  if (process.env.CODEX_HOME) return process.env.CODEX_HOME;
65161
- return import_node_path29.default.join(options.homeDir ?? import_node_os14.default.homedir(), ".codex");
65440
+ return import_node_path32.default.join(options.homeDir ?? import_node_os15.default.homedir(), ".codex");
65162
65441
  }
65163
65442
  async function pathExists4(target) {
65164
65443
  try {
@@ -65171,7 +65450,7 @@ async function pathExists4(target) {
65171
65450
  var MRRLIN_BLOCK_RE = /(^|\n)\[mcp_servers\.(?:mrrlin(?:-browser)?|external-agents)(?:\]|\.[^\]\n]*\])[\s\S]*?(?=\n\[|$)/g;
65172
65451
  async function uninstallCodex(options = {}) {
65173
65452
  const codexHome = resolveCodexHome3(options);
65174
- const configPath = import_node_path29.default.join(codexHome, "config.toml");
65453
+ const configPath = import_node_path32.default.join(codexHome, "config.toml");
65175
65454
  const removePrompts = async () => uninstallPrompts(codexHome, options.promptNames ?? []);
65176
65455
  if (!await pathExists4(configPath)) {
65177
65456
  return { action: "missing", configPath, prompts: await removePrompts() };
@@ -65199,10 +65478,10 @@ async function uninstallCodex(options = {}) {
65199
65478
  }
65200
65479
  async function uninstallPrompts(codexHome, names) {
65201
65480
  if (names.length === 0) return [];
65202
- const promptsDir = import_node_path29.default.join(codexHome, "prompts");
65481
+ const promptsDir = import_node_path32.default.join(codexHome, "prompts");
65203
65482
  const out = [];
65204
65483
  for (const name of names) {
65205
- const promptPath = import_node_path29.default.join(promptsDir, `${name}.md`);
65484
+ const promptPath = import_node_path32.default.join(promptsDir, `${name}.md`);
65206
65485
  try {
65207
65486
  await import_promises11.default.unlink(promptPath);
65208
65487
  out.push({ name, action: "removed", promptPath });
@@ -65220,7 +65499,7 @@ async function uninstallPrompts(codexHome, names) {
65220
65499
 
65221
65500
  // src/extract/command.ts
65222
65501
  var import_promises12 = require("node:fs/promises");
65223
- var import_node_path30 = require("node:path");
65502
+ var import_node_path33 = require("node:path");
65224
65503
  function parseArgs(args) {
65225
65504
  const map2 = /* @__PURE__ */ new Map();
65226
65505
  for (let i = 0; i < args.length; i++) {
@@ -65257,7 +65536,7 @@ Missing required flag(s): ${missing.join(
65257
65536
  const days = await findSessionDays(deps.stateDir, sessionId);
65258
65537
  const matchingLines = [];
65259
65538
  for (const day of days) {
65260
- const logPath = (0, import_node_path30.join)(deps.stateDir, "logs", `bridge-${day}.jsonl`);
65539
+ const logPath = (0, import_node_path33.join)(deps.stateDir, "logs", `bridge-${day}.jsonl`);
65261
65540
  let raw;
65262
65541
  try {
65263
65542
  raw = await (0, import_promises12.readFile)(logPath, "utf8");
@@ -65357,16 +65636,16 @@ function bootHookStatus() {
65357
65636
  if (process.platform !== "darwin") return { status: "unknown" };
65358
65637
  const uid = process.getuid?.();
65359
65638
  if (uid === void 0 || uid === 0) return { status: "unknown" };
65360
- const home = process.env.HOME ?? (0, import_node_os15.homedir)();
65361
- const agents = import_node_path32.default.join(home, "Library", "LaunchAgents");
65639
+ const home = process.env.HOME ?? (0, import_node_os16.homedir)();
65640
+ const agents = import_node_path35.default.join(home, "Library", "LaunchAgents");
65362
65641
  const candidates = [
65363
- { label: "com.mrrlin.director-bridge", plist: import_node_path32.default.join(agents, "com.mrrlin.director-bridge.plist") },
65364
- { label: "com.PM2", plist: import_node_path32.default.join(agents, `pm2.${(0, import_node_os15.userInfo)().username}.plist`) }
65642
+ { label: "com.mrrlin.director-bridge", plist: import_node_path35.default.join(agents, "com.mrrlin.director-bridge.plist") },
65643
+ { label: "com.PM2", plist: import_node_path35.default.join(agents, `pm2.${(0, import_node_os16.userInfo)().username}.plist`) }
65365
65644
  ];
65366
65645
  for (const candidate of candidates) {
65367
65646
  const printed = (0, import_node_child_process18.spawnSync)("launchctl", ["print", `gui/${uid}/${candidate.label}`], { encoding: "utf8" });
65368
65647
  if (printed.status !== 0) continue;
65369
- if (!(0, import_node_fs19.existsSync)(candidate.plist)) continue;
65648
+ if (!(0, import_node_fs22.existsSync)(candidate.plist)) continue;
65370
65649
  const out = printed.stdout ?? "";
65371
65650
  const runs = /^\s*runs\s*=\s*(\d+)/m.exec(out);
65372
65651
  const exitCode = /^\s*last exit code\s*=\s*(-?\d+)/m.exec(out);
@@ -65649,8 +65928,8 @@ async function main() {
65649
65928
  }
65650
65929
  }
65651
65930
  try {
65652
- const codexHome = process.env.CODEX_HOME ?? import_node_path32.default.join(process.env.HOME ?? (0, import_node_os15.homedir)(), ".codex");
65653
- (0, import_node_fs19.rmSync)(import_node_path32.default.join(codexHome, "prompts", "report-issue.md"), { force: true });
65931
+ const codexHome = process.env.CODEX_HOME ?? import_node_path35.default.join(process.env.HOME ?? (0, import_node_os16.homedir)(), ".codex");
65932
+ (0, import_node_fs22.rmSync)(import_node_path35.default.join(codexHome, "prompts", "report-issue.md"), { force: true });
65654
65933
  } catch {
65655
65934
  }
65656
65935
  const claudeResult = await installClaude({ binPath, force, serveEnv });
@@ -65711,8 +65990,8 @@ async function main() {
65711
65990
  env: process.env,
65712
65991
  cwd: process.cwd(),
65713
65992
  writeFile: (p, c) => {
65714
- (0, import_node_fs19.mkdirSync)(import_node_path32.default.dirname(p), { recursive: true, mode: 448 });
65715
- (0, import_node_fs19.writeFileSync)(p, c, { mode: 384 });
65993
+ (0, import_node_fs22.mkdirSync)(import_node_path35.default.dirname(p), { recursive: true, mode: 448 });
65994
+ (0, import_node_fs22.writeFileSync)(p, c, { mode: 384 });
65716
65995
  },
65717
65996
  runPm2: pm2Runner,
65718
65997
  which: whichBin,
@@ -65730,35 +66009,35 @@ async function main() {
65730
66009
  runPm2: (a) => ({ code: pm2Runner(a).code }),
65731
66010
  removeFile: (p) => {
65732
66011
  try {
65733
- (0, import_node_fs19.rmSync)(p, { force: true });
66012
+ (0, import_node_fs22.rmSync)(p, { force: true });
65734
66013
  } catch {
65735
66014
  }
65736
66015
  },
65737
66016
  purgeSecret: purge,
65738
66017
  secretPath: agentCredentialPath(),
65739
66018
  tokenPath: operatorTokenPath(),
65740
- ecoPath: import_node_path32.default.join(process.env.HOME ?? (0, import_node_os15.homedir)(), ".mrrlin", "ecosystem.config.cjs"),
66019
+ ecoPath: import_node_path35.default.join(process.env.HOME ?? (0, import_node_os16.homedir)(), ".mrrlin", "ecosystem.config.cjs"),
65741
66020
  log: (m) => process.stderr.write(`[mrrlin-mcp uninstall-service] ${m}
65742
66021
  `)
65743
66022
  });
65744
66023
  return;
65745
66024
  }
65746
66025
  case "uninstall": {
65747
- const home = process.env.HOME ?? (0, import_node_os15.homedir)();
66026
+ const home = process.env.HOME ?? (0, import_node_os16.homedir)();
65748
66027
  const log = (m) => process.stderr.write(`[mrrlin-mcp uninstall] ${m}
65749
66028
  `);
65750
66029
  uninstallService({
65751
66030
  runPm2: (a) => ({ code: pm2Runner(a).code }),
65752
66031
  removeFile: (p) => {
65753
66032
  try {
65754
- (0, import_node_fs19.rmSync)(p, { force: true });
66033
+ (0, import_node_fs22.rmSync)(p, { force: true });
65755
66034
  } catch {
65756
66035
  }
65757
66036
  },
65758
66037
  purgeSecret: true,
65759
66038
  secretPath: agentCredentialPath(),
65760
66039
  tokenPath: operatorTokenPath(),
65761
- ecoPath: import_node_path32.default.join(home, ".mrrlin", "ecosystem.config.cjs"),
66040
+ ecoPath: import_node_path35.default.join(home, ".mrrlin", "ecosystem.config.cjs"),
65762
66041
  log
65763
66042
  });
65764
66043
  let codexOk = true;
@@ -65778,7 +66057,7 @@ async function main() {
65778
66057
  log(`codex config NOT modified: ${error51 instanceof Error ? error51.message : String(error51)}`);
65779
66058
  }
65780
66059
  try {
65781
- (0, import_node_fs19.rmSync)(import_node_path32.default.join(home, ".mrrlin"), { recursive: true, force: true });
66060
+ (0, import_node_fs22.rmSync)(import_node_path35.default.join(home, ".mrrlin"), { recursive: true, force: true });
65782
66061
  } catch {
65783
66062
  }
65784
66063
  log("removed ~/.mrrlin");
@@ -65819,7 +66098,7 @@ ${HELP_TEXT}`);
65819
66098
  }
65820
66099
  }
65821
66100
  function resolveSelfBinPath() {
65822
- return import_node_path31.default.resolve(process.argv[1] ?? process.execPath);
66101
+ return import_node_path34.default.resolve(process.argv[1] ?? process.execPath);
65823
66102
  }
65824
66103
  main().catch((error51) => {
65825
66104
  process.stderr.write(`mrrlin-mcp fatal error: ${error51 instanceof Error ? error51.message : String(error51)}