metheus-governance-mcp-cli 0.2.106 → 0.2.108
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 +4 -4
- package/cli.mjs +6 -7
- package/lib/bot-commands.mjs +47 -33
- package/lib/doctor-checks.mjs +3 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -248,7 +248,7 @@ 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
|
|
251
|
+
- In the normal Telegram path, `bot add` does not ask for a 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.
|
|
@@ -285,7 +285,7 @@ Behavior:
|
|
|
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
287
|
- `bot global` edits Telegram-wide local settings such as API base URL, allowed updates, and the default Telegram bot selector.
|
|
288
|
-
- `bot set-default`
|
|
288
|
+
- `bot set-default` changes the default Telegram bot selection.
|
|
289
289
|
- `bot migrate` moves legacy `TELEGRAM_BOT_TOKEN` into a named Telegram bot entry.
|
|
290
290
|
|
|
291
291
|
Non-interactive examples:
|
|
@@ -301,9 +301,9 @@ metheus-governance-mcp-cli bot remove --provider telegram --bot-name <server_bot
|
|
|
301
301
|
metheus-governance-mcp-cli bot verify --provider telegram --bot-name <server_bot_name> --json true
|
|
302
302
|
```
|
|
303
303
|
|
|
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
|
|
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 a legacy compatibility selector only when you intentionally need to target an older local selector directly.
|
|
305
305
|
|
|
306
|
-
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
|
|
306
|
+
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 legacy 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.
|
|
307
307
|
|
|
308
308
|
For runner commands, you can still use `--route-name` directly, but normal operator workflows can also use `--bot-name` or `--bot-id` when those identify one enabled route uniquely. Use `runner list` first if you are not sure which route belongs to which server bot.
|
|
309
309
|
|
package/cli.mjs
CHANGED
|
@@ -249,7 +249,7 @@ function printUsage() {
|
|
|
249
249
|
` ${cmd} bot set-default --provider telegram [--bot-name <server_name>] [--bot-id <uuid>]`,
|
|
250
250
|
` ${cmd} bot migrate --provider telegram [--bot-name <server_name>] [--bot-id <uuid>]`,
|
|
251
251
|
` ${cmd} bot verify [--provider <telegram|slack|kakaotalk>] [--bot-name <server_name>] [--bot-id <uuid>] [--timeout-seconds <n>] [--json <true|false>]`,
|
|
252
|
-
` ${cmd} bot global --provider telegram [--api-base-url <url>] [--auto-clear-webhook <true|false>] [--allowed-updates <csv>] [--default-bot-
|
|
252
|
+
` ${cmd} bot global --provider telegram [--api-base-url <url>] [--auto-clear-webhook <true|false>] [--allowed-updates <csv>] [--default-bot-name <server_name>] [--default-bot-id <uuid>]`,
|
|
253
253
|
` ${cmd} doctor [--project-id <uuid>] [--ctxpack-key <key>] [--base-url <url>] [--timeout-seconds <n>] [--strict <true|false>]`,
|
|
254
254
|
` ${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>]`,
|
|
255
255
|
` ${cmd} selftest [--json <true|false>]`,
|
|
@@ -4285,10 +4285,9 @@ async function runDoctor(flags) {
|
|
|
4285
4285
|
continue;
|
|
4286
4286
|
}
|
|
4287
4287
|
const detailParts = [];
|
|
4288
|
-
if (envConfig.
|
|
4289
|
-
|
|
4290
|
-
|
|
4291
|
-
else if (envConfig.botKey) detailParts.push(`server_name=${envConfig.botKey}`);
|
|
4288
|
+
if (envConfig.serverBotName) detailParts.push(`server_bot_name=${envConfig.serverBotName}`);
|
|
4289
|
+
if (envConfig.serverBotID) detailParts.push(`server_bot_id=${envConfig.serverBotID}`);
|
|
4290
|
+
if (envConfig.botUsername) detailParts.push(`fallback_username=@${envConfig.botUsername}`);
|
|
4292
4291
|
if (envConfig.client) detailParts.push(`ai=${envConfig.client}`);
|
|
4293
4292
|
addDoctorCheck(
|
|
4294
4293
|
rows,
|
|
@@ -4316,8 +4315,8 @@ async function runDoctor(flags) {
|
|
|
4316
4315
|
"ok",
|
|
4317
4316
|
`runner route ${routeLabel} server bot`,
|
|
4318
4317
|
envConfig.botUsername
|
|
4319
|
-
? `resolved by
|
|
4320
|
-
: `resolved by server bot name ${envConfig.botKey}`,
|
|
4318
|
+
? `resolved by fallback username @${envConfig.botUsername}`
|
|
4319
|
+
: `resolved by server bot name ${envConfig.serverBotName || envConfig.botKey}`,
|
|
4321
4320
|
);
|
|
4322
4321
|
} else {
|
|
4323
4322
|
addDoctorCheck(
|
package/lib/bot-commands.mjs
CHANGED
|
@@ -223,18 +223,18 @@ function printBotUsage(deps) {
|
|
|
223
223
|
` ${cliName} bot set-default --provider telegram [--bot-name <server_name>] [--bot-id <uuid>] [--non-interactive <true|false>]`,
|
|
224
224
|
` ${cliName} bot migrate --provider telegram [--bot-name <server_name>] [--bot-id <uuid>] [--keep-legacy-token <true|false>] [--non-interactive <true|false>]`,
|
|
225
225
|
` ${cliName} bot verify [--provider <telegram|slack|kakaotalk>] [--bot-name <server_name>] [--bot-id <uuid>] [--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-
|
|
226
|
+
` ${cliName} bot global --provider telegram [--non-interactive <true|false>] [--api-base-url <url>] [--auto-clear-webhook <true|false>] [--allowed-updates <csv>] [--default-bot-name <server_name>] [--default-bot-id <uuid>]`,
|
|
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
|
-
` - in the normal Telegram path, bot add does not ask for
|
|
232
|
-
` - server bot name/UUID is the source of truth; --bot-key
|
|
231
|
+
` - in the normal Telegram path, bot add does not ask for a local selector or a server role/profile choice.`,
|
|
232
|
+
` - server bot name/UUID is the source of truth; --bot-key remains only as a legacy compatibility selector.`,
|
|
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.`,
|
|
235
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.`,
|
|
236
236
|
` - bot set-default / bot verify / bot remove also support guided numbered selection when run without flags.`,
|
|
237
|
-
` -
|
|
237
|
+
` - legacy compatibility: prefer --bot-name or --bot-id in normal operator workflows; use --bot-key only when you must target an older local selector directly.`,
|
|
238
238
|
"",
|
|
239
239
|
].join("\n"),
|
|
240
240
|
);
|
|
@@ -858,7 +858,7 @@ function findTelegramEntryByFlags(parsedEnv, flags, deps) {
|
|
|
858
858
|
if (requestedKey) {
|
|
859
859
|
const match = entries.find((entry) => entry.key === requestedKey);
|
|
860
860
|
if (!match) {
|
|
861
|
-
throw new Error(`Telegram bot entry "${requestedKey}" was not found`);
|
|
861
|
+
throw new Error(`Telegram bot entry with legacy local selector "${requestedKey}" was not found`);
|
|
862
862
|
}
|
|
863
863
|
return match;
|
|
864
864
|
}
|
|
@@ -895,7 +895,7 @@ function saveTelegramBotEdit(parsed, selected, current, deps) {
|
|
|
895
895
|
nextParsed.TELEGRAM_DEFAULT_BOT_KEY = current.key;
|
|
896
896
|
}
|
|
897
897
|
const filePath = writeProviderEnvState("telegram", nextParsed, deps);
|
|
898
|
-
process.stdout.write(`Saved Telegram bot
|
|
898
|
+
process.stdout.write(`Saved Telegram bot file for "${telegramEntryDisplayName(current)}" to ${filePath}\n`);
|
|
899
899
|
return filePath;
|
|
900
900
|
}
|
|
901
901
|
|
|
@@ -1129,7 +1129,7 @@ async function editTelegramBotGuided(ui, parsed, selected, current, flags, deps)
|
|
|
1129
1129
|
parsed.TELEGRAM_DEFAULT_BOT_KEY = "";
|
|
1130
1130
|
}
|
|
1131
1131
|
|
|
1132
|
-
if (!await promptYesNo(ui, `Save changes for "${current
|
|
1132
|
+
if (!await promptYesNo(ui, `Save changes for "${telegramEntryDisplayName(current)}" now?`, true)) {
|
|
1133
1133
|
process.stdout.write("Cancelled.\n");
|
|
1134
1134
|
return;
|
|
1135
1135
|
}
|
|
@@ -1306,11 +1306,9 @@ function printBotList(provider, state, deps) {
|
|
|
1306
1306
|
process.stdout.write(" entries: none\n");
|
|
1307
1307
|
return;
|
|
1308
1308
|
}
|
|
1309
|
-
|
|
1309
|
+
const defaultEntry = entries.find((entry) => entry.isDefault) || null;
|
|
1310
|
+
process.stdout.write(` default: ${defaultEntry ? telegramEntryDisplayName(defaultEntry) : "-"}\n`);
|
|
1310
1311
|
entries.forEach((entry) => {
|
|
1311
|
-
const advancedSelectorLine = entry.key
|
|
1312
|
-
? ` advanced_local_selector: ${entry.key} (compatibility only)`
|
|
1313
|
-
: "";
|
|
1314
1312
|
process.stdout.write(
|
|
1315
1313
|
[
|
|
1316
1314
|
` - ${telegramEntryDisplayName(entry)}${entry.isDefault ? " [default]" : ""}`,
|
|
@@ -1325,7 +1323,6 @@ function printBotList(provider, state, deps) {
|
|
|
1325
1323
|
` model: ${entry.model || "-"}`,
|
|
1326
1324
|
` permission_mode: ${entry.permissionMode || "-"}`,
|
|
1327
1325
|
` reasoning_effort: ${entry.reasoningEffort || "-"}`,
|
|
1328
|
-
advancedSelectorLine,
|
|
1329
1326
|
].join("\n") + "\n",
|
|
1330
1327
|
);
|
|
1331
1328
|
});
|
|
@@ -1361,7 +1358,6 @@ function printBotShow(provider, state, entry, deps, extras = {}) {
|
|
|
1361
1358
|
`ai_model: ${selectedEntry.model || "-"}`,
|
|
1362
1359
|
`permission_mode: ${selectedEntry.permissionMode || "-"}`,
|
|
1363
1360
|
`reasoning_effort: ${selectedEntry.reasoningEffort || "-"}`,
|
|
1364
|
-
selectedEntry.key ? `advanced_local_selector: ${selectedEntry.key} (compatibility only)` : "",
|
|
1365
1361
|
]);
|
|
1366
1362
|
if (Object.keys(serverBinding).length) {
|
|
1367
1363
|
const liveLines = [
|
|
@@ -1441,7 +1437,7 @@ async function resolveTelegramEntryForShow(ui, parsedEnv, flags, deps) {
|
|
|
1441
1437
|
}
|
|
1442
1438
|
const nonInteractive = boolFromRaw(flags["non-interactive"] ?? flags.yes ?? flags.json, false);
|
|
1443
1439
|
if (nonInteractive) {
|
|
1444
|
-
throw new Error("Telegram bot selector is required when multiple entries exist; pass --bot-
|
|
1440
|
+
throw new Error("Telegram bot selector is required when multiple entries exist; pass --bot-name or --bot-id (legacy --bot-key is still supported)");
|
|
1445
1441
|
}
|
|
1446
1442
|
return chooseTelegramEntry(ui, parsedEnv, deps, "Select Telegram bot entry", flags);
|
|
1447
1443
|
}
|
|
@@ -2270,7 +2266,6 @@ async function buildTelegramEntrySelectionRows(entries, flags, deps) {
|
|
|
2270
2266
|
const descriptionParts = [
|
|
2271
2267
|
current.serverBotID ? `stored_server_bot_id:${current.serverBotID}` : "",
|
|
2272
2268
|
current.client ? `ai_client:${displayLocalAIClientName(current.client)}` : "",
|
|
2273
|
-
current.key ? `advanced_selector:${current.key}` : "",
|
|
2274
2269
|
].filter(Boolean);
|
|
2275
2270
|
return {
|
|
2276
2271
|
value: current.key,
|
|
@@ -2430,7 +2425,7 @@ async function addTelegramBot(ui, flags, deps) {
|
|
|
2430
2425
|
defaultKeyHint,
|
|
2431
2426
|
);
|
|
2432
2427
|
if (nonInteractive && existingKeys.has(botKey)) {
|
|
2433
|
-
throw new Error(`Telegram local selector "${botKey}" already exists`);
|
|
2428
|
+
throw new Error(`Telegram legacy local selector "${botKey}" already exists`);
|
|
2434
2429
|
}
|
|
2435
2430
|
const serverGroupMatched = serverBot.matchMode === "group";
|
|
2436
2431
|
if (serverGroupMatched && !nonInteractive) {
|
|
@@ -2530,7 +2525,7 @@ async function addTelegramBot(ui, flags, deps) {
|
|
|
2530
2525
|
if (
|
|
2531
2526
|
boolFromRaw(flags.default, false)
|
|
2532
2527
|
|| (nonInteractive && !hasCurrentDefault)
|
|
2533
|
-
|| (!nonInteractive && !hasCurrentDefault && await promptYesNo(ui, "Set this bot as
|
|
2528
|
+
|| (!nonInteractive && !hasCurrentDefault && await promptYesNo(ui, "Set this bot as the default Telegram bot?", true))
|
|
2534
2529
|
) {
|
|
2535
2530
|
nextParsed.TELEGRAM_DEFAULT_BOT_KEY = botKey;
|
|
2536
2531
|
}
|
|
@@ -2543,6 +2538,12 @@ async function editTelegramGlobalSettings(ui, flags, deps) {
|
|
|
2543
2538
|
const state = loadProviderEnvState("telegram", deps);
|
|
2544
2539
|
const parsed = { ...state.parsed };
|
|
2545
2540
|
const nonInteractive = boolFromRaw(flags["non-interactive"] ?? flags.yes, false);
|
|
2541
|
+
const defaultSelectorFlags = {
|
|
2542
|
+
...flags,
|
|
2543
|
+
"bot-name": firstNonEmptyString([flags["default-bot-name"], flags["bot-name"]]),
|
|
2544
|
+
"bot-id": firstNonEmptyString([flags["default-bot-id"], flags["bot-id"]]),
|
|
2545
|
+
"bot-key": firstNonEmptyString([flags["default-bot-key"], flags["bot-key"]]),
|
|
2546
|
+
};
|
|
2546
2547
|
if (nonInteractive) {
|
|
2547
2548
|
if (Object.prototype.hasOwnProperty.call(flags, "api-base-url")) {
|
|
2548
2549
|
parsed.TELEGRAM_API_BASE_URL = String(flags["api-base-url"] || "").trim();
|
|
@@ -2553,8 +2554,16 @@ async function editTelegramGlobalSettings(ui, flags, deps) {
|
|
|
2553
2554
|
if (Object.prototype.hasOwnProperty.call(flags, "allowed-updates")) {
|
|
2554
2555
|
parsed.TELEGRAM_ALLOWED_UPDATES = String(flags["allowed-updates"] || "").trim();
|
|
2555
2556
|
}
|
|
2556
|
-
if (
|
|
2557
|
-
|
|
2557
|
+
if (
|
|
2558
|
+
Object.prototype.hasOwnProperty.call(flags, "default-bot-name")
|
|
2559
|
+
|| Object.prototype.hasOwnProperty.call(flags, "default-bot-id")
|
|
2560
|
+
|| Object.prototype.hasOwnProperty.call(flags, "default-bot-key")
|
|
2561
|
+
) {
|
|
2562
|
+
const selectedDefault = findTelegramEntryByFlags(parsed, defaultSelectorFlags, deps);
|
|
2563
|
+
if (!selectedDefault) {
|
|
2564
|
+
throw new Error("Telegram default bot selector was not found");
|
|
2565
|
+
}
|
|
2566
|
+
parsed.TELEGRAM_DEFAULT_BOT_KEY = selectedDefault.key;
|
|
2558
2567
|
}
|
|
2559
2568
|
const filePath = writeProviderEnvState("telegram", parsed, deps);
|
|
2560
2569
|
process.stdout.write(`Saved Telegram global settings to ${filePath}\n`);
|
|
@@ -2567,7 +2576,13 @@ async function editTelegramGlobalSettings(ui, flags, deps) {
|
|
|
2567
2576
|
{ value: "api", label: "API base URL", description: String(parsed.TELEGRAM_API_BASE_URL || "").trim() || "(empty)" },
|
|
2568
2577
|
{ value: "webhook", label: "Auto clear webhook", description: boolFromRaw(parsed.TELEGRAM_AUTO_CLEAR_WEBHOOK, true) ? "true" : "false" },
|
|
2569
2578
|
{ value: "updates", label: "Allowed updates", description: String(parsed.TELEGRAM_ALLOWED_UPDATES || "message,edited_message").trim() },
|
|
2570
|
-
{
|
|
2579
|
+
{
|
|
2580
|
+
value: "default",
|
|
2581
|
+
label: "Default Telegram bot",
|
|
2582
|
+
description: telegramEntryDisplayName(
|
|
2583
|
+
telegramEntriesForDisplay(parsed, deps).find((entry) => entry.isDefault) || {},
|
|
2584
|
+
) || "(empty)",
|
|
2585
|
+
},
|
|
2571
2586
|
],
|
|
2572
2587
|
{ defaultIndex: 0 },
|
|
2573
2588
|
);
|
|
@@ -2599,7 +2614,7 @@ async function editTelegramBot(ui, flags, deps) {
|
|
|
2599
2614
|
? findTelegramEntryByFlags(parsed, flags, deps)
|
|
2600
2615
|
: await chooseTelegramEntry(ui, parsed, deps, "Select Telegram bot entry", flags);
|
|
2601
2616
|
if (!selected) {
|
|
2602
|
-
throw new Error("Telegram bot selector is required for non-interactive edit");
|
|
2617
|
+
throw new Error("Telegram bot selector is required for non-interactive edit; pass --bot-name or --bot-id (legacy --bot-key is still supported)");
|
|
2603
2618
|
}
|
|
2604
2619
|
let current = { ...selected };
|
|
2605
2620
|
if (nonInteractive) {
|
|
@@ -2661,11 +2676,11 @@ async function removeTelegramBot(ui, flags, deps) {
|
|
|
2661
2676
|
const parsed = { ...state.parsed };
|
|
2662
2677
|
const selected = await chooseTelegramEntry(ui, parsed, deps, "Select Telegram bot entry to remove", flags);
|
|
2663
2678
|
if (!selected) return;
|
|
2664
|
-
if (!await promptConfirmChoice(ui, `Remove Telegram bot "${selected
|
|
2679
|
+
if (!await promptConfirmChoice(ui, `Remove Telegram bot "${telegramEntryDisplayName(selected)}"?`, {
|
|
2665
2680
|
confirmLabel: "Remove bot",
|
|
2666
|
-
confirmDescription: "delete this local Telegram bot
|
|
2681
|
+
confirmDescription: "delete this local Telegram bot file",
|
|
2667
2682
|
cancelLabel: "Cancel",
|
|
2668
|
-
cancelDescription: "keep the current local bot
|
|
2683
|
+
cancelDescription: "keep the current local Telegram bot file",
|
|
2669
2684
|
defaultValue: "cancel",
|
|
2670
2685
|
})) {
|
|
2671
2686
|
process.stdout.write("Cancelled.\n");
|
|
@@ -2698,7 +2713,7 @@ async function verifyProviderEntry(ui, provider, flags, deps) {
|
|
|
2698
2713
|
selectors = {
|
|
2699
2714
|
botKey: selected.key,
|
|
2700
2715
|
botID: selected.serverBotID,
|
|
2701
|
-
botName: selected.username,
|
|
2716
|
+
botName: selected.serverBotName || selected.username,
|
|
2702
2717
|
};
|
|
2703
2718
|
}
|
|
2704
2719
|
}
|
|
@@ -2848,7 +2863,6 @@ async function verifyProviderEntry(ui, provider, flags, deps) {
|
|
|
2848
2863
|
`ai_model: ${envConfig.model || "-"}`,
|
|
2849
2864
|
`permission_mode: ${envConfig.permissionMode || "-"}`,
|
|
2850
2865
|
`reasoning_effort: ${envConfig.reasoningEffort || "-"}`,
|
|
2851
|
-
envConfig.botKey ? `advanced_local_selector: ${envConfig.botKey} (compatibility only)` : "",
|
|
2852
2866
|
]);
|
|
2853
2867
|
}
|
|
2854
2868
|
if (provider === "telegram" && serverBinding) {
|
|
@@ -3105,7 +3119,7 @@ async function runBotRemove(ui, flags, deps) {
|
|
|
3105
3119
|
const state = loadProviderEnvState("telegram", deps);
|
|
3106
3120
|
const selected = findTelegramEntryByFlags(state.parsed, flags, deps);
|
|
3107
3121
|
if (!selected) {
|
|
3108
|
-
throw new Error("Telegram bot selector is required for non-interactive remove");
|
|
3122
|
+
throw new Error("Telegram bot selector is required for non-interactive remove; pass --bot-name or --bot-id (legacy --bot-key is still supported)");
|
|
3109
3123
|
}
|
|
3110
3124
|
const nextParsed = removeTelegramEntry(state.parsed, selected.key);
|
|
3111
3125
|
if (String(state.parsed.TELEGRAM_DEFAULT_BOT_KEY || "").trim() === selected.key) {
|
|
@@ -3145,11 +3159,11 @@ async function runBotSetDefault(ui, flags, deps) {
|
|
|
3145
3159
|
? findTelegramEntryByFlags(parsed, flags, deps)
|
|
3146
3160
|
: await chooseTelegramEntry(ui, parsed, deps, "Select default Telegram bot", flags);
|
|
3147
3161
|
if (!selected) {
|
|
3148
|
-
throw new Error("Telegram bot selector is required for set-default");
|
|
3162
|
+
throw new Error("Telegram bot selector is required for set-default; pass --bot-name or --bot-id (legacy --bot-key is still supported)");
|
|
3149
3163
|
}
|
|
3150
|
-
if (!nonInteractive && !await promptConfirmChoice(ui, `Set "${selected
|
|
3164
|
+
if (!nonInteractive && !await promptConfirmChoice(ui, `Set "${telegramEntryDisplayName(selected)}" as the default Telegram bot?`, {
|
|
3151
3165
|
confirmLabel: "Set default bot",
|
|
3152
|
-
confirmDescription: "make this the default
|
|
3166
|
+
confirmDescription: "make this the default Telegram bot for local delivery and fallback selection",
|
|
3153
3167
|
cancelLabel: "Cancel",
|
|
3154
3168
|
cancelDescription: "leave the current default unchanged",
|
|
3155
3169
|
defaultValue: "confirm",
|
|
@@ -3159,7 +3173,7 @@ async function runBotSetDefault(ui, flags, deps) {
|
|
|
3159
3173
|
}
|
|
3160
3174
|
parsed.TELEGRAM_DEFAULT_BOT_KEY = selected.key;
|
|
3161
3175
|
const filePath = writeProviderEnvState("telegram", parsed, deps);
|
|
3162
|
-
process.stdout.write(`Set
|
|
3176
|
+
process.stdout.write(`Set default Telegram bot to "${telegramEntryDisplayName(selected)}" in ${filePath}\n`);
|
|
3163
3177
|
}
|
|
3164
3178
|
|
|
3165
3179
|
async function runBotMigrate(ui, flags, deps) {
|
|
@@ -3186,11 +3200,11 @@ async function runBotMigrate(ui, flags, deps) {
|
|
|
3186
3200
|
const botKey = normalizeBotKey(
|
|
3187
3201
|
nonInteractive
|
|
3188
3202
|
? String(flags["bot-key"] || defaultKeyHint).trim()
|
|
3189
|
-
: await promptRequiredLine(ui, "
|
|
3203
|
+
: await promptRequiredLine(ui, "Legacy local selector for migrated entry", defaultKeyHint),
|
|
3190
3204
|
defaultKeyHint,
|
|
3191
3205
|
);
|
|
3192
3206
|
if (existingKeys.has(botKey)) {
|
|
3193
|
-
throw new Error(`Telegram local selector "${botKey}" already exists`);
|
|
3207
|
+
throw new Error(`Telegram legacy local selector "${botKey}" already exists`);
|
|
3194
3208
|
}
|
|
3195
3209
|
const nextParsed = upsertTelegramEntry(parsed, {
|
|
3196
3210
|
key: botKey,
|
package/lib/doctor-checks.mjs
CHANGED
|
@@ -62,11 +62,11 @@ export async function runDoctorProjectDestinationChecks({
|
|
|
62
62
|
continue;
|
|
63
63
|
}
|
|
64
64
|
const tokenDetailParts = [`configured (${envConfig.filePath})`];
|
|
65
|
-
if (envConfig.
|
|
66
|
-
tokenDetailParts.push(`
|
|
65
|
+
if (envConfig.serverBotName) {
|
|
66
|
+
tokenDetailParts.push(`server_bot_name=${envConfig.serverBotName}`);
|
|
67
67
|
}
|
|
68
68
|
if (envConfig.botUsername) {
|
|
69
|
-
tokenDetailParts.push(
|
|
69
|
+
tokenDetailParts.push(`fallback_username=@${envConfig.botUsername}`);
|
|
70
70
|
}
|
|
71
71
|
if (envConfig.roleProfile) {
|
|
72
72
|
tokenDetailParts.push(`role_profile=${envConfig.roleProfile}`);
|