@deadragdoll/tellymcp 0.0.9 → 0.0.11
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 +42 -50
- package/.env.example.gateway +49 -61
- package/CHANGELOG.md +3 -3
- package/README-ru.md +205 -384
- package/README.md +195 -1194
- package/TOOLS.md +294 -377
- package/VERSION.md +36 -10
- package/config/codex/plugins/telly-workflows/.codex-plugin/plugin.json +18 -0
- package/config/codex/plugins/telly-workflows/references/invariants.md +10 -0
- package/config/codex/plugins/telly-workflows/skills/telly-browser-screenshot/SKILL.md +27 -0
- package/config/codex/plugins/telly-workflows/skills/telly-collab-artifact/SKILL.md +22 -0
- package/config/codex/plugins/telly-workflows/skills/telly-human-telegram/SKILL.md +31 -0
- package/config/codex/plugins/telly-workflows/skills/telly-partner-note/SKILL.md +36 -0
- package/config/templates/env.both.template +40 -20
- package/config/templates/env.client.template +34 -18
- package/config/templates/env.gateway.template +38 -22
- package/dist/cli.js +322 -75
- package/dist/codexPluginInstaller.js +215 -0
- package/dist/lib/mixins/session.errors.js +34 -1
- package/dist/lib/pinoTargets.js +2 -2
- package/dist/moleculer.config.js +7 -5
- package/dist/services/features/telegram-mcp/approval.service.js +1 -1
- package/dist/services/features/telegram-mcp/browser.service.js +95 -2
- package/dist/services/features/telegram-mcp/collaboration.service.js +41 -4
- package/dist/services/features/telegram-mcp/ensuredb.service.js +145 -26
- package/dist/services/features/telegram-mcp/gateway-delivery.service.js +285 -103
- package/dist/services/features/telegram-mcp/gateway-rmq.service.js +3 -2
- package/dist/services/features/telegram-mcp/gateway-socket.service.js +905 -87
- package/dist/services/features/telegram-mcp/gateway.service.js +876 -81
- package/dist/services/features/telegram-mcp/mcp-http.service.js +9 -1
- package/dist/services/features/telegram-mcp/mcp-server.service.js +17 -26
- package/dist/services/features/telegram-mcp/notify.service.js +128 -2
- package/dist/services/features/telegram-mcp/runtime.service.js +27 -7
- package/dist/services/features/telegram-mcp/session-context.service.js +29 -2
- package/dist/services/features/telegram-mcp/src/app/bootstrap/runtime.js +133 -10
- package/dist/services/features/telegram-mcp/src/app/config/env.js +161 -51
- package/dist/services/features/telegram-mcp/src/app/http.js +375 -42
- package/dist/services/features/telegram-mcp/src/app/webapp/assets.js +386 -58
- package/dist/services/features/telegram-mcp/src/app/webapp/auth.js +3 -0
- package/dist/services/features/telegram-mcp/src/app/webapp/terminal.js +12 -0
- package/dist/services/features/telegram-mcp/src/entities/request/model/schema.js +116 -104
- package/dist/services/features/telegram-mcp/src/entities/xchange/model/types.js +2 -0
- package/dist/services/features/telegram-mcp/src/features/ask-user/model/askUserTelegram.js +1 -1
- package/dist/services/features/telegram-mcp/src/features/browser/model/browserScreenshotTool.js +1 -1
- package/dist/services/features/telegram-mcp/src/features/browser/model/browserService.js +249 -19
- package/dist/services/features/telegram-mcp/src/features/collaboration/model/gatewaySessionsService.js +71 -0
- package/dist/services/features/telegram-mcp/src/features/collaboration/model/listGatewaySessionsTool.js +33 -0
- package/dist/services/features/telegram-mcp/src/features/collaboration/model/localCollaborationBackend.js +93 -82
- package/dist/services/features/telegram-mcp/src/features/collaboration/model/sendPartnerFileService.js +47 -5
- package/dist/services/features/telegram-mcp/src/features/collaboration/model/sendPartnerFileTool.js +1 -1
- package/dist/services/features/telegram-mcp/src/features/collaboration/model/sendPartnerNoteTool.js +1 -1
- package/dist/services/features/telegram-mcp/src/features/distributed-client/model/gatewayClientAccess.js +82 -0
- package/dist/services/features/telegram-mcp/src/features/distributed-client/model/gatewayCollaborationBackend.js +22 -14
- package/dist/services/features/telegram-mcp/src/features/distributed-gateway/model/gatewayHttpService.js +649 -75
- package/dist/services/features/telegram-mcp/src/features/distributed-gateway/model/remoteConsoleActionClient.js +76 -0
- package/dist/services/features/telegram-mcp/src/features/embedded-runtime/model/embeddedRuntimeBroker.js +92 -0
- package/dist/services/features/telegram-mcp/src/features/foreground-terminal/model/foregroundTerminalRuntime.js +192 -0
- package/dist/services/features/telegram-mcp/src/features/notify/model/notifyService.js +382 -3
- package/dist/services/features/telegram-mcp/src/features/notify/model/notifyTelegramTool.js +1 -1
- package/dist/services/features/telegram-mcp/src/features/notify/model/sendFileToTelegramTool.js +33 -0
- package/dist/services/features/telegram-mcp/src/features/session-context/model/clearSessionContextTool.js +1 -1
- package/dist/services/features/telegram-mcp/src/features/session-context/model/getSessionContextTool.js +1 -1
- package/dist/services/features/telegram-mcp/src/features/session-context/model/renameSessionTool.js +1 -1
- package/dist/services/features/telegram-mcp/src/features/session-context/model/sessionContextService.js +42 -200
- package/dist/services/features/telegram-mcp/src/features/session-context/model/setSessionContextTool.js +1 -1
- package/dist/services/features/telegram-mcp/src/features/terminal-buffer/model/terminalBufferService.js +96 -0
- package/dist/services/features/telegram-mcp/src/features/terminal-input/model/terminalInputService.js +97 -0
- package/dist/services/features/telegram-mcp/src/features/tools-sync/model/refreshToolsMarkdownService.js +107 -58
- package/dist/services/features/telegram-mcp/src/features/tools-sync/model/refreshToolsMarkdownTool.js +1 -1
- package/dist/services/features/telegram-mcp/src/features/xchange/model/getXchangeRecordTool.js +28 -0
- package/dist/services/features/telegram-mcp/src/features/xchange/model/listXchangeRecordsTool.js +28 -0
- package/dist/services/features/telegram-mcp/src/features/xchange/model/markXchangeRecordReadTool.js +28 -0
- package/dist/services/features/telegram-mcp/src/features/xchange/model/xchangeService.js +169 -0
- package/dist/services/features/telegram-mcp/src/processes/human-approval/model/orchestrator.js +5 -4
- 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 +652 -0
- package/dist/services/features/telegram-mcp/src/shared/i18n/resources/ru.js +652 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/memory/processLocalSessionStore.js +27 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/object-storage/minioExchangeStore.js +11 -8
- package/dist/services/features/telegram-mcp/src/shared/integrations/redis/stateStore.js +51 -71
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/proxyFetch.js +21 -22
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transport.js +411 -6524
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportAttachmentStore.js +93 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportBroadcastActions.js +385 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportConsoleRegistry.js +143 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportConstructorWiring.js +633 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportContent.js +84 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportContext.js +78 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportDocumentActions.js +36 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportEventActions.js +292 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportFileHandoffActions.js +352 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportFormatting.js +75 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportGatewayActions.js +44 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportLifecycleActions.js +161 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportLive.js +56 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportLiveActions.js +77 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportMenuCallbacks.js +254 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportMenuFactories.js +538 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportMenuFingerprints.js +93 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportMenuFlow.js +344 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportMenuShell.js +62 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportMenuState.js +408 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportMenuText.js +216 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportMessageFlow.js +452 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportOutputActions.js +189 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportPartnerActions.js +286 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportPayloadState.js +101 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportProjectActions.js +463 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportProjectEntryActions.js +202 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportProjectEvents.js +99 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportProjectMenus.js +138 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportProjectState.js +308 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportProjectView.js +426 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportRequestFlow.js +278 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportSessionActions.js +143 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportTerminalActions.js +468 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportTerminalRuntime.js +171 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportTypes.js +2 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportUtils.js +330 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportXchangeState.js +107 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/terminal/client.js +255 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/terminal/ptyRegistry.js +543 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/xchange/sqliteRecordStore.js +223 -0
- package/dist/services/features/telegram-mcp/src/shared/lib/gatewayScope.js +24 -0
- package/dist/services/features/telegram-mcp/src/shared/lib/logger/logger.js +6 -0
- package/dist/services/features/telegram-mcp/src/shared/lib/project-identity/projectIdentity.js +147 -76
- package/dist/services/features/telegram-mcp/src/shared/lib/telegramXchangeRecords.js +72 -0
- package/dist/services/features/telegram-mcp/src/shared/lib/terminalPromptDetection.js +237 -0
- package/dist/services/features/telegram-mcp/src/shared/lib/version/versionHandshake.js +129 -1
- package/dist/services/features/telegram-mcp/src/shared/lib/xchangeRecordHints.js +98 -0
- package/dist/services/features/telegram-mcp/standalone-http.service.js +13 -1
- package/dist/services/features/telegram-mcp/terminal-buffer.service.js +42 -0
- package/dist/services/features/telegram-mcp/terminal-input.service.js +41 -0
- package/dist/services/features/telegram-mcp/tools-sync.service.js +16 -2
- package/dist/services/features/telegram-mcp/xchange.service.js +123 -0
- package/docs/STANDALONE-ru.md +172 -0
- package/docs/STANDALONE.md +172 -0
- package/package.json +11 -5
- package/scripts/build-package-artifact.sh +27 -0
- package/scripts/deploy-gateway.sh +64 -0
- package/scripts/deploy-onebot-branch.sh +27 -0
- package/scripts/postinstall.js +11 -36
- package/STANDALONE-ru.md +0 -274
- package/STANDALONE.md +0 -274
- package/dist/services/features/telegram-mcp/inbox.service.js +0 -33
- package/dist/services/features/telegram-mcp/pair.service.js +0 -33
- package/dist/services/features/telegram-mcp/src/app/webapp/tmux.js +0 -10
- package/dist/services/features/telegram-mcp/src/features/inbox/model/deleteTelegramInboxMessageTool.js +0 -33
- package/dist/services/features/telegram-mcp/src/features/inbox/model/getTelegramInboxCountTool.js +0 -33
- package/dist/services/features/telegram-mcp/src/features/inbox/model/getTelegramInboxTool.js +0 -33
- package/dist/services/features/telegram-mcp/src/features/inbox/model/inboxService.js +0 -77
- package/dist/services/features/telegram-mcp/src/features/pair-session/model/clearSessionPairingTool.js +0 -33
- package/dist/services/features/telegram-mcp/src/features/pair-session/model/createSessionPairCodeTool.js +0 -33
- package/dist/services/features/telegram-mcp/src/features/pair-session/model/generatePairCode.js +0 -202
- package/dist/services/features/telegram-mcp/src/features/session-context/model/getTmuxTargetTool.js +0 -33
- package/dist/services/features/telegram-mcp/src/features/session-context/model/setTmuxTargetTool.js +0 -33
- package/dist/services/features/telegram-mcp/src/shared/integrations/tmux/client.js +0 -363
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.canRenderLiveView = canRenderLiveView;
|
|
4
|
+
exports.buildLiveViewUrlForSessionTarget = buildLiveViewUrlForSessionTarget;
|
|
5
|
+
exports.buildLiveViewLaunchKeyboard = buildLiveViewLaunchKeyboard;
|
|
6
|
+
exports.buildLiveLauncherText = buildLiveLauncherText;
|
|
7
|
+
const grammy_1 = require("grammy");
|
|
8
|
+
const relay_1 = require("../../../app/webapp/relay");
|
|
9
|
+
const transportUtils_1 = require("./transportUtils");
|
|
10
|
+
function canRenderLiveView(config) {
|
|
11
|
+
return Boolean(config.webapp.enabled &&
|
|
12
|
+
(config.webapp.publicUrl || config.distributed.gatewayPublicUrl));
|
|
13
|
+
}
|
|
14
|
+
function buildLiveViewUrlForSessionTarget(input) {
|
|
15
|
+
const { config } = input;
|
|
16
|
+
if (!canRenderLiveView(config)) {
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
const canUseRelay = Boolean(input.targetClientUuid) &&
|
|
20
|
+
Boolean(input.targetLocalSessionId) &&
|
|
21
|
+
Boolean(config.distributed.gatewayPublicUrl);
|
|
22
|
+
const baseUrl = canUseRelay
|
|
23
|
+
? (0, relay_1.resolveGatewayWebAppBaseUrl)(config.distributed.gatewayPublicUrl, config.webapp.basePath)
|
|
24
|
+
: (0, transportUtils_1.resolveWebAppPublicBaseUrl)(config);
|
|
25
|
+
if (!baseUrl) {
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
const liveSessionId = canUseRelay
|
|
29
|
+
? (0, relay_1.buildLiveRelaySessionId)(input.targetClientUuid, input.targetLocalSessionId, input.sourceClientUuid)
|
|
30
|
+
: (input.targetLocalSessionId ?? input.targetSessionId);
|
|
31
|
+
const url = new URL(`${baseUrl}/live/${encodeURIComponent(liveSessionId)}`);
|
|
32
|
+
url.searchParams.set("launchMode", input.launchMode ?? config.webapp.launchMode);
|
|
33
|
+
return url.toString();
|
|
34
|
+
}
|
|
35
|
+
function buildLiveViewLaunchKeyboard(input) {
|
|
36
|
+
const keyboard = new grammy_1.InlineKeyboard();
|
|
37
|
+
const modes = [
|
|
38
|
+
{ mode: "fullscreen", label: input.labels.fullscreen },
|
|
39
|
+
{ mode: "expand", label: input.labels.expand },
|
|
40
|
+
{ mode: "default", label: input.labels.default },
|
|
41
|
+
];
|
|
42
|
+
for (const [index, { mode, label }] of modes.entries()) {
|
|
43
|
+
const url = input.getUrl(mode);
|
|
44
|
+
if (!url) {
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
keyboard.webApp(label, url);
|
|
48
|
+
if (index === 1) {
|
|
49
|
+
keyboard.row();
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return keyboard;
|
|
53
|
+
}
|
|
54
|
+
function buildLiveLauncherText(input) {
|
|
55
|
+
return [input.title, "", input.chooseMode].join("\n");
|
|
56
|
+
}
|
package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportLiveActions.js
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TransportLiveActions = void 0;
|
|
4
|
+
const node_url_1 = require("node:url");
|
|
5
|
+
const relay_1 = require("../../../app/webapp/relay");
|
|
6
|
+
const transportLive_1 = require("./transportLive");
|
|
7
|
+
const transportUtils_1 = require("./transportUtils");
|
|
8
|
+
class TransportLiveActions {
|
|
9
|
+
host;
|
|
10
|
+
constructor(host) {
|
|
11
|
+
this.host = host;
|
|
12
|
+
}
|
|
13
|
+
canRender() {
|
|
14
|
+
return (0, transportLive_1.canRenderLiveView)(this.host.config);
|
|
15
|
+
}
|
|
16
|
+
buildUrl(input) {
|
|
17
|
+
return (0, transportLive_1.buildLiveViewUrlForSessionTarget)({
|
|
18
|
+
config: this.host.config,
|
|
19
|
+
...input,
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
buildKeyboard(getUrl, locale = "en") {
|
|
23
|
+
return (0, transportLive_1.buildLiveViewLaunchKeyboard)({
|
|
24
|
+
getUrl,
|
|
25
|
+
labels: {
|
|
26
|
+
fullscreen: this.host.t(locale, "menu:live.buttons.fullscreen"),
|
|
27
|
+
expand: this.host.t(locale, "menu:live.buttons.expand"),
|
|
28
|
+
default: this.host.t(locale, "menu:live.buttons.default"),
|
|
29
|
+
},
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
async sendLauncherMessage(input) {
|
|
33
|
+
if (!(0, transportLive_1.canRenderLiveView)(this.host.config)) {
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
const useGatewayRelay = this.host.config.distributed.mode === "client" &&
|
|
37
|
+
Boolean(this.host.config.distributed.gatewayPublicUrl);
|
|
38
|
+
const clientUuid = useGatewayRelay
|
|
39
|
+
? await this.host.ensureGatewayClientUuid(input.principal, input.actor)
|
|
40
|
+
: null;
|
|
41
|
+
const baseUrl = useGatewayRelay
|
|
42
|
+
? (0, relay_1.resolveGatewayWebAppBaseUrl)(this.host.config.distributed.gatewayPublicUrl, this.host.config.webapp.basePath)
|
|
43
|
+
: (0, transportUtils_1.resolveWebAppPublicBaseUrl)(this.host.config);
|
|
44
|
+
if (!baseUrl) {
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
const relayTarget = (0, relay_1.parseLiveRelaySessionId)(input.sessionId);
|
|
48
|
+
const allowForeignBinding = input.allowForeignBinding === true || Boolean(relayTarget);
|
|
49
|
+
const resolvedLiveSessionId = useGatewayRelay && clientUuid && !input.sessionId.startsWith("relay~")
|
|
50
|
+
? (0, relay_1.buildLiveRelaySessionId)(clientUuid, input.sessionId)
|
|
51
|
+
: input.sessionId;
|
|
52
|
+
const url = new node_url_1.URL(`${baseUrl}/live/${encodeURIComponent(resolvedLiveSessionId)}`);
|
|
53
|
+
url.searchParams.set("launchMode", this.host.config.webapp.launchMode);
|
|
54
|
+
const sent = await this.host.sendChatMessage(input.principal.telegramChatId, (0, transportLive_1.buildLiveLauncherText)({
|
|
55
|
+
title: this.host.t(input.locale, "menu:live.screen.launcher_title", {
|
|
56
|
+
sessionName: input.sessionName,
|
|
57
|
+
}),
|
|
58
|
+
chooseMode: this.host.t(input.locale, "menu:live.actions.choose_mode"),
|
|
59
|
+
}), {
|
|
60
|
+
reply_markup: this.buildKeyboard((mode) => {
|
|
61
|
+
const modeUrl = new node_url_1.URL(url.toString());
|
|
62
|
+
modeUrl.searchParams.set("launchMode", mode);
|
|
63
|
+
return modeUrl.toString();
|
|
64
|
+
}, input.locale),
|
|
65
|
+
}, {
|
|
66
|
+
kind: "notification",
|
|
67
|
+
sessionId: input.sessionId,
|
|
68
|
+
});
|
|
69
|
+
this.host.webAppLaunchRegistry.set(input.principal.telegramUserId, input.sessionId, this.host.config.webapp.initDataTtlSeconds, {
|
|
70
|
+
telegramChatId: input.principal.telegramChatId,
|
|
71
|
+
...(allowForeignBinding ? { allowForeignBinding: true } : {}),
|
|
72
|
+
telegramMessageId: sent.message_id,
|
|
73
|
+
});
|
|
74
|
+
return sent;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
exports.TransportLiveActions = TransportLiveActions;
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.TransportMenuCallbacks = void 0;
|
|
7
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
8
|
+
const relay_1 = require("../../../app/webapp/relay");
|
|
9
|
+
class TransportMenuCallbacks {
|
|
10
|
+
host;
|
|
11
|
+
constructor(host) {
|
|
12
|
+
this.host = host;
|
|
13
|
+
}
|
|
14
|
+
async handleScreenshotOpen(ctx, payloadKey) {
|
|
15
|
+
const payload = await this.requireFileEntryPayload(ctx, payloadKey, "Screenshot");
|
|
16
|
+
if (!payload)
|
|
17
|
+
return;
|
|
18
|
+
const meta = await this.getXchangeFileMeta(payload.sessionId, payload.filePath);
|
|
19
|
+
await ctx.answerCallbackQuery({ text: "Screenshot opened." });
|
|
20
|
+
await this.host.editText(ctx, this.host.formatScreenshotDetail(payload.sessionId, payload.filePath, meta), { kind: "menu", sessionId: payload.sessionId }, { reply_markup: this.host.screenshotMessageMenu });
|
|
21
|
+
}
|
|
22
|
+
async handleScreenshotGet(ctx, payloadKey) {
|
|
23
|
+
const payload = await this.requireFileEntryPayload(ctx, payloadKey, "Screenshot");
|
|
24
|
+
if (!payload)
|
|
25
|
+
return;
|
|
26
|
+
const chatId = ctx.chat?.id;
|
|
27
|
+
if (!chatId) {
|
|
28
|
+
await ctx.answerCallbackQuery({ text: "Telegram chat is unavailable.", show_alert: true });
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
if (this.isRelaySessionId(payload.sessionId)) {
|
|
32
|
+
await this.host.callGatewayJson("/transport/send-file", {
|
|
33
|
+
session_id: payload.sessionId,
|
|
34
|
+
file_path: payload.filePath,
|
|
35
|
+
caption: `Screenshot: ${node_path_1.default.basename(payload.filePath)}`,
|
|
36
|
+
});
|
|
37
|
+
await ctx.answerCallbackQuery({ text: "Screenshot sent." });
|
|
38
|
+
await this.host.showScreenshotsMenu(ctx, "Screenshot sent to Telegram.");
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
const ensured = await this.host.ensureStoredXchangeFile(payload.sessionId, payload.filePath, "browser-screenshot");
|
|
42
|
+
await this.host.sendDocumentToChat(chatId, ensured.filePath, `Screenshot: ${node_path_1.default.basename(ensured.filePath)}`);
|
|
43
|
+
await ctx.answerCallbackQuery({ text: "Screenshot sent." });
|
|
44
|
+
await this.host.showScreenshotsMenu(ctx, "Screenshot sent to Telegram.");
|
|
45
|
+
}
|
|
46
|
+
async handleScreenshotDelete(ctx, payloadKey) {
|
|
47
|
+
const payload = await this.requireFileEntryPayload(ctx, payloadKey, "Screenshot");
|
|
48
|
+
if (!payload)
|
|
49
|
+
return;
|
|
50
|
+
const meta = await this.getXchangeFileMeta(payload.sessionId, payload.filePath);
|
|
51
|
+
if (this.isRelaySessionId(payload.sessionId)) {
|
|
52
|
+
await this.deleteXchangeFileMeta(payload.sessionId, payload.filePath);
|
|
53
|
+
await ctx.answerCallbackQuery({
|
|
54
|
+
text: meta ? "Screenshot deleted." : "Screenshot already absent.",
|
|
55
|
+
});
|
|
56
|
+
await this.host.showScreenshotsMenu(ctx, meta ? "Screenshot deleted." : "Screenshot was already removed.");
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
await this.host.objectStore.deleteStoredFile({
|
|
60
|
+
...(meta?.storageRef ? { storageRef: meta.storageRef } : {}),
|
|
61
|
+
...(typeof meta?.vfsNodeId === "number" ? { vfsNodeId: meta.vfsNodeId } : {}),
|
|
62
|
+
});
|
|
63
|
+
await this.host.xchangeFileMetaStore.deleteXchangeFileMeta(payload.sessionId, payload.filePath);
|
|
64
|
+
await ctx.answerCallbackQuery({
|
|
65
|
+
text: meta ? "Screenshot deleted." : "Screenshot already absent.",
|
|
66
|
+
});
|
|
67
|
+
await this.host.showScreenshotsMenu(ctx, meta ? "Screenshot deleted." : "Screenshot was already removed.");
|
|
68
|
+
}
|
|
69
|
+
async handleStorageOpen(ctx, payloadKey) {
|
|
70
|
+
const payload = await this.requireFileEntryPayload(ctx, payloadKey, "Storage");
|
|
71
|
+
if (!payload)
|
|
72
|
+
return;
|
|
73
|
+
const meta = await this.getXchangeFileMeta(payload.sessionId, payload.filePath);
|
|
74
|
+
await ctx.answerCallbackQuery({ text: "Storage entry opened." });
|
|
75
|
+
await this.host.editText(ctx, this.host.formatStorageDetail(payload.sessionId, payload.filePath, meta), { kind: "menu", sessionId: payload.sessionId }, { reply_markup: this.host.storageMessageMenu });
|
|
76
|
+
}
|
|
77
|
+
async handleStorageGet(ctx, payloadKey) {
|
|
78
|
+
const payload = await this.requireFileEntryPayload(ctx, payloadKey, "Storage");
|
|
79
|
+
if (!payload)
|
|
80
|
+
return;
|
|
81
|
+
const chatId = ctx.chat?.id;
|
|
82
|
+
if (!chatId) {
|
|
83
|
+
await ctx.answerCallbackQuery({ text: "Telegram chat is unavailable.", show_alert: true });
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
const meta = await this.getXchangeFileMeta(payload.sessionId, payload.filePath);
|
|
87
|
+
if (this.isRelaySessionId(payload.sessionId)) {
|
|
88
|
+
await this.host.callGatewayJson("/transport/send-file", {
|
|
89
|
+
session_id: payload.sessionId,
|
|
90
|
+
file_path: payload.filePath,
|
|
91
|
+
caption: `Storage: ${this.host.formatFilePreviewLabel(payload.filePath, meta)}`,
|
|
92
|
+
});
|
|
93
|
+
await ctx.answerCallbackQuery({ text: "Storage file sent." });
|
|
94
|
+
await this.host.showStorageMenu(ctx, "Storage file sent to Telegram.");
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
let ensured;
|
|
98
|
+
try {
|
|
99
|
+
ensured = await this.host.ensureStoredXchangeFile(payload.sessionId, payload.filePath, meta?.source ?? "telegram-upload");
|
|
100
|
+
}
|
|
101
|
+
catch (error) {
|
|
102
|
+
await ctx.answerCallbackQuery({
|
|
103
|
+
text: error instanceof Error ? error.message : "Storage file is not available locally.",
|
|
104
|
+
show_alert: true,
|
|
105
|
+
});
|
|
106
|
+
await this.host.showStorageMenu(ctx, "Storage entry is stale or missing locally. You can delete it from Storage.");
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
await this.host.sendDocumentToChat(chatId, ensured.filePath, `Storage: ${this.host.formatFilePreviewLabel(ensured.filePath, meta)}`);
|
|
110
|
+
await ctx.answerCallbackQuery({ text: "Storage file sent." });
|
|
111
|
+
await this.host.showStorageMenu(ctx, "Storage file sent to Telegram.");
|
|
112
|
+
}
|
|
113
|
+
async handleStorageDelete(ctx, payloadKey) {
|
|
114
|
+
const payload = await this.requireFileEntryPayload(ctx, payloadKey, "Storage");
|
|
115
|
+
if (!payload)
|
|
116
|
+
return;
|
|
117
|
+
const meta = await this.getXchangeFileMeta(payload.sessionId, payload.filePath);
|
|
118
|
+
if (this.isRelaySessionId(payload.sessionId)) {
|
|
119
|
+
await this.deleteXchangeFileMeta(payload.sessionId, payload.filePath);
|
|
120
|
+
await ctx.answerCallbackQuery({
|
|
121
|
+
text: "Storage metadata deleted.",
|
|
122
|
+
});
|
|
123
|
+
await this.host.showStorageMenu(ctx, "Stale storage metadata deleted.");
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
await this.host.objectStore.deleteStoredFile({
|
|
127
|
+
...(meta?.storageRef ? { storageRef: meta.storageRef } : {}),
|
|
128
|
+
...(typeof meta?.vfsNodeId === "number" ? { vfsNodeId: meta.vfsNodeId } : {}),
|
|
129
|
+
});
|
|
130
|
+
await this.host.xchangeFileMetaStore.deleteXchangeFileMeta(payload.sessionId, payload.filePath);
|
|
131
|
+
await ctx.answerCallbackQuery({
|
|
132
|
+
text: "Storage metadata deleted.",
|
|
133
|
+
});
|
|
134
|
+
await this.host.showStorageMenu(ctx, "Stale storage metadata deleted.");
|
|
135
|
+
}
|
|
136
|
+
async handleSessionSelection(ctx, payloadKey) {
|
|
137
|
+
if (!payloadKey) {
|
|
138
|
+
await ctx.answerCallbackQuery({ text: "Session payload is missing.", show_alert: true });
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
const payload = await this.host.getMenuPayloadByKey(payloadKey);
|
|
142
|
+
if (!payload || payload.kind !== "active-session") {
|
|
143
|
+
await ctx.answerCallbackQuery({ text: "Session payload is invalid or expired.", show_alert: true });
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
const principal = this.host.getPrincipalFromContext(ctx);
|
|
147
|
+
if (!principal) {
|
|
148
|
+
await ctx.answerCallbackQuery({ text: "Telegram user or chat is missing.", show_alert: true });
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
const sessionIds = await this.host.bindingStore.listBoundSessionIdsForPrincipal(principal);
|
|
152
|
+
if (!sessionIds.includes(String(payload.sessionId))) {
|
|
153
|
+
await ctx.answerCallbackQuery({
|
|
154
|
+
text: "This session is not linked to your Telegram identity.",
|
|
155
|
+
show_alert: true,
|
|
156
|
+
});
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
await this.host.bindingStore.setActiveSessionIdForPrincipal(principal, String(payload.sessionId));
|
|
160
|
+
const session = await this.host.sessionStore.getSession(String(payload.sessionId));
|
|
161
|
+
this.host.logger.info("Telegram active session changed", {
|
|
162
|
+
sessionId: payload.sessionId,
|
|
163
|
+
chatId: ctx.chat?.id,
|
|
164
|
+
userId: ctx.from?.id,
|
|
165
|
+
});
|
|
166
|
+
await this.host.maybeNotifyToolsMismatchForSession(String(payload.sessionId));
|
|
167
|
+
await ctx.answerCallbackQuery({
|
|
168
|
+
text: session?.label ? `Active session: ${session.label}` : `Active session: ${String(payload.sessionId)}`,
|
|
169
|
+
});
|
|
170
|
+
await this.host.showMainMenu(ctx);
|
|
171
|
+
}
|
|
172
|
+
async handleSessionGroupSelection(ctx, payloadKey) {
|
|
173
|
+
if (!payloadKey) {
|
|
174
|
+
await ctx.answerCallbackQuery({ text: "Session group payload is missing.", show_alert: true });
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
const payload = await this.host.getMenuPayloadByKey(payloadKey);
|
|
178
|
+
this.host.logger.info("Telegram session group payload lookup", {
|
|
179
|
+
payloadKey,
|
|
180
|
+
payload,
|
|
181
|
+
chatId: ctx.chat?.id,
|
|
182
|
+
userId: ctx.from?.id,
|
|
183
|
+
});
|
|
184
|
+
if (!payload || payload.kind !== "session-group") {
|
|
185
|
+
await ctx.answerCallbackQuery({ text: "Session group payload is invalid or expired.", show_alert: true });
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
await ctx.answerCallbackQuery({
|
|
189
|
+
text: typeof payload.ownerLabel === "string" && payload.ownerLabel.trim()
|
|
190
|
+
? payload.ownerLabel
|
|
191
|
+
: "Sessions",
|
|
192
|
+
});
|
|
193
|
+
await this.host.showSessionsMenu(ctx);
|
|
194
|
+
}
|
|
195
|
+
async requireFileEntryPayload(ctx, payloadKey, kindLabel) {
|
|
196
|
+
if (!payloadKey) {
|
|
197
|
+
await ctx.answerCallbackQuery({ text: `${kindLabel} payload is missing.`, show_alert: true });
|
|
198
|
+
return null;
|
|
199
|
+
}
|
|
200
|
+
const payload = await this.host.getMenuPayloadByKey(payloadKey);
|
|
201
|
+
if (!payload || payload.kind !== "file-entry" || !payload.filePath) {
|
|
202
|
+
await ctx.answerCallbackQuery({
|
|
203
|
+
text: `${kindLabel} payload is invalid or expired.`,
|
|
204
|
+
show_alert: true,
|
|
205
|
+
});
|
|
206
|
+
return null;
|
|
207
|
+
}
|
|
208
|
+
const sessionId = String(payload.sessionId ?? "").trim();
|
|
209
|
+
const filePath = String(payload.filePath).trim();
|
|
210
|
+
if (!sessionId) {
|
|
211
|
+
await ctx.answerCallbackQuery({
|
|
212
|
+
text: `${kindLabel} session is missing in payload.`,
|
|
213
|
+
show_alert: true,
|
|
214
|
+
});
|
|
215
|
+
return null;
|
|
216
|
+
}
|
|
217
|
+
const relay = (0, relay_1.parseLiveRelaySessionId)(sessionId);
|
|
218
|
+
if (!relay?.localSessionId) {
|
|
219
|
+
return { sessionId, filePath };
|
|
220
|
+
}
|
|
221
|
+
const localSession = await this.host.sessionStore.getSession(relay.localSessionId);
|
|
222
|
+
if (!localSession) {
|
|
223
|
+
return { sessionId, filePath };
|
|
224
|
+
}
|
|
225
|
+
return {
|
|
226
|
+
sessionId: relay.localSessionId,
|
|
227
|
+
filePath,
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
isRelaySessionId(sessionId) {
|
|
231
|
+
return Boolean((0, relay_1.parseLiveRelaySessionId)(sessionId));
|
|
232
|
+
}
|
|
233
|
+
async getXchangeFileMeta(sessionId, filePath) {
|
|
234
|
+
if (this.isRelaySessionId(sessionId)) {
|
|
235
|
+
const output = await this.host.callGatewayJson("/storage/meta", {
|
|
236
|
+
session_id: sessionId,
|
|
237
|
+
file_path: filePath,
|
|
238
|
+
});
|
|
239
|
+
return output.meta ?? null;
|
|
240
|
+
}
|
|
241
|
+
return this.host.xchangeFileMetaStore.getXchangeFileMeta(sessionId, filePath);
|
|
242
|
+
}
|
|
243
|
+
async deleteXchangeFileMeta(sessionId, filePath) {
|
|
244
|
+
if (this.isRelaySessionId(sessionId)) {
|
|
245
|
+
const output = await this.host.callGatewayJson("/storage/delete-meta", {
|
|
246
|
+
session_id: sessionId,
|
|
247
|
+
file_path: filePath,
|
|
248
|
+
});
|
|
249
|
+
return output.deleted === true;
|
|
250
|
+
}
|
|
251
|
+
return this.host.xchangeFileMetaStore.deleteXchangeFileMeta(sessionId, filePath);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
exports.TransportMenuCallbacks = TransportMenuCallbacks;
|