metheus-governance-mcp-cli 0.2.17 → 0.2.18
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/README.md +13 -2
- package/cli.mjs +115 -22
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -37,6 +37,8 @@ metheus-governance-mcp-cli setup --project-id <project_uuid> --ctxpack-key "<ctx
|
|
|
37
37
|
```
|
|
38
38
|
|
|
39
39
|
`project-id` can be omitted if your current folder (or parent) has `.metheus_ctxpack_sync.json`.
|
|
40
|
+
`setup` defaults to `--workspace-dir auto` (dynamic workspace detection).
|
|
41
|
+
Use an explicit path only when you intentionally want a fixed workspace.
|
|
40
42
|
|
|
41
43
|
Recommended for Codex/Claude multi-workspace sessions:
|
|
42
44
|
|
|
@@ -44,6 +46,15 @@ Recommended for Codex/Claude multi-workspace sessions:
|
|
|
44
46
|
metheus-governance-mcp-cli setup --project-id <project_uuid> --ctxpack-key "<ctxpack_key>" --base-url https://metheus.gesiaplatform.com --workspace-dir auto
|
|
45
47
|
```
|
|
46
48
|
|
|
49
|
+
When a client does not send workspace metadata (for example some Codex sessions),
|
|
50
|
+
set a stable fallback root once:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
metheus-governance-mcp-cli setup --project-id <project_uuid> --ctxpack-key "<ctxpack_key>" --base-url https://metheus.gesiaplatform.com --workspace-dir auto --workspace-fallback-dir C:\code_test
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
This registers `METHEUS_WORKSPACE_DIR` for Codex MCP so ctxpack sync still resolves safely.
|
|
57
|
+
|
|
47
58
|
Guardrail note:
|
|
48
59
|
- By default, CLI blocks reading/writing ctxpack sync metadata when workspace root resolves to the home directory.
|
|
49
60
|
- Override only when intentional: `METHEUS_ALLOW_HOME_WORKSPACE=1`.
|
|
@@ -93,8 +104,8 @@ These tools accept `project_id` and return:
|
|
|
93
104
|
- missing local cache -> download
|
|
94
105
|
- same version -> keep current
|
|
95
106
|
- newer server version -> update local cache
|
|
96
|
-
- workspace path ->
|
|
97
|
-
- use `--workspace-dir
|
|
107
|
+
- workspace path -> auto-detected from client metadata/env by default
|
|
108
|
+
- use `--workspace-fallback-dir <path>` when client metadata is unavailable
|
|
98
109
|
|
|
99
110
|
Ctxpack merge safety flow:
|
|
100
111
|
- call `ctxpack.merge.brief` first
|
package/cli.mjs
CHANGED
|
@@ -38,7 +38,7 @@ function printUsage() {
|
|
|
38
38
|
"Usage:",
|
|
39
39
|
` ${cmd} [--project-id <uuid>] [--ctxpack-key <key>] [--base-url <url>] [--workspace-dir <path|auto>] [--flow <auto|device|callback|manual>]`,
|
|
40
40
|
` ${cmd} init [--project-id <uuid>] [--ctxpack-key <key>] [--base-url <url>] [--flow <auto|device|callback|manual>]`,
|
|
41
|
-
` ${cmd} setup [--project-id <uuid>] [--ctxpack-key <key>] [--base-url <url>] [--workspace-dir <path|auto>] [--name <server_name>]`,
|
|
41
|
+
` ${cmd} setup [--project-id <uuid>] [--ctxpack-key <key>] [--base-url <url>] [--workspace-dir <path|auto>] [--workspace-fallback-dir <path>] [--name <server_name>]`,
|
|
42
42
|
` ${cmd} doctor [--project-id <uuid>] [--ctxpack-key <key>] [--base-url <url>] [--timeout-seconds <n>]`,
|
|
43
43
|
` ${cmd} proxy [--project-id <uuid>] [--ctxpack-key <key>] [--base-url <url>] [--workspace-dir <path|auto>] [--include-drafts <true|false>] [--auto-pull-on-conflict <true|false>] [--timeout-seconds <n>]`,
|
|
44
44
|
` ${cmd} ctxpack pull [--project-id <uuid>] [--base-url <url>] [--workspace-dir <path|auto>] [--paths <csv>] [--timeout-seconds <n>]`,
|
|
@@ -365,7 +365,7 @@ function extractWorkspaceCandidateFromFolders(rawFolders) {
|
|
|
365
365
|
return "";
|
|
366
366
|
}
|
|
367
367
|
|
|
368
|
-
function
|
|
368
|
+
function extractStrongWorkspaceCandidateFromRequest(requestObj, toolArgs) {
|
|
369
369
|
const params = safeObject(requestObj?.params);
|
|
370
370
|
const meta = safeObject(params._meta);
|
|
371
371
|
const workspaceFromFolders = firstNonEmptyString([
|
|
@@ -381,13 +381,23 @@ function extractWorkspaceCandidateFromRequest(requestObj, toolArgs) {
|
|
|
381
381
|
args.workspaceDir,
|
|
382
382
|
params.workspace_dir,
|
|
383
383
|
params.workspaceDir,
|
|
384
|
+
meta.workspace_dir,
|
|
385
|
+
meta.workspaceDir,
|
|
386
|
+
]);
|
|
387
|
+
return sanitizeWorkspaceCandidate(rawCandidate);
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
function extractWorkspaceCandidateFromRequest(requestObj, toolArgs) {
|
|
391
|
+
const strongCandidate = extractStrongWorkspaceCandidateFromRequest(requestObj, toolArgs);
|
|
392
|
+
if (strongCandidate) return strongCandidate;
|
|
393
|
+
const params = safeObject(requestObj?.params);
|
|
394
|
+
const meta = safeObject(params._meta);
|
|
395
|
+
const rawCandidate = firstNonEmptyString([
|
|
384
396
|
params.cwd,
|
|
385
397
|
params.root_path,
|
|
386
398
|
params.rootPath,
|
|
387
399
|
params.root_uri,
|
|
388
400
|
params.rootUri,
|
|
389
|
-
meta.workspace_dir,
|
|
390
|
-
meta.workspaceDir,
|
|
391
401
|
meta.cwd,
|
|
392
402
|
meta.root_path,
|
|
393
403
|
meta.rootPath,
|
|
@@ -397,13 +407,22 @@ function extractWorkspaceCandidateFromRequest(requestObj, toolArgs) {
|
|
|
397
407
|
return sanitizeWorkspaceCandidate(rawCandidate);
|
|
398
408
|
}
|
|
399
409
|
|
|
400
|
-
function
|
|
410
|
+
function extractStrongWorkspaceCandidateFromEnv() {
|
|
401
411
|
const rawCandidate = firstNonEmptyString([
|
|
402
412
|
process.env.METHEUS_WORKSPACE_DIR,
|
|
413
|
+
process.env.METHEUS_WORKSPACE_URI,
|
|
414
|
+
process.env.CODEX_WORKSPACE_DIR,
|
|
415
|
+
process.env.CODEX_WORKSPACE_URI,
|
|
403
416
|
process.env.CLAUDE_WORKSPACE_DIR,
|
|
404
417
|
process.env.CLAUDE_WORKSPACE_URI,
|
|
405
418
|
process.env.CLAUDE_PROJECT_DIR,
|
|
406
|
-
|
|
419
|
+
]);
|
|
420
|
+
return sanitizeWorkspaceCandidate(rawCandidate);
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
function extractWorkspaceCandidateFromEnv() {
|
|
424
|
+
const rawCandidate = firstNonEmptyString([
|
|
425
|
+
extractStrongWorkspaceCandidateFromEnv(),
|
|
407
426
|
process.env.WORKSPACE_DIR,
|
|
408
427
|
process.env.WORKSPACE_FOLDER,
|
|
409
428
|
process.env.VSCODE_WORKSPACE_FOLDER,
|
|
@@ -2436,7 +2455,13 @@ function hasAllCtxpackFiles(baseDir, files) {
|
|
|
2436
2455
|
return true;
|
|
2437
2456
|
}
|
|
2438
2457
|
|
|
2439
|
-
function syncCtxpackToLocalCache({
|
|
2458
|
+
function syncCtxpackToLocalCache({
|
|
2459
|
+
siteBaseURL,
|
|
2460
|
+
projectID,
|
|
2461
|
+
ctxpack,
|
|
2462
|
+
workspaceDir,
|
|
2463
|
+
workspaceSignalTrusted = true,
|
|
2464
|
+
}) {
|
|
2440
2465
|
const ctxpackID = String(ctxpack?.ctxpack_id || "").trim();
|
|
2441
2466
|
const version = String(ctxpack?.version || "").trim();
|
|
2442
2467
|
const versionID = String(ctxpack?.version_id || ctxpack?.current_version_id || "").trim();
|
|
@@ -2458,6 +2483,17 @@ function syncCtxpackToLocalCache({ siteBaseURL, projectID, ctxpack, workspaceDir
|
|
|
2458
2483
|
};
|
|
2459
2484
|
}
|
|
2460
2485
|
|
|
2486
|
+
if (!workspaceSignalTrusted) {
|
|
2487
|
+
return {
|
|
2488
|
+
sync_status: "guarded",
|
|
2489
|
+
sync_message:
|
|
2490
|
+
"Workspace signal is missing in auto mode. Guardrail blocked ctxpack local write to avoid wrong folder sync.",
|
|
2491
|
+
local_path: cacheDir,
|
|
2492
|
+
workspace_path: resolvedWorkspaceDir,
|
|
2493
|
+
local_file_count: 0,
|
|
2494
|
+
};
|
|
2495
|
+
}
|
|
2496
|
+
|
|
2461
2497
|
if (!ctxpackID || !version || files.length === 0) {
|
|
2462
2498
|
return {
|
|
2463
2499
|
sync_status: "not_available",
|
|
@@ -2542,6 +2578,7 @@ async function loadProjectSummaryForTool({
|
|
|
2542
2578
|
syncCtxpackLocal,
|
|
2543
2579
|
workspaceDir,
|
|
2544
2580
|
ctxpackPaths,
|
|
2581
|
+
workspaceSignalTrusted = true,
|
|
2545
2582
|
}) {
|
|
2546
2583
|
const encodedProjectID = encodeURIComponent(projectID);
|
|
2547
2584
|
let projectRaw = null;
|
|
@@ -2607,6 +2644,7 @@ async function loadProjectSummaryForTool({
|
|
|
2607
2644
|
projectID,
|
|
2608
2645
|
ctxpack,
|
|
2609
2646
|
workspaceDir,
|
|
2647
|
+
workspaceSignalTrusted,
|
|
2610
2648
|
});
|
|
2611
2649
|
ctxpackSyncStatus = syncResult.sync_status || "error";
|
|
2612
2650
|
ctxpackSyncMessage = String(syncResult.sync_message || "").trim();
|
|
@@ -3267,6 +3305,7 @@ async function maybeAutoSyncCtxpackForCall({
|
|
|
3267
3305
|
args,
|
|
3268
3306
|
token,
|
|
3269
3307
|
workspaceDir,
|
|
3308
|
+
workspaceSignalTrusted = true,
|
|
3270
3309
|
}) {
|
|
3271
3310
|
if (!isJsonRpcMethod(requestObj, "tools/call")) return null;
|
|
3272
3311
|
if (!token) return null;
|
|
@@ -3298,6 +3337,7 @@ async function maybeAutoSyncCtxpackForCall({
|
|
|
3298
3337
|
includeCtxpack: true,
|
|
3299
3338
|
syncCtxpackLocal: true,
|
|
3300
3339
|
workspaceDir: workspacePath,
|
|
3340
|
+
workspaceSignalTrusted,
|
|
3301
3341
|
});
|
|
3302
3342
|
} catch {
|
|
3303
3343
|
return null;
|
|
@@ -3329,7 +3369,7 @@ function appendAutoCtxpackSyncHint(responseObj, summary) {
|
|
|
3329
3369
|
return responseObj;
|
|
3330
3370
|
}
|
|
3331
3371
|
|
|
3332
|
-
async function appendWorkitemListHints(responseObj, args, toolArgs, token) {
|
|
3372
|
+
async function appendWorkitemListHints(responseObj, args, toolArgs, token, workspaceSignalTrusted = true) {
|
|
3333
3373
|
const result = safeObject(responseObj.result);
|
|
3334
3374
|
const content = ensureArray(result.content);
|
|
3335
3375
|
if (!content.length) return responseObj;
|
|
@@ -3388,6 +3428,7 @@ async function appendWorkitemListHints(responseObj, args, toolArgs, token) {
|
|
|
3388
3428
|
includeCtxpack: isEmptyBody,
|
|
3389
3429
|
syncCtxpackLocal: isEmptyBody,
|
|
3390
3430
|
workspaceDir: args.workspaceDir,
|
|
3431
|
+
workspaceSignalTrusted,
|
|
3391
3432
|
});
|
|
3392
3433
|
if (String(summary.access || "") === "granted") {
|
|
3393
3434
|
nextLines.push("Project context:");
|
|
@@ -3425,7 +3466,7 @@ async function appendWorkitemListHints(responseObj, args, toolArgs, token) {
|
|
|
3425
3466
|
return responseObj;
|
|
3426
3467
|
}
|
|
3427
3468
|
|
|
3428
|
-
function appendCtxpackEnsureSyncHints(responseObj, args, toolArgs, requestObj) {
|
|
3469
|
+
function appendCtxpackEnsureSyncHints(responseObj, args, toolArgs, requestObj, workspaceSignalTrusted = true) {
|
|
3429
3470
|
const result = safeObject(responseObj.result);
|
|
3430
3471
|
const content = ensureArray(result.content);
|
|
3431
3472
|
if (!content.length) return responseObj;
|
|
@@ -3459,6 +3500,7 @@ function appendCtxpackEnsureSyncHints(responseObj, args, toolArgs, requestObj) {
|
|
|
3459
3500
|
projectID,
|
|
3460
3501
|
ctxpack: body,
|
|
3461
3502
|
workspaceDir,
|
|
3503
|
+
workspaceSignalTrusted,
|
|
3462
3504
|
});
|
|
3463
3505
|
const baseVersionID = firstNonEmptyString([body.base_version_id, body.version_id, body.current_version_id]);
|
|
3464
3506
|
const currentVersionID = firstNonEmptyString([body.current_version_id, body.version_id, body.base_version_id]);
|
|
@@ -3616,7 +3658,15 @@ async function injectCtxpackPreflightToken(requestObj, toolName, toolArgs, args,
|
|
|
3616
3658
|
}
|
|
3617
3659
|
}
|
|
3618
3660
|
|
|
3619
|
-
async function appendCtxpackConflictHintToErrorResponse(
|
|
3661
|
+
async function appendCtxpackConflictHintToErrorResponse(
|
|
3662
|
+
responseObj,
|
|
3663
|
+
args,
|
|
3664
|
+
toolName,
|
|
3665
|
+
toolArgs,
|
|
3666
|
+
token,
|
|
3667
|
+
workspaceDir,
|
|
3668
|
+
workspaceSignalTrusted = true,
|
|
3669
|
+
) {
|
|
3620
3670
|
const out = safeObject(responseObj);
|
|
3621
3671
|
const errObj = safeObject(out.error);
|
|
3622
3672
|
const message = String(errObj.message || "").trim();
|
|
@@ -3648,6 +3698,7 @@ async function appendCtxpackConflictHintToErrorResponse(responseObj, args, toolN
|
|
|
3648
3698
|
projectID: projectIDHint,
|
|
3649
3699
|
ctxpack: safeObject(ctxpackRaw),
|
|
3650
3700
|
workspaceDir,
|
|
3701
|
+
workspaceSignalTrusted,
|
|
3651
3702
|
});
|
|
3652
3703
|
autoPullHint = ` auto-pull: ${String(syncResult.sync_status || "error")}${
|
|
3653
3704
|
syncResult.local_path ? ` (${String(syncResult.local_path)})` : ""
|
|
@@ -3684,6 +3735,7 @@ async function runProxy(flags) {
|
|
|
3684
3735
|
let lastRefreshAttemptAtMs = 0;
|
|
3685
3736
|
let lastRefreshError = "";
|
|
3686
3737
|
let sessionWorkspaceDir = "";
|
|
3738
|
+
let sessionWorkspaceTrusted = false;
|
|
3687
3739
|
|
|
3688
3740
|
const rl = readline.createInterface({
|
|
3689
3741
|
input: process.stdin,
|
|
@@ -3741,15 +3793,36 @@ async function runProxy(flags) {
|
|
|
3741
3793
|
}
|
|
3742
3794
|
|
|
3743
3795
|
const { name: toolName, args: toolArgs } = extractToolCall(requestObj);
|
|
3796
|
+
let requestWorkspaceCandidate = "";
|
|
3797
|
+
let strongRequestWorkspaceCandidate = "";
|
|
3798
|
+
let strongEnvWorkspaceCandidate = "";
|
|
3744
3799
|
if (!args.explicitPinnedWorkspace) {
|
|
3745
|
-
|
|
3746
|
-
|
|
3800
|
+
strongRequestWorkspaceCandidate = extractStrongWorkspaceCandidateFromRequest(requestObj, toolArgs);
|
|
3801
|
+
requestWorkspaceCandidate = firstNonEmptyString([
|
|
3802
|
+
strongRequestWorkspaceCandidate,
|
|
3803
|
+
extractWorkspaceCandidateFromRequest(requestObj, toolArgs),
|
|
3804
|
+
]);
|
|
3805
|
+
strongEnvWorkspaceCandidate = extractStrongWorkspaceCandidateFromEnv();
|
|
3806
|
+
const envWorkspaceCandidate = firstNonEmptyString([
|
|
3807
|
+
strongEnvWorkspaceCandidate,
|
|
3808
|
+
extractWorkspaceCandidateFromEnv(),
|
|
3809
|
+
]);
|
|
3747
3810
|
if (requestWorkspaceCandidate) {
|
|
3748
3811
|
sessionWorkspaceDir = requestWorkspaceCandidate;
|
|
3812
|
+
if (strongRequestWorkspaceCandidate) {
|
|
3813
|
+
sessionWorkspaceTrusted = true;
|
|
3814
|
+
}
|
|
3749
3815
|
} else if (envWorkspaceCandidate) {
|
|
3750
3816
|
sessionWorkspaceDir = envWorkspaceCandidate;
|
|
3817
|
+
if (strongEnvWorkspaceCandidate) {
|
|
3818
|
+
sessionWorkspaceTrusted = true;
|
|
3819
|
+
}
|
|
3751
3820
|
}
|
|
3752
3821
|
}
|
|
3822
|
+
const workspaceSignalTrusted =
|
|
3823
|
+
args.explicitPinnedWorkspace ||
|
|
3824
|
+
sessionWorkspaceTrusted ||
|
|
3825
|
+
Boolean(strongRequestWorkspaceCandidate || strongEnvWorkspaceCandidate);
|
|
3753
3826
|
const requestWorkspaceDir = args.explicitPinnedWorkspace
|
|
3754
3827
|
? resolveWorkspaceDir(args.workspaceDir || process.cwd())
|
|
3755
3828
|
: resolveWorkspaceDirForRequest(
|
|
@@ -3766,6 +3839,7 @@ async function runProxy(flags) {
|
|
|
3766
3839
|
args,
|
|
3767
3840
|
token,
|
|
3768
3841
|
workspaceDir: requestWorkspaceDir,
|
|
3842
|
+
workspaceSignalTrusted,
|
|
3769
3843
|
});
|
|
3770
3844
|
}
|
|
3771
3845
|
if (isJsonRpcMethod(requestObj, "tools/call") && LOCAL_PROJECT_TOOL_NAMES.includes(toolName)) {
|
|
@@ -3809,6 +3883,7 @@ async function runProxy(flags) {
|
|
|
3809
3883
|
includeCtxpack,
|
|
3810
3884
|
syncCtxpackLocal,
|
|
3811
3885
|
workspaceDir: requestWorkspaceDir,
|
|
3886
|
+
workspaceSignalTrusted,
|
|
3812
3887
|
});
|
|
3813
3888
|
const text = buildProjectSummaryText(summary);
|
|
3814
3889
|
process.stdout.write(
|
|
@@ -3962,6 +4037,7 @@ async function runProxy(flags) {
|
|
|
3962
4037
|
toolArgs,
|
|
3963
4038
|
token,
|
|
3964
4039
|
requestWorkspaceDir,
|
|
4040
|
+
workspaceSignalTrusted,
|
|
3965
4041
|
);
|
|
3966
4042
|
process.stdout.write(`${JSON.stringify(patched)}\n`);
|
|
3967
4043
|
return;
|
|
@@ -3971,9 +4047,15 @@ async function runProxy(flags) {
|
|
|
3971
4047
|
} else if (isJsonRpcMethod(requestObj, "initialize")) {
|
|
3972
4048
|
patched = appendProjectHintToInitialize(patched, args);
|
|
3973
4049
|
} else if (isJsonRpcMethod(requestObj, "tools/call") && toolName === "workitem.list") {
|
|
3974
|
-
patched = await appendWorkitemListHints(patched, args, toolArgs, token);
|
|
4050
|
+
patched = await appendWorkitemListHints(patched, args, toolArgs, token, workspaceSignalTrusted);
|
|
3975
4051
|
} else if (isJsonRpcMethod(requestObj, "tools/call") && toolName === "ctxpack.ensure") {
|
|
3976
|
-
patched = appendCtxpackEnsureSyncHints(
|
|
4052
|
+
patched = appendCtxpackEnsureSyncHints(
|
|
4053
|
+
patched,
|
|
4054
|
+
args,
|
|
4055
|
+
toolArgs,
|
|
4056
|
+
requestObj,
|
|
4057
|
+
workspaceSignalTrusted,
|
|
4058
|
+
);
|
|
3977
4059
|
}
|
|
3978
4060
|
if (autoSyncSummary) {
|
|
3979
4061
|
patched = appendAutoCtxpackSyncHint(patched, autoSyncSummary);
|
|
@@ -4070,18 +4152,23 @@ function resolveSetupContext(flags) {
|
|
|
4070
4152
|
const ctxpackKey = String(flags["ctxpack-key"] || buildCtxpackKeyFromMeta(workspaceMeta) || "").trim();
|
|
4071
4153
|
const baseURL = String(flags["base-url"] || DEFAULT_SITE_URL).trim().replace(/\/+$/, "");
|
|
4072
4154
|
const workspaceDirRaw = String(flags["workspace-dir"] || "").trim();
|
|
4073
|
-
const
|
|
4074
|
-
const
|
|
4075
|
-
// Default
|
|
4076
|
-
|
|
4077
|
-
|
|
4155
|
+
const workspaceFallbackDirRaw = String(flags["workspace-fallback-dir"] || "").trim();
|
|
4156
|
+
const hasWorkspaceDirFlag = Object.prototype.hasOwnProperty.call(flags, "workspace-dir");
|
|
4157
|
+
// Default to auto workspace mode for safer multi-project Codex sessions.
|
|
4158
|
+
const workspaceAutoMode = !hasWorkspaceDirFlag || isAutoWorkspaceMode(workspaceDirRaw);
|
|
4159
|
+
// Pin only when user explicitly set a non-auto workspace-dir.
|
|
4160
|
+
const shouldPinWorkspaceDir = hasWorkspaceDirFlag && !workspaceAutoMode;
|
|
4161
|
+
const workspaceFallbackDir = workspaceFallbackDirRaw
|
|
4162
|
+
? resolveWorkspaceDir(workspaceFallbackDirRaw)
|
|
4163
|
+
: "";
|
|
4078
4164
|
const workspaceDir = resolveWorkspaceDir(
|
|
4079
4165
|
shouldPinWorkspaceDir ? workspaceDirRaw || process.cwd() : process.cwd(),
|
|
4080
4166
|
);
|
|
4081
4167
|
const serverName = String(flags.name || DEFAULT_SERVER_NAME).trim() || DEFAULT_SERVER_NAME;
|
|
4082
4168
|
const proxyArgs = ["--base-url", `${baseURL}/governance/mcp`];
|
|
4083
|
-
|
|
4084
|
-
|
|
4169
|
+
if (workspaceAutoMode) {
|
|
4170
|
+
proxyArgs.push("--workspace-dir", "auto");
|
|
4171
|
+
} else if (shouldPinWorkspaceDir) {
|
|
4085
4172
|
proxyArgs.push("--workspace-dir", workspaceDir);
|
|
4086
4173
|
}
|
|
4087
4174
|
if (projectID) proxyArgs.push("--project-id", projectID);
|
|
@@ -4091,6 +4178,7 @@ function resolveSetupContext(flags) {
|
|
|
4091
4178
|
ctxpackKey,
|
|
4092
4179
|
baseURL,
|
|
4093
4180
|
workspaceDir,
|
|
4181
|
+
workspaceFallbackDir,
|
|
4094
4182
|
shouldPinWorkspaceDir,
|
|
4095
4183
|
workspaceAutoMode,
|
|
4096
4184
|
serverName,
|
|
@@ -4111,7 +4199,9 @@ function runSetupInternal(flags, options = {}) {
|
|
|
4111
4199
|
runRemove(cliBin, context.serverName);
|
|
4112
4200
|
}
|
|
4113
4201
|
const ok = tryRegister(cliBin, context.serverName, context.proxyArgs, {
|
|
4114
|
-
workspaceDir: context.
|
|
4202
|
+
workspaceDir: context.shouldPinWorkspaceDir
|
|
4203
|
+
? context.workspaceDir
|
|
4204
|
+
: context.workspaceFallbackDir,
|
|
4115
4205
|
});
|
|
4116
4206
|
const action = ensureOnly
|
|
4117
4207
|
? alreadyRegistered
|
|
@@ -4127,6 +4217,9 @@ function runSetupInternal(flags, options = {}) {
|
|
|
4127
4217
|
process.stdout.write(`Server: ${context.serverName}\n`);
|
|
4128
4218
|
process.stdout.write(`Gateway: ${context.baseURL}/governance/mcp\n`);
|
|
4129
4219
|
process.stdout.write(`Workspace: ${context.shouldPinWorkspaceDir ? context.workspaceDir : "auto (client current folder)"}\n`);
|
|
4220
|
+
if (!context.shouldPinWorkspaceDir && context.workspaceFallbackDir) {
|
|
4221
|
+
process.stdout.write(`Fallback: ${context.workspaceFallbackDir} (METHEUS_WORKSPACE_DIR)\n`);
|
|
4222
|
+
}
|
|
4130
4223
|
process.stdout.write(`Project: ${context.projectID || "auto-detect from .metheus_ctxpack_sync.json"}\n`);
|
|
4131
4224
|
if (context.ctxpackKey) {
|
|
4132
4225
|
process.stdout.write(`Ctxpack: ${context.ctxpackKey}\n`);
|