@deadragdoll/tellymcp 0.0.13 → 0.0.15

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 (86) hide show
  1. package/.env.example.client +23 -39
  2. package/.env.example.gateway +52 -61
  3. package/CHANGELOG.md +57 -0
  4. package/README-ru.md +80 -6
  5. package/README.md +80 -6
  6. package/TOOLS.md +219 -10
  7. package/config/templates/env.both.template +19 -7
  8. package/config/templates/env.client.template +9 -19
  9. package/config/templates/env.gateway.template +19 -31
  10. package/dist/cli.js +252 -47
  11. package/dist/configureServer.js +966 -0
  12. package/dist/envMigration.js +316 -0
  13. package/dist/moleculer.config.js +1 -3
  14. package/dist/services/features/telegram-mcp/approval.service.js +1 -1
  15. package/dist/services/features/telegram-mcp/browser.service.js +18 -0
  16. package/dist/services/features/telegram-mcp/collaboration.service.js +2 -2
  17. package/dist/services/features/telegram-mcp/ensuredb.service.js +1 -1
  18. package/dist/services/features/telegram-mcp/file-content.service.js +94 -0
  19. package/dist/services/features/telegram-mcp/gateway-delivery.service.js +5 -1
  20. package/dist/services/features/telegram-mcp/gateway-socket.service.js +43 -11
  21. package/dist/services/features/telegram-mcp/gateway.service.js +1 -1
  22. package/dist/services/features/telegram-mcp/mcp-http.service.js +1 -0
  23. package/dist/services/features/telegram-mcp/mcp-server.service.js +20 -0
  24. package/dist/services/features/telegram-mcp/session-context.service.js +25 -1
  25. package/dist/services/features/telegram-mcp/src/app/bootstrap/runtime.js +79 -67
  26. package/dist/services/features/telegram-mcp/src/app/config/env.js +129 -38
  27. package/dist/services/features/telegram-mcp/src/app/config/environmentContract.js +66 -0
  28. package/dist/services/features/telegram-mcp/src/app/http.js +139 -99
  29. package/dist/services/features/telegram-mcp/src/app/oauthFacade.js +642 -0
  30. package/dist/services/features/telegram-mcp/src/app/webapp/assets.js +151 -170
  31. package/dist/services/features/telegram-mcp/src/app/webapp/auth.js +96 -99
  32. package/dist/services/features/telegram-mcp/src/entities/request/model/schema.js +88 -19
  33. package/dist/services/features/telegram-mcp/src/features/browser/model/browserAttachActiveTabTool.js +28 -0
  34. package/dist/services/features/telegram-mcp/src/features/browser/model/browserAttachTabTool.js +28 -0
  35. package/dist/services/features/telegram-mcp/src/features/browser/model/browserDetachTabTool.js +28 -0
  36. package/dist/services/features/telegram-mcp/src/features/browser/model/browserListAttachedInstancesTool.js +1 -1
  37. package/dist/services/features/telegram-mcp/src/features/browser/model/browserListTabsTool.js +1 -1
  38. package/dist/services/features/telegram-mcp/src/features/browser/model/browserService.js +412 -29
  39. package/dist/services/features/telegram-mcp/src/features/browser-attach/model/browserRecordingBundle.js +37 -3
  40. package/dist/services/features/telegram-mcp/src/features/browser-attach/model/firefoxAttachRegistry.js +7 -6
  41. package/dist/services/features/telegram-mcp/src/features/browser-attach/model/firefoxAttachServer.js +214 -37
  42. package/dist/services/features/telegram-mcp/src/features/browser-attach/model/types.js +186 -0
  43. package/dist/services/features/telegram-mcp/src/features/collaboration/model/collaborationService.js +2 -0
  44. package/dist/services/features/telegram-mcp/src/features/collaboration/model/gatewaySessionsService.js +5 -5
  45. package/dist/services/features/telegram-mcp/src/features/collaboration/model/sendPartnerFileService.js +6 -3
  46. package/dist/services/features/telegram-mcp/src/features/distributed-client/model/gatewayClientAccess.js +5 -2
  47. package/dist/services/features/telegram-mcp/src/features/distributed-client/model/gatewayCollaborationBackend.js +4 -4
  48. package/dist/services/features/telegram-mcp/src/features/distributed-gateway/model/gatewayHttpService.js +33 -36
  49. package/dist/services/features/telegram-mcp/src/features/distributed-gateway/model/remoteConsoleActionClient.js +4 -3
  50. package/dist/services/features/telegram-mcp/src/features/file-content/model/getFileListTool.js +33 -0
  51. package/dist/services/features/telegram-mcp/src/features/file-content/model/getFileService.js +327 -0
  52. package/dist/services/features/telegram-mcp/src/features/file-content/model/getFileTool.js +81 -0
  53. package/dist/services/features/telegram-mcp/src/features/file-content/model/temporaryFileLinkStore.js +307 -0
  54. package/dist/services/features/telegram-mcp/src/features/file-content/model/workspaceFilePolicy.js +115 -0
  55. package/dist/services/features/telegram-mcp/src/features/notify/model/notifyService.js +9 -5
  56. package/dist/services/features/telegram-mcp/src/features/session-context/model/getRuntimeDiagnosticsTool.js +30 -0
  57. package/dist/services/features/telegram-mcp/src/features/session-context/model/sessionContextService.js +169 -7
  58. package/dist/services/features/telegram-mcp/src/shared/integrations/memory/processLocalStateStore.js +260 -0
  59. package/dist/services/features/telegram-mcp/src/shared/integrations/object-storage/minioExchangeStore.js +1 -1
  60. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transport.js +4 -1
  61. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportConsoleRegistry.js +2 -2
  62. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportFileHandoffActions.js +6 -3
  63. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportMessageFlow.js +1 -1
  64. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportProjectState.js +2 -2
  65. package/dist/services/features/telegram-mcp/src/shared/integrations/terminal/client.js +29 -6
  66. package/dist/services/features/telegram-mcp/src/shared/integrations/terminal/ptyRegistry.js +100 -2
  67. package/dist/services/features/telegram-mcp/src/shared/lib/bodyLimits.js +63 -0
  68. package/dist/services/features/telegram-mcp/src/shared/lib/gatewayAuth.js +13 -0
  69. package/dist/services/features/telegram-mcp/src/shared/lib/gatewayScope.js +5 -5
  70. package/dist/services/features/telegram-mcp/src/shared/lib/project-identity/projectIdentity.js +10 -0
  71. package/dist/services/features/telegram-mcp/src/shared/lib/time/localTimestamp.js +21 -0
  72. package/docs/CHAT_CONNECTOR.md +134 -0
  73. package/docs/STANDALONE-ru.md +41 -3
  74. package/docs/STANDALONE.md +41 -3
  75. package/package.json +5 -3
  76. package/packages/chrome-attach-extension/dist/background.js +572 -163
  77. package/packages/chrome-attach-extension/dist/manifest.json +2 -1
  78. package/packages/chrome-attach-extension/dist/options.js +15 -2
  79. package/packages/chrome-attach-extension/dist/recorder-content.js +14 -1
  80. package/packages/chrome-attach-extension/dist/recorder-page.js +34 -18
  81. package/packages/firefox-attach-extension/dist/background.js +413 -33
  82. package/packages/firefox-attach-extension/dist/manifest.json +0 -12
  83. package/packages/firefox-attach-extension/dist/options.js +14 -1
  84. package/packages/firefox-attach-extension/dist/recorder-content.js +14 -1
  85. package/packages/firefox-attach-extension/dist/recorder-page.js +34 -18
  86. package/scripts/postinstall.js +33 -1
@@ -5,16 +5,20 @@ const server_1 = require("./src/app/providers/mcp/server");
5
5
  const approval_service_1 = require("./approval.service");
6
6
  const browser_service_1 = require("./browser.service");
7
7
  const collaboration_service_1 = require("./collaboration.service");
8
+ const file_content_service_1 = require("./file-content.service");
8
9
  const notify_service_1 = require("./notify.service");
9
10
  const session_context_service_1 = require("./session-context.service");
10
11
  const tools_sync_service_1 = require("./tools-sync.service");
11
12
  const xchange_service_1 = require("./xchange.service");
12
13
  const askUserTelegram_1 = require("./src/features/ask-user/model/askUserTelegram");
14
+ const browserAttachActiveTabTool_1 = require("./src/features/browser/model/browserAttachActiveTabTool");
15
+ const browserAttachTabTool_1 = require("./src/features/browser/model/browserAttachTabTool");
13
16
  const browserClickTool_1 = require("./src/features/browser/model/browserClickTool");
14
17
  const browserClearLogsTool_1 = require("./src/features/browser/model/browserClearLogsTool");
15
18
  const browserCloseTool_1 = require("./src/features/browser/model/browserCloseTool");
16
19
  const browserComputedStyleTool_1 = require("./src/features/browser/model/browserComputedStyleTool");
17
20
  const browserConsoleTool_1 = require("./src/features/browser/model/browserConsoleTool");
21
+ const browserDetachTabTool_1 = require("./src/features/browser/model/browserDetachTabTool");
18
22
  const browserDomTool_1 = require("./src/features/browser/model/browserDomTool");
19
23
  const browserErrorsTool_1 = require("./src/features/browser/model/browserErrorsTool");
20
24
  const browserFillTool_1 = require("./src/features/browser/model/browserFillTool");
@@ -34,9 +38,12 @@ const browserWaitForUrlTool_1 = require("./src/features/browser/model/browserWai
34
38
  const sendPartnerFileTool_1 = require("./src/features/collaboration/model/sendPartnerFileTool");
35
39
  const listGatewaySessionsTool_1 = require("./src/features/collaboration/model/listGatewaySessionsTool");
36
40
  const sendPartnerNoteTool_1 = require("./src/features/collaboration/model/sendPartnerNoteTool");
41
+ const getFileTool_1 = require("./src/features/file-content/model/getFileTool");
42
+ const getFileListTool_1 = require("./src/features/file-content/model/getFileListTool");
37
43
  const sendFileToTelegramTool_1 = require("./src/features/notify/model/sendFileToTelegramTool");
38
44
  const notifyTelegramTool_1 = require("./src/features/notify/model/notifyTelegramTool");
39
45
  const clearSessionContextTool_1 = require("./src/features/session-context/model/clearSessionContextTool");
46
+ const getRuntimeDiagnosticsTool_1 = require("./src/features/session-context/model/getRuntimeDiagnosticsTool");
40
47
  const getSessionContextTool_1 = require("./src/features/session-context/model/getSessionContextTool");
41
48
  const renameSessionTool_1 = require("./src/features/session-context/model/renameSessionTool");
42
49
  const setSessionContextTool_1 = require("./src/features/session-context/model/setSessionContextTool");
@@ -53,6 +60,7 @@ const TelegramMcpMcpServerService = {
53
60
  approval_service_1.TELEGRAM_MCP_APPROVAL_SERVICE_NAME,
54
61
  browser_service_1.TELEGRAM_MCP_BROWSER_SERVICE_NAME,
55
62
  collaboration_service_1.TELEGRAM_MCP_COLLABORATION_SERVICE_NAME,
63
+ file_content_service_1.TELEGRAM_MCP_FILE_CONTENT_SERVICE_NAME,
56
64
  tools_sync_service_1.TELEGRAM_MCP_TOOLS_SYNC_SERVICE_NAME,
57
65
  xchange_service_1.TELEGRAM_MCP_XCHANGE_SERVICE_NAME,
58
66
  ],
@@ -63,6 +71,7 @@ const TelegramMcpMcpServerService = {
63
71
  const approvalService = this.broker.getLocalService(approval_service_1.TELEGRAM_MCP_APPROVAL_SERVICE_NAME);
64
72
  const browserService = this.broker.getLocalService(browser_service_1.TELEGRAM_MCP_BROWSER_SERVICE_NAME);
65
73
  const collaborationService = this.broker.getLocalService(collaboration_service_1.TELEGRAM_MCP_COLLABORATION_SERVICE_NAME);
74
+ const fileContentService = this.broker.getLocalService(file_content_service_1.TELEGRAM_MCP_FILE_CONTENT_SERVICE_NAME);
66
75
  const toolsSyncService = this.broker.getLocalService(tools_sync_service_1.TELEGRAM_MCP_TOOLS_SYNC_SERVICE_NAME);
67
76
  const xchangeService = this.broker.getLocalService(xchange_service_1.TELEGRAM_MCP_XCHANGE_SERVICE_NAME);
68
77
  if (!sessionContextService ||
@@ -70,6 +79,7 @@ const TelegramMcpMcpServerService = {
70
79
  !approvalService ||
71
80
  !browserService ||
72
81
  !collaborationService ||
82
+ !fileContentService ||
73
83
  !toolsSyncService ||
74
84
  !xchangeService) {
75
85
  throw new Error("telegram_mcp MCP server dependencies are not ready");
@@ -78,12 +88,16 @@ const TelegramMcpMcpServerService = {
78
88
  new setSessionContextTool_1.SetSessionContextTool(sessionContextService.getSessionContextService()),
79
89
  new renameSessionTool_1.RenameSessionTool(sessionContextService.getSessionContextService()),
80
90
  new getSessionContextTool_1.GetSessionContextTool(sessionContextService.getSessionContextService()),
91
+ new getRuntimeDiagnosticsTool_1.GetRuntimeDiagnosticsTool(sessionContextService.getSessionContextService()),
81
92
  new clearSessionContextTool_1.ClearSessionContextTool(sessionContextService.getSessionContextService()),
82
93
  new notifyTelegramTool_1.NotifyTelegramTool(notifyService.getNotifyService()),
83
94
  new sendFileToTelegramTool_1.SendFileToTelegramTool(notifyService.getNotifyService()),
84
95
  new askUserTelegram_1.AskUserTelegramTool(approvalService.getApprovalOrchestrator()),
85
96
  new browserListAttachedInstancesTool_1.BrowserListAttachedInstancesTool(browserService.getBrowserService()),
86
97
  new browserListTabsTool_1.BrowserListTabsTool(browserService.getBrowserService()),
98
+ new browserAttachActiveTabTool_1.BrowserAttachActiveTabTool(browserService.getBrowserService()),
99
+ new browserAttachTabTool_1.BrowserAttachTabTool(browserService.getBrowserService()),
100
+ new browserDetachTabTool_1.BrowserDetachTabTool(browserService.getBrowserService()),
87
101
  new browserRecordingStartTool_1.BrowserRecordingStartTool(browserService.getBrowserService()),
88
102
  new browserRecordingStopTool_1.BrowserRecordingStopTool(browserService.getBrowserService()),
89
103
  new browserRecordingStatusTool_1.BrowserRecordingStatusTool(browserService.getBrowserService()),
@@ -106,11 +120,16 @@ const TelegramMcpMcpServerService = {
106
120
  new sendPartnerNoteTool_1.SendPartnerNoteTool(collaborationService.getCollaborationService()),
107
121
  new listGatewaySessionsTool_1.ListGatewaySessionsTool(collaborationService.getGatewaySessionsService()),
108
122
  new sendPartnerFileTool_1.SendPartnerFileTool(collaborationService.getSendPartnerFileService()),
123
+ new getFileTool_1.GetFileTool(fileContentService.getGetFileService()),
124
+ new getFileListTool_1.GetFileListTool(fileContentService.getGetFileService()),
109
125
  new listXchangeRecordsTool_1.ListXchangeRecordsTool(xchangeService.getXchangeService()),
110
126
  new getXchangeRecordTool_1.GetXchangeRecordTool(xchangeService.getXchangeService()),
111
127
  new markXchangeRecordReadTool_1.MarkXchangeRecordReadTool(xchangeService.getXchangeService()),
112
128
  new refreshToolsMarkdownTool_1.RefreshToolsMarkdownTool(toolsSyncService.getRefreshToolsMarkdownService()),
113
129
  ];
130
+ this.logger.info("telegram_mcp MCP server instance created", {
131
+ toolCount: tools.length,
132
+ });
114
133
  return (0, server_1.createMcpServer)(tools);
115
134
  },
116
135
  },
@@ -121,6 +140,7 @@ const TelegramMcpMcpServerService = {
121
140
  approval_service_1.TELEGRAM_MCP_APPROVAL_SERVICE_NAME,
122
141
  browser_service_1.TELEGRAM_MCP_BROWSER_SERVICE_NAME,
123
142
  collaboration_service_1.TELEGRAM_MCP_COLLABORATION_SERVICE_NAME,
143
+ file_content_service_1.TELEGRAM_MCP_FILE_CONTENT_SERVICE_NAME,
124
144
  tools_sync_service_1.TELEGRAM_MCP_TOOLS_SYNC_SERVICE_NAME,
125
145
  xchange_service_1.TELEGRAM_MCP_XCHANGE_SERVICE_NAME,
126
146
  ]);
@@ -4,6 +4,7 @@ exports.TELEGRAM_MCP_SESSION_CONTEXT_SERVICE_NAME = void 0;
4
4
  const runtime_service_1 = require("./runtime.service");
5
5
  const remoteConsoleActionClient_1 = require("./src/features/distributed-gateway/model/remoteConsoleActionClient");
6
6
  const sessionContextService_1 = require("./src/features/session-context/model/sessionContextService");
7
+ const versionHandshake_1 = require("./src/shared/lib/version/versionHandshake");
7
8
  exports.TELEGRAM_MCP_SESSION_CONTEXT_SERVICE_NAME = "telegramMcp.sessionContext";
8
9
  const TelegramMcpSessionContextService = {
9
10
  name: exports.TELEGRAM_MCP_SESSION_CONTEXT_SERVICE_NAME,
@@ -15,6 +16,12 @@ const TelegramMcpSessionContextService = {
15
16
  return this.getSessionContextService().getContext(ctx.params);
16
17
  },
17
18
  },
19
+ getRuntimeDiagnosticsRemote: {
20
+ params: { $$strict: false },
21
+ async handler(ctx) {
22
+ return this.getSessionContextService().getRuntimeDiagnostics(ctx.params);
23
+ },
24
+ },
18
25
  setContextRemote: {
19
26
  params: { $$strict: false },
20
27
  async handler(ctx) {
@@ -53,7 +60,24 @@ const TelegramMcpSessionContextService = {
53
60
  }
54
61
  const runtime = await runtimeService.waitUntilReady();
55
62
  this.logger.info("Starting telegram_mcp session-context service");
56
- this.sessionContextService = new sessionContextService_1.SessionContextService(runtime.sessionStore, runtime.stateStore, runtime.logger, runtime.projectIdentityResolver, new remoteConsoleActionClient_1.RemoteConsoleActionClient((actionName, params) => this.broker.call(actionName, params, { meta: { internal_call: true } })));
63
+ this.sessionContextService = new sessionContextService_1.SessionContextService(runtime.sessionStore, runtime.stateStore, runtime.logger, runtime.projectIdentityResolver, runtime.config.distributed.mode === "client"
64
+ ? undefined
65
+ : new remoteConsoleActionClient_1.RemoteConsoleActionClient((actionName, params) => this.broker.call(actionName, params, {
66
+ meta: { internal_call: true },
67
+ })), {
68
+ mode: runtime.config.distributed.mode,
69
+ packageVersion: (0, versionHandshake_1.getTellyMcpPackageVersion)(__dirname),
70
+ protocolVersion: versionHandshake_1.TELLYMCP_PROTOCOL_VERSION,
71
+ ...(process.env.NODE_ID?.trim()
72
+ ? { nodeId: process.env.NODE_ID.trim() }
73
+ : {}),
74
+ gatewayWsUrlConfigured: Boolean(runtime.config.distributed.gatewayWsUrl),
75
+ gatewayAuthConfigured: Boolean(runtime.config.distributed.gatewayAuthToken ||
76
+ runtime.config.distributed.gatewayScopeToken),
77
+ ...(runtime.redis
78
+ ? { pingRedis: async () => await runtime.redis.ping() }
79
+ : {}),
80
+ });
57
81
  this.logger.info("telegram_mcp session-context service is ready");
58
82
  },
59
83
  };
@@ -8,11 +8,13 @@ const logger_1 = require("../../shared/lib/logger/logger");
8
8
  const projectIdentity_1 = require("../../shared/lib/project-identity/projectIdentity");
9
9
  const stateStore_1 = require("../../shared/integrations/redis/stateStore");
10
10
  const processLocalSessionStore_1 = require("../../shared/integrations/memory/processLocalSessionStore");
11
+ const processLocalStateStore_1 = require("../../shared/integrations/memory/processLocalStateStore");
11
12
  const transport_1 = require("../../shared/integrations/telegram/transport");
12
13
  const minioExchangeStore_1 = require("../../shared/integrations/object-storage/minioExchangeStore");
13
14
  const gatewayHttpService_1 = require("../../features/distributed-gateway/model/gatewayHttpService");
14
15
  const gatewayClientAccess_1 = require("../../features/distributed-client/model/gatewayClientAccess");
15
16
  const firefoxAttachServer_1 = require("../../features/browser-attach/model/firefoxAttachServer");
17
+ const temporaryFileLinkStore_1 = require("../../features/file-content/model/temporaryFileLinkStore");
16
18
  const client_2 = require("../../shared/integrations/terminal/client");
17
19
  const ptyRegistry_1 = require("../../shared/integrations/terminal/ptyRegistry");
18
20
  async function createAppRuntime(input) {
@@ -21,11 +23,14 @@ async function createAppRuntime(input) {
21
23
  const projectIdentityResolver = new projectIdentity_1.ProjectIdentityResolver(config, logger);
22
24
  logger.info("Configuration loaded", {
23
25
  mode: config.mode,
24
- redis: {
25
- host: config.redis.host,
26
- port: config.redis.port,
27
- db: config.redis.db,
28
- },
26
+ state: config.distributed.mode === "client"
27
+ ? { backend: "process-local" }
28
+ : {
29
+ backend: "redis",
30
+ host: config.redis.host,
31
+ port: config.redis.port,
32
+ db: config.redis.db,
33
+ },
29
34
  logging: {
30
35
  level: config.logging.level,
31
36
  },
@@ -34,19 +39,16 @@ async function createAppRuntime(input) {
34
39
  httpPort: config.mcp.httpPort,
35
40
  httpPath: config.mcp.httpPath,
36
41
  bearerAuthEnabled: Boolean(config.mcp.bearerToken),
42
+ oauthConnectorEnabled: Boolean(config.oauth),
37
43
  enableDebugRoutes: config.mcp.enableDebugRoutes,
38
44
  enablePruneRoute: config.mcp.enablePruneRoute,
39
45
  },
40
46
  distributed: {
41
47
  mode: config.distributed.mode,
42
48
  gatewayPublicUrlConfigured: Boolean(config.distributed.gatewayPublicUrl),
43
- gatewayBindHost: config.distributed.gatewayBindHost,
44
- gatewayBindPort: config.distributed.gatewayBindPort,
45
49
  gatewayWsUrlConfigured: Boolean(config.distributed.gatewayWsUrl),
46
50
  gatewayWsPath: config.distributed.gatewayWsPath,
47
51
  gatewayAuthEnabled: Boolean(config.distributed.gatewayAuthToken),
48
- gatewayDatabaseConfigured: Boolean(config.distributed.gatewayDatabaseUrl),
49
- gatewayS3Configured: Boolean(config.distributed.gatewayS3Bucket),
50
52
  gatewayRmqConfigured: Boolean(config.distributed.rmq?.host),
51
53
  },
52
54
  webapp: {
@@ -56,7 +58,6 @@ async function createAppRuntime(input) {
56
58
  initDataTtlSeconds: config.webapp.initDataTtlSeconds,
57
59
  sessionTtlSeconds: config.webapp.sessionTtlSeconds,
58
60
  launchMode: config.webapp.launchMode,
59
- pollIntervalMs: config.webapp.pollIntervalMs,
60
61
  actionCooldownMs: config.webapp.actionCooldownMs,
61
62
  },
62
63
  terminal: {
@@ -81,81 +82,85 @@ async function createAppRuntime(input) {
81
82
  },
82
83
  project: projectIdentityResolver.getIdentity(),
83
84
  });
84
- const redis = await (0, client_1.createRedisClient)(config);
85
- logger.info("Redis connected", {
86
- host: config.redis.host,
87
- port: config.redis.port,
88
- db: config.redis.db,
89
- });
90
- const stateStore = new stateStore_1.RedisStateStore(redis);
91
- let sessionStore = stateStore;
85
+ let redis = null;
86
+ let stateStore;
87
+ let sessionStore;
88
+ if (config.distributed.mode === "client") {
89
+ const resolvedSession = projectIdentityResolver.resolveSessionDefaults({ cwd: process.cwd() });
90
+ const marker = (0, projectIdentity_1.readSessionMarkerState)(resolvedSession.cwd, logger);
91
+ stateStore = new processLocalStateStore_1.ProcessLocalStateStore({
92
+ ...(marker?.gatewayClientUuid
93
+ ? { gatewayClientUuid: marker.gatewayClientUuid }
94
+ : {}),
95
+ onGatewayClientUuidChange: (gatewayClientUuid) => {
96
+ (0, projectIdentity_1.writeSessionMarkerState)({
97
+ cwd: resolvedSession.cwd,
98
+ localSessionId: resolvedSession.sessionId,
99
+ sessionLabel: resolvedSession.sessionLabel,
100
+ ...(marker?.envFile ? { envFile: marker.envFile } : {}),
101
+ ...(marker?.lastSeenToolsHash
102
+ ? { lastSeenToolsHash: marker.lastSeenToolsHash }
103
+ : {}),
104
+ ...(marker?.lastNotifiedToolsHash
105
+ ? { lastNotifiedToolsHash: marker.lastNotifiedToolsHash }
106
+ : {}),
107
+ gatewayClientUuid,
108
+ logger,
109
+ });
110
+ },
111
+ });
112
+ sessionStore = new processLocalSessionStore_1.ProcessLocalSessionStore();
113
+ logger.info("Client process-local state store initialized", {
114
+ gatewayClientUuidRestored: Boolean(marker?.gatewayClientUuid),
115
+ });
116
+ }
117
+ else {
118
+ redis = await (0, client_1.createRedisClient)(config);
119
+ logger.info("Redis connected", {
120
+ host: config.redis.host,
121
+ port: config.redis.port,
122
+ db: config.redis.db,
123
+ });
124
+ const redisStateStore = new stateStore_1.RedisStateStore(redis);
125
+ stateStore = redisStateStore;
126
+ sessionStore = redisStateStore;
127
+ }
92
128
  const webAppLaunchRegistry = new auth_1.WebAppLaunchRegistry();
93
- const objectStore = new minioExchangeStore_1.MinioExchangeStore(input.callBroker, stateStore, config.terminal, config.exchange.dir, config.mcp.vfsScope, logger, config.distributed.mode, config.distributed.gatewayPublicUrl, config.distributed.gatewayAuthToken);
129
+ const objectStore = new minioExchangeStore_1.MinioExchangeStore(config.terminal, config.exchange.dir, logger);
94
130
  if (config.distributed.mode === "client") {
95
131
  const resolvedSession = projectIdentityResolver.resolveSessionDefaults({
96
132
  cwd: process.cwd(),
97
133
  });
98
- const existingSession = await stateStore.getSession(resolvedSession.sessionId);
99
134
  const persistedToolsState = (0, projectIdentity_1.readSessionMarkerState)(resolvedSession.cwd, logger);
100
135
  const terminalTarget = (0, client_2.ensureTerminalTargetForSession)(config.terminal, {
101
136
  sessionId: resolvedSession.sessionId,
102
137
  cwd: resolvedSession.cwd,
103
- ...(typeof existingSession?.terminalTarget === "string"
104
- ? { target: existingSession.terminalTarget }
105
- : {}),
106
138
  });
107
139
  if (!terminalTarget) {
108
140
  throw new Error("PTY terminal target could not be created during runtime bootstrap");
109
141
  }
110
142
  const initialSession = {
111
143
  sessionId: resolvedSession.sessionId,
112
- ...(typeof existingSession?.label === "string"
113
- ? { label: existingSession.label }
114
- : { label: resolvedSession.sessionLabel }),
115
- ...(typeof existingSession?.cwd === "string"
116
- ? { cwd: existingSession.cwd }
117
- : { cwd: resolvedSession.cwd }),
118
- ...(typeof existingSession?.activeProjectUuid === "string"
119
- ? { activeProjectUuid: existingSession.activeProjectUuid }
120
- : {}),
121
- ...(typeof existingSession?.activeProjectName === "string"
122
- ? { activeProjectName: existingSession.activeProjectName }
123
- : {}),
124
- ...(typeof existingSession?.task === "string"
125
- ? { task: existingSession.task }
126
- : {}),
127
- ...(typeof existingSession?.summary === "string"
128
- ? { summary: existingSession.summary }
129
- : {}),
130
- ...(Array.isArray(existingSession?.files)
131
- ? { files: existingSession.files }
132
- : {}),
133
- ...(Array.isArray(existingSession?.decisions)
134
- ? { decisions: existingSession.decisions }
135
- : {}),
136
- ...(Array.isArray(existingSession?.risks)
137
- ? { risks: existingSession.risks }
138
- : {}),
144
+ label: resolvedSession.sessionLabel,
145
+ cwd: resolvedSession.cwd,
139
146
  terminalTarget: terminalTarget,
140
- ...(typeof existingSession?.lastTerminalNudgeAt === "string"
141
- ? { lastTerminalNudgeAt: existingSession.lastTerminalNudgeAt }
147
+ ...(typeof persistedToolsState?.lastSeenToolsHash === "string"
148
+ ? { lastSeenToolsHash: persistedToolsState.lastSeenToolsHash }
149
+ : {}),
150
+ ...(typeof persistedToolsState?.lastNotifiedToolsHash === "string"
151
+ ? { lastNotifiedToolsHash: persistedToolsState.lastNotifiedToolsHash }
142
152
  : {}),
143
- ...(typeof existingSession?.lastSeenToolsHash === "string"
144
- ? { lastSeenToolsHash: existingSession.lastSeenToolsHash }
145
- : typeof persistedToolsState?.lastSeenToolsHash === "string"
146
- ? { lastSeenToolsHash: persistedToolsState.lastSeenToolsHash }
147
- : {}),
148
- ...(typeof existingSession?.lastNotifiedToolsHash === "string"
149
- ? { lastNotifiedToolsHash: existingSession.lastNotifiedToolsHash }
150
- : typeof persistedToolsState?.lastNotifiedToolsHash === "string"
151
- ? { lastNotifiedToolsHash: persistedToolsState.lastNotifiedToolsHash }
152
- : {}),
153
153
  updatedAt: new Date().toISOString(),
154
154
  };
155
155
  sessionStore = new processLocalSessionStore_1.ProcessLocalSessionStore({
156
156
  initialSessions: [initialSession],
157
157
  onClearSession: async (sessionId) => {
158
- await stateStore.clearSession(sessionId);
158
+ await stateStore.clearBinding(sessionId);
159
+ await stateStore.clearBrowserAttachment(sessionId);
160
+ await stateStore.clearBrowserRecording(sessionId);
161
+ for (const meta of await stateStore.listXchangeFileMetas(sessionId)) {
162
+ await stateStore.deleteXchangeFileMeta(sessionId, meta.filePath);
163
+ }
159
164
  },
160
165
  });
161
166
  logger.info("Client PTY process-local session store initialized", {
@@ -174,8 +179,8 @@ async function createAppRuntime(input) {
174
179
  : {}),
175
180
  ...(config.project.name ? { projectName: config.project.name } : {}),
176
181
  ...(config.telegram.botUsername ? { botUsername: config.telegram.botUsername } : {}),
177
- ...(config.distributed.gatewayToken
178
- ? { gatewayToken: config.distributed.gatewayToken }
182
+ ...(config.distributed.gatewayScopeToken
183
+ ? { gatewayScopeToken: config.distributed.gatewayScopeToken }
179
184
  : {}),
180
185
  ...(config.distributed.gatewayUserUuid
181
186
  ? { gatewayUserUuid: config.distributed.gatewayUserUuid }
@@ -210,7 +215,12 @@ async function createAppRuntime(input) {
210
215
  await telegramTransport.sendStartupNotifications();
211
216
  logger.info("Startup Telegram notifications completed");
212
217
  const gatewayHttpService = new gatewayHttpService_1.GatewayHttpService(config, input.callBroker);
213
- const firefoxAttachServer = new firefoxAttachServer_1.FirefoxAttachServer(config, logger, stateStore, stateStore);
218
+ const temporaryFileLinkStore = config.distributed.mode !== "client" &&
219
+ config.distributed.gatewayPublicUrl?.trim()
220
+ ? new temporaryFileLinkStore_1.TemporaryFileLinkStore(config.distributed.gatewayPublicUrl, logger)
221
+ : null;
222
+ await temporaryFileLinkStore?.start();
223
+ const firefoxAttachServer = new firefoxAttachServer_1.FirefoxAttachServer(config, logger, sessionStore, stateStore);
214
224
  await firefoxAttachServer.start();
215
225
  return {
216
226
  callBroker: input.callBroker,
@@ -230,12 +240,14 @@ async function createAppRuntime(input) {
230
240
  webAppLaunchRegistry,
231
241
  gatewayHttpService,
232
242
  firefoxAttachServer,
243
+ temporaryFileLinkStore,
233
244
  shutdown: async () => {
234
245
  logger.info("Shutdown started");
246
+ await temporaryFileLinkStore?.stop();
235
247
  await firefoxAttachServer.stop();
236
248
  await telegramTransport.stop();
237
249
  (0, ptyRegistry_1.stopAllPtyTargets)();
238
- redis.disconnect();
250
+ redis?.disconnect();
239
251
  logger.info("Shutdown completed");
240
252
  },
241
253
  };
@@ -36,6 +36,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.loadConfig = loadConfig;
37
37
  const node_fs_1 = require("node:fs");
38
38
  const z = __importStar(require("zod/v4"));
39
+ const environmentContract_1 = require("./environmentContract");
39
40
  const emptyStringToUndefined = (value) => {
40
41
  if (typeof value !== "string") {
41
42
  return value;
@@ -79,13 +80,12 @@ const envSchema = z.object({
79
80
  .optional()
80
81
  .transform((value) => value === "true"),
81
82
  DEBUG_LANGUAGE: z.preprocess(emptyStringToUndefined, z.enum(["en", "ru"]).optional()),
82
- REDIS_HOST: z.string().min(1),
83
- REDIS_PORT: z.coerce.number().int().positive(),
84
- REDIS_DB: z.coerce.number().int().nonnegative(),
83
+ REDIS_HOST: z.string().min(1).default("127.0.0.1"),
84
+ REDIS_PORT: z.coerce.number().int().positive().default(6379),
85
+ REDIS_DB: z.coerce.number().int().nonnegative().default(1),
85
86
  REDIS_USERNAME: optionalNonEmptyString,
86
87
  REDIS_PASSWORD: optionalNonEmptyString,
87
- MODE: z.enum(["queue", "reject"]).default("queue"),
88
- PAIR_CODE_TTL_SECONDS: z.coerce.number().int().positive().default(600),
88
+ TELEGRAM_REQUEST_MODE: z.enum(["queue", "reject"]).default("queue"),
89
89
  PROJECT_NAME: optionalNonEmptyString,
90
90
  TELLYMCP_SESSION_ID: optionalNonEmptyString,
91
91
  TELLYMCP_SESSION_LABEL: optionalNonEmptyString,
@@ -93,6 +93,22 @@ const envSchema = z.object({
93
93
  MCP_HTTP_PORT: z.coerce.number().int().positive().default(8787),
94
94
  MCP_HTTP_PATH: z.string().min(1).default("/mcp"),
95
95
  MCP_HTTP_BEARER_TOKEN: optionalNonEmptyString,
96
+ TELLYMCP_PUBLIC_URL: optionalUrlString,
97
+ TELLYMCP_OAUTH_ISSUER: optionalUrlString,
98
+ TELLYMCP_OAUTH_AUDIENCE: optionalUrlString,
99
+ TELLYMCP_MAGIC_TOKEN: optionalNonEmptyString,
100
+ TELLYMCP_MAGIC_TOKEN_HASH: optionalNonEmptyString,
101
+ TELLYMCP_OAUTH_CLIENT_ID: optionalNonEmptyString,
102
+ TELLYMCP_OAUTH_CLIENT_SECRET: optionalNonEmptyString,
103
+ TELLYMCP_ALLOWED_REDIRECT_URIS: optionalNonEmptyString,
104
+ TELLYMCP_OAUTH_PRIVATE_KEY_PEM: optionalNonEmptyString,
105
+ TELLYMCP_AUTH_CODE_TTL_SECONDS: z.coerce
106
+ .number()
107
+ .int()
108
+ .positive()
109
+ .default(300),
110
+ TELLYMCP_OAUTH_SCOPES: z.string().min(1).default("tellymcp:read tellymcp:write"),
111
+ TELLYMCP_OAUTH_KEY_ID: z.string().min(1).default("tellymcp-oauth"),
96
112
  MCP_HTTP_ENABLE_DEBUG_ROUTES: z
97
113
  .string()
98
114
  .optional()
@@ -101,24 +117,16 @@ const envSchema = z.object({
101
117
  .string()
102
118
  .optional()
103
119
  .transform((value) => value === "true"),
104
- MCP_VFS_SCOPE: z.string().min(1).default("mcp"),
105
120
  DISTRIBUTED_MODE: z.enum(["client", "gateway", "both"]).default("client"),
106
121
  GATEWAY_PUBLIC_URL: optionalUrlString,
107
- GATEWAY_BIND_HOST: z.string().min(1).default("127.0.0.1"),
108
- GATEWAY_BIND_PORT: z.coerce.number().int().positive().default(8790),
109
122
  GATEWAY_WS_URL: optionalUrlString,
110
123
  GATEWAY_WS_PATH: z
111
124
  .string()
112
125
  .min(1)
113
126
  .default(`${(process.env.ROOT_PREFIX || "/api").replace(/\/+$/u, "")}/gateway/ws`),
114
- GATEWAY_TOKEN: optionalNonEmptyString,
127
+ GATEWAY_SCOPE_TOKEN: optionalNonEmptyString,
115
128
  GATEWAY_USER_UUID: optionalNonEmptyString,
116
129
  GATEWAY_AUTH_TOKEN: optionalNonEmptyString,
117
- GATEWAY_DATABASE_URL: optionalNonEmptyString,
118
- GATEWAY_S3_ENDPOINT: optionalNonEmptyString,
119
- GATEWAY_S3_BUCKET: optionalNonEmptyString,
120
- GATEWAY_S3_ACCESS_KEY: optionalNonEmptyString,
121
- GATEWAY_S3_SECRET_KEY: optionalNonEmptyString,
122
130
  RMQ_HOST: optionalNonEmptyString,
123
131
  RMQ_PORT: z.coerce.number().int().positive().optional(),
124
132
  RMQ_USER: optionalNonEmptyString,
@@ -145,7 +153,6 @@ const envSchema = z.object({
145
153
  .enum(["default", "expand", "fullscreen"])
146
154
  .default("fullscreen"),
147
155
  WEBAPP_VISIBLE_SCREENS: z.coerce.number().int().positive().default(2),
148
- WEBAPP_POLL_INTERVAL_MS: z.coerce.number().int().positive().default(2000),
149
156
  WEBAPP_ACTION_COOLDOWN_MS: z.coerce.number().int().nonnegative().default(150),
150
157
  MCP_XCHANGE_DIR: z.string().min(1).default(".mcp-xchange"),
151
158
  TERMINAL_SHELL: z.string().min(1).default(process.env.SHELL || "bash"),
@@ -241,11 +248,22 @@ function loadConfig() {
241
248
  else if ((0, node_fs_1.existsSync)(".env")) {
242
249
  process.loadEnvFile(".env");
243
250
  }
251
+ (0, environmentContract_1.assertNoLegacyEnvironmentVariables)(process.env);
244
252
  const parsed = envSchema.parse(process.env);
245
253
  if (parsed.DISTRIBUTED_MODE !== "client" &&
246
254
  !parsed.TELEGRAM_BOT_TOKEN?.trim()) {
247
255
  throw new Error("TELEGRAM_BOT_TOKEN is required for gateway and both distributed modes.");
248
256
  }
257
+ const gatewayServerEnabled = parsed.DISTRIBUTED_MODE === "gateway" ||
258
+ parsed.DISTRIBUTED_MODE === "both";
259
+ const gatewayClientConfigured = parsed.DISTRIBUTED_MODE === "client" &&
260
+ Boolean(parsed.GATEWAY_PUBLIC_URL || parsed.GATEWAY_WS_URL);
261
+ if ((gatewayServerEnabled || gatewayClientConfigured) &&
262
+ !parsed.GATEWAY_AUTH_TOKEN?.trim()) {
263
+ throw new Error(gatewayServerEnabled
264
+ ? "GATEWAY_AUTH_TOKEN is required for gateway and both distributed modes."
265
+ : "GATEWAY_AUTH_TOKEN is required when a client connects to a gateway.");
266
+ }
249
267
  if (parsed.ADMIN_TOKEN?.trim() && !parsed.TELEGRAM_BOT_TOKEN?.trim()) {
250
268
  throw new Error("ADMIN_TOKEN requires TELEGRAM_BOT_TOKEN because admin mode runs through the gateway bot.");
251
269
  }
@@ -257,6 +275,69 @@ function loadConfig() {
257
275
  throw new Error("TELEGRAM_WEBHOOK_ENABLED=true requires TELEGRAM_WEBHOOK_SECRET.");
258
276
  }
259
277
  }
278
+ const oauthConfigured = Boolean(parsed.TELLYMCP_PUBLIC_URL ||
279
+ parsed.TELLYMCP_OAUTH_ISSUER ||
280
+ parsed.TELLYMCP_OAUTH_AUDIENCE ||
281
+ parsed.TELLYMCP_MAGIC_TOKEN ||
282
+ parsed.TELLYMCP_MAGIC_TOKEN_HASH ||
283
+ parsed.TELLYMCP_OAUTH_CLIENT_ID ||
284
+ parsed.TELLYMCP_OAUTH_CLIENT_SECRET ||
285
+ parsed.TELLYMCP_ALLOWED_REDIRECT_URIS ||
286
+ parsed.TELLYMCP_OAUTH_PRIVATE_KEY_PEM);
287
+ if (oauthConfigured && !parsed.TELLYMCP_PUBLIC_URL) {
288
+ throw new Error("TELLYMCP_PUBLIC_URL is required when OAuth connector settings are configured.");
289
+ }
290
+ if (oauthConfigured &&
291
+ !parsed.TELLYMCP_MAGIC_TOKEN &&
292
+ !parsed.TELLYMCP_MAGIC_TOKEN_HASH) {
293
+ throw new Error("TELLYMCP_MAGIC_TOKEN or TELLYMCP_MAGIC_TOKEN_HASH is required when OAuth is configured.");
294
+ }
295
+ if (parsed.TELLYMCP_MAGIC_TOKEN && parsed.TELLYMCP_MAGIC_TOKEN_HASH) {
296
+ throw new Error("Configure only one of TELLYMCP_MAGIC_TOKEN and TELLYMCP_MAGIC_TOKEN_HASH.");
297
+ }
298
+ if (parsed.TELLYMCP_MAGIC_TOKEN_HASH &&
299
+ !/^sha256:[a-f0-9]{64}$/iu.test(parsed.TELLYMCP_MAGIC_TOKEN_HASH)) {
300
+ throw new Error("TELLYMCP_MAGIC_TOKEN_HASH must use the format sha256:<64 hex characters>.");
301
+ }
302
+ if (parsed.TELLYMCP_OAUTH_CLIENT_SECRET && !parsed.TELLYMCP_OAUTH_CLIENT_ID) {
303
+ throw new Error("TELLYMCP_OAUTH_CLIENT_SECRET requires TELLYMCP_OAUTH_CLIENT_ID.");
304
+ }
305
+ for (const [name, value] of [
306
+ ["TELLYMCP_PUBLIC_URL", parsed.TELLYMCP_PUBLIC_URL],
307
+ ["TELLYMCP_OAUTH_ISSUER", parsed.TELLYMCP_OAUTH_ISSUER],
308
+ ["TELLYMCP_OAUTH_AUDIENCE", parsed.TELLYMCP_OAUTH_AUDIENCE],
309
+ ]) {
310
+ if (!value) {
311
+ continue;
312
+ }
313
+ const url = new URL(value);
314
+ if (url.search || url.hash) {
315
+ throw new Error(`${name} must not contain a query string or fragment.`);
316
+ }
317
+ }
318
+ const oauthScopes = parsed.TELLYMCP_OAUTH_SCOPES
319
+ .split(/[\s,]+/u)
320
+ .map((scope) => scope.trim())
321
+ .filter(Boolean);
322
+ if (oauthConfigured && oauthScopes.length === 0) {
323
+ throw new Error("TELLYMCP_OAUTH_SCOPES must contain at least one scope.");
324
+ }
325
+ const allowedRedirectUris = parsed.TELLYMCP_ALLOWED_REDIRECT_URIS
326
+ ? parsed.TELLYMCP_ALLOWED_REDIRECT_URIS.split(",")
327
+ .map((redirectUri) => redirectUri.trim())
328
+ .filter(Boolean)
329
+ : [];
330
+ for (const redirectUri of allowedRedirectUris) {
331
+ try {
332
+ const parsedRedirectUri = new URL(redirectUri);
333
+ if (parsedRedirectUri.hash) {
334
+ throw new Error("fragment");
335
+ }
336
+ }
337
+ catch {
338
+ throw new Error(`TELLYMCP_ALLOWED_REDIRECT_URIS contains an invalid URL: ${redirectUri}`);
339
+ }
340
+ }
260
341
  const telegramProxy = parsed.PROXY_USE === "http"
261
342
  ? parsed.HTTP_PROXY
262
343
  ? {
@@ -315,32 +396,58 @@ function loadConfig() {
315
396
  ...(parsed.REDIS_USERNAME ? { username: parsed.REDIS_USERNAME } : {}),
316
397
  ...(parsed.REDIS_PASSWORD ? { password: parsed.REDIS_PASSWORD } : {}),
317
398
  },
318
- mode: parsed.MODE,
319
- pairCodeTtlSeconds: parsed.PAIR_CODE_TTL_SECONDS,
399
+ mode: parsed.TELEGRAM_REQUEST_MODE,
320
400
  mcp: {
321
401
  httpHost: parsed.MCP_HTTP_HOST,
322
402
  httpPort: parsed.MCP_HTTP_PORT,
323
403
  httpPath: parsed.MCP_HTTP_PATH,
324
- vfsScope: parsed.MCP_VFS_SCOPE,
325
404
  ...(parsed.MCP_HTTP_BEARER_TOKEN
326
405
  ? { bearerToken: parsed.MCP_HTTP_BEARER_TOKEN }
327
406
  : {}),
328
407
  enableDebugRoutes: parsed.MCP_HTTP_ENABLE_DEBUG_ROUTES,
329
408
  enablePruneRoute: parsed.MCP_HTTP_ENABLE_PRUNE_ROUTE,
330
409
  },
410
+ ...(oauthConfigured && parsed.TELLYMCP_PUBLIC_URL
411
+ ? {
412
+ oauth: {
413
+ publicUrl: parsed.TELLYMCP_PUBLIC_URL.replace(/\/+$/u, ""),
414
+ issuer: (parsed.TELLYMCP_OAUTH_ISSUER ?? parsed.TELLYMCP_PUBLIC_URL).replace(/\/+$/u, ""),
415
+ audience: (parsed.TELLYMCP_OAUTH_AUDIENCE ?? parsed.TELLYMCP_PUBLIC_URL).replace(/\/+$/u, ""),
416
+ ...(parsed.TELLYMCP_MAGIC_TOKEN
417
+ ? { magicToken: parsed.TELLYMCP_MAGIC_TOKEN }
418
+ : {}),
419
+ ...(parsed.TELLYMCP_MAGIC_TOKEN_HASH
420
+ ? { magicTokenHash: parsed.TELLYMCP_MAGIC_TOKEN_HASH }
421
+ : {}),
422
+ ...(parsed.TELLYMCP_OAUTH_CLIENT_ID
423
+ ? { clientId: parsed.TELLYMCP_OAUTH_CLIENT_ID }
424
+ : {}),
425
+ ...(parsed.TELLYMCP_OAUTH_CLIENT_SECRET
426
+ ? { clientSecret: parsed.TELLYMCP_OAUTH_CLIENT_SECRET }
427
+ : {}),
428
+ allowedRedirectUris,
429
+ ...(parsed.TELLYMCP_OAUTH_PRIVATE_KEY_PEM
430
+ ? {
431
+ privateKeyPem: parsed.TELLYMCP_OAUTH_PRIVATE_KEY_PEM.replace(/\\n/gu, "\n"),
432
+ }
433
+ : {}),
434
+ authCodeTtlSeconds: parsed.TELLYMCP_AUTH_CODE_TTL_SECONDS,
435
+ scopes: oauthScopes,
436
+ keyId: parsed.TELLYMCP_OAUTH_KEY_ID,
437
+ },
438
+ }
439
+ : {}),
331
440
  distributed: {
332
441
  mode: parsed.DISTRIBUTED_MODE,
333
442
  ...(parsed.GATEWAY_PUBLIC_URL
334
443
  ? { gatewayPublicUrl: parsed.GATEWAY_PUBLIC_URL }
335
444
  : {}),
336
- gatewayBindHost: parsed.GATEWAY_BIND_HOST,
337
- gatewayBindPort: parsed.GATEWAY_BIND_PORT,
338
445
  ...(parsed.GATEWAY_WS_URL
339
446
  ? { gatewayWsUrl: parsed.GATEWAY_WS_URL }
340
447
  : {}),
341
448
  gatewayWsPath: parsed.GATEWAY_WS_PATH,
342
- ...(parsed.GATEWAY_TOKEN
343
- ? { gatewayToken: parsed.GATEWAY_TOKEN }
449
+ ...(parsed.GATEWAY_SCOPE_TOKEN
450
+ ? { gatewayScopeToken: parsed.GATEWAY_SCOPE_TOKEN }
344
451
  : {}),
345
452
  ...(parsed.GATEWAY_USER_UUID
346
453
  ? { gatewayUserUuid: parsed.GATEWAY_USER_UUID }
@@ -348,21 +455,6 @@ function loadConfig() {
348
455
  ...(parsed.GATEWAY_AUTH_TOKEN
349
456
  ? { gatewayAuthToken: parsed.GATEWAY_AUTH_TOKEN }
350
457
  : {}),
351
- ...(parsed.GATEWAY_DATABASE_URL
352
- ? { gatewayDatabaseUrl: parsed.GATEWAY_DATABASE_URL }
353
- : {}),
354
- ...(parsed.GATEWAY_S3_ENDPOINT
355
- ? { gatewayS3Endpoint: parsed.GATEWAY_S3_ENDPOINT }
356
- : {}),
357
- ...(parsed.GATEWAY_S3_BUCKET
358
- ? { gatewayS3Bucket: parsed.GATEWAY_S3_BUCKET }
359
- : {}),
360
- ...(parsed.GATEWAY_S3_ACCESS_KEY
361
- ? { gatewayS3AccessKey: parsed.GATEWAY_S3_ACCESS_KEY }
362
- : {}),
363
- ...(parsed.GATEWAY_S3_SECRET_KEY
364
- ? { gatewayS3SecretKey: parsed.GATEWAY_S3_SECRET_KEY }
365
- : {}),
366
458
  ...(parsed.RMQ_HOST
367
459
  ? {
368
460
  rmq: {
@@ -386,7 +478,6 @@ function loadConfig() {
386
478
  sessionTtlSeconds: parsed.WEBAPP_SESSION_TTL_SECONDS,
387
479
  launchMode: parsed.WEBAPP_LAUNCH_MODE,
388
480
  visibleScreens: parsed.WEBAPP_VISIBLE_SCREENS,
389
- pollIntervalMs: parsed.WEBAPP_POLL_INTERVAL_MS,
390
481
  actionCooldownMs: parsed.WEBAPP_ACTION_COOLDOWN_MS,
391
482
  },
392
483
  exchange: {