metheus-governance-mcp-cli 0.2.65 → 0.2.67
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 +5 -0
- package/lib/bot-commands.mjs +110 -12
- package/lib/selftest-bot-commands.mjs +128 -10
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -226,7 +226,12 @@ Behavior:
|
|
|
226
226
|
|
|
227
227
|
- `bot setup` asks for `Telegram / Slack / KakaoTalk` first, then prompts with numbered actions.
|
|
228
228
|
- `bot add` without flags starts a guided question flow: provider -> server bot -> local bot key -> token -> verify -> role/AI binding -> default bot choice.
|
|
229
|
+
- When you choose a server Telegram bot profile such as `RyoAI_bot [monitor]`, the CLI automatically uses that server role as the local `role_profile` and fills blank AI defaults from your local `bot-runner.json` `role_profiles` mapping.
|
|
229
230
|
- `bot edit` without flags starts a guided numbered flow: provider -> bot entry -> guided edit -> step-by-step field choices.
|
|
231
|
+
- In guided `bot edit`, changing the bound server Telegram bot profile can also auto-fill blank local AI fields from the selected server role.
|
|
232
|
+
- `bot set-default` without flags starts a guided numbered flow: provider -> bot entry -> confirm default change.
|
|
233
|
+
- `bot verify` without flags starts a guided numbered flow: provider -> bot entry -> output format.
|
|
234
|
+
- `bot remove` without flags starts a guided numbered flow: provider -> bot entry -> confirm removal.
|
|
230
235
|
- Telegram supports named local bot entries with:
|
|
231
236
|
- `SERVER_BOT_ID`
|
|
232
237
|
- `USERNAME`
|
package/lib/bot-commands.mjs
CHANGED
|
@@ -182,6 +182,26 @@ async function promptYesNo(ui, promptText, defaultValue = true) {
|
|
|
182
182
|
}
|
|
183
183
|
}
|
|
184
184
|
|
|
185
|
+
async function promptConfirmChoice(
|
|
186
|
+
ui,
|
|
187
|
+
title,
|
|
188
|
+
{
|
|
189
|
+
confirmLabel = "Confirm",
|
|
190
|
+
confirmDescription = "",
|
|
191
|
+
cancelLabel = "Cancel",
|
|
192
|
+
cancelDescription = "",
|
|
193
|
+
defaultValue = "confirm",
|
|
194
|
+
} = {},
|
|
195
|
+
) {
|
|
196
|
+
const options = [
|
|
197
|
+
{ value: "confirm", label: confirmLabel, description: confirmDescription },
|
|
198
|
+
{ value: "cancel", label: cancelLabel, description: cancelDescription },
|
|
199
|
+
];
|
|
200
|
+
const defaultIndex = defaultValue === "cancel" ? 1 : 0;
|
|
201
|
+
const selected = await promptChoice(ui, title, options, { defaultIndex });
|
|
202
|
+
return selected?.value === "confirm";
|
|
203
|
+
}
|
|
204
|
+
|
|
185
205
|
function formatChoiceLabel(option) {
|
|
186
206
|
return `${String(option.label || option.value || "").trim()}${option.description ? ` - ${option.description}` : ""}`;
|
|
187
207
|
}
|
|
@@ -493,6 +513,7 @@ async function editTelegramBotGuided(ui, parsed, selected, current, flags, deps)
|
|
|
493
513
|
if (!current.roleProfile && serverBot.role) {
|
|
494
514
|
current.roleProfile = serverBot.role;
|
|
495
515
|
}
|
|
516
|
+
applyRoleProfileDefaults(current, resolveRoleProfileDefaults(current.roleProfile || serverBot.role, deps));
|
|
496
517
|
} else if (bindingAction === "clear") {
|
|
497
518
|
current.serverBotID = "";
|
|
498
519
|
}
|
|
@@ -540,6 +561,7 @@ async function editTelegramBotGuided(ui, parsed, selected, current, flags, deps)
|
|
|
540
561
|
current.roleProfile = requireDependency(deps, "normalizeRunnerRoleProfileName")(
|
|
541
562
|
await promptTelegramRoleProfile(ui, deps, current.roleProfile),
|
|
542
563
|
);
|
|
564
|
+
applyRoleProfileDefaults(current, resolveRoleProfileDefaults(current.roleProfile, deps));
|
|
543
565
|
} else if (roleAction === "clear") {
|
|
544
566
|
current.roleProfile = "";
|
|
545
567
|
}
|
|
@@ -921,6 +943,49 @@ async function promptReasoningEffort(ui, defaultValue = "") {
|
|
|
921
943
|
return String(selected?.value || "").trim();
|
|
922
944
|
}
|
|
923
945
|
|
|
946
|
+
function resolveRoleProfileDefaults(roleProfileName, deps) {
|
|
947
|
+
const profileName = String(roleProfileName || "").trim();
|
|
948
|
+
if (!profileName) {
|
|
949
|
+
return {
|
|
950
|
+
client: "",
|
|
951
|
+
model: "",
|
|
952
|
+
permissionMode: "",
|
|
953
|
+
reasoningEffort: "",
|
|
954
|
+
};
|
|
955
|
+
}
|
|
956
|
+
const config = requireDependency(deps, "loadBotRunnerConfig")({ persistIfNeeded: true });
|
|
957
|
+
const profile = safeObject(safeObject(config.roleProfiles || {})[profileName]);
|
|
958
|
+
return {
|
|
959
|
+
client: requireDependency(deps, "normalizeLocalAIClientName")(profile.client || "", ""),
|
|
960
|
+
model: String(profile.model || "").trim(),
|
|
961
|
+
permissionMode: requireDependency(deps, "normalizeLocalAIPermissionMode")(
|
|
962
|
+
profile.permission_mode || profile.permissionMode || "",
|
|
963
|
+
"",
|
|
964
|
+
),
|
|
965
|
+
reasoningEffort: requireDependency(deps, "normalizeLocalAIReasoningEffort")(
|
|
966
|
+
profile.reasoning_effort || profile.reasoningEffort || "",
|
|
967
|
+
"",
|
|
968
|
+
),
|
|
969
|
+
};
|
|
970
|
+
}
|
|
971
|
+
|
|
972
|
+
function applyRoleProfileDefaults(entry, defaults, { overwrite = false } = {}) {
|
|
973
|
+
const current = safeObject(entry);
|
|
974
|
+
const resolved = safeObject(defaults);
|
|
975
|
+
if (overwrite || !String(current.client || "").trim()) {
|
|
976
|
+
current.client = String(resolved.client || "").trim();
|
|
977
|
+
}
|
|
978
|
+
if (overwrite || !String(current.model || "").trim()) {
|
|
979
|
+
current.model = String(resolved.model || "").trim();
|
|
980
|
+
}
|
|
981
|
+
if (overwrite || !String(current.permissionMode || "").trim()) {
|
|
982
|
+
current.permissionMode = String(resolved.permissionMode || "").trim();
|
|
983
|
+
}
|
|
984
|
+
if (overwrite || !String(current.reasoningEffort || "").trim()) {
|
|
985
|
+
current.reasoningEffort = String(resolved.reasoningEffort || "").trim();
|
|
986
|
+
}
|
|
987
|
+
}
|
|
988
|
+
|
|
924
989
|
function buildTemporaryTelegramEnvConfig({ token, apiBaseURL }) {
|
|
925
990
|
return {
|
|
926
991
|
ok: true,
|
|
@@ -1013,23 +1078,26 @@ async function addTelegramBot(ui, flags, deps) {
|
|
|
1013
1078
|
? String(flags["role-profile"] || defaultRoleProfile).trim()
|
|
1014
1079
|
: await promptTelegramRoleProfile(ui, deps, defaultRoleProfile),
|
|
1015
1080
|
);
|
|
1081
|
+
const roleProfileDefaults = resolveRoleProfileDefaults(roleProfile, deps);
|
|
1016
1082
|
const client = requireDependency(deps, "normalizeLocalAIClientName")(
|
|
1017
1083
|
nonInteractive
|
|
1018
|
-
? getAIClientFlag(flags)
|
|
1019
|
-
: await promptAIClient(ui, deps, getAIClientFlag(flags)),
|
|
1084
|
+
? firstNonEmptyString([getAIClientFlag(flags), roleProfileDefaults.client])
|
|
1085
|
+
: await promptAIClient(ui, deps, firstNonEmptyString([getAIClientFlag(flags), roleProfileDefaults.client])),
|
|
1020
1086
|
"",
|
|
1021
1087
|
);
|
|
1022
|
-
const model = nonInteractive
|
|
1088
|
+
const model = nonInteractive
|
|
1089
|
+
? firstNonEmptyString([getAIModelFlag(flags), roleProfileDefaults.model])
|
|
1090
|
+
: await promptLine(ui, "AI model", firstNonEmptyString([getAIModelFlag(flags), roleProfileDefaults.model]));
|
|
1023
1091
|
const permissionMode = requireDependency(deps, "normalizeLocalAIPermissionMode")(
|
|
1024
1092
|
nonInteractive
|
|
1025
|
-
? getAIPermissionModeFlag(flags)
|
|
1026
|
-
: await promptPermissionMode(ui, getAIPermissionModeFlag(flags)),
|
|
1093
|
+
? firstNonEmptyString([getAIPermissionModeFlag(flags), roleProfileDefaults.permissionMode])
|
|
1094
|
+
: await promptPermissionMode(ui, firstNonEmptyString([getAIPermissionModeFlag(flags), roleProfileDefaults.permissionMode])),
|
|
1027
1095
|
"",
|
|
1028
1096
|
);
|
|
1029
1097
|
const reasoningEffort = requireDependency(deps, "normalizeLocalAIReasoningEffort")(
|
|
1030
1098
|
nonInteractive
|
|
1031
|
-
? getAIReasoningEffortFlag(flags)
|
|
1032
|
-
: await promptReasoningEffort(ui, getAIReasoningEffortFlag(flags)),
|
|
1099
|
+
? firstNonEmptyString([getAIReasoningEffortFlag(flags), roleProfileDefaults.reasoningEffort])
|
|
1100
|
+
: await promptReasoningEffort(ui, firstNonEmptyString([getAIReasoningEffortFlag(flags), roleProfileDefaults.reasoningEffort])),
|
|
1033
1101
|
"",
|
|
1034
1102
|
);
|
|
1035
1103
|
|
|
@@ -1262,7 +1330,13 @@ async function removeTelegramBot(ui, deps) {
|
|
|
1262
1330
|
const parsed = { ...state.parsed };
|
|
1263
1331
|
const selected = await chooseTelegramEntry(ui, parsed, deps, "Select Telegram bot entry to remove");
|
|
1264
1332
|
if (!selected) return;
|
|
1265
|
-
if (!await
|
|
1333
|
+
if (!await promptConfirmChoice(ui, `Remove Telegram bot "${selected.key}"?`, {
|
|
1334
|
+
confirmLabel: "Remove bot",
|
|
1335
|
+
confirmDescription: "delete this local Telegram bot entry",
|
|
1336
|
+
cancelLabel: "Cancel",
|
|
1337
|
+
cancelDescription: "keep the current local bot entry",
|
|
1338
|
+
defaultValue: "cancel",
|
|
1339
|
+
})) {
|
|
1266
1340
|
process.stdout.write("Cancelled.\n");
|
|
1267
1341
|
return;
|
|
1268
1342
|
}
|
|
@@ -1338,7 +1412,23 @@ async function verifyProviderEntry(ui, provider, flags, deps) {
|
|
|
1338
1412
|
}
|
|
1339
1413
|
}
|
|
1340
1414
|
}
|
|
1341
|
-
|
|
1415
|
+
const interactiveJsonChoice = (
|
|
1416
|
+
!boolFromRaw(flags.json, false)
|
|
1417
|
+
&& !boolFromRaw(flags["non-interactive"] ?? flags.yes, false)
|
|
1418
|
+
)
|
|
1419
|
+
? await promptChoice(
|
|
1420
|
+
ui,
|
|
1421
|
+
"Verification output format",
|
|
1422
|
+
[
|
|
1423
|
+
{ value: "text", label: "Text output (Recommended)", description: "human-readable summary" },
|
|
1424
|
+
{ value: "json", label: "JSON output", description: "machine-readable verification payload" },
|
|
1425
|
+
],
|
|
1426
|
+
{ defaultIndex: 0 },
|
|
1427
|
+
)
|
|
1428
|
+
: null;
|
|
1429
|
+
const outputAsJson = boolFromRaw(flags.json, false) || interactiveJsonChoice?.value === "json";
|
|
1430
|
+
|
|
1431
|
+
if (outputAsJson) {
|
|
1342
1432
|
process.stdout.write(
|
|
1343
1433
|
`${JSON.stringify({
|
|
1344
1434
|
ok: overallOK,
|
|
@@ -1594,9 +1684,7 @@ async function runBotVerify(ui, flags, deps) {
|
|
|
1594
1684
|
}
|
|
1595
1685
|
|
|
1596
1686
|
async function runBotSetDefault(ui, flags, deps) {
|
|
1597
|
-
const provider =
|
|
1598
|
-
? requireDependency(deps, "normalizeBotProvider")(flags.provider)
|
|
1599
|
-
: "telegram";
|
|
1687
|
+
const provider = await selectProvider(ui, flags.provider, deps);
|
|
1600
1688
|
if (provider !== "telegram") {
|
|
1601
1689
|
throw new Error("bot set-default currently supports only --provider telegram");
|
|
1602
1690
|
}
|
|
@@ -1609,6 +1697,16 @@ async function runBotSetDefault(ui, flags, deps) {
|
|
|
1609
1697
|
if (!selected) {
|
|
1610
1698
|
throw new Error("Telegram bot selector is required for set-default");
|
|
1611
1699
|
}
|
|
1700
|
+
if (!nonInteractive && !await promptConfirmChoice(ui, `Set "${selected.key}" as TELEGRAM_DEFAULT_BOT_KEY?`, {
|
|
1701
|
+
confirmLabel: "Set default bot",
|
|
1702
|
+
confirmDescription: "make this the default local Telegram bot entry",
|
|
1703
|
+
cancelLabel: "Cancel",
|
|
1704
|
+
cancelDescription: "leave the current default unchanged",
|
|
1705
|
+
defaultValue: "confirm",
|
|
1706
|
+
})) {
|
|
1707
|
+
process.stdout.write("Cancelled.\n");
|
|
1708
|
+
return;
|
|
1709
|
+
}
|
|
1612
1710
|
parsed.TELEGRAM_DEFAULT_BOT_KEY = selected.key;
|
|
1613
1711
|
const filePath = writeProviderEnvState("telegram", parsed, deps);
|
|
1614
1712
|
process.stdout.write(`Set TELEGRAM_DEFAULT_BOT_KEY=${selected.key} in ${filePath}\n`);
|
|
@@ -45,6 +45,45 @@ function readJSON(rawText) {
|
|
|
45
45
|
return JSON.parse(String(rawText || "").trim() || "{}");
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
+
function readTrailingJSON(rawText) {
|
|
49
|
+
const text = String(rawText || "");
|
|
50
|
+
const start = text.indexOf("{");
|
|
51
|
+
if (start < 0) {
|
|
52
|
+
return readJSON(text);
|
|
53
|
+
}
|
|
54
|
+
let depth = 0;
|
|
55
|
+
let inString = false;
|
|
56
|
+
let escaping = false;
|
|
57
|
+
for (let index = start; index < text.length; index += 1) {
|
|
58
|
+
const char = text[index];
|
|
59
|
+
if (inString) {
|
|
60
|
+
if (escaping) {
|
|
61
|
+
escaping = false;
|
|
62
|
+
} else if (char === "\\") {
|
|
63
|
+
escaping = true;
|
|
64
|
+
} else if (char === "\"") {
|
|
65
|
+
inString = false;
|
|
66
|
+
}
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
if (char === "\"") {
|
|
70
|
+
inString = true;
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
if (char === "{") {
|
|
74
|
+
depth += 1;
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
if (char === "}") {
|
|
78
|
+
depth -= 1;
|
|
79
|
+
if (depth === 0) {
|
|
80
|
+
return readJSON(text.slice(start, index + 1));
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return readJSON(text.slice(start));
|
|
85
|
+
}
|
|
86
|
+
|
|
48
87
|
function createMockServer() {
|
|
49
88
|
const serverBots = [
|
|
50
89
|
{
|
|
@@ -237,11 +276,11 @@ export async function runSelftestBotCommands(push, deps) {
|
|
|
237
276
|
"selftest-main-token",
|
|
238
277
|
"y", // verify now
|
|
239
278
|
"", // keep verified username
|
|
240
|
-
"
|
|
241
|
-
"
|
|
242
|
-
"
|
|
243
|
-
"
|
|
244
|
-
"
|
|
279
|
+
"", // keep role profile default from selected server role
|
|
280
|
+
"", // keep AI client default from role profile
|
|
281
|
+
"", // keep AI model default from role profile
|
|
282
|
+
"", // keep permission default from role profile
|
|
283
|
+
"", // keep reasoning default from role profile
|
|
245
284
|
"y", // set as default
|
|
246
285
|
]),
|
|
247
286
|
},
|
|
@@ -251,10 +290,12 @@ export async function runSelftestBotCommands(push, deps) {
|
|
|
251
290
|
"bot_add_guided_creates_named_telegram_entry",
|
|
252
291
|
String(addState.TELEGRAM_BOT_MAIN_TEST_SERVER_BOT_ID || "") === mock.bots[0].id
|
|
253
292
|
&& String(addState.TELEGRAM_BOT_MAIN_TEST_USERNAME || "").trim().toLowerCase() === "monitorselftestbot"
|
|
293
|
+
&& String(addState.TELEGRAM_BOT_MAIN_TEST_ROLE_PROFILE || "") === "monitor"
|
|
254
294
|
&& String(addState.TELEGRAM_BOT_MAIN_TEST_AI_CLIENT || "") === "codex"
|
|
255
|
-
&& String(addState.
|
|
295
|
+
&& String(addState.TELEGRAM_BOT_MAIN_TEST_AI_PERMISSION_MODE || "") === "read_only"
|
|
296
|
+
&& String(addState.TELEGRAM_BOT_MAIN_TEST_AI_REASONING_EFFORT || "") === "low"
|
|
256
297
|
&& String(addState.TELEGRAM_DEFAULT_BOT_KEY || "") === "main_test",
|
|
257
|
-
`default=${String(addState.TELEGRAM_DEFAULT_BOT_KEY || "")}
|
|
298
|
+
`default=${String(addState.TELEGRAM_DEFAULT_BOT_KEY || "")} role=${String(addState.TELEGRAM_BOT_MAIN_TEST_ROLE_PROFILE || "")} client=${String(addState.TELEGRAM_BOT_MAIN_TEST_AI_CLIENT || "")}`,
|
|
258
299
|
);
|
|
259
300
|
|
|
260
301
|
const showResult = await runCLI({
|
|
@@ -338,6 +379,50 @@ export async function runSelftestBotCommands(push, deps) {
|
|
|
338
379
|
`client=${String(editedState.TELEGRAM_BOT_MAIN_TEST_AI_CLIENT || "")} model=${String(editedState.TELEGRAM_BOT_MAIN_TEST_AI_MODEL || "")}`,
|
|
339
380
|
);
|
|
340
381
|
|
|
382
|
+
await runCLI({
|
|
383
|
+
cliPath,
|
|
384
|
+
args: ["bot", "set-default"],
|
|
385
|
+
env: {
|
|
386
|
+
...env,
|
|
387
|
+
METHEUS_SCRIPTED_PROMPT_ANSWERS: JSON.stringify([
|
|
388
|
+
"1", // provider: telegram
|
|
389
|
+
"1", // bot entry: main_test
|
|
390
|
+
"1", // confirm set default
|
|
391
|
+
]),
|
|
392
|
+
},
|
|
393
|
+
});
|
|
394
|
+
const guidedDefaultState = parseSimpleEnvText(fs.readFileSync(telegramEnvPath, "utf8"));
|
|
395
|
+
push(
|
|
396
|
+
"bot_set_default_guided_selects_entry",
|
|
397
|
+
String(guidedDefaultState.TELEGRAM_DEFAULT_BOT_KEY || "") === "main_test",
|
|
398
|
+
`default=${String(guidedDefaultState.TELEGRAM_DEFAULT_BOT_KEY || "")}`,
|
|
399
|
+
);
|
|
400
|
+
|
|
401
|
+
const guidedVerifyResult = await runCLI({
|
|
402
|
+
cliPath,
|
|
403
|
+
args: [
|
|
404
|
+
"bot", "verify",
|
|
405
|
+
"--base-url", baseURL,
|
|
406
|
+
"--timeout-seconds", "5",
|
|
407
|
+
],
|
|
408
|
+
env: {
|
|
409
|
+
...env,
|
|
410
|
+
METHEUS_SCRIPTED_PROMPT_ANSWERS: JSON.stringify([
|
|
411
|
+
"1", // provider: telegram
|
|
412
|
+
"1", // bot entry: main_test
|
|
413
|
+
"2", // output format: json
|
|
414
|
+
]),
|
|
415
|
+
},
|
|
416
|
+
});
|
|
417
|
+
const guidedVerifyPayload = readTrailingJSON(guidedVerifyResult.stdout);
|
|
418
|
+
push(
|
|
419
|
+
"bot_verify_guided_can_emit_json",
|
|
420
|
+
guidedVerifyPayload.ok === true
|
|
421
|
+
&& safeObject(guidedVerifyPayload.serverBinding).ok === true
|
|
422
|
+
&& String(guidedVerifyPayload.client || "") === "claude",
|
|
423
|
+
`verify=${String(guidedVerifyPayload.ok)} server=${String(safeObject(guidedVerifyPayload.serverBinding).detail || "")}`,
|
|
424
|
+
);
|
|
425
|
+
|
|
341
426
|
await runCLI({
|
|
342
427
|
cliPath,
|
|
343
428
|
args: [
|
|
@@ -435,16 +520,49 @@ export async function runSelftestBotCommands(push, deps) {
|
|
|
435
520
|
`client=${String(aliasAddState.TELEGRAM_BOT_EXPLICIT_TEST_AI_CLIENT || "")} model=${String(aliasAddState.TELEGRAM_BOT_EXPLICIT_TEST_AI_MODEL || "")}`,
|
|
436
521
|
);
|
|
437
522
|
|
|
523
|
+
const guidedRemoveBeforeList = await runCLI({
|
|
524
|
+
cliPath,
|
|
525
|
+
args: [
|
|
526
|
+
"bot", "list",
|
|
527
|
+
"--provider", "telegram",
|
|
528
|
+
"--json", "true",
|
|
529
|
+
],
|
|
530
|
+
env,
|
|
531
|
+
});
|
|
532
|
+
const guidedRemoveBeforePayload = ensureArray(readJSON(guidedRemoveBeforeList.stdout));
|
|
533
|
+
const guidedRemoveBeforeEntry = safeObject(guidedRemoveBeforePayload[0]);
|
|
534
|
+
const guidedRemoveEntries = ensureArray(guidedRemoveBeforeEntry.entries);
|
|
535
|
+
const explicitEntryIndex = guidedRemoveEntries.findIndex((entry) => String(safeObject(entry).key || "") === "explicit_test");
|
|
536
|
+
|
|
438
537
|
await runCLI({
|
|
538
|
+
cliPath,
|
|
539
|
+
args: ["bot", "remove"],
|
|
540
|
+
env: {
|
|
541
|
+
...env,
|
|
542
|
+
METHEUS_SCRIPTED_PROMPT_ANSWERS: JSON.stringify([
|
|
543
|
+
"1", // provider: telegram
|
|
544
|
+
String(explicitEntryIndex + 1), // bot entry: explicit_test
|
|
545
|
+
"1", // confirm remove
|
|
546
|
+
]),
|
|
547
|
+
},
|
|
548
|
+
});
|
|
549
|
+
const guidedRemoveList = await runCLI({
|
|
439
550
|
cliPath,
|
|
440
551
|
args: [
|
|
441
|
-
"bot", "
|
|
552
|
+
"bot", "list",
|
|
442
553
|
"--provider", "telegram",
|
|
443
|
-
"--
|
|
444
|
-
"--non-interactive", "true",
|
|
554
|
+
"--json", "true",
|
|
445
555
|
],
|
|
446
556
|
env,
|
|
447
557
|
});
|
|
558
|
+
const guidedRemovePayload = ensureArray(readJSON(guidedRemoveList.stdout));
|
|
559
|
+
const guidedRemoveEntry = safeObject(guidedRemovePayload[0]);
|
|
560
|
+
push(
|
|
561
|
+
"bot_remove_guided_deletes_selected_entry",
|
|
562
|
+
explicitEntryIndex >= 0
|
|
563
|
+
&& ensureArray(guidedRemoveEntry.entries).length === 0,
|
|
564
|
+
`entries=${String(ensureArray(guidedRemoveEntry.entries).length)} selected=${String(explicitEntryIndex + 1)}`,
|
|
565
|
+
);
|
|
448
566
|
|
|
449
567
|
const migratedEnv = parseSimpleEnvText(fs.readFileSync(telegramEnvPath, "utf8"));
|
|
450
568
|
migratedEnv.TELEGRAM_BOT_TOKEN = "legacy-selftest-token";
|