metheus-governance-mcp-cli 0.2.100 → 0.2.102
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 +20 -14
- package/cli.mjs +83 -17
- package/lib/bot-commands.mjs +202 -37
- package/lib/selftest-bot-commands.mjs +10 -6
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -58,8 +58,11 @@ TELEGRAM_BOT_TOKEN=
|
|
|
58
58
|
|
|
59
59
|
```env
|
|
60
60
|
# ~/.metheus/telegram-bots/ryoai_bot.env
|
|
61
|
-
|
|
62
|
-
|
|
61
|
+
TELEGRAM_BOT_SERVER_BOT_ID=<server_bot_uuid>
|
|
62
|
+
TELEGRAM_BOT_SERVER_NAME=RyoAI_bot
|
|
63
|
+
TELEGRAM_BOT_SERVER_ROLES=monitor,review,worker,approval
|
|
64
|
+
# Optional fallback only when server bot binding is unavailable
|
|
65
|
+
# TELEGRAM_BOT_USERNAME=ryoai_bot
|
|
63
66
|
TELEGRAM_BOT_TOKEN=
|
|
64
67
|
TELEGRAM_BOT_ROLE_PROFILE=
|
|
65
68
|
TELEGRAM_BOT_AI_CLIENT=
|
|
@@ -223,15 +226,15 @@ Direct commands:
|
|
|
223
226
|
|
|
224
227
|
```bash
|
|
225
228
|
metheus-governance-mcp-cli bot list
|
|
226
|
-
metheus-governance-mcp-cli bot show --provider telegram --bot-
|
|
229
|
+
metheus-governance-mcp-cli bot show --provider telegram --bot-name RyoAI_bot
|
|
227
230
|
metheus-governance-mcp-cli bot add --provider telegram
|
|
228
231
|
metheus-governance-mcp-cli bot edit
|
|
229
232
|
metheus-governance-mcp-cli bot edit --provider telegram
|
|
230
233
|
metheus-governance-mcp-cli bot remove --provider telegram
|
|
231
|
-
metheus-governance-mcp-cli bot set-default --provider telegram --bot-
|
|
232
|
-
metheus-governance-mcp-cli bot migrate --provider telegram --bot-
|
|
234
|
+
metheus-governance-mcp-cli bot set-default --provider telegram --bot-name RyoAI_bot
|
|
235
|
+
metheus-governance-mcp-cli bot migrate --provider telegram --bot-name RyoAI_bot
|
|
233
236
|
metheus-governance-mcp-cli bot global --provider telegram
|
|
234
|
-
metheus-governance-mcp-cli bot verify --provider telegram --bot-
|
|
237
|
+
metheus-governance-mcp-cli bot verify --provider telegram --bot-name RyoAI_bot
|
|
235
238
|
```
|
|
236
239
|
|
|
237
240
|
Behavior:
|
|
@@ -259,8 +262,10 @@ Behavior:
|
|
|
259
262
|
- `bot verify` without flags starts a guided numbered flow: provider -> bot entry -> output format.
|
|
260
263
|
- `bot remove` without flags starts a guided numbered flow: provider -> bot entry -> confirm removal.
|
|
261
264
|
- Telegram stores one bot file per entry under `~/.metheus/telegram-bots/<server-bot-name>.env` with generic fields:
|
|
262
|
-
- `TELEGRAM_BOT_NAME`
|
|
263
265
|
- `TELEGRAM_BOT_SERVER_BOT_ID`
|
|
266
|
+
- `TELEGRAM_BOT_SERVER_NAME`
|
|
267
|
+
- `TELEGRAM_BOT_SERVER_ROLES`
|
|
268
|
+
- `TELEGRAM_BOT_USERNAME` only as a fallback when server bot binding is unavailable
|
|
264
269
|
- `TELEGRAM_BOT_TOKEN`
|
|
265
270
|
- `TELEGRAM_BOT_ROLE_PROFILE`
|
|
266
271
|
- `TELEGRAM_BOT_AI_CLIENT`
|
|
@@ -270,6 +275,7 @@ Behavior:
|
|
|
270
275
|
- Slack and KakaoTalk currently use a single local token entry per provider in this command flow.
|
|
271
276
|
- `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.
|
|
272
277
|
- `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.
|
|
278
|
+
- In `bot show` and `bot verify`, `stored_*` fields come from the local env file and `live_server_*` fields come from the current server `me/bots` response.
|
|
273
279
|
- `bot global` edits Telegram-wide local settings such as API base URL, allowed updates, and default bot key.
|
|
274
280
|
- `bot set-default` updates `TELEGRAM_DEFAULT_BOT_KEY`.
|
|
275
281
|
- `bot migrate` moves legacy `TELEGRAM_BOT_TOKEN` into a named Telegram bot entry.
|
|
@@ -280,16 +286,16 @@ Non-interactive examples:
|
|
|
280
286
|
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
|
|
281
287
|
metheus-governance-mcp-cli bot add --provider telegram --non-interactive true --server-bot-id <server_bot_uuid> --token <telegram_bot_token> --default true
|
|
282
288
|
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
|
|
283
|
-
metheus-governance-mcp-cli bot edit --provider telegram --bot-
|
|
284
|
-
metheus-governance-mcp-cli bot set-default --provider telegram --bot-
|
|
285
|
-
metheus-governance-mcp-cli bot migrate --provider telegram --bot-
|
|
286
|
-
metheus-governance-mcp-cli bot remove --provider telegram --bot-
|
|
287
|
-
metheus-governance-mcp-cli bot verify --provider telegram --bot-
|
|
289
|
+
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
|
|
290
|
+
metheus-governance-mcp-cli bot set-default --provider telegram --bot-name RyoAI_bot --non-interactive true
|
|
291
|
+
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
|
|
292
|
+
metheus-governance-mcp-cli bot remove --provider telegram --bot-name RyoAI_bot --non-interactive true
|
|
293
|
+
metheus-governance-mcp-cli bot verify --provider telegram --bot-name RyoAI_bot --json true
|
|
288
294
|
```
|
|
289
295
|
|
|
290
|
-
For direct Telegram adds, the CLI
|
|
296
|
+
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 a different local file stem.
|
|
291
297
|
|
|
292
|
-
For direct Telegram edits, `--bot-key`
|
|
298
|
+
For direct Telegram edits, prefer `--bot-name` or `--bot-id` because server bot identity is the source of truth. Use `--bot-key` only when you intentionally need the advanced local selector. If one server bot name expands to multiple roles such as `approval / worker / review / monitor`, prefer the guided `bot edit` flow so you can keep the current grouped settings, edit one role only, or walk every role in sequence instead of forcing one entry-level AI override.
|
|
293
299
|
|
|
294
300
|
Current support status:
|
|
295
301
|
|
package/cli.mjs
CHANGED
|
@@ -241,13 +241,13 @@ function printUsage() {
|
|
|
241
241
|
` ${cmd} setup [--project-id <uuid>] [--ctxpack-key <key>] [--base-url <url>] [--workspace-dir <path|auto>] [--workspace-fallback-dir <path>] [--name <server_name>]`,
|
|
242
242
|
` ${cmd} bot setup [--provider <telegram|slack|kakaotalk>] [--base-url <url>] [--timeout-seconds <n>]`,
|
|
243
243
|
` ${cmd} bot list [--provider <telegram|slack|kakaotalk>] [--json <true|false>]`,
|
|
244
|
-
` ${cmd} bot show [--provider <telegram|slack|kakaotalk>] [--bot-
|
|
244
|
+
` ${cmd} bot show [--provider <telegram|slack|kakaotalk>] [--bot-name <server_name>] [--bot-id <uuid>] [--bot-key <advanced_key>] [--json <true|false>]`,
|
|
245
245
|
` ${cmd} bot add [--provider <telegram|slack|kakaotalk>] [--base-url <url>] [--timeout-seconds <n>]`,
|
|
246
246
|
` ${cmd} bot edit [--provider <telegram|slack|kakaotalk>] [--base-url <url>] [--timeout-seconds <n>]`,
|
|
247
247
|
` ${cmd} bot remove [--provider <telegram|slack|kakaotalk>]`,
|
|
248
|
-
` ${cmd} bot set-default --provider telegram [--bot-key <
|
|
249
|
-
` ${cmd} bot migrate --provider telegram [--bot-
|
|
250
|
-
` ${cmd} bot verify [--provider <telegram|slack|kakaotalk>] [--bot-key <
|
|
248
|
+
` ${cmd} bot set-default --provider telegram [--bot-name <server_name>] [--bot-id <uuid>] [--bot-key <advanced_key>]`,
|
|
249
|
+
` ${cmd} bot migrate --provider telegram [--bot-name <server_name>] [--bot-id <uuid>] [--bot-key <advanced_key>]`,
|
|
250
|
+
` ${cmd} bot verify [--provider <telegram|slack|kakaotalk>] [--bot-name <server_name>] [--bot-id <uuid>] [--bot-key <advanced_key>] [--timeout-seconds <n>] [--json <true|false>]`,
|
|
251
251
|
` ${cmd} bot global --provider telegram [--api-base-url <url>] [--auto-clear-webhook <true|false>] [--allowed-updates <csv>] [--default-bot-key <key>]`,
|
|
252
252
|
` ${cmd} doctor [--project-id <uuid>] [--ctxpack-key <key>] [--base-url <url>] [--timeout-seconds <n>] [--strict <true|false>]`,
|
|
253
253
|
` ${cmd} proxy [--project-id <uuid>] [--ctxpack-key <key>] [--base-url <url>] [--workspace-dir <path|auto>] [--include-drafts <true|false>] [--auto-pull-on-conflict <true|false>] [--timeout-seconds <n>]`,
|
|
@@ -759,7 +759,7 @@ function providerEnvTemplate(provider) {
|
|
|
759
759
|
"# Keep this file on your machine only. Do not commit it.",
|
|
760
760
|
"# Store Telegram-wide settings here.",
|
|
761
761
|
"# This global file now lives in ~/.metheus/telegram-bots/_global.env.",
|
|
762
|
-
"# Per-bot secrets and AI settings live in ~/.metheus/telegram-bots/<bot-
|
|
762
|
+
"# Per-bot secrets and AI settings live in ~/.metheus/telegram-bots/<server-bot-name>.env.",
|
|
763
763
|
"# Project chat destinations must be managed on the Metheus server.",
|
|
764
764
|
"",
|
|
765
765
|
"TELEGRAM_API_BASE_URL=",
|
|
@@ -2684,12 +2684,35 @@ function parseTelegramAllowedUpdates(rawValue) {
|
|
|
2684
2684
|
return Array.from(new Set(values));
|
|
2685
2685
|
}
|
|
2686
2686
|
|
|
2687
|
+
function preferredTelegramServerRoleSort(roles) {
|
|
2688
|
+
const order = ["monitor", "review", "worker", "approval"];
|
|
2689
|
+
return ensureArray(roles).slice().sort((left, right) => {
|
|
2690
|
+
const leftText = String(left || "").trim();
|
|
2691
|
+
const rightText = String(right || "").trim();
|
|
2692
|
+
const leftIndex = order.indexOf(leftText);
|
|
2693
|
+
const rightIndex = order.indexOf(rightText);
|
|
2694
|
+
if (leftIndex >= 0 && rightIndex >= 0) return leftIndex - rightIndex;
|
|
2695
|
+
if (leftIndex >= 0) return -1;
|
|
2696
|
+
if (rightIndex >= 0) return 1;
|
|
2697
|
+
return leftText.localeCompare(rightText);
|
|
2698
|
+
});
|
|
2699
|
+
}
|
|
2700
|
+
|
|
2701
|
+
function parseTelegramServerRoles(rawValue) {
|
|
2702
|
+
const values = String(rawValue || "")
|
|
2703
|
+
.split(",")
|
|
2704
|
+
.map((value) => String(value || "").trim())
|
|
2705
|
+
.filter(Boolean);
|
|
2706
|
+
if (!values.length) return [];
|
|
2707
|
+
return Array.from(new Set(preferredTelegramServerRoleSort(values)));
|
|
2708
|
+
}
|
|
2709
|
+
|
|
2687
2710
|
function collectTelegramEnvBotEntries(parsedEnv) {
|
|
2688
2711
|
const parsed = safeObject(parsedEnv);
|
|
2689
2712
|
const entries = new Map();
|
|
2690
2713
|
for (const [rawKey, rawValue] of Object.entries(parsed)) {
|
|
2691
2714
|
const match = String(rawKey || "").trim().match(
|
|
2692
|
-
/^TELEGRAM_BOT_([A-Z0-9_]+)_(TOKEN|USERNAME|SERVER_BOT_ID|ROLE_PROFILE|AI_CLIENT|AI_MODEL|AI_PERMISSION_MODE|AI_REASONING_EFFORT)$/i,
|
|
2715
|
+
/^TELEGRAM_BOT_([A-Z0-9_]+)_(TOKEN|USERNAME|SERVER_BOT_ID|SERVER_NAME|SERVER_ROLES|ROLE_PROFILE|AI_CLIENT|AI_MODEL|AI_PERMISSION_MODE|AI_REASONING_EFFORT)$/i,
|
|
2693
2716
|
);
|
|
2694
2717
|
if (!match) continue;
|
|
2695
2718
|
const botKey = normalizeTelegramBotEnvKey(match[1], "");
|
|
@@ -2700,6 +2723,8 @@ function collectTelegramEnvBotEntries(parsedEnv) {
|
|
|
2700
2723
|
token: "",
|
|
2701
2724
|
username: "",
|
|
2702
2725
|
serverBotID: "",
|
|
2726
|
+
serverBotName: "",
|
|
2727
|
+
serverRoles: [],
|
|
2703
2728
|
roleProfile: "",
|
|
2704
2729
|
client: "",
|
|
2705
2730
|
model: "",
|
|
@@ -2713,6 +2738,10 @@ function collectTelegramEnvBotEntries(parsedEnv) {
|
|
|
2713
2738
|
entry.username = normalizeTelegramBotUsername(textValue);
|
|
2714
2739
|
} else if (field === "SERVER_BOT_ID") {
|
|
2715
2740
|
entry.serverBotID = textValue;
|
|
2741
|
+
} else if (field === "SERVER_NAME") {
|
|
2742
|
+
entry.serverBotName = textValue;
|
|
2743
|
+
} else if (field === "SERVER_ROLES") {
|
|
2744
|
+
entry.serverRoles = parseTelegramServerRoles(textValue);
|
|
2716
2745
|
} else if (field === "ROLE_PROFILE") {
|
|
2717
2746
|
entry.roleProfile = normalizeRunnerRoleProfileName(textValue);
|
|
2718
2747
|
} else if (field === "AI_CLIENT") {
|
|
@@ -2738,6 +2767,8 @@ function collectTelegramEnvBotEntries(parsedEnv) {
|
|
|
2738
2767
|
|
|
2739
2768
|
function telegramBotEntryDisplayNameForState(entry) {
|
|
2740
2769
|
const current = safeObject(entry);
|
|
2770
|
+
const serverBotName = String(current.serverBotName || "").trim();
|
|
2771
|
+
if (serverBotName) return serverBotName;
|
|
2741
2772
|
const username = normalizeTelegramBotUsername(current.username || "");
|
|
2742
2773
|
if (username) return username;
|
|
2743
2774
|
return normalizeTelegramBotEnvKey(current.key || "", "telegram_bot");
|
|
@@ -2747,11 +2778,16 @@ function parseTelegramBotEntryFile(filePath) {
|
|
|
2747
2778
|
const raw = fs.readFileSync(filePath, "utf8");
|
|
2748
2779
|
const parsed = parseSimpleEnvText(raw);
|
|
2749
2780
|
const keyFromFile = normalizeTelegramBotEnvKey(path.basename(filePath, path.extname(filePath)), "telegram_bot");
|
|
2750
|
-
const keyFromName = normalizeTelegramBotEnvKey(
|
|
2781
|
+
const keyFromName = normalizeTelegramBotEnvKey(
|
|
2782
|
+
parsed.TELEGRAM_BOT_USERNAME || parsed.TELEGRAM_BOT_NAME || parsed.TELEGRAM_BOT_SERVER_NAME || "",
|
|
2783
|
+
"",
|
|
2784
|
+
);
|
|
2751
2785
|
return {
|
|
2752
|
-
key:
|
|
2753
|
-
username: normalizeTelegramBotUsername(parsed.
|
|
2786
|
+
key: keyFromFile || keyFromName,
|
|
2787
|
+
username: normalizeTelegramBotUsername(parsed.TELEGRAM_BOT_USERNAME || parsed.TELEGRAM_BOT_NAME || ""),
|
|
2754
2788
|
serverBotID: String(parsed.TELEGRAM_BOT_SERVER_BOT_ID || "").trim(),
|
|
2789
|
+
serverBotName: String(parsed.TELEGRAM_BOT_SERVER_NAME || "").trim(),
|
|
2790
|
+
serverRoles: parseTelegramServerRoles(parsed.TELEGRAM_BOT_SERVER_ROLES || ""),
|
|
2755
2791
|
token: String(parsed.TELEGRAM_BOT_TOKEN || "").trim(),
|
|
2756
2792
|
roleProfile: normalizeRunnerRoleProfileName(parsed.TELEGRAM_BOT_ROLE_PROFILE || ""),
|
|
2757
2793
|
client: normalizeLocalAIClientName(parsed.TELEGRAM_BOT_AI_CLIENT || "", ""),
|
|
@@ -2813,6 +2849,8 @@ function buildMergedTelegramEnvParsed(globalParsed, entries) {
|
|
|
2813
2849
|
const upper = String(entry.key || "").trim().toUpperCase();
|
|
2814
2850
|
if (!upper) return;
|
|
2815
2851
|
merged[`TELEGRAM_BOT_${upper}_SERVER_BOT_ID`] = String(entry.serverBotID || "").trim();
|
|
2852
|
+
merged[`TELEGRAM_BOT_${upper}_SERVER_NAME`] = String(entry.serverBotName || "").trim();
|
|
2853
|
+
merged[`TELEGRAM_BOT_${upper}_SERVER_ROLES`] = ensureArray(entry.serverRoles).join(",");
|
|
2816
2854
|
merged[`TELEGRAM_BOT_${upper}_USERNAME`] = normalizeTelegramBotUsername(entry.username || "");
|
|
2817
2855
|
merged[`TELEGRAM_BOT_${upper}_TOKEN`] = String(entry.token || "").trim();
|
|
2818
2856
|
merged[`TELEGRAM_BOT_${upper}_ROLE_PROFILE`] = String(entry.roleProfile || "").trim();
|
|
@@ -2874,12 +2912,14 @@ function readTelegramEnvState() {
|
|
|
2874
2912
|
}
|
|
2875
2913
|
|
|
2876
2914
|
function isTelegramEntryEnvKey(rawKey) {
|
|
2877
|
-
return /^TELEGRAM_BOT_([A-Z0-9_]+)_(TOKEN|USERNAME|SERVER_BOT_ID|ROLE_PROFILE|AI_CLIENT|AI_MODEL|AI_PERMISSION_MODE|AI_REASONING_EFFORT)$/i
|
|
2915
|
+
return /^TELEGRAM_BOT_([A-Z0-9_]+)_(TOKEN|USERNAME|SERVER_BOT_ID|SERVER_NAME|SERVER_ROLES|ROLE_PROFILE|AI_CLIENT|AI_MODEL|AI_PERMISSION_MODE|AI_REASONING_EFFORT)$/i
|
|
2878
2916
|
.test(String(rawKey || "").trim());
|
|
2879
2917
|
}
|
|
2880
2918
|
|
|
2881
2919
|
function telegramEntryCommentNameForEnv(entry) {
|
|
2882
2920
|
const current = safeObject(entry);
|
|
2921
|
+
const serverBotName = String(current.serverBotName || "").trim();
|
|
2922
|
+
if (serverBotName) return serverBotName;
|
|
2883
2923
|
const username = normalizeTelegramBotUsername(current.username || "");
|
|
2884
2924
|
if (username) return username;
|
|
2885
2925
|
return normalizeTelegramBotEnvKey(current.key || "", "telegram_bot");
|
|
@@ -2896,7 +2936,7 @@ function renderNormalizedTelegramEnv(parsedEnv) {
|
|
|
2896
2936
|
"# Keep this file on your machine only. Do not commit it.",
|
|
2897
2937
|
"# Store Telegram-wide settings here.",
|
|
2898
2938
|
"# This global file lives in ~/.metheus/telegram-bots/_global.env.",
|
|
2899
|
-
"# Per-bot secrets and AI settings live in ~/.metheus/telegram-bots/<bot-
|
|
2939
|
+
"# Per-bot secrets and AI settings live in ~/.metheus/telegram-bots/<server-bot-name>.env.",
|
|
2900
2940
|
"",
|
|
2901
2941
|
`TELEGRAM_API_BASE_URL=${formatProviderEnvValue(parsed.TELEGRAM_API_BASE_URL || "")}`,
|
|
2902
2942
|
`TELEGRAM_AUTO_CLEAR_WEBHOOK=${boolFromRaw(parsed.TELEGRAM_AUTO_CLEAR_WEBHOOK, true) ? "true" : "false"}`,
|
|
@@ -2930,12 +2970,22 @@ function renderNormalizedTelegramEnv(parsedEnv) {
|
|
|
2930
2970
|
function renderTelegramBotEntryEnv(entryRaw) {
|
|
2931
2971
|
const entry = safeObject(entryRaw);
|
|
2932
2972
|
const botName = telegramEntryCommentNameForEnv(entry);
|
|
2973
|
+
const serverRoles = parseTelegramServerRoles(entry.serverRoles || "");
|
|
2933
2974
|
const lines = [
|
|
2934
2975
|
"# Metheus local Telegram bot entry",
|
|
2935
|
-
`#
|
|
2976
|
+
`# Server bot: ${botName}`,
|
|
2936
2977
|
"",
|
|
2937
|
-
`TELEGRAM_BOT_NAME=${formatProviderEnvValue(botName)}`,
|
|
2938
2978
|
`TELEGRAM_BOT_SERVER_BOT_ID=${formatProviderEnvValue(entry.serverBotID || "")}`,
|
|
2979
|
+
`TELEGRAM_BOT_SERVER_NAME=${formatProviderEnvValue(entry.serverBotName || "")}`,
|
|
2980
|
+
`TELEGRAM_BOT_SERVER_ROLES=${formatProviderEnvValue(serverRoles.join(","))}`,
|
|
2981
|
+
];
|
|
2982
|
+
if (!String(entry.serverBotID || "").trim() && !String(entry.serverBotName || "").trim() && String(entry.username || "").trim()) {
|
|
2983
|
+
lines.push(
|
|
2984
|
+
"# Fallback only when server bot binding is unavailable",
|
|
2985
|
+
`TELEGRAM_BOT_USERNAME=${formatProviderEnvValue(entry.username || "")}`,
|
|
2986
|
+
);
|
|
2987
|
+
}
|
|
2988
|
+
lines.push(
|
|
2939
2989
|
`TELEGRAM_BOT_TOKEN=${formatProviderEnvValue(entry.token || "")}`,
|
|
2940
2990
|
`TELEGRAM_BOT_ROLE_PROFILE=${formatProviderEnvValue(entry.roleProfile || "")}`,
|
|
2941
2991
|
`TELEGRAM_BOT_AI_CLIENT=${formatProviderEnvValue(entry.client || "")}`,
|
|
@@ -2943,7 +2993,7 @@ function renderTelegramBotEntryEnv(entryRaw) {
|
|
|
2943
2993
|
`TELEGRAM_BOT_AI_PERMISSION_MODE=${formatProviderEnvValue(entry.permissionMode || "")}`,
|
|
2944
2994
|
`TELEGRAM_BOT_AI_REASONING_EFFORT=${formatProviderEnvValue(entry.reasoningEffort || "")}`,
|
|
2945
2995
|
"",
|
|
2946
|
-
|
|
2996
|
+
);
|
|
2947
2997
|
return `${lines.join("\n").trimEnd()}\n`;
|
|
2948
2998
|
}
|
|
2949
2999
|
|
|
@@ -2954,6 +3004,8 @@ function writeTelegramEnvState(parsedEnv) {
|
|
|
2954
3004
|
entry.token
|
|
2955
3005
|
|| entry.username
|
|
2956
3006
|
|| entry.serverBotID
|
|
3007
|
+
|| entry.serverBotName
|
|
3008
|
+
|| ensureArray(entry.serverRoles).length
|
|
2957
3009
|
|| entry.roleProfile
|
|
2958
3010
|
|| entry.client
|
|
2959
3011
|
|| entry.model
|
|
@@ -3009,7 +3061,13 @@ function normalizeExistingProviderEnvFile(provider, filePath) {
|
|
|
3009
3061
|
function resolveTelegramEnvConfig(parsedEnv, filePath, config, selectors = {}) {
|
|
3010
3062
|
const parsed = safeObject(parsedEnv);
|
|
3011
3063
|
const legacyToken = String(parsed.TELEGRAM_BOT_TOKEN || "").trim();
|
|
3012
|
-
const entries = collectTelegramEnvBotEntries(parsed).filter((entry) =>
|
|
3064
|
+
const entries = collectTelegramEnvBotEntries(parsed).filter((entry) => (
|
|
3065
|
+
entry.token
|
|
3066
|
+
|| entry.username
|
|
3067
|
+
|| entry.serverBotID
|
|
3068
|
+
|| entry.serverBotName
|
|
3069
|
+
|| ensureArray(entry.serverRoles).length
|
|
3070
|
+
));
|
|
3013
3071
|
const desiredBotID = firstNonEmptyString([
|
|
3014
3072
|
selectors.serverBotID,
|
|
3015
3073
|
selectors.botID,
|
|
@@ -3037,7 +3095,11 @@ function resolveTelegramEnvConfig(parsedEnv, filePath, config, selectors = {}) {
|
|
|
3037
3095
|
}
|
|
3038
3096
|
if (!selected && desiredUsername) {
|
|
3039
3097
|
selected = entries.find(
|
|
3040
|
-
(entry) =>
|
|
3098
|
+
(entry) => (
|
|
3099
|
+
entry.username === desiredUsername
|
|
3100
|
+
|| normalizeTelegramBotUsername(entry.serverBotName) === desiredUsername
|
|
3101
|
+
|| normalizeTelegramBotUsername(entry.key) === desiredUsername
|
|
3102
|
+
),
|
|
3041
3103
|
) || null;
|
|
3042
3104
|
}
|
|
3043
3105
|
if (!selected && desiredBotKey) {
|
|
@@ -3071,6 +3133,8 @@ function resolveTelegramEnvConfig(parsedEnv, filePath, config, selectors = {}) {
|
|
|
3071
3133
|
botKey: selected.key,
|
|
3072
3134
|
botUsername: selected.username,
|
|
3073
3135
|
serverBotID: selected.serverBotID,
|
|
3136
|
+
serverBotName: selected.serverBotName,
|
|
3137
|
+
serverRoles: ensureArray(selected.serverRoles),
|
|
3074
3138
|
roleProfile: selected.roleProfile,
|
|
3075
3139
|
client: selected.client,
|
|
3076
3140
|
model: selected.model,
|
|
@@ -3095,6 +3159,8 @@ function resolveTelegramEnvConfig(parsedEnv, filePath, config, selectors = {}) {
|
|
|
3095
3159
|
botKey: "",
|
|
3096
3160
|
botUsername: "",
|
|
3097
3161
|
serverBotID: "",
|
|
3162
|
+
serverBotName: "",
|
|
3163
|
+
serverRoles: [],
|
|
3098
3164
|
roleProfile: "",
|
|
3099
3165
|
client: "",
|
|
3100
3166
|
model: "",
|
|
@@ -5467,8 +5533,8 @@ TELEGRAM_BOT_REVIEW_TOKEN=review-token
|
|
|
5467
5533
|
normalizedGlobalText.includes("TELEGRAM_DEFAULT_BOT_KEY=ryoai_bot")
|
|
5468
5534
|
&& !normalizedGlobalText.includes("TELEGRAM_BOT_RYOAI_BOT_TOKEN")
|
|
5469
5535
|
&& !normalizedGlobalText.includes("TELEGRAM_BOT_RYOAI_TOKEN")
|
|
5470
|
-
&& normalizedBotText.includes("TELEGRAM_BOT_NAME=ryoai_bot")
|
|
5471
5536
|
&& normalizedBotText.includes("TELEGRAM_BOT_SERVER_BOT_ID=bot-ryoai")
|
|
5537
|
+
&& normalizedBotText.includes("TELEGRAM_BOT_SERVER_NAME=")
|
|
5472
5538
|
&& normalizedBotText.includes("TELEGRAM_BOT_TOKEN=ryoai-token"),
|
|
5473
5539
|
`${normalizedGlobalText}\n---\n${normalizedBotText}`,
|
|
5474
5540
|
);
|
package/lib/bot-commands.mjs
CHANGED
|
@@ -216,20 +216,21 @@ function printBotUsage(deps) {
|
|
|
216
216
|
"",
|
|
217
217
|
` ${cliName} bot setup`,
|
|
218
218
|
` ${cliName} bot list [--provider <telegram|slack|kakaotalk>] [--json <true|false>]`,
|
|
219
|
-
` ${cliName} bot show [--provider <telegram|slack|kakaotalk>] [--bot-
|
|
219
|
+
` ${cliName} bot show [--provider <telegram|slack|kakaotalk>] [--bot-name <server_name>] [--bot-id <uuid>] [--bot-key <advanced_key>] [--json <true|false>]`,
|
|
220
220
|
` ${cliName} bot add [--provider <telegram|slack|kakaotalk>] [--base-url <url>] [--timeout-seconds <n>] [--non-interactive <true|false>] [--server-bot-id <uuid>] [--token <token>] [--default <true|false>] [--verify <true|false>] [--ai-client <name>] [--ai-model <name>] [--ai-permission-mode <mode>] [--ai-reasoning-effort <level>] [--bot-key <advanced_key>] [--username <fallback_name>] [--role-profile <name>]`,
|
|
221
|
-
` ${cliName} bot edit [--provider <telegram|slack|kakaotalk>] [--base-url <url>] [--timeout-seconds <n>] [--non-interactive <true|false>] [--bot-
|
|
222
|
-
` ${cliName} bot remove [--provider <telegram|slack|kakaotalk>] [--non-interactive <true|false>] [--bot-key <
|
|
223
|
-
` ${cliName} bot set-default --provider telegram [--bot-key <
|
|
224
|
-
` ${cliName} bot migrate --provider telegram [--bot-
|
|
225
|
-
` ${cliName} bot verify [--provider <telegram|slack|kakaotalk>] [--bot-key <
|
|
226
|
-
` ${cliName} bot global --provider telegram [--non-interactive <true|false>] [--api-base-url <url>] [--auto-clear-webhook <true|false>] [--allowed-updates <csv>] [--default-bot-key <
|
|
221
|
+
` ${cliName} bot edit [--provider <telegram|slack|kakaotalk>] [--base-url <url>] [--timeout-seconds <n>] [--non-interactive <true|false>] [--bot-name <server_name>] [--bot-id <uuid>] [--bot-key <advanced_key>] [--username <fallback_name>] [--token <token>] [--role-profile <name>] [--ai-client <name>] [--ai-model <name>] [--ai-permission-mode <mode>] [--ai-reasoning-effort <level>]`,
|
|
222
|
+
` ${cliName} bot remove [--provider <telegram|slack|kakaotalk>] [--non-interactive <true|false>] [--bot-name <server_name>] [--bot-id <uuid>] [--bot-key <advanced_key>]`,
|
|
223
|
+
` ${cliName} bot set-default --provider telegram [--bot-name <server_name>] [--bot-id <uuid>] [--bot-key <advanced_key>] [--non-interactive <true|false>]`,
|
|
224
|
+
` ${cliName} bot migrate --provider telegram [--bot-name <server_name>] [--bot-id <uuid>] [--bot-key <advanced_key>] [--keep-legacy-token <true|false>] [--non-interactive <true|false>]`,
|
|
225
|
+
` ${cliName} bot verify [--provider <telegram|slack|kakaotalk>] [--bot-name <server_name>] [--bot-id <uuid>] [--bot-key <advanced_key>] [--timeout-seconds <n>] [--json <true|false>]`,
|
|
226
|
+
` ${cliName} bot global --provider telegram [--non-interactive <true|false>] [--api-base-url <url>] [--auto-clear-webhook <true|false>] [--allowed-updates <csv>] [--default-bot-key <advanced_key>]`,
|
|
227
227
|
"",
|
|
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
231
|
` - in the normal Telegram path, bot add does not ask for a local bot key or a server role/profile choice.`,
|
|
232
|
-
` - server bot name/UUID is the source of truth;
|
|
232
|
+
` - server bot name/UUID is the source of truth; --bot-key is an advanced local selector only.`,
|
|
233
|
+
` - runner commands use --route-name, not bot name. Use bot verify/show first, then run the linked route.`,
|
|
233
234
|
` - bot edit without flags asks for provider, existing entry, then walks field-by-field in a numbered flow.`,
|
|
234
235
|
` - in the normal Telegram edit path, the CLI keeps or re-resolves the server bot binding automatically instead of asking you to pick a server role/profile UUID first.`,
|
|
235
236
|
` - bot set-default / bot verify / bot remove also support guided numbered selection when run without flags.`,
|
|
@@ -442,6 +443,8 @@ function telegramEntryEnvKeys(botKey) {
|
|
|
442
443
|
const upper = String(botKey || "").trim().toUpperCase();
|
|
443
444
|
return {
|
|
444
445
|
serverBotID: `TELEGRAM_BOT_${upper}_SERVER_BOT_ID`,
|
|
446
|
+
serverBotName: `TELEGRAM_BOT_${upper}_SERVER_NAME`,
|
|
447
|
+
serverRoles: `TELEGRAM_BOT_${upper}_SERVER_ROLES`,
|
|
445
448
|
username: `TELEGRAM_BOT_${upper}_USERNAME`,
|
|
446
449
|
token: `TELEGRAM_BOT_${upper}_TOKEN`,
|
|
447
450
|
roleProfile: `TELEGRAM_BOT_${upper}_ROLE_PROFILE`,
|
|
@@ -454,6 +457,8 @@ function telegramEntryEnvKeys(botKey) {
|
|
|
454
457
|
|
|
455
458
|
function telegramEntryCommentName(entry) {
|
|
456
459
|
const current = safeObject(entry);
|
|
460
|
+
const serverBotName = String(current.serverBotName || "").trim();
|
|
461
|
+
if (serverBotName) return serverBotName;
|
|
457
462
|
const username = String(current.username || "").trim();
|
|
458
463
|
if (username) return username;
|
|
459
464
|
const key = String(current.key || "").trim();
|
|
@@ -465,6 +470,8 @@ function persistTelegramUsername(entry) {
|
|
|
465
470
|
const current = safeObject(entry);
|
|
466
471
|
if (current.__preferServerIdentity) return "";
|
|
467
472
|
if (String(current.serverBotID || "").trim()) return "";
|
|
473
|
+
if (String(current.serverBotName || "").trim()) return "";
|
|
474
|
+
if (ensureArray(current.serverRoles).length) return "";
|
|
468
475
|
return normalizeServerBotIdentityText(current.username || "");
|
|
469
476
|
}
|
|
470
477
|
|
|
@@ -486,6 +493,8 @@ function upsertTelegramEntry(parsedEnv, entry) {
|
|
|
486
493
|
const keys = telegramEntryEnvKeys(entry.key);
|
|
487
494
|
const next = { ...parsed };
|
|
488
495
|
next[keys.serverBotID] = String(entry.serverBotID || "").trim();
|
|
496
|
+
next[keys.serverBotName] = String(entry.serverBotName || "").trim();
|
|
497
|
+
next[keys.serverRoles] = ensureArray(entry.serverRoles).join(",");
|
|
489
498
|
next[keys.username] = persistTelegramUsername(entry);
|
|
490
499
|
next[keys.token] = String(entry.token || "").trim();
|
|
491
500
|
next[keys.roleProfile] = String(entry.roleProfile || "").trim();
|
|
@@ -512,7 +521,7 @@ function telegramKnownKeys(parsedEnv, deps) {
|
|
|
512
521
|
}
|
|
513
522
|
|
|
514
523
|
function isTelegramEntryEnvKey(rawKey) {
|
|
515
|
-
return /^TELEGRAM_BOT_([A-Z0-9_]+)_(TOKEN|USERNAME|SERVER_BOT_ID|ROLE_PROFILE|AI_CLIENT|AI_MODEL|AI_PERMISSION_MODE|AI_REASONING_EFFORT)$/i
|
|
524
|
+
return /^TELEGRAM_BOT_([A-Z0-9_]+)_(TOKEN|USERNAME|SERVER_BOT_ID|SERVER_NAME|SERVER_ROLES|ROLE_PROFILE|AI_CLIENT|AI_MODEL|AI_PERMISSION_MODE|AI_REASONING_EFFORT)$/i
|
|
516
525
|
.test(String(rawKey || "").trim());
|
|
517
526
|
}
|
|
518
527
|
|
|
@@ -525,6 +534,8 @@ function renderTelegramEnv(parsedEnv, deps) {
|
|
|
525
534
|
entry.token
|
|
526
535
|
|| entry.username
|
|
527
536
|
|| entry.serverBotID
|
|
537
|
+
|| entry.serverBotName
|
|
538
|
+
|| ensureArray(entry.serverRoles).length
|
|
528
539
|
|| entry.roleProfile
|
|
529
540
|
|| entry.client
|
|
530
541
|
|| entry.model
|
|
@@ -562,6 +573,8 @@ function renderTelegramEnv(parsedEnv, deps) {
|
|
|
562
573
|
const entryLines = [
|
|
563
574
|
`# Telegram bot entry: ${telegramEntryCommentName(entry)}`,
|
|
564
575
|
`${keys.serverBotID}=${formatEnvValue(entry.serverBotID || "")}`,
|
|
576
|
+
`${keys.serverBotName}=${formatEnvValue(entry.serverBotName || "")}`,
|
|
577
|
+
`${keys.serverRoles}=${formatEnvValue(ensureArray(entry.serverRoles).join(","))}`,
|
|
565
578
|
];
|
|
566
579
|
if (String(entry.username || "").trim()) {
|
|
567
580
|
entryLines.push(`${keys.username}=${formatEnvValue(entry.username || "")}`);
|
|
@@ -615,6 +628,46 @@ function renderTokenOnlyProviderEnv(provider, parsedEnv, deps) {
|
|
|
615
628
|
return `${lines.join("\n").trimEnd()}\n`;
|
|
616
629
|
}
|
|
617
630
|
|
|
631
|
+
function renderTelegramBotEntryFile(entryRaw) {
|
|
632
|
+
const entry = safeObject(entryRaw);
|
|
633
|
+
const botName = telegramEntryCommentName(entry);
|
|
634
|
+
const serverRoles = ensureArray(entry.serverRoles).join(",");
|
|
635
|
+
const lines = [
|
|
636
|
+
"# Metheus local Telegram bot entry",
|
|
637
|
+
`# Server bot: ${botName}`,
|
|
638
|
+
"",
|
|
639
|
+
`TELEGRAM_BOT_SERVER_BOT_ID=${formatEnvValue(entry.serverBotID || "")}`,
|
|
640
|
+
`TELEGRAM_BOT_SERVER_NAME=${formatEnvValue(entry.serverBotName || "")}`,
|
|
641
|
+
`TELEGRAM_BOT_SERVER_ROLES=${formatEnvValue(serverRoles)}`,
|
|
642
|
+
];
|
|
643
|
+
if (!String(entry.serverBotID || "").trim() && !String(entry.serverBotName || "").trim() && String(entry.username || "").trim()) {
|
|
644
|
+
lines.push(
|
|
645
|
+
"# Fallback only when server bot binding is unavailable",
|
|
646
|
+
`TELEGRAM_BOT_USERNAME=${formatEnvValue(entry.username || "")}`,
|
|
647
|
+
);
|
|
648
|
+
}
|
|
649
|
+
lines.push(
|
|
650
|
+
`TELEGRAM_BOT_TOKEN=${formatEnvValue(entry.token || "")}`,
|
|
651
|
+
`TELEGRAM_BOT_ROLE_PROFILE=${formatEnvValue(entry.roleProfile || "")}`,
|
|
652
|
+
`TELEGRAM_BOT_AI_CLIENT=${formatEnvValue(entry.client || "")}`,
|
|
653
|
+
`TELEGRAM_BOT_AI_MODEL=${formatEnvValue(entry.model || "")}`,
|
|
654
|
+
`TELEGRAM_BOT_AI_PERMISSION_MODE=${formatEnvValue(entry.permissionMode || "")}`,
|
|
655
|
+
`TELEGRAM_BOT_AI_REASONING_EFFORT=${formatEnvValue(entry.reasoningEffort || "")}`,
|
|
656
|
+
"",
|
|
657
|
+
);
|
|
658
|
+
return `${lines.join("\n").trimEnd()}\n`;
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
function rewriteTelegramEntryFile(entry, deps) {
|
|
662
|
+
const entryFilePath = String(requireDependency(deps, "telegramBotEntryFilePath")(entry.key) || "").trim();
|
|
663
|
+
if (!entryFilePath) return;
|
|
664
|
+
fs.mkdirSync(path.dirname(entryFilePath), { recursive: true });
|
|
665
|
+
fs.writeFileSync(entryFilePath, renderTelegramBotEntryFile(entry), {
|
|
666
|
+
encoding: "utf8",
|
|
667
|
+
mode: 0o600,
|
|
668
|
+
});
|
|
669
|
+
}
|
|
670
|
+
|
|
618
671
|
function writeProviderEnvState(provider, parsedEnv, deps) {
|
|
619
672
|
if (provider === "telegram" && typeof deps?.writeTelegramEnvState === "function") {
|
|
620
673
|
return deps.writeTelegramEnvState(parsedEnv);
|
|
@@ -644,6 +697,8 @@ function telegramEntriesForDisplay(parsedEnv, deps) {
|
|
|
644
697
|
entry.token
|
|
645
698
|
|| entry.username
|
|
646
699
|
|| entry.serverBotID
|
|
700
|
+
|| entry.serverBotName
|
|
701
|
+
|| ensureArray(entry.serverRoles).length
|
|
647
702
|
|| entry.roleProfile
|
|
648
703
|
|| entry.client
|
|
649
704
|
|| entry.model
|
|
@@ -659,6 +714,8 @@ function telegramEntriesForDisplay(parsedEnv, deps) {
|
|
|
659
714
|
|
|
660
715
|
function telegramEntryDisplayName(entry) {
|
|
661
716
|
const current = safeObject(entry);
|
|
717
|
+
const serverBotName = String(current.serverBotName || "").trim();
|
|
718
|
+
if (serverBotName) return serverBotName;
|
|
662
719
|
const username = String(current.username || "").trim();
|
|
663
720
|
if (username) return `@${username}`;
|
|
664
721
|
return String(current.key || "").trim() || "(unnamed)";
|
|
@@ -694,9 +751,9 @@ function formatRuntimeReasoningField(clientName, reasoningEffort, style = "equal
|
|
|
694
751
|
function telegramEntryDisplayDescription(entry) {
|
|
695
752
|
const current = safeObject(entry);
|
|
696
753
|
const detail = [
|
|
697
|
-
current.key ? `
|
|
698
|
-
current.serverBotID ? `
|
|
699
|
-
current.client ? `
|
|
754
|
+
current.key ? `local_selector:${current.key}` : "",
|
|
755
|
+
current.serverBotID ? `stored_server_bot_id:${current.serverBotID}` : "",
|
|
756
|
+
current.client ? `ai_client:${displayLocalAIClientName(current.client)}` : "",
|
|
700
757
|
].filter(Boolean);
|
|
701
758
|
return detail.join(" ");
|
|
702
759
|
}
|
|
@@ -705,7 +762,9 @@ function findTelegramEntryByFlags(parsedEnv, flags, deps) {
|
|
|
705
762
|
const entries = telegramEntriesForDisplay(parsedEnv, deps);
|
|
706
763
|
const requestedKey = String(flags["bot-key"] || "").trim();
|
|
707
764
|
const requestedBotID = String(flags["bot-id"] || flags["server-bot-id"] || "").trim();
|
|
708
|
-
const
|
|
765
|
+
const requestedNameRaw = String(flags["bot-name"] || flags.username || "").trim();
|
|
766
|
+
const requestedUsername = requireDependency(deps, "normalizeTelegramBotUsername")(requestedNameRaw);
|
|
767
|
+
const requestedIdentity = normalizeServerBotIdentityText(requestedNameRaw);
|
|
709
768
|
if (requestedKey) {
|
|
710
769
|
const match = entries.find((entry) => entry.key === requestedKey);
|
|
711
770
|
if (!match) {
|
|
@@ -720,12 +779,16 @@ function findTelegramEntryByFlags(parsedEnv, flags, deps) {
|
|
|
720
779
|
}
|
|
721
780
|
return match;
|
|
722
781
|
}
|
|
723
|
-
if (
|
|
782
|
+
if (requestedNameRaw) {
|
|
724
783
|
const match = entries.find(
|
|
725
|
-
(entry) =>
|
|
784
|
+
(entry) => (
|
|
785
|
+
entry.username === requestedUsername
|
|
786
|
+
|| normalizeServerBotIdentityText(entry.serverBotName) === requestedIdentity
|
|
787
|
+
|| normalizeServerBotIdentityText(entry.key) === requestedIdentity
|
|
788
|
+
),
|
|
726
789
|
);
|
|
727
790
|
if (!match) {
|
|
728
|
-
throw new Error(`Telegram bot entry with server bot name "${
|
|
791
|
+
throw new Error(`Telegram bot entry with server bot name "${requestedNameRaw}" was not found`);
|
|
729
792
|
}
|
|
730
793
|
return match;
|
|
731
794
|
}
|
|
@@ -783,6 +846,7 @@ async function editTelegramBotGuided(ui, parsed, selected, current, flags, deps)
|
|
|
783
846
|
const initialBinding = await resolveTelegramServerBindingDetails(
|
|
784
847
|
{
|
|
785
848
|
serverBotID: current.serverBotID,
|
|
849
|
+
serverBotName: current.serverBotName,
|
|
786
850
|
botUsername: current.username,
|
|
787
851
|
botKey: current.key,
|
|
788
852
|
roleProfile: current.roleProfile,
|
|
@@ -795,8 +859,13 @@ async function editTelegramBotGuided(ui, parsed, selected, current, flags, deps)
|
|
|
795
859
|
current.__preferServerIdentity = true;
|
|
796
860
|
if (initialBinding.mode === "single") {
|
|
797
861
|
current.serverBotID = String(initialBinding.serverBotID || "").trim();
|
|
862
|
+
current.serverBotName = String(initialBinding.name || "").trim();
|
|
863
|
+
current.serverRoles = ensureArray(initialBinding.roles);
|
|
798
864
|
current.roleProfile = String(initialBinding.role || current.roleProfile || "").trim();
|
|
799
865
|
applyRoleProfileDefaults(current, resolveRoleProfileDefaults(current.roleProfile, deps));
|
|
866
|
+
} else if (initialBinding.mode === "group") {
|
|
867
|
+
current.serverBotName = String(initialBinding.name || "").trim();
|
|
868
|
+
current.serverRoles = ensureArray(initialBinding.roles);
|
|
800
869
|
}
|
|
801
870
|
}
|
|
802
871
|
}
|
|
@@ -847,6 +916,8 @@ async function editTelegramBotGuided(ui, parsed, selected, current, flags, deps)
|
|
|
847
916
|
const serverBot = await autoResolveTelegramServerBot(current, flags, deps);
|
|
848
917
|
if (serverBot.matchMode === "group") {
|
|
849
918
|
current.serverBotID = "";
|
|
919
|
+
current.serverBotName = String(serverBot.name || "").trim();
|
|
920
|
+
current.serverRoles = preferredRoleSort(serverBot.roles);
|
|
850
921
|
current.__preferServerIdentity = true;
|
|
851
922
|
current.roleProfile = "";
|
|
852
923
|
current.client = "";
|
|
@@ -861,6 +932,8 @@ async function editTelegramBotGuided(ui, parsed, selected, current, flags, deps)
|
|
|
861
932
|
);
|
|
862
933
|
} else if (String(serverBot.botID || "").trim()) {
|
|
863
934
|
current.serverBotID = String(serverBot.botID || "").trim();
|
|
935
|
+
current.serverBotName = String(serverBot.name || "").trim();
|
|
936
|
+
current.serverRoles = ensureArray(serverBot.roles);
|
|
864
937
|
current.__preferServerIdentity = true;
|
|
865
938
|
current.roleProfile = String(serverBot.role || current.roleProfile || "").trim();
|
|
866
939
|
serverRoleAutoResolved = String(serverBot.role || current.roleProfile || "").trim() || "__server_binding__";
|
|
@@ -995,6 +1068,8 @@ function renderBotListPayload(provider, state, deps) {
|
|
|
995
1068
|
key: entry.key,
|
|
996
1069
|
isDefault: entry.isDefault,
|
|
997
1070
|
serverBotID: entry.serverBotID,
|
|
1071
|
+
serverBotName: entry.serverBotName,
|
|
1072
|
+
serverRoles: ensureArray(entry.serverRoles),
|
|
998
1073
|
username: entry.username,
|
|
999
1074
|
tokenConfigured: Boolean(entry.token),
|
|
1000
1075
|
roleProfile: entry.roleProfile,
|
|
@@ -1037,6 +1112,8 @@ function buildBotShowPayload(provider, state, entry, deps, extras = {}) {
|
|
|
1037
1112
|
key: selectedEntry.key,
|
|
1038
1113
|
isDefault: selectedEntry.isDefault,
|
|
1039
1114
|
serverBotID: selectedEntry.serverBotID,
|
|
1115
|
+
serverBotName: selectedEntry.serverBotName,
|
|
1116
|
+
serverRoles: ensureArray(selectedEntry.serverRoles),
|
|
1040
1117
|
username: selectedEntry.username,
|
|
1041
1118
|
tokenConfigured: Boolean(selectedEntry.token),
|
|
1042
1119
|
roleProfile: selectedEntry.roleProfile,
|
|
@@ -1133,9 +1210,9 @@ function printBotList(provider, state, deps) {
|
|
|
1133
1210
|
process.stdout.write(
|
|
1134
1211
|
[
|
|
1135
1212
|
` - ${telegramEntryDisplayName(entry)}${entry.isDefault ? " [default]" : ""}`,
|
|
1136
|
-
`
|
|
1213
|
+
` local_selector: ${entry.key || "-"}${entry.key ? " (advanced)" : ""}`,
|
|
1137
1214
|
` server_bot_id: ${entry.serverBotID || "-"}`,
|
|
1138
|
-
`
|
|
1215
|
+
` fallback_username: ${entry.username ? `@${entry.username}` : "-"}`,
|
|
1139
1216
|
` token: ${entry.token ? maskSecret(entry.token) : "-"}`,
|
|
1140
1217
|
` role_profile: ${entry.roleProfile || "-"}`,
|
|
1141
1218
|
` ai_client: ${entry.client ? displayLocalAIClientName(entry.client) : "-"}`,
|
|
@@ -1159,11 +1236,13 @@ function printBotShow(provider, state, entry, deps, extras = {}) {
|
|
|
1159
1236
|
const routeLinks = safeObject(extras.routeLinks);
|
|
1160
1237
|
process.stdout.write(`${providerLabel(provider, deps)} bot\n`);
|
|
1161
1238
|
process.stdout.write(` file: ${state.filePath}\n`);
|
|
1162
|
-
process.stdout.write(`
|
|
1163
|
-
process.stdout.write(`
|
|
1239
|
+
process.stdout.write(` server_name: ${telegramEntryDisplayName(selectedEntry)}\n`);
|
|
1240
|
+
process.stdout.write(` local_selector: ${selectedEntry.key || "-"}${selectedEntry.key ? " (advanced)" : ""}\n`);
|
|
1164
1241
|
process.stdout.write(` default: ${selectedEntry.isDefault ? "yes" : "no"}\n`);
|
|
1165
|
-
process.stdout.write(`
|
|
1166
|
-
process.stdout.write(`
|
|
1242
|
+
process.stdout.write(` stored_server_bot_id: ${selectedEntry.serverBotID || "-"}\n`);
|
|
1243
|
+
process.stdout.write(` stored_server_name: ${selectedEntry.serverBotName || "-"}\n`);
|
|
1244
|
+
process.stdout.write(` stored_server_roles: ${ensureArray(selectedEntry.serverRoles).join(", ") || "-" }\n`);
|
|
1245
|
+
process.stdout.write(` fallback_username: ${selectedEntry.username ? `@${selectedEntry.username}` : "-"}\n`);
|
|
1167
1246
|
process.stdout.write(` token: ${selectedEntry.token ? maskSecret(selectedEntry.token) : "(not configured)"}\n`);
|
|
1168
1247
|
process.stdout.write(` role_profile: ${selectedEntry.roleProfile || "-"}\n`);
|
|
1169
1248
|
process.stdout.write(` ai_client: ${selectedEntry.client ? displayLocalAIClientName(selectedEntry.client) : "-"}\n`);
|
|
@@ -1172,17 +1251,17 @@ function printBotShow(provider, state, entry, deps, extras = {}) {
|
|
|
1172
1251
|
process.stdout.write(` reasoning_effort: ${selectedEntry.reasoningEffort || "-"}\n`);
|
|
1173
1252
|
if (Object.keys(serverBinding).length) {
|
|
1174
1253
|
process.stdout.write(` server_binding: ${serverBinding.ok ? "OK" : "FAIL"}${serverBinding.detail ? ` (${serverBinding.detail})` : ""}\n`);
|
|
1175
|
-
process.stdout.write(`
|
|
1176
|
-
process.stdout.write(`
|
|
1177
|
-
process.stdout.write(`
|
|
1254
|
+
process.stdout.write(` binding_mode: ${serverBinding.mode || "-"}\n`);
|
|
1255
|
+
process.stdout.write(` live_server_name: ${serverBinding.name || "-"}\n`);
|
|
1256
|
+
process.stdout.write(` live_server_bot_id: ${serverBinding.serverBotID || selectedEntry.serverBotID || "-" }\n`);
|
|
1178
1257
|
if (serverBinding.mode === "group") {
|
|
1179
|
-
process.stdout.write(`
|
|
1258
|
+
process.stdout.write(` live_server_roles: ${ensureArray(serverBinding.roles).join(", ") || "-"}\n`);
|
|
1180
1259
|
const groupedProfiles = safeObject(serverBinding.effectiveRoleProfiles);
|
|
1181
1260
|
Object.keys(groupedProfiles).forEach((role) => {
|
|
1182
1261
|
process.stdout.write(` runtime_role_profile[${role}]: ${formatRoleProfileOutputLine(groupedProfiles[role])}\n`);
|
|
1183
1262
|
});
|
|
1184
1263
|
} else if (serverBinding.effectiveRoleProfile) {
|
|
1185
|
-
process.stdout.write(`
|
|
1264
|
+
process.stdout.write(` live_server_role: ${serverBinding.role || "-"}\n`);
|
|
1186
1265
|
process.stdout.write(` runtime_role_profile: ${formatRoleProfileOutputLine(serverBinding.effectiveRoleProfile)}\n`);
|
|
1187
1266
|
}
|
|
1188
1267
|
}
|
|
@@ -1877,7 +1956,12 @@ async function maybePromptGroupedServerRoleProfiles(ui, serverBot, deps) {
|
|
|
1877
1956
|
|
|
1878
1957
|
function resolveTelegramServerBindingDetailsFromBots(envConfig, bots, deps) {
|
|
1879
1958
|
const current = safeObject(envConfig);
|
|
1880
|
-
if (
|
|
1959
|
+
if (
|
|
1960
|
+
!String(current.serverBotID || "").trim()
|
|
1961
|
+
&& !String(current.serverBotName || "").trim()
|
|
1962
|
+
&& !String(current.botUsername || "").trim()
|
|
1963
|
+
&& !String(current.botKey || "").trim()
|
|
1964
|
+
) {
|
|
1881
1965
|
return null;
|
|
1882
1966
|
}
|
|
1883
1967
|
const resolveGroupedPayload = (matches, matchedBy) => {
|
|
@@ -1929,7 +2013,7 @@ function resolveTelegramServerBindingDetailsFromBots(envConfig, bots, deps) {
|
|
|
1929
2013
|
detail: `${String(match.name || "").trim() || "(unnamed)"} [${String(match.role || "").trim() || "-"}]`,
|
|
1930
2014
|
};
|
|
1931
2015
|
}
|
|
1932
|
-
const normalizedServerIdentity = normalizeServerBotIdentityText(current.botUsername || current.botKey);
|
|
2016
|
+
const normalizedServerIdentity = normalizeServerBotIdentityText(current.serverBotName || current.botUsername || current.botKey);
|
|
1933
2017
|
const matches = bots.filter((bot) => normalizeServerBotIdentityText(bot.name) === normalizedServerIdentity);
|
|
1934
2018
|
if (!matches.length) {
|
|
1935
2019
|
return {
|
|
@@ -2014,6 +2098,7 @@ async function buildTelegramEntrySelectionRows(entries, flags, deps) {
|
|
|
2014
2098
|
? resolveTelegramServerBindingDetailsFromBots(
|
|
2015
2099
|
{
|
|
2016
2100
|
serverBotID: current.serverBotID,
|
|
2101
|
+
serverBotName: current.serverBotName,
|
|
2017
2102
|
botUsername: current.username,
|
|
2018
2103
|
botKey: current.key,
|
|
2019
2104
|
roleProfile: current.roleProfile,
|
|
@@ -2034,9 +2119,9 @@ async function buildTelegramEntrySelectionRows(entries, flags, deps) {
|
|
|
2034
2119
|
label = serverName;
|
|
2035
2120
|
}
|
|
2036
2121
|
const descriptionParts = [
|
|
2037
|
-
current.key ? `
|
|
2038
|
-
current.serverBotID ? `
|
|
2039
|
-
current.client ? `
|
|
2122
|
+
current.key ? `local_selector:${current.key} (advanced)` : "",
|
|
2123
|
+
current.serverBotID ? `stored_server_bot_id:${current.serverBotID}` : "",
|
|
2124
|
+
current.client ? `ai_client:${displayLocalAIClientName(current.client)}` : "",
|
|
2040
2125
|
].filter(Boolean);
|
|
2041
2126
|
return {
|
|
2042
2127
|
value: current.key,
|
|
@@ -2062,6 +2147,7 @@ async function verifyTelegramTokenCandidate(provider, token, apiBaseURL, timeout
|
|
|
2062
2147
|
async function autoResolveTelegramServerBot(current, flags, deps) {
|
|
2063
2148
|
const existingBotID = String(current?.serverBotID || "").trim();
|
|
2064
2149
|
const preferredIdentity = firstNonEmptyString([
|
|
2150
|
+
current?.serverBotName,
|
|
2065
2151
|
current?.username,
|
|
2066
2152
|
current?.key,
|
|
2067
2153
|
]);
|
|
@@ -2275,6 +2361,8 @@ async function addTelegramBot(ui, flags, deps) {
|
|
|
2275
2361
|
const nextParsed = upsertTelegramEntry(parsed, {
|
|
2276
2362
|
key: botKey,
|
|
2277
2363
|
serverBotID: String(getServerBotIDFlag(flags) || serverBot.botID || "").trim(),
|
|
2364
|
+
serverBotName: String(serverBot.name || "").trim(),
|
|
2365
|
+
serverRoles: preferredRoleSort(serverBot.roles),
|
|
2278
2366
|
username,
|
|
2279
2367
|
__preferServerIdentity: serverBot.matchMode === "group" || Boolean(String(getServerBotIDFlag(flags) || serverBot.botID || "").trim()),
|
|
2280
2368
|
token,
|
|
@@ -2391,6 +2479,23 @@ async function editTelegramBot(ui, flags, deps) {
|
|
|
2391
2479
|
if (boolFromRaw(flags.default, false)) {
|
|
2392
2480
|
parsed.TELEGRAM_DEFAULT_BOT_KEY = current.key;
|
|
2393
2481
|
}
|
|
2482
|
+
if (current.serverBotID || current.username || current.serverBotName) {
|
|
2483
|
+
const resolvedServerBot = await autoResolveTelegramServerBot(current, flags, deps);
|
|
2484
|
+
if (resolvedServerBot.matchMode === "group") {
|
|
2485
|
+
current.serverBotID = String(getServerBotIDFlag(flags) || current.serverBotID || "").trim();
|
|
2486
|
+
current.serverBotName = String(resolvedServerBot.name || current.serverBotName || "").trim();
|
|
2487
|
+
current.serverRoles = preferredRoleSort(resolvedServerBot.roles);
|
|
2488
|
+
if (!hasOwnFlag(flags, "role-profile")) current.roleProfile = "";
|
|
2489
|
+
if (!(hasOwnFlag(flags, "client") || hasOwnFlag(flags, "ai-client"))) current.client = "";
|
|
2490
|
+
if (!(hasOwnFlag(flags, "model") || hasOwnFlag(flags, "ai-model"))) current.model = "";
|
|
2491
|
+
if (!(hasOwnFlag(flags, "permission-mode") || hasOwnFlag(flags, "ai-permission-mode"))) current.permissionMode = "";
|
|
2492
|
+
if (!(hasOwnFlag(flags, "reasoning-effort") || hasOwnFlag(flags, "ai-reasoning-effort"))) current.reasoningEffort = "";
|
|
2493
|
+
} else if (String(resolvedServerBot.botID || "").trim()) {
|
|
2494
|
+
current.serverBotID = String(resolvedServerBot.botID || "").trim();
|
|
2495
|
+
current.serverBotName = String(resolvedServerBot.name || "").trim();
|
|
2496
|
+
current.serverRoles = ensureArray(resolvedServerBot.roles);
|
|
2497
|
+
}
|
|
2498
|
+
}
|
|
2394
2499
|
saveTelegramBotEdit(parsed, selected, current, deps);
|
|
2395
2500
|
return;
|
|
2396
2501
|
}
|
|
@@ -2462,6 +2567,62 @@ async function verifyProviderEntry(ui, provider, flags, deps) {
|
|
|
2462
2567
|
if (serverBinding && !serverBinding.ok) {
|
|
2463
2568
|
overallOK = false;
|
|
2464
2569
|
}
|
|
2570
|
+
if (serverBinding?.ok && envConfig.botKey) {
|
|
2571
|
+
const selectedEntry = findTelegramEntryByFlags(
|
|
2572
|
+
state.parsed,
|
|
2573
|
+
{ "bot-key": envConfig.botKey },
|
|
2574
|
+
deps,
|
|
2575
|
+
);
|
|
2576
|
+
if (selectedEntry) {
|
|
2577
|
+
const desiredServerBotName = String(serverBinding.name || "").trim();
|
|
2578
|
+
const desiredServerRoles = ensureArray(serverBinding.roles);
|
|
2579
|
+
const currentServerRoles = ensureArray(selectedEntry.serverRoles);
|
|
2580
|
+
const currentServerRolesJoined = currentServerRoles.join(",");
|
|
2581
|
+
const desiredServerRolesJoined = desiredServerRoles.join(",");
|
|
2582
|
+
const desiredServerBotID = (
|
|
2583
|
+
String(selectedEntry.serverBotID || "").trim()
|
|
2584
|
+
|| (serverBinding.mode === "single" ? String(serverBinding.serverBotID || "").trim() : "")
|
|
2585
|
+
);
|
|
2586
|
+
const needsMetadataBackfill = (
|
|
2587
|
+
String(selectedEntry.serverBotName || "").trim() !== desiredServerBotName
|
|
2588
|
+
|| currentServerRolesJoined !== desiredServerRolesJoined
|
|
2589
|
+
|| String(selectedEntry.serverBotID || "").trim() !== desiredServerBotID
|
|
2590
|
+
);
|
|
2591
|
+
if (needsMetadataBackfill) {
|
|
2592
|
+
const nextEntry = {
|
|
2593
|
+
...selectedEntry,
|
|
2594
|
+
serverBotID: desiredServerBotID,
|
|
2595
|
+
serverBotName: desiredServerBotName,
|
|
2596
|
+
serverRoles: desiredServerRoles,
|
|
2597
|
+
};
|
|
2598
|
+
const nextParsed = upsertTelegramEntry(state.parsed, nextEntry);
|
|
2599
|
+
writeProviderEnvState("telegram", nextParsed, deps);
|
|
2600
|
+
rewriteTelegramEntryFile(nextEntry, deps);
|
|
2601
|
+
envConfig.serverBotID = desiredServerBotID;
|
|
2602
|
+
envConfig.serverBotName = desiredServerBotName;
|
|
2603
|
+
envConfig.serverRoles = desiredServerRoles;
|
|
2604
|
+
}
|
|
2605
|
+
const rewriteEntry = needsMetadataBackfill
|
|
2606
|
+
? {
|
|
2607
|
+
...selectedEntry,
|
|
2608
|
+
serverBotID: desiredServerBotID,
|
|
2609
|
+
serverBotName: desiredServerBotName,
|
|
2610
|
+
serverRoles: desiredServerRoles,
|
|
2611
|
+
}
|
|
2612
|
+
: selectedEntry;
|
|
2613
|
+
const currentEntryFilePath = String(
|
|
2614
|
+
rewriteEntry.entryFilePath
|
|
2615
|
+
|| requireDependency(deps, "telegramBotEntryFilePath")(rewriteEntry.key),
|
|
2616
|
+
).trim();
|
|
2617
|
+
const expectedEntryText = renderTelegramBotEntryFile(rewriteEntry);
|
|
2618
|
+
const currentEntryText = currentEntryFilePath && fs.existsSync(currentEntryFilePath)
|
|
2619
|
+
? fs.readFileSync(currentEntryFilePath, "utf8")
|
|
2620
|
+
: "";
|
|
2621
|
+
if (currentEntryText !== expectedEntryText) {
|
|
2622
|
+
rewriteTelegramEntryFile(rewriteEntry, deps);
|
|
2623
|
+
}
|
|
2624
|
+
}
|
|
2625
|
+
}
|
|
2465
2626
|
routeLinks = summarizeTelegramRouteLinks(state.parsed, {
|
|
2466
2627
|
key: envConfig.botKey,
|
|
2467
2628
|
serverBotID: envConfig.serverBotID,
|
|
@@ -2492,6 +2653,8 @@ async function verifyProviderEntry(ui, provider, flags, deps) {
|
|
|
2492
2653
|
filePath: envConfig.filePath,
|
|
2493
2654
|
botKey: envConfig.botKey || "",
|
|
2494
2655
|
serverBotID: envConfig.serverBotID || "",
|
|
2656
|
+
serverBotName: envConfig.serverBotName || "",
|
|
2657
|
+
serverRoles: ensureArray(envConfig.serverRoles),
|
|
2495
2658
|
detail: result.detail || "",
|
|
2496
2659
|
roleProfile: envConfig.roleProfile || "",
|
|
2497
2660
|
client: envConfig.client || "",
|
|
@@ -2506,8 +2669,10 @@ async function verifyProviderEntry(ui, provider, flags, deps) {
|
|
|
2506
2669
|
const lines = [
|
|
2507
2670
|
`${providerLabel(provider, deps)} verify: ${overallOK ? "OK" : "FAIL"}`,
|
|
2508
2671
|
`file: ${envConfig.filePath}`,
|
|
2509
|
-
provider === "telegram" ? `
|
|
2510
|
-
provider === "telegram" ? `
|
|
2672
|
+
provider === "telegram" ? `local_selector: ${envConfig.botKey || "-"}${envConfig.botKey ? " (advanced)" : ""}` : "",
|
|
2673
|
+
provider === "telegram" ? `stored_server_bot_id: ${envConfig.serverBotID || "-"}` : "",
|
|
2674
|
+
provider === "telegram" ? `stored_server_name: ${envConfig.serverBotName || "-"}` : "",
|
|
2675
|
+
provider === "telegram" ? `stored_server_roles: ${ensureArray(envConfig.serverRoles).join(", ") || "-"}` : "",
|
|
2511
2676
|
provider === "telegram" ? `role_profile: ${envConfig.roleProfile || "-"}` : "",
|
|
2512
2677
|
provider === "telegram" ? `ai_client: ${envConfig.client ? displayLocalAIClientName(envConfig.client) : "-"}` : "",
|
|
2513
2678
|
provider === "telegram" ? `ai_model: ${envConfig.model || "-"}` : "",
|
|
@@ -2518,9 +2683,9 @@ async function verifyProviderEntry(ui, provider, flags, deps) {
|
|
|
2518
2683
|
routeLinks ? `route_links: ${intFromRaw(routeLinks.total, 0)}` : "",
|
|
2519
2684
|
].filter(Boolean);
|
|
2520
2685
|
if (provider === "telegram" && serverBinding) {
|
|
2521
|
-
lines.push(`
|
|
2522
|
-
lines.push(`
|
|
2523
|
-
lines.push(`
|
|
2686
|
+
lines.push(`binding_mode: ${serverBinding.mode || "-"}`);
|
|
2687
|
+
lines.push(`live_server_name: ${serverBinding.name || "-"}`);
|
|
2688
|
+
lines.push(`live_server_roles: ${ensureArray(serverBinding.roles).join(", ") || "-"}`);
|
|
2524
2689
|
if (serverBinding.mode === "group") {
|
|
2525
2690
|
const groupedProfiles = safeObject(serverBinding.effectiveRoleProfiles);
|
|
2526
2691
|
Object.keys(groupedProfiles).forEach((role) => {
|
|
@@ -352,14 +352,15 @@ export async function runSelftestBotCommands(push, deps) {
|
|
|
352
352
|
const addGlobals = readTelegramGlobals();
|
|
353
353
|
push(
|
|
354
354
|
"bot_add_guided_creates_named_telegram_entry",
|
|
355
|
-
String(addState.
|
|
355
|
+
String(addState.TELEGRAM_BOT_SERVER_NAME || "") === "MonitorSelftestBot"
|
|
356
|
+
&& String(addState.TELEGRAM_BOT_SERVER_ROLES || "") === "monitor"
|
|
356
357
|
&& String(addState.TELEGRAM_BOT_TOKEN || "") === "selftest-main-token"
|
|
357
358
|
&& String(addState.TELEGRAM_BOT_ROLE_PROFILE || "") === "monitor"
|
|
358
359
|
&& String(addState.TELEGRAM_BOT_AI_CLIENT || "") === "codex"
|
|
359
360
|
&& String(addState.TELEGRAM_BOT_AI_PERMISSION_MODE || "") === "read_only"
|
|
360
361
|
&& String(addState.TELEGRAM_BOT_AI_REASONING_EFFORT || "") === "low"
|
|
361
362
|
&& String(addGlobals.TELEGRAM_DEFAULT_BOT_KEY || "") === "monitorselftestbot",
|
|
362
|
-
`default=${String(addGlobals.TELEGRAM_DEFAULT_BOT_KEY || "")} token=${String(addState.TELEGRAM_BOT_TOKEN || "")} role=${String(addState.TELEGRAM_BOT_ROLE_PROFILE || "")} client=${String(addState.TELEGRAM_BOT_AI_CLIENT || "")}`,
|
|
363
|
+
`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 || "")}`,
|
|
363
364
|
);
|
|
364
365
|
|
|
365
366
|
const groupedMock = await createMockServer({
|
|
@@ -401,12 +402,13 @@ export async function runSelftestBotCommands(push, deps) {
|
|
|
401
402
|
const groupedState = readTelegramBotEntry("ryoai_bot");
|
|
402
403
|
push(
|
|
403
404
|
"bot_add_guided_autoresolves_server_bot_group_without_role_prompt",
|
|
404
|
-
String(groupedState.
|
|
405
|
-
&& String(groupedState.
|
|
405
|
+
String(groupedState.TELEGRAM_BOT_SERVER_BOT_ID || "") === ""
|
|
406
|
+
&& String(groupedState.TELEGRAM_BOT_SERVER_NAME || "") === "RyoAI_bot"
|
|
407
|
+
&& String(groupedState.TELEGRAM_BOT_SERVER_ROLES || "") === "monitor,review,worker,approval"
|
|
406
408
|
&& String(groupedState.TELEGRAM_BOT_ROLE_PROFILE || "") === ""
|
|
407
409
|
&& String(groupedState.TELEGRAM_BOT_AI_CLIENT || "") === ""
|
|
408
410
|
&& String(groupedState.TELEGRAM_BOT_AI_PERMISSION_MODE || "") === "",
|
|
409
|
-
`
|
|
411
|
+
`server_name=${String(groupedState.TELEGRAM_BOT_SERVER_NAME || "")} roles=${String(groupedState.TELEGRAM_BOT_SERVER_ROLES || "")} server_bot_id=${String(groupedState.TELEGRAM_BOT_SERVER_BOT_ID || "")} role=${String(groupedState.TELEGRAM_BOT_ROLE_PROFILE || "")}`,
|
|
410
412
|
);
|
|
411
413
|
|
|
412
414
|
const groupedEditResult = await runCLI({
|
|
@@ -758,11 +760,13 @@ export async function runSelftestBotCommands(push, deps) {
|
|
|
758
760
|
push(
|
|
759
761
|
"bot_add_accepts_ai_prefixed_option_aliases",
|
|
760
762
|
String(aliasAddState.TELEGRAM_BOT_SERVER_BOT_ID || "") === mock.bots[0].id
|
|
763
|
+
&& String(aliasAddState.TELEGRAM_BOT_SERVER_NAME || "") === "MonitorSelftestBot"
|
|
764
|
+
&& String(aliasAddState.TELEGRAM_BOT_SERVER_ROLES || "") === "monitor"
|
|
761
765
|
&& String(aliasAddState.TELEGRAM_BOT_AI_CLIENT || "") === "codex"
|
|
762
766
|
&& String(aliasAddState.TELEGRAM_BOT_AI_MODEL || "") === "gpt-5.4"
|
|
763
767
|
&& String(aliasAddState.TELEGRAM_BOT_AI_PERMISSION_MODE || "") === "read_only"
|
|
764
768
|
&& String(aliasAddState.TELEGRAM_BOT_AI_REASONING_EFFORT || "") === "low",
|
|
765
|
-
`client=${String(aliasAddState.TELEGRAM_BOT_AI_CLIENT || "")} model=${String(aliasAddState.TELEGRAM_BOT_AI_MODEL || "")}`,
|
|
769
|
+
`server_name=${String(aliasAddState.TELEGRAM_BOT_SERVER_NAME || "")} roles=${String(aliasAddState.TELEGRAM_BOT_SERVER_ROLES || "")} client=${String(aliasAddState.TELEGRAM_BOT_AI_CLIENT || "")} model=${String(aliasAddState.TELEGRAM_BOT_AI_MODEL || "")}`,
|
|
766
770
|
);
|
|
767
771
|
|
|
768
772
|
const guidedRemoveBeforeList = await runCLI({
|