@mrrlin-dev/mcp 0.4.39 → 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.
- package/dist/bin.cjs +85 -18
- package/package.json +2 -2
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
|
|
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.
|
|
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";
|
|
@@ -48961,10 +48971,6 @@ var BROWSER_OUTWARD_TOOL_NAMES = /* @__PURE__ */ new Set([
|
|
|
48961
48971
|
"browser_select_option"
|
|
48962
48972
|
]);
|
|
48963
48973
|
var IN_PRODUCT_WRITE_TOOL_NAMES = /* @__PURE__ */ new Set(["create_task", "update_task", "create_wiki_page", "update_wiki_page", "create_inbox_item"]);
|
|
48964
|
-
function resolveTurnRecordingObligationEnabled(env = process.env) {
|
|
48965
|
-
const raw = (env.MRRLIN_TURN_RECORDING_OBLIGATION ?? "").trim().toLowerCase();
|
|
48966
|
-
return !(raw === "0" || raw === "false");
|
|
48967
|
-
}
|
|
48968
48974
|
function buildBrowserAttemptReceipt(toolName) {
|
|
48969
48975
|
return {
|
|
48970
48976
|
kind: "attempt",
|
|
@@ -49015,7 +49021,7 @@ function createBridgeLogger(stateDir, env = process.env) {
|
|
|
49015
49021
|
if (!oldest.done) contextSlugBySession.delete(oldest.value);
|
|
49016
49022
|
}
|
|
49017
49023
|
};
|
|
49018
|
-
const turnRecordingObligationEnabled =
|
|
49024
|
+
const turnRecordingObligationEnabled = true;
|
|
49019
49025
|
const obligationBySession = /* @__PURE__ */ new Map();
|
|
49020
49026
|
const getObligationState = (sessionId) => {
|
|
49021
49027
|
let state = obligationBySession.get(sessionId);
|
|
@@ -56630,6 +56636,23 @@ function checkTelemetryDefaultProject(env, warn) {
|
|
|
56630
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."
|
|
56631
56637
|
);
|
|
56632
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
|
+
}
|
|
56633
56656
|
async function startDirectorBridge() {
|
|
56634
56657
|
const config2 = parseConfig();
|
|
56635
56658
|
const failureLog = createFailureLog();
|
|
@@ -57403,10 +57426,12 @@ async function startDirectorBridge() {
|
|
|
57403
57426
|
}
|
|
57404
57427
|
let selectedProviderTimer = null;
|
|
57405
57428
|
if (tokenProvider) {
|
|
57406
|
-
const refreshSelectedProvider = (
|
|
57407
|
-
|
|
57408
|
-
|
|
57409
|
-
|
|
57429
|
+
const refreshSelectedProvider = createSelectedProviderRefresher({
|
|
57430
|
+
read: () => client.getAgentProviderConfig(),
|
|
57431
|
+
apply: setSelectedProvider,
|
|
57432
|
+
warn: (m) => process.stderr.write(`${m}
|
|
57433
|
+
`)
|
|
57434
|
+
});
|
|
57410
57435
|
refreshSelectedProvider();
|
|
57411
57436
|
selectedProviderTimer = setInterval(refreshSelectedProvider, 6e4);
|
|
57412
57437
|
selectedProviderTimer.unref?.();
|
|
@@ -64996,8 +65021,42 @@ function runSetCredential(args) {
|
|
|
64996
65021
|
|
|
64997
65022
|
// src/install-service.ts
|
|
64998
65023
|
var import_node_os13 = __toESM(require("node:os"), 1);
|
|
65024
|
+
var import_node_fs18 = require("node:fs");
|
|
64999
65025
|
var import_node_path28 = __toESM(require("node:path"), 1);
|
|
65000
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
|
+
}
|
|
65001
65060
|
function installService(deps) {
|
|
65002
65061
|
if (!deps.hasSecret()) {
|
|
65003
65062
|
deps.log("No agent credential found. Issue one in Settings, then run: mrrlin-mcp set-credential '<secret>'.");
|
|
@@ -65009,6 +65068,13 @@ function installService(deps) {
|
|
|
65009
65068
|
return { ok: false };
|
|
65010
65069
|
}
|
|
65011
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
|
+
});
|
|
65012
65078
|
const bins = ["node", "codex", "mrrlin-mcp"].map((b) => deps.which(b));
|
|
65013
65079
|
if (bins.some((b) => !b)) {
|
|
65014
65080
|
deps.log("Could not resolve absolute paths for node/codex/mrrlin-mcp on PATH. Install them or fix PATH.");
|
|
@@ -65028,6 +65094,7 @@ function installService(deps) {
|
|
|
65028
65094
|
const text = renderEcosystemConfig({
|
|
65029
65095
|
cwd: resolved.cwd,
|
|
65030
65096
|
home,
|
|
65097
|
+
user,
|
|
65031
65098
|
codexHome: deps.env.CODEX_HOME?.trim() || void 0,
|
|
65032
65099
|
pathEnv,
|
|
65033
65100
|
staging,
|
|
@@ -65299,7 +65366,7 @@ function bootHookStatus() {
|
|
|
65299
65366
|
for (const candidate of candidates) {
|
|
65300
65367
|
const printed = (0, import_node_child_process18.spawnSync)("launchctl", ["print", `gui/${uid}/${candidate.label}`], { encoding: "utf8" });
|
|
65301
65368
|
if (printed.status !== 0) continue;
|
|
65302
|
-
if (!(0,
|
|
65369
|
+
if (!(0, import_node_fs19.existsSync)(candidate.plist)) continue;
|
|
65303
65370
|
const out = printed.stdout ?? "";
|
|
65304
65371
|
const runs = /^\s*runs\s*=\s*(\d+)/m.exec(out);
|
|
65305
65372
|
const exitCode = /^\s*last exit code\s*=\s*(-?\d+)/m.exec(out);
|
|
@@ -65583,7 +65650,7 @@ async function main() {
|
|
|
65583
65650
|
}
|
|
65584
65651
|
try {
|
|
65585
65652
|
const codexHome = process.env.CODEX_HOME ?? import_node_path32.default.join(process.env.HOME ?? (0, import_node_os15.homedir)(), ".codex");
|
|
65586
|
-
(0,
|
|
65653
|
+
(0, import_node_fs19.rmSync)(import_node_path32.default.join(codexHome, "prompts", "report-issue.md"), { force: true });
|
|
65587
65654
|
} catch {
|
|
65588
65655
|
}
|
|
65589
65656
|
const claudeResult = await installClaude({ binPath, force, serveEnv });
|
|
@@ -65644,8 +65711,8 @@ async function main() {
|
|
|
65644
65711
|
env: process.env,
|
|
65645
65712
|
cwd: process.cwd(),
|
|
65646
65713
|
writeFile: (p, c) => {
|
|
65647
|
-
(0,
|
|
65648
|
-
(0,
|
|
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 });
|
|
65649
65716
|
},
|
|
65650
65717
|
runPm2: pm2Runner,
|
|
65651
65718
|
which: whichBin,
|
|
@@ -65663,7 +65730,7 @@ async function main() {
|
|
|
65663
65730
|
runPm2: (a) => ({ code: pm2Runner(a).code }),
|
|
65664
65731
|
removeFile: (p) => {
|
|
65665
65732
|
try {
|
|
65666
|
-
(0,
|
|
65733
|
+
(0, import_node_fs19.rmSync)(p, { force: true });
|
|
65667
65734
|
} catch {
|
|
65668
65735
|
}
|
|
65669
65736
|
},
|
|
@@ -65684,7 +65751,7 @@ async function main() {
|
|
|
65684
65751
|
runPm2: (a) => ({ code: pm2Runner(a).code }),
|
|
65685
65752
|
removeFile: (p) => {
|
|
65686
65753
|
try {
|
|
65687
|
-
(0,
|
|
65754
|
+
(0, import_node_fs19.rmSync)(p, { force: true });
|
|
65688
65755
|
} catch {
|
|
65689
65756
|
}
|
|
65690
65757
|
},
|
|
@@ -65711,7 +65778,7 @@ async function main() {
|
|
|
65711
65778
|
log(`codex config NOT modified: ${error51 instanceof Error ? error51.message : String(error51)}`);
|
|
65712
65779
|
}
|
|
65713
65780
|
try {
|
|
65714
|
-
(0,
|
|
65781
|
+
(0, import_node_fs19.rmSync)(import_node_path32.default.join(home, ".mrrlin"), { recursive: true, force: true });
|
|
65715
65782
|
} catch {
|
|
65716
65783
|
}
|
|
65717
65784
|
log("removed ~/.mrrlin");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mrrlin-dev/mcp",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.41",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"bin": {
|
|
6
6
|
"mrrlin-mcp": "dist/bin.cjs"
|
|
@@ -21,8 +21,8 @@
|
|
|
21
21
|
"@types/ws": "^8.18.1",
|
|
22
22
|
"esbuild": "^0.24.0",
|
|
23
23
|
"tsx": "^4.22.3",
|
|
24
|
-
"@mrrlin/agent-client": "0.0.0",
|
|
25
24
|
"@mrrlin/client": "0.0.0",
|
|
25
|
+
"@mrrlin/agent-client": "0.0.0",
|
|
26
26
|
"@mrrlin/director-e2e": "0.0.0",
|
|
27
27
|
"@mrrlin/schemas": "0.0.0",
|
|
28
28
|
"@mrrlin/tsconfig": "0.0.0",
|