@mrrlin-dev/mcp 0.4.87 → 0.4.88
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 +494 -62
- package/package.json +1 -1
package/dist/bin.cjs
CHANGED
|
@@ -56831,7 +56831,7 @@ Do NOT derail the current task - if the operator has an in-flight question, answ
|
|
|
56831
56831
|
}
|
|
56832
56832
|
|
|
56833
56833
|
// src/_generated/version.ts
|
|
56834
|
-
var PKG_VERSION = "0.4.
|
|
56834
|
+
var PKG_VERSION = "0.4.88";
|
|
56835
56835
|
|
|
56836
56836
|
// src/api-base-url-migrate.ts
|
|
56837
56837
|
var import_node_fs13 = __toESM(require("node:fs"), 1);
|
|
@@ -56856,28 +56856,45 @@ function resolveServiceCwd(opts) {
|
|
|
56856
56856
|
}
|
|
56857
56857
|
var BRIDGE_APP_NAME = "mrrlin-bridge";
|
|
56858
56858
|
function renderEcosystemConfig(opts) {
|
|
56859
|
-
|
|
56860
|
-
|
|
56861
|
-
|
|
56862
|
-
|
|
56863
|
-
|
|
56864
|
-
|
|
56865
|
-
|
|
56866
|
-
|
|
56867
|
-
|
|
56859
|
+
let envLines;
|
|
56860
|
+
if ("env" in opts && opts.env !== void 0) {
|
|
56861
|
+
const safeEnv = /* @__PURE__ */ Object.create(null);
|
|
56862
|
+
for (const key of Object.keys(opts.env)) {
|
|
56863
|
+
const val = opts.env[key];
|
|
56864
|
+
if (val !== void 0) {
|
|
56865
|
+
safeEnv[key] = val;
|
|
56866
|
+
}
|
|
56867
|
+
}
|
|
56868
|
+
const keys = Object.keys(safeEnv).sort();
|
|
56869
|
+
envLines = keys.map((k) => {
|
|
56870
|
+
const keyProp = k === "__proto__" ? '["__proto__"]' : k;
|
|
56871
|
+
return ` ${keyProp}: ${JSON.stringify(safeEnv[k])},`;
|
|
56872
|
+
}).join("\n");
|
|
56873
|
+
} else {
|
|
56874
|
+
const legacyOpts = opts;
|
|
56875
|
+
const env = {
|
|
56876
|
+
HOME: legacyOpts.home,
|
|
56877
|
+
PATH: legacyOpts.pathEnv,
|
|
56878
|
+
MRRLIN_DIRECTOR_BRIDGE_LOG: "1"
|
|
56879
|
+
};
|
|
56880
|
+
if (legacyOpts.user) {
|
|
56881
|
+
env.USER = legacyOpts.user;
|
|
56882
|
+
if (process.platform === "win32") {
|
|
56883
|
+
env.USERNAME = legacyOpts.user;
|
|
56884
|
+
}
|
|
56868
56885
|
}
|
|
56869
|
-
|
|
56870
|
-
|
|
56871
|
-
|
|
56872
|
-
|
|
56873
|
-
|
|
56874
|
-
|
|
56875
|
-
|
|
56876
|
-
|
|
56877
|
-
|
|
56886
|
+
if (legacyOpts.codexHome) env.CODEX_HOME = legacyOpts.codexHome;
|
|
56887
|
+
const claudeConfigDir = legacyOpts.claudeConfigDir?.trim();
|
|
56888
|
+
if (claudeConfigDir) env.CLAUDE_CONFIG_DIR = claudeConfigDir;
|
|
56889
|
+
const apiBaseUrl = legacyOpts.apiBaseUrl ? retargetRetiredApiBaseUrl(legacyOpts.apiBaseUrl).baseUrl : void 0;
|
|
56890
|
+
if (apiBaseUrl && !isProductionApiBaseUrl(apiBaseUrl)) {
|
|
56891
|
+
env.MRRLIN_API_BASE_URL = apiBaseUrl;
|
|
56892
|
+
if (legacyOpts.apiAllowRemote && !isStagingApiBaseUrl(apiBaseUrl) && !isLoopbackUrl(apiBaseUrl)) {
|
|
56893
|
+
env.MRRLIN_API_ALLOW_REMOTE = "1";
|
|
56894
|
+
}
|
|
56878
56895
|
}
|
|
56896
|
+
envLines = Object.entries(env).map(([k, v]) => ` ${k}: ${JSON.stringify(v)},`).join("\n");
|
|
56879
56897
|
}
|
|
56880
|
-
const envLines = Object.entries(env).map(([k, v]) => ` ${k}: ${JSON.stringify(v)},`).join("\n");
|
|
56881
56898
|
return `module.exports = {
|
|
56882
56899
|
apps: [{
|
|
56883
56900
|
name: ${JSON.stringify(BRIDGE_APP_NAME)},
|
|
@@ -71029,49 +71046,440 @@ function runSetCredential(args) {
|
|
|
71029
71046
|
var import_node_os18 = __toESM(require("node:os"), 1);
|
|
71030
71047
|
var import_node_fs24 = require("node:fs");
|
|
71031
71048
|
var import_node_path38 = __toESM(require("node:path"), 1);
|
|
71032
|
-
function
|
|
71033
|
-
|
|
71034
|
-
}
|
|
71035
|
-
|
|
71036
|
-
|
|
71037
|
-
|
|
71049
|
+
function parseEnvLine(line, env) {
|
|
71050
|
+
const trimmed = line.trim();
|
|
71051
|
+
if (!trimmed || trimmed === "}" || trimmed === "},") return;
|
|
71052
|
+
const match = /^\s*(?:([a-zA-Z_$][a-zA-Z0-9_$]*)|"((?:[^"\\]|\\.)*)"|(\["__proto__"\]))\s*:\s*("(?:[^"\\]|\\.)*")\s*,?\s*$/.exec(line);
|
|
71053
|
+
if (!match) return;
|
|
71054
|
+
const identKey = match[1];
|
|
71055
|
+
const quotedKey = match[2];
|
|
71056
|
+
const computedProto = match[3];
|
|
71057
|
+
const rawValue = match[4];
|
|
71058
|
+
if (!rawValue) return;
|
|
71059
|
+
let key = null;
|
|
71060
|
+
if (computedProto) {
|
|
71061
|
+
key = "__proto__";
|
|
71062
|
+
} else if (identKey) {
|
|
71063
|
+
if (identKey === "__proto__") {
|
|
71064
|
+
return;
|
|
71065
|
+
}
|
|
71066
|
+
key = identKey;
|
|
71067
|
+
} else if (quotedKey !== void 0) {
|
|
71068
|
+
try {
|
|
71069
|
+
const parsedKey = JSON.parse(`"${quotedKey}"`);
|
|
71070
|
+
if (typeof parsedKey !== "string" || parsedKey === "__proto__") {
|
|
71071
|
+
return;
|
|
71072
|
+
}
|
|
71073
|
+
key = parsedKey;
|
|
71074
|
+
} catch {
|
|
71075
|
+
return;
|
|
71076
|
+
}
|
|
71077
|
+
}
|
|
71078
|
+
if (key === null) return;
|
|
71038
71079
|
try {
|
|
71039
|
-
const
|
|
71040
|
-
|
|
71080
|
+
const parsedValue = JSON.parse(rawValue);
|
|
71081
|
+
if (typeof parsedValue === "string") {
|
|
71082
|
+
env[key] = parsedValue;
|
|
71083
|
+
}
|
|
71041
71084
|
} catch {
|
|
71042
|
-
return
|
|
71085
|
+
return;
|
|
71043
71086
|
}
|
|
71044
71087
|
}
|
|
71045
|
-
function
|
|
71046
|
-
|
|
71047
|
-
|
|
71048
|
-
|
|
71049
|
-
|
|
71050
|
-
|
|
71088
|
+
function parseExistingEcosystemConfig(text) {
|
|
71089
|
+
if (text === null || text === void 0) {
|
|
71090
|
+
return { kind: "missing" };
|
|
71091
|
+
}
|
|
71092
|
+
let mode = "code";
|
|
71093
|
+
const templateCurlyStack = [];
|
|
71094
|
+
let curlyDepth = 0;
|
|
71095
|
+
let squareDepth = 0;
|
|
71096
|
+
let parenDepth = 0;
|
|
71097
|
+
let moduleExportsOpened = false;
|
|
71098
|
+
let moduleExportsClosed = false;
|
|
71099
|
+
let appsArrayOpened = false;
|
|
71100
|
+
let appsArrayClosed = false;
|
|
71101
|
+
let appCandidateActive = false;
|
|
71102
|
+
let candidateHasName = false;
|
|
71103
|
+
let candidateHasScript = false;
|
|
71104
|
+
let candidateHasArgs = false;
|
|
71105
|
+
let candidateHasEnv = false;
|
|
71106
|
+
let candidateEnvOpenedOnLine = false;
|
|
71107
|
+
let candidateEnvClosed = false;
|
|
71108
|
+
let candidateEnv = null;
|
|
71109
|
+
let matchedAppEnv = null;
|
|
71110
|
+
let matchedAppCount = 0;
|
|
71111
|
+
let recentCode = "";
|
|
71112
|
+
let lineCode = "";
|
|
71113
|
+
const len = text.length;
|
|
71114
|
+
let i = 0;
|
|
71115
|
+
while (i < len) {
|
|
71116
|
+
const ch = text[i] ?? "";
|
|
71117
|
+
if (mode === "line_comment") {
|
|
71118
|
+
if (ch === "\n") {
|
|
71119
|
+
mode = "code";
|
|
71120
|
+
lineCode = "";
|
|
71121
|
+
candidateEnvOpenedOnLine = false;
|
|
71122
|
+
}
|
|
71123
|
+
i++;
|
|
71124
|
+
continue;
|
|
71125
|
+
}
|
|
71126
|
+
if (mode === "block_comment") {
|
|
71127
|
+
if (ch === "*" && i + 1 < len && text[i + 1] === "/") {
|
|
71128
|
+
mode = "code";
|
|
71129
|
+
i += 2;
|
|
71130
|
+
continue;
|
|
71131
|
+
}
|
|
71132
|
+
if (ch === "\n") {
|
|
71133
|
+
lineCode = "";
|
|
71134
|
+
candidateEnvOpenedOnLine = false;
|
|
71135
|
+
}
|
|
71136
|
+
i++;
|
|
71137
|
+
continue;
|
|
71138
|
+
}
|
|
71139
|
+
if (mode === "single_quote") {
|
|
71140
|
+
if (ch === "\\") {
|
|
71141
|
+
i += 2;
|
|
71142
|
+
continue;
|
|
71143
|
+
}
|
|
71144
|
+
if (ch === "'") {
|
|
71145
|
+
mode = "code";
|
|
71146
|
+
i++;
|
|
71147
|
+
continue;
|
|
71148
|
+
}
|
|
71149
|
+
if (ch === "\n" || ch === "\r") {
|
|
71150
|
+
return { kind: "rejected", text };
|
|
71151
|
+
}
|
|
71152
|
+
i++;
|
|
71153
|
+
continue;
|
|
71154
|
+
}
|
|
71155
|
+
if (mode === "double_quote") {
|
|
71156
|
+
if (ch === "\\") {
|
|
71157
|
+
lineCode += ch + (text[i + 1] ?? "");
|
|
71158
|
+
i += 2;
|
|
71159
|
+
continue;
|
|
71160
|
+
}
|
|
71161
|
+
lineCode += ch;
|
|
71162
|
+
if (ch === '"') {
|
|
71163
|
+
mode = "code";
|
|
71164
|
+
if (appCandidateActive && curlyDepth === 2 && squareDepth === 1) {
|
|
71165
|
+
if (/name\s*:\s*"mrrlin-bridge"/.test(lineCode)) candidateHasName = true;
|
|
71166
|
+
if (/script\s*:\s*"mrrlin-mcp"/.test(lineCode)) candidateHasScript = true;
|
|
71167
|
+
if (/args\s*:\s*"director-bridge"/.test(lineCode)) candidateHasArgs = true;
|
|
71168
|
+
}
|
|
71169
|
+
i++;
|
|
71170
|
+
continue;
|
|
71171
|
+
}
|
|
71172
|
+
if (ch === "\n" || ch === "\r") {
|
|
71173
|
+
return { kind: "rejected", text };
|
|
71174
|
+
}
|
|
71175
|
+
i++;
|
|
71176
|
+
continue;
|
|
71177
|
+
}
|
|
71178
|
+
if (mode === "template") {
|
|
71179
|
+
if (ch === "\\") {
|
|
71180
|
+
i += 2;
|
|
71181
|
+
continue;
|
|
71182
|
+
}
|
|
71183
|
+
if (ch === "`") {
|
|
71184
|
+
mode = "code";
|
|
71185
|
+
i++;
|
|
71186
|
+
continue;
|
|
71187
|
+
}
|
|
71188
|
+
if (ch === "$" && i + 1 < len && text[i + 1] === "{") {
|
|
71189
|
+
mode = "code";
|
|
71190
|
+
templateCurlyStack.push(curlyDepth);
|
|
71191
|
+
curlyDepth++;
|
|
71192
|
+
i += 2;
|
|
71193
|
+
continue;
|
|
71194
|
+
}
|
|
71195
|
+
i++;
|
|
71196
|
+
continue;
|
|
71197
|
+
}
|
|
71198
|
+
if (ch === "/" && i + 1 < len) {
|
|
71199
|
+
if (text[i + 1] === "/") {
|
|
71200
|
+
mode = "line_comment";
|
|
71201
|
+
i += 2;
|
|
71202
|
+
continue;
|
|
71203
|
+
}
|
|
71204
|
+
if (text[i + 1] === "*") {
|
|
71205
|
+
mode = "block_comment";
|
|
71206
|
+
i += 2;
|
|
71207
|
+
continue;
|
|
71208
|
+
}
|
|
71209
|
+
return { kind: "rejected", text };
|
|
71210
|
+
}
|
|
71211
|
+
if (ch === "/") {
|
|
71212
|
+
return { kind: "rejected", text };
|
|
71213
|
+
}
|
|
71214
|
+
if (ch === "'") {
|
|
71215
|
+
mode = "single_quote";
|
|
71216
|
+
i++;
|
|
71217
|
+
continue;
|
|
71218
|
+
}
|
|
71219
|
+
if (ch === '"') {
|
|
71220
|
+
mode = "double_quote";
|
|
71221
|
+
lineCode += ch;
|
|
71222
|
+
i++;
|
|
71223
|
+
continue;
|
|
71224
|
+
}
|
|
71225
|
+
if (ch === "`") {
|
|
71226
|
+
mode = "template";
|
|
71227
|
+
i++;
|
|
71228
|
+
continue;
|
|
71229
|
+
}
|
|
71230
|
+
if (ch === "\n") {
|
|
71231
|
+
if (appCandidateActive && candidateHasEnv && !candidateEnvClosed && curlyDepth === 3 && candidateEnv) {
|
|
71232
|
+
parseEnvLine(lineCode, candidateEnv);
|
|
71233
|
+
}
|
|
71234
|
+
lineCode = "";
|
|
71235
|
+
candidateEnvOpenedOnLine = false;
|
|
71236
|
+
recentCode += " ";
|
|
71237
|
+
i++;
|
|
71238
|
+
continue;
|
|
71239
|
+
}
|
|
71240
|
+
lineCode += ch;
|
|
71241
|
+
recentCode += ch;
|
|
71242
|
+
if (ch === "{") {
|
|
71243
|
+
if (curlyDepth === 0 && squareDepth === 0) {
|
|
71244
|
+
if (/module\.exports\s*=\s*\{$/.test(recentCode.trim())) {
|
|
71245
|
+
if (moduleExportsOpened) return { kind: "rejected", text };
|
|
71246
|
+
moduleExportsOpened = true;
|
|
71247
|
+
}
|
|
71248
|
+
} else if (moduleExportsOpened && !moduleExportsClosed && appsArrayOpened && !appsArrayClosed && squareDepth === 1 && curlyDepth === 1) {
|
|
71249
|
+
appCandidateActive = true;
|
|
71250
|
+
candidateHasName = false;
|
|
71251
|
+
candidateHasScript = false;
|
|
71252
|
+
candidateHasArgs = false;
|
|
71253
|
+
candidateHasEnv = false;
|
|
71254
|
+
candidateEnvOpenedOnLine = false;
|
|
71255
|
+
candidateEnvClosed = false;
|
|
71256
|
+
candidateEnv = /* @__PURE__ */ Object.create(null);
|
|
71257
|
+
} else if (appCandidateActive && squareDepth === 1 && curlyDepth === 2) {
|
|
71258
|
+
if (/\benv\s*:\s*\{$/.test(recentCode.trim())) {
|
|
71259
|
+
candidateHasEnv = true;
|
|
71260
|
+
candidateEnvOpenedOnLine = true;
|
|
71261
|
+
}
|
|
71262
|
+
}
|
|
71263
|
+
curlyDepth++;
|
|
71264
|
+
recentCode = "";
|
|
71265
|
+
i++;
|
|
71266
|
+
continue;
|
|
71267
|
+
}
|
|
71268
|
+
if (ch === "}") {
|
|
71269
|
+
if (curlyDepth === 0) return { kind: "rejected", text };
|
|
71270
|
+
if (templateCurlyStack.length > 0 && templateCurlyStack[templateCurlyStack.length - 1] === curlyDepth - 1) {
|
|
71271
|
+
templateCurlyStack.pop();
|
|
71272
|
+
mode = "template";
|
|
71273
|
+
curlyDepth--;
|
|
71274
|
+
recentCode = "";
|
|
71275
|
+
i++;
|
|
71276
|
+
continue;
|
|
71277
|
+
}
|
|
71278
|
+
if (appCandidateActive && candidateHasEnv && !candidateEnvClosed && curlyDepth === 3) {
|
|
71279
|
+
if (candidateEnvOpenedOnLine) {
|
|
71280
|
+
candidateHasEnv = false;
|
|
71281
|
+
}
|
|
71282
|
+
const beforeBrace = lineCode.slice(0, -1);
|
|
71283
|
+
if (beforeBrace.trim() && candidateEnv) {
|
|
71284
|
+
parseEnvLine(beforeBrace, candidateEnv);
|
|
71285
|
+
}
|
|
71286
|
+
candidateEnvClosed = true;
|
|
71287
|
+
} else if (appCandidateActive && curlyDepth === 2 && squareDepth === 1) {
|
|
71288
|
+
if (candidateHasName && candidateHasScript && candidateHasArgs && candidateHasEnv && candidateEnvClosed) {
|
|
71289
|
+
matchedAppCount++;
|
|
71290
|
+
if (matchedAppCount > 1) return { kind: "rejected", text };
|
|
71291
|
+
matchedAppEnv = candidateEnv;
|
|
71292
|
+
}
|
|
71293
|
+
appCandidateActive = false;
|
|
71294
|
+
candidateEnv = null;
|
|
71295
|
+
} else if (moduleExportsOpened && !moduleExportsClosed && curlyDepth === 1 && squareDepth === 0) {
|
|
71296
|
+
moduleExportsClosed = true;
|
|
71297
|
+
}
|
|
71298
|
+
curlyDepth--;
|
|
71299
|
+
recentCode = "";
|
|
71300
|
+
i++;
|
|
71301
|
+
continue;
|
|
71302
|
+
}
|
|
71303
|
+
if (ch === "[") {
|
|
71304
|
+
if (moduleExportsOpened && !moduleExportsClosed && curlyDepth === 1 && squareDepth === 0) {
|
|
71305
|
+
if (/\bapps\s*:\s*\[$/.test(recentCode.trim())) {
|
|
71306
|
+
if (appsArrayOpened) return { kind: "rejected", text };
|
|
71307
|
+
appsArrayOpened = true;
|
|
71308
|
+
}
|
|
71309
|
+
}
|
|
71310
|
+
squareDepth++;
|
|
71311
|
+
recentCode = "";
|
|
71312
|
+
i++;
|
|
71313
|
+
continue;
|
|
71314
|
+
}
|
|
71315
|
+
if (ch === "]") {
|
|
71316
|
+
if (squareDepth === 0) return { kind: "rejected", text };
|
|
71317
|
+
if (moduleExportsOpened && !moduleExportsClosed && appsArrayOpened && squareDepth === 1 && curlyDepth === 1) {
|
|
71318
|
+
appsArrayClosed = true;
|
|
71319
|
+
}
|
|
71320
|
+
squareDepth--;
|
|
71321
|
+
recentCode = "";
|
|
71322
|
+
i++;
|
|
71323
|
+
continue;
|
|
71324
|
+
}
|
|
71325
|
+
if (ch === "(") {
|
|
71326
|
+
parenDepth++;
|
|
71327
|
+
i++;
|
|
71328
|
+
continue;
|
|
71329
|
+
}
|
|
71330
|
+
if (ch === ")") {
|
|
71331
|
+
if (parenDepth === 0) return { kind: "rejected", text };
|
|
71332
|
+
parenDepth--;
|
|
71333
|
+
i++;
|
|
71334
|
+
continue;
|
|
71335
|
+
}
|
|
71336
|
+
i++;
|
|
71337
|
+
}
|
|
71338
|
+
if (mode !== "code") return { kind: "rejected", text };
|
|
71339
|
+
if (curlyDepth !== 0 || squareDepth !== 0 || parenDepth !== 0) return { kind: "rejected", text };
|
|
71340
|
+
if (!moduleExportsOpened || !moduleExportsClosed) return { kind: "rejected", text };
|
|
71341
|
+
if (!appsArrayOpened || !appsArrayClosed) return { kind: "rejected", text };
|
|
71342
|
+
if (matchedAppCount !== 1 || !matchedAppEnv) return { kind: "rejected", text };
|
|
71343
|
+
return { kind: "accepted", env: matchedAppEnv, text };
|
|
71344
|
+
}
|
|
71345
|
+
var CURATED_KEYS = [
|
|
71346
|
+
"CODEX_HOME",
|
|
71347
|
+
"CLAUDE_CONFIG_DIR",
|
|
71348
|
+
"MRRLIN_DIRECTOR_BRIDGE_LOG",
|
|
71349
|
+
"MRRLIN_API_BASE_URL",
|
|
71350
|
+
"MRRLIN_API_ALLOW_REMOTE",
|
|
71351
|
+
"MRRLIN_STAGING"
|
|
71352
|
+
];
|
|
71353
|
+
function mergeConfigEnv(depsEnv, carriedEnv) {
|
|
71354
|
+
const isWin = process.platform === "win32";
|
|
71355
|
+
const DENIED_CARRIED_KEYS = new Set(isWin ? ["HOME", "PATH", "USER", "USERNAME"] : ["HOME", "PATH", "USER"]);
|
|
71356
|
+
const mergedEnv = /* @__PURE__ */ Object.create(null);
|
|
71357
|
+
const preservedNames = [];
|
|
71358
|
+
const droppedNames = [];
|
|
71359
|
+
const carriedKeys = Object.keys(carriedEnv);
|
|
71360
|
+
for (const key of carriedKeys) {
|
|
71361
|
+
if (DENIED_CARRIED_KEYS.has(key)) {
|
|
71362
|
+
droppedNames.push(key);
|
|
71363
|
+
continue;
|
|
71364
|
+
}
|
|
71365
|
+
const envVal = depsEnv[key];
|
|
71366
|
+
if (Object.hasOwn(depsEnv, key) && envVal !== void 0) {
|
|
71367
|
+
let installerVal = envVal;
|
|
71368
|
+
if (key === "CODEX_HOME" || key === "CLAUDE_CONFIG_DIR" || key === "MRRLIN_API_BASE_URL") {
|
|
71369
|
+
installerVal = installerVal.trim();
|
|
71370
|
+
}
|
|
71371
|
+
if (installerVal === "") {
|
|
71372
|
+
droppedNames.push(key);
|
|
71373
|
+
} else {
|
|
71374
|
+
preservedNames.push(key);
|
|
71375
|
+
mergedEnv[key] = installerVal;
|
|
71376
|
+
}
|
|
71377
|
+
} else {
|
|
71378
|
+
const carriedVal = carriedEnv[key];
|
|
71379
|
+
if (carriedVal !== void 0) {
|
|
71380
|
+
preservedNames.push(key);
|
|
71381
|
+
mergedEnv[key] = carriedVal;
|
|
71382
|
+
}
|
|
71383
|
+
}
|
|
71384
|
+
}
|
|
71385
|
+
for (const key of CURATED_KEYS) {
|
|
71386
|
+
if (Object.hasOwn(carriedEnv, key)) continue;
|
|
71387
|
+
const envVal = depsEnv[key];
|
|
71388
|
+
if (Object.hasOwn(depsEnv, key) && envVal !== void 0) {
|
|
71389
|
+
let val = envVal;
|
|
71390
|
+
if (key === "CODEX_HOME" || key === "CLAUDE_CONFIG_DIR" || key === "MRRLIN_API_BASE_URL") {
|
|
71391
|
+
val = val.trim();
|
|
71392
|
+
}
|
|
71393
|
+
if (val !== "") {
|
|
71394
|
+
mergedEnv[key] = val;
|
|
71395
|
+
}
|
|
71396
|
+
} else {
|
|
71397
|
+
if (key === "MRRLIN_DIRECTOR_BRIDGE_LOG") {
|
|
71398
|
+
mergedEnv[key] = "1";
|
|
71399
|
+
}
|
|
71400
|
+
}
|
|
71401
|
+
}
|
|
71402
|
+
preservedNames.sort();
|
|
71403
|
+
droppedNames.sort();
|
|
71404
|
+
return { mergedEnv, preservedNames, droppedNames };
|
|
71051
71405
|
}
|
|
71052
|
-
function
|
|
71053
|
-
|
|
71054
|
-
|
|
71055
|
-
|
|
71056
|
-
|
|
71057
|
-
|
|
71058
|
-
return normalizeServiceApiTarget(apiBaseUrl, readEnvString(existing, "MRRLIN_API_ALLOW_REMOTE") === "1");
|
|
71406
|
+
function deriveMergedApiRouting(mergedEnv, invokingBridgeUrl) {
|
|
71407
|
+
const result = /* @__PURE__ */ Object.create(null);
|
|
71408
|
+
for (const k of Object.keys(mergedEnv)) {
|
|
71409
|
+
const v = mergedEnv[k];
|
|
71410
|
+
if (v !== void 0) {
|
|
71411
|
+
result[k] = v;
|
|
71059
71412
|
}
|
|
71060
|
-
|
|
71061
|
-
|
|
71413
|
+
}
|
|
71414
|
+
if (Object.hasOwn(result, "MRRLIN_API_BASE_URL")) {
|
|
71415
|
+
const rawApi = result["MRRLIN_API_BASE_URL"];
|
|
71416
|
+
if (rawApi === "") {
|
|
71417
|
+
result["MRRLIN_API_BASE_URL"] = "";
|
|
71418
|
+
} else if (rawApi !== void 0) {
|
|
71419
|
+
const retargeted = retargetRetiredApiBaseUrl(rawApi).baseUrl;
|
|
71420
|
+
result["MRRLIN_API_BASE_URL"] = retargeted;
|
|
71421
|
+
}
|
|
71422
|
+
} else {
|
|
71423
|
+
if (result["MRRLIN_STAGING"] === "1") {
|
|
71424
|
+
result["MRRLIN_API_BASE_URL"] = STAGING_API_BASE_URL;
|
|
71425
|
+
} else if (bridgeUrlImpliesStaging(invokingBridgeUrl)) {
|
|
71426
|
+
result["MRRLIN_API_BASE_URL"] = STAGING_API_BASE_URL;
|
|
71062
71427
|
}
|
|
71063
|
-
return void 0;
|
|
71064
|
-
} catch {
|
|
71065
|
-
return void 0;
|
|
71066
71428
|
}
|
|
71429
|
+
return result;
|
|
71430
|
+
}
|
|
71431
|
+
function escapeRegex2(s) {
|
|
71432
|
+
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
71067
71433
|
}
|
|
71068
|
-
function
|
|
71069
|
-
|
|
71070
|
-
|
|
71071
|
-
|
|
71072
|
-
|
|
71434
|
+
function performConfigBackup(deps, ecoPath, existingText) {
|
|
71435
|
+
try {
|
|
71436
|
+
if (!deps.listDir || !deps.writeExclusiveFile) {
|
|
71437
|
+
deps.log("Service config backup failed.");
|
|
71438
|
+
return;
|
|
71439
|
+
}
|
|
71440
|
+
const dir = import_node_path38.default.dirname(ecoPath);
|
|
71441
|
+
let files;
|
|
71442
|
+
try {
|
|
71443
|
+
files = deps.listDir(dir);
|
|
71444
|
+
} catch {
|
|
71445
|
+
deps.log("Service config backup failed.");
|
|
71446
|
+
return;
|
|
71447
|
+
}
|
|
71448
|
+
if (!files || !Array.isArray(files)) {
|
|
71449
|
+
deps.log("Service config backup failed.");
|
|
71450
|
+
return;
|
|
71451
|
+
}
|
|
71452
|
+
const base = import_node_path38.default.basename(ecoPath);
|
|
71453
|
+
const backupRegex = new RegExp(`^${escapeRegex2(base)}\\.bak-\\d{4}-\\d{2}-\\d{2}T\\d{2}-\\d{2}-\\d{2}-\\d{3}Z$`);
|
|
71454
|
+
const existingBackups = files.filter((f) => backupRegex.test(f));
|
|
71455
|
+
if (existingBackups.length >= 10) {
|
|
71456
|
+
deps.log("Service config backup failed.");
|
|
71457
|
+
return;
|
|
71458
|
+
}
|
|
71459
|
+
let now;
|
|
71460
|
+
try {
|
|
71461
|
+
now = deps.clock ? deps.clock() : /* @__PURE__ */ new Date();
|
|
71462
|
+
} catch {
|
|
71463
|
+
deps.log("Service config backup failed.");
|
|
71464
|
+
return;
|
|
71465
|
+
}
|
|
71466
|
+
let iso;
|
|
71467
|
+
try {
|
|
71468
|
+
iso = now.toISOString();
|
|
71469
|
+
} catch {
|
|
71470
|
+
deps.log("Service config backup failed.");
|
|
71471
|
+
return;
|
|
71472
|
+
}
|
|
71473
|
+
if (!/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/.test(iso)) {
|
|
71474
|
+
deps.log("Service config backup failed.");
|
|
71475
|
+
return;
|
|
71476
|
+
}
|
|
71477
|
+
const ts = iso.replace(/:/g, "-").replace(/\./g, "-");
|
|
71478
|
+
const backupPath = `${ecoPath}.bak-${ts}`;
|
|
71479
|
+
deps.writeExclusiveFile(backupPath, existingText);
|
|
71480
|
+
} catch {
|
|
71481
|
+
deps.log("Service config backup failed.");
|
|
71073
71482
|
}
|
|
71074
|
-
return readExistingServiceApiTarget(deps, ecoPath) ?? {};
|
|
71075
71483
|
}
|
|
71076
71484
|
var SYSTEM_PATH_DIRS = ["/usr/bin", "/bin", "/usr/sbin", "/sbin"];
|
|
71077
71485
|
function defaultHomeOwnerUid(home) {
|
|
@@ -71147,19 +71555,34 @@ function installService(deps) {
|
|
|
71147
71555
|
/* @__PURE__ */ new Set([...resolvedBins.map((b) => import_node_path38.default.dirname(b)), ...systemDirs])
|
|
71148
71556
|
).join(import_node_path38.default.delimiter);
|
|
71149
71557
|
const ecoPath = import_node_path38.default.join(home, ".mrrlin", "ecosystem.config.cjs");
|
|
71150
|
-
const
|
|
71558
|
+
const existingText = deps.readFile ? deps.readFile(ecoPath) : null;
|
|
71559
|
+
const parseResult = parseExistingEcosystemConfig(existingText);
|
|
71560
|
+
if (parseResult.kind === "rejected") {
|
|
71561
|
+
deps.log("Service config env carry skipped.");
|
|
71562
|
+
}
|
|
71563
|
+
if (existingText !== null && existingText !== void 0) {
|
|
71564
|
+
performConfigBackup(deps, ecoPath, existingText);
|
|
71565
|
+
}
|
|
71566
|
+
const carriedEnv = parseResult.kind === "accepted" ? parseResult.env : /* @__PURE__ */ Object.create(null);
|
|
71567
|
+
const { mergedEnv, preservedNames, droppedNames } = mergeConfigEnv(deps.env, carriedEnv);
|
|
71568
|
+
const routedEnv = deriveMergedApiRouting(mergedEnv, deps.env.MRRLIN_BRIDGE_URL);
|
|
71569
|
+
routedEnv.HOME = home;
|
|
71570
|
+
routedEnv.PATH = pathEnv;
|
|
71571
|
+
if (user !== void 0) {
|
|
71572
|
+
routedEnv.USER = user;
|
|
71573
|
+
}
|
|
71574
|
+
if (preservedNames.length > 0) {
|
|
71575
|
+
deps.log(`Service env preserved: ${preservedNames.join(", ")}.`);
|
|
71576
|
+
}
|
|
71577
|
+
if (droppedNames.length > 0) {
|
|
71578
|
+
deps.log(`Service env dropped: ${droppedNames.join(", ")}.`);
|
|
71579
|
+
}
|
|
71151
71580
|
const text = renderEcosystemConfig({
|
|
71152
71581
|
cwd: resolved.cwd,
|
|
71153
|
-
|
|
71154
|
-
user,
|
|
71155
|
-
codexHome: deps.env.CODEX_HOME?.trim() || void 0,
|
|
71156
|
-
claudeConfigDir: deps.env.CLAUDE_CONFIG_DIR?.trim() || void 0,
|
|
71157
|
-
pathEnv,
|
|
71158
|
-
apiBaseUrl: apiTarget.apiBaseUrl,
|
|
71159
|
-
apiAllowRemote: apiTarget.apiAllowRemote
|
|
71582
|
+
env: routedEnv
|
|
71160
71583
|
});
|
|
71161
71584
|
deps.writeFile(ecoPath, text);
|
|
71162
|
-
const start = deps.runPm2(["startOrReload", ecoPath, "--
|
|
71585
|
+
const start = deps.runPm2(["startOrReload", ecoPath, "--update-env"]);
|
|
71163
71586
|
if (start.code !== 0) {
|
|
71164
71587
|
deps.log(`pm2 startOrReload failed (exit ${start.code}).`);
|
|
71165
71588
|
return { ok: false };
|
|
@@ -71782,6 +72205,15 @@ async function main() {
|
|
|
71782
72205
|
(0, import_node_fs25.mkdirSync)(import_node_path42.default.dirname(p), { recursive: true, mode: 448 });
|
|
71783
72206
|
(0, import_node_fs25.writeFileSync)(p, c, { mode: 384 });
|
|
71784
72207
|
},
|
|
72208
|
+
writeExclusiveFile: (p, c) => (0, import_node_fs25.writeFileSync)(p, c, { flag: "wx", mode: 384 }),
|
|
72209
|
+
listDir: (p) => {
|
|
72210
|
+
try {
|
|
72211
|
+
return (0, import_node_fs25.readdirSync)(p);
|
|
72212
|
+
} catch {
|
|
72213
|
+
return null;
|
|
72214
|
+
}
|
|
72215
|
+
},
|
|
72216
|
+
clock: () => /* @__PURE__ */ new Date(),
|
|
71785
72217
|
// Swallows every error on purpose — the only caller uses this to recover settings from the
|
|
71786
72218
|
// config it is about to overwrite, and a missing or unreadable file means "no previous
|
|
71787
72219
|
// value", never a failed install. See readExistingTelemetryDefaultProject.
|