@deadragdoll/tellymcp 0.0.8 → 0.0.10
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/.env.example.client +2 -0
- package/.env.example.gateway +2 -0
- package/README-ru.md +21 -1
- package/README.md +5 -1
- package/TOOLS.md +3 -1
- package/VERSION.md +58 -0
- package/config/templates/env.both.template +1 -0
- package/config/templates/env.client.template +1 -0
- package/config/templates/env.gateway.template +1 -0
- package/dist/services/features/telegram-mcp/approval.service.js +1 -1
- package/dist/services/features/telegram-mcp/browser.service.js +1 -1
- package/dist/services/features/telegram-mcp/collaboration.service.js +1 -1
- package/dist/services/features/telegram-mcp/gateway-rmq.service.js +3 -2
- package/dist/services/features/telegram-mcp/gateway-socket.service.js +8 -2
- package/dist/services/features/telegram-mcp/inbox.service.js +1 -1
- package/dist/services/features/telegram-mcp/mcp-http.service.js +1 -1
- package/dist/services/features/telegram-mcp/notify.service.js +1 -1
- package/dist/services/features/telegram-mcp/pair.service.js +1 -1
- package/dist/services/features/telegram-mcp/runtime.service.js +27 -7
- package/dist/services/features/telegram-mcp/session-context.service.js +1 -1
- package/dist/services/features/telegram-mcp/src/app/bootstrap/runtime.js +2 -1
- package/dist/services/features/telegram-mcp/src/app/config/env.js +4 -0
- package/dist/services/features/telegram-mcp/src/app/http.js +8 -1
- package/dist/services/features/telegram-mcp/src/app/providers/mcp/server.js +2 -1
- package/dist/services/features/telegram-mcp/src/app/webapp/assets.js +201 -60
- package/dist/services/features/telegram-mcp/src/shared/i18n/index.js +46 -0
- package/dist/services/features/telegram-mcp/src/shared/i18n/resources/en.js +555 -0
- package/dist/services/features/telegram-mcp/src/shared/i18n/resources/ru.js +555 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/redis/stateStore.js +9 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transport.js +1227 -567
- package/dist/services/features/telegram-mcp/standalone-http.service.js +1 -1
- package/dist/services/features/telegram-mcp/tools-sync.service.js +1 -1
- package/package.json +2 -1
|
@@ -18,6 +18,7 @@ const collabUi_1 = require("./collabUi");
|
|
|
18
18
|
const proxyFetch_1 = require("./proxyFetch");
|
|
19
19
|
const client_1 = require("../tmux/client");
|
|
20
20
|
const versionHandshake_1 = require("../../lib/version/versionHandshake");
|
|
21
|
+
const i18n_1 = require("../../i18n");
|
|
21
22
|
const LOCAL_INDEX_FILE_NAME = "LOCAL_INDEX.md";
|
|
22
23
|
const TMUX_NUDGE_FAILURE_NOTICE_COOLDOWN_MS = 5 * 60 * 1000;
|
|
23
24
|
function trimTrailingSlashes(value) {
|
|
@@ -278,6 +279,7 @@ class TelegramTransport {
|
|
|
278
279
|
bindingStore;
|
|
279
280
|
inboxStore;
|
|
280
281
|
menuPayloadStore;
|
|
282
|
+
localeStore;
|
|
281
283
|
xchangeFileMetaStore;
|
|
282
284
|
maintenanceStore;
|
|
283
285
|
objectStore;
|
|
@@ -326,18 +328,19 @@ class TelegramTransport {
|
|
|
326
328
|
menuId: ctx.callbackQuery?.data ?? "unknown",
|
|
327
329
|
});
|
|
328
330
|
await ctx.answerCallbackQuery({
|
|
329
|
-
text:
|
|
331
|
+
text: await this.tForContext(ctx, "common:menu.refreshed"),
|
|
330
332
|
});
|
|
331
333
|
await handler(ctx);
|
|
332
334
|
},
|
|
333
335
|
};
|
|
334
336
|
}
|
|
335
|
-
constructor(config, sessionStore, bindingStore, inboxStore, menuPayloadStore, xchangeFileMetaStore, maintenanceStore, objectStore, webAppLaunchRegistry, logger) {
|
|
337
|
+
constructor(config, sessionStore, bindingStore, inboxStore, menuPayloadStore, localeStore, xchangeFileMetaStore, maintenanceStore, objectStore, webAppLaunchRegistry, logger) {
|
|
336
338
|
this.config = config;
|
|
337
339
|
this.sessionStore = sessionStore;
|
|
338
340
|
this.bindingStore = bindingStore;
|
|
339
341
|
this.inboxStore = inboxStore;
|
|
340
342
|
this.menuPayloadStore = menuPayloadStore;
|
|
343
|
+
this.localeStore = localeStore;
|
|
341
344
|
this.xchangeFileMetaStore = xchangeFileMetaStore;
|
|
342
345
|
this.maintenanceStore = maintenanceStore;
|
|
343
346
|
this.objectStore = objectStore;
|
|
@@ -405,7 +408,9 @@ class TelegramTransport {
|
|
|
405
408
|
await this.cancelPendingPartnerNote(ctx);
|
|
406
409
|
});
|
|
407
410
|
this.bot.callbackQuery("partner-back", async (ctx) => {
|
|
408
|
-
await ctx.answerCallbackQuery({
|
|
411
|
+
await ctx.answerCallbackQuery({
|
|
412
|
+
text: await this.tForContext(ctx, "menu:partner.actions.back_to_partner"),
|
|
413
|
+
});
|
|
409
414
|
await this.showPartnerMenu(ctx);
|
|
410
415
|
});
|
|
411
416
|
this.bot.callbackQuery("file-handoff-cancel", async (ctx) => {
|
|
@@ -814,26 +819,59 @@ class TelegramTransport {
|
|
|
814
819
|
if (!primarySessionId) {
|
|
815
820
|
continue;
|
|
816
821
|
}
|
|
822
|
+
const locale = await this.resolveLocaleForTelegramUserId(recipientGroup.binding.telegramUserId);
|
|
817
823
|
const uniqueSessionLabels = Array.from(new Set(recipientGroup.sessionLabels)).sort();
|
|
824
|
+
const browserStatus = this.config.browser.enabled
|
|
825
|
+
? (this.config.browser.headless ? "enabled, headless" : "enabled, headed")
|
|
826
|
+
: "disabled";
|
|
818
827
|
const startupMessage = [
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
828
|
+
this.t(locale, "menu:notices.startup.title"),
|
|
829
|
+
this.t(locale, "menu:notices.startup.version", {
|
|
830
|
+
packageVersion,
|
|
831
|
+
}),
|
|
832
|
+
this.t(locale, "menu:notices.startup.protocol", {
|
|
833
|
+
protocolVersion: versionHandshake_1.TELLYMCP_PROTOCOL_VERSION,
|
|
834
|
+
}),
|
|
835
|
+
this.t(locale, "menu:notices.startup.mode", {
|
|
836
|
+
mode: this.config.distributed.mode,
|
|
837
|
+
}),
|
|
823
838
|
...(this.config.telegram.botUsername
|
|
824
|
-
? [
|
|
839
|
+
? [
|
|
840
|
+
this.t(locale, "menu:notices.startup.bot", {
|
|
841
|
+
botUsername: this.config.telegram.botUsername.replace(/^@/u, ""),
|
|
842
|
+
}),
|
|
843
|
+
]
|
|
844
|
+
: []),
|
|
845
|
+
this.t(locale, "menu:notices.startup.sessions", {
|
|
846
|
+
count: uniqueSessionLabels.length,
|
|
847
|
+
}),
|
|
848
|
+
this.t(locale, "menu:notices.startup.session_list", {
|
|
849
|
+
sessions: uniqueSessionLabels.join(", "),
|
|
850
|
+
}),
|
|
851
|
+
this.t(locale, "menu:notices.startup.mcp", {
|
|
852
|
+
url: localMcpUrl,
|
|
853
|
+
}),
|
|
854
|
+
...(this.config.webapp.enabled
|
|
855
|
+
? [this.t(locale, "menu:notices.startup.webapp", { url: localWebappUrl })]
|
|
825
856
|
: []),
|
|
826
|
-
`Сессии: ${uniqueSessionLabels.join(", ")}`,
|
|
827
|
-
`MCP: ${localMcpUrl}`,
|
|
828
|
-
...(this.config.webapp.enabled ? [`WebApp: ${localWebappUrl}`] : []),
|
|
829
857
|
...(this.config.distributed.gatewayPublicUrl
|
|
830
|
-
? [
|
|
858
|
+
? [
|
|
859
|
+
this.t(locale, "menu:notices.startup.gateway", {
|
|
860
|
+
url: this.config.distributed.gatewayPublicUrl,
|
|
861
|
+
}),
|
|
862
|
+
]
|
|
831
863
|
: []),
|
|
832
864
|
...(this.config.distributed.gatewayWsUrl
|
|
833
|
-
? [
|
|
865
|
+
? [
|
|
866
|
+
this.t(locale, "menu:notices.startup.gateway_ws", {
|
|
867
|
+
url: this.config.distributed.gatewayWsUrl,
|
|
868
|
+
}),
|
|
869
|
+
]
|
|
834
870
|
: []),
|
|
835
|
-
|
|
836
|
-
|
|
871
|
+
this.t(locale, "menu:notices.startup.browser", {
|
|
872
|
+
status: browserStatus,
|
|
873
|
+
}),
|
|
874
|
+
this.t(locale, "menu:notices.startup.hint"),
|
|
837
875
|
].join("\n");
|
|
838
876
|
try {
|
|
839
877
|
await this.sendNotification({
|
|
@@ -900,10 +938,10 @@ class TelegramTransport {
|
|
|
900
938
|
return { externalMessageId: response.messageId };
|
|
901
939
|
}
|
|
902
940
|
async handleProjectMemberJoinedEvent(input) {
|
|
903
|
-
const
|
|
941
|
+
const rawMemberLabel = input.member_display_name?.trim() ||
|
|
904
942
|
(input.member_telegram_username?.trim()
|
|
905
943
|
? `@${input.member_telegram_username.trim().replace(/^@/u, "")}`
|
|
906
|
-
:
|
|
944
|
+
: null);
|
|
907
945
|
const sessions = await this.sessionStore.listSessions();
|
|
908
946
|
const notifiedChats = new Set();
|
|
909
947
|
for (const session of sessions) {
|
|
@@ -911,6 +949,8 @@ class TelegramTransport {
|
|
|
911
949
|
if (!binding || notifiedChats.has(binding.telegramChatId)) {
|
|
912
950
|
continue;
|
|
913
951
|
}
|
|
952
|
+
const locale = await this.resolveLocaleForTelegramUserId(binding.telegramUserId);
|
|
953
|
+
const memberLabel = rawMemberLabel ?? this.t(locale, "menu:notices.project.new_member");
|
|
914
954
|
await this.sendNotification({
|
|
915
955
|
sessionId: session.sessionId,
|
|
916
956
|
...(session.label ? { sessionLabel: session.label } : {}),
|
|
@@ -918,16 +958,19 @@ class TelegramTransport {
|
|
|
918
958
|
telegramChatId: binding.telegramChatId,
|
|
919
959
|
telegramUserId: binding.telegramUserId,
|
|
920
960
|
},
|
|
921
|
-
message:
|
|
961
|
+
message: this.t(locale, "menu:notices.project.member_joined", {
|
|
962
|
+
projectName: input.project_name,
|
|
963
|
+
memberLabel,
|
|
964
|
+
}),
|
|
922
965
|
});
|
|
923
966
|
notifiedChats.add(binding.telegramChatId);
|
|
924
967
|
}
|
|
925
968
|
}
|
|
926
969
|
async handleProjectMemberLeftEvent(input) {
|
|
927
|
-
const
|
|
970
|
+
const rawMemberLabel = input.member_display_name?.trim() ||
|
|
928
971
|
(input.member_telegram_username?.trim()
|
|
929
972
|
? `@${input.member_telegram_username.trim().replace(/^@/u, "")}`
|
|
930
|
-
:
|
|
973
|
+
: null);
|
|
931
974
|
const sessions = await this.sessionStore.listSessions();
|
|
932
975
|
const notifiedChats = new Set();
|
|
933
976
|
for (const session of sessions) {
|
|
@@ -935,6 +978,8 @@ class TelegramTransport {
|
|
|
935
978
|
if (!binding || notifiedChats.has(binding.telegramChatId)) {
|
|
936
979
|
continue;
|
|
937
980
|
}
|
|
981
|
+
const locale = await this.resolveLocaleForTelegramUserId(binding.telegramUserId);
|
|
982
|
+
const memberLabel = rawMemberLabel ?? this.t(locale, "menu:notices.project.member");
|
|
938
983
|
await this.sendNotification({
|
|
939
984
|
sessionId: session.sessionId,
|
|
940
985
|
...(session.label ? { sessionLabel: session.label } : {}),
|
|
@@ -942,7 +987,10 @@ class TelegramTransport {
|
|
|
942
987
|
telegramChatId: binding.telegramChatId,
|
|
943
988
|
telegramUserId: binding.telegramUserId,
|
|
944
989
|
},
|
|
945
|
-
message:
|
|
990
|
+
message: this.t(locale, "menu:notices.project.member_left", {
|
|
991
|
+
projectName: input.project_name,
|
|
992
|
+
memberLabel,
|
|
993
|
+
}),
|
|
946
994
|
});
|
|
947
995
|
notifiedChats.add(binding.telegramChatId);
|
|
948
996
|
}
|
|
@@ -963,6 +1011,7 @@ class TelegramTransport {
|
|
|
963
1011
|
if (!binding || notifiedChats.has(binding.telegramChatId)) {
|
|
964
1012
|
continue;
|
|
965
1013
|
}
|
|
1014
|
+
const locale = await this.resolveLocaleForTelegramUserId(binding.telegramUserId);
|
|
966
1015
|
await this.sendNotification({
|
|
967
1016
|
sessionId: session.sessionId,
|
|
968
1017
|
...(session.label ? { sessionLabel: session.label } : {}),
|
|
@@ -970,7 +1019,9 @@ class TelegramTransport {
|
|
|
970
1019
|
telegramChatId: binding.telegramChatId,
|
|
971
1020
|
telegramUserId: binding.telegramUserId,
|
|
972
1021
|
},
|
|
973
|
-
message:
|
|
1022
|
+
message: this.t(locale, "menu:notices.project.deleted", {
|
|
1023
|
+
projectName: input.project_name,
|
|
1024
|
+
}),
|
|
974
1025
|
});
|
|
975
1026
|
notifiedChats.add(binding.telegramChatId);
|
|
976
1027
|
}
|
|
@@ -1055,9 +1106,11 @@ class TelegramTransport {
|
|
|
1055
1106
|
telegramUserId: binding.telegramUserId,
|
|
1056
1107
|
},
|
|
1057
1108
|
message: [
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1109
|
+
await this.tForTelegramUserId(binding.telegramUserId, "menu:notices.tools.changed"),
|
|
1110
|
+
await this.tForTelegramUserId(binding.telegramUserId, "menu:notices.tools.session", {
|
|
1111
|
+
sessionName: session.label ?? input.session_label ?? session.sessionId,
|
|
1112
|
+
}),
|
|
1113
|
+
await this.tForTelegramUserId(binding.telegramUserId, "menu:notices.tools.action_required"),
|
|
1061
1114
|
].join("\n"),
|
|
1062
1115
|
});
|
|
1063
1116
|
await this.sessionStore.setSession({
|
|
@@ -1124,12 +1177,20 @@ class TelegramTransport {
|
|
|
1124
1177
|
telegramUserId: binding.telegramUserId,
|
|
1125
1178
|
},
|
|
1126
1179
|
message: [
|
|
1127
|
-
input.compatibility === "reject"
|
|
1128
|
-
? "
|
|
1129
|
-
: "
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1180
|
+
await this.tForTelegramUserId(binding.telegramUserId, input.compatibility === "reject"
|
|
1181
|
+
? "menu:notices.version.reject"
|
|
1182
|
+
: "menu:notices.version.warn"),
|
|
1183
|
+
await this.tForTelegramUserId(binding.telegramUserId, "menu:notices.version.session", {
|
|
1184
|
+
sessionName: session.label ?? input.session_label ?? session.sessionId,
|
|
1185
|
+
}),
|
|
1186
|
+
await this.tForTelegramUserId(binding.telegramUserId, "menu:notices.version.client", {
|
|
1187
|
+
packageVersion: input.client_package_version,
|
|
1188
|
+
protocolVersion: input.client_protocol_version,
|
|
1189
|
+
}),
|
|
1190
|
+
await this.tForTelegramUserId(binding.telegramUserId, "menu:notices.version.gateway", {
|
|
1191
|
+
packageVersion: input.gateway_package_version,
|
|
1192
|
+
protocolVersion: input.gateway_protocol_version,
|
|
1193
|
+
}),
|
|
1133
1194
|
input.instruction,
|
|
1134
1195
|
].join("\n"),
|
|
1135
1196
|
});
|
|
@@ -1151,6 +1212,7 @@ class TelegramTransport {
|
|
|
1151
1212
|
});
|
|
1152
1213
|
return;
|
|
1153
1214
|
}
|
|
1215
|
+
const locale = await this.resolveLocaleForTelegramUserId(binding.telegramUserId);
|
|
1154
1216
|
const payloadKey = await this.createLiveApprovalMenuPayload({
|
|
1155
1217
|
sessionId: targetSession.sessionId,
|
|
1156
1218
|
sourceSessionId: input.source_session_id,
|
|
@@ -1165,17 +1227,27 @@ class TelegramTransport {
|
|
|
1165
1227
|
...(input.project_name ? { projectName: input.project_name } : {}),
|
|
1166
1228
|
});
|
|
1167
1229
|
const sent = await this.sendChatMessage(binding.telegramChatId, [
|
|
1168
|
-
|
|
1230
|
+
this.t(locale, "menu:live.approval.request_title"),
|
|
1169
1231
|
"",
|
|
1170
|
-
...(input.project_name
|
|
1171
|
-
|
|
1232
|
+
...(input.project_name
|
|
1233
|
+
? [
|
|
1234
|
+
this.t(locale, "menu:live.approval.project", {
|
|
1235
|
+
projectName: input.project_name,
|
|
1236
|
+
}),
|
|
1237
|
+
]
|
|
1238
|
+
: []),
|
|
1239
|
+
this.t(locale, "menu:live.approval.route", {
|
|
1240
|
+
sourceSessionName: input.source_session_label,
|
|
1241
|
+
targetSessionName: input.target_session_label,
|
|
1242
|
+
}),
|
|
1172
1243
|
"",
|
|
1173
|
-
|
|
1174
|
-
|
|
1244
|
+
this.t(locale, "menu:live.approval.request_message", {
|
|
1245
|
+
sourceSessionName: input.source_session_label,
|
|
1246
|
+
}),
|
|
1175
1247
|
].join("\n"), {
|
|
1176
1248
|
reply_markup: new grammy_1.InlineKeyboard()
|
|
1177
|
-
.text(
|
|
1178
|
-
.text(
|
|
1249
|
+
.text(`✅ ${this.t(locale, "menu:live.approval.approve")}`, `live-approval:approve:${payloadKey}`)
|
|
1250
|
+
.text(`❌ ${this.t(locale, "menu:live.approval.deny")}`, `live-approval:deny:${payloadKey}`),
|
|
1179
1251
|
}, {
|
|
1180
1252
|
kind: "notification",
|
|
1181
1253
|
sessionId: targetSession.sessionId,
|
|
@@ -1205,6 +1277,7 @@ class TelegramTransport {
|
|
|
1205
1277
|
});
|
|
1206
1278
|
return;
|
|
1207
1279
|
}
|
|
1280
|
+
const locale = await this.resolveLocaleForTelegramUserId(binding.telegramUserId);
|
|
1208
1281
|
if (!input.approved) {
|
|
1209
1282
|
await this.sendNotification({
|
|
1210
1283
|
sessionId: sourceSession.sessionId,
|
|
@@ -1214,9 +1287,18 @@ class TelegramTransport {
|
|
|
1214
1287
|
telegramUserId: binding.telegramUserId,
|
|
1215
1288
|
},
|
|
1216
1289
|
message: [
|
|
1217
|
-
|
|
1218
|
-
...(input.project_name
|
|
1219
|
-
|
|
1290
|
+
this.t(locale, "menu:live.approval.denied"),
|
|
1291
|
+
...(input.project_name
|
|
1292
|
+
? [
|
|
1293
|
+
this.t(locale, "menu:live.approval.project", {
|
|
1294
|
+
projectName: input.project_name,
|
|
1295
|
+
}),
|
|
1296
|
+
]
|
|
1297
|
+
: []),
|
|
1298
|
+
this.t(locale, "menu:live.approval.route", {
|
|
1299
|
+
sourceSessionName: input.source_session_label,
|
|
1300
|
+
targetSessionName: input.target_session_label,
|
|
1301
|
+
}),
|
|
1220
1302
|
].join("\n"),
|
|
1221
1303
|
});
|
|
1222
1304
|
return;
|
|
@@ -1231,14 +1313,29 @@ class TelegramTransport {
|
|
|
1231
1313
|
throw new Error("Unable to build Live View URL for approved request.");
|
|
1232
1314
|
}
|
|
1233
1315
|
const sent = await this.sendChatMessage(binding.telegramChatId, [
|
|
1234
|
-
|
|
1316
|
+
this.t(locale, "menu:live.approval.approved"),
|
|
1235
1317
|
"",
|
|
1236
|
-
...(input.project_name
|
|
1237
|
-
|
|
1318
|
+
...(input.project_name
|
|
1319
|
+
? [
|
|
1320
|
+
this.t(locale, "menu:live.approval.project", {
|
|
1321
|
+
projectName: input.project_name,
|
|
1322
|
+
}),
|
|
1323
|
+
]
|
|
1324
|
+
: []),
|
|
1325
|
+
this.t(locale, "menu:live.approval.route", {
|
|
1326
|
+
sourceSessionName: input.source_session_label,
|
|
1327
|
+
targetSessionName: input.target_session_label,
|
|
1328
|
+
}),
|
|
1238
1329
|
"",
|
|
1239
|
-
|
|
1330
|
+
this.t(locale, "menu:live.actions.choose_mode"),
|
|
1240
1331
|
].join("\n"), {
|
|
1241
|
-
reply_markup:
|
|
1332
|
+
reply_markup: this.buildLiveViewLaunchKeyboard((mode) => this.buildLiveViewUrlForSessionTarget({
|
|
1333
|
+
targetSessionId: input.target_session_id,
|
|
1334
|
+
targetClientUuid: input.target_client_uuid,
|
|
1335
|
+
targetLocalSessionId: input.target_local_session_id,
|
|
1336
|
+
sourceClientUuid: input.source_client_uuid,
|
|
1337
|
+
launchMode: mode,
|
|
1338
|
+
}), locale),
|
|
1242
1339
|
}, {
|
|
1243
1340
|
kind: "notification",
|
|
1244
1341
|
sessionId: sourceSession.sessionId,
|
|
@@ -1469,22 +1566,26 @@ class TelegramTransport {
|
|
|
1469
1566
|
fingerprint: async (ctx) => this.buildMainMenuFingerprint(ctx),
|
|
1470
1567
|
...this.createMenuOptions((ctx) => this.showMainMenu(ctx)),
|
|
1471
1568
|
})
|
|
1472
|
-
.text(
|
|
1569
|
+
.text(async (ctx) => this.tForContext(ctx, "menu:main.buttons.live"), async (ctx) => {
|
|
1473
1570
|
await this.showLiveViewLauncher(ctx);
|
|
1474
1571
|
})
|
|
1475
|
-
.text(
|
|
1476
|
-
await ctx.answerCallbackQuery({
|
|
1572
|
+
.text(async (ctx) => this.tForContext(ctx, "menu:main.buttons.content"), async (ctx) => {
|
|
1573
|
+
await ctx.answerCallbackQuery({
|
|
1574
|
+
text: await this.tForContext(ctx, "menu:main.actions.open_content"),
|
|
1575
|
+
});
|
|
1477
1576
|
await this.showBufferMenu(ctx);
|
|
1478
1577
|
})
|
|
1479
|
-
.text(
|
|
1480
|
-
await ctx.answerCallbackQuery({
|
|
1578
|
+
.text(async (ctx) => this.tForContext(ctx, "menu:main.buttons.browser"), async (ctx) => {
|
|
1579
|
+
await ctx.answerCallbackQuery({
|
|
1580
|
+
text: await this.tForContext(ctx, "menu:main.actions.open_browser"),
|
|
1581
|
+
});
|
|
1481
1582
|
await this.showBrowserMenu(ctx);
|
|
1482
1583
|
})
|
|
1483
1584
|
.row()
|
|
1484
|
-
.text(
|
|
1585
|
+
.text(async (ctx) => this.tForContext(ctx, "menu:main.buttons.local"), async (ctx) => {
|
|
1485
1586
|
await this.showLocalEntryPoint(ctx);
|
|
1486
1587
|
})
|
|
1487
|
-
.text(
|
|
1588
|
+
.text(async (ctx) => this.tForContext(ctx, "menu:main.buttons.collab"), async (ctx) => {
|
|
1488
1589
|
await this.showProjectsEntryPoint(ctx);
|
|
1489
1590
|
})
|
|
1490
1591
|
.row()
|
|
@@ -1493,32 +1594,44 @@ class TelegramTransport {
|
|
|
1493
1594
|
chatId: ctx.chat?.id,
|
|
1494
1595
|
userId: ctx.from?.id,
|
|
1495
1596
|
});
|
|
1496
|
-
await ctx.answerCallbackQuery({
|
|
1597
|
+
await ctx.answerCallbackQuery({
|
|
1598
|
+
text: await this.tForContext(ctx, "menu:main.actions.open_inbox"),
|
|
1599
|
+
});
|
|
1497
1600
|
await this.showInboxMenu(ctx);
|
|
1498
1601
|
})
|
|
1499
|
-
.text(
|
|
1500
|
-
await ctx.answerCallbackQuery({
|
|
1602
|
+
.text(async (ctx) => this.tForContext(ctx, "menu:main.buttons.storage"), async (ctx) => {
|
|
1603
|
+
await ctx.answerCallbackQuery({
|
|
1604
|
+
text: await this.tForContext(ctx, "menu:main.actions.open_storage"),
|
|
1605
|
+
});
|
|
1501
1606
|
await this.showStorageMenu(ctx);
|
|
1502
1607
|
})
|
|
1503
|
-
.text(
|
|
1504
|
-
await ctx.answerCallbackQuery({
|
|
1608
|
+
.text(async (ctx) => this.tForContext(ctx, "menu:main.buttons.settings"), async (ctx) => {
|
|
1609
|
+
await ctx.answerCallbackQuery({
|
|
1610
|
+
text: await this.tForContext(ctx, "menu:main.actions.open_settings"),
|
|
1611
|
+
});
|
|
1505
1612
|
await this.showSettingsMenu(ctx);
|
|
1506
1613
|
})
|
|
1507
1614
|
.row()
|
|
1508
|
-
.text(
|
|
1509
|
-
await ctx.answerCallbackQuery({
|
|
1615
|
+
.text(async (ctx) => this.tForContext(ctx, "menu:main.buttons.back"), async (ctx) => {
|
|
1616
|
+
await ctx.answerCallbackQuery({
|
|
1617
|
+
text: await this.tForContext(ctx, "menu:main.actions.back_to_sessions"),
|
|
1618
|
+
});
|
|
1510
1619
|
await this.showSessionsMenu(ctx);
|
|
1511
1620
|
});
|
|
1512
1621
|
}
|
|
1513
1622
|
createBrowserMenu() {
|
|
1514
1623
|
return new menu_1.Menu("telegram-browser-menu", this.createMenuOptions((ctx) => this.showBrowserMenu(ctx)))
|
|
1515
1624
|
.text(async (ctx) => this.buildScreenshotsButtonLabel(ctx), async (ctx) => {
|
|
1516
|
-
await ctx.answerCallbackQuery({
|
|
1625
|
+
await ctx.answerCallbackQuery({
|
|
1626
|
+
text: await this.tForContext(ctx, "menu:browser.actions.open_screenshots"),
|
|
1627
|
+
});
|
|
1517
1628
|
await this.showScreenshotsMenu(ctx);
|
|
1518
1629
|
})
|
|
1519
1630
|
.row()
|
|
1520
|
-
.text(
|
|
1521
|
-
await ctx.answerCallbackQuery({
|
|
1631
|
+
.text(async (ctx) => this.tForContext(ctx, "common:menu.back"), async (ctx) => {
|
|
1632
|
+
await ctx.answerCallbackQuery({
|
|
1633
|
+
text: await this.tForContext(ctx, "menu:browser.actions.back_to_session_menu"),
|
|
1634
|
+
});
|
|
1522
1635
|
await this.showMainMenu(ctx);
|
|
1523
1636
|
});
|
|
1524
1637
|
}
|
|
@@ -1531,9 +1644,9 @@ class TelegramTransport {
|
|
|
1531
1644
|
const range = new menu_1.MenuRange();
|
|
1532
1645
|
const { session, projects } = await this.loadProjectsContext(ctx);
|
|
1533
1646
|
if (!session || !projects) {
|
|
1534
|
-
range.text(
|
|
1647
|
+
range.text(await this.tForContext(ctx, "common:menu.gateway_unavailable"), async (innerCtx) => {
|
|
1535
1648
|
await innerCtx.answerCallbackQuery({
|
|
1536
|
-
text:
|
|
1649
|
+
text: await this.tForContext(innerCtx, "menu:collab.actions.gateway_only"),
|
|
1537
1650
|
show_alert: true,
|
|
1538
1651
|
});
|
|
1539
1652
|
});
|
|
@@ -1541,9 +1654,9 @@ class TelegramTransport {
|
|
|
1541
1654
|
}
|
|
1542
1655
|
if (projects.length === 0) {
|
|
1543
1656
|
range
|
|
1544
|
-
.text(
|
|
1657
|
+
.text(await this.tForContext(ctx, "menu:collab.labels.no_projects"), async (innerCtx) => {
|
|
1545
1658
|
await innerCtx.answerCallbackQuery({
|
|
1546
|
-
text:
|
|
1659
|
+
text: await this.tForContext(innerCtx, "menu:collab.actions.no_projects"),
|
|
1547
1660
|
});
|
|
1548
1661
|
})
|
|
1549
1662
|
.row();
|
|
@@ -1562,38 +1675,46 @@ class TelegramTransport {
|
|
|
1562
1675
|
}
|
|
1563
1676
|
return range;
|
|
1564
1677
|
})
|
|
1565
|
-
.text(
|
|
1678
|
+
.text(async (ctx) => this.tForContext(ctx, "menu:collab.buttons.create"), async (ctx) => {
|
|
1566
1679
|
await this.beginProjectMode(ctx, "create");
|
|
1567
1680
|
})
|
|
1568
|
-
.text(
|
|
1569
|
-
await ctx.answerCallbackQuery({
|
|
1681
|
+
.text(async (ctx) => this.tForContext(ctx, "menu:collab.buttons.tools"), async (ctx) => {
|
|
1682
|
+
await ctx.answerCallbackQuery({
|
|
1683
|
+
text: await this.tForContext(ctx, "menu:collab.actions.open_tools"),
|
|
1684
|
+
});
|
|
1570
1685
|
await this.showCollabToolsMenu(ctx);
|
|
1571
1686
|
})
|
|
1572
1687
|
.row()
|
|
1573
|
-
.text(
|
|
1688
|
+
.text(async (ctx) => this.tForContext(ctx, "menu:collab.buttons.join"), async (ctx) => {
|
|
1574
1689
|
await this.beginProjectMode(ctx, "join");
|
|
1575
1690
|
})
|
|
1576
|
-
.text(
|
|
1577
|
-
await ctx.answerCallbackQuery({
|
|
1691
|
+
.text(async (ctx) => this.tForContext(ctx, "common:menu.back"), async (ctx) => {
|
|
1692
|
+
await ctx.answerCallbackQuery({
|
|
1693
|
+
text: await this.tForContext(ctx, "menu:collab.actions.back_to_session_menu"),
|
|
1694
|
+
});
|
|
1578
1695
|
await this.showMainMenu(ctx);
|
|
1579
1696
|
});
|
|
1580
1697
|
}
|
|
1581
1698
|
createCollabToolsMenu() {
|
|
1582
1699
|
return new menu_1.Menu("telegram-collab-tools-menu", this.createMenuOptions((ctx) => this.showCollabToolsMenu(ctx)))
|
|
1583
|
-
.text(
|
|
1700
|
+
.text(async (ctx) => this.tForContext(ctx, "menu:collab.buttons.broadcast"), async (ctx) => {
|
|
1584
1701
|
await this.beginProjectBroadcast(ctx);
|
|
1585
1702
|
})
|
|
1586
|
-
.text(
|
|
1703
|
+
.text(async (ctx) => this.tForContext(ctx, "menu:collab.buttons.history"), async (ctx) => {
|
|
1587
1704
|
await this.handleCollabHistoryExport(ctx);
|
|
1588
1705
|
})
|
|
1589
1706
|
.row()
|
|
1590
|
-
.text(
|
|
1591
|
-
await ctx.answerCallbackQuery({
|
|
1707
|
+
.text(async (ctx) => this.tForContext(ctx, "menu:collab.buttons.delete"), async (ctx) => {
|
|
1708
|
+
await ctx.answerCallbackQuery({
|
|
1709
|
+
text: await this.tForContext(ctx, "menu:collab.actions.open_delete"),
|
|
1710
|
+
});
|
|
1592
1711
|
await this.showCollabDeleteMenu(ctx);
|
|
1593
1712
|
})
|
|
1594
1713
|
.row()
|
|
1595
|
-
.text(
|
|
1596
|
-
await ctx.answerCallbackQuery({
|
|
1714
|
+
.text(async (ctx) => this.tForContext(ctx, "common:menu.back"), async (ctx) => {
|
|
1715
|
+
await ctx.answerCallbackQuery({
|
|
1716
|
+
text: await this.tForContext(ctx, "menu:collab.actions.back_to_collab"),
|
|
1717
|
+
});
|
|
1597
1718
|
await this.showProjectsMenu(ctx);
|
|
1598
1719
|
});
|
|
1599
1720
|
}
|
|
@@ -1606,18 +1727,18 @@ class TelegramTransport {
|
|
|
1606
1727
|
const range = new menu_1.MenuRange();
|
|
1607
1728
|
const { session, projects } = await this.loadProjectsContext(ctx);
|
|
1608
1729
|
if (!session || !projects) {
|
|
1609
|
-
range.text(
|
|
1730
|
+
range.text(await this.tForContext(ctx, "common:menu.gateway_unavailable"), async (innerCtx) => {
|
|
1610
1731
|
await innerCtx.answerCallbackQuery({
|
|
1611
|
-
text:
|
|
1732
|
+
text: await this.tForContext(innerCtx, "menu:collab.actions.gateway_only"),
|
|
1612
1733
|
show_alert: true,
|
|
1613
1734
|
});
|
|
1614
1735
|
});
|
|
1615
1736
|
return range;
|
|
1616
1737
|
}
|
|
1617
1738
|
if (projects.length === 0) {
|
|
1618
|
-
range.text(
|
|
1739
|
+
range.text(await this.tForContext(ctx, "menu:collab.labels.no_projects"), async (innerCtx) => {
|
|
1619
1740
|
await innerCtx.answerCallbackQuery({
|
|
1620
|
-
text:
|
|
1741
|
+
text: await this.tForContext(innerCtx, "menu:collab.actions.no_projects"),
|
|
1621
1742
|
});
|
|
1622
1743
|
});
|
|
1623
1744
|
return range;
|
|
@@ -1635,22 +1756,26 @@ class TelegramTransport {
|
|
|
1635
1756
|
}
|
|
1636
1757
|
return range;
|
|
1637
1758
|
})
|
|
1638
|
-
.text(
|
|
1639
|
-
await ctx.answerCallbackQuery({
|
|
1759
|
+
.text(async (ctx) => this.tForContext(ctx, "common:menu.back"), async (ctx) => {
|
|
1760
|
+
await ctx.answerCallbackQuery({
|
|
1761
|
+
text: await this.tForContext(ctx, "menu:collab.actions.back_to_tools"),
|
|
1762
|
+
});
|
|
1640
1763
|
await this.showCollabToolsMenu(ctx);
|
|
1641
1764
|
});
|
|
1642
1765
|
}
|
|
1643
1766
|
createLocalMenu() {
|
|
1644
1767
|
return new menu_1.Menu("telegram-local-menu", this.createMenuOptions((ctx) => this.showLocalMenu(ctx)))
|
|
1645
|
-
.text(
|
|
1768
|
+
.text(async (ctx) => this.tForContext(ctx, "menu:local.buttons.partner"), async (ctx) => {
|
|
1646
1769
|
await this.showPartnerEntryPoint(ctx);
|
|
1647
1770
|
})
|
|
1648
1771
|
.text(async (ctx) => this.buildLinkButtonLabel(ctx), async (ctx) => {
|
|
1649
1772
|
await this.handleLinkButton(ctx);
|
|
1650
1773
|
})
|
|
1651
1774
|
.row()
|
|
1652
|
-
.text(
|
|
1653
|
-
await ctx.answerCallbackQuery({
|
|
1775
|
+
.text(async (ctx) => this.tForContext(ctx, "common:menu.back"), async (ctx) => {
|
|
1776
|
+
await ctx.answerCallbackQuery({
|
|
1777
|
+
text: await this.tForContext(ctx, "menu:local.actions.back_to_session_menu"),
|
|
1778
|
+
});
|
|
1654
1779
|
await this.showMainMenu(ctx);
|
|
1655
1780
|
});
|
|
1656
1781
|
}
|
|
@@ -1663,9 +1788,9 @@ class TelegramTransport {
|
|
|
1663
1788
|
const range = new menu_1.MenuRange();
|
|
1664
1789
|
const principal = this.getPrincipalFromContext(ctx);
|
|
1665
1790
|
if (!principal) {
|
|
1666
|
-
range.text(
|
|
1791
|
+
range.text(await this.tForContext(ctx, "common:menu.no_telegram_identity_label"), async (innerCtx) => {
|
|
1667
1792
|
await innerCtx.answerCallbackQuery({
|
|
1668
|
-
text:
|
|
1793
|
+
text: await this.tForContext(innerCtx, "common:errors.missing_telegram_context"),
|
|
1669
1794
|
show_alert: true,
|
|
1670
1795
|
});
|
|
1671
1796
|
});
|
|
@@ -1673,9 +1798,9 @@ class TelegramTransport {
|
|
|
1673
1798
|
}
|
|
1674
1799
|
const activeSessionId = await this.bindingStore.getActiveSessionIdForPrincipal(principal);
|
|
1675
1800
|
if (!activeSessionId) {
|
|
1676
|
-
range.text(
|
|
1801
|
+
range.text(await this.tForContext(ctx, "common:menu.no_active_session_label"), async (innerCtx) => {
|
|
1677
1802
|
await innerCtx.answerCallbackQuery({
|
|
1678
|
-
text:
|
|
1803
|
+
text: await this.tForContext(innerCtx, "common:errors.no_active_session"),
|
|
1679
1804
|
show_alert: true,
|
|
1680
1805
|
});
|
|
1681
1806
|
});
|
|
@@ -1685,9 +1810,9 @@ class TelegramTransport {
|
|
|
1685
1810
|
.filter((sessionId) => sessionId !== activeSessionId)
|
|
1686
1811
|
.sort();
|
|
1687
1812
|
if (sessionIds.length === 0) {
|
|
1688
|
-
range.text(
|
|
1813
|
+
range.text(await this.tForContext(ctx, "menu:link.labels.no_partner_sessions"), async (innerCtx) => {
|
|
1689
1814
|
await innerCtx.answerCallbackQuery({
|
|
1690
|
-
text:
|
|
1815
|
+
text: await this.tForContext(innerCtx, "menu:link.actions.no_partner_sessions"),
|
|
1691
1816
|
show_alert: true,
|
|
1692
1817
|
});
|
|
1693
1818
|
});
|
|
@@ -1706,72 +1831,82 @@ class TelegramTransport {
|
|
|
1706
1831
|
}
|
|
1707
1832
|
return range;
|
|
1708
1833
|
})
|
|
1709
|
-
.text(
|
|
1710
|
-
await ctx.answerCallbackQuery({
|
|
1834
|
+
.text(async (ctx) => this.tForContext(ctx, "common:menu.back"), async (ctx) => {
|
|
1835
|
+
await ctx.answerCallbackQuery({
|
|
1836
|
+
text: await this.tForContext(ctx, "menu:link.actions.back_to_session_menu"),
|
|
1837
|
+
});
|
|
1711
1838
|
await this.showMainMenu(ctx);
|
|
1712
1839
|
});
|
|
1713
1840
|
}
|
|
1714
1841
|
createPartnerMenu() {
|
|
1715
1842
|
return new menu_1.Menu("telegram-partner-menu", this.createMenuOptions((ctx) => this.showPartnerMenu(ctx)))
|
|
1716
|
-
.text(
|
|
1843
|
+
.text(async (ctx) => this.tForContext(ctx, "menu:partner.buttons.ask"), async (ctx) => {
|
|
1717
1844
|
await this.beginPartnerNoteMode(ctx, "question");
|
|
1718
1845
|
})
|
|
1719
|
-
.text(
|
|
1846
|
+
.text(async (ctx) => this.tForContext(ctx, "menu:partner.buttons.share"), async (ctx) => {
|
|
1720
1847
|
await this.beginPartnerNoteMode(ctx, "share");
|
|
1721
1848
|
})
|
|
1722
1849
|
.row()
|
|
1723
|
-
.text(
|
|
1850
|
+
.text(async (ctx) => this.tForContext(ctx, "menu:partner.buttons.unlink"), async (ctx) => {
|
|
1724
1851
|
await this.handleLinkButton(ctx);
|
|
1725
1852
|
})
|
|
1726
|
-
.text(
|
|
1727
|
-
await ctx.answerCallbackQuery({
|
|
1853
|
+
.text(async (ctx) => this.tForContext(ctx, "common:menu.back"), async (ctx) => {
|
|
1854
|
+
await ctx.answerCallbackQuery({
|
|
1855
|
+
text: await this.tForContext(ctx, "menu:partner.actions.back_to_session_menu"),
|
|
1856
|
+
});
|
|
1728
1857
|
await this.showMainMenu(ctx);
|
|
1729
1858
|
});
|
|
1730
1859
|
}
|
|
1731
1860
|
createBufferMenu() {
|
|
1732
1861
|
return new menu_1.Menu("telegram-buffer-menu", this.createMenuOptions((ctx) => this.showBufferMenu(ctx)))
|
|
1733
|
-
.text(
|
|
1862
|
+
.text(async (ctx) => this.tForContext(ctx, "menu:buffer.buttons.visible"), async (ctx) => {
|
|
1734
1863
|
await this.sendActiveSessionBuffer(ctx, { mode: "visible" });
|
|
1735
1864
|
})
|
|
1736
|
-
.text(
|
|
1865
|
+
.text(async (ctx) => this.tForContext(ctx, "menu:buffer.buttons.full"), async (ctx) => {
|
|
1737
1866
|
await this.sendActiveSessionBuffer(ctx, { mode: "full" });
|
|
1738
1867
|
})
|
|
1739
1868
|
.row()
|
|
1740
|
-
.text(
|
|
1869
|
+
.text(async (ctx) => this.tForContext(ctx, "menu:buffer.buttons.last_300"), async (ctx) => {
|
|
1741
1870
|
await this.sendActiveSessionBuffer(ctx, {
|
|
1742
1871
|
mode: "lines",
|
|
1743
1872
|
lines: 300,
|
|
1744
1873
|
});
|
|
1745
1874
|
})
|
|
1746
|
-
.text(
|
|
1875
|
+
.text(async (ctx) => this.tForContext(ctx, "menu:buffer.buttons.last_1000"), async (ctx) => {
|
|
1747
1876
|
await this.sendActiveSessionBuffer(ctx, {
|
|
1748
1877
|
mode: "lines",
|
|
1749
1878
|
lines: 1000,
|
|
1750
1879
|
});
|
|
1751
1880
|
})
|
|
1752
1881
|
.row()
|
|
1753
|
-
.text(
|
|
1754
|
-
await ctx.answerCallbackQuery({
|
|
1882
|
+
.text(async (ctx) => this.tForContext(ctx, "common:menu.back"), async (ctx) => {
|
|
1883
|
+
await ctx.answerCallbackQuery({
|
|
1884
|
+
text: await this.tForContext(ctx, "menu:local.actions.back_to_session_menu"),
|
|
1885
|
+
});
|
|
1755
1886
|
await this.showMainMenu(ctx);
|
|
1756
1887
|
});
|
|
1757
1888
|
}
|
|
1758
1889
|
createSettingsMenu() {
|
|
1759
1890
|
return new menu_1.Menu("telegram-settings-menu", this.createMenuOptions((ctx) => this.showSettingsMenu(ctx)))
|
|
1760
|
-
.text(
|
|
1891
|
+
.text(async (ctx) => this.tForContext(ctx, "menu:settings.buttons.info"), async (ctx) => {
|
|
1761
1892
|
await this.showActiveSessionInfo(ctx);
|
|
1762
1893
|
})
|
|
1763
1894
|
.row()
|
|
1764
|
-
.text(
|
|
1895
|
+
.text(async (ctx) => this.tForContext(ctx, "menu:settings.buttons.rename"), async (ctx) => {
|
|
1765
1896
|
await this.beginRenameActiveSession(ctx);
|
|
1766
1897
|
})
|
|
1767
1898
|
.row()
|
|
1768
|
-
.text(
|
|
1769
|
-
await ctx.answerCallbackQuery({
|
|
1899
|
+
.text(async (ctx) => this.tForContext(ctx, "menu:settings.buttons.unpair"), async (ctx) => {
|
|
1900
|
+
await ctx.answerCallbackQuery({
|
|
1901
|
+
text: await this.tForContext(ctx, "menu:settings.actions.confirm_unpair"),
|
|
1902
|
+
});
|
|
1770
1903
|
await this.showUnpairConfirmMenu(ctx);
|
|
1771
1904
|
})
|
|
1772
1905
|
.row()
|
|
1773
|
-
.text(
|
|
1774
|
-
await ctx.answerCallbackQuery({
|
|
1906
|
+
.text(async (ctx) => this.tForContext(ctx, "common:menu.back"), async (ctx) => {
|
|
1907
|
+
await ctx.answerCallbackQuery({
|
|
1908
|
+
text: await this.tForContext(ctx, "menu:local.actions.back_to_session_menu"),
|
|
1909
|
+
});
|
|
1775
1910
|
await this.showMainMenu(ctx);
|
|
1776
1911
|
});
|
|
1777
1912
|
}
|
|
@@ -1793,12 +1928,14 @@ class TelegramTransport {
|
|
|
1793
1928
|
}
|
|
1794
1929
|
createUnpairConfirmMenu() {
|
|
1795
1930
|
return new menu_1.Menu("telegram-unpair-confirm-menu", this.createMenuOptions((ctx) => this.showUnpairConfirmMenu(ctx)))
|
|
1796
|
-
.text(
|
|
1931
|
+
.text(async (ctx) => this.tForContext(ctx, "menu:settings.buttons.confirm_unpair"), async (ctx) => {
|
|
1797
1932
|
await this.unpairActiveSession(ctx);
|
|
1798
1933
|
})
|
|
1799
1934
|
.row()
|
|
1800
|
-
.text(
|
|
1801
|
-
await ctx.answerCallbackQuery({
|
|
1935
|
+
.text(async (ctx) => this.tForContext(ctx, "common:menu.back"), async (ctx) => {
|
|
1936
|
+
await ctx.answerCallbackQuery({
|
|
1937
|
+
text: await this.tForContext(ctx, "menu:settings.actions.back_to_settings"),
|
|
1938
|
+
});
|
|
1802
1939
|
await this.showSettingsMenu(ctx);
|
|
1803
1940
|
});
|
|
1804
1941
|
}
|
|
@@ -1822,9 +1959,9 @@ class TelegramTransport {
|
|
|
1822
1959
|
const range = new menu_1.MenuRange();
|
|
1823
1960
|
const principal = this.getPrincipalFromContext(ctx);
|
|
1824
1961
|
if (!principal) {
|
|
1825
|
-
range.text(
|
|
1962
|
+
range.text(await this.tForContext(ctx, "common:menu.no_telegram_identity_label"), async (innerCtx) => {
|
|
1826
1963
|
await innerCtx.answerCallbackQuery({
|
|
1827
|
-
text:
|
|
1964
|
+
text: await this.tForContext(innerCtx, "common:errors.missing_telegram_context"),
|
|
1828
1965
|
show_alert: true,
|
|
1829
1966
|
});
|
|
1830
1967
|
});
|
|
@@ -1832,9 +1969,9 @@ class TelegramTransport {
|
|
|
1832
1969
|
}
|
|
1833
1970
|
const sessionId = await this.bindingStore.getActiveSessionIdForPrincipal(principal);
|
|
1834
1971
|
if (!sessionId) {
|
|
1835
|
-
range.text(
|
|
1972
|
+
range.text(await this.tForContext(ctx, "common:menu.no_active_session_label"), async (innerCtx) => {
|
|
1836
1973
|
await innerCtx.answerCallbackQuery({
|
|
1837
|
-
text:
|
|
1974
|
+
text: await this.tForContext(innerCtx, "common:errors.no_active_session"),
|
|
1838
1975
|
show_alert: true,
|
|
1839
1976
|
});
|
|
1840
1977
|
});
|
|
@@ -1842,9 +1979,9 @@ class TelegramTransport {
|
|
|
1842
1979
|
}
|
|
1843
1980
|
const inboxMessages = await this.inboxStore.listInboxMessages(sessionId, 10);
|
|
1844
1981
|
if (inboxMessages.length === 0) {
|
|
1845
|
-
range.text(
|
|
1982
|
+
range.text(await this.tForContext(ctx, "menu:inbox.labels.empty"), async (innerCtx) => {
|
|
1846
1983
|
await innerCtx.answerCallbackQuery({
|
|
1847
|
-
text:
|
|
1984
|
+
text: await this.tForContext(innerCtx, "menu:inbox.actions.empty"),
|
|
1848
1985
|
show_alert: false,
|
|
1849
1986
|
});
|
|
1850
1987
|
});
|
|
@@ -1862,12 +1999,16 @@ class TelegramTransport {
|
|
|
1862
1999
|
}
|
|
1863
2000
|
return range;
|
|
1864
2001
|
})
|
|
1865
|
-
.text(
|
|
1866
|
-
await ctx.answerCallbackQuery({
|
|
2002
|
+
.text(async (ctx) => this.tForContext(ctx, "common:menu.refresh"), async (ctx) => {
|
|
2003
|
+
await ctx.answerCallbackQuery({
|
|
2004
|
+
text: await this.tForContext(ctx, "menu:inbox.actions.refreshed"),
|
|
2005
|
+
});
|
|
1867
2006
|
await this.showInboxMenu(ctx);
|
|
1868
2007
|
})
|
|
1869
|
-
.text(
|
|
1870
|
-
await ctx.answerCallbackQuery({
|
|
2008
|
+
.text(async (ctx) => this.tForContext(ctx, "common:menu.back"), async (ctx) => {
|
|
2009
|
+
await ctx.answerCallbackQuery({
|
|
2010
|
+
text: await this.tForContext(ctx, "menu:local.actions.back_to_session_menu"),
|
|
2011
|
+
});
|
|
1871
2012
|
await this.showMainMenu(ctx);
|
|
1872
2013
|
});
|
|
1873
2014
|
}
|
|
@@ -1880,9 +2021,9 @@ class TelegramTransport {
|
|
|
1880
2021
|
const range = new menu_1.MenuRange();
|
|
1881
2022
|
const principal = this.getPrincipalFromContext(ctx);
|
|
1882
2023
|
if (!principal) {
|
|
1883
|
-
range.text(
|
|
2024
|
+
range.text(await this.tForContext(ctx, "common:menu.no_telegram_identity_label"), async (innerCtx) => {
|
|
1884
2025
|
await innerCtx.answerCallbackQuery({
|
|
1885
|
-
text:
|
|
2026
|
+
text: await this.tForContext(innerCtx, "common:errors.missing_telegram_context"),
|
|
1886
2027
|
show_alert: true,
|
|
1887
2028
|
});
|
|
1888
2029
|
});
|
|
@@ -1890,9 +2031,9 @@ class TelegramTransport {
|
|
|
1890
2031
|
}
|
|
1891
2032
|
const sessionId = await this.bindingStore.getActiveSessionIdForPrincipal(principal);
|
|
1892
2033
|
if (!sessionId) {
|
|
1893
|
-
range.text(
|
|
2034
|
+
range.text(await this.tForContext(ctx, "common:menu.no_active_session_label"), async (innerCtx) => {
|
|
1894
2035
|
await innerCtx.answerCallbackQuery({
|
|
1895
|
-
text:
|
|
2036
|
+
text: await this.tForContext(innerCtx, "common:errors.no_active_session"),
|
|
1896
2037
|
show_alert: true,
|
|
1897
2038
|
});
|
|
1898
2039
|
});
|
|
@@ -1900,9 +2041,9 @@ class TelegramTransport {
|
|
|
1900
2041
|
}
|
|
1901
2042
|
const entries = await this.listActiveSessionStorageEntries(sessionId);
|
|
1902
2043
|
if (entries.length === 0) {
|
|
1903
|
-
range.text(
|
|
2044
|
+
range.text(await this.tForContext(ctx, "menu:storage.labels.empty"), async (innerCtx) => {
|
|
1904
2045
|
await innerCtx.answerCallbackQuery({
|
|
1905
|
-
text:
|
|
2046
|
+
text: await this.tForContext(innerCtx, "menu:storage.actions.empty"),
|
|
1906
2047
|
});
|
|
1907
2048
|
});
|
|
1908
2049
|
return range;
|
|
@@ -1919,12 +2060,16 @@ class TelegramTransport {
|
|
|
1919
2060
|
}
|
|
1920
2061
|
return range;
|
|
1921
2062
|
})
|
|
1922
|
-
.text(
|
|
1923
|
-
await ctx.answerCallbackQuery({
|
|
2063
|
+
.text(async (ctx) => this.tForContext(ctx, "common:menu.refresh"), async (ctx) => {
|
|
2064
|
+
await ctx.answerCallbackQuery({
|
|
2065
|
+
text: await this.tForContext(ctx, "menu:storage.actions.refreshed"),
|
|
2066
|
+
});
|
|
1924
2067
|
await this.showStorageMenu(ctx);
|
|
1925
2068
|
})
|
|
1926
|
-
.text(
|
|
1927
|
-
await ctx.answerCallbackQuery({
|
|
2069
|
+
.text(async (ctx) => this.tForContext(ctx, "common:menu.back"), async (ctx) => {
|
|
2070
|
+
await ctx.answerCallbackQuery({
|
|
2071
|
+
text: await this.tForContext(ctx, "menu:local.actions.back_to_session_menu"),
|
|
2072
|
+
});
|
|
1928
2073
|
await this.showMainMenu(ctx);
|
|
1929
2074
|
});
|
|
1930
2075
|
}
|
|
@@ -1937,9 +2082,9 @@ class TelegramTransport {
|
|
|
1937
2082
|
const range = new menu_1.MenuRange();
|
|
1938
2083
|
const principal = this.getPrincipalFromContext(ctx);
|
|
1939
2084
|
if (!principal) {
|
|
1940
|
-
range.text(
|
|
2085
|
+
range.text(await this.tForContext(ctx, "common:menu.no_telegram_identity_label"), async (innerCtx) => {
|
|
1941
2086
|
await innerCtx.answerCallbackQuery({
|
|
1942
|
-
text:
|
|
2087
|
+
text: await this.tForContext(innerCtx, "common:errors.missing_telegram_context"),
|
|
1943
2088
|
show_alert: true,
|
|
1944
2089
|
});
|
|
1945
2090
|
});
|
|
@@ -1947,9 +2092,9 @@ class TelegramTransport {
|
|
|
1947
2092
|
}
|
|
1948
2093
|
const sessionId = await this.bindingStore.getActiveSessionIdForPrincipal(principal);
|
|
1949
2094
|
if (!sessionId) {
|
|
1950
|
-
range.text(
|
|
2095
|
+
range.text(await this.tForContext(ctx, "common:menu.no_active_session_label"), async (innerCtx) => {
|
|
1951
2096
|
await innerCtx.answerCallbackQuery({
|
|
1952
|
-
text:
|
|
2097
|
+
text: await this.tForContext(innerCtx, "common:errors.no_active_session"),
|
|
1953
2098
|
show_alert: true,
|
|
1954
2099
|
});
|
|
1955
2100
|
});
|
|
@@ -1957,9 +2102,9 @@ class TelegramTransport {
|
|
|
1957
2102
|
}
|
|
1958
2103
|
const filePaths = await this.listActiveSessionScreenshots(sessionId);
|
|
1959
2104
|
if (filePaths.length === 0) {
|
|
1960
|
-
range.text(
|
|
2105
|
+
range.text(await this.tForContext(ctx, "menu:screenshots.labels.empty"), async (innerCtx) => {
|
|
1961
2106
|
await innerCtx.answerCallbackQuery({
|
|
1962
|
-
text:
|
|
2107
|
+
text: await this.tForContext(innerCtx, "menu:screenshots.actions.empty"),
|
|
1963
2108
|
});
|
|
1964
2109
|
});
|
|
1965
2110
|
return range;
|
|
@@ -1976,12 +2121,16 @@ class TelegramTransport {
|
|
|
1976
2121
|
}
|
|
1977
2122
|
return range;
|
|
1978
2123
|
})
|
|
1979
|
-
.text(
|
|
1980
|
-
await ctx.answerCallbackQuery({
|
|
2124
|
+
.text(async (ctx) => this.tForContext(ctx, "common:menu.refresh"), async (ctx) => {
|
|
2125
|
+
await ctx.answerCallbackQuery({
|
|
2126
|
+
text: await this.tForContext(ctx, "menu:screenshots.actions.refreshed"),
|
|
2127
|
+
});
|
|
1981
2128
|
await this.showScreenshotsMenu(ctx);
|
|
1982
2129
|
})
|
|
1983
|
-
.text(
|
|
1984
|
-
await ctx.answerCallbackQuery({
|
|
2130
|
+
.text(async (ctx) => this.tForContext(ctx, "common:menu.back"), async (ctx) => {
|
|
2131
|
+
await ctx.answerCallbackQuery({
|
|
2132
|
+
text: await this.tForContext(ctx, "menu:browser.actions.back_to_browser_menu"),
|
|
2133
|
+
});
|
|
1985
2134
|
await this.showBrowserMenu(ctx);
|
|
1986
2135
|
});
|
|
1987
2136
|
}
|
|
@@ -1995,9 +2144,9 @@ class TelegramTransport {
|
|
|
1995
2144
|
try {
|
|
1996
2145
|
const principal = this.getPrincipalFromContext(ctx);
|
|
1997
2146
|
if (!principal) {
|
|
1998
|
-
range.text(
|
|
2147
|
+
range.text(await this.tForContext(ctx, "common:menu.no_telegram_identity_label"), async (innerCtx) => {
|
|
1999
2148
|
await innerCtx.answerCallbackQuery({
|
|
2000
|
-
text:
|
|
2149
|
+
text: await this.tForContext(innerCtx, "common:errors.missing_telegram_context"),
|
|
2001
2150
|
show_alert: true,
|
|
2002
2151
|
});
|
|
2003
2152
|
});
|
|
@@ -2006,9 +2155,9 @@ class TelegramTransport {
|
|
|
2006
2155
|
const activeSessionId = await this.bindingStore.getActiveSessionIdForPrincipal(principal);
|
|
2007
2156
|
const sessionIds = (await this.bindingStore.listBoundSessionIdsForPrincipal(principal)).sort();
|
|
2008
2157
|
if (sessionIds.length === 0) {
|
|
2009
|
-
range.text(
|
|
2158
|
+
range.text(await this.tForContext(ctx, "menu:sessions.labels.no_linked_sessions"), async (innerCtx) => {
|
|
2010
2159
|
await innerCtx.answerCallbackQuery({
|
|
2011
|
-
text:
|
|
2160
|
+
text: await this.tForContext(innerCtx, "menu:sessions.actions.no_linked_sessions"),
|
|
2012
2161
|
show_alert: true,
|
|
2013
2162
|
});
|
|
2014
2163
|
});
|
|
@@ -2046,21 +2195,25 @@ class TelegramTransport {
|
|
|
2046
2195
|
userId: ctx.from?.id,
|
|
2047
2196
|
error: error instanceof Error ? (error.stack ?? error.message) : String(error),
|
|
2048
2197
|
});
|
|
2049
|
-
range.text(
|
|
2198
|
+
range.text(await this.tForContext(ctx, "menu:sessions.labels.unavailable"), async (innerCtx) => {
|
|
2050
2199
|
await innerCtx.answerCallbackQuery({
|
|
2051
|
-
text: "
|
|
2200
|
+
text: await this.tForContext(innerCtx, "menu:sessions.actions.unavailable"),
|
|
2052
2201
|
show_alert: true,
|
|
2053
2202
|
});
|
|
2054
2203
|
});
|
|
2055
2204
|
return range;
|
|
2056
2205
|
}
|
|
2057
2206
|
})
|
|
2058
|
-
.text(
|
|
2059
|
-
await ctx.answerCallbackQuery({
|
|
2207
|
+
.text(async (ctx) => this.tForContext(ctx, "common:menu.refresh"), async (ctx) => {
|
|
2208
|
+
await ctx.answerCallbackQuery({
|
|
2209
|
+
text: await this.tForContext(ctx, "menu:sessions.actions.refreshed"),
|
|
2210
|
+
});
|
|
2060
2211
|
await this.showSessionsMenu(ctx);
|
|
2061
2212
|
})
|
|
2062
|
-
.text(
|
|
2063
|
-
await ctx.answerCallbackQuery({
|
|
2213
|
+
.text(async (ctx) => this.tForContext(ctx, "menu:sessions.labels.tools"), async (ctx) => {
|
|
2214
|
+
await ctx.answerCallbackQuery({
|
|
2215
|
+
text: await this.tForContext(ctx, "menu:sessions.actions.open_tools"),
|
|
2216
|
+
});
|
|
2064
2217
|
await this.showDeveloperMenu(ctx);
|
|
2065
2218
|
});
|
|
2066
2219
|
}
|
|
@@ -2070,13 +2223,15 @@ class TelegramTransport {
|
|
|
2070
2223
|
...this.createMenuOptions((ctx) => this.showInboxMenu(ctx)),
|
|
2071
2224
|
})
|
|
2072
2225
|
.text({
|
|
2073
|
-
text:
|
|
2226
|
+
text: async (ctx) => this.tForContext(ctx, "common:menu.delete"),
|
|
2074
2227
|
payload: (ctx) => readMenuPayloadKey(ctx) ?? "missing",
|
|
2075
2228
|
}, async (ctx) => {
|
|
2076
2229
|
await this.handleInboxMessageDelete(ctx);
|
|
2077
2230
|
})
|
|
2078
|
-
.text(
|
|
2079
|
-
await ctx.answerCallbackQuery({
|
|
2231
|
+
.text(async (ctx) => this.tForContext(ctx, "common:menu.close"), async (ctx) => {
|
|
2232
|
+
await ctx.answerCallbackQuery({
|
|
2233
|
+
text: await this.tForContext(ctx, "common:menu.close"),
|
|
2234
|
+
});
|
|
2080
2235
|
await ctx.deleteMessage();
|
|
2081
2236
|
});
|
|
2082
2237
|
}
|
|
@@ -2086,20 +2241,22 @@ class TelegramTransport {
|
|
|
2086
2241
|
...this.createMenuOptions((ctx) => this.showStorageMenu(ctx)),
|
|
2087
2242
|
})
|
|
2088
2243
|
.text({
|
|
2089
|
-
text:
|
|
2244
|
+
text: async (ctx) => this.tForContext(ctx, "common:menu.get"),
|
|
2090
2245
|
payload: (ctx) => readMenuPayloadKey(ctx) ?? "missing",
|
|
2091
2246
|
}, async (ctx) => {
|
|
2092
2247
|
await this.handleStorageGet(ctx);
|
|
2093
2248
|
})
|
|
2094
2249
|
.text({
|
|
2095
|
-
text:
|
|
2250
|
+
text: async (ctx) => this.tForContext(ctx, "menu:storage.buttons.delete"),
|
|
2096
2251
|
payload: (ctx) => readMenuPayloadKey(ctx) ?? "missing",
|
|
2097
2252
|
}, async (ctx) => {
|
|
2098
2253
|
await this.handleStorageDelete(ctx);
|
|
2099
2254
|
})
|
|
2100
2255
|
.row()
|
|
2101
|
-
.text(
|
|
2102
|
-
await ctx.answerCallbackQuery({
|
|
2256
|
+
.text(async (ctx) => this.tForContext(ctx, "common:menu.back"), async (ctx) => {
|
|
2257
|
+
await ctx.answerCallbackQuery({
|
|
2258
|
+
text: await this.tForContext(ctx, "menu:storage.actions.back_to_storage"),
|
|
2259
|
+
});
|
|
2103
2260
|
await this.showStorageMenu(ctx);
|
|
2104
2261
|
});
|
|
2105
2262
|
}
|
|
@@ -2109,20 +2266,22 @@ class TelegramTransport {
|
|
|
2109
2266
|
...this.createMenuOptions((ctx) => this.showScreenshotsMenu(ctx)),
|
|
2110
2267
|
})
|
|
2111
2268
|
.text({
|
|
2112
|
-
text:
|
|
2269
|
+
text: async (ctx) => this.tForContext(ctx, "menu:storage.buttons.get"),
|
|
2113
2270
|
payload: (ctx) => readMenuPayloadKey(ctx) ?? "missing",
|
|
2114
2271
|
}, async (ctx) => {
|
|
2115
2272
|
await this.handleScreenshotGet(ctx);
|
|
2116
2273
|
})
|
|
2117
2274
|
.text({
|
|
2118
|
-
text:
|
|
2275
|
+
text: async (ctx) => this.tForContext(ctx, "menu:storage.buttons.delete"),
|
|
2119
2276
|
payload: (ctx) => readMenuPayloadKey(ctx) ?? "missing",
|
|
2120
2277
|
}, async (ctx) => {
|
|
2121
2278
|
await this.handleScreenshotDelete(ctx);
|
|
2122
2279
|
})
|
|
2123
2280
|
.row()
|
|
2124
|
-
.text(
|
|
2125
|
-
await ctx.answerCallbackQuery({
|
|
2281
|
+
.text(async (ctx) => this.tForContext(ctx, "common:menu.back"), async (ctx) => {
|
|
2282
|
+
await ctx.answerCallbackQuery({
|
|
2283
|
+
text: await this.tForContext(ctx, "menu:screenshots.actions.back_to_screenshots"),
|
|
2284
|
+
});
|
|
2126
2285
|
await this.showScreenshotsMenu(ctx);
|
|
2127
2286
|
});
|
|
2128
2287
|
}
|
|
@@ -2468,8 +2627,12 @@ class TelegramTransport {
|
|
|
2468
2627
|
});
|
|
2469
2628
|
}
|
|
2470
2629
|
await this.replyText(ctx, currentTarget.projectUuid
|
|
2471
|
-
?
|
|
2472
|
-
|
|
2630
|
+
? await this.tForContext(ctx, "menu:handoff.uploaded_to_session", {
|
|
2631
|
+
label: currentTarget.targetSessionLabel,
|
|
2632
|
+
})
|
|
2633
|
+
: await this.tForContext(ctx, "menu:handoff.uploaded_to_partner", {
|
|
2634
|
+
label: currentTarget.targetSessionLabel,
|
|
2635
|
+
}), {
|
|
2473
2636
|
kind: "inbox",
|
|
2474
2637
|
sessionId,
|
|
2475
2638
|
}, { reply_markup: this.mainMenu });
|
|
@@ -2493,11 +2656,21 @@ class TelegramTransport {
|
|
|
2493
2656
|
});
|
|
2494
2657
|
await this.replyText(ctx, session?.label
|
|
2495
2658
|
? attachments.length === 1
|
|
2496
|
-
?
|
|
2497
|
-
|
|
2659
|
+
? await this.tForContext(ctx, "menu:handoff.delivered_one", {
|
|
2660
|
+
label: session.label,
|
|
2661
|
+
})
|
|
2662
|
+
: await this.tForContext(ctx, "menu:handoff.delivered_many", {
|
|
2663
|
+
label: session.label,
|
|
2664
|
+
count: attachments.length,
|
|
2665
|
+
})
|
|
2498
2666
|
: attachments.length === 1
|
|
2499
|
-
?
|
|
2500
|
-
|
|
2667
|
+
? await this.tForContext(ctx, "menu:handoff.delivered_one", {
|
|
2668
|
+
label: sessionId,
|
|
2669
|
+
})
|
|
2670
|
+
: await this.tForContext(ctx, "menu:handoff.delivered_many", {
|
|
2671
|
+
label: sessionId,
|
|
2672
|
+
count: attachments.length,
|
|
2673
|
+
}), {
|
|
2501
2674
|
kind: "inbox",
|
|
2502
2675
|
sessionId,
|
|
2503
2676
|
}, { reply_markup: this.mainMenu });
|
|
@@ -2533,6 +2706,12 @@ class TelegramTransport {
|
|
|
2533
2706
|
: String(error),
|
|
2534
2707
|
};
|
|
2535
2708
|
if ((0, client_1.isTmuxUnavailableError)(error)) {
|
|
2709
|
+
void this.sessionStore.getSession(sessionId).then((session) => {
|
|
2710
|
+
if (!session?.tmuxTarget) {
|
|
2711
|
+
return;
|
|
2712
|
+
}
|
|
2713
|
+
return this.notifyTmuxUnavailable(sessionId, session, error);
|
|
2714
|
+
});
|
|
2536
2715
|
this.logger.warn("tmux nudge skipped because tmux is unavailable", payload);
|
|
2537
2716
|
return;
|
|
2538
2717
|
}
|
|
@@ -2611,7 +2790,11 @@ class TelegramTransport {
|
|
|
2611
2790
|
await this.sessionStore.setSession({
|
|
2612
2791
|
...session,
|
|
2613
2792
|
tmuxTarget,
|
|
2614
|
-
...(tmuxTarget
|
|
2793
|
+
...(tmuxTarget.startsWith("%")
|
|
2794
|
+
? { tmuxPaneId: tmuxTarget }
|
|
2795
|
+
: session.tmuxPaneId
|
|
2796
|
+
? { tmuxPaneId: session.tmuxPaneId }
|
|
2797
|
+
: {}),
|
|
2615
2798
|
lastTmuxNudgeAt,
|
|
2616
2799
|
});
|
|
2617
2800
|
this.tmuxNudgeFailureNoticeAt.delete(sessionId);
|
|
@@ -2669,6 +2852,7 @@ class TelegramTransport {
|
|
|
2669
2852
|
const sessionLabel = session.label ?? sessionId;
|
|
2670
2853
|
const tmuxTarget = session.tmuxTarget ?? "unknown";
|
|
2671
2854
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
2855
|
+
const locale = await this.resolveLocaleForTelegramUserId(binding.telegramUserId);
|
|
2672
2856
|
try {
|
|
2673
2857
|
await this.sendNotification({
|
|
2674
2858
|
sessionId,
|
|
@@ -2678,11 +2862,17 @@ class TelegramTransport {
|
|
|
2678
2862
|
telegramUserId: binding.telegramUserId,
|
|
2679
2863
|
},
|
|
2680
2864
|
message: [
|
|
2681
|
-
|
|
2682
|
-
|
|
2683
|
-
|
|
2684
|
-
|
|
2685
|
-
|
|
2865
|
+
this.t(locale, "menu:notices.tmux.target_invalid_title", {
|
|
2866
|
+
sessionName: sessionLabel,
|
|
2867
|
+
}),
|
|
2868
|
+
this.t(locale, "menu:notices.tmux.target_invalid_target", {
|
|
2869
|
+
tmuxTarget,
|
|
2870
|
+
}),
|
|
2871
|
+
this.t(locale, "menu:system.error_prefix", {
|
|
2872
|
+
message: errorMessage,
|
|
2873
|
+
}),
|
|
2874
|
+
this.t(locale, "menu:system.tmux_recreated_hint"),
|
|
2875
|
+
this.t(locale, "menu:notices.tmux.target_invalid_action"),
|
|
2686
2876
|
].join("\n"),
|
|
2687
2877
|
});
|
|
2688
2878
|
}
|
|
@@ -2698,6 +2888,58 @@ class TelegramTransport {
|
|
|
2698
2888
|
});
|
|
2699
2889
|
}
|
|
2700
2890
|
}
|
|
2891
|
+
async notifyTmuxUnavailable(sessionId, session, error) {
|
|
2892
|
+
const binding = await this.bindingStore.getBinding(sessionId);
|
|
2893
|
+
if (!binding) {
|
|
2894
|
+
return;
|
|
2895
|
+
}
|
|
2896
|
+
const nowMs = Date.now();
|
|
2897
|
+
const lastNoticeAt = this.tmuxNudgeFailureNoticeAt.get(sessionId);
|
|
2898
|
+
if (lastNoticeAt &&
|
|
2899
|
+
nowMs - lastNoticeAt < TMUX_NUDGE_FAILURE_NOTICE_COOLDOWN_MS) {
|
|
2900
|
+
return;
|
|
2901
|
+
}
|
|
2902
|
+
this.tmuxNudgeFailureNoticeAt.set(sessionId, nowMs);
|
|
2903
|
+
const sessionLabel = session.label ?? sessionId;
|
|
2904
|
+
const tmuxTarget = session.tmuxTarget ?? "unknown";
|
|
2905
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
2906
|
+
const locale = await this.resolveLocaleForTelegramUserId(binding.telegramUserId);
|
|
2907
|
+
try {
|
|
2908
|
+
await this.sendNotification({
|
|
2909
|
+
sessionId,
|
|
2910
|
+
sessionLabel: "TellyMCP",
|
|
2911
|
+
recipient: {
|
|
2912
|
+
telegramChatId: binding.telegramChatId,
|
|
2913
|
+
telegramUserId: binding.telegramUserId,
|
|
2914
|
+
},
|
|
2915
|
+
message: [
|
|
2916
|
+
this.t(locale, "menu:notices.tmux.unavailable_title", {
|
|
2917
|
+
sessionName: sessionLabel,
|
|
2918
|
+
}),
|
|
2919
|
+
this.t(locale, "menu:notices.tmux.unavailable_body"),
|
|
2920
|
+
this.t(locale, "menu:notices.tmux.unavailable_target", {
|
|
2921
|
+
tmuxTarget,
|
|
2922
|
+
}),
|
|
2923
|
+
this.t(locale, "menu:system.error_prefix", {
|
|
2924
|
+
message: errorMessage,
|
|
2925
|
+
}),
|
|
2926
|
+
this.t(locale, "menu:notices.tmux.unavailable_reason"),
|
|
2927
|
+
this.t(locale, "menu:notices.tmux.unavailable_action"),
|
|
2928
|
+
].join("\n"),
|
|
2929
|
+
});
|
|
2930
|
+
}
|
|
2931
|
+
catch (notifyError) {
|
|
2932
|
+
this.logger.warn("Failed to deliver tmux unavailable notification", {
|
|
2933
|
+
sessionId,
|
|
2934
|
+
tmuxTarget,
|
|
2935
|
+
telegramChatId: binding.telegramChatId,
|
|
2936
|
+
telegramUserId: binding.telegramUserId,
|
|
2937
|
+
notifyError: notifyError instanceof Error
|
|
2938
|
+
? (notifyError.stack ?? notifyError.message)
|
|
2939
|
+
: String(notifyError),
|
|
2940
|
+
});
|
|
2941
|
+
}
|
|
2942
|
+
}
|
|
2701
2943
|
async sendTypingForSession(sessionId) {
|
|
2702
2944
|
const binding = await this.bindingStore.getBinding(sessionId);
|
|
2703
2945
|
if (!binding) {
|
|
@@ -2742,13 +2984,14 @@ class TelegramTransport {
|
|
|
2742
2984
|
await this.renderMenuHtmlScreen(ctx, intro ? `${intro}\n\n${text}` : text, { kind: "menu" }, this.mainMenu);
|
|
2743
2985
|
}
|
|
2744
2986
|
async buildMainMenuText(ctx) {
|
|
2987
|
+
const locale = await this.resolveLocaleForContext(ctx);
|
|
2745
2988
|
const principal = this.getPrincipalFromContext(ctx);
|
|
2746
2989
|
if (!principal) {
|
|
2747
|
-
return
|
|
2990
|
+
return this.t(locale, "common:errors.no_telegram_identity");
|
|
2748
2991
|
}
|
|
2749
2992
|
const activeSessionId = await this.bindingStore.getActiveSessionIdForPrincipal(principal);
|
|
2750
2993
|
if (!activeSessionId) {
|
|
2751
|
-
return
|
|
2994
|
+
return this.t(locale, "common:errors.no_active_session");
|
|
2752
2995
|
}
|
|
2753
2996
|
const session = await this.sessionStore.getSession(activeSessionId);
|
|
2754
2997
|
const inboxCount = await this.inboxStore.countInboxMessages(activeSessionId);
|
|
@@ -2760,80 +3003,89 @@ class TelegramTransport {
|
|
|
2760
3003
|
? await this.sessionStore.getSession(session.linkedSessionId)
|
|
2761
3004
|
: null;
|
|
2762
3005
|
return [
|
|
2763
|
-
|
|
3006
|
+
this.t(locale, "menu:main.screen.title", { sessionName }),
|
|
2764
3007
|
"",
|
|
2765
|
-
|
|
2766
|
-
...(projectName
|
|
3008
|
+
this.t(locale, "menu:main.screen.inbox_messages", { count: inboxCount }),
|
|
3009
|
+
...(projectName
|
|
3010
|
+
? [this.t(locale, "menu:main.screen.project", { projectName })]
|
|
3011
|
+
: []),
|
|
2767
3012
|
...(session?.linkedSessionId
|
|
2768
3013
|
? [
|
|
2769
|
-
|
|
3014
|
+
this.t(locale, "menu:main.screen.partner", {
|
|
3015
|
+
partnerName: escapeHtml(linkedSession?.label ?? session.linkedSessionId),
|
|
3016
|
+
}),
|
|
2770
3017
|
"",
|
|
2771
|
-
|
|
3018
|
+
this.t(locale, "menu:main.screen.partner_hint"),
|
|
2772
3019
|
]
|
|
2773
|
-
: ["", "
|
|
3020
|
+
: ["", this.t(locale, "menu:main.screen.link_hint")]),
|
|
2774
3021
|
].join("\n");
|
|
2775
3022
|
}
|
|
2776
|
-
async getTmuxStatusLine() {
|
|
2777
|
-
return "
|
|
3023
|
+
async getTmuxStatusLine(locale) {
|
|
3024
|
+
return this.t(locale, "menu:main.screen.tmux_mode_direct");
|
|
2778
3025
|
}
|
|
2779
3026
|
async buildMainMenuFingerprint(ctx) {
|
|
3027
|
+
const locale = await this.resolveLocaleForContext(ctx);
|
|
2780
3028
|
const principal = this.getPrincipalFromContext(ctx);
|
|
2781
3029
|
if (!principal) {
|
|
2782
|
-
return
|
|
3030
|
+
return `${locale}:no-principal`;
|
|
2783
3031
|
}
|
|
2784
3032
|
const sessionId = await this.bindingStore.getActiveSessionIdForPrincipal(principal);
|
|
2785
3033
|
if (!sessionId) {
|
|
2786
|
-
return
|
|
3034
|
+
return `${locale}:no-active-session`;
|
|
2787
3035
|
}
|
|
2788
3036
|
const count = await this.inboxStore.countInboxMessages(sessionId);
|
|
2789
3037
|
const session = await this.sessionStore.getSession(sessionId);
|
|
2790
|
-
return `${sessionId}:${count}:${session?.linkedSessionId ?? "none"}`;
|
|
3038
|
+
return `${locale}:${sessionId}:${count}:${session?.linkedSessionId ?? "none"}`;
|
|
2791
3039
|
}
|
|
2792
3040
|
async buildInboxFingerprint(ctx) {
|
|
3041
|
+
const locale = await this.resolveLocaleForContext(ctx);
|
|
2793
3042
|
const principal = this.getPrincipalFromContext(ctx);
|
|
2794
3043
|
if (!principal) {
|
|
2795
|
-
return
|
|
3044
|
+
return `${locale}:no-principal`;
|
|
2796
3045
|
}
|
|
2797
3046
|
const sessionId = await this.bindingStore.getActiveSessionIdForPrincipal(principal);
|
|
2798
3047
|
if (!sessionId) {
|
|
2799
|
-
return
|
|
3048
|
+
return `${locale}:no-active-session`;
|
|
2800
3049
|
}
|
|
2801
3050
|
const messages = await this.inboxStore.listInboxMessages(sessionId, 10);
|
|
2802
|
-
return `${sessionId}:${messages.map((message) => message.id).join(",")}`;
|
|
3051
|
+
return `${locale}:${sessionId}:${messages.map((message) => message.id).join(",")}`;
|
|
2803
3052
|
}
|
|
2804
3053
|
async buildStorageFingerprint(ctx) {
|
|
3054
|
+
const locale = await this.resolveLocaleForContext(ctx);
|
|
2805
3055
|
const principal = this.getPrincipalFromContext(ctx);
|
|
2806
3056
|
if (!principal) {
|
|
2807
|
-
return
|
|
3057
|
+
return `${locale}:no-principal`;
|
|
2808
3058
|
}
|
|
2809
3059
|
const sessionId = await this.bindingStore.getActiveSessionIdForPrincipal(principal);
|
|
2810
3060
|
if (!sessionId) {
|
|
2811
|
-
return
|
|
3061
|
+
return `${locale}:no-active-session`;
|
|
2812
3062
|
}
|
|
2813
3063
|
const entries = await this.listActiveSessionStorageEntries(sessionId);
|
|
2814
|
-
return `${sessionId}:${entries.map((entry) => entry.filePath).join(",")}`;
|
|
3064
|
+
return `${locale}:${sessionId}:${entries.map((entry) => entry.filePath).join(",")}`;
|
|
2815
3065
|
}
|
|
2816
3066
|
async buildScreenshotsFingerprint(ctx) {
|
|
3067
|
+
const locale = await this.resolveLocaleForContext(ctx);
|
|
2817
3068
|
const principal = this.getPrincipalFromContext(ctx);
|
|
2818
3069
|
if (!principal) {
|
|
2819
|
-
return
|
|
3070
|
+
return `${locale}:no-principal`;
|
|
2820
3071
|
}
|
|
2821
3072
|
const sessionId = await this.bindingStore.getActiveSessionIdForPrincipal(principal);
|
|
2822
3073
|
if (!sessionId) {
|
|
2823
|
-
return
|
|
3074
|
+
return `${locale}:no-active-session`;
|
|
2824
3075
|
}
|
|
2825
3076
|
const files = await this.listActiveSessionScreenshots(sessionId);
|
|
2826
|
-
return `${sessionId}:${files.join(",")}`;
|
|
3077
|
+
return `${locale}:${sessionId}:${files.join(",")}`;
|
|
2827
3078
|
}
|
|
2828
3079
|
async buildSessionsFingerprint(ctx) {
|
|
2829
3080
|
try {
|
|
3081
|
+
const locale = await this.resolveLocaleForContext(ctx);
|
|
2830
3082
|
const principal = this.getPrincipalFromContext(ctx);
|
|
2831
3083
|
if (!principal) {
|
|
2832
|
-
return
|
|
3084
|
+
return `${locale}:no-principal`;
|
|
2833
3085
|
}
|
|
2834
3086
|
const activeSessionId = await this.bindingStore.getActiveSessionIdForPrincipal(principal);
|
|
2835
3087
|
const sessionIds = (await this.bindingStore.listBoundSessionIdsForPrincipal(principal)).sort();
|
|
2836
|
-
return `${activeSessionId ?? "none"}:${sessionIds.join(",")}`;
|
|
3088
|
+
return `${locale}:${activeSessionId ?? "none"}:${sessionIds.join(",")}`;
|
|
2837
3089
|
}
|
|
2838
3090
|
catch (error) {
|
|
2839
3091
|
this.logger.warn("Failed to build Telegram sessions menu fingerprint", {
|
|
@@ -2845,61 +3097,71 @@ class TelegramTransport {
|
|
|
2845
3097
|
}
|
|
2846
3098
|
}
|
|
2847
3099
|
async buildLinkFingerprint(ctx) {
|
|
3100
|
+
const locale = await this.resolveLocaleForContext(ctx);
|
|
2848
3101
|
const principal = this.getPrincipalFromContext(ctx);
|
|
2849
3102
|
if (!principal) {
|
|
2850
|
-
return
|
|
3103
|
+
return `${locale}:no-principal`;
|
|
2851
3104
|
}
|
|
2852
3105
|
const activeSessionId = await this.bindingStore.getActiveSessionIdForPrincipal(principal);
|
|
2853
3106
|
if (!activeSessionId) {
|
|
2854
|
-
return
|
|
3107
|
+
return `${locale}:no-active-session`;
|
|
2855
3108
|
}
|
|
2856
3109
|
const session = await this.sessionStore.getSession(activeSessionId);
|
|
2857
3110
|
const sessionIds = (await this.bindingStore.listBoundSessionIdsForPrincipal(principal))
|
|
2858
3111
|
.filter((sessionId) => sessionId !== activeSessionId)
|
|
2859
3112
|
.sort();
|
|
2860
|
-
return `${activeSessionId}:${session?.linkedSessionId ?? "none"}:${sessionIds.join(",")}`;
|
|
3113
|
+
return `${locale}:${activeSessionId}:${session?.linkedSessionId ?? "none"}:${sessionIds.join(",")}`;
|
|
2861
3114
|
}
|
|
2862
3115
|
async buildInboxButtonLabel(ctx) {
|
|
3116
|
+
const locale = await this.resolveLocaleForContext(ctx);
|
|
2863
3117
|
const principal = this.getPrincipalFromContext(ctx);
|
|
2864
3118
|
if (!principal) {
|
|
2865
|
-
return "
|
|
3119
|
+
return this.t(locale, "menu:inbox.button");
|
|
2866
3120
|
}
|
|
2867
3121
|
const sessionId = await this.bindingStore.getActiveSessionIdForPrincipal(principal);
|
|
2868
3122
|
if (!sessionId) {
|
|
2869
|
-
return
|
|
3123
|
+
return this.t(locale, "menu:inbox.button");
|
|
2870
3124
|
}
|
|
2871
3125
|
const count = await this.inboxStore.countInboxMessages(sessionId);
|
|
2872
|
-
return count > 0
|
|
3126
|
+
return count > 0
|
|
3127
|
+
? this.t(locale, "menu:inbox.button_count", { count })
|
|
3128
|
+
: this.t(locale, "menu:inbox.button");
|
|
2873
3129
|
}
|
|
2874
3130
|
async buildScreenshotsButtonLabel(ctx) {
|
|
3131
|
+
const locale = await this.resolveLocaleForContext(ctx);
|
|
2875
3132
|
const principal = this.getPrincipalFromContext(ctx);
|
|
2876
3133
|
if (!principal) {
|
|
2877
|
-
return
|
|
3134
|
+
return this.t(locale, "menu:browser.buttons.screenshots");
|
|
2878
3135
|
}
|
|
2879
3136
|
const sessionId = await this.bindingStore.getActiveSessionIdForPrincipal(principal);
|
|
2880
3137
|
if (!sessionId) {
|
|
2881
|
-
return
|
|
3138
|
+
return this.t(locale, "menu:browser.buttons.screenshots");
|
|
2882
3139
|
}
|
|
2883
3140
|
const count = (await this.listActiveSessionScreenshots(sessionId)).length;
|
|
2884
|
-
return count > 0
|
|
3141
|
+
return count > 0
|
|
3142
|
+
? this.t(locale, "menu:browser.buttons.screenshots_count", { count })
|
|
3143
|
+
: this.t(locale, "menu:browser.buttons.screenshots");
|
|
2885
3144
|
}
|
|
2886
3145
|
async buildLinkButtonLabel(ctx) {
|
|
3146
|
+
const locale = await this.resolveLocaleForContext(ctx);
|
|
2887
3147
|
const principal = this.getPrincipalFromContext(ctx);
|
|
2888
3148
|
if (!principal) {
|
|
2889
|
-
return
|
|
3149
|
+
return this.t(locale, "menu:local.buttons.link");
|
|
2890
3150
|
}
|
|
2891
3151
|
const sessionId = await this.bindingStore.getActiveSessionIdForPrincipal(principal);
|
|
2892
3152
|
if (!sessionId) {
|
|
2893
|
-
return
|
|
3153
|
+
return this.t(locale, "menu:local.buttons.link");
|
|
2894
3154
|
}
|
|
2895
3155
|
const session = await this.sessionStore.getSession(sessionId);
|
|
2896
3156
|
if (!session?.linkedSessionId) {
|
|
2897
|
-
return
|
|
3157
|
+
return this.t(locale, "menu:local.buttons.link");
|
|
2898
3158
|
}
|
|
2899
3159
|
const linkedSession = await this.sessionStore.getSession(session.linkedSessionId);
|
|
2900
3160
|
return linkedSession?.label
|
|
2901
|
-
?
|
|
2902
|
-
|
|
3161
|
+
? this.t(locale, "menu:link.buttons.unlink_with_name", {
|
|
3162
|
+
sessionName: linkedSession.label,
|
|
3163
|
+
})
|
|
3164
|
+
: this.t(locale, "menu:link.buttons.unlink");
|
|
2903
3165
|
}
|
|
2904
3166
|
async createInboxMenuPayload(sessionId, messageId) {
|
|
2905
3167
|
const key = (0, ids_1.createMenuPayloadKey)();
|
|
@@ -3137,20 +3399,28 @@ class TelegramTransport {
|
|
|
3137
3399
|
(meta?.relativePath ? node_path_1.default.basename(meta.relativePath) : undefined) ||
|
|
3138
3400
|
node_path_1.default.basename(input.filePath);
|
|
3139
3401
|
const principalKey = buildPrincipalKey(principal);
|
|
3402
|
+
const locale = await this.resolveLocaleForContext(ctx);
|
|
3140
3403
|
await ctx.answerCallbackQuery({
|
|
3141
|
-
text: "
|
|
3404
|
+
text: this.t(locale, "menu:handoff.prompt_title"),
|
|
3142
3405
|
});
|
|
3143
3406
|
const sent = await this.replyText(ctx, [
|
|
3144
|
-
|
|
3407
|
+
this.t(locale, "menu:handoff.prompt_title"),
|
|
3145
3408
|
"",
|
|
3146
|
-
|
|
3147
|
-
|
|
3148
|
-
|
|
3409
|
+
this.t(locale, "menu:handoff.route", {
|
|
3410
|
+
sourceSessionName: session?.label ?? input.sessionId,
|
|
3411
|
+
targetSessionName: input.targetSessionLabel,
|
|
3412
|
+
}),
|
|
3413
|
+
this.t(locale, "menu:handoff.recipient", {
|
|
3414
|
+
label: input.targetSessionLabel,
|
|
3415
|
+
}),
|
|
3416
|
+
this.t(locale, "menu:handoff.file", {
|
|
3417
|
+
fileName,
|
|
3418
|
+
}),
|
|
3149
3419
|
"",
|
|
3150
|
-
|
|
3151
|
-
"
|
|
3420
|
+
this.t(locale, "menu:handoff.prompt_body"),
|
|
3421
|
+
this.t(locale, "menu:handoff.prompt_hint"),
|
|
3152
3422
|
].join("\n"), { kind: "menu", sessionId: input.sessionId }, {
|
|
3153
|
-
reply_markup: new grammy_1.InlineKeyboard().text("
|
|
3423
|
+
reply_markup: new grammy_1.InlineKeyboard().text(this.t(locale, "menu:handoff.cancel"), "file-handoff-cancel"),
|
|
3154
3424
|
});
|
|
3155
3425
|
this.pendingFileHandoffs.set(principalKey, {
|
|
3156
3426
|
sessionId: input.sessionId,
|
|
@@ -3164,10 +3434,11 @@ class TelegramTransport {
|
|
|
3164
3434
|
});
|
|
3165
3435
|
}
|
|
3166
3436
|
async handleLinkButton(ctx) {
|
|
3437
|
+
const locale = await this.resolveLocaleForContext(ctx);
|
|
3167
3438
|
const principal = this.getPrincipalFromContext(ctx);
|
|
3168
3439
|
if (!principal) {
|
|
3169
3440
|
await ctx.answerCallbackQuery({
|
|
3170
|
-
text:
|
|
3441
|
+
text: this.t(locale, "common:errors.no_telegram_identity"),
|
|
3171
3442
|
show_alert: true,
|
|
3172
3443
|
});
|
|
3173
3444
|
return;
|
|
@@ -3175,7 +3446,7 @@ class TelegramTransport {
|
|
|
3175
3446
|
const sessionId = await this.bindingStore.getActiveSessionIdForPrincipal(principal);
|
|
3176
3447
|
if (!sessionId) {
|
|
3177
3448
|
await ctx.answerCallbackQuery({
|
|
3178
|
-
text:
|
|
3449
|
+
text: await this.tForContext(ctx, "common:errors.no_active_session"),
|
|
3179
3450
|
show_alert: true,
|
|
3180
3451
|
});
|
|
3181
3452
|
return;
|
|
@@ -3183,18 +3454,23 @@ class TelegramTransport {
|
|
|
3183
3454
|
const session = await this.sessionStore.getSession(sessionId);
|
|
3184
3455
|
if (session?.linkedSessionId) {
|
|
3185
3456
|
await this.unlinkSessions(sessionId, session.linkedSessionId);
|
|
3186
|
-
await ctx.answerCallbackQuery({
|
|
3187
|
-
|
|
3457
|
+
await ctx.answerCallbackQuery({
|
|
3458
|
+
text: this.t(locale, "menu:link.actions.unlinked"),
|
|
3459
|
+
});
|
|
3460
|
+
await this.showMainMenu(ctx, this.t(locale, "menu:link.actions.unlinked"));
|
|
3188
3461
|
return;
|
|
3189
3462
|
}
|
|
3190
|
-
await ctx.answerCallbackQuery({
|
|
3463
|
+
await ctx.answerCallbackQuery({
|
|
3464
|
+
text: this.t(locale, "menu:link.actions.choose_partner"),
|
|
3465
|
+
});
|
|
3191
3466
|
await this.showLinkMenu(ctx);
|
|
3192
3467
|
}
|
|
3193
3468
|
async showPartnerEntryPoint(ctx) {
|
|
3469
|
+
const locale = await this.resolveLocaleForContext(ctx);
|
|
3194
3470
|
const principal = this.getPrincipalFromContext(ctx);
|
|
3195
3471
|
if (!principal) {
|
|
3196
3472
|
await ctx.answerCallbackQuery({
|
|
3197
|
-
text:
|
|
3473
|
+
text: this.t(locale, "common:errors.no_telegram_identity"),
|
|
3198
3474
|
show_alert: true,
|
|
3199
3475
|
});
|
|
3200
3476
|
return;
|
|
@@ -3202,7 +3478,7 @@ class TelegramTransport {
|
|
|
3202
3478
|
const sessionId = await this.bindingStore.getActiveSessionIdForPrincipal(principal);
|
|
3203
3479
|
if (!sessionId) {
|
|
3204
3480
|
await ctx.answerCallbackQuery({
|
|
3205
|
-
text:
|
|
3481
|
+
text: this.t(locale, "common:errors.no_active_session"),
|
|
3206
3482
|
show_alert: true,
|
|
3207
3483
|
});
|
|
3208
3484
|
return;
|
|
@@ -3210,19 +3486,22 @@ class TelegramTransport {
|
|
|
3210
3486
|
const session = await this.sessionStore.getSession(sessionId);
|
|
3211
3487
|
if (!session?.linkedSessionId) {
|
|
3212
3488
|
await ctx.answerCallbackQuery({
|
|
3213
|
-
text:
|
|
3489
|
+
text: await this.tForContext(ctx, "menu:partner.screen.use_link_first"),
|
|
3214
3490
|
show_alert: true,
|
|
3215
3491
|
});
|
|
3216
3492
|
return;
|
|
3217
3493
|
}
|
|
3218
|
-
await ctx.answerCallbackQuery({
|
|
3494
|
+
await ctx.answerCallbackQuery({
|
|
3495
|
+
text: await this.tForContext(ctx, "menu:partner.actions.open_partner_menu"),
|
|
3496
|
+
});
|
|
3219
3497
|
await this.showPartnerMenu(ctx);
|
|
3220
3498
|
}
|
|
3221
3499
|
async showPartnerFiles(ctx) {
|
|
3500
|
+
const locale = await this.resolveLocaleForContext(ctx);
|
|
3222
3501
|
const principal = this.getPrincipalFromContext(ctx);
|
|
3223
3502
|
if (!principal) {
|
|
3224
3503
|
await ctx.answerCallbackQuery({
|
|
3225
|
-
text:
|
|
3504
|
+
text: this.t(locale, "common:errors.no_telegram_identity"),
|
|
3226
3505
|
show_alert: true,
|
|
3227
3506
|
});
|
|
3228
3507
|
return;
|
|
@@ -3230,7 +3509,7 @@ class TelegramTransport {
|
|
|
3230
3509
|
const sessionId = await this.bindingStore.getActiveSessionIdForPrincipal(principal);
|
|
3231
3510
|
if (!sessionId) {
|
|
3232
3511
|
await ctx.answerCallbackQuery({
|
|
3233
|
-
text:
|
|
3512
|
+
text: this.t(locale, "common:errors.no_active_session"),
|
|
3234
3513
|
show_alert: true,
|
|
3235
3514
|
});
|
|
3236
3515
|
return;
|
|
@@ -3238,7 +3517,7 @@ class TelegramTransport {
|
|
|
3238
3517
|
const session = await this.sessionStore.getSession(sessionId);
|
|
3239
3518
|
if (!session?.linkedSessionId) {
|
|
3240
3519
|
await ctx.answerCallbackQuery({
|
|
3241
|
-
text:
|
|
3520
|
+
text: this.t(locale, "menu:partner.screen.use_link_first"),
|
|
3242
3521
|
show_alert: true,
|
|
3243
3522
|
});
|
|
3244
3523
|
return;
|
|
@@ -3246,13 +3525,15 @@ class TelegramTransport {
|
|
|
3246
3525
|
const linkedSession = await this.sessionStore.getSession(session.linkedSessionId);
|
|
3247
3526
|
const files = await this.listActiveSessionFiles(sessionId);
|
|
3248
3527
|
const lines = [
|
|
3249
|
-
|
|
3528
|
+
this.t(locale, "menu:handoff.choose_title"),
|
|
3250
3529
|
"",
|
|
3251
|
-
|
|
3530
|
+
this.t(locale, "menu:handoff.choose_recipient", {
|
|
3531
|
+
label: linkedSession?.label ?? session.linkedSessionId,
|
|
3532
|
+
}),
|
|
3252
3533
|
"",
|
|
3253
3534
|
files.length > 0
|
|
3254
|
-
?
|
|
3255
|
-
:
|
|
3535
|
+
? this.t(locale, "menu:handoff.choose_local")
|
|
3536
|
+
: this.t(locale, "menu:handoff.no_files"),
|
|
3256
3537
|
];
|
|
3257
3538
|
const keyboard = new grammy_1.InlineKeyboard();
|
|
3258
3539
|
for (const filePath of files) {
|
|
@@ -3261,7 +3542,7 @@ class TelegramTransport {
|
|
|
3261
3542
|
const payloadKey = await this.createPartnerFileTargetPayload(sessionId, session.linkedSessionId, linkedSession?.label ?? session.linkedSessionId, filePath);
|
|
3262
3543
|
keyboard.text(label, `partner-file-open:${payloadKey}`).row();
|
|
3263
3544
|
}
|
|
3264
|
-
keyboard.text(
|
|
3545
|
+
keyboard.text(await this.tForContext(ctx, "common:menu.back"), "partner-back");
|
|
3265
3546
|
const text = lines.join("\n");
|
|
3266
3547
|
if (ctx.callbackQuery?.message) {
|
|
3267
3548
|
await this.editText(ctx, text, { kind: "menu", sessionId }, { reply_markup: keyboard });
|
|
@@ -3270,18 +3551,22 @@ class TelegramTransport {
|
|
|
3270
3551
|
await this.replyText(ctx, text, { kind: "menu", sessionId }, { reply_markup: keyboard });
|
|
3271
3552
|
}
|
|
3272
3553
|
async showLocalEntryPoint(ctx) {
|
|
3273
|
-
await ctx.answerCallbackQuery({
|
|
3554
|
+
await ctx.answerCallbackQuery({
|
|
3555
|
+
text: await this.tForContext(ctx, "menu:local.actions.open_local"),
|
|
3556
|
+
});
|
|
3274
3557
|
await this.showLocalMenu(ctx);
|
|
3275
3558
|
}
|
|
3276
3559
|
async showProjectsEntryPoint(ctx) {
|
|
3277
3560
|
if (!this.config.distributed.gatewayPublicUrl) {
|
|
3278
3561
|
await ctx.answerCallbackQuery({
|
|
3279
|
-
text:
|
|
3562
|
+
text: await this.tForContext(ctx, "menu:collab.actions.gateway_only"),
|
|
3280
3563
|
show_alert: true,
|
|
3281
3564
|
});
|
|
3282
3565
|
return;
|
|
3283
3566
|
}
|
|
3284
|
-
await ctx.answerCallbackQuery({
|
|
3567
|
+
await ctx.answerCallbackQuery({
|
|
3568
|
+
text: await this.tForContext(ctx, "menu:collab.actions.open_collab"),
|
|
3569
|
+
});
|
|
3285
3570
|
await this.showProjectsMenu(ctx);
|
|
3286
3571
|
}
|
|
3287
3572
|
async handleLinkTargetSelect(ctx) {
|
|
@@ -3821,6 +4106,47 @@ class TelegramTransport {
|
|
|
3821
4106
|
telegramUserId: userId,
|
|
3822
4107
|
};
|
|
3823
4108
|
}
|
|
4109
|
+
async resolveLocaleForContext(ctx) {
|
|
4110
|
+
if (this.config?.telegram?.debugLanguage) {
|
|
4111
|
+
return (0, i18n_1.normalizeLocale)(this.config.telegram.debugLanguage);
|
|
4112
|
+
}
|
|
4113
|
+
const telegramUserId = ctx.from?.id;
|
|
4114
|
+
const telegramLanguageCode = ctx.from?.language_code;
|
|
4115
|
+
if (!telegramUserId) {
|
|
4116
|
+
return (0, i18n_1.normalizeLocale)(telegramLanguageCode);
|
|
4117
|
+
}
|
|
4118
|
+
const storedLocale = await this.localeStore?.getUserLocale?.(telegramUserId);
|
|
4119
|
+
if (storedLocale) {
|
|
4120
|
+
return (0, i18n_1.normalizeLocale)(storedLocale);
|
|
4121
|
+
}
|
|
4122
|
+
const detectedLocale = (0, i18n_1.normalizeLocale)(telegramLanguageCode);
|
|
4123
|
+
await this.localeStore?.setUserLocale?.(telegramUserId, detectedLocale);
|
|
4124
|
+
return detectedLocale;
|
|
4125
|
+
}
|
|
4126
|
+
async resolveLocaleForTelegramUserId(telegramUserId, telegramLanguageCode) {
|
|
4127
|
+
if (this.config?.telegram?.debugLanguage) {
|
|
4128
|
+
return (0, i18n_1.normalizeLocale)(this.config.telegram.debugLanguage);
|
|
4129
|
+
}
|
|
4130
|
+
if (!telegramUserId) {
|
|
4131
|
+
return (0, i18n_1.normalizeLocale)(telegramLanguageCode);
|
|
4132
|
+
}
|
|
4133
|
+
const storedLocale = await this.localeStore?.getUserLocale?.(telegramUserId);
|
|
4134
|
+
if (storedLocale) {
|
|
4135
|
+
return (0, i18n_1.normalizeLocale)(storedLocale);
|
|
4136
|
+
}
|
|
4137
|
+
const detectedLocale = (0, i18n_1.normalizeLocale)(telegramLanguageCode);
|
|
4138
|
+
await this.localeStore?.setUserLocale?.(telegramUserId, detectedLocale);
|
|
4139
|
+
return detectedLocale;
|
|
4140
|
+
}
|
|
4141
|
+
async tForContext(ctx, key, options) {
|
|
4142
|
+
return this.t(await this.resolveLocaleForContext(ctx), key, options);
|
|
4143
|
+
}
|
|
4144
|
+
async tForTelegramUserId(telegramUserId, key, options) {
|
|
4145
|
+
return this.t(await this.resolveLocaleForTelegramUserId(telegramUserId), key, options);
|
|
4146
|
+
}
|
|
4147
|
+
t(locale, key, options) {
|
|
4148
|
+
return (0, i18n_1.translate)(locale, key, options);
|
|
4149
|
+
}
|
|
3824
4150
|
getGatewayActorFromContext(ctx) {
|
|
3825
4151
|
const firstName = ctx.from?.first_name?.trim();
|
|
3826
4152
|
const lastName = ctx.from?.last_name?.trim();
|
|
@@ -3849,7 +4175,7 @@ class TelegramTransport {
|
|
|
3849
4175
|
userId: ctx.from?.id,
|
|
3850
4176
|
error: error instanceof Error ? (error.stack ?? error.message) : String(error),
|
|
3851
4177
|
});
|
|
3852
|
-
await this.replyText(ctx,
|
|
4178
|
+
await this.replyText(ctx, await this.tForContext(ctx, "menu:system.sessions_menu_unavailable"), { kind: "menu" });
|
|
3853
4179
|
}
|
|
3854
4180
|
}
|
|
3855
4181
|
async showInboxMenu(ctx, introText) {
|
|
@@ -3909,15 +4235,18 @@ class TelegramTransport {
|
|
|
3909
4235
|
await this.renderMenuScreen(ctx, introText ? `${introText}\n\n${text}` : text, { kind: "menu" }, this.collabToolsMenu);
|
|
3910
4236
|
}
|
|
3911
4237
|
buildCollabHistoryMarkdown(input) {
|
|
4238
|
+
const locale = input.locale ?? "en";
|
|
3912
4239
|
const lines = [
|
|
3913
|
-
|
|
4240
|
+
this.t(locale, "menu:history.title"),
|
|
3914
4241
|
"",
|
|
3915
|
-
|
|
4242
|
+
this.t(locale, "menu:history.session", {
|
|
4243
|
+
sessionName: input.sessionLabel,
|
|
4244
|
+
}),
|
|
3916
4245
|
`Generated at: ${new Date().toISOString()}`,
|
|
3917
4246
|
"",
|
|
3918
4247
|
];
|
|
3919
4248
|
if (input.history.length === 0) {
|
|
3920
|
-
lines.push("
|
|
4249
|
+
lines.push(this.t(locale, "menu:history.empty"));
|
|
3921
4250
|
lines.push("");
|
|
3922
4251
|
return lines.join("\n");
|
|
3923
4252
|
}
|
|
@@ -3929,7 +4258,9 @@ class TelegramTransport {
|
|
|
3929
4258
|
lines.push(`- Direction: ${item.direction}`);
|
|
3930
4259
|
lines.push(`- Route: ${item.from_label} -> ${item.to_label}`);
|
|
3931
4260
|
if (item.project_name) {
|
|
3932
|
-
lines.push(
|
|
4261
|
+
lines.push(this.t(locale, "menu:history.project", {
|
|
4262
|
+
projectName: item.project_name,
|
|
4263
|
+
}));
|
|
3933
4264
|
}
|
|
3934
4265
|
if (item.delivery_status) {
|
|
3935
4266
|
lines.push(`- Status: ${item.delivery_status}`);
|
|
@@ -3940,27 +4271,33 @@ class TelegramTransport {
|
|
|
3940
4271
|
return lines.join("\n");
|
|
3941
4272
|
}
|
|
3942
4273
|
async handleCollabHistoryExport(ctx) {
|
|
4274
|
+
const locale = await this.resolveLocaleForContext(ctx);
|
|
3943
4275
|
const { principal, session } = await this.loadProjectsContext(ctx);
|
|
3944
4276
|
if (!this.config.distributed.gatewayPublicUrl || !principal || !session) {
|
|
3945
4277
|
await ctx.answerCallbackQuery({
|
|
3946
|
-
text:
|
|
4278
|
+
text: this.t(locale, "menu:collab.screen.unavailable"),
|
|
3947
4279
|
show_alert: true,
|
|
3948
4280
|
});
|
|
3949
4281
|
return;
|
|
3950
4282
|
}
|
|
3951
4283
|
const history = await this.listGatewaySessionHistory(principal, session.sessionId);
|
|
3952
4284
|
const markdown = this.buildCollabHistoryMarkdown({
|
|
4285
|
+
locale,
|
|
3953
4286
|
sessionLabel: session.label ?? session.sessionId,
|
|
3954
4287
|
history,
|
|
3955
4288
|
});
|
|
3956
4289
|
const fileName = `collab-history-${slugifyFilenamePart(session.label ?? session.sessionId) || "session"}.md`;
|
|
3957
4290
|
await this.replyDocumentWithRetry(ctx, new grammy_1.InputFile(Buffer.from(markdown, "utf8"), fileName), {
|
|
3958
|
-
caption:
|
|
4291
|
+
caption: this.t(locale, "menu:history.caption", {
|
|
4292
|
+
sessionName: session.label ?? session.sessionId,
|
|
4293
|
+
}),
|
|
3959
4294
|
}, {
|
|
3960
4295
|
kind: "menu",
|
|
3961
4296
|
sessionId: session.sessionId,
|
|
3962
4297
|
});
|
|
3963
|
-
await ctx.answerCallbackQuery({
|
|
4298
|
+
await ctx.answerCallbackQuery({
|
|
4299
|
+
text: this.t(locale, "menu:collab.buttons.history"),
|
|
4300
|
+
});
|
|
3964
4301
|
}
|
|
3965
4302
|
async showCollabDeleteMenu(ctx, introText) {
|
|
3966
4303
|
const text = await this.buildCollabDeleteMenuText(ctx);
|
|
@@ -4024,24 +4361,26 @@ class TelegramTransport {
|
|
|
4024
4361
|
});
|
|
4025
4362
|
}
|
|
4026
4363
|
async showHelp(ctx) {
|
|
4364
|
+
const locale = await this.resolveLocaleForContext(ctx);
|
|
4027
4365
|
await this.replyText(ctx, [
|
|
4028
|
-
"
|
|
4366
|
+
this.t(locale, "menu:help.title"),
|
|
4029
4367
|
"",
|
|
4030
|
-
"
|
|
4031
|
-
|
|
4368
|
+
this.t(locale, "menu:help.menu"),
|
|
4369
|
+
this.t(locale, "menu:help.help"),
|
|
4032
4370
|
"",
|
|
4033
|
-
"
|
|
4034
|
-
|
|
4035
|
-
|
|
4036
|
-
|
|
4037
|
-
|
|
4371
|
+
this.t(locale, "menu:help.how_it_works"),
|
|
4372
|
+
this.t(locale, "menu:help.step_choose"),
|
|
4373
|
+
this.t(locale, "menu:help.step_inbox"),
|
|
4374
|
+
this.t(locale, "menu:help.step_nudge"),
|
|
4375
|
+
this.t(locale, "menu:help.step_tools"),
|
|
4038
4376
|
].join("\n"), { kind: "menu" });
|
|
4039
4377
|
}
|
|
4040
4378
|
async showLiveViewLauncher(ctx) {
|
|
4379
|
+
const locale = await this.resolveLocaleForContext(ctx);
|
|
4041
4380
|
const principal = this.getPrincipalFromContext(ctx);
|
|
4042
4381
|
if (!principal) {
|
|
4043
4382
|
await ctx.answerCallbackQuery({
|
|
4044
|
-
text: "
|
|
4383
|
+
text: this.t(locale, "menu:live.errors.identity_unavailable"),
|
|
4045
4384
|
show_alert: true,
|
|
4046
4385
|
});
|
|
4047
4386
|
return;
|
|
@@ -4049,7 +4388,7 @@ class TelegramTransport {
|
|
|
4049
4388
|
const activeSessionId = await this.bindingStore.getActiveSessionIdForPrincipal(principal);
|
|
4050
4389
|
if (!activeSessionId) {
|
|
4051
4390
|
await ctx.answerCallbackQuery({
|
|
4052
|
-
text: "
|
|
4391
|
+
text: this.t(locale, "menu:live.errors.no_active_session"),
|
|
4053
4392
|
show_alert: true,
|
|
4054
4393
|
});
|
|
4055
4394
|
return;
|
|
@@ -4058,7 +4397,7 @@ class TelegramTransport {
|
|
|
4058
4397
|
(!this.config.webapp.publicUrl &&
|
|
4059
4398
|
!this.config.distributed.gatewayPublicUrl)) {
|
|
4060
4399
|
await ctx.answerCallbackQuery({
|
|
4061
|
-
text: "
|
|
4400
|
+
text: this.t(locale, "menu:live.errors.webapp_disabled"),
|
|
4062
4401
|
show_alert: true,
|
|
4063
4402
|
});
|
|
4064
4403
|
return;
|
|
@@ -4075,7 +4414,7 @@ class TelegramTransport {
|
|
|
4075
4414
|
: resolveWebAppPublicBaseUrl(this.config);
|
|
4076
4415
|
if (!baseUrl) {
|
|
4077
4416
|
await ctx.answerCallbackQuery({
|
|
4078
|
-
text: "
|
|
4417
|
+
text: this.t(locale, "menu:live.errors.public_url_missing"),
|
|
4079
4418
|
show_alert: true,
|
|
4080
4419
|
});
|
|
4081
4420
|
return;
|
|
@@ -4084,9 +4423,22 @@ class TelegramTransport {
|
|
|
4084
4423
|
? (0, relay_1.buildLiveRelaySessionId)(clientUuid, activeSessionId)
|
|
4085
4424
|
: activeSessionId;
|
|
4086
4425
|
const url = new URL(`${baseUrl}/live/${encodeURIComponent(liveSessionId)}`);
|
|
4087
|
-
|
|
4088
|
-
|
|
4089
|
-
|
|
4426
|
+
url.searchParams.set("launchMode", this.config.webapp.launchMode);
|
|
4427
|
+
await ctx.answerCallbackQuery({
|
|
4428
|
+
text: this.t(locale, "menu:live.actions.opening"),
|
|
4429
|
+
});
|
|
4430
|
+
const sent = await this.replyText(ctx, [
|
|
4431
|
+
this.t(locale, "menu:live.screen.launcher_title", {
|
|
4432
|
+
sessionName: session?.label ?? activeSessionId,
|
|
4433
|
+
}),
|
|
4434
|
+
"",
|
|
4435
|
+
this.t(locale, "menu:live.actions.choose_mode"),
|
|
4436
|
+
].join("\n"), { kind: "menu", sessionId: activeSessionId }, {
|
|
4437
|
+
reply_markup: this.buildLiveViewLaunchKeyboard((mode) => {
|
|
4438
|
+
const modeUrl = new URL(url.toString());
|
|
4439
|
+
modeUrl.searchParams.set("launchMode", mode);
|
|
4440
|
+
return modeUrl.toString();
|
|
4441
|
+
}, locale),
|
|
4090
4442
|
});
|
|
4091
4443
|
this.webAppLaunchRegistry.set(principal.telegramUserId, activeSessionId, this.config.webapp.initDataTtlSeconds, {
|
|
4092
4444
|
telegramChatId: principal.telegramChatId,
|
|
@@ -4113,7 +4465,37 @@ class TelegramTransport {
|
|
|
4113
4465
|
const liveSessionId = canUseRelay
|
|
4114
4466
|
? (0, relay_1.buildLiveRelaySessionId)(input.targetClientUuid, input.targetLocalSessionId, input.sourceClientUuid)
|
|
4115
4467
|
: (input.targetLocalSessionId ?? input.targetSessionId);
|
|
4116
|
-
|
|
4468
|
+
const url = new URL(`${baseUrl}/live/${encodeURIComponent(liveSessionId)}`);
|
|
4469
|
+
url.searchParams.set("launchMode", input.launchMode ?? this.config.webapp.launchMode);
|
|
4470
|
+
return url.toString();
|
|
4471
|
+
}
|
|
4472
|
+
buildLiveViewLaunchKeyboard(getUrl, locale = "en") {
|
|
4473
|
+
const keyboard = new grammy_1.InlineKeyboard();
|
|
4474
|
+
const modes = [
|
|
4475
|
+
{
|
|
4476
|
+
mode: "fullscreen",
|
|
4477
|
+
label: this.t(locale, "menu:live.buttons.fullscreen"),
|
|
4478
|
+
},
|
|
4479
|
+
{
|
|
4480
|
+
mode: "expand",
|
|
4481
|
+
label: this.t(locale, "menu:live.buttons.expand"),
|
|
4482
|
+
},
|
|
4483
|
+
{
|
|
4484
|
+
mode: "default",
|
|
4485
|
+
label: this.t(locale, "menu:live.buttons.default"),
|
|
4486
|
+
},
|
|
4487
|
+
];
|
|
4488
|
+
for (const [index, { mode, label }] of modes.entries()) {
|
|
4489
|
+
const url = getUrl(mode);
|
|
4490
|
+
if (!url) {
|
|
4491
|
+
continue;
|
|
4492
|
+
}
|
|
4493
|
+
keyboard.webApp(label, url);
|
|
4494
|
+
if (index === 1) {
|
|
4495
|
+
keyboard.row();
|
|
4496
|
+
}
|
|
4497
|
+
}
|
|
4498
|
+
return keyboard;
|
|
4117
4499
|
}
|
|
4118
4500
|
clearPendingInteractionsForContext(ctx) {
|
|
4119
4501
|
const principal = this.getPrincipalFromContext(ctx);
|
|
@@ -4140,10 +4522,11 @@ class TelegramTransport {
|
|
|
4140
4522
|
this.currentAttachmentTargets.delete(key);
|
|
4141
4523
|
}
|
|
4142
4524
|
async sendActiveSessionBuffer(ctx, scope) {
|
|
4525
|
+
const locale = await this.resolveLocaleForContext(ctx);
|
|
4143
4526
|
const principal = this.getPrincipalFromContext(ctx);
|
|
4144
4527
|
if (!principal) {
|
|
4145
4528
|
await ctx.answerCallbackQuery({
|
|
4146
|
-
text: "
|
|
4529
|
+
text: this.t(locale, "common:errors.no_telegram_identity"),
|
|
4147
4530
|
show_alert: true,
|
|
4148
4531
|
});
|
|
4149
4532
|
return;
|
|
@@ -4151,7 +4534,7 @@ class TelegramTransport {
|
|
|
4151
4534
|
const sessionId = await this.bindingStore.getActiveSessionIdForPrincipal(principal);
|
|
4152
4535
|
if (!sessionId) {
|
|
4153
4536
|
await ctx.answerCallbackQuery({
|
|
4154
|
-
text: "
|
|
4537
|
+
text: this.t(locale, "common:errors.no_active_session"),
|
|
4155
4538
|
show_alert: true,
|
|
4156
4539
|
});
|
|
4157
4540
|
return;
|
|
@@ -4202,14 +4585,15 @@ class TelegramTransport {
|
|
|
4202
4585
|
}
|
|
4203
4586
|
}
|
|
4204
4587
|
async buildSessionsMenuText(ctx) {
|
|
4588
|
+
const locale = await this.resolveLocaleForContext(ctx);
|
|
4205
4589
|
const principal = this.getPrincipalFromContext(ctx);
|
|
4206
4590
|
if (!principal) {
|
|
4207
|
-
return
|
|
4591
|
+
return this.t(locale, "common:errors.no_telegram_identity");
|
|
4208
4592
|
}
|
|
4209
4593
|
const activeSessionId = await this.bindingStore.getActiveSessionIdForPrincipal(principal);
|
|
4210
4594
|
const sessionIds = (await this.bindingStore.listBoundSessionIdsForPrincipal(principal)).sort();
|
|
4211
4595
|
if (sessionIds.length === 0) {
|
|
4212
|
-
return "
|
|
4596
|
+
return this.t(locale, "menu:sessions.screen.no_linked_sessions");
|
|
4213
4597
|
}
|
|
4214
4598
|
let lastWorkedSession;
|
|
4215
4599
|
for (const sessionId of sessionIds) {
|
|
@@ -4228,353 +4612,439 @@ class TelegramTransport {
|
|
|
4228
4612
|
};
|
|
4229
4613
|
}
|
|
4230
4614
|
}
|
|
4231
|
-
const lines = [
|
|
4615
|
+
const lines = [this.t(locale, "menu:sessions.screen.title"), ""];
|
|
4232
4616
|
if (lastWorkedSession) {
|
|
4233
|
-
lines.push(
|
|
4617
|
+
lines.push(this.t(locale, "menu:sessions.screen.last_worked", {
|
|
4618
|
+
sessionName: escapeHtml(lastWorkedSession.label ?? lastWorkedSession.sessionId),
|
|
4619
|
+
}));
|
|
4234
4620
|
const formattedUpdatedAt = formatMenuTimestamp(lastWorkedSession.updatedAt);
|
|
4235
4621
|
if (formattedUpdatedAt) {
|
|
4236
|
-
lines.push(
|
|
4622
|
+
lines.push(this.t(locale, "menu:sessions.screen.updated", {
|
|
4623
|
+
timestamp: escapeHtml(formattedUpdatedAt),
|
|
4624
|
+
}));
|
|
4237
4625
|
}
|
|
4238
4626
|
lines.push("");
|
|
4239
4627
|
}
|
|
4240
4628
|
if (activeSessionId) {
|
|
4241
4629
|
const activeSession = await this.sessionStore.getSession(activeSessionId);
|
|
4242
|
-
lines.push(
|
|
4630
|
+
lines.push(this.t(locale, "menu:sessions.screen.current_active", {
|
|
4631
|
+
sessionName: escapeHtml(activeSession?.label ?? activeSessionId),
|
|
4632
|
+
}));
|
|
4243
4633
|
lines.push("");
|
|
4244
4634
|
}
|
|
4245
|
-
lines.push(`<i>${escapeHtml(await this.getTmuxStatusLine())}</i>`);
|
|
4635
|
+
lines.push(`<i>${escapeHtml(await this.getTmuxStatusLine(locale))}</i>`);
|
|
4246
4636
|
lines.push("");
|
|
4247
4637
|
return lines.join("\n");
|
|
4248
4638
|
}
|
|
4249
4639
|
async buildInboxMenuText(ctx) {
|
|
4640
|
+
const locale = await this.resolveLocaleForContext(ctx);
|
|
4250
4641
|
const principal = this.getPrincipalFromContext(ctx);
|
|
4251
4642
|
if (!principal) {
|
|
4252
|
-
return
|
|
4643
|
+
return this.t(locale, "common:errors.no_telegram_identity");
|
|
4253
4644
|
}
|
|
4254
4645
|
const activeSessionId = await this.bindingStore.getActiveSessionIdForPrincipal(principal);
|
|
4255
4646
|
if (!activeSessionId) {
|
|
4256
|
-
return
|
|
4647
|
+
return this.t(locale, "common:errors.no_active_session");
|
|
4257
4648
|
}
|
|
4258
4649
|
const session = await this.sessionStore.getSession(activeSessionId);
|
|
4259
4650
|
const total = await this.inboxStore.countInboxMessages(activeSessionId);
|
|
4260
4651
|
return [
|
|
4261
|
-
|
|
4652
|
+
this.t(locale, "menu:inbox.screen.title"),
|
|
4262
4653
|
"",
|
|
4263
|
-
|
|
4264
|
-
|
|
4654
|
+
this.t(locale, "menu:inbox.screen.active_session", {
|
|
4655
|
+
sessionName: session?.label ?? activeSessionId,
|
|
4656
|
+
}),
|
|
4657
|
+
this.t(locale, "menu:inbox.screen.stored_messages", {
|
|
4658
|
+
count: total,
|
|
4659
|
+
}),
|
|
4265
4660
|
"",
|
|
4266
4661
|
total > 0
|
|
4267
|
-
? "
|
|
4268
|
-
:
|
|
4662
|
+
? this.t(locale, "menu:inbox.screen.choose_message")
|
|
4663
|
+
: this.t(locale, "menu:inbox.screen.empty"),
|
|
4269
4664
|
].join("\n");
|
|
4270
4665
|
}
|
|
4271
4666
|
async buildBufferMenuText(ctx) {
|
|
4667
|
+
const locale = await this.resolveLocaleForContext(ctx);
|
|
4272
4668
|
const principal = this.getPrincipalFromContext(ctx);
|
|
4273
4669
|
if (!principal) {
|
|
4274
|
-
return
|
|
4670
|
+
return this.t(locale, "common:errors.no_telegram_identity");
|
|
4275
4671
|
}
|
|
4276
4672
|
const activeSessionId = await this.bindingStore.getActiveSessionIdForPrincipal(principal);
|
|
4277
4673
|
if (!activeSessionId) {
|
|
4278
|
-
return
|
|
4674
|
+
return this.t(locale, "common:errors.no_active_session");
|
|
4279
4675
|
}
|
|
4280
4676
|
const session = await this.sessionStore.getSession(activeSessionId);
|
|
4281
4677
|
return [
|
|
4282
|
-
|
|
4678
|
+
this.t(locale, "menu:buffer.screen.title"),
|
|
4283
4679
|
"",
|
|
4284
|
-
|
|
4285
|
-
|
|
4680
|
+
this.t(locale, "menu:buffer.screen.active_session", {
|
|
4681
|
+
sessionName: session?.label ?? activeSessionId,
|
|
4682
|
+
}),
|
|
4683
|
+
this.t(locale, "menu:buffer.screen.tmux_target", {
|
|
4684
|
+
tmuxTarget: session?.tmuxTarget ?? "not set",
|
|
4685
|
+
}),
|
|
4286
4686
|
"",
|
|
4287
|
-
"
|
|
4288
|
-
|
|
4687
|
+
this.t(locale, "menu:buffer.screen.export_hint"),
|
|
4688
|
+
this.t(locale, "menu:buffer.screen.export_modes"),
|
|
4289
4689
|
].join("\n");
|
|
4290
4690
|
}
|
|
4291
4691
|
async buildBrowserMenuText(ctx) {
|
|
4692
|
+
const locale = await this.resolveLocaleForContext(ctx);
|
|
4292
4693
|
const principal = this.getPrincipalFromContext(ctx);
|
|
4293
4694
|
if (!principal) {
|
|
4294
|
-
return
|
|
4695
|
+
return this.t(locale, "common:errors.no_telegram_identity");
|
|
4295
4696
|
}
|
|
4296
4697
|
const activeSessionId = await this.bindingStore.getActiveSessionIdForPrincipal(principal);
|
|
4297
4698
|
if (!activeSessionId) {
|
|
4298
|
-
return
|
|
4699
|
+
return this.t(locale, "common:errors.no_active_session");
|
|
4299
4700
|
}
|
|
4300
4701
|
const session = await this.sessionStore.getSession(activeSessionId);
|
|
4301
4702
|
const screenshots = await this.listActiveSessionScreenshots(activeSessionId);
|
|
4302
4703
|
return [
|
|
4303
|
-
|
|
4704
|
+
this.t(locale, "menu:browser.screen.title"),
|
|
4304
4705
|
"",
|
|
4305
|
-
|
|
4306
|
-
|
|
4706
|
+
this.t(locale, "menu:browser.screen.active_session", {
|
|
4707
|
+
sessionName: session?.label ?? activeSessionId,
|
|
4708
|
+
}),
|
|
4709
|
+
this.t(locale, "menu:browser.screen.stored_screenshots", {
|
|
4710
|
+
count: screenshots.length,
|
|
4711
|
+
}),
|
|
4307
4712
|
"",
|
|
4308
|
-
"
|
|
4713
|
+
this.t(locale, "menu:browser.screen.choose_action"),
|
|
4309
4714
|
].join("\n");
|
|
4310
4715
|
}
|
|
4311
4716
|
async buildSettingsMenuText(ctx) {
|
|
4717
|
+
const locale = await this.resolveLocaleForContext(ctx);
|
|
4312
4718
|
const principal = this.getPrincipalFromContext(ctx);
|
|
4313
4719
|
if (!principal) {
|
|
4314
|
-
return
|
|
4720
|
+
return this.t(locale, "common:errors.no_telegram_identity");
|
|
4315
4721
|
}
|
|
4316
4722
|
const activeSessionId = await this.bindingStore.getActiveSessionIdForPrincipal(principal);
|
|
4317
4723
|
if (!activeSessionId) {
|
|
4318
|
-
return
|
|
4724
|
+
return this.t(locale, "common:errors.no_active_session");
|
|
4319
4725
|
}
|
|
4320
4726
|
const session = await this.sessionStore.getSession(activeSessionId);
|
|
4321
4727
|
return [
|
|
4322
|
-
|
|
4728
|
+
this.t(locale, "menu:settings.screen.title"),
|
|
4323
4729
|
"",
|
|
4324
|
-
|
|
4730
|
+
this.t(locale, "menu:settings.screen.active_session", {
|
|
4731
|
+
sessionName: session?.label ?? activeSessionId,
|
|
4732
|
+
}),
|
|
4325
4733
|
"",
|
|
4326
|
-
"
|
|
4734
|
+
this.t(locale, "menu:settings.screen.hint"),
|
|
4327
4735
|
].join("\n");
|
|
4328
4736
|
}
|
|
4329
4737
|
async buildScreenshotsMenuText(ctx) {
|
|
4738
|
+
const locale = await this.resolveLocaleForContext(ctx);
|
|
4330
4739
|
const principal = this.getPrincipalFromContext(ctx);
|
|
4331
4740
|
if (!principal) {
|
|
4332
|
-
return
|
|
4741
|
+
return this.t(locale, "common:errors.no_telegram_identity");
|
|
4333
4742
|
}
|
|
4334
4743
|
const activeSessionId = await this.bindingStore.getActiveSessionIdForPrincipal(principal);
|
|
4335
4744
|
if (!activeSessionId) {
|
|
4336
|
-
return
|
|
4745
|
+
return this.t(locale, "common:errors.no_active_session");
|
|
4337
4746
|
}
|
|
4338
4747
|
const session = await this.sessionStore.getSession(activeSessionId);
|
|
4339
4748
|
const files = await this.listActiveSessionScreenshots(activeSessionId);
|
|
4340
4749
|
return [
|
|
4341
|
-
|
|
4750
|
+
this.t(locale, "menu:screenshots.screen.title"),
|
|
4342
4751
|
"",
|
|
4343
|
-
|
|
4344
|
-
|
|
4752
|
+
this.t(locale, "menu:screenshots.screen.active_session", {
|
|
4753
|
+
sessionName: session?.label ?? activeSessionId,
|
|
4754
|
+
}),
|
|
4755
|
+
this.t(locale, "menu:screenshots.screen.stored_screenshots", {
|
|
4756
|
+
count: files.length,
|
|
4757
|
+
}),
|
|
4345
4758
|
"",
|
|
4346
4759
|
files.length > 0
|
|
4347
|
-
? "
|
|
4348
|
-
: "
|
|
4760
|
+
? this.t(locale, "menu:screenshots.screen.choose_screenshot")
|
|
4761
|
+
: this.t(locale, "menu:screenshots.screen.empty"),
|
|
4349
4762
|
].join("\n");
|
|
4350
4763
|
}
|
|
4351
4764
|
async buildStorageMenuText(ctx) {
|
|
4765
|
+
const locale = await this.resolveLocaleForContext(ctx);
|
|
4352
4766
|
const principal = this.getPrincipalFromContext(ctx);
|
|
4353
4767
|
if (!principal) {
|
|
4354
|
-
return
|
|
4768
|
+
return this.t(locale, "common:errors.no_telegram_identity");
|
|
4355
4769
|
}
|
|
4356
4770
|
const activeSessionId = await this.bindingStore.getActiveSessionIdForPrincipal(principal);
|
|
4357
4771
|
if (!activeSessionId) {
|
|
4358
|
-
return
|
|
4772
|
+
return this.t(locale, "common:errors.no_active_session");
|
|
4359
4773
|
}
|
|
4360
4774
|
const session = await this.sessionStore.getSession(activeSessionId);
|
|
4361
4775
|
const entries = await this.listActiveSessionStorageEntries(activeSessionId);
|
|
4362
4776
|
return [
|
|
4363
|
-
|
|
4777
|
+
this.t(locale, "menu:storage.screen.title"),
|
|
4364
4778
|
"",
|
|
4365
|
-
|
|
4366
|
-
|
|
4779
|
+
this.t(locale, "menu:storage.screen.active_session", {
|
|
4780
|
+
sessionName: session?.label ?? activeSessionId,
|
|
4781
|
+
}),
|
|
4782
|
+
this.t(locale, "menu:storage.screen.stored_files", {
|
|
4783
|
+
count: entries.length,
|
|
4784
|
+
}),
|
|
4367
4785
|
"",
|
|
4368
4786
|
entries.length > 0
|
|
4369
|
-
? "
|
|
4370
|
-
:
|
|
4787
|
+
? this.t(locale, "menu:storage.screen.choose_file")
|
|
4788
|
+
: this.t(locale, "menu:storage.screen.empty"),
|
|
4371
4789
|
].join("\n");
|
|
4372
4790
|
}
|
|
4373
4791
|
async buildLinkMenuText(ctx) {
|
|
4792
|
+
const locale = await this.resolveLocaleForContext(ctx);
|
|
4374
4793
|
const principal = this.getPrincipalFromContext(ctx);
|
|
4375
4794
|
if (!principal) {
|
|
4376
|
-
return
|
|
4795
|
+
return this.t(locale, "common:errors.no_telegram_identity");
|
|
4377
4796
|
}
|
|
4378
4797
|
const activeSessionId = await this.bindingStore.getActiveSessionIdForPrincipal(principal);
|
|
4379
4798
|
if (!activeSessionId) {
|
|
4380
|
-
return
|
|
4799
|
+
return this.t(locale, "common:errors.no_active_session");
|
|
4381
4800
|
}
|
|
4382
4801
|
const session = await this.sessionStore.getSession(activeSessionId);
|
|
4383
4802
|
return [
|
|
4384
|
-
|
|
4803
|
+
this.t(locale, "menu:link.screen.title"),
|
|
4385
4804
|
"",
|
|
4386
|
-
|
|
4805
|
+
this.t(locale, "menu:link.screen.active_session", {
|
|
4806
|
+
sessionName: session?.label ?? activeSessionId,
|
|
4807
|
+
}),
|
|
4387
4808
|
"",
|
|
4388
|
-
"
|
|
4389
|
-
|
|
4809
|
+
this.t(locale, "menu:link.screen.choose_partner"),
|
|
4810
|
+
this.t(locale, "menu:link.screen.hint"),
|
|
4390
4811
|
].join("\n");
|
|
4391
4812
|
}
|
|
4392
4813
|
async buildPartnerMenuText(ctx) {
|
|
4814
|
+
const locale = await this.resolveLocaleForContext(ctx);
|
|
4393
4815
|
const principal = this.getPrincipalFromContext(ctx);
|
|
4394
4816
|
if (!principal) {
|
|
4395
|
-
return
|
|
4817
|
+
return this.t(locale, "common:errors.no_telegram_identity");
|
|
4396
4818
|
}
|
|
4397
4819
|
const activeSessionId = await this.bindingStore.getActiveSessionIdForPrincipal(principal);
|
|
4398
4820
|
if (!activeSessionId) {
|
|
4399
|
-
return
|
|
4821
|
+
return this.t(locale, "common:errors.no_active_session");
|
|
4400
4822
|
}
|
|
4401
4823
|
const session = await this.sessionStore.getSession(activeSessionId);
|
|
4402
4824
|
if (!session?.linkedSessionId) {
|
|
4403
4825
|
return [
|
|
4404
|
-
|
|
4826
|
+
this.t(locale, "menu:partner.screen.title"),
|
|
4405
4827
|
"",
|
|
4406
|
-
|
|
4828
|
+
this.t(locale, "menu:partner.screen.active_session", {
|
|
4829
|
+
sessionName: session?.label ?? activeSessionId,
|
|
4830
|
+
}),
|
|
4407
4831
|
"",
|
|
4408
|
-
"
|
|
4409
|
-
"
|
|
4832
|
+
this.t(locale, "menu:partner.screen.no_partner"),
|
|
4833
|
+
this.t(locale, "menu:partner.screen.use_link_first"),
|
|
4410
4834
|
].join("\n");
|
|
4411
4835
|
}
|
|
4412
4836
|
const linkedSession = await this.sessionStore.getSession(session.linkedSessionId);
|
|
4413
4837
|
return [
|
|
4414
|
-
|
|
4838
|
+
this.t(locale, "menu:partner.screen.title"),
|
|
4415
4839
|
"",
|
|
4416
|
-
|
|
4417
|
-
|
|
4840
|
+
this.t(locale, "menu:partner.screen.active_session", {
|
|
4841
|
+
sessionName: session.label ?? activeSessionId,
|
|
4842
|
+
}),
|
|
4843
|
+
this.t(locale, "menu:partner.screen.linked_partner", {
|
|
4844
|
+
partnerName: linkedSession?.label ?? session.linkedSessionId,
|
|
4845
|
+
}),
|
|
4418
4846
|
"",
|
|
4419
|
-
"
|
|
4420
|
-
"
|
|
4847
|
+
this.t(locale, "menu:partner.screen.prompt_hint"),
|
|
4848
|
+
this.t(locale, "menu:partner.screen.prompt_format"),
|
|
4421
4849
|
].join("\n");
|
|
4422
4850
|
}
|
|
4423
4851
|
async buildLocalMenuText(ctx) {
|
|
4852
|
+
const locale = await this.resolveLocaleForContext(ctx);
|
|
4424
4853
|
const principal = this.getPrincipalFromContext(ctx);
|
|
4425
4854
|
if (!principal) {
|
|
4426
|
-
return
|
|
4855
|
+
return this.t(locale, "menu:local.screen.unavailable");
|
|
4427
4856
|
}
|
|
4428
4857
|
const activeSessionId = await this.bindingStore.getActiveSessionIdForPrincipal(principal);
|
|
4429
4858
|
if (!activeSessionId) {
|
|
4430
|
-
return "
|
|
4859
|
+
return this.t(locale, "menu:local.screen.no_active_session");
|
|
4431
4860
|
}
|
|
4432
4861
|
const session = await this.sessionStore.getSession(activeSessionId);
|
|
4433
4862
|
const linkedSession = session?.linkedSessionId
|
|
4434
4863
|
? await this.sessionStore.getSession(session.linkedSessionId)
|
|
4435
4864
|
: null;
|
|
4436
4865
|
return [
|
|
4437
|
-
|
|
4866
|
+
this.t(locale, "menu:main.buttons.local"),
|
|
4438
4867
|
"",
|
|
4439
|
-
|
|
4440
|
-
|
|
4868
|
+
this.t(locale, "menu:local.screen.active_session", {
|
|
4869
|
+
sessionName: session?.label ?? activeSessionId,
|
|
4870
|
+
}),
|
|
4871
|
+
linkedSession?.label
|
|
4872
|
+
? this.t(locale, "menu:local.screen.link_status", {
|
|
4873
|
+
linkedSessionName: linkedSession.label,
|
|
4874
|
+
})
|
|
4875
|
+
: this.t(locale, "menu:local.screen.link_status_none"),
|
|
4441
4876
|
"",
|
|
4442
|
-
|
|
4443
|
-
"
|
|
4877
|
+
this.t(locale, "menu:local.screen.hint_title"),
|
|
4878
|
+
this.t(locale, "menu:local.screen.hint_body"),
|
|
4444
4879
|
].join("\n");
|
|
4445
4880
|
}
|
|
4446
4881
|
async buildProjectsMenuText(ctx) {
|
|
4882
|
+
const locale = await this.resolveLocaleForContext(ctx);
|
|
4447
4883
|
const { session, projects } = await this.loadProjectsContext(ctx);
|
|
4448
4884
|
if (!this.config.distributed.gatewayPublicUrl) {
|
|
4449
4885
|
return [
|
|
4450
|
-
|
|
4886
|
+
this.t(locale, "menu:collab.screen.title"),
|
|
4451
4887
|
"",
|
|
4452
|
-
|
|
4453
|
-
"
|
|
4888
|
+
this.t(locale, "menu:collab.screen.gateway_not_configured"),
|
|
4889
|
+
this.t(locale, "menu:collab.screen.use_local_instead"),
|
|
4454
4890
|
].join("\n");
|
|
4455
4891
|
}
|
|
4456
4892
|
if (!session || !projects) {
|
|
4457
|
-
return
|
|
4893
|
+
return this.t(locale, "menu:collab.screen.unavailable");
|
|
4458
4894
|
}
|
|
4459
4895
|
return [
|
|
4460
|
-
|
|
4896
|
+
this.t(locale, "menu:collab.screen.title"),
|
|
4461
4897
|
"",
|
|
4462
|
-
|
|
4463
|
-
|
|
4464
|
-
|
|
4898
|
+
this.t(locale, "menu:collab.screen.active_session", {
|
|
4899
|
+
sessionName: session.label ?? session.sessionId,
|
|
4900
|
+
}),
|
|
4901
|
+
session.activeProjectName
|
|
4902
|
+
? this.t(locale, "menu:collab.screen.open_project", {
|
|
4903
|
+
projectName: session.activeProjectName,
|
|
4904
|
+
})
|
|
4905
|
+
: this.t(locale, "menu:collab.screen.open_project_none"),
|
|
4906
|
+
this.t(locale, "menu:collab.screen.project_count", {
|
|
4907
|
+
count: projects.length,
|
|
4908
|
+
}),
|
|
4465
4909
|
"",
|
|
4466
|
-
|
|
4910
|
+
this.t(locale, "menu:collab.screen.invite_hint"),
|
|
4467
4911
|
].join("\n");
|
|
4468
4912
|
}
|
|
4469
4913
|
async buildCollabToolsMenuText(ctx) {
|
|
4914
|
+
const locale = await this.resolveLocaleForContext(ctx);
|
|
4470
4915
|
const principal = this.getPrincipalFromContext(ctx);
|
|
4471
4916
|
if (!principal || !this.config.distributed.gatewayPublicUrl) {
|
|
4472
|
-
return
|
|
4917
|
+
return this.t(locale, "menu:collab.screen.gateway_not_configured");
|
|
4473
4918
|
}
|
|
4474
4919
|
const sessionId = await this.bindingStore.getActiveSessionIdForPrincipal(principal);
|
|
4475
4920
|
if (!sessionId) {
|
|
4476
|
-
return
|
|
4921
|
+
return this.t(locale, "common:errors.no_active_session");
|
|
4477
4922
|
}
|
|
4478
4923
|
const session = await this.sessionStore.getSession(sessionId);
|
|
4479
4924
|
const projects = await this.listGatewayProjects(principal);
|
|
4480
4925
|
if (projects.length === 0) {
|
|
4481
4926
|
return [
|
|
4482
|
-
|
|
4927
|
+
this.t(locale, "menu:collab.screen.tools_title"),
|
|
4483
4928
|
"",
|
|
4484
|
-
|
|
4929
|
+
this.t(locale, "menu:collab.screen.active_session", {
|
|
4930
|
+
sessionName: session?.label ?? sessionId,
|
|
4931
|
+
}),
|
|
4485
4932
|
"",
|
|
4486
|
-
|
|
4933
|
+
this.t(locale, "menu:collab.screen.tools_empty"),
|
|
4487
4934
|
].join("\n");
|
|
4488
4935
|
}
|
|
4489
4936
|
const targets = await this.collectCollabBroadcastTargets(principal, sessionId);
|
|
4490
4937
|
const uniqueCount = targets.localTargetSessionIds.length + targets.remoteTargets.length;
|
|
4491
4938
|
return [
|
|
4492
|
-
|
|
4939
|
+
this.t(locale, "menu:collab.screen.tools_title"),
|
|
4493
4940
|
"",
|
|
4494
|
-
|
|
4495
|
-
|
|
4496
|
-
|
|
4941
|
+
this.t(locale, "menu:collab.screen.active_session", {
|
|
4942
|
+
sessionName: session?.label ?? sessionId,
|
|
4943
|
+
}),
|
|
4944
|
+
this.t(locale, "menu:collab.screen.tools_project_count", {
|
|
4945
|
+
count: projects.length,
|
|
4946
|
+
}),
|
|
4947
|
+
this.t(locale, "menu:collab.screen.tools_session_count", {
|
|
4948
|
+
count: uniqueCount,
|
|
4949
|
+
}),
|
|
4497
4950
|
"",
|
|
4498
|
-
|
|
4499
|
-
|
|
4500
|
-
|
|
4951
|
+
this.t(locale, "menu:collab.screen.tools_broadcast"),
|
|
4952
|
+
this.t(locale, "menu:collab.screen.tools_history"),
|
|
4953
|
+
this.t(locale, "menu:broadcast.collab_hint"),
|
|
4501
4954
|
].join("\n");
|
|
4502
4955
|
}
|
|
4503
4956
|
async buildCollabDeleteMenuText(ctx) {
|
|
4957
|
+
const locale = await this.resolveLocaleForContext(ctx);
|
|
4504
4958
|
const { session, projects } = await this.loadProjectsContext(ctx);
|
|
4505
4959
|
if (!this.config.distributed.gatewayPublicUrl) {
|
|
4506
|
-
return
|
|
4960
|
+
return this.t(locale, "menu:collab.screen.gateway_not_configured");
|
|
4507
4961
|
}
|
|
4508
4962
|
if (!session || !projects) {
|
|
4509
|
-
return
|
|
4963
|
+
return this.t(locale, "menu:collab.screen.unavailable");
|
|
4510
4964
|
}
|
|
4511
4965
|
const ownerCount = projects.filter((project) => project.role === "owner").length;
|
|
4512
4966
|
return [
|
|
4513
|
-
|
|
4967
|
+
this.t(locale, "menu:project.delete_menu_title"),
|
|
4514
4968
|
"",
|
|
4515
|
-
|
|
4516
|
-
|
|
4517
|
-
|
|
4969
|
+
this.t(locale, "menu:project.active_session", {
|
|
4970
|
+
sessionName: session.label ?? session.sessionId,
|
|
4971
|
+
}),
|
|
4972
|
+
this.t(locale, "menu:project.total_count", {
|
|
4973
|
+
count: projects.length,
|
|
4974
|
+
}),
|
|
4975
|
+
this.t(locale, "menu:project.owner_count", {
|
|
4976
|
+
count: ownerCount,
|
|
4977
|
+
}),
|
|
4518
4978
|
"",
|
|
4519
|
-
|
|
4520
|
-
"
|
|
4521
|
-
"
|
|
4979
|
+
this.t(locale, "menu:project.delete_choose"),
|
|
4980
|
+
this.t(locale, "menu:project.delete_body"),
|
|
4981
|
+
this.t(locale, "menu:project.delete_owner_hint"),
|
|
4522
4982
|
].join("\n");
|
|
4523
4983
|
}
|
|
4524
4984
|
async buildDeveloperMenuText(ctx) {
|
|
4985
|
+
const locale = await this.resolveLocaleForContext(ctx);
|
|
4525
4986
|
const principal = this.getPrincipalFromContext(ctx);
|
|
4526
4987
|
if (!principal) {
|
|
4527
|
-
return
|
|
4988
|
+
return this.t(locale, "common:errors.no_telegram_identity");
|
|
4528
4989
|
}
|
|
4529
4990
|
const sessionIds = await this.bindingStore.listBoundSessionIdsForPrincipal(principal);
|
|
4530
4991
|
return [
|
|
4531
|
-
|
|
4992
|
+
this.t(locale, "menu:developer.screen.title"),
|
|
4532
4993
|
"",
|
|
4533
|
-
|
|
4994
|
+
this.t(locale, "menu:developer.screen.linked_sessions", {
|
|
4995
|
+
count: sessionIds.length,
|
|
4996
|
+
}),
|
|
4534
4997
|
"",
|
|
4535
|
-
"
|
|
4536
|
-
|
|
4998
|
+
this.t(locale, "menu:developer.screen.broadcast_help"),
|
|
4999
|
+
this.t(locale, "menu:developer.screen.prune_help"),
|
|
4537
5000
|
].join("\n");
|
|
4538
5001
|
}
|
|
4539
5002
|
async buildUnpairConfirmText(ctx) {
|
|
5003
|
+
const locale = await this.resolveLocaleForContext(ctx);
|
|
4540
5004
|
const principal = this.getPrincipalFromContext(ctx);
|
|
4541
5005
|
if (!principal) {
|
|
4542
|
-
return
|
|
5006
|
+
return this.t(locale, "common:errors.no_telegram_identity");
|
|
4543
5007
|
}
|
|
4544
5008
|
const activeSessionId = await this.bindingStore.getActiveSessionIdForPrincipal(principal);
|
|
4545
5009
|
if (!activeSessionId) {
|
|
4546
|
-
return "
|
|
5010
|
+
return this.t(locale, "common:errors.no_active_session");
|
|
4547
5011
|
}
|
|
4548
5012
|
const session = await this.sessionStore.getSession(activeSessionId);
|
|
4549
5013
|
return [
|
|
4550
|
-
"
|
|
5014
|
+
this.t(locale, "menu:unpair.title"),
|
|
4551
5015
|
"",
|
|
4552
|
-
|
|
5016
|
+
this.t(locale, "menu:unpair.active_session", {
|
|
5017
|
+
sessionName: session?.label ?? activeSessionId,
|
|
5018
|
+
}),
|
|
4553
5019
|
"",
|
|
4554
|
-
"
|
|
4555
|
-
"
|
|
5020
|
+
this.t(locale, "menu:unpair.body_1"),
|
|
5021
|
+
this.t(locale, "menu:unpair.body_2"),
|
|
4556
5022
|
].join("\n");
|
|
4557
5023
|
}
|
|
4558
5024
|
async buildPruneConfirmText(ctx) {
|
|
5025
|
+
const locale = await this.resolveLocaleForContext(ctx);
|
|
4559
5026
|
const principal = this.getPrincipalFromContext(ctx);
|
|
4560
5027
|
if (!principal) {
|
|
4561
|
-
return
|
|
5028
|
+
return this.t(locale, "common:errors.no_telegram_identity");
|
|
4562
5029
|
}
|
|
4563
5030
|
const sessionIds = await this.bindingStore.listBoundSessionIdsForPrincipal(principal);
|
|
4564
5031
|
return [
|
|
4565
|
-
"
|
|
5032
|
+
this.t(locale, "menu:prune.title"),
|
|
4566
5033
|
"",
|
|
4567
|
-
|
|
5034
|
+
this.t(locale, "menu:prune.linked_sessions", {
|
|
5035
|
+
count: sessionIds.length,
|
|
5036
|
+
}),
|
|
4568
5037
|
"",
|
|
4569
|
-
"
|
|
4570
|
-
|
|
5038
|
+
this.t(locale, "menu:prune.body_1"),
|
|
5039
|
+
this.t(locale, "menu:prune.body_2"),
|
|
4571
5040
|
].join("\n");
|
|
4572
5041
|
}
|
|
4573
5042
|
async showActiveSessionInfo(ctx) {
|
|
5043
|
+
const locale = await this.resolveLocaleForContext(ctx);
|
|
4574
5044
|
const principal = this.getPrincipalFromContext(ctx);
|
|
4575
5045
|
if (!principal) {
|
|
4576
5046
|
await ctx.answerCallbackQuery({
|
|
4577
|
-
text: "
|
|
5047
|
+
text: this.t(locale, "common:errors.no_telegram_identity"),
|
|
4578
5048
|
show_alert: true,
|
|
4579
5049
|
});
|
|
4580
5050
|
return;
|
|
@@ -4582,7 +5052,7 @@ class TelegramTransport {
|
|
|
4582
5052
|
const sessionId = await this.bindingStore.getActiveSessionIdForPrincipal(principal);
|
|
4583
5053
|
if (!sessionId) {
|
|
4584
5054
|
await ctx.answerCallbackQuery({
|
|
4585
|
-
text: "
|
|
5055
|
+
text: this.t(locale, "common:errors.no_active_session"),
|
|
4586
5056
|
show_alert: true,
|
|
4587
5057
|
});
|
|
4588
5058
|
return;
|
|
@@ -4593,23 +5063,55 @@ class TelegramTransport {
|
|
|
4593
5063
|
const linkedSession = session?.linkedSessionId
|
|
4594
5064
|
? await this.sessionStore.getSession(session.linkedSessionId)
|
|
4595
5065
|
: null;
|
|
4596
|
-
await ctx.answerCallbackQuery({
|
|
5066
|
+
await ctx.answerCallbackQuery({
|
|
5067
|
+
text: this.t(locale, "menu:session_info.opened"),
|
|
5068
|
+
});
|
|
4597
5069
|
await this.replyText(ctx, [
|
|
4598
|
-
|
|
5070
|
+
this.t(locale, "menu:session_info.title"),
|
|
4599
5071
|
"",
|
|
4600
|
-
|
|
4601
|
-
|
|
4602
|
-
|
|
4603
|
-
|
|
4604
|
-
|
|
4605
|
-
|
|
5072
|
+
this.t(locale, "menu:session_info.label", {
|
|
5073
|
+
value: session?.label ?? sessionId,
|
|
5074
|
+
}),
|
|
5075
|
+
this.t(locale, "menu:session_info.session_id", {
|
|
5076
|
+
value: sessionId,
|
|
5077
|
+
}),
|
|
5078
|
+
this.t(locale, "menu:session_info.inbox_count", {
|
|
5079
|
+
count: inboxCount,
|
|
5080
|
+
}),
|
|
5081
|
+
this.t(locale, "menu:session_info.paired", {
|
|
5082
|
+
value: binding
|
|
5083
|
+
? this.t(locale, "menu:session_info.yes")
|
|
5084
|
+
: this.t(locale, "menu:session_info.no"),
|
|
5085
|
+
}),
|
|
5086
|
+
this.t(locale, "menu:session_info.partner", {
|
|
5087
|
+
value: linkedSession?.label ??
|
|
5088
|
+
session?.linkedSessionId ??
|
|
5089
|
+
this.t(locale, "menu:session_info.not_linked"),
|
|
5090
|
+
}),
|
|
5091
|
+
this.t(locale, "menu:session_info.tmux_target", {
|
|
5092
|
+
value: session?.tmuxTarget ?? this.t(locale, "menu:session_info.not_set"),
|
|
5093
|
+
}),
|
|
4606
5094
|
...(session?.tmuxSessionName
|
|
4607
|
-
? [
|
|
5095
|
+
? [
|
|
5096
|
+
this.t(locale, "menu:session_info.tmux_session", {
|
|
5097
|
+
value: session.tmuxSessionName,
|
|
5098
|
+
}),
|
|
5099
|
+
]
|
|
4608
5100
|
: []),
|
|
4609
5101
|
...(session?.tmuxWindowName
|
|
4610
|
-
? [
|
|
5102
|
+
? [
|
|
5103
|
+
this.t(locale, "menu:session_info.tmux_window", {
|
|
5104
|
+
value: session.tmuxWindowName,
|
|
5105
|
+
}),
|
|
5106
|
+
]
|
|
5107
|
+
: []),
|
|
5108
|
+
...(session?.tmuxPaneId
|
|
5109
|
+
? [
|
|
5110
|
+
this.t(locale, "menu:session_info.tmux_pane", {
|
|
5111
|
+
value: session.tmuxPaneId,
|
|
5112
|
+
}),
|
|
5113
|
+
]
|
|
4611
5114
|
: []),
|
|
4612
|
-
...(session?.tmuxPaneId ? [`🔹 tmux pane: ${session.tmuxPaneId}`] : []),
|
|
4613
5115
|
].join("\n"), { kind: "menu", sessionId }, { reply_markup: this.settingsMenu });
|
|
4614
5116
|
}
|
|
4615
5117
|
async linkSessions(sessionId, targetSessionId) {
|
|
@@ -4750,10 +5252,11 @@ class TelegramTransport {
|
|
|
4750
5252
|
}
|
|
4751
5253
|
}
|
|
4752
5254
|
async unpairActiveSession(ctx) {
|
|
5255
|
+
const locale = await this.resolveLocaleForContext(ctx);
|
|
4753
5256
|
const principal = this.getPrincipalFromContext(ctx);
|
|
4754
5257
|
if (!principal) {
|
|
4755
5258
|
await ctx.answerCallbackQuery({
|
|
4756
|
-
text: "
|
|
5259
|
+
text: this.t(locale, "common:errors.no_telegram_identity"),
|
|
4757
5260
|
show_alert: true,
|
|
4758
5261
|
});
|
|
4759
5262
|
return;
|
|
@@ -4761,7 +5264,7 @@ class TelegramTransport {
|
|
|
4761
5264
|
const sessionId = await this.bindingStore.getActiveSessionIdForPrincipal(principal);
|
|
4762
5265
|
if (!sessionId) {
|
|
4763
5266
|
await ctx.answerCallbackQuery({
|
|
4764
|
-
text: "
|
|
5267
|
+
text: this.t(locale, "common:errors.no_active_session"),
|
|
4765
5268
|
show_alert: true,
|
|
4766
5269
|
});
|
|
4767
5270
|
return;
|
|
@@ -4790,19 +5293,20 @@ class TelegramTransport {
|
|
|
4790
5293
|
});
|
|
4791
5294
|
this.clearPendingInteractionsForContext(ctx);
|
|
4792
5295
|
await ctx.answerCallbackQuery({
|
|
4793
|
-
text:
|
|
4794
|
-
|
|
4795
|
-
|
|
5296
|
+
text: this.t(locale, "menu:unpair.done", {
|
|
5297
|
+
sessionName: session?.label ?? sessionId,
|
|
5298
|
+
}),
|
|
4796
5299
|
});
|
|
4797
|
-
await this.showSessionsMenu(ctx,
|
|
4798
|
-
|
|
4799
|
-
|
|
5300
|
+
await this.showSessionsMenu(ctx, this.t(locale, "menu:unpair.shown", {
|
|
5301
|
+
sessionName: session?.label ?? sessionId,
|
|
5302
|
+
}));
|
|
4800
5303
|
}
|
|
4801
5304
|
async beginRenameActiveSession(ctx) {
|
|
5305
|
+
const locale = await this.resolveLocaleForContext(ctx);
|
|
4802
5306
|
const principal = this.getPrincipalFromContext(ctx);
|
|
4803
5307
|
if (!principal) {
|
|
4804
5308
|
await ctx.answerCallbackQuery({
|
|
4805
|
-
text: "
|
|
5309
|
+
text: this.t(locale, "common:errors.no_telegram_identity"),
|
|
4806
5310
|
show_alert: true,
|
|
4807
5311
|
});
|
|
4808
5312
|
return;
|
|
@@ -4810,7 +5314,7 @@ class TelegramTransport {
|
|
|
4810
5314
|
const sessionId = await this.bindingStore.getActiveSessionIdForPrincipal(principal);
|
|
4811
5315
|
if (!sessionId) {
|
|
4812
5316
|
await ctx.answerCallbackQuery({
|
|
4813
|
-
text: "
|
|
5317
|
+
text: this.t(locale, "common:errors.no_active_session"),
|
|
4814
5318
|
show_alert: true,
|
|
4815
5319
|
});
|
|
4816
5320
|
return;
|
|
@@ -4818,19 +5322,17 @@ class TelegramTransport {
|
|
|
4818
5322
|
const principalKey = buildPrincipalKey(principal);
|
|
4819
5323
|
this.pendingBroadcasts.delete(principalKey);
|
|
4820
5324
|
this.pendingRenames.set(principalKey, { sessionId });
|
|
4821
|
-
await ctx.answerCallbackQuery({
|
|
4822
|
-
|
|
4823
|
-
|
|
4824
|
-
|
|
4825
|
-
"Send the next text message as the new title for the active session.",
|
|
4826
|
-
"Commands like /menu or /help will cancel rename mode.",
|
|
4827
|
-
].join("\n"), { kind: "menu", sessionId });
|
|
5325
|
+
await ctx.answerCallbackQuery({
|
|
5326
|
+
text: this.t(locale, "menu:settings.actions.rename_prompt"),
|
|
5327
|
+
});
|
|
5328
|
+
await this.replyText(ctx, ["✏ Rename session", "", this.t(locale, "menu:settings.actions.rename_body")].join("\n"), { kind: "menu", sessionId });
|
|
4828
5329
|
}
|
|
4829
5330
|
async beginBroadcast(ctx) {
|
|
5331
|
+
const locale = await this.resolveLocaleForContext(ctx);
|
|
4830
5332
|
const principal = this.getPrincipalFromContext(ctx);
|
|
4831
5333
|
if (!principal) {
|
|
4832
5334
|
await ctx.answerCallbackQuery({
|
|
4833
|
-
text: "
|
|
5335
|
+
text: this.t(locale, "common:errors.no_telegram_identity"),
|
|
4834
5336
|
show_alert: true,
|
|
4835
5337
|
});
|
|
4836
5338
|
return;
|
|
@@ -4838,7 +5340,7 @@ class TelegramTransport {
|
|
|
4838
5340
|
const sessionIds = await this.bindingStore.listBoundSessionIdsForPrincipal(principal);
|
|
4839
5341
|
if (sessionIds.length === 0) {
|
|
4840
5342
|
await ctx.answerCallbackQuery({
|
|
4841
|
-
text: "
|
|
5343
|
+
text: this.t(locale, "menu:broadcast.no_linked_sessions"),
|
|
4842
5344
|
show_alert: true,
|
|
4843
5345
|
});
|
|
4844
5346
|
return;
|
|
@@ -4846,14 +5348,18 @@ class TelegramTransport {
|
|
|
4846
5348
|
const principalKey = buildPrincipalKey(principal);
|
|
4847
5349
|
this.pendingRenames.delete(principalKey);
|
|
4848
5350
|
await ctx.answerCallbackQuery({
|
|
4849
|
-
text:
|
|
5351
|
+
text: this.t(locale, "menu:broadcast.begin", {
|
|
5352
|
+
count: sessionIds.length,
|
|
5353
|
+
}),
|
|
4850
5354
|
});
|
|
4851
5355
|
const sent = await this.replyText(ctx, [
|
|
4852
|
-
|
|
5356
|
+
this.t(locale, "menu:broadcast.title"),
|
|
4853
5357
|
"",
|
|
4854
|
-
|
|
4855
|
-
|
|
4856
|
-
|
|
5358
|
+
this.t(locale, "menu:broadcast.body", {
|
|
5359
|
+
count: sessionIds.length,
|
|
5360
|
+
}),
|
|
5361
|
+
this.t(locale, "menu:broadcast.hint"),
|
|
5362
|
+
this.t(locale, "menu:broadcast.cancel_hint"),
|
|
4857
5363
|
].join("\n"), { kind: "menu" }, {
|
|
4858
5364
|
reply_markup: new grammy_1.InlineKeyboard().text("Cancel", "broadcast-cancel"),
|
|
4859
5365
|
});
|
|
@@ -4867,10 +5373,11 @@ class TelegramTransport {
|
|
|
4867
5373
|
});
|
|
4868
5374
|
}
|
|
4869
5375
|
async beginProjectBroadcast(ctx) {
|
|
5376
|
+
const locale = await this.resolveLocaleForContext(ctx);
|
|
4870
5377
|
const principal = this.getPrincipalFromContext(ctx);
|
|
4871
5378
|
if (!principal) {
|
|
4872
5379
|
await ctx.answerCallbackQuery({
|
|
4873
|
-
text: "
|
|
5380
|
+
text: this.t(locale, "common:errors.no_telegram_identity"),
|
|
4874
5381
|
show_alert: true,
|
|
4875
5382
|
});
|
|
4876
5383
|
return;
|
|
@@ -4878,7 +5385,7 @@ class TelegramTransport {
|
|
|
4878
5385
|
const sessionId = await this.bindingStore.getActiveSessionIdForPrincipal(principal);
|
|
4879
5386
|
if (!sessionId) {
|
|
4880
5387
|
await ctx.answerCallbackQuery({
|
|
4881
|
-
text:
|
|
5388
|
+
text: this.t(locale, "common:errors.no_active_session"),
|
|
4882
5389
|
show_alert: true,
|
|
4883
5390
|
});
|
|
4884
5391
|
return;
|
|
@@ -4886,7 +5393,7 @@ class TelegramTransport {
|
|
|
4886
5393
|
const projects = await this.listGatewayProjects(principal);
|
|
4887
5394
|
if (projects.length === 0) {
|
|
4888
5395
|
await ctx.answerCallbackQuery({
|
|
4889
|
-
text:
|
|
5396
|
+
text: this.t(locale, "menu:broadcast.no_projects_first"),
|
|
4890
5397
|
show_alert: true,
|
|
4891
5398
|
});
|
|
4892
5399
|
return;
|
|
@@ -4895,7 +5402,7 @@ class TelegramTransport {
|
|
|
4895
5402
|
const totalTargets = targets.localTargetSessionIds.length + targets.remoteTargets.length;
|
|
4896
5403
|
if (totalTargets === 0) {
|
|
4897
5404
|
await ctx.answerCallbackQuery({
|
|
4898
|
-
text: "
|
|
5405
|
+
text: this.t(locale, "menu:broadcast.no_collab_targets"),
|
|
4899
5406
|
show_alert: true,
|
|
4900
5407
|
});
|
|
4901
5408
|
return;
|
|
@@ -4903,17 +5410,23 @@ class TelegramTransport {
|
|
|
4903
5410
|
const principalKey = buildPrincipalKey(principal);
|
|
4904
5411
|
this.pendingRenames.delete(principalKey);
|
|
4905
5412
|
await ctx.answerCallbackQuery({
|
|
4906
|
-
text:
|
|
5413
|
+
text: this.t(locale, "menu:broadcast.collab_begin", {
|
|
5414
|
+
count: totalTargets,
|
|
5415
|
+
}),
|
|
4907
5416
|
});
|
|
4908
5417
|
const sent = await this.replyText(ctx, [
|
|
4909
|
-
|
|
5418
|
+
this.t(locale, "menu:broadcast.collab_title"),
|
|
4910
5419
|
"",
|
|
4911
|
-
|
|
4912
|
-
|
|
5420
|
+
this.t(locale, "menu:broadcast.collab_projects", {
|
|
5421
|
+
count: projects.length,
|
|
5422
|
+
}),
|
|
5423
|
+
this.t(locale, "menu:broadcast.collab_sessions", {
|
|
5424
|
+
count: totalTargets,
|
|
5425
|
+
}),
|
|
4913
5426
|
"",
|
|
4914
|
-
|
|
4915
|
-
|
|
4916
|
-
"
|
|
5427
|
+
this.t(locale, "menu:broadcast.collab_body"),
|
|
5428
|
+
this.t(locale, "menu:broadcast.collab_hint"),
|
|
5429
|
+
this.t(locale, "menu:broadcast.cancel_hint"),
|
|
4917
5430
|
].join("\n"), { kind: "menu", sessionId }, {
|
|
4918
5431
|
reply_markup: new grammy_1.InlineKeyboard().text("Cancel", "broadcast-cancel"),
|
|
4919
5432
|
});
|
|
@@ -4992,10 +5505,11 @@ class TelegramTransport {
|
|
|
4992
5505
|
}
|
|
4993
5506
|
}
|
|
4994
5507
|
async cancelPendingBroadcast(ctx) {
|
|
5508
|
+
const locale = await this.resolveLocaleForContext(ctx);
|
|
4995
5509
|
const principal = this.getPrincipalFromContext(ctx);
|
|
4996
5510
|
if (!principal) {
|
|
4997
5511
|
await ctx.answerCallbackQuery({
|
|
4998
|
-
text: "
|
|
5512
|
+
text: this.t(locale, "common:errors.no_telegram_identity"),
|
|
4999
5513
|
show_alert: true,
|
|
5000
5514
|
});
|
|
5001
5515
|
return;
|
|
@@ -5004,7 +5518,7 @@ class TelegramTransport {
|
|
|
5004
5518
|
const pending = this.pendingBroadcasts.get(principalKey);
|
|
5005
5519
|
if (!pending) {
|
|
5006
5520
|
await ctx.answerCallbackQuery({
|
|
5007
|
-
text: "
|
|
5521
|
+
text: this.t(locale, "menu:broadcast.mode_not_active"),
|
|
5008
5522
|
show_alert: true,
|
|
5009
5523
|
});
|
|
5010
5524
|
return;
|
|
@@ -5013,7 +5527,9 @@ class TelegramTransport {
|
|
|
5013
5527
|
await this.deletePendingBroadcastArtifacts(ctx, pending, {
|
|
5014
5528
|
deleteMenuMessage: false,
|
|
5015
5529
|
});
|
|
5016
|
-
await ctx.answerCallbackQuery({
|
|
5530
|
+
await ctx.answerCallbackQuery({
|
|
5531
|
+
text: this.t(locale, "menu:broadcast.cancelled"),
|
|
5532
|
+
});
|
|
5017
5533
|
if (pending.scope === "project") {
|
|
5018
5534
|
await this.showCollabToolsMenu(ctx);
|
|
5019
5535
|
return;
|
|
@@ -5223,12 +5739,22 @@ class TelegramTransport {
|
|
|
5223
5739
|
});
|
|
5224
5740
|
await this.replyText(ctx, pending.scope === "project"
|
|
5225
5741
|
? [
|
|
5226
|
-
"
|
|
5227
|
-
|
|
5228
|
-
|
|
5229
|
-
|
|
5742
|
+
this.t(await this.resolveLocaleForContext(ctx), "menu:broadcast.completed_collab", {
|
|
5743
|
+
count: storedCount + remoteCount,
|
|
5744
|
+
}),
|
|
5745
|
+
this.t(await this.resolveLocaleForContext(ctx), "menu:broadcast.completed_collab_local", {
|
|
5746
|
+
count: storedCount,
|
|
5747
|
+
}),
|
|
5748
|
+
this.t(await this.resolveLocaleForContext(ctx), "menu:broadcast.completed_collab_remote", {
|
|
5749
|
+
count: remoteCount,
|
|
5750
|
+
}),
|
|
5751
|
+
this.t(await this.resolveLocaleForContext(ctx), "menu:broadcast.completed_collab_total", {
|
|
5752
|
+
count: storedCount + remoteCount,
|
|
5753
|
+
}),
|
|
5230
5754
|
].join("\n")
|
|
5231
|
-
:
|
|
5755
|
+
: await this.tForContext(ctx, "menu:broadcast.completed_linked", {
|
|
5756
|
+
count: storedCount,
|
|
5757
|
+
}), {
|
|
5232
5758
|
kind: "menu",
|
|
5233
5759
|
...(pending.sessionId ? { sessionId: pending.sessionId } : {}),
|
|
5234
5760
|
});
|
|
@@ -5245,10 +5771,11 @@ class TelegramTransport {
|
|
|
5245
5771
|
};
|
|
5246
5772
|
}
|
|
5247
5773
|
async beginPartnerNoteMode(ctx, kind, target) {
|
|
5774
|
+
const locale = await this.resolveLocaleForContext(ctx);
|
|
5248
5775
|
const principal = this.getPrincipalFromContext(ctx);
|
|
5249
5776
|
if (!principal) {
|
|
5250
5777
|
await ctx.answerCallbackQuery({
|
|
5251
|
-
text: "
|
|
5778
|
+
text: this.t(locale, "common:errors.no_telegram_identity"),
|
|
5252
5779
|
show_alert: true,
|
|
5253
5780
|
});
|
|
5254
5781
|
return;
|
|
@@ -5256,7 +5783,7 @@ class TelegramTransport {
|
|
|
5256
5783
|
const sessionId = await this.bindingStore.getActiveSessionIdForPrincipal(principal);
|
|
5257
5784
|
if (!sessionId) {
|
|
5258
5785
|
await ctx.answerCallbackQuery({
|
|
5259
|
-
text: "
|
|
5786
|
+
text: this.t(locale, "common:errors.no_active_session"),
|
|
5260
5787
|
show_alert: true,
|
|
5261
5788
|
});
|
|
5262
5789
|
return;
|
|
@@ -5264,7 +5791,7 @@ class TelegramTransport {
|
|
|
5264
5791
|
const session = await this.sessionStore.getSession(sessionId);
|
|
5265
5792
|
if (!target && !session?.linkedSessionId) {
|
|
5266
5793
|
await ctx.answerCallbackQuery({
|
|
5267
|
-
text: "
|
|
5794
|
+
text: this.t(locale, "menu:partner.screen.use_link_first"),
|
|
5268
5795
|
show_alert: true,
|
|
5269
5796
|
});
|
|
5270
5797
|
return;
|
|
@@ -5275,7 +5802,7 @@ class TelegramTransport {
|
|
|
5275
5802
|
const targetLabel = target?.targetSessionLabel ??
|
|
5276
5803
|
linkedSession?.label ??
|
|
5277
5804
|
session?.linkedSessionId ??
|
|
5278
|
-
"
|
|
5805
|
+
this.t(locale, "menu:partner.screen.default_partner");
|
|
5279
5806
|
const sourceLabel = session?.label ?? sessionId;
|
|
5280
5807
|
const isProjectTarget = Boolean(target?.projectUuid);
|
|
5281
5808
|
const prompt = (0, collabUi_1.buildPartnerNotePromptText)({
|
|
@@ -5287,7 +5814,7 @@ class TelegramTransport {
|
|
|
5287
5814
|
const kindLabel = prompt.kindLabel;
|
|
5288
5815
|
await ctx.answerCallbackQuery({ text: `${kindLabel}.` });
|
|
5289
5816
|
const sent = await this.replyText(ctx, prompt.text, { kind: "menu", sessionId }, {
|
|
5290
|
-
reply_markup: new grammy_1.InlineKeyboard().text("
|
|
5817
|
+
reply_markup: new grammy_1.InlineKeyboard().text(this.t(locale, "menu:handoff.cancel"), "partner-note-cancel"),
|
|
5291
5818
|
});
|
|
5292
5819
|
this.pendingPartnerNotes.set(buildPrincipalKey(principal), {
|
|
5293
5820
|
sessionId,
|
|
@@ -5315,10 +5842,11 @@ class TelegramTransport {
|
|
|
5315
5842
|
}
|
|
5316
5843
|
}
|
|
5317
5844
|
async cancelPendingPartnerNote(ctx) {
|
|
5845
|
+
const locale = await this.resolveLocaleForContext(ctx);
|
|
5318
5846
|
const principal = this.getPrincipalFromContext(ctx);
|
|
5319
5847
|
if (!principal) {
|
|
5320
5848
|
await ctx.answerCallbackQuery({
|
|
5321
|
-
text:
|
|
5849
|
+
text: this.t(locale, "common:errors.no_telegram_identity"),
|
|
5322
5850
|
show_alert: true,
|
|
5323
5851
|
});
|
|
5324
5852
|
return;
|
|
@@ -5327,21 +5855,24 @@ class TelegramTransport {
|
|
|
5327
5855
|
const pending = this.pendingPartnerNotes.get(principalKey);
|
|
5328
5856
|
if (!pending) {
|
|
5329
5857
|
await ctx.answerCallbackQuery({
|
|
5330
|
-
text:
|
|
5858
|
+
text: this.t(locale, "menu:partner.actions.no_pending_note_input"),
|
|
5331
5859
|
show_alert: true,
|
|
5332
5860
|
});
|
|
5333
5861
|
return;
|
|
5334
5862
|
}
|
|
5335
5863
|
this.pendingPartnerNotes.delete(principalKey);
|
|
5336
5864
|
await this.deletePendingPartnerNotePrompt(ctx, pending);
|
|
5337
|
-
await ctx.answerCallbackQuery({
|
|
5865
|
+
await ctx.answerCallbackQuery({
|
|
5866
|
+
text: this.t(locale, "menu:partner.actions.cancel_note_input"),
|
|
5867
|
+
});
|
|
5338
5868
|
await this.showPartnerMenu(ctx);
|
|
5339
5869
|
}
|
|
5340
5870
|
async beginProjectMode(ctx, mode) {
|
|
5871
|
+
const locale = await this.resolveLocaleForContext(ctx);
|
|
5341
5872
|
const principal = this.getPrincipalFromContext(ctx);
|
|
5342
5873
|
if (!principal) {
|
|
5343
5874
|
await ctx.answerCallbackQuery({
|
|
5344
|
-
text: "
|
|
5875
|
+
text: this.t(locale, "common:errors.no_telegram_identity"),
|
|
5345
5876
|
show_alert: true,
|
|
5346
5877
|
});
|
|
5347
5878
|
return;
|
|
@@ -5349,23 +5880,23 @@ class TelegramTransport {
|
|
|
5349
5880
|
const sessionId = await this.bindingStore.getActiveSessionIdForPrincipal(principal);
|
|
5350
5881
|
if (!sessionId) {
|
|
5351
5882
|
await ctx.answerCallbackQuery({
|
|
5352
|
-
text: "
|
|
5883
|
+
text: this.t(locale, "common:errors.no_active_session"),
|
|
5353
5884
|
show_alert: true,
|
|
5354
5885
|
});
|
|
5355
5886
|
return;
|
|
5356
5887
|
}
|
|
5357
5888
|
const sent = await this.replyText(ctx, mode === "create"
|
|
5358
5889
|
? [
|
|
5359
|
-
|
|
5890
|
+
this.t(locale, "menu:project.create_prompt_title"),
|
|
5360
5891
|
"",
|
|
5361
|
-
|
|
5362
|
-
"
|
|
5892
|
+
this.t(locale, "menu:project.create_prompt_body"),
|
|
5893
|
+
this.t(locale, "menu:project.prompt_cancel"),
|
|
5363
5894
|
].join("\n")
|
|
5364
5895
|
: [
|
|
5365
|
-
|
|
5896
|
+
this.t(locale, "menu:project.join_prompt_title"),
|
|
5366
5897
|
"",
|
|
5367
|
-
|
|
5368
|
-
"
|
|
5898
|
+
this.t(locale, "menu:project.join_prompt_body"),
|
|
5899
|
+
this.t(locale, "menu:project.prompt_cancel"),
|
|
5369
5900
|
].join("\n"), { kind: "menu", sessionId });
|
|
5370
5901
|
this.pendingProjects.set(buildPrincipalKey(principal), {
|
|
5371
5902
|
sessionId,
|
|
@@ -5374,14 +5905,17 @@ class TelegramTransport {
|
|
|
5374
5905
|
...(sent ? { promptMessageId: sent.message_id } : {}),
|
|
5375
5906
|
});
|
|
5376
5907
|
await ctx.answerCallbackQuery({
|
|
5377
|
-
text: mode === "create"
|
|
5908
|
+
text: mode === "create"
|
|
5909
|
+
? this.t(locale, "menu:project.start_create")
|
|
5910
|
+
: this.t(locale, "menu:project.start_join"),
|
|
5378
5911
|
});
|
|
5379
5912
|
}
|
|
5380
5913
|
async handleProjectSelect(ctx) {
|
|
5914
|
+
const locale = await this.resolveLocaleForContext(ctx);
|
|
5381
5915
|
const payloadKey = readMenuPayloadKey(ctx);
|
|
5382
5916
|
if (!payloadKey) {
|
|
5383
5917
|
await ctx.answerCallbackQuery({
|
|
5384
|
-
text:
|
|
5918
|
+
text: this.t(locale, "menu:project.data_missing"),
|
|
5385
5919
|
show_alert: true,
|
|
5386
5920
|
});
|
|
5387
5921
|
return;
|
|
@@ -5392,7 +5926,7 @@ class TelegramTransport {
|
|
|
5392
5926
|
!payload.sessionId ||
|
|
5393
5927
|
!payload.projectUuid) {
|
|
5394
5928
|
await ctx.answerCallbackQuery({
|
|
5395
|
-
text:
|
|
5929
|
+
text: this.t(locale, "menu:project.data_stale"),
|
|
5396
5930
|
show_alert: true,
|
|
5397
5931
|
});
|
|
5398
5932
|
return;
|
|
@@ -5400,7 +5934,7 @@ class TelegramTransport {
|
|
|
5400
5934
|
const principal = this.getPrincipalFromContext(ctx);
|
|
5401
5935
|
if (!principal) {
|
|
5402
5936
|
await ctx.answerCallbackQuery({
|
|
5403
|
-
text: "
|
|
5937
|
+
text: this.t(locale, "common:errors.no_telegram_identity"),
|
|
5404
5938
|
show_alert: true,
|
|
5405
5939
|
});
|
|
5406
5940
|
return;
|
|
@@ -5408,7 +5942,7 @@ class TelegramTransport {
|
|
|
5408
5942
|
const project = await this.getProjectPayloadByUuid(payload.sessionId, payload.projectUuid);
|
|
5409
5943
|
if (!project) {
|
|
5410
5944
|
await ctx.answerCallbackQuery({
|
|
5411
|
-
text:
|
|
5945
|
+
text: this.t(locale, "menu:project.not_found"),
|
|
5412
5946
|
show_alert: true,
|
|
5413
5947
|
});
|
|
5414
5948
|
return;
|
|
@@ -5419,14 +5953,17 @@ class TelegramTransport {
|
|
|
5419
5953
|
projectUuid: project.projectUuid,
|
|
5420
5954
|
projectName: project.projectName,
|
|
5421
5955
|
});
|
|
5422
|
-
await ctx.answerCallbackQuery({
|
|
5956
|
+
await ctx.answerCallbackQuery({
|
|
5957
|
+
text: this.t(locale, "menu:project.opening_members"),
|
|
5958
|
+
});
|
|
5423
5959
|
await this.showProjectMembers(ctx, project);
|
|
5424
5960
|
}
|
|
5425
5961
|
async handleProjectDeleteSelect(ctx) {
|
|
5962
|
+
const locale = await this.resolveLocaleForContext(ctx);
|
|
5426
5963
|
const payloadKey = readMenuPayloadKey(ctx);
|
|
5427
5964
|
if (!payloadKey) {
|
|
5428
5965
|
await ctx.answerCallbackQuery({
|
|
5429
|
-
text:
|
|
5966
|
+
text: this.t(locale, "menu:project.data_missing"),
|
|
5430
5967
|
show_alert: true,
|
|
5431
5968
|
});
|
|
5432
5969
|
return;
|
|
@@ -5437,7 +5974,7 @@ class TelegramTransport {
|
|
|
5437
5974
|
!payload.sessionId ||
|
|
5438
5975
|
!payload.projectUuid) {
|
|
5439
5976
|
await ctx.answerCallbackQuery({
|
|
5440
|
-
text:
|
|
5977
|
+
text: this.t(locale, "menu:project.data_stale"),
|
|
5441
5978
|
show_alert: true,
|
|
5442
5979
|
});
|
|
5443
5980
|
await ctx.deleteMessage().catch(() => undefined);
|
|
@@ -5446,7 +5983,7 @@ class TelegramTransport {
|
|
|
5446
5983
|
const principal = this.getPrincipalFromContext(ctx);
|
|
5447
5984
|
if (!principal) {
|
|
5448
5985
|
await ctx.answerCallbackQuery({
|
|
5449
|
-
text: "
|
|
5986
|
+
text: this.t(locale, "common:errors.no_telegram_identity"),
|
|
5450
5987
|
show_alert: true,
|
|
5451
5988
|
});
|
|
5452
5989
|
return;
|
|
@@ -5455,7 +5992,7 @@ class TelegramTransport {
|
|
|
5455
5992
|
const project = projects.find((item) => item.project_uuid === payload.projectUuid);
|
|
5456
5993
|
if (!project) {
|
|
5457
5994
|
await ctx.answerCallbackQuery({
|
|
5458
|
-
text:
|
|
5995
|
+
text: this.t(locale, "menu:project.not_found"),
|
|
5459
5996
|
show_alert: true,
|
|
5460
5997
|
});
|
|
5461
5998
|
await ctx.deleteMessage().catch(() => undefined);
|
|
@@ -5463,7 +6000,7 @@ class TelegramTransport {
|
|
|
5463
6000
|
}
|
|
5464
6001
|
if (project.role !== "owner") {
|
|
5465
6002
|
await ctx.answerCallbackQuery({
|
|
5466
|
-
text: "
|
|
6003
|
+
text: this.t(locale, "menu:project.delete_only_owner"),
|
|
5467
6004
|
show_alert: true,
|
|
5468
6005
|
});
|
|
5469
6006
|
return;
|
|
@@ -5471,10 +6008,11 @@ class TelegramTransport {
|
|
|
5471
6008
|
await this.handleProjectDeleteByUuid(ctx, payload.projectUuid);
|
|
5472
6009
|
}
|
|
5473
6010
|
async leaveActiveProject(ctx) {
|
|
6011
|
+
const locale = await this.resolveLocaleForContext(ctx);
|
|
5474
6012
|
const principal = this.getPrincipalFromContext(ctx);
|
|
5475
6013
|
if (!principal) {
|
|
5476
6014
|
await ctx.answerCallbackQuery({
|
|
5477
|
-
text: "
|
|
6015
|
+
text: this.t(locale, "common:errors.no_telegram_identity"),
|
|
5478
6016
|
show_alert: true,
|
|
5479
6017
|
});
|
|
5480
6018
|
return;
|
|
@@ -5482,7 +6020,7 @@ class TelegramTransport {
|
|
|
5482
6020
|
const sessionId = await this.bindingStore.getActiveSessionIdForPrincipal(principal);
|
|
5483
6021
|
if (!sessionId) {
|
|
5484
6022
|
await ctx.answerCallbackQuery({
|
|
5485
|
-
text: "
|
|
6023
|
+
text: this.t(locale, "common:errors.no_active_session"),
|
|
5486
6024
|
show_alert: true,
|
|
5487
6025
|
});
|
|
5488
6026
|
return;
|
|
@@ -5490,7 +6028,7 @@ class TelegramTransport {
|
|
|
5490
6028
|
const session = await this.sessionStore.getSession(sessionId);
|
|
5491
6029
|
if (!session?.activeProjectUuid) {
|
|
5492
6030
|
await ctx.answerCallbackQuery({
|
|
5493
|
-
text: "
|
|
6031
|
+
text: this.t(locale, "menu:project.no_active_project"),
|
|
5494
6032
|
show_alert: true,
|
|
5495
6033
|
});
|
|
5496
6034
|
return;
|
|
@@ -5506,8 +6044,10 @@ class TelegramTransport {
|
|
|
5506
6044
|
activeProjectName: undefined,
|
|
5507
6045
|
updatedAt: new Date().toISOString(),
|
|
5508
6046
|
});
|
|
5509
|
-
await ctx.answerCallbackQuery({
|
|
5510
|
-
|
|
6047
|
+
await ctx.answerCallbackQuery({
|
|
6048
|
+
text: this.t(locale, "menu:project.left_current"),
|
|
6049
|
+
});
|
|
6050
|
+
await this.showProjectsMenu(ctx, this.t(locale, "menu:project.left_current_screen"));
|
|
5511
6051
|
}
|
|
5512
6052
|
async showProjectDetail(ctx, input) {
|
|
5513
6053
|
await this.showProjectMembers(ctx, input);
|
|
@@ -5555,6 +6095,7 @@ class TelegramTransport {
|
|
|
5555
6095
|
if (!binding) {
|
|
5556
6096
|
throw new Error("Binding is missing for project members screen.");
|
|
5557
6097
|
}
|
|
6098
|
+
const locale = await this.resolveLocaleForTelegramUserId(binding.telegramUserId);
|
|
5558
6099
|
const sessions = await this.listGatewayProjectSessions({
|
|
5559
6100
|
telegramChatId: binding.telegramChatId,
|
|
5560
6101
|
telegramUserId: binding.telegramUserId,
|
|
@@ -5562,19 +6103,25 @@ class TelegramTransport {
|
|
|
5562
6103
|
const activeSessionId = session?.sessionId ?? null;
|
|
5563
6104
|
const selectableMembers = sessions.filter((item) => item.local_session_id !== activeSessionId);
|
|
5564
6105
|
const lines = [
|
|
5565
|
-
|
|
6106
|
+
this.t(locale, "menu:project.members_title", {
|
|
6107
|
+
projectName: escapeHtml(input.projectName),
|
|
6108
|
+
}),
|
|
5566
6109
|
"",
|
|
5567
6110
|
`UUID: ${input.projectUuid}`,
|
|
5568
6111
|
`Invite: <code>${escapeHtml(input.inviteToken)}</code>`,
|
|
5569
6112
|
"",
|
|
5570
|
-
|
|
5571
|
-
|
|
6113
|
+
this.t(locale, "menu:project.current_session", {
|
|
6114
|
+
sessionName: escapeHtml(session?.label ?? input.sessionId),
|
|
6115
|
+
}),
|
|
6116
|
+
this.t(locale, "menu:project.other_sessions", {
|
|
6117
|
+
count: selectableMembers.length,
|
|
6118
|
+
}),
|
|
5572
6119
|
"",
|
|
5573
6120
|
selectableMembers.length > 0
|
|
5574
6121
|
? options?.filePath
|
|
5575
|
-
?
|
|
5576
|
-
:
|
|
5577
|
-
:
|
|
6122
|
+
? this.t(locale, "menu:project.choose_file_target")
|
|
6123
|
+
: this.t(locale, "menu:project.choose_member_action")
|
|
6124
|
+
: this.t(locale, "menu:project.no_other_active"),
|
|
5578
6125
|
];
|
|
5579
6126
|
const keyboard = new grammy_1.InlineKeyboard();
|
|
5580
6127
|
for (const member of selectableMembers) {
|
|
@@ -5598,11 +6145,12 @@ class TelegramTransport {
|
|
|
5598
6145
|
keyboard.text(buttonLabel, `project-member-open:${payloadKey}`).row();
|
|
5599
6146
|
}
|
|
5600
6147
|
keyboard
|
|
5601
|
-
.text(
|
|
5602
|
-
.text(
|
|
6148
|
+
.text(this.t(locale, "menu:project.leave"), `project-leave:${input.projectUuid}`)
|
|
6149
|
+
.text(this.t(locale, "menu:project.back_to_projects"), "project-back");
|
|
5603
6150
|
return { text: lines.join("\n"), keyboard };
|
|
5604
6151
|
}
|
|
5605
6152
|
async showProjectMemberDetail(ctx, input) {
|
|
6153
|
+
const locale = await this.resolveLocaleForContext(ctx);
|
|
5606
6154
|
const principal = this.getPrincipalFromContext(ctx);
|
|
5607
6155
|
if (principal) {
|
|
5608
6156
|
await this.ensureOpenedProjectIsActive({
|
|
@@ -5637,8 +6185,8 @@ class TelegramTransport {
|
|
|
5637
6185
|
: {}),
|
|
5638
6186
|
});
|
|
5639
6187
|
const keyboard = new grammy_1.InlineKeyboard()
|
|
5640
|
-
.text(
|
|
5641
|
-
.text(
|
|
6188
|
+
.text(this.t(locale, "menu:project.ask"), `project-member-note:question:${payloadKey}`)
|
|
6189
|
+
.text(this.t(locale, "menu:project.share_button"), `project-member-note:share:${payloadKey}`)
|
|
5642
6190
|
.row();
|
|
5643
6191
|
if (this.config.webapp.enabled &&
|
|
5644
6192
|
this.config.distributed.gatewayPublicUrl &&
|
|
@@ -5647,7 +6195,7 @@ class TelegramTransport {
|
|
|
5647
6195
|
input.targetLocalSessionId) {
|
|
5648
6196
|
keyboard.text("🖥 Live", `project-member-live:${payloadKey}`).row();
|
|
5649
6197
|
}
|
|
5650
|
-
keyboard.text(
|
|
6198
|
+
keyboard.text(this.t(locale, "menu:project.back_to_members"), `project-members:${input.projectUuid}`);
|
|
5651
6199
|
if (ctx.callbackQuery?.message) {
|
|
5652
6200
|
if (principal && ctx.chat && "message_id" in ctx.callbackQuery.message) {
|
|
5653
6201
|
this.webAppLaunchRegistry.set(principal.telegramUserId, input.sessionId, this.config.webapp.initDataTtlSeconds, {
|
|
@@ -5669,6 +6217,7 @@ class TelegramTransport {
|
|
|
5669
6217
|
}
|
|
5670
6218
|
}
|
|
5671
6219
|
async showProjectMemberFiles(ctx, input) {
|
|
6220
|
+
const locale = await this.resolveLocaleForContext(ctx);
|
|
5672
6221
|
const principal = this.getPrincipalFromContext(ctx);
|
|
5673
6222
|
if (principal) {
|
|
5674
6223
|
await this.ensureOpenedProjectIsActive({
|
|
@@ -5680,14 +6229,18 @@ class TelegramTransport {
|
|
|
5680
6229
|
}
|
|
5681
6230
|
const files = await this.listActiveSessionFiles(input.sessionId);
|
|
5682
6231
|
const lines = [
|
|
5683
|
-
|
|
6232
|
+
this.t(locale, "menu:project.file_title"),
|
|
5684
6233
|
"",
|
|
5685
|
-
|
|
5686
|
-
|
|
6234
|
+
this.t(locale, "menu:project.file_project", {
|
|
6235
|
+
projectName: input.projectName,
|
|
6236
|
+
}),
|
|
6237
|
+
this.t(locale, "menu:project.file_recipient", {
|
|
6238
|
+
label: input.targetSessionLabel,
|
|
6239
|
+
}),
|
|
5687
6240
|
"",
|
|
5688
6241
|
files.length > 0
|
|
5689
|
-
?
|
|
5690
|
-
:
|
|
6242
|
+
? this.t(locale, "menu:project.file_choose")
|
|
6243
|
+
: this.t(locale, "menu:project.file_none"),
|
|
5691
6244
|
];
|
|
5692
6245
|
const keyboard = new grammy_1.InlineKeyboard();
|
|
5693
6246
|
for (const filePath of files) {
|
|
@@ -5704,7 +6257,7 @@ class TelegramTransport {
|
|
|
5704
6257
|
});
|
|
5705
6258
|
keyboard.text(label, `project-member-open:${payloadKey}`).row();
|
|
5706
6259
|
}
|
|
5707
|
-
keyboard.text(
|
|
6260
|
+
keyboard.text(this.t(locale, "menu:project.back_to_session"), `project-member-open:${await this.createProjectMemberMenuPayload(input.sessionId, input.projectUuid, input.targetSessionId, input.targetSessionLabel, {
|
|
5708
6261
|
...(input.targetClientUuid
|
|
5709
6262
|
? { targetClientUuid: input.targetClientUuid }
|
|
5710
6263
|
: {}),
|
|
@@ -5826,11 +6379,12 @@ class TelegramTransport {
|
|
|
5826
6379
|
return data.slice(prefix.length) || null;
|
|
5827
6380
|
}
|
|
5828
6381
|
async handleProjectSetCallback(ctx) {
|
|
6382
|
+
const locale = await this.resolveLocaleForContext(ctx);
|
|
5829
6383
|
const projectUuid = this.extractCallbackSuffix(ctx, "project-set:");
|
|
5830
6384
|
const principal = this.getPrincipalFromContext(ctx);
|
|
5831
6385
|
if (!projectUuid || !principal) {
|
|
5832
6386
|
await ctx.answerCallbackQuery({
|
|
5833
|
-
text:
|
|
6387
|
+
text: this.t(locale, "menu:project.invalid_action"),
|
|
5834
6388
|
show_alert: true,
|
|
5835
6389
|
});
|
|
5836
6390
|
return;
|
|
@@ -5838,7 +6392,7 @@ class TelegramTransport {
|
|
|
5838
6392
|
const sessionId = await this.bindingStore.getActiveSessionIdForPrincipal(principal);
|
|
5839
6393
|
if (!sessionId) {
|
|
5840
6394
|
await ctx.answerCallbackQuery({
|
|
5841
|
-
text:
|
|
6395
|
+
text: this.t(locale, "common:errors.no_active_session"),
|
|
5842
6396
|
show_alert: true,
|
|
5843
6397
|
});
|
|
5844
6398
|
return;
|
|
@@ -5846,7 +6400,7 @@ class TelegramTransport {
|
|
|
5846
6400
|
const payload = await this.getProjectPayloadByUuid(sessionId, projectUuid);
|
|
5847
6401
|
if (!payload) {
|
|
5848
6402
|
await ctx.answerCallbackQuery({
|
|
5849
|
-
text:
|
|
6403
|
+
text: this.t(locale, "menu:project.not_found"),
|
|
5850
6404
|
show_alert: true,
|
|
5851
6405
|
});
|
|
5852
6406
|
return;
|
|
@@ -5857,15 +6411,18 @@ class TelegramTransport {
|
|
|
5857
6411
|
projectUuid: payload.projectUuid,
|
|
5858
6412
|
projectName: payload.projectName,
|
|
5859
6413
|
});
|
|
5860
|
-
await ctx.answerCallbackQuery({
|
|
6414
|
+
await ctx.answerCallbackQuery({
|
|
6415
|
+
text: this.t(locale, "menu:project.opening_members"),
|
|
6416
|
+
});
|
|
5861
6417
|
await this.showProjectMembers(ctx, payload);
|
|
5862
6418
|
}
|
|
5863
6419
|
async handleProjectDetailCallback(ctx) {
|
|
6420
|
+
const locale = await this.resolveLocaleForContext(ctx);
|
|
5864
6421
|
const projectUuid = this.extractCallbackSuffix(ctx, "project-detail:");
|
|
5865
6422
|
const principal = this.getPrincipalFromContext(ctx);
|
|
5866
6423
|
if (!projectUuid || !principal) {
|
|
5867
6424
|
await ctx.answerCallbackQuery({
|
|
5868
|
-
text:
|
|
6425
|
+
text: this.t(locale, "menu:project.invalid_action"),
|
|
5869
6426
|
show_alert: true,
|
|
5870
6427
|
});
|
|
5871
6428
|
return;
|
|
@@ -5873,7 +6430,7 @@ class TelegramTransport {
|
|
|
5873
6430
|
const sessionId = await this.bindingStore.getActiveSessionIdForPrincipal(principal);
|
|
5874
6431
|
if (!sessionId) {
|
|
5875
6432
|
await ctx.answerCallbackQuery({
|
|
5876
|
-
text:
|
|
6433
|
+
text: this.t(locale, "common:errors.no_active_session"),
|
|
5877
6434
|
show_alert: true,
|
|
5878
6435
|
});
|
|
5879
6436
|
return;
|
|
@@ -5881,7 +6438,7 @@ class TelegramTransport {
|
|
|
5881
6438
|
const payload = await this.getProjectPayloadByUuid(sessionId, projectUuid);
|
|
5882
6439
|
if (!payload) {
|
|
5883
6440
|
await ctx.answerCallbackQuery({
|
|
5884
|
-
text:
|
|
6441
|
+
text: this.t(locale, "menu:project.not_found"),
|
|
5885
6442
|
show_alert: true,
|
|
5886
6443
|
});
|
|
5887
6444
|
return;
|
|
@@ -5892,14 +6449,17 @@ class TelegramTransport {
|
|
|
5892
6449
|
projectUuid: payload.projectUuid,
|
|
5893
6450
|
projectName: payload.projectName,
|
|
5894
6451
|
});
|
|
5895
|
-
await ctx.answerCallbackQuery({
|
|
6452
|
+
await ctx.answerCallbackQuery({
|
|
6453
|
+
text: this.t(locale, "menu:project.opening_members"),
|
|
6454
|
+
});
|
|
5896
6455
|
await this.showProjectMembers(ctx, payload);
|
|
5897
6456
|
}
|
|
5898
6457
|
async handleProjectDeleteCallback(ctx) {
|
|
6458
|
+
const locale = await this.resolveLocaleForContext(ctx);
|
|
5899
6459
|
const projectUuid = this.extractCallbackSuffix(ctx, "project-delete:");
|
|
5900
6460
|
if (!projectUuid) {
|
|
5901
6461
|
await ctx.answerCallbackQuery({
|
|
5902
|
-
text:
|
|
6462
|
+
text: this.t(locale, "menu:project.invalid_action"),
|
|
5903
6463
|
show_alert: true,
|
|
5904
6464
|
});
|
|
5905
6465
|
return;
|
|
@@ -5907,10 +6467,11 @@ class TelegramTransport {
|
|
|
5907
6467
|
await this.handleProjectDeleteByUuid(ctx, projectUuid);
|
|
5908
6468
|
}
|
|
5909
6469
|
async handleProjectMemberOpenCallback(ctx) {
|
|
6470
|
+
const locale = await this.resolveLocaleForContext(ctx);
|
|
5910
6471
|
const payloadKey = this.extractCallbackSuffix(ctx, "project-member-open:");
|
|
5911
6472
|
if (!payloadKey) {
|
|
5912
6473
|
await ctx.answerCallbackQuery({
|
|
5913
|
-
text:
|
|
6474
|
+
text: this.t(locale, "menu:project.invalid_member_payload"),
|
|
5914
6475
|
show_alert: true,
|
|
5915
6476
|
});
|
|
5916
6477
|
return;
|
|
@@ -5918,7 +6479,7 @@ class TelegramTransport {
|
|
|
5918
6479
|
const payload = await this.getProjectMemberPayloadByKey(payloadKey);
|
|
5919
6480
|
if (!payload) {
|
|
5920
6481
|
await ctx.answerCallbackQuery({
|
|
5921
|
-
text:
|
|
6482
|
+
text: this.t(locale, "menu:project.stale_member_payload"),
|
|
5922
6483
|
show_alert: true,
|
|
5923
6484
|
});
|
|
5924
6485
|
await ctx.deleteMessage().catch(() => undefined);
|
|
@@ -5934,15 +6495,18 @@ class TelegramTransport {
|
|
|
5934
6495
|
});
|
|
5935
6496
|
return;
|
|
5936
6497
|
}
|
|
5937
|
-
await ctx.answerCallbackQuery({
|
|
6498
|
+
await ctx.answerCallbackQuery({
|
|
6499
|
+
text: this.t(locale, "menu:project.opening_session"),
|
|
6500
|
+
});
|
|
5938
6501
|
await this.showProjectMemberDetail(ctx, payload);
|
|
5939
6502
|
}
|
|
5940
6503
|
async handleProjectMemberNoteCallback(ctx) {
|
|
6504
|
+
const locale = await this.resolveLocaleForContext(ctx);
|
|
5941
6505
|
const data = ctx.callbackQuery?.data ?? "";
|
|
5942
6506
|
const match = data.match(/^project-member-note:(question|share):(.+)$/u);
|
|
5943
6507
|
if (!match) {
|
|
5944
6508
|
await ctx.answerCallbackQuery({
|
|
5945
|
-
text:
|
|
6509
|
+
text: this.t(locale, "menu:project.invalid_member_action"),
|
|
5946
6510
|
show_alert: true,
|
|
5947
6511
|
});
|
|
5948
6512
|
return;
|
|
@@ -5951,7 +6515,7 @@ class TelegramTransport {
|
|
|
5951
6515
|
const payloadKey = payloadKeyRaw?.trim();
|
|
5952
6516
|
if (!payloadKey) {
|
|
5953
6517
|
await ctx.answerCallbackQuery({
|
|
5954
|
-
text:
|
|
6518
|
+
text: this.t(locale, "menu:project.invalid_member_payload"),
|
|
5955
6519
|
show_alert: true,
|
|
5956
6520
|
});
|
|
5957
6521
|
return;
|
|
@@ -5959,7 +6523,7 @@ class TelegramTransport {
|
|
|
5959
6523
|
const payload = await this.getProjectMemberPayloadByKey(payloadKey);
|
|
5960
6524
|
if (!payload) {
|
|
5961
6525
|
await ctx.answerCallbackQuery({
|
|
5962
|
-
text:
|
|
6526
|
+
text: this.t(locale, "menu:project.stale_member_payload"),
|
|
5963
6527
|
show_alert: true,
|
|
5964
6528
|
});
|
|
5965
6529
|
await ctx.deleteMessage().catch(() => undefined);
|
|
@@ -5972,10 +6536,11 @@ class TelegramTransport {
|
|
|
5972
6536
|
});
|
|
5973
6537
|
}
|
|
5974
6538
|
async handleProjectMemberLiveCallback(ctx) {
|
|
6539
|
+
const locale = await this.resolveLocaleForContext(ctx);
|
|
5975
6540
|
const payloadKey = this.extractCallbackSuffix(ctx, "project-member-live:");
|
|
5976
6541
|
if (!payloadKey) {
|
|
5977
6542
|
await ctx.answerCallbackQuery({
|
|
5978
|
-
text: "
|
|
6543
|
+
text: this.t(locale, "menu:project.invalid_live_payload"),
|
|
5979
6544
|
show_alert: true,
|
|
5980
6545
|
});
|
|
5981
6546
|
return;
|
|
@@ -5983,7 +6548,7 @@ class TelegramTransport {
|
|
|
5983
6548
|
const payload = await this.getProjectMemberPayloadByKey(payloadKey);
|
|
5984
6549
|
if (!payload || !payload.targetClientUuid || !payload.targetLocalSessionId) {
|
|
5985
6550
|
await ctx.answerCallbackQuery({
|
|
5986
|
-
text:
|
|
6551
|
+
text: this.t(locale, "menu:project.stale_live_payload"),
|
|
5987
6552
|
show_alert: true,
|
|
5988
6553
|
});
|
|
5989
6554
|
await ctx.deleteMessage().catch(() => undefined);
|
|
@@ -5992,7 +6557,7 @@ class TelegramTransport {
|
|
|
5992
6557
|
const principal = this.getPrincipalFromContext(ctx);
|
|
5993
6558
|
if (!principal) {
|
|
5994
6559
|
await ctx.answerCallbackQuery({
|
|
5995
|
-
text:
|
|
6560
|
+
text: this.t(locale, "menu:project.no_telegram_user"),
|
|
5996
6561
|
show_alert: true,
|
|
5997
6562
|
});
|
|
5998
6563
|
return;
|
|
@@ -6017,17 +6582,18 @@ class TelegramTransport {
|
|
|
6017
6582
|
});
|
|
6018
6583
|
await ctx.answerCallbackQuery({
|
|
6019
6584
|
text: result?.delivered
|
|
6020
|
-
?
|
|
6021
|
-
:
|
|
6585
|
+
? this.t(locale, "menu:project.request_live_sent")
|
|
6586
|
+
: this.t(locale, "menu:live.actions.approval_unavailable"),
|
|
6022
6587
|
...(result?.delivered ? {} : { show_alert: true }),
|
|
6023
6588
|
});
|
|
6024
6589
|
}
|
|
6025
6590
|
async handleLiveApprovalCallback(ctx) {
|
|
6591
|
+
const locale = await this.resolveLocaleForContext(ctx);
|
|
6026
6592
|
const data = ctx.callbackQuery?.data ?? "";
|
|
6027
6593
|
const match = data.match(/^live-approval:(approve|deny):(.+)$/u);
|
|
6028
6594
|
if (!match) {
|
|
6029
6595
|
await ctx.answerCallbackQuery({
|
|
6030
|
-
text: "
|
|
6596
|
+
text: this.t(locale, "menu:project.invalid_approval"),
|
|
6031
6597
|
show_alert: true,
|
|
6032
6598
|
});
|
|
6033
6599
|
return;
|
|
@@ -6036,7 +6602,7 @@ class TelegramTransport {
|
|
|
6036
6602
|
const payloadKey = payloadKeyRaw?.trim();
|
|
6037
6603
|
if (!payloadKey) {
|
|
6038
6604
|
await ctx.answerCallbackQuery({
|
|
6039
|
-
text:
|
|
6605
|
+
text: this.t(locale, "menu:project.invalid_approval_data"),
|
|
6040
6606
|
show_alert: true,
|
|
6041
6607
|
});
|
|
6042
6608
|
return;
|
|
@@ -6044,7 +6610,7 @@ class TelegramTransport {
|
|
|
6044
6610
|
const payload = await this.getLiveApprovalPayloadByKey(payloadKey);
|
|
6045
6611
|
if (!payload) {
|
|
6046
6612
|
await ctx.answerCallbackQuery({
|
|
6047
|
-
text:
|
|
6613
|
+
text: this.t(locale, "menu:project.approval_stale"),
|
|
6048
6614
|
show_alert: true,
|
|
6049
6615
|
});
|
|
6050
6616
|
await ctx.deleteMessage().catch(() => undefined);
|
|
@@ -6068,28 +6634,45 @@ class TelegramTransport {
|
|
|
6068
6634
|
},
|
|
6069
6635
|
});
|
|
6070
6636
|
await ctx.answerCallbackQuery({
|
|
6071
|
-
text: approved
|
|
6637
|
+
text: approved
|
|
6638
|
+
? this.t(locale, "menu:live.approval.approved")
|
|
6639
|
+
: this.t(locale, "menu:live.approval.denied"),
|
|
6072
6640
|
});
|
|
6073
6641
|
if (ctx.callbackQuery?.message) {
|
|
6074
6642
|
await this.editText(ctx, [
|
|
6075
|
-
approved
|
|
6643
|
+
approved
|
|
6644
|
+
? this.t(locale, "menu:live.approval.approved")
|
|
6645
|
+
: this.t(locale, "menu:live.approval.denied"),
|
|
6076
6646
|
"",
|
|
6077
|
-
...(payload.projectName
|
|
6078
|
-
|
|
6647
|
+
...(payload.projectName
|
|
6648
|
+
? [
|
|
6649
|
+
this.t(locale, "menu:live.approval.project", {
|
|
6650
|
+
projectName: payload.projectName,
|
|
6651
|
+
}),
|
|
6652
|
+
]
|
|
6653
|
+
: []),
|
|
6654
|
+
this.t(locale, "menu:live.approval.route", {
|
|
6655
|
+
sourceSessionName: payload.sourceSessionLabel,
|
|
6656
|
+
targetSessionName: payload.targetSessionLabel,
|
|
6657
|
+
}),
|
|
6079
6658
|
"",
|
|
6080
6659
|
result?.delivered
|
|
6081
6660
|
? approved
|
|
6082
|
-
? "
|
|
6083
|
-
: "
|
|
6084
|
-
|
|
6661
|
+
? this.t(locale, "menu:live.approval.source_open")
|
|
6662
|
+
: this.t(locale, "menu:live.approval.result_denied", {
|
|
6663
|
+
sourceSessionName: payload.sourceSessionLabel,
|
|
6664
|
+
targetSessionName: payload.targetSessionLabel,
|
|
6665
|
+
})
|
|
6666
|
+
: this.t(locale, "menu:live.actions.approval_unavailable"),
|
|
6085
6667
|
].join("\n"), { kind: "menu", sessionId: payload.sessionId });
|
|
6086
6668
|
}
|
|
6087
6669
|
}
|
|
6088
6670
|
async handleProjectMemberFilesCallback(ctx) {
|
|
6671
|
+
const locale = await this.resolveLocaleForContext(ctx);
|
|
6089
6672
|
const payloadKey = this.extractCallbackSuffix(ctx, "project-member-files:");
|
|
6090
6673
|
if (!payloadKey) {
|
|
6091
6674
|
await ctx.answerCallbackQuery({
|
|
6092
|
-
text:
|
|
6675
|
+
text: this.t(locale, "menu:project.invalid_member_payload"),
|
|
6093
6676
|
show_alert: true,
|
|
6094
6677
|
});
|
|
6095
6678
|
return;
|
|
@@ -6097,20 +6680,23 @@ class TelegramTransport {
|
|
|
6097
6680
|
const payload = await this.getProjectMemberPayloadByKey(payloadKey);
|
|
6098
6681
|
if (!payload) {
|
|
6099
6682
|
await ctx.answerCallbackQuery({
|
|
6100
|
-
text:
|
|
6683
|
+
text: this.t(locale, "menu:project.stale_member_payload"),
|
|
6101
6684
|
show_alert: true,
|
|
6102
6685
|
});
|
|
6103
6686
|
await ctx.deleteMessage().catch(() => undefined);
|
|
6104
6687
|
return;
|
|
6105
6688
|
}
|
|
6106
|
-
await ctx.answerCallbackQuery({
|
|
6689
|
+
await ctx.answerCallbackQuery({
|
|
6690
|
+
text: this.t(locale, "menu:project.opening_files"),
|
|
6691
|
+
});
|
|
6107
6692
|
await this.showProjectMemberFiles(ctx, payload);
|
|
6108
6693
|
}
|
|
6109
6694
|
async handlePartnerFileOpenCallback(ctx) {
|
|
6695
|
+
const locale = await this.resolveLocaleForContext(ctx);
|
|
6110
6696
|
const payloadKey = this.extractCallbackSuffix(ctx, "partner-file-open:");
|
|
6111
6697
|
if (!payloadKey) {
|
|
6112
6698
|
await ctx.answerCallbackQuery({
|
|
6113
|
-
text:
|
|
6699
|
+
text: this.t(locale, "menu:project.invalid_member_payload"),
|
|
6114
6700
|
show_alert: true,
|
|
6115
6701
|
});
|
|
6116
6702
|
return;
|
|
@@ -6118,7 +6704,7 @@ class TelegramTransport {
|
|
|
6118
6704
|
const payload = await this.getPartnerFileTargetPayloadByKey(payloadKey);
|
|
6119
6705
|
if (!payload) {
|
|
6120
6706
|
await ctx.answerCallbackQuery({
|
|
6121
|
-
text:
|
|
6707
|
+
text: this.t(locale, "menu:project.data_stale"),
|
|
6122
6708
|
show_alert: true,
|
|
6123
6709
|
});
|
|
6124
6710
|
return;
|
|
@@ -6131,11 +6717,12 @@ class TelegramTransport {
|
|
|
6131
6717
|
});
|
|
6132
6718
|
}
|
|
6133
6719
|
async handleProjectMembersCallback(ctx) {
|
|
6720
|
+
const locale = await this.resolveLocaleForContext(ctx);
|
|
6134
6721
|
const projectUuid = this.extractCallbackSuffix(ctx, "project-members:");
|
|
6135
6722
|
const principal = this.getPrincipalFromContext(ctx);
|
|
6136
6723
|
if (!projectUuid || !principal) {
|
|
6137
6724
|
await ctx.answerCallbackQuery({
|
|
6138
|
-
text:
|
|
6725
|
+
text: this.t(locale, "menu:project.invalid_action"),
|
|
6139
6726
|
show_alert: true,
|
|
6140
6727
|
});
|
|
6141
6728
|
return;
|
|
@@ -6143,7 +6730,7 @@ class TelegramTransport {
|
|
|
6143
6730
|
const sessionId = await this.bindingStore.getActiveSessionIdForPrincipal(principal);
|
|
6144
6731
|
if (!sessionId) {
|
|
6145
6732
|
await ctx.answerCallbackQuery({
|
|
6146
|
-
text:
|
|
6733
|
+
text: this.t(locale, "common:errors.no_active_session"),
|
|
6147
6734
|
show_alert: true,
|
|
6148
6735
|
});
|
|
6149
6736
|
return;
|
|
@@ -6151,20 +6738,23 @@ class TelegramTransport {
|
|
|
6151
6738
|
const payload = await this.getProjectPayloadByUuid(sessionId, projectUuid);
|
|
6152
6739
|
if (!payload) {
|
|
6153
6740
|
await ctx.answerCallbackQuery({
|
|
6154
|
-
text:
|
|
6741
|
+
text: this.t(locale, "menu:project.not_found"),
|
|
6155
6742
|
show_alert: true,
|
|
6156
6743
|
});
|
|
6157
6744
|
return;
|
|
6158
6745
|
}
|
|
6159
|
-
await ctx.answerCallbackQuery({
|
|
6746
|
+
await ctx.answerCallbackQuery({
|
|
6747
|
+
text: this.t(locale, "menu:project.loading_members"),
|
|
6748
|
+
});
|
|
6160
6749
|
await this.showProjectMembers(ctx, payload);
|
|
6161
6750
|
}
|
|
6162
6751
|
async handleProjectLeaveCallback(ctx) {
|
|
6752
|
+
const locale = await this.resolveLocaleForContext(ctx);
|
|
6163
6753
|
const projectUuid = this.extractCallbackSuffix(ctx, "project-leave:");
|
|
6164
6754
|
const principal = this.getPrincipalFromContext(ctx);
|
|
6165
6755
|
if (!projectUuid || !principal) {
|
|
6166
6756
|
await ctx.answerCallbackQuery({
|
|
6167
|
-
text:
|
|
6757
|
+
text: this.t(locale, "menu:project.invalid_action"),
|
|
6168
6758
|
show_alert: true,
|
|
6169
6759
|
});
|
|
6170
6760
|
return;
|
|
@@ -6172,7 +6762,7 @@ class TelegramTransport {
|
|
|
6172
6762
|
const sessionId = await this.bindingStore.getActiveSessionIdForPrincipal(principal);
|
|
6173
6763
|
if (!sessionId) {
|
|
6174
6764
|
await ctx.answerCallbackQuery({
|
|
6175
|
-
text:
|
|
6765
|
+
text: this.t(locale, "common:errors.no_active_session"),
|
|
6176
6766
|
show_alert: true,
|
|
6177
6767
|
});
|
|
6178
6768
|
return;
|
|
@@ -6191,14 +6781,17 @@ class TelegramTransport {
|
|
|
6191
6781
|
updatedAt: new Date().toISOString(),
|
|
6192
6782
|
});
|
|
6193
6783
|
}
|
|
6194
|
-
await ctx.answerCallbackQuery({
|
|
6195
|
-
|
|
6784
|
+
await ctx.answerCallbackQuery({
|
|
6785
|
+
text: this.t(locale, "menu:project.left_callback"),
|
|
6786
|
+
});
|
|
6787
|
+
await this.showProjectsMenu(ctx, this.t(locale, "menu:project.left_screen"));
|
|
6196
6788
|
}
|
|
6197
6789
|
async handleProjectDeleteByUuid(ctx, projectUuid) {
|
|
6790
|
+
const locale = await this.resolveLocaleForContext(ctx);
|
|
6198
6791
|
const principal = this.getPrincipalFromContext(ctx);
|
|
6199
6792
|
if (!principal) {
|
|
6200
6793
|
await ctx.answerCallbackQuery({
|
|
6201
|
-
text: "
|
|
6794
|
+
text: this.t(locale, "common:errors.no_telegram_identity"),
|
|
6202
6795
|
show_alert: true,
|
|
6203
6796
|
});
|
|
6204
6797
|
return;
|
|
@@ -6206,7 +6799,7 @@ class TelegramTransport {
|
|
|
6206
6799
|
const sessionId = await this.bindingStore.getActiveSessionIdForPrincipal(principal);
|
|
6207
6800
|
if (!sessionId) {
|
|
6208
6801
|
await ctx.answerCallbackQuery({
|
|
6209
|
-
text:
|
|
6802
|
+
text: this.t(locale, "common:errors.no_active_session"),
|
|
6210
6803
|
show_alert: true,
|
|
6211
6804
|
});
|
|
6212
6805
|
return;
|
|
@@ -6215,7 +6808,7 @@ class TelegramTransport {
|
|
|
6215
6808
|
const project = projects.find((item) => item.project_uuid === projectUuid);
|
|
6216
6809
|
if (!project) {
|
|
6217
6810
|
await ctx.answerCallbackQuery({
|
|
6218
|
-
text:
|
|
6811
|
+
text: this.t(locale, "menu:project.not_found"),
|
|
6219
6812
|
show_alert: true,
|
|
6220
6813
|
});
|
|
6221
6814
|
await ctx.deleteMessage().catch(() => undefined);
|
|
@@ -6223,7 +6816,7 @@ class TelegramTransport {
|
|
|
6223
6816
|
}
|
|
6224
6817
|
if (project.role !== "owner") {
|
|
6225
6818
|
await ctx.answerCallbackQuery({
|
|
6226
|
-
text: "
|
|
6819
|
+
text: this.t(locale, "menu:project.delete_only_owner"),
|
|
6227
6820
|
show_alert: true,
|
|
6228
6821
|
});
|
|
6229
6822
|
return;
|
|
@@ -6242,8 +6835,12 @@ class TelegramTransport {
|
|
|
6242
6835
|
updatedAt: new Date().toISOString(),
|
|
6243
6836
|
});
|
|
6244
6837
|
}
|
|
6245
|
-
await ctx.answerCallbackQuery({
|
|
6246
|
-
|
|
6838
|
+
await ctx.answerCallbackQuery({
|
|
6839
|
+
text: this.t(locale, "menu:project.deleted_callback"),
|
|
6840
|
+
});
|
|
6841
|
+
await this.showCollabDeleteMenu(ctx, this.t(locale, "menu:project.deleted_screen", {
|
|
6842
|
+
projectName: project.name,
|
|
6843
|
+
}));
|
|
6247
6844
|
}
|
|
6248
6845
|
async deletePendingFileHandoffPrompt(ctx, pending) {
|
|
6249
6846
|
if (!pending.promptMessageId) {
|
|
@@ -6262,10 +6859,11 @@ class TelegramTransport {
|
|
|
6262
6859
|
}
|
|
6263
6860
|
}
|
|
6264
6861
|
async cancelPendingFileHandoff(ctx) {
|
|
6862
|
+
const locale = await this.resolveLocaleForContext(ctx);
|
|
6265
6863
|
const principal = this.getPrincipalFromContext(ctx);
|
|
6266
6864
|
if (!principal) {
|
|
6267
6865
|
await ctx.answerCallbackQuery({
|
|
6268
|
-
text: "
|
|
6866
|
+
text: this.t(locale, "common:errors.no_telegram_identity"),
|
|
6269
6867
|
show_alert: true,
|
|
6270
6868
|
});
|
|
6271
6869
|
return;
|
|
@@ -6274,14 +6872,16 @@ class TelegramTransport {
|
|
|
6274
6872
|
const pending = this.pendingFileHandoffs.get(principalKey);
|
|
6275
6873
|
if (!pending) {
|
|
6276
6874
|
await ctx.answerCallbackQuery({
|
|
6277
|
-
text: "
|
|
6875
|
+
text: this.t(locale, "menu:handoff.no_pending"),
|
|
6278
6876
|
show_alert: true,
|
|
6279
6877
|
});
|
|
6280
6878
|
return;
|
|
6281
6879
|
}
|
|
6282
6880
|
this.pendingFileHandoffs.delete(principalKey);
|
|
6283
6881
|
await this.deletePendingFileHandoffPrompt(ctx, pending);
|
|
6284
|
-
await ctx.answerCallbackQuery({
|
|
6882
|
+
await ctx.answerCallbackQuery({
|
|
6883
|
+
text: this.t(locale, "menu:handoff.cancelled"),
|
|
6884
|
+
});
|
|
6285
6885
|
if (pending.projectUuid && pending.targetSessionId && pending.targetSessionLabel) {
|
|
6286
6886
|
const project = await this.getProjectPayloadByUuid(pending.sessionId, pending.projectUuid);
|
|
6287
6887
|
if (project) {
|
|
@@ -6425,6 +7025,7 @@ class TelegramTransport {
|
|
|
6425
7025
|
});
|
|
6426
7026
|
}
|
|
6427
7027
|
async handlePendingPartnerNote(ctx, text) {
|
|
7028
|
+
const locale = await this.resolveLocaleForContext(ctx);
|
|
6428
7029
|
const principal = this.getPrincipalFromContext(ctx);
|
|
6429
7030
|
if (!principal) {
|
|
6430
7031
|
return false;
|
|
@@ -6446,9 +7047,11 @@ class TelegramTransport {
|
|
|
6446
7047
|
if (!resolvedTargetLabel && sourceSession?.linkedSessionId) {
|
|
6447
7048
|
const linkedSession = await this.sessionStore.getSession(sourceSession.linkedSessionId);
|
|
6448
7049
|
resolvedTargetLabel =
|
|
6449
|
-
linkedSession?.label ??
|
|
7050
|
+
linkedSession?.label ??
|
|
7051
|
+
sourceSession.linkedSessionId ??
|
|
7052
|
+
this.t(locale, "menu:partner.screen.default_partner");
|
|
6450
7053
|
}
|
|
6451
|
-
const targetLabel = resolvedTargetLabel ?? "
|
|
7054
|
+
const targetLabel = resolvedTargetLabel ?? this.t(locale, "menu:partner.screen.default_partner");
|
|
6452
7055
|
this.pendingPartnerNotes.delete(principalKey);
|
|
6453
7056
|
await this.deletePendingPartnerNotePrompt(ctx, pending);
|
|
6454
7057
|
if ((0, collabSemantics_1.isExecutorTargetKind)(pending.kind)) {
|
|
@@ -6484,13 +7087,30 @@ class TelegramTransport {
|
|
|
6484
7087
|
requires_reply: true,
|
|
6485
7088
|
});
|
|
6486
7089
|
const sent = await this.replyText(ctx, [
|
|
6487
|
-
|
|
7090
|
+
this.t(locale, "menu:partner.actions.task_sent"),
|
|
6488
7091
|
...(output.project_name ? [`Проект: ${output.project_name}`] : []),
|
|
6489
|
-
...(output.target_actor_label
|
|
6490
|
-
|
|
6491
|
-
|
|
6492
|
-
|
|
6493
|
-
|
|
7092
|
+
...(output.target_actor_label
|
|
7093
|
+
? [
|
|
7094
|
+
this.t(locale, "menu:partner.screen.executor", {
|
|
7095
|
+
label: output.target_actor_label,
|
|
7096
|
+
}),
|
|
7097
|
+
]
|
|
7098
|
+
: []),
|
|
7099
|
+
this.t(locale, "menu:partner.screen.route_result", {
|
|
7100
|
+
source: targetLabel,
|
|
7101
|
+
target: sourceLabel,
|
|
7102
|
+
}),
|
|
7103
|
+
this.t(locale, "menu:partner.screen.type", {
|
|
7104
|
+
kind: pending.kind,
|
|
7105
|
+
}),
|
|
7106
|
+
this.t(locale, "menu:partner.screen.summary", {
|
|
7107
|
+
summary: parsed.summary,
|
|
7108
|
+
}),
|
|
7109
|
+
this.t(locale, "menu:partner.screen.status", {
|
|
7110
|
+
status: output.delivery_status === "delivered"
|
|
7111
|
+
? this.t(locale, "menu:partner.screen.delivered")
|
|
7112
|
+
: this.t(locale, "menu:partner.screen.queued"),
|
|
7113
|
+
}),
|
|
6494
7114
|
`Share: ${output.share_id}`,
|
|
6495
7115
|
].join("\n"), { kind: "menu", sessionId: pending.sessionId });
|
|
6496
7116
|
if (output.delivery_status === "queued" &&
|
|
@@ -6532,11 +7152,18 @@ class TelegramTransport {
|
|
|
6532
7152
|
...(pending.projectUuid ? { projectUuid: pending.projectUuid } : {}),
|
|
6533
7153
|
});
|
|
6534
7154
|
await this.replyText(ctx, [
|
|
6535
|
-
|
|
6536
|
-
|
|
6537
|
-
|
|
6538
|
-
|
|
6539
|
-
|
|
7155
|
+
this.t(locale, "menu:partner.actions.inbox_queued"),
|
|
7156
|
+
this.t(locale, "menu:partner.screen.route_send", {
|
|
7157
|
+
source: sourceLabel,
|
|
7158
|
+
target: targetLabel,
|
|
7159
|
+
}),
|
|
7160
|
+
this.t(locale, "menu:partner.screen.type", {
|
|
7161
|
+
kind: pending.kind,
|
|
7162
|
+
}),
|
|
7163
|
+
this.t(locale, "menu:partner.screen.summary", {
|
|
7164
|
+
summary: parsed.summary,
|
|
7165
|
+
}),
|
|
7166
|
+
this.t(locale, "menu:partner.screen.current_session_handles"),
|
|
6540
7167
|
].join("\n"), { kind: "menu", sessionId: pending.sessionId });
|
|
6541
7168
|
return true;
|
|
6542
7169
|
}
|
|
@@ -6580,6 +7207,7 @@ class TelegramTransport {
|
|
|
6580
7207
|
await this.nudgeSessionInbox(input.sessionId);
|
|
6581
7208
|
}
|
|
6582
7209
|
async handlePendingFileHandoff(ctx, text) {
|
|
7210
|
+
const locale = await this.resolveLocaleForContext(ctx);
|
|
6583
7211
|
const principal = this.getPrincipalFromContext(ctx);
|
|
6584
7212
|
if (!principal) {
|
|
6585
7213
|
return false;
|
|
@@ -6608,7 +7236,7 @@ class TelegramTransport {
|
|
|
6608
7236
|
});
|
|
6609
7237
|
this.pendingFileHandoffs.delete(principalKey);
|
|
6610
7238
|
await this.deletePendingFileHandoffPrompt(ctx, pending);
|
|
6611
|
-
await this.replyText(ctx,
|
|
7239
|
+
await this.replyText(ctx, this.t(locale, "menu:handoff.delivered_agent"), { kind: "menu", sessionId: pending.sessionId });
|
|
6612
7240
|
return true;
|
|
6613
7241
|
}
|
|
6614
7242
|
if (pending.projectUuid) {
|
|
@@ -6630,12 +7258,36 @@ class TelegramTransport {
|
|
|
6630
7258
|
this.pendingFileHandoffs.delete(principalKey);
|
|
6631
7259
|
await this.deletePendingFileHandoffPrompt(ctx, pending);
|
|
6632
7260
|
const sent = await this.replyText(ctx, [
|
|
6633
|
-
|
|
6634
|
-
...(output.project_name
|
|
6635
|
-
|
|
6636
|
-
|
|
6637
|
-
|
|
6638
|
-
|
|
7261
|
+
this.t(locale, "menu:handoff.queued_partner"),
|
|
7262
|
+
...(output.project_name
|
|
7263
|
+
? [
|
|
7264
|
+
this.t(locale, "menu:handoff.project", {
|
|
7265
|
+
projectName: output.project_name,
|
|
7266
|
+
}),
|
|
7267
|
+
]
|
|
7268
|
+
: []),
|
|
7269
|
+
...(output.target_actor_label
|
|
7270
|
+
? [
|
|
7271
|
+
this.t(locale, "menu:handoff.recipient", {
|
|
7272
|
+
label: output.target_actor_label,
|
|
7273
|
+
}),
|
|
7274
|
+
]
|
|
7275
|
+
: []),
|
|
7276
|
+
...(output.target_session_label
|
|
7277
|
+
? [
|
|
7278
|
+
this.t(locale, "menu:handoff.session", {
|
|
7279
|
+
label: output.target_session_label,
|
|
7280
|
+
}),
|
|
7281
|
+
]
|
|
7282
|
+
: []),
|
|
7283
|
+
this.t(locale, "menu:handoff.status", {
|
|
7284
|
+
status: output.delivery_status === "delivered"
|
|
7285
|
+
? this.t(locale, "menu:handoff.delivered")
|
|
7286
|
+
: this.t(locale, "menu:handoff.queued"),
|
|
7287
|
+
}),
|
|
7288
|
+
this.t(locale, "menu:handoff.share", {
|
|
7289
|
+
shareId: output.share_id,
|
|
7290
|
+
}),
|
|
6639
7291
|
].join("\n"), { kind: "menu", sessionId: pending.sessionId });
|
|
6640
7292
|
if (output.delivery_status === "queued" &&
|
|
6641
7293
|
sent &&
|
|
@@ -6671,6 +7323,7 @@ class TelegramTransport {
|
|
|
6671
7323
|
return true;
|
|
6672
7324
|
}
|
|
6673
7325
|
async handlePendingProject(ctx, text) {
|
|
7326
|
+
const locale = await this.resolveLocaleForContext(ctx);
|
|
6674
7327
|
const principal = this.getPrincipalFromContext(ctx);
|
|
6675
7328
|
if (!principal) {
|
|
6676
7329
|
return false;
|
|
@@ -6704,7 +7357,10 @@ class TelegramTransport {
|
|
|
6704
7357
|
projectUuid,
|
|
6705
7358
|
projectName,
|
|
6706
7359
|
});
|
|
6707
|
-
await this.replyText(ctx,
|
|
7360
|
+
await this.replyText(ctx, this.t(locale, "menu:project.created", {
|
|
7361
|
+
projectName,
|
|
7362
|
+
inviteToken: created.invite_token,
|
|
7363
|
+
}), { kind: "menu", sessionId: pending.sessionId });
|
|
6708
7364
|
}
|
|
6709
7365
|
else {
|
|
6710
7366
|
const joined = await this.callGatewayJson("/projects/join", {
|
|
@@ -6719,10 +7375,14 @@ class TelegramTransport {
|
|
|
6719
7375
|
projectUuid,
|
|
6720
7376
|
projectName,
|
|
6721
7377
|
});
|
|
6722
|
-
await this.replyText(ctx,
|
|
7378
|
+
await this.replyText(ctx, this.t(locale, "menu:project.joined", {
|
|
7379
|
+
projectName,
|
|
7380
|
+
}), { kind: "menu", sessionId: pending.sessionId });
|
|
6723
7381
|
}
|
|
6724
7382
|
this.pendingProjects.delete(principalKey);
|
|
6725
|
-
await this.showProjectsMenu(ctx,
|
|
7383
|
+
await this.showProjectsMenu(ctx, this.t(locale, "menu:project.opened", {
|
|
7384
|
+
projectName,
|
|
7385
|
+
}));
|
|
6726
7386
|
return true;
|
|
6727
7387
|
}
|
|
6728
7388
|
}
|