metheus-governance-mcp-cli 0.2.29 → 0.2.31
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 +1 -0
- package/cli.mjs +81 -8
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -60,6 +60,7 @@ metheus-governance-mcp-cli setup --project-id <project_uuid> --ctxpack-key "<ctx
|
|
|
60
60
|
This sets fallback workspace context for clients that do not pass workspace metadata:
|
|
61
61
|
- Codex/Antigravity/Cursor: `METHEUS_WORKSPACE_DIR` env
|
|
62
62
|
- Gemini: pinned `--workspace-dir <fallback>` and `METHEUS_WORKSPACE_DIR` in MCP registration
|
|
63
|
+
- fallback env is used only when workspace cannot be resolved (or resolves to home); when current `cwd` is a real project folder, sync uses that folder.
|
|
63
64
|
|
|
64
65
|
Guardrail note:
|
|
65
66
|
- By default, CLI blocks reading/writing ctxpack sync metadata when workspace root resolves to the home directory.
|
package/cli.mjs
CHANGED
|
@@ -639,18 +639,30 @@ function resolveWorkspaceDirForRequest(defaultWorkspaceDir, requestObj, toolArgs
|
|
|
639
639
|
const weakRequestCandidate = extractWeakWorkspaceCandidateFromRequest(requestObj);
|
|
640
640
|
const weakEnvCandidate = extractWeakWorkspaceCandidateFromEnv();
|
|
641
641
|
const homeCandidate = firstNonEmptyString([process.env.USERPROFILE, process.env.HOME]);
|
|
642
|
-
|
|
642
|
+
const localPreferredCandidates = [
|
|
643
643
|
strongRequestCandidate,
|
|
644
|
-
strongEnvCandidate,
|
|
645
644
|
weakRequestCandidate,
|
|
646
|
-
weakEnvCandidate,
|
|
647
645
|
defaultWorkspaceDir,
|
|
648
646
|
process.cwd(),
|
|
649
|
-
|
|
650
|
-
|
|
647
|
+
];
|
|
648
|
+
for (const rawCandidate of localPreferredCandidates) {
|
|
649
|
+
const resolved = sanitizeWorkspaceCandidate(rawCandidate);
|
|
650
|
+
if (!resolved) continue;
|
|
651
|
+
// If local candidate points to home directory, prefer explicit fallback env when available.
|
|
652
|
+
if (isHomeWorkspaceRoot(resolved)) {
|
|
653
|
+
const strongEnvResolved = sanitizeWorkspaceCandidate(strongEnvCandidate);
|
|
654
|
+
if (strongEnvResolved && !isHomeWorkspaceRoot(strongEnvResolved)) {
|
|
655
|
+
return strongEnvResolved;
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
return resolved;
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
for (const rawCandidate of [strongEnvCandidate, weakEnvCandidate, homeCandidate]) {
|
|
651
662
|
const resolved = sanitizeWorkspaceCandidate(rawCandidate);
|
|
652
663
|
if (resolved) return resolved;
|
|
653
664
|
}
|
|
665
|
+
|
|
654
666
|
return resolveWorkspaceDir(process.cwd());
|
|
655
667
|
}
|
|
656
668
|
|
|
@@ -3573,6 +3585,49 @@ async function maybeAutoSyncCtxpackForCall({
|
|
|
3573
3585
|
}
|
|
3574
3586
|
}
|
|
3575
3587
|
|
|
3588
|
+
async function maybeAutoSyncCtxpackForSessionRequest({
|
|
3589
|
+
requestObj,
|
|
3590
|
+
args,
|
|
3591
|
+
token,
|
|
3592
|
+
workspaceDir,
|
|
3593
|
+
workspaceSignalTrusted = true,
|
|
3594
|
+
}) {
|
|
3595
|
+
if (!token) return null;
|
|
3596
|
+
const method = String(requestObj?.method || "").trim().toLowerCase();
|
|
3597
|
+
if (method !== "initialize" && method !== "tools/list") return null;
|
|
3598
|
+
|
|
3599
|
+
const projectID = resolveProjectIDForRequest({
|
|
3600
|
+
toolArgs: {},
|
|
3601
|
+
args,
|
|
3602
|
+
workspaceDir,
|
|
3603
|
+
});
|
|
3604
|
+
if (!isUUID(projectID)) return null;
|
|
3605
|
+
|
|
3606
|
+
const workspacePath = resolveWorkspaceDir(workspaceDir || process.cwd());
|
|
3607
|
+
const trackerKey = `${workspacePath}::${projectID}::session-bootstrap`;
|
|
3608
|
+
const now = Date.now();
|
|
3609
|
+
const lastAt = Number(autoCtxpackSyncTracker.get(trackerKey) || 0);
|
|
3610
|
+
if (lastAt > 0 && now - lastAt < AUTO_CTXPACK_SYNC_INTERVAL_MS) {
|
|
3611
|
+
return null;
|
|
3612
|
+
}
|
|
3613
|
+
autoCtxpackSyncTracker.set(trackerKey, now);
|
|
3614
|
+
|
|
3615
|
+
try {
|
|
3616
|
+
return await loadProjectSummaryForTool({
|
|
3617
|
+
siteBaseURL: normalizeSiteBaseURL(args.baseURL),
|
|
3618
|
+
projectID,
|
|
3619
|
+
token,
|
|
3620
|
+
timeoutSeconds: args.timeoutSeconds,
|
|
3621
|
+
includeCtxpack: true,
|
|
3622
|
+
syncCtxpackLocal: true,
|
|
3623
|
+
workspaceDir: workspacePath,
|
|
3624
|
+
workspaceSignalTrusted,
|
|
3625
|
+
});
|
|
3626
|
+
} catch {
|
|
3627
|
+
return null;
|
|
3628
|
+
}
|
|
3629
|
+
}
|
|
3630
|
+
|
|
3576
3631
|
function appendAutoCtxpackSyncHint(responseObj, summary) {
|
|
3577
3632
|
const status = String(summary?.ctxpack_sync_status || "").trim();
|
|
3578
3633
|
if (!status || status === "disabled" || status === "not_attempted" || status === "current") {
|
|
@@ -4042,14 +4097,23 @@ async function runProxy(flags) {
|
|
|
4042
4097
|
if (strongRequestWorkspaceCandidate) {
|
|
4043
4098
|
sessionWorkspaceDir = strongRequestWorkspaceCandidate;
|
|
4044
4099
|
sessionWorkspaceTrusted = true;
|
|
4045
|
-
} else if (strongEnvWorkspaceCandidate) {
|
|
4046
|
-
sessionWorkspaceDir = strongEnvWorkspaceCandidate;
|
|
4047
|
-
sessionWorkspaceTrusted = true;
|
|
4048
4100
|
} else if (weakRequestWorkspaceCandidate) {
|
|
4049
4101
|
sessionWorkspaceDir = weakRequestWorkspaceCandidate;
|
|
4050
4102
|
} else if (weakEnvWorkspaceCandidate) {
|
|
4051
4103
|
sessionWorkspaceDir = weakEnvWorkspaceCandidate;
|
|
4052
4104
|
}
|
|
4105
|
+
if (!sessionWorkspaceDir) {
|
|
4106
|
+
const currentCwdCandidate = sanitizeWorkspaceCandidate(process.cwd());
|
|
4107
|
+
if (currentCwdCandidate && !isHomeWorkspaceRoot(currentCwdCandidate)) {
|
|
4108
|
+
sessionWorkspaceDir = currentCwdCandidate;
|
|
4109
|
+
}
|
|
4110
|
+
}
|
|
4111
|
+
if (strongEnvWorkspaceCandidate) {
|
|
4112
|
+
sessionWorkspaceTrusted = true;
|
|
4113
|
+
if (!sessionWorkspaceDir || isHomeWorkspaceRoot(sessionWorkspaceDir)) {
|
|
4114
|
+
sessionWorkspaceDir = strongEnvWorkspaceCandidate;
|
|
4115
|
+
}
|
|
4116
|
+
}
|
|
4053
4117
|
}
|
|
4054
4118
|
const workspaceSignalTrusted =
|
|
4055
4119
|
args.explicitPinnedWorkspace ||
|
|
@@ -4074,6 +4138,15 @@ async function runProxy(flags) {
|
|
|
4074
4138
|
workspaceSignalTrusted,
|
|
4075
4139
|
});
|
|
4076
4140
|
}
|
|
4141
|
+
if (!autoSyncSummary) {
|
|
4142
|
+
autoSyncSummary = await maybeAutoSyncCtxpackForSessionRequest({
|
|
4143
|
+
requestObj,
|
|
4144
|
+
args,
|
|
4145
|
+
token,
|
|
4146
|
+
workspaceDir: requestWorkspaceDir,
|
|
4147
|
+
workspaceSignalTrusted,
|
|
4148
|
+
});
|
|
4149
|
+
}
|
|
4077
4150
|
if (isJsonRpcMethod(requestObj, "tools/call") && LOCAL_PROJECT_TOOL_NAMES.includes(toolName)) {
|
|
4078
4151
|
const projectID = String(
|
|
4079
4152
|
resolveProjectIDForRequest({
|