@deadragdoll/tellymcp 0.0.8 → 0.0.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/.env.example.client +2 -0
  2. package/.env.example.gateway +2 -0
  3. package/README-ru.md +21 -1
  4. package/README.md +5 -1
  5. package/TOOLS.md +3 -1
  6. package/VERSION.md +58 -0
  7. package/config/templates/env.both.template +1 -0
  8. package/config/templates/env.client.template +1 -0
  9. package/config/templates/env.gateway.template +1 -0
  10. package/dist/services/features/telegram-mcp/approval.service.js +1 -1
  11. package/dist/services/features/telegram-mcp/browser.service.js +1 -1
  12. package/dist/services/features/telegram-mcp/collaboration.service.js +1 -1
  13. package/dist/services/features/telegram-mcp/gateway-rmq.service.js +3 -2
  14. package/dist/services/features/telegram-mcp/gateway-socket.service.js +8 -2
  15. package/dist/services/features/telegram-mcp/inbox.service.js +1 -1
  16. package/dist/services/features/telegram-mcp/mcp-http.service.js +1 -1
  17. package/dist/services/features/telegram-mcp/notify.service.js +1 -1
  18. package/dist/services/features/telegram-mcp/pair.service.js +1 -1
  19. package/dist/services/features/telegram-mcp/runtime.service.js +27 -7
  20. package/dist/services/features/telegram-mcp/session-context.service.js +1 -1
  21. package/dist/services/features/telegram-mcp/src/app/bootstrap/runtime.js +2 -1
  22. package/dist/services/features/telegram-mcp/src/app/config/env.js +4 -0
  23. package/dist/services/features/telegram-mcp/src/app/http.js +8 -1
  24. package/dist/services/features/telegram-mcp/src/app/providers/mcp/server.js +2 -1
  25. package/dist/services/features/telegram-mcp/src/app/webapp/assets.js +201 -60
  26. package/dist/services/features/telegram-mcp/src/shared/i18n/index.js +46 -0
  27. package/dist/services/features/telegram-mcp/src/shared/i18n/resources/en.js +555 -0
  28. package/dist/services/features/telegram-mcp/src/shared/i18n/resources/ru.js +555 -0
  29. package/dist/services/features/telegram-mcp/src/shared/integrations/redis/stateStore.js +9 -0
  30. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transport.js +1227 -567
  31. package/dist/services/features/telegram-mcp/standalone-http.service.js +1 -1
  32. package/dist/services/features/telegram-mcp/tools-sync.service.js +1 -1
  33. package/package.json +2 -1
@@ -4,6 +4,8 @@
4
4
  TELEGRAM_BOT_TOKEN=
5
5
  # Username бота, с @ или без.
6
6
  TELEGRAM_BOT_USERNAME=
7
+ # Принудительный язык UI для отладки локализации: en или ru.
8
+ # DEBUG_LANGUAGE=ru
7
9
  # Необязательная подпись проекта/сессии в prompt и note.
8
10
  PROJECT_NAME=
9
11
 
@@ -4,6 +4,8 @@
4
4
  TELEGRAM_BOT_TOKEN=
5
5
  # Username бота, с @ или без.
6
6
  TELEGRAM_BOT_USERNAME=
7
+ # Принудительный язык UI для отладки локализации: en или ru.
8
+ # DEBUG_LANGUAGE=ru
7
9
  # Необязательная подпись проекта/сессии.
8
10
  PROJECT_NAME=
9
11
 
package/README-ru.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # TellyMCP
2
2
 
3
- [English](README.md) | [Русский](README-ru.md) | [Standalone Guide](STANDALONE.md) | [Standalone RU](STANDALONE-ru.md) | [Release Notes](VERSION.md)
3
+ [English](README.md) | [Русский](README-ru.md) | [Standalone Guide](STANDALONE.md) | [Standalone RU](STANDALONE-ru.md) | [Screenshots](screenshots/README.md) | [Gallery](screenshots/GALLERY.md) | [Release Notes](VERSION.md)
4
4
 
5
5
  [![npm version](https://img.shields.io/npm/v/%40deadragdoll%2Ftellymcp)](https://www.npmjs.com/package/@deadragdoll/tellymcp)
6
6
  [![npm downloads](https://img.shields.io/npm/dm/%40deadragdoll%2Ftellymcp)](https://www.npmjs.com/package/@deadragdoll/tellymcp)
@@ -239,6 +239,26 @@ tellymcp run --env .env
239
239
 
240
240
  - `https://your-host.example/api/mcp`
241
241
 
242
+ ## Mini App / Live
243
+
244
+ Если `WEBAPP_ENABLED=true`, в меню сессии появляется `🖥 Live`.
245
+
246
+ Mini App:
247
+
248
+ - обслуживается этим же Node service по `WEBAPP_BASE_PATH`
249
+ - в `client`-режиме тоже может открываться через общий gateway domain
250
+ - показывает видимую область tmux pane и отправляет ограниченный набор control actions
251
+ - валидирует Telegram `initData` на сервере
252
+ - умеет открываться в режимах:
253
+ - `default`
254
+ - `expand`
255
+ - `fullscreen` с fallback на `expand`
256
+ - после успешного bootstrap удаляет временное launcher-сообщение
257
+ - автоматически восстанавливается после короткого рестарта шлюза:
258
+ - краткий `502/503` переживается обычным polling
259
+ - если in-process WebApp session на шлюзе была потеряна и приходит `401/403`, Mini App сама делает повторный bootstrap
260
+ - в типовом restart-case переоткрывать `Live` не нужно
261
+
242
262
  ## Docker: только для инфраструктуры или для `gateway`-only
243
263
 
244
264
  Docker больше не является основным способом запуска TellyMCP, но один container path поддерживается:
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # TellyMCP
2
2
 
3
- [English](README.md) | [Русский](README-ru.md) | [Standalone Guide](STANDALONE.md) | [Standalone RU](STANDALONE-ru.md) | [Release Notes](VERSION.md)
3
+ [English](README.md) | [Русский](README-ru.md) | [Standalone Guide](STANDALONE.md) | [Standalone RU](STANDALONE-ru.md) | [Screenshots](screenshots/README.md) | [Gallery](screenshots/GALLERY.md) | [Release Notes](VERSION.md)
4
4
 
5
5
  [![npm version](https://img.shields.io/npm/v/%40deadragdoll%2Ftellymcp)](https://www.npmjs.com/package/@deadragdoll/tellymcp)
6
6
  [![npm downloads](https://img.shields.io/npm/dm/%40deadragdoll%2Ftellymcp)](https://www.npmjs.com/package/@deadragdoll/tellymcp)
@@ -521,6 +521,10 @@ The Mini App:
521
521
  - requires the Telegram user from `initData` to match the bound session user
522
522
  - resolves the active session from the bound Telegram user, so a session id in the URL is not required for normal use
523
523
  - deletes the temporary `Open Live View` launcher message after successful Mini App bootstrap
524
+ - auto-recovers after a short gateway restart:
525
+ - short `502/503` periods are tolerated by polling
526
+ - expired in-process WebApp sessions (`401/403`) trigger an automatic re-bootstrap
527
+ - in normal restart cases the user does not need to reopen `Live`
524
528
  - allows only a fixed control set:
525
529
  - `Esc`
526
530
  - `Tab`
package/TOOLS.md CHANGED
@@ -1,10 +1,12 @@
1
1
  # Tools
2
2
 
3
- Version: `2026-05-17.1`
3
+ Version: `2026-05-18.1`
4
4
 
5
5
  Gateway/client runtime compatibility:
6
6
 
7
7
  - `TOOLS.md` hash sync and runtime version handshake are separate checks.
8
+ - The authoritative freshness check for `TOOLS.md` is the content hash, not this human-readable `Version:` line.
9
+ - Treat this `Version:` line only as a quick visual marker for humans and logs.
8
10
  - `TOOLS.md` sync tells the agent to refresh instructions.
9
11
  - `ws hello/hello_ack` checks `package_version`, `protocol_version`, and `capabilities`.
10
12
  - If protocol major versions differ, gateway transport is blocked until the older side is upgraded.
package/VERSION.md CHANGED
@@ -4,6 +4,60 @@ Public, user-facing release notes for published versions of `@deadragdoll/tellym
4
4
 
5
5
  For detailed engineering history, refactors, and internal development notes, see [CHANGELOG.md](CHANGELOG.md).
6
6
 
7
+ ## 0.0.10
8
+
9
+ ### Added
10
+ - Telegram UI localization for the bot layer:
11
+ - English and Russian catalogs for user-facing bot screens
12
+ - locale resolution from Telegram profile with persisted user preference
13
+ - `DEBUG_LANGUAGE=en|ru` override for fast testing without changing the Telegram profile
14
+
15
+ ### Changed
16
+ - Localization scope is now explicit:
17
+ - Telegram bot UI is localized
18
+ - MCP tools, logs, `TOOLS.md`, and the Live Mini App remain canonical English by design
19
+ - Telegram menus, callbacks, project/collaboration screens, startup notices, and operational bot notices now render through a shared translation layer instead of ad hoc inline strings
20
+
21
+ ### Fixed
22
+ - Builder startup is more robust:
23
+ - runtime-dependent services now wait for full runtime readiness instead of racing broker registration
24
+ - this avoids `telegram_mcp runtime is not initialized yet` failures during `yarn dev:builder`
25
+ - Locale resolution is safe for partial test mocks and startup paths
26
+ - Telegram UI text is now consistent across:
27
+ - main menus
28
+ - inbox/session flows
29
+ - project/collab flows
30
+ - live approval prompts
31
+ - tmux and operational bot notices
32
+
33
+ ## 0.0.9
34
+
35
+ ### Added
36
+ - Public screenshot docs:
37
+ - full screenshot index in `screenshots/README.md`
38
+ - shorter public gallery in `screenshots/GALLERY.md`
39
+ - More explicit Live launch modes from Telegram:
40
+ - `Fullscreen`
41
+ - `Expand`
42
+ - `Default`
43
+
44
+ ### Changed
45
+ - README and README-RU now surface screenshot links directly in the top navigation.
46
+ - The `Live` Mini App UI is more practical on phones:
47
+ - wrap/unwrap toggle moved into the status bar
48
+ - session name is shown as a compact state badge
49
+ - update timestamp is shorter and less noisy
50
+ - local `Live` screenshots are documented in a clearer flow near the launcher step
51
+
52
+ ### Fixed
53
+ - `Live` now reconnects more gracefully after a gateway restart:
54
+ - short `502/503` gaps recover through polling
55
+ - expired in-process WebApp sessions (`401/403`) trigger automatic re-bootstrap
56
+ - reopening the Mini App is no longer required in the normal restart case
57
+ - Runtime MCP metadata now reports the actual package version instead of stale hardcoded version data.
58
+ - Successful tmux nudges no longer overwrite `tmuxPaneId` with non-pane targets such as `backend:0.0`.
59
+ - If tmux itself is unavailable for a paired session with a saved tmux target, Telegram now receives an operational warning instead of leaving the signal only in backend logs.
60
+
7
61
  ## 0.0.8
8
62
 
9
63
  ### Added
@@ -32,6 +86,10 @@ For detailed engineering history, refactors, and internal development notes, see
32
86
  - Stale tmux pane ids like `%1 -> %2` no longer require manual user understanding before the service can try to wake the session again.
33
87
  - Broken tmux nudge targets are now visible to the user in Telegram, not only in backend logs.
34
88
  - `Share` inbox instructions are now explicit enough to reduce the chance that one agent re-delegates the task back into the collaboration graph.
89
+ - `Live` Mini App now survives a normal gateway restart much better:
90
+ - short `502/503` periods recover through polling
91
+ - lost in-process WebApp sessions (`401/403`) trigger automatic re-bootstrap
92
+ - reopening the Mini App is no longer required in the normal restart case
35
93
 
36
94
  ## 0.0.3
37
95
 
@@ -2,6 +2,7 @@
2
2
 
3
3
  TELEGRAM_BOT_TOKEN=
4
4
  TELEGRAM_BOT_USERNAME=
5
+ # DEBUG_LANGUAGE=ru
5
6
  PROJECT_NAME=
6
7
 
7
8
  REDIS_HOST=127.0.0.1
@@ -2,6 +2,7 @@
2
2
 
3
3
  TELEGRAM_BOT_TOKEN=
4
4
  TELEGRAM_BOT_USERNAME=
5
+ # DEBUG_LANGUAGE=ru
5
6
  PROJECT_NAME=
6
7
 
7
8
  REDIS_HOST=127.0.0.1
@@ -2,6 +2,7 @@
2
2
 
3
3
  TELEGRAM_BOT_TOKEN=
4
4
  TELEGRAM_BOT_USERNAME=
5
+ # DEBUG_LANGUAGE=ru
5
6
  PROJECT_NAME=
6
7
 
7
8
  REDIS_HOST=127.0.0.1
@@ -24,7 +24,7 @@ const TelegramMcpApprovalService = {
24
24
  if (!runtimeService) {
25
25
  throw new Error(`Local Moleculer service '${runtime_service_1.TELEGRAM_MCP_RUNTIME_SERVICE_NAME}' is unavailable`);
26
26
  }
27
- const runtime = runtimeService.getRuntime();
27
+ const runtime = await runtimeService.waitUntilReady();
28
28
  this.logger.info("Starting telegram_mcp approval service");
29
29
  this.approvalOrchestrator = new orchestrator_1.HumanApprovalOrchestrator(runtime.config, runtime.stateStore, runtime.stateStore, runtime.stateStore, runtime.telegramTransport, runtime.logger, runtime.projectIdentityResolver);
30
30
  this.logger.info("telegram_mcp approval service is ready");
@@ -24,7 +24,7 @@ const TelegramMcpBrowserService = {
24
24
  if (!runtimeService) {
25
25
  throw new Error(`Local Moleculer service '${runtime_service_1.TELEGRAM_MCP_RUNTIME_SERVICE_NAME}' is unavailable`);
26
26
  }
27
- const runtime = runtimeService.getRuntime();
27
+ const runtime = await runtimeService.waitUntilReady();
28
28
  this.logger.info("Starting telegram_mcp browser service");
29
29
  this.browserService = new browserService_1.BrowserService(runtime.config, runtime.stateStore, runtime.stateStore, runtime.stateStore, runtime.objectStore, runtime.telegramTransport, runtime.logger, runtime.projectIdentityResolver);
30
30
  this.logger.info("telegram_mcp browser service is ready");
@@ -34,7 +34,7 @@ const TelegramMcpCollaborationService = {
34
34
  if (!runtimeService) {
35
35
  throw new Error(`Local Moleculer service '${runtime_service_1.TELEGRAM_MCP_RUNTIME_SERVICE_NAME}' is unavailable`);
36
36
  }
37
- const runtime = runtimeService.getRuntime();
37
+ const runtime = await runtimeService.waitUntilReady();
38
38
  this.logger.info("Starting telegram_mcp collaboration service");
39
39
  const localBackend = new localCollaborationBackend_1.LocalCollaborationBackend(runtime.config, runtime.stateStore, runtime.stateStore, runtime.stateStore, runtime.stateStore, runtime.objectStore, runtime.telegramTransport, runtime.logger);
40
40
  runtime.gatewayHttpService.setPartnerNoteRelayHandler(async (input) => {
@@ -276,10 +276,11 @@ const TelegramMcpGatewayRmqService = {
276
276
  throw new Error(`Local Moleculer service '${runtime_service_1.TELEGRAM_MCP_RUNTIME_SERVICE_NAME}' is unavailable`);
277
277
  }
278
278
  this.runtimeService = runtimeService;
279
+ const runtime = await runtimeService.waitUntilReady();
279
280
  if (!this.isEnabled?.()) {
280
281
  this.logger.info("Gateway RMQ is disabled", {
281
- distributedMode: runtimeService.getRuntime().config.distributed.mode,
282
- rmqConfigured: Boolean(runtimeService.getRuntime().config.distributed.rmq?.host),
282
+ distributedMode: runtime.config.distributed.mode,
283
+ rmqConfigured: Boolean(runtime.config.distributed.rmq?.host),
283
284
  });
284
285
  return;
285
286
  }
@@ -1455,8 +1455,14 @@ const TelegramMcpGatewaySocketService = {
1455
1455
  },
1456
1456
  },
1457
1457
  async started() {
1458
- const runtime = this.getRuntimeOrThrow?.();
1459
- const mode = runtime?.config.distributed.mode;
1458
+ await this.broker.waitForServices([runtime_service_1.TELEGRAM_MCP_RUNTIME_SERVICE_NAME]);
1459
+ const runtimeService = this.broker.getLocalService(runtime_service_1.TELEGRAM_MCP_RUNTIME_SERVICE_NAME);
1460
+ if (!runtimeService) {
1461
+ throw new Error(`Local Moleculer service '${runtime_service_1.TELEGRAM_MCP_RUNTIME_SERVICE_NAME}' is unavailable`);
1462
+ }
1463
+ this.runtimeService = runtimeService;
1464
+ const runtime = await runtimeService.waitUntilReady();
1465
+ const mode = runtime.config.distributed.mode;
1460
1466
  const gatewayEnabled = mode === "gateway" || mode === "both";
1461
1467
  const clientEnabled = mode === "client" || mode === "both";
1462
1468
  if (gatewayEnabled) {
@@ -24,7 +24,7 @@ const TelegramMcpInboxService = {
24
24
  if (!runtimeService) {
25
25
  throw new Error(`Local Moleculer service '${runtime_service_1.TELEGRAM_MCP_RUNTIME_SERVICE_NAME}' is unavailable`);
26
26
  }
27
- const runtime = runtimeService.getRuntime();
27
+ const runtime = await runtimeService.waitUntilReady();
28
28
  this.logger.info("Starting telegram_mcp inbox service");
29
29
  this.inboxService = new inboxService_1.InboxService(runtime.config, runtime.stateStore, runtime.stateStore, runtime.logger, runtime.projectIdentityResolver);
30
30
  this.logger.info("telegram_mcp inbox service is ready");
@@ -52,7 +52,7 @@ const TelegramMcpHttpService = {
52
52
  if (!mcpServerService) {
53
53
  throw new Error(`Local Moleculer service '${mcp_server_service_1.TELEGRAM_MCP_MCP_SERVER_SERVICE_NAME}' is unavailable`);
54
54
  }
55
- const runtime = runtimeService.getRuntime();
55
+ const runtime = await runtimeService.waitUntilReady();
56
56
  this.logger.info("Starting telegram_mcp HTTP service");
57
57
  this.httpHandler = (0, http_1.createMcpHttpHandler)(runtime, {
58
58
  createMcpServer: () => mcpServerService.createServer(),
@@ -24,7 +24,7 @@ const TelegramMcpNotifyService = {
24
24
  if (!runtimeService) {
25
25
  throw new Error(`Local Moleculer service '${runtime_service_1.TELEGRAM_MCP_RUNTIME_SERVICE_NAME}' is unavailable`);
26
26
  }
27
- const runtime = runtimeService.getRuntime();
27
+ const runtime = await runtimeService.waitUntilReady();
28
28
  this.logger.info("Starting telegram_mcp notify service");
29
29
  this.notifyService = new notifyService_1.NotifyService(runtime.config, runtime.stateStore, runtime.stateStore, runtime.telegramTransport, runtime.logger, runtime.projectIdentityResolver);
30
30
  this.logger.info("telegram_mcp notify service is ready");
@@ -24,7 +24,7 @@ const TelegramMcpPairService = {
24
24
  if (!runtimeService) {
25
25
  throw new Error(`Local Moleculer service '${runtime_service_1.TELEGRAM_MCP_RUNTIME_SERVICE_NAME}' is unavailable`);
26
26
  }
27
- const runtime = runtimeService.getRuntime();
27
+ const runtime = await runtimeService.waitUntilReady();
28
28
  this.logger.info("Starting telegram_mcp pair service");
29
29
  this.pairSessionService = new generatePairCode_1.PairSessionService(runtime.config, runtime.stateStore, runtime.stateStore, runtime.stateStore, runtime.logger, runtime.projectIdentityResolver);
30
30
  this.logger.info("telegram_mcp pair service is ready");
@@ -8,6 +8,10 @@ const TelegramMcpRuntimeService = {
8
8
  name: exports.TELEGRAM_MCP_RUNTIME_SERVICE_NAME,
9
9
  created() {
10
10
  this.runtime = null;
11
+ this.readyPromise = new Promise((resolve, reject) => {
12
+ this.resolveReady = resolve;
13
+ this.rejectReady = reject;
14
+ });
11
15
  },
12
16
  methods: {
13
17
  getRuntime() {
@@ -16,19 +20,35 @@ const TelegramMcpRuntimeService = {
16
20
  }
17
21
  return this.runtime;
18
22
  },
23
+ waitUntilReady() {
24
+ if (this.runtime) {
25
+ return Promise.resolve(this.runtime);
26
+ }
27
+ if (!this.readyPromise) {
28
+ return Promise.reject(new Error("telegram_mcp runtime readiness promise is unavailable"));
29
+ }
30
+ return this.readyPromise;
31
+ },
19
32
  },
20
33
  async started() {
21
34
  this.logger.info("Starting telegram_mcp runtime service", {
22
35
  packageVersion: (0, versionHandshake_1.getTellyMcpPackageVersion)(__dirname),
23
36
  protocolVersion: versionHandshake_1.TELLYMCP_PROTOCOL_VERSION,
24
37
  });
25
- this.runtime = await (0, runtime_1.createAppRuntime)({
26
- callBroker: (actionName, params, options) => this.broker.call(actionName, params, options),
27
- });
28
- this.logger.info("telegram_mcp runtime service is ready", {
29
- packageVersion: (0, versionHandshake_1.getTellyMcpPackageVersion)(__dirname),
30
- protocolVersion: versionHandshake_1.TELLYMCP_PROTOCOL_VERSION,
31
- });
38
+ try {
39
+ this.runtime = await (0, runtime_1.createAppRuntime)({
40
+ callBroker: (actionName, params, options) => this.broker.call(actionName, params, options),
41
+ });
42
+ this.resolveReady?.(this.runtime);
43
+ this.logger.info("telegram_mcp runtime service is ready", {
44
+ packageVersion: (0, versionHandshake_1.getTellyMcpPackageVersion)(__dirname),
45
+ protocolVersion: versionHandshake_1.TELLYMCP_PROTOCOL_VERSION,
46
+ });
47
+ }
48
+ catch (error) {
49
+ this.rejectReady?.(error);
50
+ throw error;
51
+ }
32
52
  },
33
53
  async stopped() {
34
54
  if (!this.runtime) {
@@ -24,7 +24,7 @@ const TelegramMcpSessionContextService = {
24
24
  if (!runtimeService) {
25
25
  throw new Error(`Local Moleculer service '${runtime_service_1.TELEGRAM_MCP_RUNTIME_SERVICE_NAME}' is unavailable`);
26
26
  }
27
- const runtime = runtimeService.getRuntime();
27
+ const runtime = await runtimeService.waitUntilReady();
28
28
  this.logger.info("Starting telegram_mcp session-context service");
29
29
  this.sessionContextService = new sessionContextService_1.SessionContextService(runtime.stateStore, runtime.stateStore, runtime.logger, runtime.projectIdentityResolver);
30
30
  this.logger.info("telegram_mcp session-context service is ready");
@@ -72,7 +72,7 @@ async function createAppRuntime(input) {
72
72
  const objectStore = new minioExchangeStore_1.MinioExchangeStore(input.callBroker, stateStore, config.tmux, config.exchange.dir, config.mcp.vfsScope, logger, config.distributed.mode, config.distributed.gatewayPublicUrl, config.distributed.gatewayAuthToken);
73
73
  await stateStore.resetRuntimeState();
74
74
  logger.info("Runtime pending state reset");
75
- const telegramTransport = new transport_1.TelegramTransport(config, stateStore, stateStore, stateStore, stateStore, stateStore, stateStore, objectStore, webAppLaunchRegistry, logger);
75
+ const telegramTransport = new transport_1.TelegramTransport(config, stateStore, stateStore, stateStore, stateStore, stateStore, stateStore, stateStore, objectStore, webAppLaunchRegistry, logger);
76
76
  await telegramTransport.start();
77
77
  logger.info("Telegram transport ready");
78
78
  await telegramTransport.recoverPendingInboxNudges();
@@ -89,6 +89,7 @@ async function createAppRuntime(input) {
89
89
  sessionStore: stateStore,
90
90
  bindingStore: stateStore,
91
91
  inboxStore: stateStore,
92
+ localeStore: stateStore,
92
93
  xchangeFileMetaStore: stateStore,
93
94
  maintenanceStore: stateStore,
94
95
  objectStore,
@@ -59,6 +59,7 @@ const envSchema = z.object({
59
59
  .int()
60
60
  .positive()
61
61
  .default(300),
62
+ DEBUG_LANGUAGE: z.enum(["en", "ru"]).optional(),
62
63
  REDIS_HOST: z.string().min(1),
63
64
  REDIS_PORT: z.coerce.number().int().positive(),
64
65
  REDIS_DB: z.coerce.number().int().nonnegative(),
@@ -205,6 +206,9 @@ function loadConfig() {
205
206
  ...(parsed.TELEGRAM_BOT_USERNAME
206
207
  ? { botUsername: parsed.TELEGRAM_BOT_USERNAME }
207
208
  : {}),
209
+ ...(parsed.DEBUG_LANGUAGE
210
+ ? { debugLanguage: parsed.DEBUG_LANGUAGE }
211
+ : {}),
208
212
  pollIntervalMs: parsed.TELEGRAM_POLL_INTERVAL_MS,
209
213
  defaultTimeoutSeconds: parsed.TELEGRAM_DEFAULT_TIMEOUT_SECONDS,
210
214
  maxContextChars: parsed.TELEGRAM_MAX_CONTEXT_CHARS,
@@ -105,6 +105,11 @@ function normalizePrefixedPathname(pathname) {
105
105
  const stripped = pathname.slice(normalizedRootPrefix.length);
106
106
  return stripped.startsWith("/") ? stripped : `/${stripped || ""}`;
107
107
  }
108
+ function resolveLaunchModeOverride(value) {
109
+ return value === "default" || value === "expand" || value === "fullscreen"
110
+ ? value
111
+ : null;
112
+ }
108
113
  function normalizeBasePath(value) {
109
114
  const trimmed = value.trim().replace(/\/+$/u, "");
110
115
  if (!trimmed) {
@@ -152,9 +157,11 @@ function createMcpHttpHandler(runtime, input) {
152
157
  writeText(res, 405, "Method not allowed");
153
158
  return;
154
159
  }
160
+ const launchMode = resolveLaunchModeOverride(requestUrl.searchParams.get("launchMode")) ??
161
+ runtime.config.webapp.launchMode;
155
162
  writeHtml(res, 200, (0, assets_1.renderWebAppHtml)({
156
163
  basePath: publicWebAppBasePath,
157
- launchMode: runtime.config.webapp.launchMode,
164
+ launchMode,
158
165
  }));
159
166
  return;
160
167
  }
@@ -3,10 +3,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.createMcpServer = createMcpServer;
4
4
  const mcp_js_1 = require("@modelcontextprotocol/sdk/server/mcp.js");
5
5
  const registry_1 = require("../../../shared/api/tool-registry/registry");
6
+ const versionHandshake_1 = require("../../../shared/lib/version/versionHandshake");
6
7
  function createMcpServer(tools) {
7
8
  const server = new mcp_js_1.McpServer({
8
9
  name: "tellymcp",
9
- version: "0.0.6",
10
+ version: (0, versionHandshake_1.getTellyMcpPackageVersion)(__dirname),
10
11
  });
11
12
  (0, registry_1.registerTools)(server, tools);
12
13
  return server;