metheus-governance-mcp-cli 0.2.69 → 0.2.71

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
@@ -55,7 +55,8 @@ TELEGRAM_BOT_TOKEN=
55
55
 
56
56
  # Preferred named bot mapping
57
57
  TELEGRAM_BOT_MAIN_SERVER_BOT_ID=
58
- TELEGRAM_BOT_MAIN_USERNAME=<bot_username>
58
+ # Optional fallback only when server bot binding is unavailable
59
+ # TELEGRAM_BOT_MAIN_USERNAME=<bot_username>
59
60
  TELEGRAM_BOT_MAIN_TOKEN=
60
61
  TELEGRAM_BOT_MAIN_ROLE_PROFILE=monitor
61
62
  TELEGRAM_BOT_MAIN_AI_CLIENT=codex
@@ -225,17 +226,19 @@ metheus-governance-mcp-cli bot verify --provider telegram --bot-key main
225
226
  Behavior:
226
227
 
227
228
  - `bot setup` asks for `Telegram / Slack / KakaoTalk` first, then prompts with numbered actions.
228
- - `bot add` without flags starts a guided question flow: provider -> bot responsibility -> local bot key -> token -> verify.
229
- - For Telegram, the CLI asks for the server-side bot responsibility first and automatically resolves the matching server bot profile when the role is unique.
230
- - When you choose a Telegram responsibility such as `monitor`, the CLI automatically uses that server role as the local `role_profile` and fills blank AI defaults from your local `bot-runner.json` `role_profiles` mapping.
231
- - `bot edit` without flags starts a guided numbered flow: provider -> bot entry -> guided edit -> step-by-step field choices.
232
- - In guided `bot edit`, changing the bound Telegram responsibility can also auto-fill blank local AI fields from the selected server role and skip redundant role/AI prompts.
229
+ - `bot add` without flags now uses the shortest practical guided flow: provider -> token -> verify -> optional save-anyway only when verify fails -> optional username fallback only when verify cannot discover it -> optional default bot.
230
+ - In the normal Telegram path, `bot add` does not ask for a local bot key, a server bot UUID, or an approval / worker / review / monitor choice.
231
+ - For Telegram, the local env key is auto-generated from the matched server bot name or verified username, so you do not have to invent a separate local nickname first.
232
+ - For Telegram, the CLI tries to match the verified bot identity against the server `me/bots` list first. If the server exposes one logical bot name with multiple roles such as `approval`, `worker`, `review`, and `monitor`, the CLI does not ask you to choose one UUID. It binds by server bot name and keeps the local role/AI fields empty so runtime can use the server bot role for each route.
233
+ - When the Telegram username matches exactly one server bot role, the CLI still auto-fills the local `role_profile` and blank AI defaults from your local `bot-runner.json` `role_profiles` mapping.
234
+ - `bot edit` without flags now uses the same sequential flow every time: provider -> bot entry -> username/token review -> AI field choices -> default choice -> save.
235
+ - In the normal Telegram edit path, the CLI keeps or re-resolves the server bot binding automatically. It no longer asks you to pick `approval / worker / review / monitor` or a server bot UUID first.
233
236
  - `bot set-default` without flags starts a guided numbered flow: provider -> bot entry -> confirm default change.
234
237
  - `bot verify` without flags starts a guided numbered flow: provider -> bot entry -> output format.
235
238
  - `bot remove` without flags starts a guided numbered flow: provider -> bot entry -> confirm removal.
236
239
  - Telegram supports named local bot entries with:
237
240
  - `SERVER_BOT_ID`
238
- - `USERNAME`
241
+ - `USERNAME` (optional fallback only when server binding is unavailable)
239
242
  - `TOKEN`
240
243
  - `ROLE_PROFILE`
241
244
  - `AI_CLIENT`
@@ -253,7 +256,8 @@ Non-interactive examples:
253
256
 
254
257
  ```bash
255
258
  metheus-governance-mcp-cli bot global --provider telegram --non-interactive true --api-base-url http://127.0.0.1:8999/telegram --auto-clear-webhook false --allowed-updates message,edited_message,channel_post
256
- metheus-governance-mcp-cli bot add --provider telegram --non-interactive true --bot-key main --server-bot-id <server_bot_uuid> --username <telegram_username> --token <telegram_bot_token> --role-profile monitor --ai-client codex --ai-model gpt-5-codex --ai-permission-mode read_only --ai-reasoning-effort low --default true
259
+ metheus-governance-mcp-cli bot add --provider telegram --non-interactive true --server-bot-id <server_bot_uuid> --token <telegram_bot_token> --default true
260
+ metheus-governance-mcp-cli bot add --provider telegram --non-interactive true --server-bot-id <server_bot_uuid> --token <telegram_bot_token> --ai-client codex --ai-model gpt-5-codex --ai-permission-mode read_only --ai-reasoning-effort low
257
261
  metheus-governance-mcp-cli bot edit --provider telegram --bot-key main --non-interactive true --ai-client claude --ai-model claude-sonnet --ai-permission-mode workspace_write --ai-reasoning-effort medium
258
262
  metheus-governance-mcp-cli bot set-default --provider telegram --bot-key main --non-interactive true
259
263
  metheus-governance-mcp-cli bot migrate --provider telegram --bot-key main --server-bot-id <server_bot_uuid> --bot-name <telegram_username> --role-profile monitor --ai-client codex --ai-permission-mode read_only --ai-reasoning-effort low --non-interactive true
@@ -261,6 +265,8 @@ metheus-governance-mcp-cli bot remove --provider telegram --bot-key main --non-i
261
265
  metheus-governance-mcp-cli bot verify --provider telegram --bot-key main --json true
262
266
  ```
263
267
 
268
+ For direct Telegram adds, the CLI can derive the local entry key from the matched server bot name. You no longer need `--bot-key` or `--username` in the normal server-bound path. Treat `--bot-key` as an advanced override only when you intentionally want a different local suffix.
269
+
264
270
  Current support status:
265
271
 
266
272
  - Telegram: full local bot entry management, token verification, bot-to-AI binding, inbound runner support
package/cli.mjs CHANGED
@@ -748,7 +748,7 @@ function providerEnvTemplate(provider) {
748
748
  "# Preferred v2 multi-bot mapping:",
749
749
  "# TELEGRAM_DEFAULT_BOT_KEY=main",
750
750
  "# TELEGRAM_BOT_MAIN_SERVER_BOT_ID=<server bot uuid>",
751
- "# TELEGRAM_BOT_MAIN_USERNAME=<bot username>",
751
+ "# TELEGRAM_BOT_MAIN_USERNAME=<optional fallback username when server binding is unavailable>",
752
752
  "# TELEGRAM_BOT_MAIN_TOKEN=<bot token>",
753
753
  "# TELEGRAM_BOT_MAIN_ROLE_PROFILE=monitor",
754
754
  "# TELEGRAM_BOT_MAIN_AI_CLIENT=codex",
@@ -766,7 +766,6 @@ function providerEnvTemplate(provider) {
766
766
  "",
767
767
  "# Preferred named bot entry",
768
768
  "TELEGRAM_BOT_MAIN_SERVER_BOT_ID=",
769
- "TELEGRAM_BOT_MAIN_USERNAME=",
770
769
  "TELEGRAM_BOT_MAIN_TOKEN=",
771
770
  "TELEGRAM_BOT_MAIN_ROLE_PROFILE=",
772
771
  "TELEGRAM_BOT_MAIN_AI_CLIENT=",
@@ -2730,7 +2729,9 @@ function resolveTelegramEnvConfig(parsedEnv, filePath, config, selectors = {}) {
2730
2729
  selected = entries.find((entry) => entry.serverBotID === desiredBotID) || null;
2731
2730
  }
2732
2731
  if (!selected && desiredUsername) {
2733
- selected = entries.find((entry) => entry.username === desiredUsername) || null;
2732
+ selected = entries.find(
2733
+ (entry) => entry.username === desiredUsername || normalizeTelegramBotUsername(entry.key) === desiredUsername,
2734
+ ) || null;
2734
2735
  }
2735
2736
  if (!selected && desiredBotKey) {
2736
2737
  selected = entries.find((entry) => entry.key === desiredBotKey) || null;
@@ -3697,8 +3698,9 @@ async function runDoctor(flags) {
3697
3698
  }
3698
3699
  const detailParts = [];
3699
3700
  if (envConfig.botKey) detailParts.push(`bot=${envConfig.botKey}`);
3700
- if (envConfig.botUsername) detailParts.push(`@${envConfig.botUsername}`);
3701
- if (envConfig.serverBotID) detailParts.push(`server_bot_id=${envConfig.serverBotID}`);
3701
+ if (envConfig.botUsername) detailParts.push(`@${envConfig.botUsername}`);
3702
+ if (envConfig.serverBotID) detailParts.push(`server_bot_id=${envConfig.serverBotID}`);
3703
+ else if (envConfig.botKey) detailParts.push(`server_name=${envConfig.botKey}`);
3702
3704
  if (envConfig.client) detailParts.push(`ai=${envConfig.client}`);
3703
3705
  addDoctorCheck(
3704
3706
  rows,
@@ -3715,12 +3717,28 @@ async function runDoctor(flags) {
3715
3717
  );
3716
3718
  }
3717
3719
  if (route.botID && !envConfig.serverBotID) {
3718
- addDoctorCheck(
3719
- rows,
3720
- strictMode ? "fail" : "warn",
3721
- `runner route ${routeLabel} server_bot_id`,
3722
- `route bot_id ${route.botID} is set, but local env entry does not carry SERVER_BOT_ID`,
3720
+ const serverMatch = ensureArray(serverBots).find((bot) => String(bot.id || "").trim() === String(route.botID || "").trim());
3721
+ const routeBotName = normalizeTelegramBotUsername(
3722
+ firstNonEmptyString([route.botName, route.bot_name, serverMatch?.name]),
3723
3723
  );
3724
+ const envBotName = normalizeTelegramBotUsername(envConfig.botUsername || envConfig.botKey);
3725
+ if (routeBotName && envBotName && routeBotName === envBotName) {
3726
+ addDoctorCheck(
3727
+ rows,
3728
+ "ok",
3729
+ `runner route ${routeLabel} server bot`,
3730
+ envConfig.botUsername
3731
+ ? `resolved by bot username @${envConfig.botUsername}`
3732
+ : `resolved by server bot name ${envConfig.botKey}`,
3733
+ );
3734
+ } else {
3735
+ addDoctorCheck(
3736
+ rows,
3737
+ strictMode ? "fail" : "warn",
3738
+ `runner route ${routeLabel} server_bot_id`,
3739
+ `route bot_id ${route.botID} is set, but local env entry does not carry SERVER_BOT_ID`,
3740
+ );
3741
+ }
3724
3742
  }
3725
3743
  if (serverBots && route.botID) {
3726
3744
  const match = ensureArray(serverBots).find((bot) => String(bot.id || "").trim() === String(route.botID || "").trim());