metheus-governance-mcp-cli 0.2.42 → 0.2.44
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/cli.mjs +55 -14
- package/package.json +1 -1
package/cli.mjs
CHANGED
|
@@ -683,12 +683,18 @@ function resolveWorkspaceDirForRequest(defaultWorkspaceDir, requestObj, toolArgs
|
|
|
683
683
|
if (strongRequestResolved) {
|
|
684
684
|
return strongRequestResolved;
|
|
685
685
|
}
|
|
686
|
-
if (strongEnvResolved) {
|
|
687
|
-
return strongEnvResolved;
|
|
688
|
-
}
|
|
689
686
|
if (weakRequestResolved) {
|
|
687
|
+
// Prefer client-provided current workspace over fallback env, unless request resolves to home.
|
|
688
|
+
if (isHomeWorkspaceRoot(weakRequestResolved)) {
|
|
689
|
+
if (strongEnvResolved && !isHomeWorkspaceRoot(strongEnvResolved)) {
|
|
690
|
+
return strongEnvResolved;
|
|
691
|
+
}
|
|
692
|
+
}
|
|
690
693
|
return weakRequestResolved;
|
|
691
694
|
}
|
|
695
|
+
if (strongEnvResolved) {
|
|
696
|
+
return strongEnvResolved;
|
|
697
|
+
}
|
|
692
698
|
|
|
693
699
|
const localPreferredCandidates = [
|
|
694
700
|
defaultWorkspaceDir,
|
|
@@ -2749,11 +2755,11 @@ function syncCtxpackToLocalCache({
|
|
|
2749
2755
|
? metaPath
|
|
2750
2756
|
: path.join(resolvedWorkspaceDir, CTXPACK_META_FILENAME);
|
|
2751
2757
|
|
|
2752
|
-
if (!workspaceSignalTrusted
|
|
2758
|
+
if (!workspaceSignalTrusted) {
|
|
2753
2759
|
return {
|
|
2754
2760
|
sync_status: "guarded",
|
|
2755
2761
|
sync_message:
|
|
2756
|
-
"Workspace signal is missing in auto mode. Guardrail blocked ctxpack local write
|
|
2762
|
+
"Workspace signal is missing in auto mode. Guardrail blocked ctxpack local write.",
|
|
2757
2763
|
local_path: cacheDir,
|
|
2758
2764
|
workspace_path: resolvedWorkspaceDir,
|
|
2759
2765
|
local_file_count: 0,
|
|
@@ -3632,6 +3638,15 @@ function shouldUseSafeToolAliasesForClient(initParamsRaw) {
|
|
|
3632
3638
|
return name.includes("cursor") || name.includes("antigravity");
|
|
3633
3639
|
}
|
|
3634
3640
|
|
|
3641
|
+
function canTrustProcessCwdForClient(clientNameRaw) {
|
|
3642
|
+
const name = String(clientNameRaw || "").trim().toLowerCase();
|
|
3643
|
+
if (!name) return false;
|
|
3644
|
+
// Codex app-server may not pass workspace signals reliably; never trust bare process.cwd().
|
|
3645
|
+
if (name.includes("codex")) return false;
|
|
3646
|
+
// VS Code forks generally spawn MCP in active workspace folder.
|
|
3647
|
+
return name.includes("cursor") || name.includes("antigravity");
|
|
3648
|
+
}
|
|
3649
|
+
|
|
3635
3650
|
function displayToolNameForClient(canonicalName, useSafeToolAliases = false) {
|
|
3636
3651
|
const canonical = String(canonicalName || "").trim();
|
|
3637
3652
|
if (!canonical) return "";
|
|
@@ -4216,6 +4231,7 @@ async function runProxy(flags) {
|
|
|
4216
4231
|
let sessionUseSafeToolAliases = false;
|
|
4217
4232
|
let sessionToolAliasToCanonical = new Map();
|
|
4218
4233
|
let sessionToolCanonicalToAlias = new Map();
|
|
4234
|
+
let sessionClientName = "";
|
|
4219
4235
|
|
|
4220
4236
|
// Proxy-initiated requests (e.g., roots/list) pending client responses.
|
|
4221
4237
|
const pendingProxyRequests = new Map(); // id → callback(responseObj)
|
|
@@ -4347,8 +4363,13 @@ async function runProxy(flags) {
|
|
|
4347
4363
|
return;
|
|
4348
4364
|
}
|
|
4349
4365
|
|
|
4350
|
-
if (isJsonRpcMethod(requestObj, "initialize")
|
|
4351
|
-
|
|
4366
|
+
if (isJsonRpcMethod(requestObj, "initialize")) {
|
|
4367
|
+
const initParams = safeObject(requestObj?.params);
|
|
4368
|
+
const initClientInfo = safeObject(initParams.clientInfo);
|
|
4369
|
+
sessionClientName = String(initClientInfo.name || "").trim().toLowerCase();
|
|
4370
|
+
if (shouldUseSafeToolAliasesForClient(initParams)) {
|
|
4371
|
+
sessionUseSafeToolAliases = true;
|
|
4372
|
+
}
|
|
4352
4373
|
}
|
|
4353
4374
|
if (sessionUseSafeToolAliases) {
|
|
4354
4375
|
requestObj = rewriteAliasedToolCallToCanonical(requestObj, sessionToolAliasToCanonical);
|
|
@@ -4374,10 +4395,13 @@ async function runProxy(flags) {
|
|
|
4374
4395
|
}
|
|
4375
4396
|
if (!sessionWorkspaceDir) {
|
|
4376
4397
|
const currentCwdCandidate = sanitizeWorkspaceCandidate(process.cwd());
|
|
4377
|
-
if (
|
|
4398
|
+
if (
|
|
4399
|
+
currentCwdCandidate &&
|
|
4400
|
+
!isHomeWorkspaceRoot(currentCwdCandidate) &&
|
|
4401
|
+
canTrustProcessCwdForClient(sessionClientName)
|
|
4402
|
+
) {
|
|
4378
4403
|
sessionWorkspaceDir = currentCwdCandidate;
|
|
4379
|
-
//
|
|
4380
|
-
// when spawning MCP server processes, so treat plausible cwd as trusted.
|
|
4404
|
+
// For selected clients, process cwd is a valid workspace signal.
|
|
4381
4405
|
sessionWorkspaceTrusted = true;
|
|
4382
4406
|
}
|
|
4383
4407
|
}
|
|
@@ -4388,9 +4412,12 @@ async function runProxy(flags) {
|
|
|
4388
4412
|
}
|
|
4389
4413
|
}
|
|
4390
4414
|
}
|
|
4415
|
+
const hasWeakRequestWorkspaceSignal =
|
|
4416
|
+
Boolean(weakRequestWorkspaceCandidate) && !isHomeWorkspaceRoot(weakRequestWorkspaceCandidate);
|
|
4391
4417
|
const workspaceSignalTrusted =
|
|
4392
4418
|
args.explicitPinnedWorkspace ||
|
|
4393
4419
|
sessionWorkspaceTrusted ||
|
|
4420
|
+
hasWeakRequestWorkspaceSignal ||
|
|
4394
4421
|
Boolean(strongRequestWorkspaceCandidate || strongEnvWorkspaceCandidate);
|
|
4395
4422
|
const requestWorkspaceDir = args.explicitPinnedWorkspace
|
|
4396
4423
|
? resolveWorkspaceDir(args.workspaceDir || process.cwd())
|
|
@@ -5149,13 +5176,9 @@ function runSetupInternal(flags, options = {}) {
|
|
|
5149
5176
|
const transport = getRegisteredTransport(cliBin, context.serverName);
|
|
5150
5177
|
if (transport) {
|
|
5151
5178
|
const existingWorkspaceDir = extractWorkspaceDirArg(transport.args);
|
|
5152
|
-
const existingEnv = safeObject(transport.env);
|
|
5153
|
-
const existingWorkspaceEnv = String(existingEnv.METHEUS_WORKSPACE_DIR || "").trim();
|
|
5154
5179
|
if (existingWorkspaceDir && !isAutoWorkspaceMode(existingWorkspaceDir)) {
|
|
5155
5180
|
proxyArgsForRegister = withWorkspaceDirArg(proxyArgsForRegister, existingWorkspaceDir);
|
|
5156
5181
|
workspaceEnvForRegister = "";
|
|
5157
|
-
} else if (!workspaceEnvForRegister && existingWorkspaceEnv) {
|
|
5158
|
-
workspaceEnvForRegister = resolveWorkspaceDir(existingWorkspaceEnv);
|
|
5159
5182
|
}
|
|
5160
5183
|
}
|
|
5161
5184
|
}
|
|
@@ -5266,10 +5289,21 @@ function runSelftest(flags = {}) {
|
|
|
5266
5289
|
const originalWorkspaceEnv = process.env.METHEUS_WORKSPACE_DIR;
|
|
5267
5290
|
const forcedEnvWorkspace = path.join(tempRoot, "forced-workspace");
|
|
5268
5291
|
const defaultWorkspace = path.join(tempRoot, "default-workspace");
|
|
5292
|
+
const weakRequestWorkspace = path.join(tempRoot, "weak-request-workspace");
|
|
5269
5293
|
fs.mkdirSync(forcedEnvWorkspace, { recursive: true });
|
|
5270
5294
|
fs.mkdirSync(defaultWorkspace, { recursive: true });
|
|
5295
|
+
fs.mkdirSync(weakRequestWorkspace, { recursive: true });
|
|
5271
5296
|
process.env.METHEUS_WORKSPACE_DIR = forcedEnvWorkspace;
|
|
5272
5297
|
const resolvedByEnvPriority = resolveWorkspaceDirForRequest(defaultWorkspace, {}, {});
|
|
5298
|
+
const resolvedByWeakRequestPriority = resolveWorkspaceDirForRequest(
|
|
5299
|
+
defaultWorkspace,
|
|
5300
|
+
{
|
|
5301
|
+
params: {
|
|
5302
|
+
cwd: weakRequestWorkspace,
|
|
5303
|
+
},
|
|
5304
|
+
},
|
|
5305
|
+
{},
|
|
5306
|
+
);
|
|
5273
5307
|
if (typeof originalWorkspaceEnv === "string") {
|
|
5274
5308
|
process.env.METHEUS_WORKSPACE_DIR = originalWorkspaceEnv;
|
|
5275
5309
|
} else {
|
|
@@ -5282,6 +5316,13 @@ function runSelftest(flags = {}) {
|
|
|
5282
5316
|
envPriorityOk,
|
|
5283
5317
|
`env=${forcedEnvWorkspace} default=${defaultWorkspace} resolved=${resolvedByEnvPriority || "(none)"}`,
|
|
5284
5318
|
);
|
|
5319
|
+
const weakRequestPriorityOk =
|
|
5320
|
+
normalizedPathForCompare(resolvedByWeakRequestPriority) === normalizedPathForCompare(weakRequestWorkspace);
|
|
5321
|
+
push(
|
|
5322
|
+
"workspace_weak_request_priority_over_env",
|
|
5323
|
+
weakRequestPriorityOk,
|
|
5324
|
+
`request=${weakRequestWorkspace} env=${forcedEnvWorkspace} resolved=${resolvedByWeakRequestPriority || "(none)"}`,
|
|
5325
|
+
);
|
|
5285
5326
|
} catch (err) {
|
|
5286
5327
|
push("workspace_env_guard_test_setup", false, String(err?.message || err));
|
|
5287
5328
|
} finally {
|