@mrrlin-dev/mcp 0.4.40 → 0.4.41

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 +84 -13
  2. package/package.json +1 -1
package/dist/bin.cjs CHANGED
@@ -20646,7 +20646,7 @@ var require_dist = __commonJS({
20646
20646
  // src/bin.ts
20647
20647
  var import_node_path31 = __toESM(require("node:path"), 1);
20648
20648
  var import_node_child_process18 = require("node:child_process");
20649
- var import_node_fs18 = require("node:fs");
20649
+ var import_node_fs19 = require("node:fs");
20650
20650
  var import_node_os15 = require("node:os");
20651
20651
  var import_node_path32 = __toESM(require("node:path"), 1);
20652
20652
 
@@ -36942,6 +36942,7 @@ var openApiOperationIds = {
36942
36942
  getProviderReadiness: "getProviderReadiness",
36943
36943
  putProviderReadiness: "putProviderReadiness",
36944
36944
  getConsensusConfig: "getConsensusConfig",
36945
+ getAgentProviderConfig: "getAgentProviderConfig",
36945
36946
  updateWikiPageCas: "updateWikiPageCas",
36946
36947
  promoteSpecReadyCas: "promoteSpecReadyCas",
36947
36948
  recordSpecConsensusReview: "recordSpecConsensusReview",
@@ -37027,6 +37028,10 @@ var operatorPresenceResponseSchema = external_exports.object({ data: external_ex
37027
37028
  var operatorPresenceRequestSchema = external_exports.object({ projectSlug: external_exports.string().min(1).optional() }).strict().optional();
37028
37029
  var mrrlinConsensusConfigSchema = external_exports.object({ consensusEnabled: external_exports.boolean() });
37029
37030
  var consensusConfigResponseSchema = external_exports.object({ data: mrrlinConsensusConfigSchema });
37031
+ var mrrlinAgentProviderConfigSchema = external_exports.object({
37032
+ agentProvider: external_exports.enum(["codex", "claude"])
37033
+ });
37034
+ var agentProviderConfigResponseSchema = external_exports.object({ data: mrrlinAgentProviderConfigSchema });
37030
37035
  var agentPoolSnapshotSchema = external_exports.object({
37031
37036
  collected_at: external_exports.string(),
37032
37037
  status: external_exports.enum(["ok", "unavailable"]),
@@ -41397,6 +41402,10 @@ function createMrrlinClient(config2) {
41397
41402
  const body = await request(`/operator/settings`);
41398
41403
  return operatorSettingsGetResponseSchema.parse(body).data;
41399
41404
  },
41405
+ async getAgentProviderConfig() {
41406
+ const body = await request(`/operator/agent-provider`);
41407
+ return agentProviderConfigResponseSchema.parse(body).data;
41408
+ },
41400
41409
  async updateOperatorSettings(input) {
41401
41410
  const body = await request(`/operator/settings`, {
41402
41411
  body: JSON.stringify(input),
@@ -42071,7 +42080,7 @@ Do NOT derail the current task - if the operator has an in-flight question, answ
42071
42080
  }
42072
42081
 
42073
42082
  // src/_generated/version.ts
42074
- var PKG_VERSION = "0.4.40";
42083
+ var PKG_VERSION = "0.4.41";
42075
42084
 
42076
42085
  // src/api-base-url-migrate.ts
42077
42086
  var import_node_fs3 = __toESM(require("node:fs"), 1);
@@ -42101,6 +42110,7 @@ function renderEcosystemConfig(opts) {
42101
42110
  PATH: opts.pathEnv,
42102
42111
  MRRLIN_DIRECTOR_BRIDGE_LOG: "1"
42103
42112
  };
42113
+ if (opts.user) env.USER = opts.user;
42104
42114
  if (opts.codexHome) env.CODEX_HOME = opts.codexHome;
42105
42115
  const retargeted = opts.apiBaseUrl ? retargetRetiredApiBaseUrl(opts.apiBaseUrl).baseUrl : void 0;
42106
42116
  if (opts.staging || retargeted && isStagingApiBaseUrl(retargeted)) env.MRRLIN_STAGING = "1";
@@ -56626,6 +56636,23 @@ function checkTelemetryDefaultProject(env, warn) {
56626
56636
  "[mrrlin-mcp director-bridge] MRRLIN_TELEMETRY_DEFAULT_PROJECT is not set \u2014 telemetry for turns with no project-scoped tool call will not be uploaded. Set it in the pm2 ecosystem config to enable unattributed telemetry upload."
56627
56637
  );
56628
56638
  }
56639
+ function createSelectedProviderRefresher(deps) {
56640
+ let lastError = null;
56641
+ return () => {
56642
+ deps.read().then((config2) => {
56643
+ lastError = null;
56644
+ deps.apply(config2.agentProvider);
56645
+ }).catch((error51) => {
56646
+ const message = error51 instanceof Error ? error51.message : String(error51);
56647
+ if (message !== lastError) {
56648
+ lastError = message;
56649
+ deps.warn(
56650
+ `[mrrlin-mcp director-bridge] agent-provider refresh failed; keeping the held seat: ${message}`
56651
+ );
56652
+ }
56653
+ });
56654
+ };
56655
+ }
56629
56656
  async function startDirectorBridge() {
56630
56657
  const config2 = parseConfig();
56631
56658
  const failureLog = createFailureLog();
@@ -57399,10 +57426,12 @@ async function startDirectorBridge() {
57399
57426
  }
57400
57427
  let selectedProviderTimer = null;
57401
57428
  if (tokenProvider) {
57402
- const refreshSelectedProvider = () => {
57403
- client.getOperatorSettings().then((settings) => setSelectedProvider(settings.agentProvider)).catch(() => {
57404
- });
57405
- };
57429
+ const refreshSelectedProvider = createSelectedProviderRefresher({
57430
+ read: () => client.getAgentProviderConfig(),
57431
+ apply: setSelectedProvider,
57432
+ warn: (m) => process.stderr.write(`${m}
57433
+ `)
57434
+ });
57406
57435
  refreshSelectedProvider();
57407
57436
  selectedProviderTimer = setInterval(refreshSelectedProvider, 6e4);
57408
57437
  selectedProviderTimer.unref?.();
@@ -64992,8 +65021,42 @@ function runSetCredential(args) {
64992
65021
 
64993
65022
  // src/install-service.ts
64994
65023
  var import_node_os13 = __toESM(require("node:os"), 1);
65024
+ var import_node_fs18 = require("node:fs");
64995
65025
  var import_node_path28 = __toESM(require("node:path"), 1);
64996
65026
  var SYSTEM_PATH_DIRS = ["/usr/bin", "/bin", "/usr/sbin", "/sbin"];
65027
+ function defaultHomeOwnerUid(home) {
65028
+ try {
65029
+ return (0, import_node_fs18.statSync)(home).uid;
65030
+ } catch {
65031
+ return null;
65032
+ }
65033
+ }
65034
+ function resolveBridgeUser(deps) {
65035
+ if (deps.env.SUDO_USER?.trim()) {
65036
+ deps.log(
65037
+ "Running under sudo, so USER is left out of the service config: HOME, the pm2 daemon and the resolved user would all be root's, and Claude reads its credentials from a user's own keychain. Re-run install-service WITHOUT sudo unless you really mean to run as root."
65038
+ );
65039
+ return void 0;
65040
+ }
65041
+ let info;
65042
+ try {
65043
+ info = deps.userInfo();
65044
+ } catch {
65045
+ deps.log(
65046
+ "Could not resolve the OS user, so USER is left out of the service config. If the Claude CLI reports 'Not logged in' despite a real login, this is why."
65047
+ );
65048
+ return void 0;
65049
+ }
65050
+ const ownerUid = deps.homeOwnerUid(deps.home);
65051
+ const uidsAreMeaningful = info.uid >= 0 && ownerUid !== null && ownerUid >= 0;
65052
+ if (uidsAreMeaningful && ownerUid !== info.uid) {
65053
+ deps.log(
65054
+ `USER is left out of the service config: this process runs as '${info.username}' (uid ${info.uid}) but HOME ${deps.home} is owned by uid ${ownerUid}. Install as the user who owns that home directory, whose keychain Claude will read.`
65055
+ );
65056
+ return void 0;
65057
+ }
65058
+ return info.username;
65059
+ }
64997
65060
  function installService(deps) {
64998
65061
  if (!deps.hasSecret()) {
64999
65062
  deps.log("No agent credential found. Issue one in Settings, then run: mrrlin-mcp set-credential '<secret>'.");
@@ -65005,6 +65068,13 @@ function installService(deps) {
65005
65068
  return { ok: false };
65006
65069
  }
65007
65070
  const home = deps.env.HOME ?? import_node_os13.default.homedir();
65071
+ const user = resolveBridgeUser({
65072
+ env: deps.env,
65073
+ home,
65074
+ userInfo: deps.userInfo ?? (() => import_node_os13.default.userInfo()),
65075
+ homeOwnerUid: deps.homeOwnerUid ?? defaultHomeOwnerUid,
65076
+ log: deps.log
65077
+ });
65008
65078
  const bins = ["node", "codex", "mrrlin-mcp"].map((b) => deps.which(b));
65009
65079
  if (bins.some((b) => !b)) {
65010
65080
  deps.log("Could not resolve absolute paths for node/codex/mrrlin-mcp on PATH. Install them or fix PATH.");
@@ -65024,6 +65094,7 @@ function installService(deps) {
65024
65094
  const text = renderEcosystemConfig({
65025
65095
  cwd: resolved.cwd,
65026
65096
  home,
65097
+ user,
65027
65098
  codexHome: deps.env.CODEX_HOME?.trim() || void 0,
65028
65099
  pathEnv,
65029
65100
  staging,
@@ -65295,7 +65366,7 @@ function bootHookStatus() {
65295
65366
  for (const candidate of candidates) {
65296
65367
  const printed = (0, import_node_child_process18.spawnSync)("launchctl", ["print", `gui/${uid}/${candidate.label}`], { encoding: "utf8" });
65297
65368
  if (printed.status !== 0) continue;
65298
- if (!(0, import_node_fs18.existsSync)(candidate.plist)) continue;
65369
+ if (!(0, import_node_fs19.existsSync)(candidate.plist)) continue;
65299
65370
  const out = printed.stdout ?? "";
65300
65371
  const runs = /^\s*runs\s*=\s*(\d+)/m.exec(out);
65301
65372
  const exitCode = /^\s*last exit code\s*=\s*(-?\d+)/m.exec(out);
@@ -65579,7 +65650,7 @@ async function main() {
65579
65650
  }
65580
65651
  try {
65581
65652
  const codexHome = process.env.CODEX_HOME ?? import_node_path32.default.join(process.env.HOME ?? (0, import_node_os15.homedir)(), ".codex");
65582
- (0, import_node_fs18.rmSync)(import_node_path32.default.join(codexHome, "prompts", "report-issue.md"), { force: true });
65653
+ (0, import_node_fs19.rmSync)(import_node_path32.default.join(codexHome, "prompts", "report-issue.md"), { force: true });
65583
65654
  } catch {
65584
65655
  }
65585
65656
  const claudeResult = await installClaude({ binPath, force, serveEnv });
@@ -65640,8 +65711,8 @@ async function main() {
65640
65711
  env: process.env,
65641
65712
  cwd: process.cwd(),
65642
65713
  writeFile: (p, c) => {
65643
- (0, import_node_fs18.mkdirSync)(import_node_path32.default.dirname(p), { recursive: true, mode: 448 });
65644
- (0, import_node_fs18.writeFileSync)(p, c, { mode: 384 });
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 });
65645
65716
  },
65646
65717
  runPm2: pm2Runner,
65647
65718
  which: whichBin,
@@ -65659,7 +65730,7 @@ async function main() {
65659
65730
  runPm2: (a) => ({ code: pm2Runner(a).code }),
65660
65731
  removeFile: (p) => {
65661
65732
  try {
65662
- (0, import_node_fs18.rmSync)(p, { force: true });
65733
+ (0, import_node_fs19.rmSync)(p, { force: true });
65663
65734
  } catch {
65664
65735
  }
65665
65736
  },
@@ -65680,7 +65751,7 @@ async function main() {
65680
65751
  runPm2: (a) => ({ code: pm2Runner(a).code }),
65681
65752
  removeFile: (p) => {
65682
65753
  try {
65683
- (0, import_node_fs18.rmSync)(p, { force: true });
65754
+ (0, import_node_fs19.rmSync)(p, { force: true });
65684
65755
  } catch {
65685
65756
  }
65686
65757
  },
@@ -65707,7 +65778,7 @@ async function main() {
65707
65778
  log(`codex config NOT modified: ${error51 instanceof Error ? error51.message : String(error51)}`);
65708
65779
  }
65709
65780
  try {
65710
- (0, import_node_fs18.rmSync)(import_node_path32.default.join(home, ".mrrlin"), { recursive: true, force: true });
65781
+ (0, import_node_fs19.rmSync)(import_node_path32.default.join(home, ".mrrlin"), { recursive: true, force: true });
65711
65782
  } catch {
65712
65783
  }
65713
65784
  log("removed ~/.mrrlin");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mrrlin-dev/mcp",
3
- "version": "0.4.40",
3
+ "version": "0.4.41",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "mrrlin-mcp": "dist/bin.cjs"