@mrrlin-dev/mcp 0.4.44 → 0.4.46

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 +62 -14
  2. package/package.json +3 -3
package/dist/bin.cjs CHANGED
@@ -40132,8 +40132,21 @@ var ClaudeAgentHandle = class {
40132
40132
  };
40133
40133
 
40134
40134
  // ../../packages/agent-client/dist/registry.js
40135
+ var KNOWN_PROVIDERS = { codex: true, claude: true };
40136
+ var KNOWN_PROVIDER_IDS = Object.keys(KNOWN_PROVIDERS);
40137
+ function readProviderFromEnv(env) {
40138
+ const raw = env.MRRLIN_AGENT_PROVIDER;
40139
+ if (raw === void 0)
40140
+ return null;
40141
+ const normalized = raw.trim().toLowerCase();
40142
+ if (!normalized)
40143
+ return null;
40144
+ if (Object.hasOwn(KNOWN_PROVIDERS, normalized))
40145
+ return normalized;
40146
+ throw new Error(`MRRLIN_AGENT_PROVIDER is set to ${JSON.stringify(raw.slice(0, 64))}, which is not an agent provider this build can run. Valid values: ${KNOWN_PROVIDER_IDS.join(", ")}. Unset the variable to use the operator's persisted choice.`);
40147
+ }
40135
40148
  function resolveProvider(env, persisted) {
40136
- const id = env.MRRLIN_AGENT_PROVIDER ?? persisted ?? "codex";
40149
+ const id = readProviderFromEnv(env) ?? persisted ?? "codex";
40137
40150
  if (id === "codex") {
40138
40151
  return new CodexProviderAdapter();
40139
40152
  }
@@ -42295,7 +42308,7 @@ Do NOT derail the current task - if the operator has an in-flight question, answ
42295
42308
  }
42296
42309
 
42297
42310
  // src/_generated/version.ts
42298
- var PKG_VERSION = "0.4.44";
42311
+ var PKG_VERSION = "0.4.46";
42299
42312
 
42300
42313
  // src/api-base-url-migrate.ts
42301
42314
  var import_node_fs3 = __toESM(require("node:fs"), 1);
@@ -45021,6 +45034,7 @@ function resolveInstallationId(stateDir) {
45021
45034
 
45022
45035
  // src/telemetry/daily-uploader.ts
45023
45036
  var ROWS_FILE_RE = /^rows-(.+)-(\d{4}-\d{2}-\d{2})\.jsonl$/;
45037
+ var GATE_FILE_RE = /^gate-(.+)-(\d{4}-\d{2}-\d{2})\.jsonl$/;
45024
45038
  async function uploadPendingDays(stateDir, client, bridgeHealth, gateCtx) {
45025
45039
  const telemetryDir = (0, import_node_path15.join)(stateDir, "telemetry");
45026
45040
  let files;
@@ -45030,21 +45044,39 @@ async function uploadPendingDays(stateDir, client, bridgeHealth, gateCtx) {
45030
45044
  if (err?.code === "ENOENT") return;
45031
45045
  throw err;
45032
45046
  }
45033
- const pending = [];
45047
+ const discovered = /* @__PURE__ */ new Map();
45034
45048
  for (const file2 of files) {
45035
- const match = ROWS_FILE_RE.exec(file2);
45049
+ const rowsMatch = ROWS_FILE_RE.exec(file2);
45050
+ const match = rowsMatch ?? GATE_FILE_RE.exec(file2);
45036
45051
  if (!match) continue;
45037
45052
  const [, projectSlug, day] = match;
45053
+ const key = `${projectSlug}\0${day}`;
45054
+ const entry = discovered.get(key) ?? { projectSlug, day, rowsPath: null };
45055
+ if (rowsMatch) entry.rowsPath = (0, import_node_path15.join)(telemetryDir, file2);
45056
+ discovered.set(key, entry);
45057
+ }
45058
+ const today = telemetryDay();
45059
+ const pending = [];
45060
+ const deferred = [];
45061
+ for (const { projectSlug, day, rowsPath } of discovered.values()) {
45038
45062
  const markerPath = (0, import_node_path15.join)(telemetryDir, `.processed-${projectSlug}-${day}`);
45063
+ if (rowsPath === null && day >= today) {
45064
+ try {
45065
+ await (0, import_promises6.access)(markerPath);
45066
+ } catch {
45067
+ deferred.push({ projectSlug, day });
45068
+ }
45069
+ continue;
45070
+ }
45039
45071
  try {
45040
45072
  await (0, import_promises6.access)(markerPath);
45041
45073
  } catch {
45042
- pending.push({ projectSlug, day, rowsPath: (0, import_node_path15.join)(telemetryDir, file2), markerPath });
45074
+ pending.push({ projectSlug, day, rowsPath, markerPath });
45043
45075
  }
45044
45076
  }
45045
45077
  if (pending.length === 0) return;
45046
45078
  const knownCrashCount = bridgeHealth.knownCrashCount() ?? 0;
45047
- const fullUnprocessed = pending.map((p) => ({ projectSlug: p.projectSlug, day: p.day }));
45079
+ const fullUnprocessed = [...pending.map((p) => ({ projectSlug: p.projectSlug, day: p.day })), ...deferred];
45048
45080
  pending.sort((a, b) => a.day.localeCompare(b.day));
45049
45081
  for (const cur of pending) {
45050
45082
  const failurePath = (0, import_node_path15.join)(telemetryDir, `.failed-${cur.projectSlug}-${cur.day}.json`);
@@ -45061,12 +45093,14 @@ async function uploadPendingDays(stateDir, client, bridgeHealth, gateCtx) {
45061
45093
  }
45062
45094
  let success2 = false;
45063
45095
  try {
45064
- let raw;
45065
- try {
45066
- raw = await (0, import_promises6.readFile)(cur.rowsPath, "utf8");
45067
- } catch (err) {
45068
- console.error(`uploadPendingDays: failed to read ${cur.rowsPath}`, err);
45069
- throw err;
45096
+ let raw = "";
45097
+ if (cur.rowsPath !== null) {
45098
+ try {
45099
+ raw = await (0, import_promises6.readFile)(cur.rowsPath, "utf8");
45100
+ } catch (err) {
45101
+ console.error(`uploadPendingDays: failed to read ${cur.rowsPath}`, err);
45102
+ throw err;
45103
+ }
45070
45104
  }
45071
45105
  const rows = [];
45072
45106
  for (const line of raw.split("\n")) {
@@ -45088,6 +45122,7 @@ async function uploadPendingDays(stateDir, client, bridgeHealth, gateCtx) {
45088
45122
  }
45089
45123
  } catch {
45090
45124
  }
45125
+ if (cur.rowsPath === null && gateCalls.length === 0) continue;
45091
45126
  const batch = {
45092
45127
  day: cur.day,
45093
45128
  bridgeVersion: PKG_VERSION,
@@ -62023,11 +62058,24 @@ async function runShadowPanel(input, deps) {
62023
62058
  const res = await built.runner.runHead(persona, input.artifact, "");
62024
62059
  if (res.ok) {
62025
62060
  const parsed = parseVerdict(res.text);
62026
- return { persona, agent, verdict: parsed.verdict, ok: true };
62061
+ return {
62062
+ persona,
62063
+ agent,
62064
+ verdict: parsed.verdict,
62065
+ ok: true,
62066
+ // The optional chain is required by the TYPE, not left over from not knowing the
62067
+ // invariant: `MultiHeadRunResult.usage` is declared `usage?: ExecTokenUsage | null`
62068
+ // (optional so the shape stays assignable to the gate's older `RunResult`), even though
62069
+ // `parseDispatch` always sets it. `?? null` therefore covers both "no usage key" and
62070
+ // "usage was null" — and covers neither zero: a reported 0 is a measurement and
62071
+ // survives, which is the distinction this whole field exists to preserve.
62072
+ inputTokens: res.usage?.inputTokens ?? null,
62073
+ outputTokens: res.usage?.outputTokens ?? null
62074
+ };
62027
62075
  }
62028
62076
  } catch {
62029
62077
  }
62030
- return { persona, agent, verdict: "ERROR", ok: false };
62078
+ return { persona, agent, verdict: "ERROR", ok: false, inputTokens: null, outputTokens: null };
62031
62079
  })
62032
62080
  );
62033
62081
  for (const h of perHead) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mrrlin-dev/mcp",
3
- "version": "0.4.44",
3
+ "version": "0.4.46",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "mrrlin-mcp": "dist/bin.cjs"
@@ -22,11 +22,11 @@
22
22
  "esbuild": "^0.24.0",
23
23
  "tsx": "^4.22.3",
24
24
  "@mrrlin/agent-client": "0.0.0",
25
- "@mrrlin/client": "0.0.0",
26
25
  "@mrrlin/director-e2e": "0.0.0",
27
26
  "@mrrlin/schemas": "0.0.0",
28
27
  "@mrrlin/tsconfig": "0.0.0",
29
- "@mrrlin/wiki": "0.0.0"
28
+ "@mrrlin/wiki": "0.0.0",
29
+ "@mrrlin/client": "0.0.0"
30
30
  },
31
31
  "dependencies": {
32
32
  "@iarna/toml": "^2.2.5",