metheus-governance-mcp-cli 0.2.105 → 0.2.106

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
@@ -58,9 +58,9 @@ TELEGRAM_BOT_TOKEN=
58
58
  ```
59
59
 
60
60
  ```env
61
- # ~/.metheus/telegram-bots/RyoAI_bot.env
61
+ # ~/.metheus/telegram-bots/<ServerBotName>.env
62
62
  TELEGRAM_BOT_SERVER_BOT_ID=<server_bot_uuid>
63
- TELEGRAM_BOT_SERVER_NAME=RyoAI_bot
63
+ TELEGRAM_BOT_SERVER_NAME=<ServerBotName>
64
64
  TELEGRAM_BOT_SERVER_ROLES=monitor,review,worker,approval
65
65
  TELEGRAM_BOT_SERVER_ROLE_IDS=monitor:<uuid>,review:<uuid>,worker:<uuid>,approval:<uuid>
66
66
  # Optional fallback only when server bot binding is unavailable
@@ -233,22 +233,22 @@ Direct commands:
233
233
 
234
234
  ```bash
235
235
  metheus-governance-mcp-cli bot list
236
- metheus-governance-mcp-cli bot show --provider telegram --bot-name RyoAI_bot
236
+ metheus-governance-mcp-cli bot show --provider telegram --bot-name <server_bot_name>
237
237
  metheus-governance-mcp-cli bot add --provider telegram
238
238
  metheus-governance-mcp-cli bot edit
239
239
  metheus-governance-mcp-cli bot edit --provider telegram
240
240
  metheus-governance-mcp-cli bot remove --provider telegram
241
- metheus-governance-mcp-cli bot set-default --provider telegram --bot-name RyoAI_bot
242
- metheus-governance-mcp-cli bot migrate --provider telegram --bot-name RyoAI_bot
241
+ metheus-governance-mcp-cli bot set-default --provider telegram --bot-name <server_bot_name>
242
+ metheus-governance-mcp-cli bot migrate --provider telegram --bot-name <server_bot_name>
243
243
  metheus-governance-mcp-cli bot global --provider telegram
244
- metheus-governance-mcp-cli bot verify --provider telegram --bot-name RyoAI_bot
244
+ metheus-governance-mcp-cli bot verify --provider telegram --bot-name <server_bot_name>
245
245
  ```
246
246
 
247
247
  Behavior:
248
248
 
249
249
  - `bot setup` asks for `Telegram / Slack / KakaoTalk` first, then prompts with numbered actions.
250
250
  - `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 AI model selection when the resolved defaults leave it blank -> optional default bot.
251
- - 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.
251
+ - In the normal Telegram path, `bot add` does not ask for an advanced local selector, a server bot UUID, or an approval / worker / review / monitor choice.
252
252
  - For Telegram, the local bot file stem is auto-generated from the matched server bot name or verified username, so you do not have to invent a separate local nickname first.
253
253
  - 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.
254
254
  - 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.
@@ -284,7 +284,7 @@ Behavior:
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
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.
287
- - `bot global` edits Telegram-wide local settings such as API base URL, allowed updates, and default bot key.
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` updates `TELEGRAM_DEFAULT_BOT_KEY`.
289
289
  - `bot migrate` moves legacy `TELEGRAM_BOT_TOKEN` into a named Telegram bot entry.
290
290
 
@@ -294,11 +294,11 @@ Non-interactive examples:
294
294
  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
295
295
  metheus-governance-mcp-cli bot add --provider telegram --non-interactive true --server-bot-id <server_bot_uuid> --token <telegram_bot_token> --default true
296
296
  metheus-governance-mcp-cli bot add --provider telegram --non-interactive true --server-bot-id <server_bot_uuid> --token <telegram_bot_token> --ai-client gpt --ai-model "gpt-5.4" --ai-permission-mode read_only --ai-reasoning-effort low
297
- metheus-governance-mcp-cli bot edit --provider telegram --bot-name RyoAI_bot --non-interactive true --ai-client claude --ai-model "Sonnet 4.6r" --ai-permission-mode danger_full_access --ai-reasoning-effort high
298
- metheus-governance-mcp-cli bot set-default --provider telegram --bot-name RyoAI_bot --non-interactive true
299
- metheus-governance-mcp-cli bot migrate --provider telegram --bot-name RyoAI_bot --server-bot-id <server_bot_uuid> --role-profile monitor --ai-client gpt --ai-permission-mode read_only --ai-reasoning-effort low --non-interactive true
300
- metheus-governance-mcp-cli bot remove --provider telegram --bot-name RyoAI_bot --non-interactive true
301
- metheus-governance-mcp-cli bot verify --provider telegram --bot-name RyoAI_bot --json true
297
+ metheus-governance-mcp-cli bot edit --provider telegram --bot-name <server_bot_name> --non-interactive true --ai-client claude --ai-model "Sonnet 4.6r" --ai-permission-mode danger_full_access --ai-reasoning-effort high
298
+ metheus-governance-mcp-cli bot set-default --provider telegram --bot-name <server_bot_name> --non-interactive true
299
+ metheus-governance-mcp-cli bot migrate --provider telegram --bot-name <server_bot_name> --server-bot-id <server_bot_uuid> --role-profile monitor --ai-client gpt --ai-permission-mode read_only --ai-reasoning-effort low --non-interactive true
300
+ metheus-governance-mcp-cli bot remove --provider telegram --bot-name <server_bot_name> --non-interactive true
301
+ metheus-governance-mcp-cli bot verify --provider telegram --bot-name <server_bot_name> --json true
302
302
  ```
303
303
 
304
304
  For direct Telegram adds, the CLI derives the local file name from the matched server bot name. You normally do not need `--bot-key` or `--username`. Treat `--bot-key` as an advanced compatibility selector only when you intentionally need to target an older local selector directly.
@@ -228,7 +228,7 @@ function printBotUsage(deps) {
228
228
  `Behavior:`,
229
229
  ` - bot setup asks for provider first, then shows a numbered action menu.`,
230
230
  ` - bot add without flags uses the shortest practical guided flow: provider -> token -> verify -> optional username fallback -> optional default bot.`,
231
- ` - in the normal Telegram path, bot add does not ask for a local bot key or a server role/profile choice.`,
231
+ ` - in the normal Telegram path, bot add does not ask for an advanced local selector or a server role/profile choice.`,
232
232
  ` - server bot name/UUID is the source of truth; --bot-key is an advanced compatibility selector only.`,
233
233
  ` - runner commands can auto-select by --bot-name or --bot-id when one enabled route matches. Use runner list first if you are unsure.`,
234
234
  ` - bot edit without flags asks for provider, existing entry, then walks field-by-field in a numbered flow.`,
@@ -1568,12 +1568,12 @@ async function chooseServerBot(ui, provider, baseURL, timeoutSeconds, deps, opti
1568
1568
  {
1569
1569
  value: "__manual__",
1570
1570
  label: "Manual entry",
1571
- description: "type the server bot UUID yourself",
1571
+ description: "enter a server bot UUID manually",
1572
1572
  },
1573
1573
  {
1574
1574
  value: "__blank__",
1575
1575
  label: "Leave empty",
1576
- description: "skip server bot UUID binding",
1576
+ description: "continue without a server bot binding",
1577
1577
  },
1578
1578
  ],
1579
1579
  { defaultIndex: 0 },
@@ -1618,12 +1618,12 @@ async function chooseServerBot(ui, provider, baseURL, timeoutSeconds, deps, opti
1618
1618
  {
1619
1619
  value: "__manual__",
1620
1620
  label: "Manual entry",
1621
- description: "type the server bot UUID yourself",
1621
+ description: "enter a server bot UUID manually",
1622
1622
  },
1623
1623
  {
1624
1624
  value: "__blank__",
1625
1625
  label: "Leave empty",
1626
- description: "skip server bot UUID binding",
1626
+ description: "continue without a server bot binding",
1627
1627
  },
1628
1628
  ],
1629
1629
  { defaultIndex: 0 },
@@ -1710,7 +1710,7 @@ async function resolveServerBotForNonInteractive(provider, flags, deps, options
1710
1710
  (bot) => normalizeServerBotIdentityText(bot.name) === requestedName,
1711
1711
  );
1712
1712
  if (!matchedByName.length) {
1713
- throw new Error(`no server bot matched ${requestedName}`);
1713
+ throw new Error(`no server bot matched the requested server bot name "${requestedName}"`);
1714
1714
  }
1715
1715
  if (matchedByName.length === 1) {
1716
1716
  const match = matchedByName[0] || {};
@@ -1789,23 +1789,26 @@ async function promptAIModel(ui, deps, clientName, defaultValue = "", title = "S
1789
1789
  const normalizedClient = requireDependency(deps, "normalizeLocalAIClientName")(clientName || "", "");
1790
1790
  const currentValue = String(defaultValue || "").trim();
1791
1791
  const suggestions = suggestedAIModelsForClient(normalizedClient);
1792
+ const currentMatchesSuggestions = currentValue && suggestions.some((item) => item.value === currentValue);
1792
1793
  const options = [
1793
1794
  { value: "", label: "(blank)", description: "leave AI model empty" },
1794
1795
  ];
1795
- if (currentValue && !suggestions.some((item) => item.value === currentValue)) {
1796
+ options.push(...suggestions);
1797
+ if (currentValue && !currentMatchesSuggestions) {
1796
1798
  options.push({
1797
1799
  value: currentValue,
1798
- label: currentValue,
1799
- description: "current saved model",
1800
+ label: `Keep current custom model (${currentValue})`,
1801
+ description: "reuse the model already saved on disk",
1800
1802
  });
1801
1803
  }
1802
- options.push(...suggestions);
1803
1804
  options.push({
1804
1805
  value: "__manual__",
1805
1806
  label: "Manual entry",
1806
1807
  description: "type the model name yourself",
1807
1808
  });
1808
- const selectedIndex = Math.max(0, options.findIndex((item) => item.value === currentValue));
1809
+ const selectedIndex = currentMatchesSuggestions
1810
+ ? Math.max(0, options.findIndex((item) => item.value === currentValue))
1811
+ : (suggestions.length ? 1 : Math.max(0, options.findIndex((item) => item.value === currentValue)));
1809
1812
  const selected = await promptChoice(ui, title, options, { defaultIndex: selectedIndex >= 0 ? selectedIndex : 0 });
1810
1813
  if (String(selected?.value || "") === "__manual__") {
1811
1814
  return String(await promptRequiredLine(ui, "AI model", currentValue)).trim();
@@ -2154,6 +2157,11 @@ function resolveTelegramServerBindingDetailsFromBots(envConfig, bots, deps) {
2154
2157
  const normalizedServerIdentity = normalizeServerBotIdentityText(current.serverBotName || current.botUsername || current.botKey);
2155
2158
  const matches = bots.filter((bot) => normalizeServerBotIdentityText(bot.name) === normalizedServerIdentity);
2156
2159
  if (!matches.length) {
2160
+ const unmatchedIdentity = String(current.botUsername || "").trim()
2161
+ ? `@${String(current.botUsername || "").trim()}`
2162
+ : String(current.serverBotName || "").trim()
2163
+ ? `"${String(current.serverBotName || "").trim()}"`
2164
+ : "this local Telegram bot";
2157
2165
  return {
2158
2166
  ok: false,
2159
2167
  mode: "missing",
@@ -2165,7 +2173,7 @@ function resolveTelegramServerBindingDetailsFromBots(envConfig, bots, deps) {
2165
2173
  serverBotID: "",
2166
2174
  effectiveRoleProfile: null,
2167
2175
  effectiveRoleProfiles: {},
2168
- detail: `no server bot matched ${current.botUsername ? `@${current.botUsername}` : current.botKey}`,
2176
+ detail: `no server bot matched ${unmatchedIdentity}`,
2169
2177
  };
2170
2178
  }
2171
2179
  if (matches.length > 1) {
@@ -2422,12 +2430,12 @@ async function addTelegramBot(ui, flags, deps) {
2422
2430
  defaultKeyHint,
2423
2431
  );
2424
2432
  if (nonInteractive && existingKeys.has(botKey)) {
2425
- throw new Error(`Telegram bot key "${botKey}" already exists`);
2433
+ throw new Error(`Telegram local selector "${botKey}" already exists`);
2426
2434
  }
2427
2435
  const serverGroupMatched = serverBot.matchMode === "group";
2428
2436
  if (serverGroupMatched && !nonInteractive) {
2429
2437
  process.stdout.write(
2430
- `Matched server Telegram bot "${serverBot.name || username || botKey}" with roles: ${ensureArray(serverBot.roles).join(", ")}. Runtime will use the server role, so local role/AI fields can stay empty.\n`,
2438
+ `Matched server Telegram bot "${serverBot.name || username || "current Telegram bot"}" with roles: ${ensureArray(serverBot.roles).join(", ")}. Runtime will use the server role, so local role/AI fields can stay empty.\n`,
2431
2439
  );
2432
2440
  }
2433
2441
  const aiFlagOverrides = hasOwnFlag(flags, "client")
@@ -2528,7 +2536,7 @@ async function addTelegramBot(ui, flags, deps) {
2528
2536
  }
2529
2537
 
2530
2538
  const filePath = writeProviderEnvState("telegram", nextParsed, deps);
2531
- process.stdout.write(`Saved Telegram bot entry "${botKey}" to ${filePath}\n`);
2539
+ process.stdout.write(`Saved Telegram bot file for "${String(serverBot.name || username || botKey).trim() || "telegram"}" to ${filePath}\n`);
2532
2540
  }
2533
2541
 
2534
2542
  async function editTelegramGlobalSettings(ui, flags, deps) {
@@ -2559,7 +2567,7 @@ async function editTelegramGlobalSettings(ui, flags, deps) {
2559
2567
  { value: "api", label: "API base URL", description: String(parsed.TELEGRAM_API_BASE_URL || "").trim() || "(empty)" },
2560
2568
  { value: "webhook", label: "Auto clear webhook", description: boolFromRaw(parsed.TELEGRAM_AUTO_CLEAR_WEBHOOK, true) ? "true" : "false" },
2561
2569
  { value: "updates", label: "Allowed updates", description: String(parsed.TELEGRAM_ALLOWED_UPDATES || "message,edited_message").trim() },
2562
- { value: "default", label: "Default bot key", description: String(parsed.TELEGRAM_DEFAULT_BOT_KEY || "").trim() || "(empty)" },
2570
+ { value: "default", label: "Default Telegram bot", description: String(parsed.TELEGRAM_DEFAULT_BOT_KEY || "").trim() || "(empty)" },
2563
2571
  ],
2564
2572
  { defaultIndex: 0 },
2565
2573
  );
@@ -2669,7 +2677,7 @@ async function removeTelegramBot(ui, flags, deps) {
2669
2677
  nextParsed.TELEGRAM_DEFAULT_BOT_KEY = remaining[0]?.key || "";
2670
2678
  }
2671
2679
  const filePath = writeProviderEnvState("telegram", nextParsed, deps);
2672
- process.stdout.write(`Removed Telegram bot "${selected.key}" from ${filePath}\n`);
2680
+ process.stdout.write(`Removed Telegram bot file for "${String(selected.serverBotName || selected.username || selected.key).trim() || "telegram"}" from ${filePath}\n`);
2673
2681
  }
2674
2682
 
2675
2683
  async function verifyProviderEntry(ui, provider, flags, deps) {
@@ -3105,7 +3113,7 @@ async function runBotRemove(ui, flags, deps) {
3105
3113
  nextParsed.TELEGRAM_DEFAULT_BOT_KEY = remaining[0]?.key || "";
3106
3114
  }
3107
3115
  const filePath = writeProviderEnvState("telegram", nextParsed, deps);
3108
- process.stdout.write(`Removed Telegram bot "${selected.key}" from ${filePath}\n`);
3116
+ process.stdout.write(`Removed Telegram bot file for "${String(selected.serverBotName || selected.username || selected.key).trim() || "telegram"}" from ${filePath}\n`);
3109
3117
  return;
3110
3118
  }
3111
3119
  await removeTelegramBot(ui, flags, deps);
@@ -3178,11 +3186,11 @@ async function runBotMigrate(ui, flags, deps) {
3178
3186
  const botKey = normalizeBotKey(
3179
3187
  nonInteractive
3180
3188
  ? String(flags["bot-key"] || defaultKeyHint).trim()
3181
- : await promptRequiredLine(ui, "Local Telegram bot key for migrated entry", defaultKeyHint),
3189
+ : await promptRequiredLine(ui, "Advanced local selector for migrated entry", defaultKeyHint),
3182
3190
  defaultKeyHint,
3183
3191
  );
3184
3192
  if (existingKeys.has(botKey)) {
3185
- throw new Error(`Telegram bot key "${botKey}" already exists`);
3193
+ throw new Error(`Telegram local selector "${botKey}" already exists`);
3186
3194
  }
3187
3195
  const nextParsed = upsertTelegramEntry(parsed, {
3188
3196
  key: botKey,
@@ -3203,7 +3211,7 @@ async function runBotMigrate(ui, flags, deps) {
3203
3211
  }
3204
3212
  const filePath = writeProviderEnvState("telegram", nextParsed, deps);
3205
3213
  process.stdout.write(
3206
- `Migrated TELEGRAM_BOT_TOKEN to named entry "${botKey}" in ${filePath}${boolFromRaw(flags["keep-legacy-token"], false) ? " (legacy token preserved)" : ""}\n`,
3214
+ `Migrated TELEGRAM_BOT_TOKEN to named entry selector "${botKey}" in ${filePath}${boolFromRaw(flags["keep-legacy-token"], false) ? " (legacy token preserved)" : ""}\n`,
3207
3215
  );
3208
3216
  }
3209
3217
 
@@ -63,7 +63,7 @@ export async function runDoctorProjectDestinationChecks({
63
63
  }
64
64
  const tokenDetailParts = [`configured (${envConfig.filePath})`];
65
65
  if (envConfig.botKey) {
66
- tokenDetailParts.push(`bot=${envConfig.botKey}`);
66
+ tokenDetailParts.push(`local_selector=${envConfig.botKey}`);
67
67
  }
68
68
  if (envConfig.botUsername) {
69
69
  tokenDetailParts.push(`@${envConfig.botUsername}`);
@@ -95,7 +95,7 @@ function createMockServer(options = {}) {
95
95
  : [
96
96
  {
97
97
  id: "11111111-2222-3333-4444-555555555555",
98
- name: "MonitorSelftestBot",
98
+ name: "ServerProtocolMonitorBot",
99
99
  provider: "telegram",
100
100
  bot_role: "monitor",
101
101
  is_active: true,
@@ -105,8 +105,8 @@ function createMockServer(options = {}) {
105
105
  ensureArray(options.telegramUsersByToken).length
106
106
  ? ensureArray(options.telegramUsersByToken)
107
107
  : [
108
- ["selftest-main-token", "MonitorSelftestBot"],
109
- ["selftest-edited-token", "MonitorSelftestBot"],
108
+ ["selftest-main-token", "ServerProtocolMonitorBot"],
109
+ ["selftest-edited-token", "ServerProtocolMonitorBot"],
110
110
  ],
111
111
  );
112
112
 
@@ -290,6 +290,7 @@ export async function runSelftestBotCommands(push, deps) {
290
290
  const telegramApiBaseURL = `${baseURL}/telegram`;
291
291
  const telegramBotEntriesDir = path.join(tempHome, ".metheus", "telegram-bots");
292
292
  const telegramEnvPath = path.join(telegramBotEntriesDir, "global.env");
293
+ const botRunnerConfigPath = path.join(tempHome, ".metheus", "bot-runner.json");
293
294
  const readTelegramGlobals = () => parseSimpleEnvText(fs.readFileSync(telegramEnvPath, "utf8"));
294
295
  const readTelegramBotEntry = (selector) => {
295
296
  const requested = String(selector || "").trim().toLowerCase();
@@ -309,6 +310,42 @@ export async function runSelftestBotCommands(push, deps) {
309
310
  }
310
311
  return parseSimpleEnvText(fs.readFileSync(filePath, "utf8"));
311
312
  };
313
+ fs.mkdirSync(path.join(tempHome, ".metheus"), { recursive: true });
314
+ fs.writeFileSync(
315
+ botRunnerConfigPath,
316
+ `${JSON.stringify({
317
+ version: 2,
318
+ project_mappings: {},
319
+ role_profiles: {
320
+ monitor: {
321
+ client: "gpt",
322
+ model: "",
323
+ permission_mode: "read_only",
324
+ reasoning_effort: "low",
325
+ },
326
+ review: {
327
+ client: "claude",
328
+ model: "Sonnet 4.6r",
329
+ permission_mode: "danger_full_access",
330
+ reasoning_effort: "high",
331
+ },
332
+ worker: {
333
+ client: "gpt",
334
+ model: "gpt-5.4",
335
+ permission_mode: "danger_full_access",
336
+ reasoning_effort: "high",
337
+ },
338
+ approval: {
339
+ client: "claude",
340
+ model: "Sonnet 4.6r",
341
+ permission_mode: "danger_full_access",
342
+ reasoning_effort: "high",
343
+ },
344
+ },
345
+ routes: [],
346
+ }, null, 2)}\n`,
347
+ "utf8",
348
+ );
312
349
 
313
350
  const setupResult = await runCLI({
314
351
  cliPath,
@@ -359,29 +396,29 @@ export async function runSelftestBotCommands(push, deps) {
359
396
  ]),
360
397
  },
361
398
  });
362
- const addState = readTelegramBotEntry("monitorselftestbot");
399
+ const addState = readTelegramBotEntry("serverprotocolmonitorbot");
363
400
  const addGlobals = readTelegramGlobals();
364
401
  push(
365
402
  "bot_add_guided_creates_named_telegram_entry",
366
- String(addState.TELEGRAM_BOT_SERVER_NAME || "") === "MonitorSelftestBot"
403
+ String(addState.TELEGRAM_BOT_SERVER_NAME || "") === "ServerProtocolMonitorBot"
367
404
  && String(addState.TELEGRAM_BOT_SERVER_ROLES || "") === "monitor"
368
405
  && String(addState.TELEGRAM_BOT_TOKEN || "") === "selftest-main-token"
369
406
  && String(addState.TELEGRAM_BOT_ROLE_PROFILE || "") === "monitor"
370
407
  && String(addState.TELEGRAM_BOT_AI_CLIENT || "") === "gpt"
371
408
  && String(addState.TELEGRAM_BOT_AI_PERMISSION_MODE || "") === "read_only"
372
409
  && String(addState.TELEGRAM_BOT_AI_REASONING_EFFORT || "") === "low"
373
- && String(addGlobals.TELEGRAM_DEFAULT_BOT_KEY || "") === "monitorselftestbot",
410
+ && String(addGlobals.TELEGRAM_DEFAULT_BOT_KEY || "") === "serverprotocolmonitorbot",
374
411
  `default=${String(addGlobals.TELEGRAM_DEFAULT_BOT_KEY || "")} token=${String(addState.TELEGRAM_BOT_TOKEN || "")} server_name=${String(addState.TELEGRAM_BOT_SERVER_NAME || "")} roles=${String(addState.TELEGRAM_BOT_SERVER_ROLES || "")} role=${String(addState.TELEGRAM_BOT_ROLE_PROFILE || "")} client=${String(addState.TELEGRAM_BOT_AI_CLIENT || "")}`,
375
412
  );
376
413
 
377
414
  const groupedMock = await createMockServer({
378
415
  serverBots: [
379
- { id: "977ef999-c40b-4cf6-a142-ade246f1b9cf", name: "RyoAI_bot", provider: "telegram", bot_role: "approval", is_active: true },
380
- { id: "d74b57de-a635-4bac-a20f-f8ada188cf97", name: "RyoAI_bot", provider: "telegram", bot_role: "worker", is_active: true },
381
- { id: "bbae9450-4236-487c-9a05-61dc4a626215", name: "RyoAI_bot", provider: "telegram", bot_role: "review", is_active: true },
382
- { id: "353896c5-3b6b-422f-9eeb-5dc9354f77b3", name: "RyoAI_bot", provider: "telegram", bot_role: "monitor", is_active: true },
416
+ { id: "977ef999-c40b-4cf6-a142-ade246f1b9cf", name: "GroupedServerProtocolBot", provider: "telegram", bot_role: "approval", is_active: true },
417
+ { id: "d74b57de-a635-4bac-a20f-f8ada188cf97", name: "GroupedServerProtocolBot", provider: "telegram", bot_role: "worker", is_active: true },
418
+ { id: "bbae9450-4236-487c-9a05-61dc4a626215", name: "GroupedServerProtocolBot", provider: "telegram", bot_role: "review", is_active: true },
419
+ { id: "353896c5-3b6b-422f-9eeb-5dc9354f77b3", name: "GroupedServerProtocolBot", provider: "telegram", bot_role: "monitor", is_active: true },
383
420
  ],
384
- telegramUsersByToken: [["selftest-group-token", "RyoAI_bot"]],
421
+ telegramUsersByToken: [["selftest-group-token", "GroupedServerProtocolBot"]],
385
422
  }).listen();
386
423
  try {
387
424
  await runCLI({
@@ -410,11 +447,11 @@ export async function runSelftestBotCommands(push, deps) {
410
447
  ]),
411
448
  },
412
449
  });
413
- const groupedState = readTelegramBotEntry("ryoai_bot");
450
+ const groupedState = readTelegramBotEntry("groupedserverprotocolbot");
414
451
  push(
415
452
  "bot_add_guided_autoresolves_server_bot_group_without_role_prompt",
416
453
  String(groupedState.TELEGRAM_BOT_SERVER_BOT_ID || "") === ""
417
- && String(groupedState.TELEGRAM_BOT_SERVER_NAME || "") === "RyoAI_bot"
454
+ && String(groupedState.TELEGRAM_BOT_SERVER_NAME || "") === "GroupedServerProtocolBot"
418
455
  && String(groupedState.TELEGRAM_BOT_SERVER_ROLES || "") === "monitor,review,worker,approval"
419
456
  && String(groupedState.TELEGRAM_BOT_ROLE_PROFILE || "") === ""
420
457
  && String(groupedState.TELEGRAM_BOT_AI_CLIENT || "") === ""
@@ -433,13 +470,13 @@ export async function runSelftestBotCommands(push, deps) {
433
470
  ...env,
434
471
  METHEUS_SCRIPTED_PROMPT_ANSWERS: JSON.stringify([
435
472
  "1", // provider: telegram
436
- "2", // bot entry: ryoai_bot
473
+ "1", // bot entry: GroupedServerProtocolBot
437
474
  "1", // keep token
438
475
  "2", // grouped role settings: edit one role
439
476
  "3", // select role to edit: worker
440
477
  "2", // worker: edit settings
441
478
  "3", // worker AI client: claude
442
- "3", // worker AI model: Sonnet 4.6r
479
+ "2", // worker AI model: Sonnet 4.6r
443
480
  "4", // worker permission: danger_full_access
444
481
  "4", // worker reasoning: high
445
482
  "y", // edit another role
@@ -462,15 +499,16 @@ export async function runSelftestBotCommands(push, deps) {
462
499
  );
463
500
  const groupedRunnerConfigPath = path.join(tempHome, ".metheus", "bot-runner.json");
464
501
  const groupedRunnerConfig = readJSON(fs.readFileSync(groupedRunnerConfigPath, "utf8"));
502
+ const groupedRoleProfiles = safeObject(groupedRunnerConfig.role_profiles || groupedRunnerConfig.roleProfiles);
465
503
  push(
466
504
  "bot_edit_grouped_server_roles_updates_role_profiles",
467
- String(safeObject(safeObject(groupedRunnerConfig.role_profiles || {}).worker).client || "") === "claude"
468
- && String(safeObject(safeObject(groupedRunnerConfig.role_profiles || {}).worker).model || "") === "Sonnet 4.6r"
469
- && String(safeObject(safeObject(groupedRunnerConfig.role_profiles || {}).worker).permission_mode || "") === "danger_full_access"
470
- && String(safeObject(safeObject(groupedRunnerConfig.role_profiles || {}).worker).reasoning_effort || "") === "high"
471
- && String(safeObject(safeObject(groupedRunnerConfig.role_profiles || {}).approval).client || "") === "gemini"
472
- && String(safeObject(safeObject(groupedRunnerConfig.role_profiles || {}).approval).model || "") === "gemini-3.1-pro",
473
- `worker=${JSON.stringify(safeObject(safeObject(groupedRunnerConfig.role_profiles || {}).worker))} approval=${JSON.stringify(safeObject(safeObject(groupedRunnerConfig.role_profiles || {}).approval))}`,
505
+ String(safeObject(safeObject(groupedRoleProfiles).worker).client || "") === "claude"
506
+ && String(safeObject(safeObject(groupedRoleProfiles).worker).model || "") === "Sonnet 4.6r"
507
+ && String(safeObject(safeObject(groupedRoleProfiles).worker).permission_mode || "") === "danger_full_access"
508
+ && String(safeObject(safeObject(groupedRoleProfiles).worker).reasoning_effort || "") === "high"
509
+ && String(safeObject(safeObject(groupedRoleProfiles).approval).client || "") === "gemini"
510
+ && String(safeObject(safeObject(groupedRoleProfiles).approval).model || "") === "gemini-3.1-pro",
511
+ `worker=${JSON.stringify(safeObject(safeObject(groupedRoleProfiles).worker))} approval=${JSON.stringify(safeObject(safeObject(groupedRoleProfiles).approval))}`,
474
512
  );
475
513
 
476
514
  const groupedShowResult = await runCLI({
@@ -478,7 +516,7 @@ export async function runSelftestBotCommands(push, deps) {
478
516
  args: [
479
517
  "bot", "show",
480
518
  "--provider", "telegram",
481
- "--bot-key", "ryoai_bot",
519
+ "--bot-key", "groupedserverprotocolbot",
482
520
  "--base-url", `http://127.0.0.1:${groupedMock.port}`,
483
521
  "--json", "true",
484
522
  ],
@@ -512,7 +550,7 @@ export async function runSelftestBotCommands(push, deps) {
512
550
  args: [
513
551
  "bot", "show",
514
552
  "--provider", "telegram",
515
- "--bot-key", "monitorselftestbot",
553
+ "--bot-key", "serverprotocolmonitorbot",
516
554
  "--base-url", baseURL,
517
555
  "--json", "true",
518
556
  ],
@@ -543,7 +581,7 @@ export async function runSelftestBotCommands(push, deps) {
543
581
  args: [
544
582
  "bot", "show",
545
583
  "--provider", "telegram",
546
- "--bot-key", "monitorselftestbot",
584
+ "--bot-key", "serverprotocolmonitorbot",
547
585
  "--base-url", baseURL,
548
586
  "--json", "true",
549
587
  ],
@@ -552,7 +590,7 @@ export async function runSelftestBotCommands(push, deps) {
552
590
  const showWithRoutesPayload = readJSON(showWithRoutesResult.stdout);
553
591
  push(
554
592
  "bot_show_returns_selected_telegram_entry",
555
- safeObject(showPayload.entry).key === "monitorselftestbot"
593
+ safeObject(showPayload.entry).key === "serverprotocolmonitorbot"
556
594
  && safeObject(showPayload.entry).client === "gpt"
557
595
  && safeObject(showPayload.serverBinding).mode === "single",
558
596
  `key=${String(safeObject(showPayload.entry).key || "")} client=${String(safeObject(showPayload.entry).client || "")} mode=${String(safeObject(showPayload.serverBinding).mode || "")}`,
@@ -574,12 +612,12 @@ export async function runSelftestBotCommands(push, deps) {
574
612
  ...env,
575
613
  METHEUS_SCRIPTED_PROMPT_ANSWERS: JSON.stringify([
576
614
  "1", // provider: telegram
577
- "1", // bot entry: @monitorselftestbot
615
+ "2", // bot entry: @serverprotocolmonitorbot
578
616
  "1", // keep token
579
617
  "2", // change AI client
580
618
  "4", // gemini
581
619
  "2", // change AI model
582
- "3", // gemini model: gemini-3.1-pro
620
+ "2", // gemini model: gemini-3.1-pro
583
621
  "2", // change permission mode
584
622
  "3", // workspace_write
585
623
  "2", // change reasoning effort
@@ -594,7 +632,7 @@ export async function runSelftestBotCommands(push, deps) {
594
632
  !String(guidedEditResult.stdout || "").includes("Telegram username (without @)"),
595
633
  String(guidedEditResult.stdout || "").split(/\r?\n/).filter((line) => line.includes("Telegram username")).join(" | ") || "username prompt skipped",
596
634
  );
597
- const guidedState = readTelegramBotEntry("monitorselftestbot");
635
+ const guidedState = readTelegramBotEntry("serverprotocolmonitorbot");
598
636
  push(
599
637
  "bot_edit_guided_prompts_update_ai_binding_fields",
600
638
  String(guidedState.TELEGRAM_BOT_AI_CLIENT || "") === "gemini"
@@ -609,7 +647,7 @@ export async function runSelftestBotCommands(push, deps) {
609
647
  args: [
610
648
  "bot", "edit",
611
649
  "--provider", "telegram",
612
- "--bot-key", "monitorselftestbot",
650
+ "--bot-key", "serverprotocolmonitorbot",
613
651
  "--non-interactive", "true",
614
652
  "--token", "selftest-edited-token",
615
653
  "--client", "claude",
@@ -619,7 +657,7 @@ export async function runSelftestBotCommands(push, deps) {
619
657
  ],
620
658
  env,
621
659
  });
622
- const editedState = readTelegramBotEntry("monitorselftestbot");
660
+ const editedState = readTelegramBotEntry("serverprotocolmonitorbot");
623
661
  push(
624
662
  "bot_edit_updates_ai_binding_fields",
625
663
  String(editedState.TELEGRAM_BOT_TOKEN || "") === "selftest-edited-token"
@@ -637,7 +675,7 @@ export async function runSelftestBotCommands(push, deps) {
637
675
  ...env,
638
676
  METHEUS_SCRIPTED_PROMPT_ANSWERS: JSON.stringify([
639
677
  "1", // provider: telegram
640
- "1", // bot entry: @monitorselftestbot
678
+ "2", // bot entry: @serverprotocolmonitorbot
641
679
  "1", // confirm set default
642
680
  ]),
643
681
  },
@@ -645,7 +683,7 @@ export async function runSelftestBotCommands(push, deps) {
645
683
  const guidedDefaultState = readTelegramGlobals();
646
684
  push(
647
685
  "bot_set_default_guided_selects_entry",
648
- String(guidedDefaultState.TELEGRAM_DEFAULT_BOT_KEY || "") === "monitorselftestbot",
686
+ String(guidedDefaultState.TELEGRAM_DEFAULT_BOT_KEY || "") === "serverprotocolmonitorbot",
649
687
  `default=${String(guidedDefaultState.TELEGRAM_DEFAULT_BOT_KEY || "")}`,
650
688
  );
651
689
 
@@ -660,7 +698,7 @@ export async function runSelftestBotCommands(push, deps) {
660
698
  ...env,
661
699
  METHEUS_SCRIPTED_PROMPT_ANSWERS: JSON.stringify([
662
700
  "1", // provider: telegram
663
- "1", // bot entry: @monitorselftestbot
701
+ "2", // bot entry: @serverprotocolmonitorbot
664
702
  "2", // output format: json
665
703
  ]),
666
704
  },
@@ -680,7 +718,7 @@ export async function runSelftestBotCommands(push, deps) {
680
718
  args: [
681
719
  "bot", "set-default",
682
720
  "--provider", "telegram",
683
- "--bot-key", "monitorselftestbot",
721
+ "--bot-key", "serverprotocolmonitorbot",
684
722
  "--non-interactive", "true",
685
723
  ],
686
724
  env,
@@ -688,7 +726,7 @@ export async function runSelftestBotCommands(push, deps) {
688
726
  const defaultState = readTelegramGlobals();
689
727
  push(
690
728
  "bot_set_default_updates_default_bot_key",
691
- String(defaultState.TELEGRAM_DEFAULT_BOT_KEY || "") === "monitorselftestbot",
729
+ String(defaultState.TELEGRAM_DEFAULT_BOT_KEY || "") === "serverprotocolmonitorbot",
692
730
  `default=${String(defaultState.TELEGRAM_DEFAULT_BOT_KEY || "")}`,
693
731
  );
694
732
 
@@ -697,7 +735,7 @@ export async function runSelftestBotCommands(push, deps) {
697
735
  args: [
698
736
  "bot", "verify",
699
737
  "--provider", "telegram",
700
- "--bot-key", "monitorselftestbot",
738
+ "--bot-key", "serverprotocolmonitorbot",
701
739
  "--base-url", baseURL,
702
740
  "--timeout-seconds", "5",
703
741
  "--json", "true",
@@ -727,7 +765,7 @@ export async function runSelftestBotCommands(push, deps) {
727
765
  args: [
728
766
  "bot", "remove",
729
767
  "--provider", "telegram",
730
- "--bot-key", "monitorselftestbot",
768
+ "--bot-key", "serverprotocolmonitorbot",
731
769
  "--non-interactive", "true",
732
770
  ],
733
771
  env,
@@ -745,7 +783,7 @@ export async function runSelftestBotCommands(push, deps) {
745
783
  const telegramEntry = safeObject(listPayload[0]);
746
784
  push(
747
785
  "bot_remove_deletes_named_telegram_entry",
748
- !ensureArray(telegramEntry.entries).some((entry) => String(safeObject(entry).key || "") === "monitorselftestbot"),
786
+ !ensureArray(telegramEntry.entries).some((entry) => String(safeObject(entry).key || "") === "serverprotocolmonitorbot"),
749
787
  `entries=${String(ensureArray(telegramEntry.entries).length)}`,
750
788
  );
751
789
 
@@ -767,11 +805,11 @@ export async function runSelftestBotCommands(push, deps) {
767
805
  ],
768
806
  env,
769
807
  });
770
- const aliasAddState = readTelegramBotEntry("monitorselftestbot");
808
+ const aliasAddState = readTelegramBotEntry("serverprotocolmonitorbot");
771
809
  push(
772
810
  "bot_add_accepts_ai_prefixed_option_aliases",
773
811
  String(aliasAddState.TELEGRAM_BOT_SERVER_BOT_ID || "") === mock.bots[0].id
774
- && String(aliasAddState.TELEGRAM_BOT_SERVER_NAME || "") === "MonitorSelftestBot"
812
+ && String(aliasAddState.TELEGRAM_BOT_SERVER_NAME || "") === "ServerProtocolMonitorBot"
775
813
  && String(aliasAddState.TELEGRAM_BOT_SERVER_ROLES || "") === "monitor"
776
814
  && String(aliasAddState.TELEGRAM_BOT_AI_CLIENT || "") === "gpt"
777
815
  && String(aliasAddState.TELEGRAM_BOT_AI_MODEL || "") === "gpt-5.4"
@@ -792,7 +830,7 @@ export async function runSelftestBotCommands(push, deps) {
792
830
  const guidedRemoveBeforePayload = ensureArray(readJSON(guidedRemoveBeforeList.stdout));
793
831
  const guidedRemoveBeforeEntry = safeObject(guidedRemoveBeforePayload[0]);
794
832
  const guidedRemoveEntries = ensureArray(guidedRemoveBeforeEntry.entries);
795
- const explicitEntryIndex = guidedRemoveEntries.findIndex((entry) => String(safeObject(entry).key || "") === "monitorselftestbot");
833
+ const explicitEntryIndex = guidedRemoveEntries.findIndex((entry) => String(safeObject(entry).key || "") === "serverprotocolmonitorbot");
796
834
 
797
835
  await runCLI({
798
836
  cliPath,
@@ -838,7 +876,7 @@ export async function runSelftestBotCommands(push, deps) {
838
876
  "--provider", "telegram",
839
877
  "--bot-key", "legacy_main",
840
878
  "--bot-id", mock.bots[0].id,
841
- "--bot-name", "MonitorSelftestBot",
879
+ "--bot-name", "ServerProtocolMonitorBot",
842
880
  "--role-profile", "monitor",
843
881
  "--client", "codex",
844
882
  "--permission-mode", "read_only",
@@ -186,9 +186,9 @@ export async function runSelftestRunnerScenarios(push, deps) {
186
186
  project_id: selftestProjectID,
187
187
  provider: "telegram",
188
188
  role: "monitor",
189
- bot_name: "RyoAI_bot",
189
+ bot_name: "ServerProtocolMonitorBot",
190
190
  }),
191
- { name: "RyoAI_bot", role: "review" },
191
+ { name: "ServerProtocolMonitorBot", role: "review" },
192
192
  normalizeBotRunnerConfigContents(
193
193
  {
194
194
  version: 2,
@@ -211,7 +211,7 @@ export async function runSelftestRunnerScenarios(push, deps) {
211
211
  },
212
212
  },
213
213
  bot_bindings: {
214
- RyoAI_bot: {
214
+ ServerProtocolMonitorBot: {
215
215
  role_profile: "approval",
216
216
  },
217
217
  },
@@ -237,9 +237,9 @@ export async function runSelftestRunnerScenarios(push, deps) {
237
237
  project_id: selftestProjectID,
238
238
  provider: "telegram",
239
239
  role: "monitor",
240
- bot_name: "RyoAI_bot",
240
+ bot_name: "ServerProtocolMonitorBot",
241
241
  }),
242
- { name: "RyoAI_bot", role: "monitor" },
242
+ { name: "ServerProtocolMonitorBot", role: "monitor" },
243
243
  normalizeBotRunnerConfigContents(
244
244
  {
245
245
  version: 2,
@@ -257,7 +257,7 @@ export async function runSelftestRunnerScenarios(push, deps) {
257
257
  },
258
258
  },
259
259
  bot_bindings: {
260
- RyoAI_bot: {
260
+ ServerProtocolMonitorBot: {
261
261
  role_profile: "monitor",
262
262
  client: "claude",
263
263
  reasoning_effort: "high",
@@ -435,7 +435,7 @@ export async function runSelftestRunnerScenarios(push, deps) {
435
435
  provider: "telegram",
436
436
  role: "monitor",
437
437
  role_profile: "monitor",
438
- bot_name: "RyoAI_bot",
438
+ bot_name: "ServerProtocolMonitorBot",
439
439
  destination_label: "AI incubating CHAT ROOM",
440
440
  archive_work_item_id: "304ce77a-7032-421c-aeda-bc54daf088dd",
441
441
  },
@@ -451,7 +451,7 @@ export async function runSelftestRunnerScenarios(push, deps) {
451
451
  provider: "telegram",
452
452
  role: "monitor",
453
453
  "role-profile": "monitor",
454
- "bot-name": "RyoAI_bot",
454
+ "bot-name": "ServerProtocolMonitorBot",
455
455
  "dry-run-delivery": true,
456
456
  },
457
457
  "once",
@@ -463,7 +463,7 @@ export async function runSelftestRunnerScenarios(push, deps) {
463
463
  && resolvedRunnerRoute.name === "telegram-monitor"
464
464
  && resolvedRunnerRoute.destinationLabel === "AI incubating CHAT ROOM"
465
465
  && resolvedRunnerRoute.dryRunDelivery === true
466
- && runnerRouteKey(resolvedRunnerRoute) === "telegram-monitor::11111111-1111-1111-1111-111111111111::telegram::monitor::RyoAI_bot::AI incubating CHAT ROOM",
466
+ && runnerRouteKey(resolvedRunnerRoute) === "telegram-monitor::11111111-1111-1111-1111-111111111111::telegram::monitor::ServerProtocolMonitorBot::AI incubating CHAT ROOM",
467
467
  `name=${resolvedRunnerRoute.name || "(none)"} destination=${resolvedRunnerRoute.destinationLabel || "(none)"} key=${runnerRouteKey(resolvedRunnerRoute)}`,
468
468
  );
469
469
  } catch (err) {
@@ -515,7 +515,7 @@ export async function runSelftestRunnerScenarios(push, deps) {
515
515
  provider: "telegram",
516
516
  role: "monitor",
517
517
  role_profile: "monitor",
518
- bot_name: "RyoAI_bot",
518
+ bot_name: "ServerProtocolMonitorBot",
519
519
  destination_label: "AI incubating CHAT ROOM",
520
520
  },
521
521
  ],
@@ -527,7 +527,7 @@ export async function runSelftestRunnerScenarios(push, deps) {
527
527
  `${JSON.stringify({
528
528
  version: 1,
529
529
  routes: {
530
- "-::11111111-1111-1111-1111-111111111111::telegram::monitor::RyoAI_bot::-": {
530
+ "-::11111111-1111-1111-1111-111111111111::telegram::monitor::ServerProtocolMonitorBot::-": {
531
531
  last_processed_comment_id: "comment-a",
532
532
  last_processed_created_at: "2026-03-13T06:00:00.000Z",
533
533
  last_source_message_id: 41,
@@ -543,7 +543,7 @@ export async function runSelftestRunnerScenarios(push, deps) {
543
543
  process.env.HOME = migrationHome;
544
544
  process.env.USERPROFILE = migrationHome;
545
545
  const migratedRunnerState = loadBotRunnerState();
546
- const canonicalRunnerStateKey = "telegram-monitor::11111111-1111-1111-1111-111111111111::telegram::monitor::RyoAI_bot::AI incubating CHAT ROOM";
546
+ const canonicalRunnerStateKey = "telegram-monitor::11111111-1111-1111-1111-111111111111::telegram::monitor::ServerProtocolMonitorBot::AI incubating CHAT ROOM";
547
547
  const persistedRunnerState = tryJsonParse(
548
548
  fs.readFileSync(path.join(migrationMetheusDir, "bot-runner-state.json"), "utf8"),
549
549
  );
@@ -552,7 +552,7 @@ export async function runSelftestRunnerScenarios(push, deps) {
552
552
  migratedRunnerState.migrated === true
553
553
  && migratedRunnerState.migratedKeys.length === 1
554
554
  && Boolean(migratedRunnerState.routes[canonicalRunnerStateKey])
555
- && !migratedRunnerState.routes["-::11111111-1111-1111-1111-111111111111::telegram::monitor::RyoAI_bot::-"]
555
+ && !migratedRunnerState.routes["-::11111111-1111-1111-1111-111111111111::telegram::monitor::ServerProtocolMonitorBot::-"]
556
556
  && Boolean(safeObject(persistedRunnerState.routes)[canonicalRunnerStateKey]),
557
557
  `migrated=${String(migratedRunnerState.migrated)} key=${canonicalRunnerStateKey}`,
558
558
  );
@@ -619,7 +619,7 @@ export async function runSelftestRunnerScenarios(push, deps) {
619
619
  },
620
620
  },
621
621
  mentionOnlyRoute,
622
- { name: "RyoAI_bot", role: "monitor" },
622
+ { name: "ServerProtocolMonitorBot", role: "monitor" },
623
623
  );
624
624
  push(
625
625
  "telegram_trigger_mentions_only_skips_unmentioned_group_message",
@@ -634,13 +634,13 @@ export async function runSelftestRunnerScenarios(push, deps) {
634
634
  kind: "telegram_message",
635
635
  chatID: "-100123",
636
636
  chatType: "supergroup",
637
- body: "hello @RyoAI_bot",
637
+ body: "hello @ServerProtocolMonitorBot",
638
638
  mentionUsernames: ["ryoai_bot"],
639
639
  replyToSenderIsBot: false,
640
640
  },
641
641
  },
642
642
  mentionOnlyRoute,
643
- { name: "RyoAI_bot", role: "monitor" },
643
+ { name: "ServerProtocolMonitorBot", role: "monitor" },
644
644
  );
645
645
  push(
646
646
  "telegram_trigger_mentions_only_accepts_bot_mention",
@@ -650,7 +650,7 @@ export async function runSelftestRunnerScenarios(push, deps) {
650
650
 
651
651
  const botReplyArchiveComment = formatBotReplyArchiveComment({
652
652
  provider: "telegram",
653
- bot: { id: "bot-1", name: "RyoAI_bot", role: "monitor" },
653
+ bot: { id: "bot-1", name: "ServerProtocolMonitorBot", role: "monitor" },
654
654
  destination: { chatID: "-100123", label: "Main Room" },
655
655
  replyText: "hello",
656
656
  messageID: 4321,
@@ -234,7 +234,7 @@ export async function runSelftestTelegramE2E(push, deps) {
234
234
  const e2eTelegramToken = "123456:test-token";
235
235
  const e2eBot = {
236
236
  id: "55555555-5555-4555-8555-555555555555",
237
- name: "RyoAI_bot",
237
+ name: "ServerProtocolMonitorBot",
238
238
  role: "monitor",
239
239
  };
240
240
  const e2eDestination = {
@@ -356,7 +356,7 @@ export async function runSelftestTelegramE2E(push, deps) {
356
356
  && e2eResult.execution_mode === "role_profile"
357
357
  && e2eResult.role_profile === "monitor"
358
358
  && telegramE2EServer.state.sentMessages.length === 1
359
- && String(telegramE2EServer.state.sentMessages[0]?.text || "").trim() === "Acknowledged: hello @RyoAI_bot"
359
+ && String(telegramE2EServer.state.sentMessages[0]?.text || "").trim() === "Acknowledged: hello @ServerProtocolMonitorBot"
360
360
  && intFromRawAllowZero(telegramE2EServer.state.sentMessages[0]?.reply_to_message_id, 0) === 41
361
361
  && telegramE2EServer.state.chatActions.length >= 1
362
362
  && Boolean(mirroredReply)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "metheus-governance-mcp-cli",
3
- "version": "0.2.105",
3
+ "version": "0.2.106",
4
4
  "description": "Metheus Governance MCP CLI (setup + stdio proxy)",
5
5
  "type": "module",
6
6
  "files": [