metheus-governance-mcp-cli 0.2.108 → 0.2.110

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 CHANGED
@@ -103,8 +103,8 @@ Runner template:
103
103
  },
104
104
  "bot_bindings": {
105
105
  "primary_monitor_bot": {
106
- "bot_id": "<server_bot_uuid>",
107
- "bot_name": "<bot_name>",
106
+ "server_bot_id": "<server_bot_uuid>",
107
+ "server_bot_name": "<server_bot_name>",
108
108
  "role_profile": "monitor",
109
109
  "client": "gpt",
110
110
  "model": "",
@@ -119,7 +119,7 @@ Runner template:
119
119
  "project_id": "<project_uuid>",
120
120
  "provider": "telegram",
121
121
  "role": "monitor",
122
- "bot_id": "<server_bot_uuid>",
122
+ "server_bot_id": "<server_bot_uuid>",
123
123
  "trigger_policy": {
124
124
  "mentions_only": true,
125
125
  "direct_messages": true,
@@ -283,7 +283,7 @@ Behavior:
283
283
  - Slack and KakaoTalk currently use a single local token entry per provider in this command flow.
284
284
  - `bot verify` checks the configured local token, cross-checks the server bot binding, prints the effective runtime role profile summary that the runner will use, and shows which local runner routes currently point at this bot entry.
285
285
  - `bot show` prints one local bot entry in detail, including grouped role summaries when one server bot name expands to multiple roles and any linked local runner routes.
286
- - In `bot show` and `bot verify`, `saved_local_file` means the values already stored on disk under `~/.metheus/telegram-bots/*.env`, while `current_server_protocol` means the fresh `/api/v1/me/bots` response from the server right now.
286
+ - In `bot show` and `bot verify`, `saved_local_file` means the values already stored on disk under `~/.metheus/telegram-bots/*.env`, while `live_server_response` means the fresh `/api/v1/me/bots` response from the server right now.
287
287
  - `bot global` edits Telegram-wide local settings such as API base URL, allowed updates, and the default Telegram bot selector.
288
288
  - `bot set-default` changes the default Telegram bot selection.
289
289
  - `bot migrate` moves legacy `TELEGRAM_BOT_TOKEN` into a named Telegram bot entry.
package/cli.mjs CHANGED
@@ -1006,8 +1006,8 @@ function normalizeRunnerBotBinding(bindingName, rawBinding, defaults = {}) {
1006
1006
  const binding = safeObject(rawBinding);
1007
1007
  const normalizedName = String(bindingName || binding.name || "").trim();
1008
1008
  const normalizedClient = normalizeLocalAIClientName(binding.client || defaults.client || "", "");
1009
- let botID = String(binding.bot_id || binding.botID || defaults.botID || "").trim();
1010
- let botName = String(binding.bot_name || binding.botName || defaults.botName || "").trim();
1009
+ let botID = String(binding.server_bot_id || binding.serverBotID || binding.bot_id || binding.botID || defaults.botID || "").trim();
1010
+ let botName = String(binding.server_bot_name || binding.serverBotName || binding.bot_name || binding.botName || defaults.botName || "").trim();
1011
1011
  if (!botID && !botName && normalizedName) {
1012
1012
  if (isUUID(normalizedName)) {
1013
1013
  botID = normalizedName;
@@ -1038,8 +1038,8 @@ function normalizeRunnerBotBinding(bindingName, rawBinding, defaults = {}) {
1038
1038
  function serializeRunnerBotBinding(binding) {
1039
1039
  const normalized = normalizeRunnerBotBinding(binding?.name, binding);
1040
1040
  return {
1041
- ...(normalized.botName ? { bot_name: normalized.botName } : {}),
1042
- ...(normalized.botID ? { bot_id: normalized.botID } : {}),
1041
+ ...(normalized.botName ? { server_bot_name: normalized.botName } : {}),
1042
+ ...(normalized.botID ? { server_bot_id: normalized.botID } : {}),
1043
1043
  ...(normalized.roleProfile ? { role_profile: normalized.roleProfile } : {}),
1044
1044
  ...(normalized.client ? { client: normalized.client } : {}),
1045
1045
  ...(normalized.model ? { model: normalized.model } : {}),
@@ -1129,6 +1129,8 @@ function botRunnerConfigTemplate() {
1129
1129
  role_profiles: defaultBotRunnerRoleProfiles(),
1130
1130
  bot_bindings: {
1131
1131
  "<bot_name>": {
1132
+ server_bot_name: "<server_bot_name>",
1133
+ server_bot_id: "<server_bot_uuid>",
1132
1134
  role_profile: "monitor",
1133
1135
  },
1134
1136
  },
@@ -1140,8 +1142,8 @@ function botRunnerConfigTemplate() {
1140
1142
  provider: "telegram",
1141
1143
  role: "monitor",
1142
1144
  role_profile: "monitor",
1143
- bot_name: "",
1144
- bot_id: "",
1145
+ server_bot_name: "",
1146
+ server_bot_id: "",
1145
1147
  destination_id: "",
1146
1148
  destination_label: "",
1147
1149
  archive_thread_id: "",
@@ -1176,8 +1178,8 @@ function serializeRunnerRoute(route) {
1176
1178
  provider: normalized.provider,
1177
1179
  role: normalized.role,
1178
1180
  ...(normalized.roleProfile ? { role_profile: normalized.roleProfile } : {}),
1179
- bot_name: normalized.botName,
1180
- bot_id: normalized.botID,
1181
+ server_bot_name: normalized.botName,
1182
+ server_bot_id: normalized.botID,
1181
1183
  destination_id: normalized.destinationID,
1182
1184
  destination_label: normalized.destinationLabel,
1183
1185
  archive_thread_id: normalized.archiveThreadID,
@@ -1693,8 +1695,8 @@ function normalizeRunnerRoute(rawRoute, overrides = {}) {
1693
1695
  const role = normalizeBotRole(route.role || route.bot_role || route.botRole);
1694
1696
  const roleProfile = normalizeRunnerRoleProfileName(route.role_profile || route.roleProfile || route.execution_profile || route.executionProfile);
1695
1697
  const name = String(route.name || "").trim();
1696
- const botName = String(route.bot_name || route.botName || "").trim();
1697
- const botID = String(route.bot_id || route.botID || "").trim();
1698
+ const botName = String(route.server_bot_name || route.serverBotName || route.bot_name || route.botName || "").trim();
1699
+ const botID = String(route.server_bot_id || route.serverBotID || route.bot_id || route.botID || "").trim();
1698
1700
  const command = String(route.command || "").trim();
1699
1701
  const destinationID = String(route.destination_id || route.destinationID || "").trim();
1700
1702
  const destinationLabel = String(route.destination_label || route.destinationLabel || "").trim();
@@ -1769,7 +1771,7 @@ function validateRunnerRoute(route, { requireCommand = true, config = null } = {
1769
1771
  errors.push("workspace_dir is missing for project_id; configure project_mappings or route.workspace_dir");
1770
1772
  }
1771
1773
  if (route.botID && !isUUID(route.botID)) {
1772
- errors.push("bot_id must be a valid UUID");
1774
+ errors.push("server_bot_id must be a valid UUID");
1773
1775
  }
1774
1776
  if (route.archiveThreadID && !isUUID(route.archiveThreadID)) {
1775
1777
  errors.push("archive_thread_id must be a valid UUID");
@@ -2631,13 +2633,13 @@ async function runRunnerList(flags) {
2631
2633
  ` provider: ${row.provider}`,
2632
2634
  ` project_id: ${row.projectID}`,
2633
2635
  ` server_bot_name: ${row.botName}`,
2634
- ` bot_id: ${row.botID}`,
2636
+ ` server_bot_id: ${row.botID}`,
2635
2637
  ` role: ${row.role}`,
2636
2638
  ` role_profile: ${row.roleProfile}`,
2637
2639
  ` destination_label: ${row.destinationLabel}`,
2638
2640
  ` poll_interval_ms: ${row.pollIntervalMs}`,
2639
2641
  ` run_once: ${CLI_NAME} runner once --route-name ${row.name}`,
2640
- row.botName ? ` run_once_by_bot_name: ${CLI_NAME} runner once --bot-name "${row.botName}"` : "",
2642
+ row.botName ? ` run_once_by_server_bot_name: ${CLI_NAME} runner once --bot-name "${row.botName}"` : "",
2641
2643
  ].join("\n") + "\n",
2642
2644
  );
2643
2645
  });
@@ -4300,7 +4302,7 @@ async function runDoctor(flags) {
4300
4302
  rows,
4301
4303
  strictMode ? "fail" : "warn",
4302
4304
  `runner route ${routeLabel} server_bot_id`,
4303
- `route bot_id ${route.botID} != local env ${envConfig.serverBotID}`,
4305
+ `route server_bot_id ${route.botID} != local env ${envConfig.serverBotID}`,
4304
4306
  );
4305
4307
  }
4306
4308
  if (route.botID && !envConfig.serverBotID) {
@@ -4323,7 +4325,7 @@ async function runDoctor(flags) {
4323
4325
  rows,
4324
4326
  strictMode ? "fail" : "warn",
4325
4327
  `runner route ${routeLabel} server_bot_id`,
4326
- `route bot_id ${route.botID} is set, but local env entry does not carry SERVER_BOT_ID`,
4328
+ `route server_bot_id ${route.botID} is set, but local env entry does not carry SERVER_BOT_ID`,
4327
4329
  );
4328
4330
  }
4329
4331
  }
@@ -1276,9 +1276,9 @@ function summarizeTelegramRouteLinks(parsedEnv, entry, serverBinding, deps) {
1276
1276
  const routeRole = String(route.role_profile || route.roleProfile || route.role || "").trim();
1277
1277
  let matchedBy = "";
1278
1278
  if (serverBotID && routeBotID === serverBotID) {
1279
- matchedBy = "bot_id";
1279
+ matchedBy = "server_bot_id";
1280
1280
  } else if (routeBotName && normalizedNames.has(routeBotName)) {
1281
- matchedBy = "bot_name";
1281
+ matchedBy = "server_bot_name";
1282
1282
  } else if (!routeBotID && !routeBotName && entryKey && defaultBotKey && entryKey === defaultBotKey) {
1283
1283
  matchedBy = "default_bot";
1284
1284
  }
@@ -1343,7 +1343,7 @@ function printBotShow(provider, state, entry, deps, extras = {}) {
1343
1343
  `global_file: ${state.filePath}`,
1344
1344
  `entry_file: ${resolveTelegramEntryFilePath(selectedEntry, deps) || "-"}`,
1345
1345
  `server_name: ${telegramEntryDisplayName(selectedEntry)}`,
1346
- `comparison_help: saved_local_file = values stored on disk | current_server_protocol = fresh /api/v1/me/bots response`,
1346
+ `comparison_help: saved_local_file = values saved on this machine | live_server_response = fresh /api/v1/me/bots response`,
1347
1347
  ];
1348
1348
  appendTextSection(lines, "saved_local_file", [
1349
1349
  `default_entry: ${selectedEntry.isDefault ? "yes" : "no"}`,
@@ -1378,7 +1378,7 @@ function printBotShow(provider, state, entry, deps, extras = {}) {
1378
1378
  liveLines.push(`server_role_ids_now: ${formatTelegramServerRoleIDs(serverBinding.serverRoleIDs) || "-"}`);
1379
1379
  liveLines.push(`runtime_role_profile: ${formatRoleProfileOutputLine(serverBinding.effectiveRoleProfile)}`);
1380
1380
  }
1381
- appendTextSection(lines, "current_server_protocol", liveLines);
1381
+ appendTextSection(lines, "live_server_response", liveLines);
1382
1382
  }
1383
1383
  const routeLines = [`count: ${intFromRaw(routeLinks.total, 0)}`];
1384
1384
  ensureArray(routeLinks.routes).forEach((route) => {
@@ -2850,7 +2850,7 @@ async function verifyProviderEntry(ui, provider, flags, deps) {
2850
2850
  `global_file: ${envConfig.filePath}`,
2851
2851
  provider === "telegram" ? `entry_file: ${resolveTelegramEntryFilePath(envConfig, deps) || "-"}` : "",
2852
2852
  `detail: ${result.detail || "-"}`,
2853
- provider === "telegram" ? `comparison_help: saved_local_file = values stored on disk | current_server_protocol = fresh /api/v1/me/bots response` : "",
2853
+ provider === "telegram" ? `comparison_help: saved_local_file = values saved on this machine | live_server_response = fresh /api/v1/me/bots response` : "",
2854
2854
  ];
2855
2855
  if (provider === "telegram") {
2856
2856
  appendTextSection(lines, "saved_local_file", [
@@ -2881,7 +2881,7 @@ async function verifyProviderEntry(ui, provider, flags, deps) {
2881
2881
  } else if (serverBinding.effectiveRoleProfile) {
2882
2882
  liveLines.push(`runtime_role_profile: ${formatRoleProfileOutputLine(serverBinding.effectiveRoleProfile)}`);
2883
2883
  }
2884
- appendTextSection(lines, "current_server_protocol", liveLines);
2884
+ appendTextSection(lines, "live_server_response", liveLines);
2885
2885
  }
2886
2886
  if (provider === "telegram" && routeLinks) {
2887
2887
  const routeSection = [`count: ${intFromRaw(routeLinks.total, 0)}`];
@@ -83,7 +83,7 @@ export function selectRunnerBot(bots, route, deps) {
83
83
  }
84
84
  const names = matches.map((item) => `${item.name} (${item.id})`).join(", ");
85
85
  throw new Error(
86
- `Multiple active ${providerLabel} bot profiles matched role "${normalizedRoute.role}". Set bot_name or bot_id. Matches: ${names}`,
86
+ `Multiple active ${providerLabel} bot profiles matched role "${normalizedRoute.role}". Set server_bot_name or server_bot_id in the route config, or use --bot-name / --bot-id on the command line. Matches: ${names}`,
87
87
  );
88
88
  }
89
89
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "metheus-governance-mcp-cli",
3
- "version": "0.2.108",
3
+ "version": "0.2.110",
4
4
  "description": "Metheus Governance MCP CLI (setup + stdio proxy)",
5
5
  "type": "module",
6
6
  "files": [
package/postinstall.mjs CHANGED
@@ -13,6 +13,9 @@ const PROVIDERS = [
13
13
  function resolveTargetPath(provider) {
14
14
  const home = String(process.env.USERPROFILE || process.env.HOME || os.homedir() || "").trim();
15
15
  if (!home) return "";
16
+ if (provider === "telegram") {
17
+ return path.join(home, ".metheus", "telegram-bots", "global.env");
18
+ }
16
19
  return path.join(home, ".metheus", `${provider}.env`);
17
20
  }
18
21
 
@@ -21,27 +24,16 @@ function template(provider, label, tokenKey) {
21
24
  return [
22
25
  `# Metheus local ${label} bot settings`,
23
26
  "# Keep this file on your machine only. Do not commit it.",
24
- "# Store Telegram bot secrets and local transport options here.",
25
- "# Project chat destinations must be managed on the Metheus server.",
26
- "# Per-bot local AI client/model binding can also be defined here.",
27
+ "# Store Telegram-wide transport options here.",
28
+ "# Per-bot secrets and AI settings live in ~/.metheus/telegram-bots/<ServerBotName>.env.",
27
29
  "",
28
- "# Legacy single-bot fallback:",
29
- `# ${tokenKey}=`,
30
- "",
31
- "# Preferred multi-bot mapping:",
32
30
  "TELEGRAM_API_BASE_URL=",
33
31
  "TELEGRAM_AUTO_CLEAR_WEBHOOK=true",
34
32
  "TELEGRAM_ALLOWED_UPDATES=message,edited_message",
35
- "TELEGRAM_DEFAULT_BOT_KEY=main",
33
+ "TELEGRAM_DEFAULT_BOT_KEY=",
36
34
  "",
37
- "TELEGRAM_BOT_MAIN_SERVER_BOT_ID=",
38
- "TELEGRAM_BOT_MAIN_USERNAME=",
39
- "TELEGRAM_BOT_MAIN_TOKEN=",
40
- "TELEGRAM_BOT_MAIN_ROLE_PROFILE=",
41
- "TELEGRAM_BOT_MAIN_AI_CLIENT=",
42
- "TELEGRAM_BOT_MAIN_AI_MODEL=",
43
- "TELEGRAM_BOT_MAIN_AI_PERMISSION_MODE=",
44
- "TELEGRAM_BOT_MAIN_AI_REASONING_EFFORT=",
35
+ "# Legacy single-bot fallback:",
36
+ `${tokenKey}=`,
45
37
  "",
46
38
  ].join("\n");
47
39
  }
@@ -101,8 +93,8 @@ function botRunnerTemplate() {
101
93
  },
102
94
  bot_bindings: {
103
95
  "<binding_key>": {
104
- bot_id: "<server_bot_uuid>",
105
- bot_name: "<bot_name>",
96
+ server_bot_id: "<server_bot_uuid>",
97
+ server_bot_name: "<server_bot_name>",
106
98
  role_profile: "monitor",
107
99
  client: "gpt",
108
100
  model: "",
@@ -117,8 +109,8 @@ function botRunnerTemplate() {
117
109
  project_id: "<project_uuid>",
118
110
  provider: "telegram",
119
111
  role: "monitor",
120
- bot_name: "",
121
- bot_id: "<server_bot_uuid>",
112
+ server_bot_name: "",
113
+ server_bot_id: "<server_bot_uuid>",
122
114
  destination_id: "",
123
115
  destination_label: "",
124
116
  archive_thread_id: "",