metheus-governance-mcp-cli 0.2.100 → 0.2.101
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/cli.mjs +60 -4
- package/lib/bot-commands.mjs +136 -4
- package/lib/selftest-bot-commands.mjs +9 -3
- package/package.json +1 -1
package/cli.mjs
CHANGED
|
@@ -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");
|
|
@@ -2752,6 +2783,8 @@ function parseTelegramBotEntryFile(filePath) {
|
|
|
2752
2783
|
key: keyFromName || keyFromFile,
|
|
2753
2784
|
username: normalizeTelegramBotUsername(parsed.TELEGRAM_BOT_NAME || parsed.TELEGRAM_BOT_USERNAME || ""),
|
|
2754
2785
|
serverBotID: String(parsed.TELEGRAM_BOT_SERVER_BOT_ID || "").trim(),
|
|
2786
|
+
serverBotName: String(parsed.TELEGRAM_BOT_SERVER_NAME || "").trim(),
|
|
2787
|
+
serverRoles: parseTelegramServerRoles(parsed.TELEGRAM_BOT_SERVER_ROLES || ""),
|
|
2755
2788
|
token: String(parsed.TELEGRAM_BOT_TOKEN || "").trim(),
|
|
2756
2789
|
roleProfile: normalizeRunnerRoleProfileName(parsed.TELEGRAM_BOT_ROLE_PROFILE || ""),
|
|
2757
2790
|
client: normalizeLocalAIClientName(parsed.TELEGRAM_BOT_AI_CLIENT || "", ""),
|
|
@@ -2813,6 +2846,8 @@ function buildMergedTelegramEnvParsed(globalParsed, entries) {
|
|
|
2813
2846
|
const upper = String(entry.key || "").trim().toUpperCase();
|
|
2814
2847
|
if (!upper) return;
|
|
2815
2848
|
merged[`TELEGRAM_BOT_${upper}_SERVER_BOT_ID`] = String(entry.serverBotID || "").trim();
|
|
2849
|
+
merged[`TELEGRAM_BOT_${upper}_SERVER_NAME`] = String(entry.serverBotName || "").trim();
|
|
2850
|
+
merged[`TELEGRAM_BOT_${upper}_SERVER_ROLES`] = ensureArray(entry.serverRoles).join(",");
|
|
2816
2851
|
merged[`TELEGRAM_BOT_${upper}_USERNAME`] = normalizeTelegramBotUsername(entry.username || "");
|
|
2817
2852
|
merged[`TELEGRAM_BOT_${upper}_TOKEN`] = String(entry.token || "").trim();
|
|
2818
2853
|
merged[`TELEGRAM_BOT_${upper}_ROLE_PROFILE`] = String(entry.roleProfile || "").trim();
|
|
@@ -2874,12 +2909,14 @@ function readTelegramEnvState() {
|
|
|
2874
2909
|
}
|
|
2875
2910
|
|
|
2876
2911
|
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
|
|
2912
|
+
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
2913
|
.test(String(rawKey || "").trim());
|
|
2879
2914
|
}
|
|
2880
2915
|
|
|
2881
2916
|
function telegramEntryCommentNameForEnv(entry) {
|
|
2882
2917
|
const current = safeObject(entry);
|
|
2918
|
+
const serverBotName = String(current.serverBotName || "").trim();
|
|
2919
|
+
if (serverBotName) return serverBotName;
|
|
2883
2920
|
const username = normalizeTelegramBotUsername(current.username || "");
|
|
2884
2921
|
if (username) return username;
|
|
2885
2922
|
return normalizeTelegramBotEnvKey(current.key || "", "telegram_bot");
|
|
@@ -2930,12 +2967,15 @@ function renderNormalizedTelegramEnv(parsedEnv) {
|
|
|
2930
2967
|
function renderTelegramBotEntryEnv(entryRaw) {
|
|
2931
2968
|
const entry = safeObject(entryRaw);
|
|
2932
2969
|
const botName = telegramEntryCommentNameForEnv(entry);
|
|
2970
|
+
const serverRoles = parseTelegramServerRoles(entry.serverRoles || "");
|
|
2933
2971
|
const lines = [
|
|
2934
2972
|
"# Metheus local Telegram bot entry",
|
|
2935
2973
|
`# Bot: ${botName}`,
|
|
2936
2974
|
"",
|
|
2937
2975
|
`TELEGRAM_BOT_NAME=${formatProviderEnvValue(botName)}`,
|
|
2938
2976
|
`TELEGRAM_BOT_SERVER_BOT_ID=${formatProviderEnvValue(entry.serverBotID || "")}`,
|
|
2977
|
+
`TELEGRAM_BOT_SERVER_NAME=${formatProviderEnvValue(entry.serverBotName || "")}`,
|
|
2978
|
+
`TELEGRAM_BOT_SERVER_ROLES=${formatProviderEnvValue(serverRoles.join(","))}`,
|
|
2939
2979
|
`TELEGRAM_BOT_TOKEN=${formatProviderEnvValue(entry.token || "")}`,
|
|
2940
2980
|
`TELEGRAM_BOT_ROLE_PROFILE=${formatProviderEnvValue(entry.roleProfile || "")}`,
|
|
2941
2981
|
`TELEGRAM_BOT_AI_CLIENT=${formatProviderEnvValue(entry.client || "")}`,
|
|
@@ -2954,6 +2994,8 @@ function writeTelegramEnvState(parsedEnv) {
|
|
|
2954
2994
|
entry.token
|
|
2955
2995
|
|| entry.username
|
|
2956
2996
|
|| entry.serverBotID
|
|
2997
|
+
|| entry.serverBotName
|
|
2998
|
+
|| ensureArray(entry.serverRoles).length
|
|
2957
2999
|
|| entry.roleProfile
|
|
2958
3000
|
|| entry.client
|
|
2959
3001
|
|| entry.model
|
|
@@ -3009,7 +3051,13 @@ function normalizeExistingProviderEnvFile(provider, filePath) {
|
|
|
3009
3051
|
function resolveTelegramEnvConfig(parsedEnv, filePath, config, selectors = {}) {
|
|
3010
3052
|
const parsed = safeObject(parsedEnv);
|
|
3011
3053
|
const legacyToken = String(parsed.TELEGRAM_BOT_TOKEN || "").trim();
|
|
3012
|
-
const entries = collectTelegramEnvBotEntries(parsed).filter((entry) =>
|
|
3054
|
+
const entries = collectTelegramEnvBotEntries(parsed).filter((entry) => (
|
|
3055
|
+
entry.token
|
|
3056
|
+
|| entry.username
|
|
3057
|
+
|| entry.serverBotID
|
|
3058
|
+
|| entry.serverBotName
|
|
3059
|
+
|| ensureArray(entry.serverRoles).length
|
|
3060
|
+
));
|
|
3013
3061
|
const desiredBotID = firstNonEmptyString([
|
|
3014
3062
|
selectors.serverBotID,
|
|
3015
3063
|
selectors.botID,
|
|
@@ -3037,7 +3085,11 @@ function resolveTelegramEnvConfig(parsedEnv, filePath, config, selectors = {}) {
|
|
|
3037
3085
|
}
|
|
3038
3086
|
if (!selected && desiredUsername) {
|
|
3039
3087
|
selected = entries.find(
|
|
3040
|
-
(entry) =>
|
|
3088
|
+
(entry) => (
|
|
3089
|
+
entry.username === desiredUsername
|
|
3090
|
+
|| normalizeTelegramBotUsername(entry.serverBotName) === desiredUsername
|
|
3091
|
+
|| normalizeTelegramBotUsername(entry.key) === desiredUsername
|
|
3092
|
+
),
|
|
3041
3093
|
) || null;
|
|
3042
3094
|
}
|
|
3043
3095
|
if (!selected && desiredBotKey) {
|
|
@@ -3071,6 +3123,8 @@ function resolveTelegramEnvConfig(parsedEnv, filePath, config, selectors = {}) {
|
|
|
3071
3123
|
botKey: selected.key,
|
|
3072
3124
|
botUsername: selected.username,
|
|
3073
3125
|
serverBotID: selected.serverBotID,
|
|
3126
|
+
serverBotName: selected.serverBotName,
|
|
3127
|
+
serverRoles: ensureArray(selected.serverRoles),
|
|
3074
3128
|
roleProfile: selected.roleProfile,
|
|
3075
3129
|
client: selected.client,
|
|
3076
3130
|
model: selected.model,
|
|
@@ -3095,6 +3149,8 @@ function resolveTelegramEnvConfig(parsedEnv, filePath, config, selectors = {}) {
|
|
|
3095
3149
|
botKey: "",
|
|
3096
3150
|
botUsername: "",
|
|
3097
3151
|
serverBotID: "",
|
|
3152
|
+
serverBotName: "",
|
|
3153
|
+
serverRoles: [],
|
|
3098
3154
|
roleProfile: "",
|
|
3099
3155
|
client: "",
|
|
3100
3156
|
model: "",
|
package/lib/bot-commands.mjs
CHANGED
|
@@ -442,6 +442,8 @@ function telegramEntryEnvKeys(botKey) {
|
|
|
442
442
|
const upper = String(botKey || "").trim().toUpperCase();
|
|
443
443
|
return {
|
|
444
444
|
serverBotID: `TELEGRAM_BOT_${upper}_SERVER_BOT_ID`,
|
|
445
|
+
serverBotName: `TELEGRAM_BOT_${upper}_SERVER_NAME`,
|
|
446
|
+
serverRoles: `TELEGRAM_BOT_${upper}_SERVER_ROLES`,
|
|
445
447
|
username: `TELEGRAM_BOT_${upper}_USERNAME`,
|
|
446
448
|
token: `TELEGRAM_BOT_${upper}_TOKEN`,
|
|
447
449
|
roleProfile: `TELEGRAM_BOT_${upper}_ROLE_PROFILE`,
|
|
@@ -454,6 +456,8 @@ function telegramEntryEnvKeys(botKey) {
|
|
|
454
456
|
|
|
455
457
|
function telegramEntryCommentName(entry) {
|
|
456
458
|
const current = safeObject(entry);
|
|
459
|
+
const serverBotName = String(current.serverBotName || "").trim();
|
|
460
|
+
if (serverBotName) return serverBotName;
|
|
457
461
|
const username = String(current.username || "").trim();
|
|
458
462
|
if (username) return username;
|
|
459
463
|
const key = String(current.key || "").trim();
|
|
@@ -486,6 +490,8 @@ function upsertTelegramEntry(parsedEnv, entry) {
|
|
|
486
490
|
const keys = telegramEntryEnvKeys(entry.key);
|
|
487
491
|
const next = { ...parsed };
|
|
488
492
|
next[keys.serverBotID] = String(entry.serverBotID || "").trim();
|
|
493
|
+
next[keys.serverBotName] = String(entry.serverBotName || "").trim();
|
|
494
|
+
next[keys.serverRoles] = ensureArray(entry.serverRoles).join(",");
|
|
489
495
|
next[keys.username] = persistTelegramUsername(entry);
|
|
490
496
|
next[keys.token] = String(entry.token || "").trim();
|
|
491
497
|
next[keys.roleProfile] = String(entry.roleProfile || "").trim();
|
|
@@ -512,7 +518,7 @@ function telegramKnownKeys(parsedEnv, deps) {
|
|
|
512
518
|
}
|
|
513
519
|
|
|
514
520
|
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
|
|
521
|
+
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
522
|
.test(String(rawKey || "").trim());
|
|
517
523
|
}
|
|
518
524
|
|
|
@@ -525,6 +531,8 @@ function renderTelegramEnv(parsedEnv, deps) {
|
|
|
525
531
|
entry.token
|
|
526
532
|
|| entry.username
|
|
527
533
|
|| entry.serverBotID
|
|
534
|
+
|| entry.serverBotName
|
|
535
|
+
|| ensureArray(entry.serverRoles).length
|
|
528
536
|
|| entry.roleProfile
|
|
529
537
|
|| entry.client
|
|
530
538
|
|| entry.model
|
|
@@ -562,6 +570,8 @@ function renderTelegramEnv(parsedEnv, deps) {
|
|
|
562
570
|
const entryLines = [
|
|
563
571
|
`# Telegram bot entry: ${telegramEntryCommentName(entry)}`,
|
|
564
572
|
`${keys.serverBotID}=${formatEnvValue(entry.serverBotID || "")}`,
|
|
573
|
+
`${keys.serverBotName}=${formatEnvValue(entry.serverBotName || "")}`,
|
|
574
|
+
`${keys.serverRoles}=${formatEnvValue(ensureArray(entry.serverRoles).join(","))}`,
|
|
565
575
|
];
|
|
566
576
|
if (String(entry.username || "").trim()) {
|
|
567
577
|
entryLines.push(`${keys.username}=${formatEnvValue(entry.username || "")}`);
|
|
@@ -615,6 +625,39 @@ function renderTokenOnlyProviderEnv(provider, parsedEnv, deps) {
|
|
|
615
625
|
return `${lines.join("\n").trimEnd()}\n`;
|
|
616
626
|
}
|
|
617
627
|
|
|
628
|
+
function renderTelegramBotEntryFile(entryRaw) {
|
|
629
|
+
const entry = safeObject(entryRaw);
|
|
630
|
+
const botName = telegramEntryCommentName(entry);
|
|
631
|
+
const serverRoles = ensureArray(entry.serverRoles).join(",");
|
|
632
|
+
const lines = [
|
|
633
|
+
"# Metheus local Telegram bot entry",
|
|
634
|
+
`# Bot: ${botName}`,
|
|
635
|
+
"",
|
|
636
|
+
`TELEGRAM_BOT_NAME=${formatEnvValue(botName)}`,
|
|
637
|
+
`TELEGRAM_BOT_SERVER_BOT_ID=${formatEnvValue(entry.serverBotID || "")}`,
|
|
638
|
+
`TELEGRAM_BOT_SERVER_NAME=${formatEnvValue(entry.serverBotName || "")}`,
|
|
639
|
+
`TELEGRAM_BOT_SERVER_ROLES=${formatEnvValue(serverRoles)}`,
|
|
640
|
+
`TELEGRAM_BOT_TOKEN=${formatEnvValue(entry.token || "")}`,
|
|
641
|
+
`TELEGRAM_BOT_ROLE_PROFILE=${formatEnvValue(entry.roleProfile || "")}`,
|
|
642
|
+
`TELEGRAM_BOT_AI_CLIENT=${formatEnvValue(entry.client || "")}`,
|
|
643
|
+
`TELEGRAM_BOT_AI_MODEL=${formatEnvValue(entry.model || "")}`,
|
|
644
|
+
`TELEGRAM_BOT_AI_PERMISSION_MODE=${formatEnvValue(entry.permissionMode || "")}`,
|
|
645
|
+
`TELEGRAM_BOT_AI_REASONING_EFFORT=${formatEnvValue(entry.reasoningEffort || "")}`,
|
|
646
|
+
"",
|
|
647
|
+
];
|
|
648
|
+
return `${lines.join("\n").trimEnd()}\n`;
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
function rewriteTelegramEntryFile(entry, deps) {
|
|
652
|
+
const entryFilePath = String(requireDependency(deps, "telegramBotEntryFilePath")(entry.key) || "").trim();
|
|
653
|
+
if (!entryFilePath) return;
|
|
654
|
+
fs.mkdirSync(path.dirname(entryFilePath), { recursive: true });
|
|
655
|
+
fs.writeFileSync(entryFilePath, renderTelegramBotEntryFile(entry), {
|
|
656
|
+
encoding: "utf8",
|
|
657
|
+
mode: 0o600,
|
|
658
|
+
});
|
|
659
|
+
}
|
|
660
|
+
|
|
618
661
|
function writeProviderEnvState(provider, parsedEnv, deps) {
|
|
619
662
|
if (provider === "telegram" && typeof deps?.writeTelegramEnvState === "function") {
|
|
620
663
|
return deps.writeTelegramEnvState(parsedEnv);
|
|
@@ -644,6 +687,8 @@ function telegramEntriesForDisplay(parsedEnv, deps) {
|
|
|
644
687
|
entry.token
|
|
645
688
|
|| entry.username
|
|
646
689
|
|| entry.serverBotID
|
|
690
|
+
|| entry.serverBotName
|
|
691
|
+
|| ensureArray(entry.serverRoles).length
|
|
647
692
|
|| entry.roleProfile
|
|
648
693
|
|| entry.client
|
|
649
694
|
|| entry.model
|
|
@@ -659,6 +704,8 @@ function telegramEntriesForDisplay(parsedEnv, deps) {
|
|
|
659
704
|
|
|
660
705
|
function telegramEntryDisplayName(entry) {
|
|
661
706
|
const current = safeObject(entry);
|
|
707
|
+
const serverBotName = String(current.serverBotName || "").trim();
|
|
708
|
+
if (serverBotName) return serverBotName;
|
|
662
709
|
const username = String(current.username || "").trim();
|
|
663
710
|
if (username) return `@${username}`;
|
|
664
711
|
return String(current.key || "").trim() || "(unnamed)";
|
|
@@ -722,7 +769,11 @@ function findTelegramEntryByFlags(parsedEnv, flags, deps) {
|
|
|
722
769
|
}
|
|
723
770
|
if (requestedName) {
|
|
724
771
|
const match = entries.find(
|
|
725
|
-
(entry) =>
|
|
772
|
+
(entry) => (
|
|
773
|
+
entry.username === requestedName
|
|
774
|
+
|| normalizeServerBotIdentityText(entry.serverBotName) === requestedName
|
|
775
|
+
|| normalizeServerBotIdentityText(entry.key) === requestedName
|
|
776
|
+
),
|
|
726
777
|
);
|
|
727
778
|
if (!match) {
|
|
728
779
|
throw new Error(`Telegram bot entry with server bot name "${requestedName}" was not found`);
|
|
@@ -783,6 +834,7 @@ async function editTelegramBotGuided(ui, parsed, selected, current, flags, deps)
|
|
|
783
834
|
const initialBinding = await resolveTelegramServerBindingDetails(
|
|
784
835
|
{
|
|
785
836
|
serverBotID: current.serverBotID,
|
|
837
|
+
serverBotName: current.serverBotName,
|
|
786
838
|
botUsername: current.username,
|
|
787
839
|
botKey: current.key,
|
|
788
840
|
roleProfile: current.roleProfile,
|
|
@@ -795,8 +847,13 @@ async function editTelegramBotGuided(ui, parsed, selected, current, flags, deps)
|
|
|
795
847
|
current.__preferServerIdentity = true;
|
|
796
848
|
if (initialBinding.mode === "single") {
|
|
797
849
|
current.serverBotID = String(initialBinding.serverBotID || "").trim();
|
|
850
|
+
current.serverBotName = String(initialBinding.name || "").trim();
|
|
851
|
+
current.serverRoles = ensureArray(initialBinding.roles);
|
|
798
852
|
current.roleProfile = String(initialBinding.role || current.roleProfile || "").trim();
|
|
799
853
|
applyRoleProfileDefaults(current, resolveRoleProfileDefaults(current.roleProfile, deps));
|
|
854
|
+
} else if (initialBinding.mode === "group") {
|
|
855
|
+
current.serverBotName = String(initialBinding.name || "").trim();
|
|
856
|
+
current.serverRoles = ensureArray(initialBinding.roles);
|
|
800
857
|
}
|
|
801
858
|
}
|
|
802
859
|
}
|
|
@@ -847,6 +904,8 @@ async function editTelegramBotGuided(ui, parsed, selected, current, flags, deps)
|
|
|
847
904
|
const serverBot = await autoResolveTelegramServerBot(current, flags, deps);
|
|
848
905
|
if (serverBot.matchMode === "group") {
|
|
849
906
|
current.serverBotID = "";
|
|
907
|
+
current.serverBotName = String(serverBot.name || "").trim();
|
|
908
|
+
current.serverRoles = preferredRoleSort(serverBot.roles);
|
|
850
909
|
current.__preferServerIdentity = true;
|
|
851
910
|
current.roleProfile = "";
|
|
852
911
|
current.client = "";
|
|
@@ -861,6 +920,8 @@ async function editTelegramBotGuided(ui, parsed, selected, current, flags, deps)
|
|
|
861
920
|
);
|
|
862
921
|
} else if (String(serverBot.botID || "").trim()) {
|
|
863
922
|
current.serverBotID = String(serverBot.botID || "").trim();
|
|
923
|
+
current.serverBotName = String(serverBot.name || "").trim();
|
|
924
|
+
current.serverRoles = ensureArray(serverBot.roles);
|
|
864
925
|
current.__preferServerIdentity = true;
|
|
865
926
|
current.roleProfile = String(serverBot.role || current.roleProfile || "").trim();
|
|
866
927
|
serverRoleAutoResolved = String(serverBot.role || current.roleProfile || "").trim() || "__server_binding__";
|
|
@@ -995,6 +1056,8 @@ function renderBotListPayload(provider, state, deps) {
|
|
|
995
1056
|
key: entry.key,
|
|
996
1057
|
isDefault: entry.isDefault,
|
|
997
1058
|
serverBotID: entry.serverBotID,
|
|
1059
|
+
serverBotName: entry.serverBotName,
|
|
1060
|
+
serverRoles: ensureArray(entry.serverRoles),
|
|
998
1061
|
username: entry.username,
|
|
999
1062
|
tokenConfigured: Boolean(entry.token),
|
|
1000
1063
|
roleProfile: entry.roleProfile,
|
|
@@ -1037,6 +1100,8 @@ function buildBotShowPayload(provider, state, entry, deps, extras = {}) {
|
|
|
1037
1100
|
key: selectedEntry.key,
|
|
1038
1101
|
isDefault: selectedEntry.isDefault,
|
|
1039
1102
|
serverBotID: selectedEntry.serverBotID,
|
|
1103
|
+
serverBotName: selectedEntry.serverBotName,
|
|
1104
|
+
serverRoles: ensureArray(selectedEntry.serverRoles),
|
|
1040
1105
|
username: selectedEntry.username,
|
|
1041
1106
|
tokenConfigured: Boolean(selectedEntry.token),
|
|
1042
1107
|
roleProfile: selectedEntry.roleProfile,
|
|
@@ -1877,7 +1942,12 @@ async function maybePromptGroupedServerRoleProfiles(ui, serverBot, deps) {
|
|
|
1877
1942
|
|
|
1878
1943
|
function resolveTelegramServerBindingDetailsFromBots(envConfig, bots, deps) {
|
|
1879
1944
|
const current = safeObject(envConfig);
|
|
1880
|
-
if (
|
|
1945
|
+
if (
|
|
1946
|
+
!String(current.serverBotID || "").trim()
|
|
1947
|
+
&& !String(current.serverBotName || "").trim()
|
|
1948
|
+
&& !String(current.botUsername || "").trim()
|
|
1949
|
+
&& !String(current.botKey || "").trim()
|
|
1950
|
+
) {
|
|
1881
1951
|
return null;
|
|
1882
1952
|
}
|
|
1883
1953
|
const resolveGroupedPayload = (matches, matchedBy) => {
|
|
@@ -1929,7 +1999,7 @@ function resolveTelegramServerBindingDetailsFromBots(envConfig, bots, deps) {
|
|
|
1929
1999
|
detail: `${String(match.name || "").trim() || "(unnamed)"} [${String(match.role || "").trim() || "-"}]`,
|
|
1930
2000
|
};
|
|
1931
2001
|
}
|
|
1932
|
-
const normalizedServerIdentity = normalizeServerBotIdentityText(current.botUsername || current.botKey);
|
|
2002
|
+
const normalizedServerIdentity = normalizeServerBotIdentityText(current.serverBotName || current.botUsername || current.botKey);
|
|
1933
2003
|
const matches = bots.filter((bot) => normalizeServerBotIdentityText(bot.name) === normalizedServerIdentity);
|
|
1934
2004
|
if (!matches.length) {
|
|
1935
2005
|
return {
|
|
@@ -2014,6 +2084,7 @@ async function buildTelegramEntrySelectionRows(entries, flags, deps) {
|
|
|
2014
2084
|
? resolveTelegramServerBindingDetailsFromBots(
|
|
2015
2085
|
{
|
|
2016
2086
|
serverBotID: current.serverBotID,
|
|
2087
|
+
serverBotName: current.serverBotName,
|
|
2017
2088
|
botUsername: current.username,
|
|
2018
2089
|
botKey: current.key,
|
|
2019
2090
|
roleProfile: current.roleProfile,
|
|
@@ -2062,6 +2133,7 @@ async function verifyTelegramTokenCandidate(provider, token, apiBaseURL, timeout
|
|
|
2062
2133
|
async function autoResolveTelegramServerBot(current, flags, deps) {
|
|
2063
2134
|
const existingBotID = String(current?.serverBotID || "").trim();
|
|
2064
2135
|
const preferredIdentity = firstNonEmptyString([
|
|
2136
|
+
current?.serverBotName,
|
|
2065
2137
|
current?.username,
|
|
2066
2138
|
current?.key,
|
|
2067
2139
|
]);
|
|
@@ -2275,6 +2347,8 @@ async function addTelegramBot(ui, flags, deps) {
|
|
|
2275
2347
|
const nextParsed = upsertTelegramEntry(parsed, {
|
|
2276
2348
|
key: botKey,
|
|
2277
2349
|
serverBotID: String(getServerBotIDFlag(flags) || serverBot.botID || "").trim(),
|
|
2350
|
+
serverBotName: String(serverBot.name || "").trim(),
|
|
2351
|
+
serverRoles: preferredRoleSort(serverBot.roles),
|
|
2278
2352
|
username,
|
|
2279
2353
|
__preferServerIdentity: serverBot.matchMode === "group" || Boolean(String(getServerBotIDFlag(flags) || serverBot.botID || "").trim()),
|
|
2280
2354
|
token,
|
|
@@ -2391,6 +2465,23 @@ async function editTelegramBot(ui, flags, deps) {
|
|
|
2391
2465
|
if (boolFromRaw(flags.default, false)) {
|
|
2392
2466
|
parsed.TELEGRAM_DEFAULT_BOT_KEY = current.key;
|
|
2393
2467
|
}
|
|
2468
|
+
if (current.serverBotID || current.username || current.serverBotName) {
|
|
2469
|
+
const resolvedServerBot = await autoResolveTelegramServerBot(current, flags, deps);
|
|
2470
|
+
if (resolvedServerBot.matchMode === "group") {
|
|
2471
|
+
current.serverBotID = String(getServerBotIDFlag(flags) || current.serverBotID || "").trim();
|
|
2472
|
+
current.serverBotName = String(resolvedServerBot.name || current.serverBotName || "").trim();
|
|
2473
|
+
current.serverRoles = preferredRoleSort(resolvedServerBot.roles);
|
|
2474
|
+
if (!hasOwnFlag(flags, "role-profile")) current.roleProfile = "";
|
|
2475
|
+
if (!(hasOwnFlag(flags, "client") || hasOwnFlag(flags, "ai-client"))) current.client = "";
|
|
2476
|
+
if (!(hasOwnFlag(flags, "model") || hasOwnFlag(flags, "ai-model"))) current.model = "";
|
|
2477
|
+
if (!(hasOwnFlag(flags, "permission-mode") || hasOwnFlag(flags, "ai-permission-mode"))) current.permissionMode = "";
|
|
2478
|
+
if (!(hasOwnFlag(flags, "reasoning-effort") || hasOwnFlag(flags, "ai-reasoning-effort"))) current.reasoningEffort = "";
|
|
2479
|
+
} else if (String(resolvedServerBot.botID || "").trim()) {
|
|
2480
|
+
current.serverBotID = String(resolvedServerBot.botID || "").trim();
|
|
2481
|
+
current.serverBotName = String(resolvedServerBot.name || "").trim();
|
|
2482
|
+
current.serverRoles = ensureArray(resolvedServerBot.roles);
|
|
2483
|
+
}
|
|
2484
|
+
}
|
|
2394
2485
|
saveTelegramBotEdit(parsed, selected, current, deps);
|
|
2395
2486
|
return;
|
|
2396
2487
|
}
|
|
@@ -2462,6 +2553,43 @@ async function verifyProviderEntry(ui, provider, flags, deps) {
|
|
|
2462
2553
|
if (serverBinding && !serverBinding.ok) {
|
|
2463
2554
|
overallOK = false;
|
|
2464
2555
|
}
|
|
2556
|
+
if (serverBinding?.ok && envConfig.botKey) {
|
|
2557
|
+
const selectedEntry = findTelegramEntryByFlags(
|
|
2558
|
+
state.parsed,
|
|
2559
|
+
{ "bot-key": envConfig.botKey },
|
|
2560
|
+
deps,
|
|
2561
|
+
);
|
|
2562
|
+
if (selectedEntry) {
|
|
2563
|
+
const desiredServerBotName = String(serverBinding.name || "").trim();
|
|
2564
|
+
const desiredServerRoles = ensureArray(serverBinding.roles);
|
|
2565
|
+
const currentServerRoles = ensureArray(selectedEntry.serverRoles);
|
|
2566
|
+
const currentServerRolesJoined = currentServerRoles.join(",");
|
|
2567
|
+
const desiredServerRolesJoined = desiredServerRoles.join(",");
|
|
2568
|
+
const desiredServerBotID = (
|
|
2569
|
+
String(selectedEntry.serverBotID || "").trim()
|
|
2570
|
+
|| (serverBinding.mode === "single" ? String(serverBinding.serverBotID || "").trim() : "")
|
|
2571
|
+
);
|
|
2572
|
+
const needsMetadataBackfill = (
|
|
2573
|
+
String(selectedEntry.serverBotName || "").trim() !== desiredServerBotName
|
|
2574
|
+
|| currentServerRolesJoined !== desiredServerRolesJoined
|
|
2575
|
+
|| String(selectedEntry.serverBotID || "").trim() !== desiredServerBotID
|
|
2576
|
+
);
|
|
2577
|
+
if (needsMetadataBackfill) {
|
|
2578
|
+
const nextEntry = {
|
|
2579
|
+
...selectedEntry,
|
|
2580
|
+
serverBotID: desiredServerBotID,
|
|
2581
|
+
serverBotName: desiredServerBotName,
|
|
2582
|
+
serverRoles: desiredServerRoles,
|
|
2583
|
+
};
|
|
2584
|
+
const nextParsed = upsertTelegramEntry(state.parsed, nextEntry);
|
|
2585
|
+
writeProviderEnvState("telegram", nextParsed, deps);
|
|
2586
|
+
rewriteTelegramEntryFile(nextEntry, deps);
|
|
2587
|
+
envConfig.serverBotID = desiredServerBotID;
|
|
2588
|
+
envConfig.serverBotName = desiredServerBotName;
|
|
2589
|
+
envConfig.serverRoles = desiredServerRoles;
|
|
2590
|
+
}
|
|
2591
|
+
}
|
|
2592
|
+
}
|
|
2465
2593
|
routeLinks = summarizeTelegramRouteLinks(state.parsed, {
|
|
2466
2594
|
key: envConfig.botKey,
|
|
2467
2595
|
serverBotID: envConfig.serverBotID,
|
|
@@ -2492,6 +2620,8 @@ async function verifyProviderEntry(ui, provider, flags, deps) {
|
|
|
2492
2620
|
filePath: envConfig.filePath,
|
|
2493
2621
|
botKey: envConfig.botKey || "",
|
|
2494
2622
|
serverBotID: envConfig.serverBotID || "",
|
|
2623
|
+
serverBotName: envConfig.serverBotName || "",
|
|
2624
|
+
serverRoles: ensureArray(envConfig.serverRoles),
|
|
2495
2625
|
detail: result.detail || "",
|
|
2496
2626
|
roleProfile: envConfig.roleProfile || "",
|
|
2497
2627
|
client: envConfig.client || "",
|
|
@@ -2508,6 +2638,8 @@ async function verifyProviderEntry(ui, provider, flags, deps) {
|
|
|
2508
2638
|
`file: ${envConfig.filePath}`,
|
|
2509
2639
|
provider === "telegram" ? `bot_key: ${envConfig.botKey || "-"}` : "",
|
|
2510
2640
|
provider === "telegram" ? `server_bot_id: ${envConfig.serverBotID || "-"}` : "",
|
|
2641
|
+
provider === "telegram" ? `stored_server_name: ${envConfig.serverBotName || "-"}` : "",
|
|
2642
|
+
provider === "telegram" ? `stored_server_roles: ${ensureArray(envConfig.serverRoles).join(", ") || "-"}` : "",
|
|
2511
2643
|
provider === "telegram" ? `role_profile: ${envConfig.roleProfile || "-"}` : "",
|
|
2512
2644
|
provider === "telegram" ? `ai_client: ${envConfig.client ? displayLocalAIClientName(envConfig.client) : "-"}` : "",
|
|
2513
2645
|
provider === "telegram" ? `ai_model: ${envConfig.model || "-"}` : "",
|
|
@@ -353,13 +353,15 @@ export async function runSelftestBotCommands(push, deps) {
|
|
|
353
353
|
push(
|
|
354
354
|
"bot_add_guided_creates_named_telegram_entry",
|
|
355
355
|
String(addState.TELEGRAM_BOT_NAME || "").toLowerCase().includes("monitorselftestbot")
|
|
356
|
+
&& String(addState.TELEGRAM_BOT_SERVER_NAME || "") === "MonitorSelftestBot"
|
|
357
|
+
&& String(addState.TELEGRAM_BOT_SERVER_ROLES || "") === "monitor"
|
|
356
358
|
&& String(addState.TELEGRAM_BOT_TOKEN || "") === "selftest-main-token"
|
|
357
359
|
&& String(addState.TELEGRAM_BOT_ROLE_PROFILE || "") === "monitor"
|
|
358
360
|
&& String(addState.TELEGRAM_BOT_AI_CLIENT || "") === "codex"
|
|
359
361
|
&& String(addState.TELEGRAM_BOT_AI_PERMISSION_MODE || "") === "read_only"
|
|
360
362
|
&& String(addState.TELEGRAM_BOT_AI_REASONING_EFFORT || "") === "low"
|
|
361
363
|
&& 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 || "")}`,
|
|
364
|
+
`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
365
|
);
|
|
364
366
|
|
|
365
367
|
const groupedMock = await createMockServer({
|
|
@@ -403,10 +405,12 @@ export async function runSelftestBotCommands(push, deps) {
|
|
|
403
405
|
"bot_add_guided_autoresolves_server_bot_group_without_role_prompt",
|
|
404
406
|
String(groupedState.TELEGRAM_BOT_NAME || "").toLowerCase() === "ryoai_bot"
|
|
405
407
|
&& String(groupedState.TELEGRAM_BOT_SERVER_BOT_ID || "") === ""
|
|
408
|
+
&& String(groupedState.TELEGRAM_BOT_SERVER_NAME || "") === "RyoAI_bot"
|
|
409
|
+
&& String(groupedState.TELEGRAM_BOT_SERVER_ROLES || "") === "monitor,review,worker,approval"
|
|
406
410
|
&& String(groupedState.TELEGRAM_BOT_ROLE_PROFILE || "") === ""
|
|
407
411
|
&& String(groupedState.TELEGRAM_BOT_AI_CLIENT || "") === ""
|
|
408
412
|
&& String(groupedState.TELEGRAM_BOT_AI_PERMISSION_MODE || "") === "",
|
|
409
|
-
`name=${String(groupedState.TELEGRAM_BOT_NAME || "")} server_bot_id=${String(groupedState.TELEGRAM_BOT_SERVER_BOT_ID || "")} role=${String(groupedState.TELEGRAM_BOT_ROLE_PROFILE || "")}`,
|
|
413
|
+
`name=${String(groupedState.TELEGRAM_BOT_NAME || "")} 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
414
|
);
|
|
411
415
|
|
|
412
416
|
const groupedEditResult = await runCLI({
|
|
@@ -758,11 +762,13 @@ export async function runSelftestBotCommands(push, deps) {
|
|
|
758
762
|
push(
|
|
759
763
|
"bot_add_accepts_ai_prefixed_option_aliases",
|
|
760
764
|
String(aliasAddState.TELEGRAM_BOT_SERVER_BOT_ID || "") === mock.bots[0].id
|
|
765
|
+
&& String(aliasAddState.TELEGRAM_BOT_SERVER_NAME || "") === "MonitorSelftestBot"
|
|
766
|
+
&& String(aliasAddState.TELEGRAM_BOT_SERVER_ROLES || "") === "monitor"
|
|
761
767
|
&& String(aliasAddState.TELEGRAM_BOT_AI_CLIENT || "") === "codex"
|
|
762
768
|
&& String(aliasAddState.TELEGRAM_BOT_AI_MODEL || "") === "gpt-5.4"
|
|
763
769
|
&& String(aliasAddState.TELEGRAM_BOT_AI_PERMISSION_MODE || "") === "read_only"
|
|
764
770
|
&& String(aliasAddState.TELEGRAM_BOT_AI_REASONING_EFFORT || "") === "low",
|
|
765
|
-
`client=${String(aliasAddState.TELEGRAM_BOT_AI_CLIENT || "")} model=${String(aliasAddState.TELEGRAM_BOT_AI_MODEL || "")}`,
|
|
771
|
+
`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
772
|
);
|
|
767
773
|
|
|
768
774
|
const guidedRemoveBeforeList = await runCLI({
|