@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.
Files changed (157) hide show
  1. package/.env.example.client +42 -50
  2. package/.env.example.gateway +49 -61
  3. package/CHANGELOG.md +3 -3
  4. package/README-ru.md +205 -384
  5. package/README.md +195 -1194
  6. package/TOOLS.md +294 -377
  7. package/VERSION.md +36 -10
  8. package/config/codex/plugins/telly-workflows/.codex-plugin/plugin.json +18 -0
  9. package/config/codex/plugins/telly-workflows/references/invariants.md +10 -0
  10. package/config/codex/plugins/telly-workflows/skills/telly-browser-screenshot/SKILL.md +27 -0
  11. package/config/codex/plugins/telly-workflows/skills/telly-collab-artifact/SKILL.md +22 -0
  12. package/config/codex/plugins/telly-workflows/skills/telly-human-telegram/SKILL.md +31 -0
  13. package/config/codex/plugins/telly-workflows/skills/telly-partner-note/SKILL.md +36 -0
  14. package/config/templates/env.both.template +40 -20
  15. package/config/templates/env.client.template +34 -18
  16. package/config/templates/env.gateway.template +38 -22
  17. package/dist/cli.js +322 -75
  18. package/dist/codexPluginInstaller.js +215 -0
  19. package/dist/lib/mixins/session.errors.js +34 -1
  20. package/dist/lib/pinoTargets.js +2 -2
  21. package/dist/moleculer.config.js +7 -5
  22. package/dist/services/features/telegram-mcp/approval.service.js +1 -1
  23. package/dist/services/features/telegram-mcp/browser.service.js +95 -2
  24. package/dist/services/features/telegram-mcp/collaboration.service.js +41 -4
  25. package/dist/services/features/telegram-mcp/ensuredb.service.js +145 -26
  26. package/dist/services/features/telegram-mcp/gateway-delivery.service.js +285 -103
  27. package/dist/services/features/telegram-mcp/gateway-rmq.service.js +3 -2
  28. package/dist/services/features/telegram-mcp/gateway-socket.service.js +905 -87
  29. package/dist/services/features/telegram-mcp/gateway.service.js +876 -81
  30. package/dist/services/features/telegram-mcp/mcp-http.service.js +9 -1
  31. package/dist/services/features/telegram-mcp/mcp-server.service.js +17 -26
  32. package/dist/services/features/telegram-mcp/notify.service.js +128 -2
  33. package/dist/services/features/telegram-mcp/runtime.service.js +27 -7
  34. package/dist/services/features/telegram-mcp/session-context.service.js +29 -2
  35. package/dist/services/features/telegram-mcp/src/app/bootstrap/runtime.js +133 -10
  36. package/dist/services/features/telegram-mcp/src/app/config/env.js +161 -51
  37. package/dist/services/features/telegram-mcp/src/app/http.js +375 -42
  38. package/dist/services/features/telegram-mcp/src/app/webapp/assets.js +386 -58
  39. package/dist/services/features/telegram-mcp/src/app/webapp/auth.js +3 -0
  40. package/dist/services/features/telegram-mcp/src/app/webapp/terminal.js +12 -0
  41. package/dist/services/features/telegram-mcp/src/entities/request/model/schema.js +116 -104
  42. package/dist/services/features/telegram-mcp/src/entities/xchange/model/types.js +2 -0
  43. package/dist/services/features/telegram-mcp/src/features/ask-user/model/askUserTelegram.js +1 -1
  44. package/dist/services/features/telegram-mcp/src/features/browser/model/browserScreenshotTool.js +1 -1
  45. package/dist/services/features/telegram-mcp/src/features/browser/model/browserService.js +249 -19
  46. package/dist/services/features/telegram-mcp/src/features/collaboration/model/gatewaySessionsService.js +71 -0
  47. package/dist/services/features/telegram-mcp/src/features/collaboration/model/listGatewaySessionsTool.js +33 -0
  48. package/dist/services/features/telegram-mcp/src/features/collaboration/model/localCollaborationBackend.js +93 -82
  49. package/dist/services/features/telegram-mcp/src/features/collaboration/model/sendPartnerFileService.js +47 -5
  50. package/dist/services/features/telegram-mcp/src/features/collaboration/model/sendPartnerFileTool.js +1 -1
  51. package/dist/services/features/telegram-mcp/src/features/collaboration/model/sendPartnerNoteTool.js +1 -1
  52. package/dist/services/features/telegram-mcp/src/features/distributed-client/model/gatewayClientAccess.js +82 -0
  53. package/dist/services/features/telegram-mcp/src/features/distributed-client/model/gatewayCollaborationBackend.js +22 -14
  54. package/dist/services/features/telegram-mcp/src/features/distributed-gateway/model/gatewayHttpService.js +649 -75
  55. package/dist/services/features/telegram-mcp/src/features/distributed-gateway/model/remoteConsoleActionClient.js +76 -0
  56. package/dist/services/features/telegram-mcp/src/features/embedded-runtime/model/embeddedRuntimeBroker.js +92 -0
  57. package/dist/services/features/telegram-mcp/src/features/foreground-terminal/model/foregroundTerminalRuntime.js +192 -0
  58. package/dist/services/features/telegram-mcp/src/features/notify/model/notifyService.js +382 -3
  59. package/dist/services/features/telegram-mcp/src/features/notify/model/notifyTelegramTool.js +1 -1
  60. package/dist/services/features/telegram-mcp/src/features/notify/model/sendFileToTelegramTool.js +33 -0
  61. package/dist/services/features/telegram-mcp/src/features/session-context/model/clearSessionContextTool.js +1 -1
  62. package/dist/services/features/telegram-mcp/src/features/session-context/model/getSessionContextTool.js +1 -1
  63. package/dist/services/features/telegram-mcp/src/features/session-context/model/renameSessionTool.js +1 -1
  64. package/dist/services/features/telegram-mcp/src/features/session-context/model/sessionContextService.js +42 -200
  65. package/dist/services/features/telegram-mcp/src/features/session-context/model/setSessionContextTool.js +1 -1
  66. package/dist/services/features/telegram-mcp/src/features/terminal-buffer/model/terminalBufferService.js +96 -0
  67. package/dist/services/features/telegram-mcp/src/features/terminal-input/model/terminalInputService.js +97 -0
  68. package/dist/services/features/telegram-mcp/src/features/tools-sync/model/refreshToolsMarkdownService.js +107 -58
  69. package/dist/services/features/telegram-mcp/src/features/tools-sync/model/refreshToolsMarkdownTool.js +1 -1
  70. package/dist/services/features/telegram-mcp/src/features/xchange/model/getXchangeRecordTool.js +28 -0
  71. package/dist/services/features/telegram-mcp/src/features/xchange/model/listXchangeRecordsTool.js +28 -0
  72. package/dist/services/features/telegram-mcp/src/features/xchange/model/markXchangeRecordReadTool.js +28 -0
  73. package/dist/services/features/telegram-mcp/src/features/xchange/model/xchangeService.js +169 -0
  74. package/dist/services/features/telegram-mcp/src/processes/human-approval/model/orchestrator.js +5 -4
  75. package/dist/services/features/telegram-mcp/src/shared/i18n/index.js +46 -0
  76. package/dist/services/features/telegram-mcp/src/shared/i18n/resources/en.js +652 -0
  77. package/dist/services/features/telegram-mcp/src/shared/i18n/resources/ru.js +652 -0
  78. package/dist/services/features/telegram-mcp/src/shared/integrations/memory/processLocalSessionStore.js +27 -0
  79. package/dist/services/features/telegram-mcp/src/shared/integrations/object-storage/minioExchangeStore.js +11 -8
  80. package/dist/services/features/telegram-mcp/src/shared/integrations/redis/stateStore.js +51 -71
  81. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/proxyFetch.js +21 -22
  82. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transport.js +411 -6524
  83. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportAttachmentStore.js +93 -0
  84. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportBroadcastActions.js +385 -0
  85. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportConsoleRegistry.js +143 -0
  86. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportConstructorWiring.js +633 -0
  87. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportContent.js +84 -0
  88. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportContext.js +78 -0
  89. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportDocumentActions.js +36 -0
  90. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportEventActions.js +292 -0
  91. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportFileHandoffActions.js +352 -0
  92. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportFormatting.js +75 -0
  93. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportGatewayActions.js +44 -0
  94. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportLifecycleActions.js +161 -0
  95. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportLive.js +56 -0
  96. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportLiveActions.js +77 -0
  97. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportMenuCallbacks.js +254 -0
  98. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportMenuFactories.js +538 -0
  99. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportMenuFingerprints.js +93 -0
  100. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportMenuFlow.js +344 -0
  101. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportMenuShell.js +62 -0
  102. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportMenuState.js +408 -0
  103. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportMenuText.js +216 -0
  104. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportMessageFlow.js +452 -0
  105. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportOutputActions.js +189 -0
  106. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportPartnerActions.js +286 -0
  107. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportPayloadState.js +101 -0
  108. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportProjectActions.js +463 -0
  109. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportProjectEntryActions.js +202 -0
  110. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportProjectEvents.js +99 -0
  111. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportProjectMenus.js +138 -0
  112. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportProjectState.js +308 -0
  113. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportProjectView.js +426 -0
  114. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportRequestFlow.js +278 -0
  115. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportSessionActions.js +143 -0
  116. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportTerminalActions.js +468 -0
  117. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportTerminalRuntime.js +171 -0
  118. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportTypes.js +2 -0
  119. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportUtils.js +330 -0
  120. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportXchangeState.js +107 -0
  121. package/dist/services/features/telegram-mcp/src/shared/integrations/terminal/client.js +255 -0
  122. package/dist/services/features/telegram-mcp/src/shared/integrations/terminal/ptyRegistry.js +543 -0
  123. package/dist/services/features/telegram-mcp/src/shared/integrations/xchange/sqliteRecordStore.js +223 -0
  124. package/dist/services/features/telegram-mcp/src/shared/lib/gatewayScope.js +24 -0
  125. package/dist/services/features/telegram-mcp/src/shared/lib/logger/logger.js +6 -0
  126. package/dist/services/features/telegram-mcp/src/shared/lib/project-identity/projectIdentity.js +147 -76
  127. package/dist/services/features/telegram-mcp/src/shared/lib/telegramXchangeRecords.js +72 -0
  128. package/dist/services/features/telegram-mcp/src/shared/lib/terminalPromptDetection.js +237 -0
  129. package/dist/services/features/telegram-mcp/src/shared/lib/version/versionHandshake.js +129 -1
  130. package/dist/services/features/telegram-mcp/src/shared/lib/xchangeRecordHints.js +98 -0
  131. package/dist/services/features/telegram-mcp/standalone-http.service.js +13 -1
  132. package/dist/services/features/telegram-mcp/terminal-buffer.service.js +42 -0
  133. package/dist/services/features/telegram-mcp/terminal-input.service.js +41 -0
  134. package/dist/services/features/telegram-mcp/tools-sync.service.js +16 -2
  135. package/dist/services/features/telegram-mcp/xchange.service.js +123 -0
  136. package/docs/STANDALONE-ru.md +172 -0
  137. package/docs/STANDALONE.md +172 -0
  138. package/package.json +11 -5
  139. package/scripts/build-package-artifact.sh +27 -0
  140. package/scripts/deploy-gateway.sh +64 -0
  141. package/scripts/deploy-onebot-branch.sh +27 -0
  142. package/scripts/postinstall.js +11 -36
  143. package/STANDALONE-ru.md +0 -274
  144. package/STANDALONE.md +0 -274
  145. package/dist/services/features/telegram-mcp/inbox.service.js +0 -33
  146. package/dist/services/features/telegram-mcp/pair.service.js +0 -33
  147. package/dist/services/features/telegram-mcp/src/app/webapp/tmux.js +0 -10
  148. package/dist/services/features/telegram-mcp/src/features/inbox/model/deleteTelegramInboxMessageTool.js +0 -33
  149. package/dist/services/features/telegram-mcp/src/features/inbox/model/getTelegramInboxCountTool.js +0 -33
  150. package/dist/services/features/telegram-mcp/src/features/inbox/model/getTelegramInboxTool.js +0 -33
  151. package/dist/services/features/telegram-mcp/src/features/inbox/model/inboxService.js +0 -77
  152. package/dist/services/features/telegram-mcp/src/features/pair-session/model/clearSessionPairingTool.js +0 -33
  153. package/dist/services/features/telegram-mcp/src/features/pair-session/model/createSessionPairCodeTool.js +0 -33
  154. package/dist/services/features/telegram-mcp/src/features/pair-session/model/generatePairCode.js +0 -202
  155. package/dist/services/features/telegram-mcp/src/features/session-context/model/getTmuxTargetTool.js +0 -33
  156. package/dist/services/features/telegram-mcp/src/features/session-context/model/setTmuxTargetTool.js +0 -33
  157. package/dist/services/features/telegram-mcp/src/shared/integrations/tmux/client.js +0 -363
@@ -5,6 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.BrowserService = void 0;
7
7
  const node_path_1 = __importDefault(require("node:path"));
8
+ const gatewayClientAccess_1 = require("../../distributed-client/model/gatewayClientAccess");
8
9
  function pushBounded(list, entry, max) {
9
10
  list.push(entry);
10
11
  if (list.length > max) {
@@ -49,35 +50,47 @@ function escapeCssAttributeValue(value) {
49
50
  class BrowserService {
50
51
  config;
51
52
  sessionStore;
53
+ maintenanceStore;
52
54
  bindingStore;
53
55
  xchangeFileMetaStore;
54
56
  objectStore;
55
57
  telegramTransport;
56
58
  logger;
57
59
  projectIdentityResolver;
60
+ remoteConsoleInvoker;
58
61
  playwrightModulePromise;
59
62
  browserPromise;
60
63
  sessionStates = new Map();
61
- constructor(config, sessionStore, bindingStore, xchangeFileMetaStore, objectStore, telegramTransport, logger, projectIdentityResolver) {
64
+ constructor(config, sessionStore, maintenanceStore, bindingStore, xchangeFileMetaStore, objectStore, telegramTransport, logger, projectIdentityResolver, remoteConsoleInvoker) {
62
65
  this.config = config;
63
66
  this.sessionStore = sessionStore;
67
+ this.maintenanceStore = maintenanceStore;
64
68
  this.bindingStore = bindingStore;
65
69
  this.xchangeFileMetaStore = xchangeFileMetaStore;
66
70
  this.objectStore = objectStore;
67
71
  this.telegramTransport = telegramTransport;
68
72
  this.logger = logger;
69
73
  this.projectIdentityResolver = projectIdentityResolver;
74
+ this.remoteConsoleInvoker = remoteConsoleInvoker;
70
75
  }
71
76
  async open(input) {
72
- this.ensureEnabled();
73
77
  const resolved = this.projectIdentityResolver.resolveSessionDefaults(input);
74
- const existingState = this.sessionStates.get(resolved.sessionId);
78
+ const normalizedSessionId = await this.normalizeSessionIdForAccess(resolved.sessionId);
79
+ const remote = await this.invokeRemote(normalizedSessionId, "telegramMcp.browser.openRemote", {
80
+ ...input,
81
+ session_id: normalizedSessionId,
82
+ });
83
+ if (remote) {
84
+ return remote;
85
+ }
86
+ this.ensureEnabled();
87
+ const existingState = this.sessionStates.get(normalizedSessionId);
75
88
  const shouldReset = input.reset_context === true;
76
89
  const targetUrl = this.resolveBrowserUrl(input.url);
77
90
  if (shouldReset && existingState) {
78
- await this.closeState(resolved.sessionId, existingState);
91
+ await this.closeState(normalizedSessionId, existingState);
79
92
  }
80
- const { state, createdContext } = await this.ensureSessionState(resolved.sessionId, shouldReset);
93
+ const { state, createdContext } = await this.ensureSessionState(normalizedSessionId, shouldReset);
81
94
  const waitUntil = (input.wait_until ??
82
95
  this.config.browser.waitUntil);
83
96
  await state.page.goto(targetUrl, {
@@ -89,6 +102,7 @@ class BrowserService {
89
102
  state.lastUsedAt = new Date().toISOString();
90
103
  this.logger.info("Browser page opened", {
91
104
  sessionId: resolved.sessionId,
105
+ normalizedSessionId,
92
106
  url: state.currentUrl,
93
107
  title: state.title,
94
108
  createdContext,
@@ -96,7 +110,7 @@ class BrowserService {
96
110
  headless: this.config.browser.headless,
97
111
  });
98
112
  return {
99
- session_id: resolved.sessionId,
113
+ session_id: normalizedSessionId,
100
114
  opened: true,
101
115
  created_context: createdContext,
102
116
  url: state.currentUrl,
@@ -104,6 +118,15 @@ class BrowserService {
104
118
  };
105
119
  }
106
120
  async getConsole(input) {
121
+ const resolved = this.projectIdentityResolver.resolveSessionDefaults(input);
122
+ const normalizedSessionId = await this.normalizeSessionIdForAccess(resolved.sessionId);
123
+ const remote = await this.invokeRemote(normalizedSessionId, "telegramMcp.browser.getConsoleRemote", {
124
+ ...input,
125
+ session_id: normalizedSessionId,
126
+ });
127
+ if (remote) {
128
+ return remote;
129
+ }
107
130
  this.ensureEnabled();
108
131
  const { sessionId, state } = await this.requireSessionState(input);
109
132
  state.lastUsedAt = new Date().toISOString();
@@ -119,6 +142,15 @@ class BrowserService {
119
142
  };
120
143
  }
121
144
  async click(input) {
145
+ const resolved = this.projectIdentityResolver.resolveSessionDefaults(input);
146
+ const normalizedSessionId = await this.normalizeSessionIdForAccess(resolved.sessionId);
147
+ const remote = await this.invokeRemote(normalizedSessionId, "telegramMcp.browser.clickRemote", {
148
+ ...input,
149
+ session_id: normalizedSessionId,
150
+ });
151
+ if (remote) {
152
+ return remote;
153
+ }
122
154
  this.ensureEnabled();
123
155
  const { sessionId, state } = await this.requireSessionState(input);
124
156
  const locator = this.resolveLocator(state.page, input);
@@ -139,6 +171,15 @@ class BrowserService {
139
171
  };
140
172
  }
141
173
  async fill(input) {
174
+ const resolved = this.projectIdentityResolver.resolveSessionDefaults(input);
175
+ const normalizedSessionId = await this.normalizeSessionIdForAccess(resolved.sessionId);
176
+ const remote = await this.invokeRemote(normalizedSessionId, "telegramMcp.browser.fillRemote", {
177
+ ...input,
178
+ session_id: normalizedSessionId,
179
+ });
180
+ if (remote) {
181
+ return remote;
182
+ }
142
183
  this.ensureEnabled();
143
184
  const { sessionId, state } = await this.requireSessionState(input);
144
185
  const locator = this.resolveLocator(state.page, input);
@@ -160,6 +201,15 @@ class BrowserService {
160
201
  };
161
202
  }
162
203
  async press(input) {
204
+ const resolved = this.projectIdentityResolver.resolveSessionDefaults(input);
205
+ const normalizedSessionId = await this.normalizeSessionIdForAccess(resolved.sessionId);
206
+ const remote = await this.invokeRemote(normalizedSessionId, "telegramMcp.browser.pressRemote", {
207
+ ...input,
208
+ session_id: normalizedSessionId,
209
+ });
210
+ if (remote) {
211
+ return remote;
212
+ }
163
213
  this.ensureEnabled();
164
214
  const { sessionId, state } = await this.requireSessionState(input);
165
215
  if (input.selector || input.text) {
@@ -186,6 +236,15 @@ class BrowserService {
186
236
  };
187
237
  }
188
238
  async reload(input) {
239
+ const resolved = this.projectIdentityResolver.resolveSessionDefaults(input);
240
+ const normalizedSessionId = await this.normalizeSessionIdForAccess(resolved.sessionId);
241
+ const remote = await this.invokeRemote(normalizedSessionId, "telegramMcp.browser.reloadRemote", {
242
+ ...input,
243
+ session_id: normalizedSessionId,
244
+ });
245
+ if (remote) {
246
+ return remote;
247
+ }
189
248
  this.ensureEnabled();
190
249
  const { sessionId, state } = await this.requireSessionState(input);
191
250
  const waitUntil = (input.wait_until ??
@@ -211,6 +270,15 @@ class BrowserService {
211
270
  };
212
271
  }
213
272
  async waitFor(input) {
273
+ const resolved = this.projectIdentityResolver.resolveSessionDefaults(input);
274
+ const normalizedSessionId = await this.normalizeSessionIdForAccess(resolved.sessionId);
275
+ const remote = await this.invokeRemote(normalizedSessionId, "telegramMcp.browser.waitForRemote", {
276
+ ...input,
277
+ session_id: normalizedSessionId,
278
+ });
279
+ if (remote) {
280
+ return remote;
281
+ }
214
282
  this.ensureEnabled();
215
283
  const { sessionId, state } = await this.requireSessionState(input);
216
284
  const locator = this.resolveLocator(state.page, input);
@@ -234,6 +302,15 @@ class BrowserService {
234
302
  };
235
303
  }
236
304
  async waitForUrl(input) {
305
+ const resolved = this.projectIdentityResolver.resolveSessionDefaults(input);
306
+ const normalizedSessionId = await this.normalizeSessionIdForAccess(resolved.sessionId);
307
+ const remote = await this.invokeRemote(normalizedSessionId, "telegramMcp.browser.waitForUrlRemote", {
308
+ ...input,
309
+ session_id: normalizedSessionId,
310
+ });
311
+ if (remote) {
312
+ return remote;
313
+ }
237
314
  this.ensureEnabled();
238
315
  const { sessionId, state } = await this.requireSessionState(input);
239
316
  const timeout = this.resolveTimeoutMs(input.timeout_ms);
@@ -267,6 +344,15 @@ class BrowserService {
267
344
  };
268
345
  }
269
346
  async getErrors(input) {
347
+ const resolved = this.projectIdentityResolver.resolveSessionDefaults(input);
348
+ const normalizedSessionId = await this.normalizeSessionIdForAccess(resolved.sessionId);
349
+ const remote = await this.invokeRemote(normalizedSessionId, "telegramMcp.browser.getErrorsRemote", {
350
+ ...input,
351
+ session_id: normalizedSessionId,
352
+ });
353
+ if (remote) {
354
+ return remote;
355
+ }
270
356
  this.ensureEnabled();
271
357
  const { sessionId, state } = await this.requireSessionState(input);
272
358
  state.lastUsedAt = new Date().toISOString();
@@ -281,6 +367,15 @@ class BrowserService {
281
367
  };
282
368
  }
283
369
  async getNetworkFailures(input) {
370
+ const resolved = this.projectIdentityResolver.resolveSessionDefaults(input);
371
+ const normalizedSessionId = await this.normalizeSessionIdForAccess(resolved.sessionId);
372
+ const remote = await this.invokeRemote(normalizedSessionId, "telegramMcp.browser.getNetworkFailuresRemote", {
373
+ ...input,
374
+ session_id: normalizedSessionId,
375
+ });
376
+ if (remote) {
377
+ return remote;
378
+ }
284
379
  this.ensureEnabled();
285
380
  const { sessionId, state } = await this.requireSessionState(input);
286
381
  state.lastUsedAt = new Date().toISOString();
@@ -300,6 +395,15 @@ class BrowserService {
300
395
  };
301
396
  }
302
397
  async clearLogs(input) {
398
+ const resolved = this.projectIdentityResolver.resolveSessionDefaults(input);
399
+ const normalizedSessionId = await this.normalizeSessionIdForAccess(resolved.sessionId);
400
+ const remote = await this.invokeRemote(normalizedSessionId, "telegramMcp.browser.clearLogsRemote", {
401
+ ...input,
402
+ session_id: normalizedSessionId,
403
+ });
404
+ if (remote) {
405
+ return remote;
406
+ }
303
407
  this.ensureEnabled();
304
408
  const { sessionId, state } = await this.requireSessionState(input);
305
409
  const consoleMessagesCleared = state.consoleMessages.length;
@@ -318,6 +422,15 @@ class BrowserService {
318
422
  };
319
423
  }
320
424
  async getDom(input) {
425
+ const resolved = this.projectIdentityResolver.resolveSessionDefaults(input);
426
+ const normalizedSessionId = await this.normalizeSessionIdForAccess(resolved.sessionId);
427
+ const remote = await this.invokeRemote(normalizedSessionId, "telegramMcp.browser.getDomRemote", {
428
+ ...input,
429
+ session_id: normalizedSessionId,
430
+ });
431
+ if (remote) {
432
+ return remote;
433
+ }
321
434
  this.ensureEnabled();
322
435
  const { sessionId, state } = await this.requireSessionState(input);
323
436
  const selector = input.selector?.trim() || "body";
@@ -373,6 +486,15 @@ class BrowserService {
373
486
  };
374
487
  }
375
488
  async getComputedStyle(input) {
489
+ const resolved = this.projectIdentityResolver.resolveSessionDefaults(input);
490
+ const normalizedSessionId = await this.normalizeSessionIdForAccess(resolved.sessionId);
491
+ const remote = await this.invokeRemote(normalizedSessionId, "telegramMcp.browser.getComputedStyleRemote", {
492
+ ...input,
493
+ session_id: normalizedSessionId,
494
+ });
495
+ if (remote) {
496
+ return remote;
497
+ }
376
498
  this.ensureEnabled();
377
499
  const { sessionId, state } = await this.requireSessionState(input);
378
500
  const properties = input.properties?.length
@@ -430,6 +552,15 @@ class BrowserService {
430
552
  };
431
553
  }
432
554
  async screenshot(input) {
555
+ const resolved = this.projectIdentityResolver.resolveSessionDefaults(input);
556
+ const normalizedSessionId = await this.normalizeSessionIdForAccess(resolved.sessionId);
557
+ const remote = await this.invokeRemote(normalizedSessionId, "telegramMcp.browser.screenshotRemote", {
558
+ ...input,
559
+ session_id: normalizedSessionId,
560
+ });
561
+ if (remote) {
562
+ return remote;
563
+ }
433
564
  this.ensureEnabled();
434
565
  const { sessionId, state, session } = await this.requireSessionState(input);
435
566
  const fileName = sanitizeScreenshotName(input.file_name);
@@ -472,18 +603,34 @@ class BrowserService {
472
603
  relativePath: storedFile.relativePath,
473
604
  source: "browser-screenshot",
474
605
  uploadedAt: new Date().toISOString(),
606
+ storageRef: storedFile.storageRef,
607
+ bucketName: storedFile.bucketName,
608
+ objectName: storedFile.objectName,
609
+ vfsNodeId: storedFile.vfsNodeId,
610
+ vfsPublicUrl: storedFile.vfsPublicUrl,
611
+ vfsParentId: storedFile.vfsParentId,
475
612
  mimeType: "image/png",
476
613
  sizeBytes: storedFile.sizeBytes,
477
614
  ...(input.caption ? { caption: input.caption } : {}),
478
615
  });
479
616
  let telegramMessageId;
480
617
  if (input.send_to_telegram === true) {
481
- const binding = await this.bindingStore.getBinding(sessionId);
482
- if (!binding) {
483
- throw new Error("Session is not linked to Telegram, so screenshot cannot be sent there.");
618
+ if (this.config.distributed.mode === "client") {
619
+ telegramMessageId = await this.sendScreenshotToGatewayTelegramRoute({
620
+ sessionId,
621
+ fileName,
622
+ pngBuffer,
623
+ ...(input.caption ? { caption: input.caption } : {}),
624
+ });
625
+ }
626
+ else {
627
+ const binding = await this.bindingStore.getBinding(sessionId);
628
+ if (!binding) {
629
+ throw new Error("Session is not linked to Telegram, so screenshot cannot be sent there.");
630
+ }
631
+ const sent = await this.telegramTransport.sendDocumentToChat(binding.telegramChatId, filePath, input.caption);
632
+ telegramMessageId = sent.messageId;
484
633
  }
485
- const sent = await this.telegramTransport.sendDocumentToChat(binding.telegramChatId, filePath, input.caption);
486
- telegramMessageId = sent.messageId;
487
634
  }
488
635
  return {
489
636
  session_id: sessionId,
@@ -498,14 +645,22 @@ class BrowserService {
498
645
  };
499
646
  }
500
647
  async close(input) {
501
- this.ensureEnabled();
502
648
  const resolved = this.projectIdentityResolver.resolveSessionDefaults(input);
503
- const state = this.sessionStates.get(resolved.sessionId);
649
+ const normalizedSessionId = await this.normalizeSessionIdForAccess(resolved.sessionId);
650
+ const remote = await this.invokeRemote(normalizedSessionId, "telegramMcp.browser.closeRemote", {
651
+ ...input,
652
+ session_id: normalizedSessionId,
653
+ });
654
+ if (remote) {
655
+ return remote;
656
+ }
657
+ this.ensureEnabled();
658
+ const state = this.sessionStates.get(normalizedSessionId);
504
659
  if (state) {
505
- await this.closeState(resolved.sessionId, state);
660
+ await this.closeState(normalizedSessionId, state);
506
661
  }
507
662
  return {
508
- session_id: resolved.sessionId,
663
+ session_id: normalizedSessionId,
509
664
  closed: Boolean(state),
510
665
  };
511
666
  }
@@ -623,19 +778,94 @@ class BrowserService {
623
778
  }
624
779
  async requireSessionState(input) {
625
780
  const resolved = this.projectIdentityResolver.resolveSessionDefaults(input);
626
- const state = this.sessionStates.get(resolved.sessionId);
781
+ const sessionId = await this.normalizeSessionIdForAccess(resolved.sessionId);
782
+ const state = this.sessionStates.get(sessionId);
627
783
  if (!state) {
628
784
  throw new Error("Browser session is not open. Call browser_open first for this session.");
629
785
  }
630
- const session = await this.sessionStore.getSession(resolved.sessionId);
786
+ const session = await this.sessionStore.getSession(sessionId);
631
787
  return {
632
- sessionId: resolved.sessionId,
788
+ sessionId,
633
789
  session,
634
790
  state,
635
791
  };
636
792
  }
637
793
  resolveWorkspaceDir(session) {
638
- return session?.cwd?.trim() || process.cwd();
794
+ const workspaceDir = session?.cwd?.trim();
795
+ if (!workspaceDir) {
796
+ throw new Error("Workspace cwd is not registered for this browser console.");
797
+ }
798
+ return workspaceDir;
799
+ }
800
+ async invokeRemote(sessionId, actionName, input) {
801
+ if (this.config.distributed.mode === "client") {
802
+ return undefined;
803
+ }
804
+ return await this.remoteConsoleInvoker?.invokeForRelaySession(sessionId, actionName, input);
805
+ }
806
+ async normalizeSessionIdForAccess(sessionId) {
807
+ const trimmed = sessionId.trim();
808
+ if (!trimmed) {
809
+ return trimmed;
810
+ }
811
+ const direct = await this.sessionStore.getSession(trimmed);
812
+ if (direct) {
813
+ return trimmed;
814
+ }
815
+ const separatorIndex = trimmed.indexOf(":");
816
+ if (separatorIndex <= 0) {
817
+ return trimmed;
818
+ }
819
+ const localClientUuid = await this.maintenanceStore.getGatewayClientUuid();
820
+ const clientUuid = trimmed.slice(0, separatorIndex).trim();
821
+ const localSessionId = trimmed.slice(separatorIndex + 1).trim();
822
+ if (!localClientUuid || clientUuid !== localClientUuid || !localSessionId) {
823
+ return trimmed;
824
+ }
825
+ const localSession = await this.sessionStore.getSession(localSessionId);
826
+ return localSession ? localSessionId : trimmed;
827
+ }
828
+ async sendScreenshotToGatewayTelegramRoute(input) {
829
+ if (!this.config.distributed.gatewayPublicUrl) {
830
+ throw new Error("send_to_telegram on client nodes requires GATEWAY_PUBLIC_URL.");
831
+ }
832
+ const clientUuid = await (0, gatewayClientAccess_1.ensureGatewayClientUuid)({
833
+ maintenanceStore: this.maintenanceStore,
834
+ gatewayPublicUrl: this.config.distributed.gatewayPublicUrl,
835
+ ...(this.config.distributed.gatewayAuthToken
836
+ ? { gatewayAuthToken: this.config.distributed.gatewayAuthToken }
837
+ : {}),
838
+ ...(this.config.distributed.gatewayToken
839
+ ? { gatewayToken: this.config.distributed.gatewayToken }
840
+ : {}),
841
+ ...(this.config.project.name
842
+ ? { projectName: this.config.project.name }
843
+ : {}),
844
+ ...(this.config.telegram.botUsername
845
+ ? { botUsername: this.config.telegram.botUsername }
846
+ : {}),
847
+ ...(this.config.distributed.gatewayUserUuid
848
+ ? { gatewayUserUuid: this.config.distributed.gatewayUserUuid }
849
+ : {}),
850
+ });
851
+ const output = await (0, gatewayClientAccess_1.callGatewayJson)({
852
+ gatewayPublicUrl: this.config.distributed.gatewayPublicUrl,
853
+ ...(this.config.distributed.gatewayAuthToken
854
+ ? { gatewayAuthToken: this.config.distributed.gatewayAuthToken }
855
+ : {}),
856
+ endpointPath: "/transport/document",
857
+ body: {
858
+ client_uuid: clientUuid,
859
+ local_session_id: input.sessionId,
860
+ file_name: input.fileName,
861
+ content_base64: input.pngBuffer.toString("base64"),
862
+ ...(input.caption?.trim() ? { caption: input.caption.trim() } : {}),
863
+ },
864
+ });
865
+ if (!output.sent) {
866
+ throw new Error("Gateway did not confirm Telegram document delivery for the screenshot.");
867
+ }
868
+ return typeof output.message_id === "number" ? output.message_id : undefined;
639
869
  }
640
870
  ensureEnabled() {
641
871
  if (!this.config.browser.enabled) {
@@ -0,0 +1,71 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GatewaySessionsService = void 0;
4
+ const gatewayClientAccess_1 = require("../../distributed-client/model/gatewayClientAccess");
5
+ class GatewaySessionsService {
6
+ logger;
7
+ maintenanceStore;
8
+ gatewayPublicUrl;
9
+ gatewayAuthToken;
10
+ gatewayToken;
11
+ gatewayUserUuid;
12
+ projectName;
13
+ botUsername;
14
+ constructor(logger, maintenanceStore, gatewayPublicUrl, gatewayAuthToken, gatewayToken, gatewayUserUuid, projectName, botUsername) {
15
+ this.logger = logger;
16
+ this.maintenanceStore = maintenanceStore;
17
+ this.gatewayPublicUrl = gatewayPublicUrl;
18
+ this.gatewayAuthToken = gatewayAuthToken;
19
+ this.gatewayToken = gatewayToken;
20
+ this.gatewayUserUuid = gatewayUserUuid;
21
+ this.projectName = projectName;
22
+ this.botUsername = botUsername;
23
+ }
24
+ async listKnownSessions(input = {}) {
25
+ if (!this.gatewayPublicUrl) {
26
+ throw new Error("Gateway session listing requires GATEWAY_PUBLIC_URL.");
27
+ }
28
+ await (0, gatewayClientAccess_1.ensureGatewayClientUuid)({
29
+ maintenanceStore: this.maintenanceStore,
30
+ gatewayPublicUrl: this.gatewayPublicUrl,
31
+ ...(this.gatewayAuthToken
32
+ ? { gatewayAuthToken: this.gatewayAuthToken }
33
+ : {}),
34
+ ...(this.gatewayToken ? { gatewayToken: this.gatewayToken } : {}),
35
+ ...(this.gatewayUserUuid ? { gatewayUserUuid: this.gatewayUserUuid } : {}),
36
+ ...(this.projectName ? { projectName: this.projectName } : {}),
37
+ ...(this.botUsername ? { botUsername: this.botUsername } : {}),
38
+ });
39
+ const response = await (0, gatewayClientAccess_1.callGatewayJson)({
40
+ gatewayPublicUrl: this.gatewayPublicUrl,
41
+ ...(this.gatewayAuthToken
42
+ ? { gatewayAuthToken: this.gatewayAuthToken }
43
+ : {}),
44
+ endpointPath: "/sessions/known",
45
+ body: {
46
+ ...(input.client_uuid?.trim()
47
+ ? { client_uuid: input.client_uuid.trim() }
48
+ : {}),
49
+ ...(this.gatewayToken ? { gateway_token: this.gatewayToken } : {}),
50
+ ...(this.gatewayUserUuid
51
+ ? { owner_user_uuid: this.gatewayUserUuid }
52
+ : {}),
53
+ ...(typeof input.connected_only === "boolean"
54
+ ? { connected_only: input.connected_only }
55
+ : {}),
56
+ },
57
+ });
58
+ const sessions = Array.isArray(response.sessions) ? response.sessions : [];
59
+ this.logger.info("Known gateway sessions listed", {
60
+ total: sessions.length,
61
+ connectedOnly: input.connected_only ?? false,
62
+ });
63
+ return {
64
+ total: typeof response.total === "number" && Number.isFinite(response.total)
65
+ ? response.total
66
+ : sessions.length,
67
+ sessions,
68
+ };
69
+ }
70
+ }
71
+ exports.GatewaySessionsService = GatewaySessionsService;
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ListGatewaySessionsTool = void 0;
4
+ const schema_1 = require("../../../entities/request/model/schema");
5
+ function createContent(output) {
6
+ return [
7
+ {
8
+ type: "text",
9
+ text: JSON.stringify(output, null, 2),
10
+ },
11
+ ];
12
+ }
13
+ class ListGatewaySessionsTool {
14
+ gatewaySessionsService;
15
+ constructor(gatewaySessionsService) {
16
+ this.gatewaySessionsService = gatewaySessionsService;
17
+ }
18
+ register(server) {
19
+ server.registerTool("list_gateway_sessions", {
20
+ title: "List Gateway Sessions",
21
+ description: "List all known consoles from the configured gateway. Use this before direct cross-console communication outside a single collab project, or when you need to discover a console id once. The result includes live connected consoles and project-registered consoles known to the gateway. The canonical gateway-facing session_id is the composite value client_uuid:local_session_id from this list. Reuse that exact session_id in later gateway-routed tools instead of reconstructing it, stripping it, or re-listing sessions when the current console id is already known. target_client_uuid and target_local_session_id are also returned for direct routing APIs that need them.",
22
+ inputSchema: schema_1.listGatewaySessionsInputSchema,
23
+ outputSchema: schema_1.listGatewaySessionsOutputSchema,
24
+ }, async (args) => {
25
+ const output = await this.gatewaySessionsService.listKnownSessions(args);
26
+ return {
27
+ content: createContent(output),
28
+ structuredContent: output,
29
+ };
30
+ });
31
+ }
32
+ }
33
+ exports.ListGatewaySessionsTool = ListGatewaySessionsTool;