@mrrlin-dev/mcp 0.4.65 → 0.4.66

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 +154 -65
  2. package/package.json +3 -3
package/dist/bin.cjs CHANGED
@@ -40814,6 +40814,8 @@ async function mintResolvedSeat(provider, opts) {
40814
40814
  const providerId = provider.id;
40815
40815
  let strongModel;
40816
40816
  let weakModel;
40817
+ let pinRetired;
40818
+ let retiredPin;
40817
40819
  const strongEnvValue = process.env[providerId === "codex" ? CODEX_STRONG_MODEL_ENV : CLAUDE_STRONG_MODEL_ENV]?.trim();
40818
40820
  if (opts?.handle && capabilities.listsModels) {
40819
40821
  try {
@@ -40827,6 +40829,8 @@ async function mintResolvedSeat(provider, opts) {
40827
40829
  strongModel = picked;
40828
40830
  if (strongEnvValue) {
40829
40831
  logFallback(providerId, "strong", "live-default (env pin retired)", strongModel);
40832
+ pinRetired = true;
40833
+ retiredPin = strongEnvValue;
40830
40834
  }
40831
40835
  } else {
40832
40836
  throw new Error("empty model list");
@@ -40874,7 +40878,8 @@ async function mintResolvedSeat(provider, opts) {
40874
40878
  return {
40875
40879
  id: providerId,
40876
40880
  capabilities,
40877
- models: { strong: strongModel, weak: weakModel }
40881
+ models: { strong: strongModel, weak: weakModel },
40882
+ ...pinRetired ? { pinRetired: true, retiredPin } : {}
40878
40883
  };
40879
40884
  }
40880
40885
 
@@ -42940,7 +42945,7 @@ Do NOT derail the current task - if the operator has an in-flight question, answ
42940
42945
  }
42941
42946
 
42942
42947
  // src/_generated/version.ts
42943
- var PKG_VERSION = "0.4.65";
42948
+ var PKG_VERSION = "0.4.66";
42944
42949
 
42945
42950
  // src/api-base-url-migrate.ts
42946
42951
  var import_node_fs5 = __toESM(require("node:fs"), 1);
@@ -46355,7 +46360,7 @@ function setSelectedProvider(value) {
46355
46360
  // src/execution-consumer.ts
46356
46361
  var import_node_child_process13 = require("node:child_process");
46357
46362
  var import_node_crypto7 = __toESM(require("node:crypto"), 1);
46358
- var import_node_path20 = __toESM(require("node:path"), 1);
46363
+ var import_node_path21 = __toESM(require("node:path"), 1);
46359
46364
  var import_node_util = require("node:util");
46360
46365
 
46361
46366
  // src/consensus/deliverable-gate-outcome.ts
@@ -47962,6 +47967,132 @@ function effortDisabled(env = process.env) {
47962
47967
  return (env.MRRLIN_EXEC_EFFORT_DISABLE ?? "").trim() === "1";
47963
47968
  }
47964
47969
 
47970
+ // src/operator-token.ts
47971
+ var import_node_fs13 = require("node:fs");
47972
+ var import_node_os10 = __toESM(require("node:os"), 1);
47973
+ var import_node_path20 = __toESM(require("node:path"), 1);
47974
+ function operatorDir() {
47975
+ const base = process.env.CODEX_HOME ? import_node_path20.default.join(process.env.CODEX_HOME, "mrrlin") : import_node_path20.default.join(import_node_os10.default.homedir(), ".mrrlin");
47976
+ return base;
47977
+ }
47978
+ function operatorTokenPath() {
47979
+ return import_node_path20.default.join(operatorDir(), "operator-token");
47980
+ }
47981
+ function readOperatorToken() {
47982
+ try {
47983
+ const token = (0, import_node_fs13.readFileSync)(operatorTokenPath(), "utf8").trim();
47984
+ return token.length > 0 ? token : null;
47985
+ } catch {
47986
+ return null;
47987
+ }
47988
+ }
47989
+ function persistOperatorToken(token) {
47990
+ const dir = operatorDir();
47991
+ (0, import_node_fs13.mkdirSync)(dir, { recursive: true, mode: 448 });
47992
+ (0, import_node_fs13.writeFileSync)(operatorTokenPath(), `${token.trim()}
47993
+ `, { encoding: "utf8", mode: 384 });
47994
+ }
47995
+ function agentCredentialPath() {
47996
+ return import_node_path20.default.join(operatorDir(), "agent-credential");
47997
+ }
47998
+ function persistAgentSecret(secret) {
47999
+ const dir = operatorDir();
48000
+ (0, import_node_fs13.mkdirSync)(dir, { recursive: true, mode: 448 });
48001
+ (0, import_node_fs13.writeFileSync)(agentCredentialPath(), `${secret.trim()}
48002
+ `, { encoding: "utf8", mode: 384 });
48003
+ }
48004
+ function readAgentSecret() {
48005
+ const fromEnv = process.env.MRRLIN_AGENT_SECRET?.trim();
48006
+ if (fromEnv) return fromEnv;
48007
+ try {
48008
+ const raw = (0, import_node_fs13.readFileSync)(agentCredentialPath(), "utf8").trim();
48009
+ return raw || void 0;
48010
+ } catch {
48011
+ return void 0;
48012
+ }
48013
+ }
48014
+
48015
+ // src/pin-retirement-notifier.ts
48016
+ var notifiedPins = /* @__PURE__ */ new Set();
48017
+ var inFlightPins = /* @__PURE__ */ new Set();
48018
+ function getDedupKey(providerId, pinnedModel) {
48019
+ return pinnedModel ? `${providerId}:${pinnedModel}` : providerId;
48020
+ }
48021
+ async function notifyPinRetirement(info, opts) {
48022
+ if (info.providerId === "claude") {
48023
+ return;
48024
+ }
48025
+ const dedupKey = getDedupKey(info.providerId, info.pinnedModel);
48026
+ if (notifiedPins.has(dedupKey) || inFlightPins.has(dedupKey)) {
48027
+ return;
48028
+ }
48029
+ inFlightPins.add(dedupKey);
48030
+ try {
48031
+ const apiBaseUrl = opts?.apiBaseUrl ?? process.env.MRRLIN_API_BASE_URL ?? "http://127.0.0.1:8787";
48032
+ const projectSlug = info.projectSlug ?? process.env.MRRLIN_REPORT_PROJECT_SLUG?.trim() ?? "mrrlin";
48033
+ const token = opts?.token !== void 0 ? opts.token : process.env.MRRLIN_API_TOKEN?.trim() || readOperatorToken();
48034
+ const fetchImpl = opts?.fetch ?? globalThis.fetch;
48035
+ const endpoint = `${apiBaseUrl.replace(/\/+$/, "")}/projects/${encodeURIComponent(
48036
+ projectSlug
48037
+ )}/tasks`;
48038
+ const headers = {
48039
+ "content-type": "application/json",
48040
+ "x-mrrlin-actor": "mrrlin-bridge",
48041
+ "x-mrrlin-director-session-id": "pin-retirement-signal"
48042
+ };
48043
+ if (token) {
48044
+ headers.authorization = `Bearer ${token}`;
48045
+ }
48046
+ const body = {
48047
+ title: `[Bug] Retired strong-model pin: ${info.providerId} (${info.pinnedModel})`,
48048
+ type: "bug",
48049
+ category: "bug",
48050
+ subcategory: "reported",
48051
+ domain: "code",
48052
+ impact: "medium",
48053
+ notes: `The pinned strong model "${info.pinnedModel}" for provider "${info.providerId}" was not found in the provider's live model list (retired by provider). Falling back to live default model "${info.fallbackModel}". Please update the operator pin in ~/.mrrlin/ecosystem.config.cjs or the corresponding environment variable (MRRLIN_${info.providerId.toUpperCase()}_STRONG_MODEL).`,
48054
+ operatorSeedRequest: `The pinned strong model "${info.pinnedModel}" for provider "${info.providerId}" has been retired. Fallback in use: "${info.fallbackModel}". Update the strong model pin.`,
48055
+ autonomyLevel: "human_review",
48056
+ autonomyReason: "Needs human review before automation."
48057
+ };
48058
+ const response = await fetchImpl(endpoint, {
48059
+ method: "POST",
48060
+ headers,
48061
+ body: JSON.stringify(body)
48062
+ });
48063
+ if (response.ok) {
48064
+ notifiedPins.add(dedupKey);
48065
+ } else {
48066
+ console.warn(
48067
+ `[pin-retirement-notifier] received non-2xx status (${response.status}) from ${endpoint}`
48068
+ );
48069
+ }
48070
+ } catch (err) {
48071
+ console.warn(
48072
+ `[pin-retirement-notifier] failed to report retirement for provider "${info.providerId}":`,
48073
+ err
48074
+ );
48075
+ } finally {
48076
+ inFlightPins.delete(dedupKey);
48077
+ }
48078
+ }
48079
+ async function notifyPinRetirementIfRetired(seat, opts) {
48080
+ if (!seat.pinRetired) {
48081
+ return;
48082
+ }
48083
+ const pinnedModel = seat.retiredPin ?? (seat.id === "codex" ? process.env.MRRLIN_CODEX_STRONG_MODEL : seat.id === "claude" ? process.env.MRRLIN_CLAUDE_STRONG_MODEL : void 0) ?? "unknown";
48084
+ const fallbackModel = seat.models?.strong ?? "unknown";
48085
+ await notifyPinRetirement(
48086
+ {
48087
+ providerId: seat.id,
48088
+ pinnedModel,
48089
+ fallbackModel,
48090
+ projectSlug: opts?.projectSlug
48091
+ },
48092
+ opts
48093
+ );
48094
+ }
48095
+
47965
48096
  // src/execution-consumer.ts
47966
48097
  var DEFAULT_STALE_SECONDS = 300;
47967
48098
  var DEFAULT_MAX_LEASE_RECLAIMS = 3;
@@ -48689,6 +48820,7 @@ async function driveRun(deps, projectSlug, runId) {
48689
48820
  resolvedProviderId = claimed.agentSeat;
48690
48821
  } else {
48691
48822
  const seat = await mintResolvedSeat(resolveProvider(process.env, getSelectedProvider()));
48823
+ void notifyPinRetirementIfRetired(seat, { projectSlug });
48692
48824
  resolvedProviderId = seat.id;
48693
48825
  await deps.client.updateExecutionRun(projectSlug, runId, { agentSeat: seat.id }).catch((err) => {
48694
48826
  console.warn(
@@ -49956,8 +50088,8 @@ async function runBackstopSweep(deps, drive = (slug, id) => driveRun(deps, slug,
49956
50088
  function isRunRecoverableByThisBridge(run3, worktreeRoot) {
49957
50089
  if (!worktreeRoot) return true;
49958
50090
  if (!run3.worktreeId) return false;
49959
- const relative = import_node_path20.default.relative(import_node_path20.default.resolve(worktreeRoot), import_node_path20.default.resolve(run3.worktreeId));
49960
- return relative === "" || relative.length > 0 && !relative.startsWith("..") && !import_node_path20.default.isAbsolute(relative);
50091
+ const relative = import_node_path21.default.relative(import_node_path21.default.resolve(worktreeRoot), import_node_path21.default.resolve(run3.worktreeId));
50092
+ return relative === "" || relative.length > 0 && !relative.startsWith("..") && !import_node_path21.default.isAbsolute(relative);
49961
50093
  }
49962
50094
  async function deployGateHandoff(deps, projectSlug, task, runId, reason, leaseId) {
49963
50095
  await deps.client.updateExecutionRun(projectSlug, runId, { status: "failed", finishedAt: (/* @__PURE__ */ new Date()).toISOString(), leaseId: leaseId ?? void 0 }).catch(() => {
@@ -50006,9 +50138,9 @@ function getAsyncToolDescriptor(toolName) {
50006
50138
  }
50007
50139
 
50008
50140
  // src/bridge-log.ts
50009
- var import_node_fs13 = require("node:fs");
50141
+ var import_node_fs14 = require("node:fs");
50010
50142
  var import_promises7 = require("node:fs/promises");
50011
- var import_node_path21 = require("node:path");
50143
+ var import_node_path22 = require("node:path");
50012
50144
 
50013
50145
  // src/redact.ts
50014
50146
  var REDACTED = "[REDACTED]";
@@ -50284,14 +50416,14 @@ function resolvePromptsEnabled(env = process.env) {
50284
50416
  }
50285
50417
  function createBridgeLogger(stateDir, env = process.env) {
50286
50418
  if (!resolveBridgeLogEnabled(env)) return NOOP_LOGGER;
50287
- const logsDir = (0, import_node_path21.join)(stateDir, "logs");
50419
+ const logsDir = (0, import_node_path22.join)(stateDir, "logs");
50288
50420
  try {
50289
- (0, import_node_fs13.mkdirSync)(logsDir, { recursive: true });
50421
+ (0, import_node_fs14.mkdirSync)(logsDir, { recursive: true });
50290
50422
  } catch {
50291
50423
  return NOOP_LOGGER;
50292
50424
  }
50293
50425
  const includePrompts = resolvePromptsEnabled(env);
50294
- const fileFor = () => (0, import_node_path21.join)(logsDir, `bridge-${(/* @__PURE__ */ new Date()).toISOString().slice(0, 10)}.jsonl`);
50426
+ const fileFor = () => (0, import_node_path22.join)(logsDir, `bridge-${(/* @__PURE__ */ new Date()).toISOString().slice(0, 10)}.jsonl`);
50295
50427
  const MAX_TRACKED_SESSIONS = 64;
50296
50428
  const contextSlugBySession = /* @__PURE__ */ new Map();
50297
50429
  const rememberContextSlug = (sessionId, payload) => {
@@ -50332,10 +50464,10 @@ function createBridgeLogger(stateDir, env = process.env) {
50332
50464
  return { isGap, isNewTurn };
50333
50465
  };
50334
50466
  const gainDay = (sessionId) => {
50335
- const sessionsPath = (0, import_node_path21.join)(logsDir, ".sessions.json");
50467
+ const sessionsPath = (0, import_node_path22.join)(logsDir, ".sessions.json");
50336
50468
  let sessionsObj = {};
50337
50469
  try {
50338
- const parsed = JSON.parse((0, import_node_fs13.readFileSync)(sessionsPath, "utf8"));
50470
+ const parsed = JSON.parse((0, import_node_fs14.readFileSync)(sessionsPath, "utf8"));
50339
50471
  if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) sessionsObj = parsed;
50340
50472
  } catch {
50341
50473
  sessionsObj = {};
@@ -50345,8 +50477,8 @@ function createBridgeLogger(stateDir, env = process.env) {
50345
50477
  if (idsToday.includes(sessionId)) return;
50346
50478
  sessionsObj[day] = [...idsToday, sessionId];
50347
50479
  const tmpPath = `${sessionsPath}.tmp`;
50348
- (0, import_node_fs13.writeFileSync)(tmpPath, JSON.stringify(sessionsObj));
50349
- (0, import_node_fs13.renameSync)(tmpPath, sessionsPath);
50480
+ (0, import_node_fs14.writeFileSync)(tmpPath, JSON.stringify(sessionsObj));
50481
+ (0, import_node_fs14.renameSync)(tmpPath, sessionsPath);
50350
50482
  };
50351
50483
  const write = (dir, rec) => {
50352
50484
  try {
@@ -50437,7 +50569,7 @@ function createBridgeLogger(stateDir, env = process.env) {
50437
50569
  ...recordingObligationUnresolved ? { recordingObligationUnresolved } : {},
50438
50570
  ...recordingObligationMultiResolve ? { recordingObligationMultiResolve } : {}
50439
50571
  }) + "\n";
50440
- (0, import_node_fs13.appendFileSync)(fileFor(), line);
50572
+ (0, import_node_fs14.appendFileSync)(fileFor(), line);
50441
50573
  if (rec.sessionId !== null) gainDay(rec.sessionId);
50442
50574
  } catch {
50443
50575
  }
@@ -50450,7 +50582,7 @@ function createBridgeLogger(stateDir, env = process.env) {
50450
50582
  };
50451
50583
  }
50452
50584
  async function findSessionDays(stateDir, sessionId) {
50453
- const sessionsPath = (0, import_node_path21.join)(stateDir, "logs", ".sessions.json");
50585
+ const sessionsPath = (0, import_node_path22.join)(stateDir, "logs", ".sessions.json");
50454
50586
  let sessionsObj;
50455
50587
  try {
50456
50588
  const parsed = JSON.parse(await (0, import_promises7.readFile)(sessionsPath, "utf8"));
@@ -50632,12 +50764,12 @@ async function runAsyncBackstopSweep(deps, drive = (slug, jobId) => driveAsyncJo
50632
50764
  }
50633
50765
 
50634
50766
  // src/state-dir.ts
50635
- var import_node_os10 = __toESM(require("node:os"), 1);
50636
- var import_node_path22 = __toESM(require("node:path"), 1);
50767
+ var import_node_os11 = __toESM(require("node:os"), 1);
50768
+ var import_node_path23 = __toESM(require("node:path"), 1);
50637
50769
  function resolveStateDir(env = process.env) {
50638
50770
  const codexHome = env.CODEX_HOME;
50639
- if (codexHome) return import_node_path22.default.join(codexHome, "mrrlin", "director-bridge");
50640
- return import_node_path22.default.join(import_node_os10.default.homedir(), ".mrrlin", "director-bridge");
50771
+ if (codexHome) return import_node_path23.default.join(codexHome, "mrrlin", "director-bridge");
50772
+ return import_node_path23.default.join(import_node_os11.default.homedir(), ".mrrlin", "director-bridge");
50641
50773
  }
50642
50774
 
50643
50775
  // src/consensus/deliverable-gate.ts
@@ -50892,51 +51024,6 @@ function agentIdleMs(provider) {
50892
51024
  return seconds * 1e3;
50893
51025
  }
50894
51026
 
50895
- // src/operator-token.ts
50896
- var import_node_fs14 = require("node:fs");
50897
- var import_node_os11 = __toESM(require("node:os"), 1);
50898
- var import_node_path23 = __toESM(require("node:path"), 1);
50899
- function operatorDir() {
50900
- const base = process.env.CODEX_HOME ? import_node_path23.default.join(process.env.CODEX_HOME, "mrrlin") : import_node_path23.default.join(import_node_os11.default.homedir(), ".mrrlin");
50901
- return base;
50902
- }
50903
- function operatorTokenPath() {
50904
- return import_node_path23.default.join(operatorDir(), "operator-token");
50905
- }
50906
- function readOperatorToken() {
50907
- try {
50908
- const token = (0, import_node_fs14.readFileSync)(operatorTokenPath(), "utf8").trim();
50909
- return token.length > 0 ? token : null;
50910
- } catch {
50911
- return null;
50912
- }
50913
- }
50914
- function persistOperatorToken(token) {
50915
- const dir = operatorDir();
50916
- (0, import_node_fs14.mkdirSync)(dir, { recursive: true, mode: 448 });
50917
- (0, import_node_fs14.writeFileSync)(operatorTokenPath(), `${token.trim()}
50918
- `, { encoding: "utf8", mode: 384 });
50919
- }
50920
- function agentCredentialPath() {
50921
- return import_node_path23.default.join(operatorDir(), "agent-credential");
50922
- }
50923
- function persistAgentSecret(secret) {
50924
- const dir = operatorDir();
50925
- (0, import_node_fs14.mkdirSync)(dir, { recursive: true, mode: 448 });
50926
- (0, import_node_fs14.writeFileSync)(agentCredentialPath(), `${secret.trim()}
50927
- `, { encoding: "utf8", mode: 384 });
50928
- }
50929
- function readAgentSecret() {
50930
- const fromEnv = process.env.MRRLIN_AGENT_SECRET?.trim();
50931
- if (fromEnv) return fromEnv;
50932
- try {
50933
- const raw = (0, import_node_fs14.readFileSync)(agentCredentialPath(), "utf8").trim();
50934
- return raw || void 0;
50935
- } catch {
50936
- return void 0;
50937
- }
50938
- }
50939
-
50940
51027
  // src/thread-index.ts
50941
51028
  var import_node_fs15 = require("node:fs");
50942
51029
  var import_node_path24 = __toESM(require("node:path"), 1);
@@ -57102,6 +57189,7 @@ function createBridgeMessageHandler(deps) {
57102
57189
  return;
57103
57190
  }
57104
57191
  const compactionSeat = await mintResolvedSeat(resolveProvider(process.env, getSelectedProvider()));
57192
+ void notifyPinRetirementIfRetired(compactionSeat);
57105
57193
  const result = await deps.runCompaction({
57106
57194
  history,
57107
57195
  provider: compactionSeat.id,
@@ -57473,6 +57561,7 @@ function createBridgeMessageHandler(deps) {
57473
57561
  }
57474
57562
  pendingTurnSessions.add(directorSessionId);
57475
57563
  const turnSeat = await mintResolvedSeat(resolveProvider(process.env, getSelectedProvider()));
57564
+ void notifyPinRetirementIfRetired(turnSeat);
57476
57565
  const turnProviderCapabilities = turnSeat.capabilities;
57477
57566
  const codexClient = await deps.acquireCodex(turnSeat.id);
57478
57567
  let thread = deps.threads.get(directorSessionId);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mrrlin-dev/mcp",
3
- "version": "0.4.65",
3
+ "version": "0.4.66",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "mrrlin-mcp": "dist/bin.cjs"
@@ -21,12 +21,12 @@
21
21
  "@types/ws": "^8.18.1",
22
22
  "esbuild": "^0.24.0",
23
23
  "tsx": "^4.22.3",
24
+ "@mrrlin/client": "0.0.0",
24
25
  "@mrrlin/agent-client": "0.0.0",
25
26
  "@mrrlin/director-e2e": "0.0.0",
26
- "@mrrlin/schemas": "0.0.0",
27
27
  "@mrrlin/tsconfig": "0.0.0",
28
28
  "@mrrlin/wiki": "0.0.0",
29
- "@mrrlin/client": "0.0.0"
29
+ "@mrrlin/schemas": "0.0.0"
30
30
  },
31
31
  "dependencies": {
32
32
  "@iarna/toml": "^2.2.5",