metheus-governance-mcp-cli 0.2.48 → 0.2.50
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 +32 -1
- package/cli.mjs +116 -10
- package/package.json +5 -3
- package/postinstall.mjs +42 -0
package/README.md
CHANGED
|
@@ -20,6 +20,25 @@ Compatibility note: legacy command alias `metheus-governance-mcp` is still suppo
|
|
|
20
20
|
npm install -g metheus-governance-mcp-cli@latest
|
|
21
21
|
```
|
|
22
22
|
|
|
23
|
+
Install creates a local Telegram settings template here:
|
|
24
|
+
|
|
25
|
+
- `~/.metheus/telegram.env`
|
|
26
|
+
|
|
27
|
+
This file is for the local Telegram bot secret only.
|
|
28
|
+
|
|
29
|
+
- Store locally:
|
|
30
|
+
- `TELEGRAM_BOT_TOKEN`
|
|
31
|
+
- Server-side Metheus stores project Telegram destination metadata separately:
|
|
32
|
+
- `chat_id`
|
|
33
|
+
- label / active state
|
|
34
|
+
- Do not put project `chat_id` in the local Telegram env file.
|
|
35
|
+
|
|
36
|
+
Example template:
|
|
37
|
+
|
|
38
|
+
```env
|
|
39
|
+
TELEGRAM_BOT_TOKEN=
|
|
40
|
+
```
|
|
41
|
+
|
|
23
42
|
## One command bootstrap (recommended)
|
|
24
43
|
|
|
25
44
|
Run in your project folder:
|
|
@@ -36,16 +55,26 @@ If auth is not ready, login starts automatically, then MCP registration is compl
|
|
|
36
55
|
metheus-governance-mcp-cli setup --project-id <project_uuid> --ctxpack-key "<ctxpack_key>" --base-url https://metheus.gesiaplatform.com
|
|
37
56
|
```
|
|
38
57
|
|
|
39
|
-
`project-id` can be
|
|
58
|
+
Technical fallback: `project-id` can be auto-detected if your current folder (or parent) has `.metheus_ctxpack_sync.json`.
|
|
40
59
|
`setup` defaults to `--workspace-dir auto` (dynamic workspace detection).
|
|
41
60
|
Use an explicit path only when you intentionally want a fixed workspace.
|
|
42
61
|
|
|
62
|
+
Ops policy (recommended):
|
|
63
|
+
- Always pass explicit `--project-id <project_uuid>` during setup.
|
|
64
|
+
- Omit `--project-id` only in advanced cases where `.metheus_ctxpack_sync.json` is already present and verified.
|
|
65
|
+
|
|
43
66
|
Recommended for Codex/Claude/Gemini/Antigravity/Cursor multi-workspace sessions:
|
|
44
67
|
|
|
45
68
|
```bash
|
|
46
69
|
metheus-governance-mcp-cli setup --project-id <project_uuid> --ctxpack-key "<ctxpack_key>" --base-url https://metheus.gesiaplatform.com --workspace-dir auto
|
|
47
70
|
```
|
|
48
71
|
|
|
72
|
+
`setup` also ensures the local Telegram template exists:
|
|
73
|
+
|
|
74
|
+
- `~/.metheus/telegram.env`
|
|
75
|
+
|
|
76
|
+
Fill only the bot token locally. Project Telegram `chat_id` destinations should be managed on the Metheus server as project Telegram destinations, not as local env values and not inside Chat Hooks.
|
|
77
|
+
|
|
49
78
|
Gemini CLI note:
|
|
50
79
|
- `gemini mcp` commands require Gemini auth to be configured first (`GEMINI_API_KEY` or `~/.gemini/settings.json` auth).
|
|
51
80
|
- `setup` registers Gemini in both `user` and `project` scopes to improve auto-discovery across folders.
|
|
@@ -76,6 +105,7 @@ metheus-governance-mcp-cli doctor --project-id <project_uuid> --base-url https:/
|
|
|
76
105
|
|
|
77
106
|
Checks:
|
|
78
107
|
- auth token status (+ auto refresh attempt)
|
|
108
|
+
- local Telegram env template presence
|
|
79
109
|
- codex/claude/gemini/antigravity/cursor registration state
|
|
80
110
|
- gateway `tools/list` reachability
|
|
81
111
|
- `project.summary` access
|
|
@@ -126,6 +156,7 @@ These tools accept `project_id` and return:
|
|
|
126
156
|
Project-ID first-call rule:
|
|
127
157
|
- when user gives only `Project ID`, call `project.summary` first.
|
|
128
158
|
- call `ctxpack.ensure` after `project.summary` only when extra ctxpack refresh/export context is needed.
|
|
159
|
+
- for support/ops workflows, do not run ctxpack sync/download before a successful `project.summary`.
|
|
129
160
|
|
|
130
161
|
Ctxpack merge safety flow:
|
|
131
162
|
- call `ctxpack.merge.brief` first
|
package/cli.mjs
CHANGED
|
@@ -15,6 +15,7 @@ const DEFAULT_SITE_URL = "https://metheus.gesiaplatform.com";
|
|
|
15
15
|
const DEFAULT_BASE_URL = `${DEFAULT_SITE_URL}/governance/mcp`;
|
|
16
16
|
const DEFAULT_SERVER_NAME = "metheus-governance-mcp";
|
|
17
17
|
const AUTH_STORE_RELATIVE_PATH = path.join(".metheus", "governance-mcp-auth.json");
|
|
18
|
+
const TELEGRAM_ENV_RELATIVE_PATH = path.join(".metheus", "telegram.env");
|
|
18
19
|
const SELF_UPDATE_STATE_RELATIVE_PATH = path.join(".metheus", "governance-mcp-cli-update.json");
|
|
19
20
|
const CTXPACK_CACHE_RELATIVE_DIR = path.join(".metheus", "ctxpack-cache");
|
|
20
21
|
const CTXPACK_META_FILENAME = ".metheus_ctxpack_sync.json";
|
|
@@ -57,6 +58,8 @@ function printUsage() {
|
|
|
57
58
|
` ${ALLOW_HOME_WORKSPACE_ENV_KEY}=1 to allow using home directory as workspace root (disabled by default).`,
|
|
58
59
|
" If env is missing, stored token file is used:",
|
|
59
60
|
` ${AUTH_STORE_RELATIVE_PATH}`,
|
|
61
|
+
" Local Telegram bot token template is stored at:",
|
|
62
|
+
` ${TELEGRAM_ENV_RELATIVE_PATH}`,
|
|
60
63
|
"",
|
|
61
64
|
].join("\n"),
|
|
62
65
|
);
|
|
@@ -66,7 +69,7 @@ function loadCLIMeta() {
|
|
|
66
69
|
try {
|
|
67
70
|
const dir = path.dirname(fileURLToPath(import.meta.url));
|
|
68
71
|
const raw = fs.readFileSync(path.join(dir, "package.json"), "utf8");
|
|
69
|
-
const parsed = JSON.parse(raw);
|
|
72
|
+
const parsed = JSON.parse(stripUTF8BOM(raw));
|
|
70
73
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
71
74
|
return {};
|
|
72
75
|
}
|
|
@@ -80,6 +83,12 @@ function printVersion() {
|
|
|
80
83
|
process.stdout.write(`${CLI_NAME} ${CLI_VERSION}\n`);
|
|
81
84
|
}
|
|
82
85
|
|
|
86
|
+
function stripUTF8BOM(rawText) {
|
|
87
|
+
const text = String(rawText || "");
|
|
88
|
+
if (!text) return "";
|
|
89
|
+
return text.charCodeAt(0) === 0xfeff ? text.slice(1) : text;
|
|
90
|
+
}
|
|
91
|
+
|
|
83
92
|
function resolveHomeFilePath(relativePath) {
|
|
84
93
|
const home = String(process.env.USERPROFILE || process.env.HOME || "").trim();
|
|
85
94
|
if (!home) {
|
|
@@ -284,7 +293,7 @@ function loadSelfUpdateState() {
|
|
|
284
293
|
const filePath = updateStateFilePath();
|
|
285
294
|
try {
|
|
286
295
|
const raw = fs.readFileSync(filePath, "utf8");
|
|
287
|
-
const parsed = JSON.parse(raw);
|
|
296
|
+
const parsed = JSON.parse(stripUTF8BOM(raw));
|
|
288
297
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
289
298
|
return { filePath, checkedAt: "", latestVersion: "", installedVersion: "", updatedAt: "" };
|
|
290
299
|
}
|
|
@@ -470,6 +479,36 @@ function authStoreFilePath() {
|
|
|
470
479
|
return resolveHomeFilePath(AUTH_STORE_RELATIVE_PATH);
|
|
471
480
|
}
|
|
472
481
|
|
|
482
|
+
function telegramEnvFilePath() {
|
|
483
|
+
return resolveHomeFilePath(TELEGRAM_ENV_RELATIVE_PATH);
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
function telegramEnvTemplate() {
|
|
487
|
+
return [
|
|
488
|
+
"# Metheus local Telegram bot settings",
|
|
489
|
+
"# Keep this file on your machine only. Do not commit it.",
|
|
490
|
+
"# Store only the Telegram bot token locally.",
|
|
491
|
+
"# Project chat_id must be managed on the Metheus server as a project Telegram destination.",
|
|
492
|
+
"",
|
|
493
|
+
"TELEGRAM_BOT_TOKEN=",
|
|
494
|
+
"",
|
|
495
|
+
].join("\n");
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
function ensureTelegramEnvTemplate() {
|
|
499
|
+
const filePath = telegramEnvFilePath();
|
|
500
|
+
try {
|
|
501
|
+
if (fs.existsSync(filePath)) {
|
|
502
|
+
return { filePath, created: false, existed: true };
|
|
503
|
+
}
|
|
504
|
+
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
505
|
+
fs.writeFileSync(filePath, telegramEnvTemplate(), "utf8");
|
|
506
|
+
return { filePath, created: true, existed: false };
|
|
507
|
+
} catch (err) {
|
|
508
|
+
return { filePath, created: false, existed: false, error: String(err?.message || err) };
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
|
|
473
512
|
function resolveWorkspaceDir(rawPath) {
|
|
474
513
|
const input = String(rawPath || "").trim();
|
|
475
514
|
if (input) {
|
|
@@ -757,9 +796,9 @@ function resolveProjectIDForRequest({
|
|
|
757
796
|
}) {
|
|
758
797
|
const resolvedWorkspaceDir = resolveWorkspaceDir(workspaceDir || process.cwd());
|
|
759
798
|
const workspaceMeta = loadWorkspaceMeta(resolvedWorkspaceDir);
|
|
799
|
+
const toolProjectID = resolveProjectIDFromToolArgs(toolArgs);
|
|
760
800
|
return firstNonEmptyString([
|
|
761
|
-
|
|
762
|
-
toolArgs?.projectID,
|
|
801
|
+
toolProjectID,
|
|
763
802
|
responseProjectID,
|
|
764
803
|
envelopeProjectID,
|
|
765
804
|
args?.projectID,
|
|
@@ -795,7 +834,7 @@ function loadStoredAuth() {
|
|
|
795
834
|
return { filePath, token: "", refreshToken: "", baseURL: "", updatedAt: "" };
|
|
796
835
|
}
|
|
797
836
|
const raw = fs.readFileSync(filePath, "utf8");
|
|
798
|
-
const parsed = JSON.parse(raw);
|
|
837
|
+
const parsed = JSON.parse(stripUTF8BOM(raw));
|
|
799
838
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
800
839
|
return { filePath, token: "", refreshToken: "", baseURL: "", updatedAt: "" };
|
|
801
840
|
}
|
|
@@ -1461,7 +1500,7 @@ function currentAccessTokenSource() {
|
|
|
1461
1500
|
|
|
1462
1501
|
function tryJsonParse(raw) {
|
|
1463
1502
|
try {
|
|
1464
|
-
return JSON.parse(raw);
|
|
1503
|
+
return JSON.parse(stripUTF8BOM(raw));
|
|
1465
1504
|
} catch {
|
|
1466
1505
|
return null;
|
|
1467
1506
|
}
|
|
@@ -1505,7 +1544,7 @@ function loadWorkspaceMeta(startDir) {
|
|
|
1505
1544
|
if (!metaFile) return {};
|
|
1506
1545
|
try {
|
|
1507
1546
|
const raw = fs.readFileSync(metaFile, "utf8");
|
|
1508
|
-
const parsed = JSON.parse(raw);
|
|
1547
|
+
const parsed = JSON.parse(stripUTF8BOM(raw));
|
|
1509
1548
|
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
1510
1549
|
return parsed;
|
|
1511
1550
|
}
|
|
@@ -1552,6 +1591,40 @@ function isUUID(raw) {
|
|
|
1552
1591
|
return /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(value);
|
|
1553
1592
|
}
|
|
1554
1593
|
|
|
1594
|
+
function extractUUIDFromText(raw) {
|
|
1595
|
+
const text = String(raw || "").trim();
|
|
1596
|
+
if (!text) return "";
|
|
1597
|
+
const match = text.match(/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/i);
|
|
1598
|
+
return String(match?.[0] || "").trim();
|
|
1599
|
+
}
|
|
1600
|
+
|
|
1601
|
+
function resolveProjectIDFromToolArgs(rawToolArgs) {
|
|
1602
|
+
const toolArgs = safeObject(rawToolArgs);
|
|
1603
|
+
const direct = firstNonEmptyString([
|
|
1604
|
+
toolArgs.project_id,
|
|
1605
|
+
toolArgs.projectID,
|
|
1606
|
+
toolArgs.projectId,
|
|
1607
|
+
toolArgs["project-id"],
|
|
1608
|
+
toolArgs.project_uuid,
|
|
1609
|
+
toolArgs.projectUUID,
|
|
1610
|
+
toolArgs.projectUuid,
|
|
1611
|
+
]);
|
|
1612
|
+
if (isUUID(direct)) return direct;
|
|
1613
|
+
|
|
1614
|
+
const hinted = firstNonEmptyString([
|
|
1615
|
+
extractUUIDFromText(toolArgs.project),
|
|
1616
|
+
extractUUIDFromText(toolArgs.project_id_text),
|
|
1617
|
+
extractUUIDFromText(toolArgs.projectIdText),
|
|
1618
|
+
extractUUIDFromText(toolArgs.input),
|
|
1619
|
+
extractUUIDFromText(toolArgs.text),
|
|
1620
|
+
extractUUIDFromText(toolArgs.query),
|
|
1621
|
+
extractUUIDFromText(toolArgs.prompt),
|
|
1622
|
+
]);
|
|
1623
|
+
if (isUUID(hinted)) return hinted;
|
|
1624
|
+
|
|
1625
|
+
return "";
|
|
1626
|
+
}
|
|
1627
|
+
|
|
1555
1628
|
async function runAuthStatus() {
|
|
1556
1629
|
const resolved = resolveCurrentAccessToken();
|
|
1557
1630
|
const token = resolved.token;
|
|
@@ -2067,6 +2140,18 @@ async function runDoctor(flags) {
|
|
|
2067
2140
|
});
|
|
2068
2141
|
const rows = [];
|
|
2069
2142
|
|
|
2143
|
+
const telegramEnv = ensureTelegramEnvTemplate();
|
|
2144
|
+
if (telegramEnv.error) {
|
|
2145
|
+
addDoctorCheck(rows, "warn", "local telegram env", `unavailable (${telegramEnv.error})`);
|
|
2146
|
+
} else {
|
|
2147
|
+
addDoctorCheck(
|
|
2148
|
+
rows,
|
|
2149
|
+
telegramEnv.created ? "warn" : "ok",
|
|
2150
|
+
"local telegram env",
|
|
2151
|
+
`${telegramEnv.created ? "created template" : "ready"} (${telegramEnv.filePath})`,
|
|
2152
|
+
);
|
|
2153
|
+
}
|
|
2154
|
+
|
|
2070
2155
|
const resolved = await resolveAccessTokenForCommand(context.baseURL, timeoutSeconds);
|
|
2071
2156
|
const token = resolved.token;
|
|
2072
2157
|
if (!token) {
|
|
@@ -2720,7 +2805,7 @@ function loadCtxpackMeta(metaPath) {
|
|
|
2720
2805
|
try {
|
|
2721
2806
|
if (!fs.existsSync(metaPath)) return null;
|
|
2722
2807
|
const raw = fs.readFileSync(metaPath, "utf8");
|
|
2723
|
-
const parsed = JSON.parse(raw);
|
|
2808
|
+
const parsed = JSON.parse(stripUTF8BOM(raw));
|
|
2724
2809
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return null;
|
|
2725
2810
|
return parsed;
|
|
2726
2811
|
} catch {
|
|
@@ -3730,6 +3815,7 @@ function appendProjectHintToInitialize(responseObj, args, options = {}) {
|
|
|
3730
3815
|
]
|
|
3731
3816
|
: []),
|
|
3732
3817
|
`- MUST call \`${projectSummaryTool}\` first when the user provides only a Project ID or asks project overview/agenda.`,
|
|
3818
|
+
`- If user enters a Project ID in text (e.g., "Project ID <uuid>"), pass that exact UUID as \`project_id\` argument when calling \`${projectSummaryTool}\`.`,
|
|
3733
3819
|
`- \`${projectDescribeTool}\` and \`${projectGetTool}\` are aliases of \`${projectSummaryTool}\`.`,
|
|
3734
3820
|
`- Never handle a bare Project ID by local file/transcript search before \`${projectSummaryTool}\` succeeds.`,
|
|
3735
3821
|
`- Run \`${ctxpackEnsureTool}\` only after \`${projectSummaryTool}\`, and only when additional ctxpack refresh/export context is needed.`,
|
|
@@ -4505,7 +4591,13 @@ async function runProxy(flags) {
|
|
|
4505
4591
|
}),
|
|
4506
4592
|
).trim();
|
|
4507
4593
|
if (!projectID) {
|
|
4508
|
-
writeProxyJson(
|
|
4594
|
+
writeProxyJson(
|
|
4595
|
+
jsonRpcError(
|
|
4596
|
+
requestObj,
|
|
4597
|
+
-32001,
|
|
4598
|
+
'project_id is required. Enter a valid UUID (e.g., {"project_id":"00000000-0000-0000-0000-000000000000"}) or set --project-id during setup.',
|
|
4599
|
+
),
|
|
4600
|
+
);
|
|
4509
4601
|
return;
|
|
4510
4602
|
}
|
|
4511
4603
|
if (!isUUID(projectID)) {
|
|
@@ -4561,7 +4653,13 @@ async function runProxy(flags) {
|
|
|
4561
4653
|
}),
|
|
4562
4654
|
).trim();
|
|
4563
4655
|
if (!projectID) {
|
|
4564
|
-
writeProxyJson(
|
|
4656
|
+
writeProxyJson(
|
|
4657
|
+
jsonRpcError(
|
|
4658
|
+
requestObj,
|
|
4659
|
+
-32001,
|
|
4660
|
+
'project_id is required. Enter a valid UUID (e.g., {"project_id":"00000000-0000-0000-0000-000000000000"}) or set --project-id during setup.',
|
|
4661
|
+
),
|
|
4662
|
+
);
|
|
4565
4663
|
return;
|
|
4566
4664
|
}
|
|
4567
4665
|
if (!isUUID(projectID)) {
|
|
@@ -5198,6 +5296,7 @@ function runSetupInternal(flags, options = {}) {
|
|
|
5198
5296
|
const context = resolveSetupContext(flags);
|
|
5199
5297
|
const clients = [...MCP_CLIENTS];
|
|
5200
5298
|
const results = [];
|
|
5299
|
+
const telegramEnv = ensureTelegramEnvTemplate();
|
|
5201
5300
|
|
|
5202
5301
|
for (const cliBin of clients) {
|
|
5203
5302
|
if (!commandExists(cliBin)) continue;
|
|
@@ -5247,6 +5346,13 @@ function runSetupInternal(flags, options = {}) {
|
|
|
5247
5346
|
process.stdout.write(`Fallback: ${context.workspaceFallbackDir} (METHEUS_WORKSPACE_DIR)\n`);
|
|
5248
5347
|
}
|
|
5249
5348
|
process.stdout.write(`Project: ${context.projectID || "auto-detect from .metheus_ctxpack_sync.json"}\n`);
|
|
5349
|
+
if (telegramEnv.error) {
|
|
5350
|
+
process.stdout.write(`Telegram: template unavailable (${telegramEnv.error})\n`);
|
|
5351
|
+
} else {
|
|
5352
|
+
process.stdout.write(
|
|
5353
|
+
`Telegram: ${telegramEnv.created ? "template created" : "template ready"} (${telegramEnv.filePath})\n`,
|
|
5354
|
+
);
|
|
5355
|
+
}
|
|
5250
5356
|
if (context.ctxpackKey) {
|
|
5251
5357
|
process.stdout.write(`Ctxpack: ${context.ctxpackKey}\n`);
|
|
5252
5358
|
}
|
package/package.json
CHANGED
|
@@ -1,21 +1,23 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "metheus-governance-mcp-cli",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.50",
|
|
4
4
|
"description": "Metheus Governance MCP CLI (setup + stdio proxy)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
7
7
|
"bin/metheus-governance-mcp.js",
|
|
8
8
|
"cli.mjs",
|
|
9
|
+
"postinstall.mjs",
|
|
9
10
|
"README.md",
|
|
10
11
|
".env.npm.local.example"
|
|
11
12
|
],
|
|
12
13
|
"scripts": {
|
|
13
|
-
"check": "node --check cli.mjs && node --check release.mjs",
|
|
14
|
+
"check": "node --check cli.mjs && node --check postinstall.mjs && node --check release.mjs",
|
|
14
15
|
"test:compat": "node cli.mjs selftest --json",
|
|
15
16
|
"smoke:proxy": "node scripts/smoke-proxy.mjs",
|
|
16
17
|
"pack:dry": "npm pack --dry-run",
|
|
17
18
|
"publish:dry": "node release.mjs --dry-run",
|
|
18
|
-
"publish:public": "node release.mjs"
|
|
19
|
+
"publish:public": "node release.mjs",
|
|
20
|
+
"postinstall": "node postinstall.mjs"
|
|
19
21
|
},
|
|
20
22
|
"bin": {
|
|
21
23
|
"metheus-governance-mcp": "bin/metheus-governance-mcp.js",
|
package/postinstall.mjs
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import fs from "node:fs";
|
|
4
|
+
import os from "node:os";
|
|
5
|
+
import path from "node:path";
|
|
6
|
+
|
|
7
|
+
const RELATIVE_PATH = path.join(".metheus", "telegram.env");
|
|
8
|
+
|
|
9
|
+
function resolveTargetPath() {
|
|
10
|
+
const home = String(process.env.USERPROFILE || process.env.HOME || os.homedir() || "").trim();
|
|
11
|
+
if (!home) return "";
|
|
12
|
+
return path.join(home, RELATIVE_PATH);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function template() {
|
|
16
|
+
return [
|
|
17
|
+
"# Metheus local Telegram bot settings",
|
|
18
|
+
"# Keep this file on your machine only. Do not commit it.",
|
|
19
|
+
"# Store only the Telegram bot token locally.",
|
|
20
|
+
"# Project chat_id must be managed on the Metheus server as a project Telegram destination.",
|
|
21
|
+
"",
|
|
22
|
+
"TELEGRAM_BOT_TOKEN=",
|
|
23
|
+
"",
|
|
24
|
+
].join("\n");
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function main() {
|
|
28
|
+
const filePath = resolveTargetPath();
|
|
29
|
+
if (!filePath) return;
|
|
30
|
+
try {
|
|
31
|
+
if (fs.existsSync(filePath)) return;
|
|
32
|
+
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
33
|
+
fs.writeFileSync(filePath, template(), "utf8");
|
|
34
|
+
process.stdout.write(`[metheus-governance-mcp-cli] created ${filePath}\n`);
|
|
35
|
+
} catch (err) {
|
|
36
|
+
process.stderr.write(
|
|
37
|
+
`[metheus-governance-mcp-cli] could not create ${filePath}: ${String(err?.message || err)}\n`,
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
main();
|