@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
@@ -1,20 +1,27 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.SessionContextService = void 0;
4
+ const ptyRegistry_1 = require("../../../shared/integrations/terminal/ptyRegistry");
4
5
  const redactSecrets_1 = require("../../../shared/lib/redact-secrets/redactSecrets");
5
6
  class SessionContextService {
6
7
  sessionStore;
7
8
  bindingStore;
8
9
  logger;
9
10
  projectIdentityResolver;
10
- constructor(sessionStore, bindingStore, logger, projectIdentityResolver) {
11
+ remoteConsoleInvoker;
12
+ constructor(sessionStore, bindingStore, logger, projectIdentityResolver, remoteConsoleInvoker) {
11
13
  this.sessionStore = sessionStore;
12
14
  this.bindingStore = bindingStore;
13
15
  this.logger = logger;
14
16
  this.projectIdentityResolver = projectIdentityResolver;
17
+ this.remoteConsoleInvoker = remoteConsoleInvoker;
15
18
  }
16
19
  async setContext(input) {
17
20
  const resolved = this.projectIdentityResolver.resolveSessionDefaults(input);
21
+ const remote = await this.remoteConsoleInvoker?.invokeForRelaySession(resolved.sessionId, "telegramMcp.sessionContext.setContextRemote", input);
22
+ if (remote) {
23
+ return remote;
24
+ }
18
25
  const updatedAt = new Date().toISOString();
19
26
  const existing = await this.sessionStore.getSession(resolved.sessionId);
20
27
  const binding = await this.bindingStore.getBinding(resolved.sessionId);
@@ -28,9 +35,6 @@ class SessionContextService {
28
35
  ? { label: existing.label }
29
36
  : {}),
30
37
  ...(existing?.cwd ? { cwd: existing.cwd } : { cwd: resolved.cwd }),
31
- ...(existing?.linkedSessionId
32
- ? { linkedSessionId: existing.linkedSessionId }
33
- : {}),
34
38
  ...(existing?.activeProjectUuid
35
39
  ? { activeProjectUuid: existing.activeProjectUuid }
36
40
  : {}),
@@ -58,22 +62,9 @@ class SessionContextService {
58
62
  : existing?.risks
59
63
  ? { risks: existing.risks }
60
64
  : {}),
61
- ...(existing?.tmuxSessionName
62
- ? { tmuxSessionName: existing.tmuxSessionName }
63
- : {}),
64
- ...(existing?.tmuxWindowName
65
- ? { tmuxWindowName: existing.tmuxWindowName }
66
- : {}),
67
- ...(typeof existing?.tmuxWindowIndex === "number"
68
- ? { tmuxWindowIndex: existing.tmuxWindowIndex }
69
- : {}),
70
- ...(existing?.tmuxPaneId ? { tmuxPaneId: existing.tmuxPaneId } : {}),
71
- ...(typeof existing?.tmuxPaneIndex === "number"
72
- ? { tmuxPaneIndex: existing.tmuxPaneIndex }
73
- : {}),
74
- ...(existing?.tmuxTarget ? { tmuxTarget: existing.tmuxTarget } : {}),
75
- ...(existing?.lastTmuxNudgeAt
76
- ? { lastTmuxNudgeAt: existing.lastTmuxNudgeAt }
65
+ ...(existing?.terminalTarget ? { terminalTarget: existing.terminalTarget } : {}),
66
+ ...(existing?.lastTerminalNudgeAt
67
+ ? { lastTerminalNudgeAt: existing.lastTerminalNudgeAt }
77
68
  : {}),
78
69
  ...(existing?.lastSeenToolsHash
79
70
  ? { lastSeenToolsHash: existing.lastSeenToolsHash }
@@ -107,6 +98,10 @@ class SessionContextService {
107
98
  }
108
99
  async renameSession(input) {
109
100
  const resolved = this.projectIdentityResolver.resolveSessionDefaults(input);
101
+ const remote = await this.remoteConsoleInvoker?.invokeForRelaySession(resolved.sessionId, "telegramMcp.sessionContext.renameSessionRemote", input);
102
+ if (remote) {
103
+ return remote;
104
+ }
110
105
  const existing = await this.sessionStore.getSession(resolved.sessionId);
111
106
  const updatedAt = new Date().toISOString();
112
107
  const label = (0, redactSecrets_1.redactSecrets)(input.title);
@@ -114,9 +109,6 @@ class SessionContextService {
114
109
  sessionId: resolved.sessionId,
115
110
  label,
116
111
  ...(existing?.cwd ? { cwd: existing.cwd } : { cwd: resolved.cwd }),
117
- ...(existing?.linkedSessionId
118
- ? { linkedSessionId: existing.linkedSessionId }
119
- : {}),
120
112
  ...(existing?.activeProjectUuid
121
113
  ? { activeProjectUuid: existing.activeProjectUuid }
122
114
  : {}),
@@ -128,22 +120,9 @@ class SessionContextService {
128
120
  ...(existing?.files ? { files: existing.files } : {}),
129
121
  ...(existing?.decisions ? { decisions: existing.decisions } : {}),
130
122
  ...(existing?.risks ? { risks: existing.risks } : {}),
131
- ...(existing?.tmuxSessionName
132
- ? { tmuxSessionName: existing.tmuxSessionName }
133
- : {}),
134
- ...(existing?.tmuxWindowName
135
- ? { tmuxWindowName: existing.tmuxWindowName }
136
- : {}),
137
- ...(typeof existing?.tmuxWindowIndex === "number"
138
- ? { tmuxWindowIndex: existing.tmuxWindowIndex }
139
- : {}),
140
- ...(existing?.tmuxPaneId ? { tmuxPaneId: existing.tmuxPaneId } : {}),
141
- ...(typeof existing?.tmuxPaneIndex === "number"
142
- ? { tmuxPaneIndex: existing.tmuxPaneIndex }
143
- : {}),
144
- ...(existing?.tmuxTarget ? { tmuxTarget: existing.tmuxTarget } : {}),
145
- ...(existing?.lastTmuxNudgeAt
146
- ? { lastTmuxNudgeAt: existing.lastTmuxNudgeAt }
123
+ ...(existing?.terminalTarget ? { terminalTarget: existing.terminalTarget } : {}),
124
+ ...(existing?.lastTerminalNudgeAt
125
+ ? { lastTerminalNudgeAt: existing.lastTerminalNudgeAt }
147
126
  : {}),
148
127
  ...(existing?.lastSeenToolsHash
149
128
  ? { lastSeenToolsHash: existing.lastSeenToolsHash }
@@ -172,11 +151,12 @@ class SessionContextService {
172
151
  }
173
152
  async getContext(input) {
174
153
  const resolved = this.projectIdentityResolver.resolveSessionDefaults(input);
154
+ const remote = await this.remoteConsoleInvoker?.invokeForRelaySession(resolved.sessionId, "telegramMcp.sessionContext.getContextRemote", input);
155
+ if (remote) {
156
+ return remote;
157
+ }
175
158
  const session = await this.sessionStore.getSession(resolved.sessionId);
176
159
  const binding = await this.bindingStore.getBinding(resolved.sessionId);
177
- const linkedSession = session?.linkedSessionId
178
- ? await this.sessionStore.getSession(session.linkedSessionId)
179
- : null;
180
160
  this.logger.debug("Session context requested", {
181
161
  sessionId: resolved.sessionId,
182
162
  sessionIdDerived: resolved.sessionIdDerived,
@@ -184,12 +164,12 @@ class SessionContextService {
184
164
  hasBinding: Boolean(binding),
185
165
  });
186
166
  const statusMessage = binding
187
- ? session?.tmuxTarget
188
- ? "Telegram pairing is active for this session. A tmux target is configured, so ordinary Telegram messages can wake the agent through tmux nudges."
189
- : "Telegram pairing is active for this session. No tmux target is configured, so inbox handling requires passive MCP checks."
167
+ ? session?.terminalTarget
168
+ ? "Gateway console binding is active for this session. A terminal target is configured, so ordinary Telegram messages can wake the agent through terminal nudges."
169
+ : "Gateway console binding is active for this session. No terminal target is configured, so inbox handling requires passive MCP checks."
190
170
  : session
191
- ? "Session metadata exists, but Telegram pairing is not active."
192
- : "Session metadata and Telegram pairing are both absent.";
171
+ ? "Session metadata exists, but no gateway console binding is active."
172
+ : "Session metadata and gateway console binding are both absent.";
193
173
  return {
194
174
  session_id: resolved.sessionId,
195
175
  exists: Boolean(session),
@@ -200,12 +180,6 @@ class SessionContextService {
200
180
  context: {
201
181
  ...(session.label ? { session_label: session.label } : {}),
202
182
  ...(session.cwd ? { cwd: session.cwd } : {}),
203
- ...(session.linkedSessionId
204
- ? { linked_session_id: session.linkedSessionId }
205
- : {}),
206
- ...(linkedSession?.label
207
- ? { linked_session_label: linkedSession.label }
208
- : {}),
209
183
  ...(session.activeProjectUuid
210
184
  ? { active_project_uuid: session.activeProjectUuid }
211
185
  : {}),
@@ -235,28 +209,13 @@ class SessionContextService {
235
209
  : {}),
236
210
  ...(session
237
211
  ? {
238
- tmux: {
239
- configured: Boolean(session.tmuxTarget),
240
- ...(session.tmuxSessionName
241
- ? { tmux_session_name: session.tmuxSessionName }
242
- : {}),
243
- ...(session.tmuxWindowName
244
- ? { tmux_window_name: session.tmuxWindowName }
245
- : {}),
246
- ...(typeof session.tmuxWindowIndex === "number"
247
- ? { tmux_window_index: session.tmuxWindowIndex }
248
- : {}),
249
- ...(session.tmuxPaneId
250
- ? { tmux_pane_id: session.tmuxPaneId }
212
+ terminal: {
213
+ configured: Boolean(session.terminalTarget),
214
+ ...(session.terminalTarget
215
+ ? { terminal_target: session.terminalTarget }
251
216
  : {}),
252
- ...(typeof session.tmuxPaneIndex === "number"
253
- ? { tmux_pane_index: session.tmuxPaneIndex }
254
- : {}),
255
- ...(session.tmuxTarget
256
- ? { tmux_target: session.tmuxTarget }
257
- : {}),
258
- ...(session.lastTmuxNudgeAt
259
- ? { last_nudge_at: session.lastTmuxNudgeAt }
217
+ ...(session.lastTerminalNudgeAt
218
+ ? { last_nudge_at: session.lastTerminalNudgeAt }
260
219
  : {}),
261
220
  },
262
221
  }
@@ -265,14 +224,22 @@ class SessionContextService {
265
224
  }
266
225
  async clearContext(input) {
267
226
  const resolved = this.projectIdentityResolver.resolveSessionDefaults(input);
227
+ const remote = await this.remoteConsoleInvoker?.invokeForRelaySession(resolved.sessionId, "telegramMcp.sessionContext.clearContextRemote", input);
228
+ if (remote) {
229
+ return remote;
230
+ }
268
231
  const existing = await this.sessionStore.getSession(resolved.sessionId);
232
+ const existingTarget = existing?.terminalTarget;
233
+ if (existingTarget && (0, ptyRegistry_1.isPtyTarget)(existingTarget)) {
234
+ (0, ptyRegistry_1.stopPtyTarget)(existingTarget);
235
+ }
269
236
  await this.sessionStore.clearSession(resolved.sessionId);
270
237
  await this.bindingStore.clearBinding(resolved.sessionId);
271
238
  this.projectIdentityResolver.removeSessionMarker(existing?.cwd || resolved.cwd);
272
239
  this.logger.info("Session context cleared", {
273
240
  sessionId: resolved.sessionId,
274
241
  sessionIdDerived: resolved.sessionIdDerived,
275
- clearedPairing: true,
242
+ clearedTelegramRoute: true,
276
243
  });
277
244
  return {
278
245
  cleared: true,
@@ -280,130 +247,5 @@ class SessionContextService {
280
247
  cleared_pairing: true,
281
248
  };
282
249
  }
283
- async setTmuxTarget(input) {
284
- const resolved = this.projectIdentityResolver.resolveSessionDefaults(input);
285
- const existing = await this.sessionStore.getSession(resolved.sessionId);
286
- const updatedAt = new Date().toISOString();
287
- const sanitizedTarget = (0, redactSecrets_1.redactSecrets)(input.tmux_target);
288
- const sanitizedSessionName = input.tmux_session_name
289
- ? (0, redactSecrets_1.redactSecrets)(input.tmux_session_name)
290
- : existing?.tmuxSessionName;
291
- const sanitizedWindowName = input.tmux_window_name
292
- ? (0, redactSecrets_1.redactSecrets)(input.tmux_window_name)
293
- : existing?.tmuxWindowName;
294
- const sanitizedPaneId = input.tmux_pane_id
295
- ? (0, redactSecrets_1.redactSecrets)(input.tmux_pane_id)
296
- : existing?.tmuxPaneId;
297
- await this.sessionStore.setSession({
298
- sessionId: resolved.sessionId,
299
- ...(existing?.label
300
- ? { label: existing.label }
301
- : resolved.sessionLabel
302
- ? { label: (0, redactSecrets_1.redactSecrets)(resolved.sessionLabel) }
303
- : {}),
304
- ...(existing?.cwd ? { cwd: existing.cwd } : { cwd: resolved.cwd }),
305
- ...(existing?.linkedSessionId
306
- ? { linkedSessionId: existing.linkedSessionId }
307
- : {}),
308
- ...(existing?.activeProjectUuid
309
- ? { activeProjectUuid: existing.activeProjectUuid }
310
- : {}),
311
- ...(existing?.activeProjectName
312
- ? { activeProjectName: existing.activeProjectName }
313
- : {}),
314
- ...(existing?.task ? { task: existing.task } : {}),
315
- ...(existing?.summary ? { summary: existing.summary } : {}),
316
- ...(existing?.files ? { files: existing.files } : {}),
317
- ...(existing?.decisions ? { decisions: existing.decisions } : {}),
318
- ...(existing?.risks ? { risks: existing.risks } : {}),
319
- ...(sanitizedSessionName
320
- ? { tmuxSessionName: sanitizedSessionName }
321
- : {}),
322
- ...(sanitizedWindowName ? { tmuxWindowName: sanitizedWindowName } : {}),
323
- ...(typeof input.tmux_window_index === "number"
324
- ? { tmuxWindowIndex: input.tmux_window_index }
325
- : typeof existing?.tmuxWindowIndex === "number"
326
- ? { tmuxWindowIndex: existing.tmuxWindowIndex }
327
- : {}),
328
- ...(sanitizedPaneId ? { tmuxPaneId: sanitizedPaneId } : {}),
329
- ...(typeof input.tmux_pane_index === "number"
330
- ? { tmuxPaneIndex: input.tmux_pane_index }
331
- : typeof existing?.tmuxPaneIndex === "number"
332
- ? { tmuxPaneIndex: existing.tmuxPaneIndex }
333
- : {}),
334
- tmuxTarget: sanitizedTarget,
335
- ...(existing?.lastTmuxNudgeAt
336
- ? { lastTmuxNudgeAt: existing.lastTmuxNudgeAt }
337
- : {}),
338
- updatedAt,
339
- });
340
- this.projectIdentityResolver.persistSessionMarker({
341
- cwd: resolved.cwd,
342
- sessionId: resolved.sessionId,
343
- sessionLabel: existing?.label || resolved.sessionLabel,
344
- });
345
- this.logger.info("Session tmux target saved", {
346
- sessionId: resolved.sessionId,
347
- sessionIdDerived: resolved.sessionIdDerived,
348
- tmuxSessionName: sanitizedSessionName,
349
- tmuxWindowName: sanitizedWindowName,
350
- tmuxWindowIndex: input.tmux_window_index,
351
- tmuxPaneId: sanitizedPaneId,
352
- tmuxPaneIndex: input.tmux_pane_index,
353
- tmuxTarget: sanitizedTarget,
354
- });
355
- return {
356
- session_id: resolved.sessionId,
357
- tmux_target: sanitizedTarget,
358
- ...(sanitizedSessionName
359
- ? { tmux_session_name: sanitizedSessionName }
360
- : {}),
361
- ...(sanitizedWindowName
362
- ? { tmux_window_name: sanitizedWindowName }
363
- : {}),
364
- ...(typeof input.tmux_window_index === "number"
365
- ? { tmux_window_index: input.tmux_window_index }
366
- : {}),
367
- ...(sanitizedPaneId ? { tmux_pane_id: sanitizedPaneId } : {}),
368
- ...(typeof input.tmux_pane_index === "number"
369
- ? { tmux_pane_index: input.tmux_pane_index }
370
- : {}),
371
- status_message: "tmux target saved for this session. For a paired session, the service can now nudge this tmux pane when a new non-reply Telegram message is stored in inbox.",
372
- };
373
- }
374
- async getTmuxTarget(input) {
375
- const resolved = this.projectIdentityResolver.resolveSessionDefaults(input);
376
- const session = await this.sessionStore.getSession(resolved.sessionId);
377
- const configured = Boolean(session?.tmuxTarget);
378
- this.logger.debug("Session tmux target requested", {
379
- sessionId: resolved.sessionId,
380
- sessionIdDerived: resolved.sessionIdDerived,
381
- configured,
382
- });
383
- return {
384
- session_id: resolved.sessionId,
385
- configured,
386
- ...(session?.tmuxTarget ? { tmux_target: session.tmuxTarget } : {}),
387
- ...(session?.tmuxSessionName
388
- ? { tmux_session_name: session.tmuxSessionName }
389
- : {}),
390
- ...(session?.tmuxWindowName
391
- ? { tmux_window_name: session.tmuxWindowName }
392
- : {}),
393
- ...(typeof session?.tmuxWindowIndex === "number"
394
- ? { tmux_window_index: session.tmuxWindowIndex }
395
- : {}),
396
- ...(session?.tmuxPaneId ? { tmux_pane_id: session.tmuxPaneId } : {}),
397
- ...(typeof session?.tmuxPaneIndex === "number"
398
- ? { tmux_pane_index: session.tmuxPaneIndex }
399
- : {}),
400
- ...(session?.lastTmuxNudgeAt
401
- ? { last_nudge_at: session.lastTmuxNudgeAt }
402
- : {}),
403
- status_message: configured
404
- ? "tmux target is configured for this session."
405
- : "tmux target is not configured for this session.",
406
- };
407
- }
408
250
  }
409
251
  exports.SessionContextService = SessionContextService;
@@ -18,7 +18,7 @@ class SetSessionContextTool {
18
18
  register(server) {
19
19
  server.registerTool("set_session_context", {
20
20
  title: "Set Session Context",
21
- description: "Save compact reusable context for the session: current task, summary, decisions, files, and risks. Use this to leave a short durable working state for later Telegram-driven continuation.",
21
+ description: "Save compact reusable context for the current console: current task, summary, decisions, files, and risks. Use this to leave a short durable working state for later gateway-routed continuation.",
22
22
  inputSchema: schema_1.setSessionContextInputSchema,
23
23
  outputSchema: schema_1.setSessionContextOutputSchema,
24
24
  }, async (args) => {
@@ -0,0 +1,96 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TerminalBufferService = void 0;
4
+ const relay_1 = require("../../../app/webapp/relay");
5
+ const client_1 = require("../../../shared/integrations/terminal/client");
6
+ const transportUtils_1 = require("../../../shared/integrations/telegram/transportUtils");
7
+ class TerminalBufferService {
8
+ config;
9
+ sessionStore;
10
+ logger;
11
+ projectIdentityResolver;
12
+ remoteConsoleInvoker;
13
+ constructor(config, sessionStore, logger, projectIdentityResolver, remoteConsoleInvoker) {
14
+ this.config = config;
15
+ this.sessionStore = sessionStore;
16
+ this.logger = logger;
17
+ this.projectIdentityResolver = projectIdentityResolver;
18
+ this.remoteConsoleInvoker = remoteConsoleInvoker;
19
+ }
20
+ async captureBuffer(input) {
21
+ const resolved = this.projectIdentityResolver.resolveSessionDefaults(input);
22
+ const remote = await this.remoteConsoleInvoker?.invokeForRelaySession(resolved.sessionId, "telegramMcp.terminalBuffer.captureBufferRemote", input);
23
+ if (remote) {
24
+ return remote;
25
+ }
26
+ const session = await this.sessionStore.getSession(resolved.sessionId);
27
+ const target = session?.terminalTarget?.trim();
28
+ if (!target) {
29
+ throw new Error("terminal target is not configured for this session");
30
+ }
31
+ const paneStart = await this.resolveCaptureStart(target, input.scope);
32
+ const stdout = await (0, client_1.captureTerminalPaneRange)(this.config.terminal, target, paneStart, false);
33
+ const capturedAt = new Date().toISOString();
34
+ const scopeDescription = this.describeCaptureScope(input.scope);
35
+ const titleBase = session?.label ?? resolved.sessionLabel ?? resolved.sessionId;
36
+ const filenameBase = (0, transportUtils_1.slugifyFilenamePart)(titleBase) || "session-buffer";
37
+ const timestamp = capturedAt.replace(/[:.]/g, "-");
38
+ const filename = `${filenameBase}-${timestamp}.md`;
39
+ const markdownContent = [
40
+ "# Terminal Buffer",
41
+ "",
42
+ `- Session: ${session?.label ?? resolved.sessionLabel ?? resolved.sessionId}`,
43
+ `- Session ID: ${resolved.sessionId}`,
44
+ `- terminal target: ${target}`,
45
+ `- Capture scope: ${scopeDescription}`,
46
+ `- Captured at: ${capturedAt}`,
47
+ "",
48
+ "```text",
49
+ stdout.replaceAll("\u0000", ""),
50
+ "```",
51
+ "",
52
+ ].join("\n");
53
+ this.logger.info("Terminal buffer captured", {
54
+ sessionId: resolved.sessionId,
55
+ terminalTarget: target,
56
+ captureMode: input.scope.mode,
57
+ scopeDescription,
58
+ isRelay: Boolean((0, relay_1.parseLiveRelaySessionId)(resolved.sessionId)),
59
+ });
60
+ return {
61
+ session_id: resolved.sessionId,
62
+ ...(session?.label ?? resolved.sessionLabel
63
+ ? { session_label: session?.label ?? resolved.sessionLabel }
64
+ : {}),
65
+ terminal_target: target,
66
+ filename,
67
+ markdown_content: markdownContent,
68
+ capture_mode: input.scope.mode,
69
+ scope_description: scopeDescription,
70
+ };
71
+ }
72
+ async resolveCaptureStart(target, scope) {
73
+ if (scope.mode === "full") {
74
+ return "-";
75
+ }
76
+ if (scope.mode === "lines") {
77
+ return `-${scope.lines}`;
78
+ }
79
+ const height = await (0, client_1.getTerminalWindowHeight)(this.config.terminal, target);
80
+ if (typeof height !== "number" || height <= 0) {
81
+ return `-${this.config.terminal.captureLines}`;
82
+ }
83
+ return `-${height}`;
84
+ }
85
+ describeCaptureScope(scope) {
86
+ switch (scope.mode) {
87
+ case "visible":
88
+ return "visible pane";
89
+ case "lines":
90
+ return `last ${scope.lines} lines`;
91
+ case "full":
92
+ return "full history";
93
+ }
94
+ }
95
+ }
96
+ exports.TerminalBufferService = TerminalBufferService;
@@ -0,0 +1,97 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TerminalInputService = void 0;
4
+ const client_1 = require("../../../shared/integrations/terminal/client");
5
+ function buildSubmittedText(input) {
6
+ const text = input.text.trim();
7
+ const attachments = (input.attachments ?? []).filter((item) => typeof item === "string" && item.trim().length > 0);
8
+ if (attachments.length === 0) {
9
+ return text;
10
+ }
11
+ return `${text} [attachments saved: ${attachments.join(", ")}]`.trim();
12
+ }
13
+ class TerminalInputService {
14
+ config;
15
+ sessionStore;
16
+ logger;
17
+ constructor(config, sessionStore, logger) {
18
+ this.config = config;
19
+ this.sessionStore = sessionStore;
20
+ this.logger = logger;
21
+ }
22
+ async submitHumanMessage(input) {
23
+ const sessionId = input.session_id.trim();
24
+ if (!sessionId) {
25
+ throw new Error("session_id is required");
26
+ }
27
+ const session = await this.sessionStore.getSession(sessionId);
28
+ const terminalTarget = (0, client_1.ensureTerminalTargetForSession)(this.config.terminal, {
29
+ sessionId,
30
+ ...(typeof session?.cwd === "string" ? { cwd: session.cwd } : {}),
31
+ ...(typeof session?.terminalTarget === "string"
32
+ ? { target: session.terminalTarget }
33
+ : {}),
34
+ });
35
+ if (!terminalTarget) {
36
+ throw new Error("terminal target is not configured for this console");
37
+ }
38
+ const submittedText = buildSubmittedText(input);
39
+ if (!submittedText) {
40
+ throw new Error("text is required");
41
+ }
42
+ if (!session || session.terminalTarget !== terminalTarget) {
43
+ await this.sessionStore.setSession({
44
+ sessionId,
45
+ ...(typeof session?.label === "string" ? { label: session.label } : {}),
46
+ ...(typeof session?.cwd === "string" ? { cwd: session.cwd } : {}),
47
+ ...(typeof session?.activeProjectUuid === "string"
48
+ ? { activeProjectUuid: session.activeProjectUuid }
49
+ : {}),
50
+ ...(typeof session?.activeProjectName === "string"
51
+ ? { activeProjectName: session.activeProjectName }
52
+ : {}),
53
+ ...(typeof session?.task === "string" ? { task: session.task } : {}),
54
+ ...(typeof session?.summary === "string"
55
+ ? { summary: session.summary }
56
+ : {}),
57
+ ...(Array.isArray(session?.files) ? { files: session.files } : {}),
58
+ ...(Array.isArray(session?.decisions)
59
+ ? { decisions: session.decisions }
60
+ : {}),
61
+ ...(Array.isArray(session?.risks) ? { risks: session.risks } : {}),
62
+ terminalTarget: terminalTarget,
63
+ ...(typeof session?.lastTerminalNudgeAt === "string"
64
+ ? { lastTerminalNudgeAt: session.lastTerminalNudgeAt }
65
+ : {}),
66
+ ...(typeof session?.lastSeenToolsHash === "string"
67
+ ? { lastSeenToolsHash: session.lastSeenToolsHash }
68
+ : {}),
69
+ ...(typeof session?.lastNotifiedToolsHash === "string"
70
+ ? { lastNotifiedToolsHash: session.lastNotifiedToolsHash }
71
+ : {}),
72
+ updatedAt: new Date().toISOString(),
73
+ });
74
+ }
75
+ this.logger.info("Submitting direct human terminal message", {
76
+ sessionId,
77
+ terminalTarget,
78
+ sourceLabel: input.source_label,
79
+ attachmentCount: input.attachments?.length ?? 0,
80
+ textLength: submittedText.length,
81
+ });
82
+ await (0, client_1.sendTerminalLiteralLine)(this.config.terminal, terminalTarget, submittedText);
83
+ this.logger.info("Direct human terminal message submitted", {
84
+ sessionId,
85
+ terminalTarget,
86
+ sourceLabel: input.source_label,
87
+ attachmentCount: input.attachments?.length ?? 0,
88
+ });
89
+ return {
90
+ ok: true,
91
+ session_id: sessionId,
92
+ terminal_target: terminalTarget,
93
+ submitted_text: submittedText,
94
+ };
95
+ }
96
+ }
97
+ exports.TerminalInputService = TerminalInputService;