@deadragdoll/tellymcp 0.0.1

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.
Files changed (124) hide show
  1. package/.env.example.client +93 -0
  2. package/.env.example.gateway +120 -0
  3. package/CHANGELOG.md +155 -0
  4. package/LICENSE +21 -0
  5. package/README-ru.md +338 -0
  6. package/README.md +1262 -0
  7. package/STANDALONE-ru.md +266 -0
  8. package/STANDALONE.md +266 -0
  9. package/TOOLS.md +1296 -0
  10. package/config/templates/env.both.template +83 -0
  11. package/config/templates/env.client.template +60 -0
  12. package/config/templates/env.gateway.template +82 -0
  13. package/dist/cli.js +636 -0
  14. package/dist/index.js +17 -0
  15. package/dist/lib/logfeed/store.js +52 -0
  16. package/dist/lib/middlewares/tracer.js +172 -0
  17. package/dist/lib/mixins/db.js +267 -0
  18. package/dist/lib/mixins/logfeed.js +34 -0
  19. package/dist/lib/mixins/session.errors.js +142 -0
  20. package/dist/lib/moleculer.js +2 -0
  21. package/dist/lib/trace.js +147 -0
  22. package/dist/lib/traceContext.js +116 -0
  23. package/dist/moleculer.config.js +274 -0
  24. package/dist/services/features/telegram-mcp/approval.service.js +33 -0
  25. package/dist/services/features/telegram-mcp/browser.service.js +42 -0
  26. package/dist/services/features/telegram-mcp/collaboration.service.js +53 -0
  27. package/dist/services/features/telegram-mcp/ensuredb.service.js +337 -0
  28. package/dist/services/features/telegram-mcp/gateway-delivery.service.js +378 -0
  29. package/dist/services/features/telegram-mcp/gateway-loopback.js +10 -0
  30. package/dist/services/features/telegram-mcp/gateway-rmq.service.js +294 -0
  31. package/dist/services/features/telegram-mcp/gateway-socket.service.js +1463 -0
  32. package/dist/services/features/telegram-mcp/gateway.service.js +1141 -0
  33. package/dist/services/features/telegram-mcp/inbox.service.js +33 -0
  34. package/dist/services/features/telegram-mcp/mcp-http.service.js +76 -0
  35. package/dist/services/features/telegram-mcp/mcp-server.service.js +127 -0
  36. package/dist/services/features/telegram-mcp/notify.service.js +33 -0
  37. package/dist/services/features/telegram-mcp/pair.service.js +33 -0
  38. package/dist/services/features/telegram-mcp/runtime.service.js +36 -0
  39. package/dist/services/features/telegram-mcp/session-context.service.js +33 -0
  40. package/dist/services/features/telegram-mcp/src/app/bootstrap/runtime.js +103 -0
  41. package/dist/services/features/telegram-mcp/src/app/config/env.js +317 -0
  42. package/dist/services/features/telegram-mcp/src/app/http.js +774 -0
  43. package/dist/services/features/telegram-mcp/src/app/index.js +2 -0
  44. package/dist/services/features/telegram-mcp/src/app/providers/mcp/server.js +13 -0
  45. package/dist/services/features/telegram-mcp/src/app/providers/redis/client.js +18 -0
  46. package/dist/services/features/telegram-mcp/src/app/webapp/assets.js +740 -0
  47. package/dist/services/features/telegram-mcp/src/app/webapp/auth.js +267 -0
  48. package/dist/services/features/telegram-mcp/src/app/webapp/relay.js +69 -0
  49. package/dist/services/features/telegram-mcp/src/app/webapp/tmux.js +9 -0
  50. package/dist/services/features/telegram-mcp/src/entities/auth/model/types.js +2 -0
  51. package/dist/services/features/telegram-mcp/src/entities/browser/model/types.js +2 -0
  52. package/dist/services/features/telegram-mcp/src/entities/collaboration/model/types.js +2 -0
  53. package/dist/services/features/telegram-mcp/src/entities/inbox/model/types.js +2 -0
  54. package/dist/services/features/telegram-mcp/src/entities/request/model/schema.js +545 -0
  55. package/dist/services/features/telegram-mcp/src/entities/request/model/types.js +2 -0
  56. package/dist/services/features/telegram-mcp/src/entities/session/model/types.js +2 -0
  57. package/dist/services/features/telegram-mcp/src/features/ask-user/model/askUserTelegram.js +33 -0
  58. package/dist/services/features/telegram-mcp/src/features/browser/model/browserClearLogsTool.js +28 -0
  59. package/dist/services/features/telegram-mcp/src/features/browser/model/browserClickTool.js +28 -0
  60. package/dist/services/features/telegram-mcp/src/features/browser/model/browserCloseTool.js +28 -0
  61. package/dist/services/features/telegram-mcp/src/features/browser/model/browserComputedStyleTool.js +28 -0
  62. package/dist/services/features/telegram-mcp/src/features/browser/model/browserConsoleTool.js +28 -0
  63. package/dist/services/features/telegram-mcp/src/features/browser/model/browserDomTool.js +28 -0
  64. package/dist/services/features/telegram-mcp/src/features/browser/model/browserErrorsTool.js +28 -0
  65. package/dist/services/features/telegram-mcp/src/features/browser/model/browserFillTool.js +28 -0
  66. package/dist/services/features/telegram-mcp/src/features/browser/model/browserNetworkFailuresTool.js +28 -0
  67. package/dist/services/features/telegram-mcp/src/features/browser/model/browserOpenTool.js +33 -0
  68. package/dist/services/features/telegram-mcp/src/features/browser/model/browserPressTool.js +28 -0
  69. package/dist/services/features/telegram-mcp/src/features/browser/model/browserReloadTool.js +28 -0
  70. package/dist/services/features/telegram-mcp/src/features/browser/model/browserScreenshotTool.js +28 -0
  71. package/dist/services/features/telegram-mcp/src/features/browser/model/browserService.js +689 -0
  72. package/dist/services/features/telegram-mcp/src/features/browser/model/browserWaitForTool.js +28 -0
  73. package/dist/services/features/telegram-mcp/src/features/browser/model/browserWaitForUrlTool.js +28 -0
  74. package/dist/services/features/telegram-mcp/src/features/collaboration/model/backend.js +2 -0
  75. package/dist/services/features/telegram-mcp/src/features/collaboration/model/collaborationService.js +26 -0
  76. package/dist/services/features/telegram-mcp/src/features/collaboration/model/localCollaborationBackend.js +390 -0
  77. package/dist/services/features/telegram-mcp/src/features/collaboration/model/sendPartnerFileService.js +102 -0
  78. package/dist/services/features/telegram-mcp/src/features/collaboration/model/sendPartnerFileTool.js +33 -0
  79. package/dist/services/features/telegram-mcp/src/features/collaboration/model/sendPartnerNoteTool.js +33 -0
  80. package/dist/services/features/telegram-mcp/src/features/distributed-client/model/gatewayCollaborationBackend.js +69 -0
  81. package/dist/services/features/telegram-mcp/src/features/distributed-gateway/model/gatewayHttpService.js +657 -0
  82. package/dist/services/features/telegram-mcp/src/features/distributed-gateway/model/gatewayReplyResolution.js +17 -0
  83. package/dist/services/features/telegram-mcp/src/features/inbox/model/deleteTelegramInboxMessageTool.js +33 -0
  84. package/dist/services/features/telegram-mcp/src/features/inbox/model/getTelegramInboxCountTool.js +33 -0
  85. package/dist/services/features/telegram-mcp/src/features/inbox/model/getTelegramInboxTool.js +33 -0
  86. package/dist/services/features/telegram-mcp/src/features/inbox/model/inboxService.js +77 -0
  87. package/dist/services/features/telegram-mcp/src/features/notify/model/notifyService.js +93 -0
  88. package/dist/services/features/telegram-mcp/src/features/notify/model/notifyTelegramTool.js +33 -0
  89. package/dist/services/features/telegram-mcp/src/features/pair-session/model/clearSessionPairingTool.js +33 -0
  90. package/dist/services/features/telegram-mcp/src/features/pair-session/model/createSessionPairCodeTool.js +33 -0
  91. package/dist/services/features/telegram-mcp/src/features/pair-session/model/generatePairCode.js +202 -0
  92. package/dist/services/features/telegram-mcp/src/features/session-context/model/clearSessionContextTool.js +33 -0
  93. package/dist/services/features/telegram-mcp/src/features/session-context/model/getSessionContextTool.js +33 -0
  94. package/dist/services/features/telegram-mcp/src/features/session-context/model/getTmuxTargetTool.js +33 -0
  95. package/dist/services/features/telegram-mcp/src/features/session-context/model/renameSessionTool.js +33 -0
  96. package/dist/services/features/telegram-mcp/src/features/session-context/model/sessionContextService.js +409 -0
  97. package/dist/services/features/telegram-mcp/src/features/session-context/model/setSessionContextTool.js +33 -0
  98. package/dist/services/features/telegram-mcp/src/features/session-context/model/setTmuxTargetTool.js +33 -0
  99. package/dist/services/features/telegram-mcp/src/features/tools-sync/model/refreshToolsMarkdownService.js +123 -0
  100. package/dist/services/features/telegram-mcp/src/features/tools-sync/model/refreshToolsMarkdownTool.js +33 -0
  101. package/dist/services/features/telegram-mcp/src/processes/human-approval/model/orchestrator.js +243 -0
  102. package/dist/services/features/telegram-mcp/src/shared/api/storage/contract.js +2 -0
  103. package/dist/services/features/telegram-mcp/src/shared/api/tool-registry/registry.js +8 -0
  104. package/dist/services/features/telegram-mcp/src/shared/api/tool-registry/types.js +2 -0
  105. package/dist/services/features/telegram-mcp/src/shared/api/transport/contract.js +2 -0
  106. package/dist/services/features/telegram-mcp/src/shared/integrations/object-storage/minioExchangeStore.js +86 -0
  107. package/dist/services/features/telegram-mcp/src/shared/integrations/redis/stateStore.js +436 -0
  108. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/collabSemantics.js +21 -0
  109. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/collabUi.js +87 -0
  110. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/messageFormat.js +60 -0
  111. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/proxyFetch.js +46 -0
  112. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transport.js +6534 -0
  113. package/dist/services/features/telegram-mcp/src/shared/integrations/tmux/client.js +280 -0
  114. package/dist/services/features/telegram-mcp/src/shared/lib/ids/ids.js +34 -0
  115. package/dist/services/features/telegram-mcp/src/shared/lib/logger/logger.js +68 -0
  116. package/dist/services/features/telegram-mcp/src/shared/lib/project-identity/projectIdentity.js +223 -0
  117. package/dist/services/features/telegram-mcp/src/shared/lib/redact-secrets/redactSecrets.js +22 -0
  118. package/dist/services/features/telegram-mcp/src/shared/lib/truncate/truncate.js +12 -0
  119. package/dist/services/features/telegram-mcp/src/shared/lib/version/versionHandshake.js +124 -0
  120. package/dist/services/features/telegram-mcp/src/shared/types/common.js +2 -0
  121. package/dist/services/features/telegram-mcp/standalone-http.service.js +113 -0
  122. package/dist/services/features/telegram-mcp/tools-sync.service.js +33 -0
  123. package/package.json +110 -0
  124. package/scripts/postinstall.js +60 -0
@@ -0,0 +1,657 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GatewayHttpService = void 0;
4
+ const node_fs_1 = require("node:fs");
5
+ const node_path_1 = require("node:path");
6
+ const schema_1 = require("../../../entities/request/model/schema");
7
+ function readHeader(req, headerName) {
8
+ const value = req.headers[headerName];
9
+ return Array.isArray(value) ? value[0] : value;
10
+ }
11
+ function writeJson(res, statusCode, payload) {
12
+ res.statusCode = statusCode;
13
+ res.setHeader("content-type", "application/json");
14
+ res.end(JSON.stringify(payload));
15
+ }
16
+ function writeText(res, statusCode, message) {
17
+ res.statusCode = statusCode;
18
+ res.setHeader("content-type", "text/plain; charset=utf-8");
19
+ res.end(message);
20
+ }
21
+ function unwrapLiveRelayResult(response) {
22
+ if (!response || typeof response !== "object") {
23
+ return null;
24
+ }
25
+ if ("result" in response) {
26
+ const wrapped = response;
27
+ if (wrapped.result && typeof wrapped.result === "object") {
28
+ return wrapped.result;
29
+ }
30
+ }
31
+ return response;
32
+ }
33
+ function normalizeLiveRelayBootstrapResult(response) {
34
+ if (!response || typeof response !== "object") {
35
+ return null;
36
+ }
37
+ const record = response;
38
+ const sessionId = typeof record.session_id === "string" ? record.session_id.trim() : "";
39
+ const telegramUserId = typeof record.telegram_user_id === "number"
40
+ ? record.telegram_user_id
41
+ : typeof record.telegram_user_id === "string" &&
42
+ /^\d+$/u.test(record.telegram_user_id.trim())
43
+ ? Number(record.telegram_user_id.trim())
44
+ : NaN;
45
+ if (!sessionId || !Number.isFinite(telegramUserId)) {
46
+ return null;
47
+ }
48
+ return {
49
+ session_id: sessionId,
50
+ session_label: typeof record.session_label === "string" ? record.session_label : null,
51
+ tmux_target: record.tmux_target === true,
52
+ poll_interval_ms: typeof record.poll_interval_ms === "number" && record.poll_interval_ms > 0
53
+ ? record.poll_interval_ms
54
+ : 2000,
55
+ telegram_user_id: telegramUserId,
56
+ };
57
+ }
58
+ function buildPartnerNoteOutputFallback(input, rawOutput) {
59
+ const outputRecord = rawOutput && typeof rawOutput === "object"
60
+ ? rawOutput
61
+ : {};
62
+ return {
63
+ session_id: typeof outputRecord.session_id === "string"
64
+ ? outputRecord.session_id
65
+ : input.session_id ?? "unknown-session",
66
+ partner_session_id: typeof outputRecord.partner_session_id === "string"
67
+ ? outputRecord.partner_session_id
68
+ : input.target_session_id ?? "unknown-partner-session",
69
+ kind: typeof outputRecord.kind === "string"
70
+ ? outputRecord.kind
71
+ : input.kind,
72
+ share_id: typeof outputRecord.share_id === "string"
73
+ ? outputRecord.share_id
74
+ : `gateway-${Date.now()}`,
75
+ delivery_status: outputRecord.delivery_status === "delivered" ? "delivered" : "queued",
76
+ note_path: typeof outputRecord.note_path === "string"
77
+ ? outputRecord.note_path
78
+ : "gateway://shares/pending.md",
79
+ share_index_path: typeof outputRecord.share_index_path === "string"
80
+ ? outputRecord.share_index_path
81
+ : "gateway://SHARED_INDEX.md",
82
+ copied_artifacts: Array.isArray(outputRecord.copied_artifacts)
83
+ ? outputRecord.copied_artifacts.filter((item) => typeof item === "string")
84
+ : [
85
+ ...(input.artifact_refs?.map((item) => item.original_name ?? item.relative_path ?? item.file_path) ?? []),
86
+ ...(input.artifacts ?? []),
87
+ ],
88
+ inbox_message_id: typeof outputRecord.inbox_message_id === "string"
89
+ ? outputRecord.inbox_message_id
90
+ : `gateway-${Date.now()}`,
91
+ requires_reply: typeof outputRecord.requires_reply === "boolean"
92
+ ? outputRecord.requires_reply
93
+ : Boolean(input.requires_reply ?? (input.kind === "question" || input.kind === "request")),
94
+ };
95
+ }
96
+ class GatewayHttpService {
97
+ config;
98
+ callBroker;
99
+ constructor(config, callBroker) {
100
+ this.config = config;
101
+ this.callBroker = callBroker;
102
+ }
103
+ partnerNoteRelayHandler = null;
104
+ setPartnerNoteRelayHandler(handler) {
105
+ this.partnerNoteRelayHandler = handler;
106
+ }
107
+ isEnabled() {
108
+ return (this.config.distributed.mode === "gateway" ||
109
+ this.config.distributed.mode === "both");
110
+ }
111
+ matches(pathname) {
112
+ return pathname === "/gateway/healthz" || pathname.startsWith("/gateway/");
113
+ }
114
+ async requestLiveRelayBootstrap(input) {
115
+ const payload = typeof input.telegramUserId === "number"
116
+ ? {
117
+ telegramUserId: input.telegramUserId,
118
+ ...(input.allowForeignBinding ? { allowForeignBinding: true } : {}),
119
+ }
120
+ : {
121
+ initDataRaw: input.initDataRaw,
122
+ initDataUnsafe: input.initDataUnsafe,
123
+ };
124
+ const rawResponse = await this.callBroker("telegramMcp.gatewaySocket.requestLiveRelay", {
125
+ clientUuid: input.clientUuid,
126
+ localSessionId: input.localSessionId,
127
+ requestType: "bootstrap",
128
+ payload,
129
+ }, { meta: { internal_call: true } });
130
+ const response = normalizeLiveRelayBootstrapResult(unwrapLiveRelayResult(rawResponse));
131
+ if (!response) {
132
+ throw new Error(`Invalid live relay bootstrap response: ${JSON.stringify(rawResponse)}`);
133
+ }
134
+ return response;
135
+ }
136
+ async requestLiveRelayBootstrapValidation(input) {
137
+ const rawResponse = await this.callBroker("telegramMcp.gatewaySocket.requestLiveRelay", {
138
+ clientUuid: input.clientUuid,
139
+ localSessionId: "",
140
+ requestType: "bootstrap_validate",
141
+ payload: {
142
+ initDataRaw: input.initDataRaw,
143
+ initDataUnsafe: input.initDataUnsafe,
144
+ },
145
+ }, { meta: { internal_call: true } });
146
+ const response = unwrapLiveRelayResult(rawResponse);
147
+ if (!response ||
148
+ typeof response !== "object" ||
149
+ typeof response.telegram_user_id !== "number") {
150
+ throw new Error(`Invalid live relay bootstrap validation response: ${JSON.stringify(rawResponse)}`);
151
+ }
152
+ return response;
153
+ }
154
+ async requestLiveRelayView(input) {
155
+ const rawResponse = await this.callBroker("telegramMcp.gatewaySocket.requestLiveRelay", {
156
+ clientUuid: input.clientUuid,
157
+ localSessionId: input.localSessionId,
158
+ requestType: "view",
159
+ payload: {},
160
+ }, { meta: { internal_call: true } });
161
+ const response = unwrapLiveRelayResult(rawResponse);
162
+ if (!response ||
163
+ typeof response !== "object" ||
164
+ typeof response.content !== "string") {
165
+ throw new Error("Invalid live relay view response");
166
+ }
167
+ return response;
168
+ }
169
+ async requestLiveRelayAction(input) {
170
+ const rawResponse = await this.callBroker("telegramMcp.gatewaySocket.requestLiveRelay", {
171
+ clientUuid: input.clientUuid,
172
+ localSessionId: input.localSessionId,
173
+ requestType: "action",
174
+ payload: {
175
+ action: input.action,
176
+ },
177
+ }, { meta: { internal_call: true } });
178
+ const response = unwrapLiveRelayResult(rawResponse);
179
+ if (!response ||
180
+ typeof response !== "object" ||
181
+ response.ok !== true) {
182
+ throw new Error("Invalid live relay action response");
183
+ }
184
+ return response;
185
+ }
186
+ isAuthorized(req) {
187
+ if (!this.config.distributed.gatewayAuthToken) {
188
+ return true;
189
+ }
190
+ const authorization = readHeader(req, "authorization");
191
+ return authorization === `Bearer ${this.config.distributed.gatewayAuthToken}`;
192
+ }
193
+ extractActionErrorMessage(value, fallback) {
194
+ if (value && typeof value === "object") {
195
+ const record = value;
196
+ if (typeof record.message === "string" && record.message.trim()) {
197
+ return record.message;
198
+ }
199
+ const extensions = record.extensions;
200
+ if (extensions && typeof extensions === "object") {
201
+ const extRecord = extensions;
202
+ if (typeof extRecord.message === "string" && extRecord.message.trim()) {
203
+ return extRecord.message;
204
+ }
205
+ }
206
+ }
207
+ return fallback;
208
+ }
209
+ async readJsonBody(req) {
210
+ const knownBody = req.body;
211
+ if (knownBody !== undefined) {
212
+ return knownBody;
213
+ }
214
+ const knownParams = req.$params;
215
+ if (knownParams &&
216
+ typeof knownParams === "object" &&
217
+ ("kind" in knownParams ||
218
+ "summary" in knownParams ||
219
+ "message" in knownParams ||
220
+ "session_id" in knownParams)) {
221
+ return knownParams;
222
+ }
223
+ const chunks = [];
224
+ for await (const chunk of req) {
225
+ chunks.push(typeof chunk === "string" ? Buffer.from(chunk) : chunk);
226
+ }
227
+ if (chunks.length === 0) {
228
+ return undefined;
229
+ }
230
+ const raw = Buffer.concat(chunks).toString("utf8").trim();
231
+ if (!raw) {
232
+ return undefined;
233
+ }
234
+ return JSON.parse(raw);
235
+ }
236
+ async handleRequest(req, res, pathname) {
237
+ if (!this.isEnabled() || !this.matches(pathname)) {
238
+ return false;
239
+ }
240
+ if (pathname === "/gateway/healthz") {
241
+ writeJson(res, 200, {
242
+ ok: true,
243
+ service: "telegram-human-mcp-gateway",
244
+ mode: this.config.distributed.mode,
245
+ databaseConfigured: Boolean(process.env.DB_HOST && process.env.DB_NAME),
246
+ s3Configured: Boolean(this.config.distributed.gatewayS3Bucket),
247
+ });
248
+ return true;
249
+ }
250
+ if (!this.isAuthorized(req)) {
251
+ writeText(res, 401, "Unauthorized");
252
+ return true;
253
+ }
254
+ if (pathname === "/gateway/tools-md") {
255
+ if (req.method !== "GET") {
256
+ writeText(res, 405, "Method not allowed");
257
+ return true;
258
+ }
259
+ try {
260
+ const toolsPath = (0, node_path_1.join)(process.cwd(), "TOOLS.md");
261
+ res.statusCode = 200;
262
+ res.setHeader("content-type", "text/markdown; charset=utf-8");
263
+ res.end((0, node_fs_1.readFileSync)(toolsPath, "utf8"));
264
+ return true;
265
+ }
266
+ catch (error) {
267
+ writeJson(res, 404, {
268
+ error: error instanceof Error ? error.message : String(error),
269
+ });
270
+ return true;
271
+ }
272
+ }
273
+ if (pathname === "/gateway/partner-note") {
274
+ if (req.method !== "POST") {
275
+ writeText(res, 405, "Method not allowed");
276
+ return true;
277
+ }
278
+ try {
279
+ const body = await this.readJsonBody(req);
280
+ const input = schema_1.sendPartnerNoteInputSchema.parse(body);
281
+ const useQueuedGatewayDelivery = typeof body?.client_uuid === "string" &&
282
+ typeof input.target_session_id === "string" &&
283
+ input.target_session_id.trim().length > 0;
284
+ const output = useQueuedGatewayDelivery
285
+ ? await this.callBroker("telegramMcp.gateway.sendPartnerNote", body, { meta: { internal_call: true } })
286
+ : this.partnerNoteRelayHandler
287
+ ? await this.partnerNoteRelayHandler(input)
288
+ : (() => {
289
+ throw new Error("Gateway partner relay handler is not configured.");
290
+ })();
291
+ if (useQueuedGatewayDelivery &&
292
+ output &&
293
+ typeof output === "object" &&
294
+ typeof output.target_client_uuid ===
295
+ "string" &&
296
+ output.delivery &&
297
+ typeof output.delivery === "object") {
298
+ const publishResult = await this.callBroker("telegramMcp.gatewayRmq.publishDeliveryQueued", {
299
+ clientUuid: output.target_client_uuid,
300
+ delivery: output.delivery,
301
+ }, { meta: { internal_call: true } });
302
+ if (!publishResult?.published) {
303
+ await this.callBroker("telegramMcp.gatewaySocket.notifyDeliveryQueued", {
304
+ clientUuid: output.target_client_uuid,
305
+ delivery: output.delivery,
306
+ }, { meta: { internal_call: true } });
307
+ }
308
+ }
309
+ const parsedOutput = schema_1.sendPartnerNoteOutputSchema.safeParse(output);
310
+ if (!parsedOutput.success) {
311
+ if (useQueuedGatewayDelivery) {
312
+ writeJson(res, 500, {
313
+ error: "Invalid queued gateway partner-note response",
314
+ details: parsedOutput.error.issues,
315
+ output,
316
+ });
317
+ return true;
318
+ }
319
+ const fallback = buildPartnerNoteOutputFallback(input, output);
320
+ writeJson(res, 200, fallback);
321
+ return true;
322
+ }
323
+ writeJson(res, 200, parsedOutput.data);
324
+ return true;
325
+ }
326
+ catch (error) {
327
+ writeJson(res, 400, {
328
+ error: error instanceof Error ? error.message : String(error),
329
+ });
330
+ return true;
331
+ }
332
+ }
333
+ if (pathname === "/gateway/live/request-approval") {
334
+ if (req.method !== "POST") {
335
+ writeText(res, 405, "Method not allowed");
336
+ return true;
337
+ }
338
+ try {
339
+ const body = (await this.readJsonBody(req));
340
+ const clientUuid = typeof body.client_uuid === "string" ? body.client_uuid.trim() : "";
341
+ const payload = body.payload && typeof body.payload === "object"
342
+ ? body.payload
343
+ : null;
344
+ if (!clientUuid || !payload) {
345
+ writeJson(res, 400, { error: "client_uuid and payload are required" });
346
+ return true;
347
+ }
348
+ const result = await this.callBroker("telegramMcp.gatewaySocket.notifyLiveApprovalRequest", {
349
+ clientUuid,
350
+ payload,
351
+ }, { meta: { internal_call: true } });
352
+ writeJson(res, 200, { delivered: Boolean(result?.delivered) });
353
+ return true;
354
+ }
355
+ catch (error) {
356
+ writeJson(res, 400, {
357
+ error: error instanceof Error ? error.message : String(error),
358
+ });
359
+ return true;
360
+ }
361
+ }
362
+ if (pathname === "/gateway/live/resolve-approval") {
363
+ if (req.method !== "POST") {
364
+ writeText(res, 405, "Method not allowed");
365
+ return true;
366
+ }
367
+ try {
368
+ const body = (await this.readJsonBody(req));
369
+ const clientUuid = typeof body.client_uuid === "string" ? body.client_uuid.trim() : "";
370
+ const approved = body.approved === true;
371
+ const payload = body.payload && typeof body.payload === "object"
372
+ ? body.payload
373
+ : null;
374
+ if (!clientUuid || !payload) {
375
+ writeJson(res, 400, { error: "client_uuid and payload are required" });
376
+ return true;
377
+ }
378
+ const result = await this.callBroker("telegramMcp.gatewaySocket.notifyLiveApprovalResolved", {
379
+ clientUuid,
380
+ approved,
381
+ payload,
382
+ }, { meta: { internal_call: true } });
383
+ writeJson(res, 200, { delivered: Boolean(result?.delivered) });
384
+ return true;
385
+ }
386
+ catch (error) {
387
+ writeJson(res, 400, {
388
+ error: error instanceof Error ? error.message : String(error),
389
+ });
390
+ return true;
391
+ }
392
+ }
393
+ if (pathname === "/gateway/client/register") {
394
+ if (req.method !== "POST") {
395
+ writeText(res, 405, "Method not allowed");
396
+ return true;
397
+ }
398
+ try {
399
+ const body = (await this.readJsonBody(req));
400
+ const result = await this.callBroker("telegramMcp.gateway.registerClient", body, { meta: { internal_call: true } });
401
+ writeJson(res, 200, result);
402
+ return true;
403
+ }
404
+ catch (error) {
405
+ writeJson(res, 400, {
406
+ error: error instanceof Error ? error.message : String(error),
407
+ });
408
+ return true;
409
+ }
410
+ }
411
+ if (pathname === "/gateway/projects/create") {
412
+ if (req.method !== "POST") {
413
+ writeText(res, 405, "Method not allowed");
414
+ return true;
415
+ }
416
+ try {
417
+ const body = (await this.readJsonBody(req));
418
+ const result = await this.callBroker("telegramMcp.gateway.createProject", body, { meta: { internal_call: true } });
419
+ writeJson(res, 200, result);
420
+ return true;
421
+ }
422
+ catch (error) {
423
+ writeJson(res, 400, {
424
+ error: error instanceof Error ? error.message : String(error),
425
+ });
426
+ return true;
427
+ }
428
+ }
429
+ if (pathname === "/gateway/projects/join") {
430
+ if (req.method !== "POST") {
431
+ writeText(res, 405, "Method not allowed");
432
+ return true;
433
+ }
434
+ try {
435
+ const body = (await this.readJsonBody(req));
436
+ const result = await this.callBroker("telegramMcp.gateway.joinProject", body, { meta: { internal_call: true } });
437
+ if (Array.isArray(result.notify_client_uuids) &&
438
+ result.notify_client_uuids.length > 0 &&
439
+ typeof result.project_uuid === "string" &&
440
+ typeof result.name === "string") {
441
+ const publishResult = await this.callBroker("telegramMcp.gatewayRmq.publishProjectMemberJoined", {
442
+ clientUuids: result.notify_client_uuids,
443
+ projectUuid: result.project_uuid,
444
+ projectName: result.name,
445
+ memberDisplayName: typeof result.member_display_name === "string"
446
+ ? result.member_display_name
447
+ : undefined,
448
+ memberTelegramUsername: typeof result.member_telegram_username === "string"
449
+ ? result.member_telegram_username
450
+ : undefined,
451
+ }, { meta: { internal_call: true } });
452
+ if (!publishResult?.published) {
453
+ await this.callBroker("telegramMcp.gatewaySocket.notifyProjectMemberJoined", {
454
+ clientUuids: result.notify_client_uuids,
455
+ projectUuid: result.project_uuid,
456
+ projectName: result.name,
457
+ memberDisplayName: typeof result.member_display_name === "string"
458
+ ? result.member_display_name
459
+ : undefined,
460
+ memberTelegramUsername: typeof result.member_telegram_username === "string"
461
+ ? result.member_telegram_username
462
+ : undefined,
463
+ }, { meta: { internal_call: true } });
464
+ }
465
+ }
466
+ writeJson(res, 200, result);
467
+ return true;
468
+ }
469
+ catch (error) {
470
+ writeJson(res, 400, {
471
+ error: error instanceof Error ? error.message : String(error),
472
+ });
473
+ return true;
474
+ }
475
+ }
476
+ if (pathname === "/gateway/sessions/register") {
477
+ if (req.method !== "POST") {
478
+ writeText(res, 405, "Method not allowed");
479
+ return true;
480
+ }
481
+ try {
482
+ const body = (await this.readJsonBody(req));
483
+ const result = await this.callBroker("telegramMcp.gateway.registerSession", body, { meta: { internal_call: true } });
484
+ writeJson(res, 200, result);
485
+ return true;
486
+ }
487
+ catch (error) {
488
+ writeJson(res, 400, {
489
+ error: error instanceof Error ? error.message : String(error),
490
+ });
491
+ return true;
492
+ }
493
+ }
494
+ if (pathname === "/gateway/sessions/unregister") {
495
+ if (req.method !== "POST") {
496
+ writeText(res, 405, "Method not allowed");
497
+ return true;
498
+ }
499
+ try {
500
+ const body = (await this.readJsonBody(req));
501
+ const result = await this.callBroker("telegramMcp.gateway.unregisterSession", body, { meta: { internal_call: true } });
502
+ writeJson(res, 200, result);
503
+ return true;
504
+ }
505
+ catch (error) {
506
+ writeJson(res, 400, {
507
+ error: error instanceof Error ? error.message : String(error),
508
+ });
509
+ return true;
510
+ }
511
+ }
512
+ if (pathname === "/gateway/projects/list") {
513
+ if (req.method !== "POST") {
514
+ writeText(res, 405, "Method not allowed");
515
+ return true;
516
+ }
517
+ try {
518
+ const body = (await this.readJsonBody(req));
519
+ const result = await this.callBroker("telegramMcp.gateway.listProjects", body, { meta: { internal_call: true } });
520
+ writeJson(res, 200, result);
521
+ return true;
522
+ }
523
+ catch (error) {
524
+ writeJson(res, 400, {
525
+ error: error instanceof Error ? error.message : String(error),
526
+ });
527
+ return true;
528
+ }
529
+ }
530
+ if (pathname === "/gateway/history/list") {
531
+ if (req.method !== "POST") {
532
+ writeText(res, 405, "Method not allowed");
533
+ return true;
534
+ }
535
+ try {
536
+ const body = (await this.readJsonBody(req));
537
+ const result = await this.callBroker("telegramMcp.gateway.listSessionHistory", body, { meta: { internal_call: true } });
538
+ writeJson(res, 200, result);
539
+ return true;
540
+ }
541
+ catch (error) {
542
+ writeJson(res, 400, {
543
+ error: error instanceof Error ? error.message : String(error),
544
+ });
545
+ return true;
546
+ }
547
+ }
548
+ if (pathname === "/gateway/projects/leave") {
549
+ if (req.method !== "POST") {
550
+ writeText(res, 405, "Method not allowed");
551
+ return true;
552
+ }
553
+ try {
554
+ const body = (await this.readJsonBody(req));
555
+ const result = await this.callBroker("telegramMcp.gateway.leaveProject", body, { meta: { internal_call: true } });
556
+ if (result.left === true &&
557
+ Array.isArray(result.notify_client_uuids) &&
558
+ result.notify_client_uuids.length > 0 &&
559
+ typeof result.project_uuid === "string" &&
560
+ typeof result.project_name === "string") {
561
+ const publishResult = await this.callBroker("telegramMcp.gatewayRmq.publishProjectMemberLeft", {
562
+ clientUuids: result.notify_client_uuids,
563
+ projectUuid: result.project_uuid,
564
+ projectName: result.project_name,
565
+ memberDisplayName: typeof result.member_display_name === "string"
566
+ ? result.member_display_name
567
+ : undefined,
568
+ memberTelegramUsername: typeof result.member_telegram_username === "string"
569
+ ? result.member_telegram_username
570
+ : undefined,
571
+ }, { meta: { internal_call: true } });
572
+ if (!publishResult?.published) {
573
+ await this.callBroker("telegramMcp.gatewaySocket.notifyProjectMemberLeft", {
574
+ clientUuids: result.notify_client_uuids,
575
+ projectUuid: result.project_uuid,
576
+ projectName: result.project_name,
577
+ memberDisplayName: typeof result.member_display_name === "string"
578
+ ? result.member_display_name
579
+ : undefined,
580
+ memberTelegramUsername: typeof result.member_telegram_username === "string"
581
+ ? result.member_telegram_username
582
+ : undefined,
583
+ }, { meta: { internal_call: true } });
584
+ }
585
+ }
586
+ writeJson(res, 200, result);
587
+ return true;
588
+ }
589
+ catch (error) {
590
+ writeJson(res, 400, {
591
+ error: error instanceof Error ? error.message : String(error),
592
+ });
593
+ return true;
594
+ }
595
+ }
596
+ if (pathname === "/gateway/projects/delete") {
597
+ if (req.method !== "POST") {
598
+ writeText(res, 405, "Method not allowed");
599
+ return true;
600
+ }
601
+ try {
602
+ const body = (await this.readJsonBody(req));
603
+ const result = await this.callBroker("telegramMcp.gateway.deleteProject", body, { meta: { internal_call: true } });
604
+ if (result.deleted === true &&
605
+ Array.isArray(result.notify_client_uuids) &&
606
+ result.notify_client_uuids.length > 0 &&
607
+ typeof result.project_uuid === "string" &&
608
+ typeof result.project_name === "string") {
609
+ const publishResult = await this.callBroker("telegramMcp.gatewayRmq.publishProjectDeleted", {
610
+ clientUuids: result.notify_client_uuids,
611
+ projectUuid: result.project_uuid,
612
+ projectName: result.project_name,
613
+ }, { meta: { internal_call: true } });
614
+ if (!publishResult?.published) {
615
+ await this.callBroker("telegramMcp.gatewaySocket.notifyProjectDeleted", {
616
+ clientUuids: result.notify_client_uuids,
617
+ projectUuid: result.project_uuid,
618
+ projectName: result.project_name,
619
+ }, { meta: { internal_call: true } });
620
+ }
621
+ }
622
+ writeJson(res, 200, result);
623
+ return true;
624
+ }
625
+ catch (error) {
626
+ writeJson(res, 400, {
627
+ error: error instanceof Error ? error.message : String(error),
628
+ });
629
+ return true;
630
+ }
631
+ }
632
+ if (pathname === "/gateway/projects/sessions") {
633
+ if (req.method !== "POST") {
634
+ writeText(res, 405, "Method not allowed");
635
+ return true;
636
+ }
637
+ try {
638
+ const body = (await this.readJsonBody(req));
639
+ const result = await this.callBroker("telegramMcp.gateway.listProjectSessions", body, { meta: { internal_call: true } });
640
+ writeJson(res, 200, result);
641
+ return true;
642
+ }
643
+ catch (error) {
644
+ writeJson(res, 400, {
645
+ error: error instanceof Error ? error.message : String(error),
646
+ });
647
+ return true;
648
+ }
649
+ }
650
+ writeJson(res, 501, {
651
+ error: "Distributed gateway relay is scaffolded but not implemented yet in this build.",
652
+ mode: this.config.distributed.mode,
653
+ });
654
+ return true;
655
+ }
656
+ }
657
+ exports.GatewayHttpService = GatewayHttpService;
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.resolveGatewayInReplyTo = resolveGatewayInReplyTo;
4
+ function normalizeOptionalText(value) {
5
+ return typeof value === "string" && value.trim() ? value.trim() : undefined;
6
+ }
7
+ async function resolveGatewayInReplyTo(inReplyTo, deps) {
8
+ const candidate = normalizeOptionalText(inReplyTo);
9
+ if (!candidate) {
10
+ return undefined;
11
+ }
12
+ const direct = normalizeOptionalText(await deps.findMessageUuidByMessageUuid(candidate));
13
+ if (direct) {
14
+ return direct;
15
+ }
16
+ return normalizeOptionalText(await deps.findMessageUuidByShareId(candidate));
17
+ }