@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
@@ -0,0 +1,426 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TransportProjectView = void 0;
4
+ const node_buffer_1 = require("node:buffer");
5
+ const grammy_1 = require("grammy");
6
+ const relay_1 = require("../../../app/webapp/relay");
7
+ const collabUi_1 = require("./collabUi");
8
+ const transportMenuText_1 = require("./transportMenuText");
9
+ const transportUtils_1 = require("./transportUtils");
10
+ class TransportProjectView {
11
+ host;
12
+ constructor(host) {
13
+ this.host = host;
14
+ }
15
+ async buildProjectsMenuText(ctx) {
16
+ const locale = await this.host.resolveLocaleForContext(ctx);
17
+ const { session, projects } = await this.host.loadProjectsContext(ctx);
18
+ if (!this.host.config.distributed.gatewayPublicUrl) {
19
+ return (0, transportMenuText_1.buildProjectsMenuText)({
20
+ title: this.host.t(locale, "menu:collab.screen.title"),
21
+ gatewayNotConfiguredLine: this.host.t(locale, "menu:collab.screen.gateway_not_configured"),
22
+ });
23
+ }
24
+ if (!session || !projects) {
25
+ return this.host.t(locale, "menu:collab.screen.unavailable");
26
+ }
27
+ return (0, transportMenuText_1.buildProjectsMenuText)({
28
+ title: this.host.t(locale, "menu:collab.screen.title"),
29
+ activeSessionLine: this.host.t(locale, "menu:collab.screen.active_session", {
30
+ sessionName: session.label ?? session.sessionId,
31
+ }),
32
+ openProjectLine: session.activeProjectName
33
+ ? this.host.t(locale, "menu:collab.screen.open_project", {
34
+ projectName: session.activeProjectName,
35
+ })
36
+ : this.host.t(locale, "menu:collab.screen.open_project_none"),
37
+ projectCountLine: this.host.t(locale, "menu:collab.screen.project_count", {
38
+ count: projects.length,
39
+ }),
40
+ inviteHintLine: this.host.t(locale, "menu:collab.screen.invite_hint"),
41
+ });
42
+ }
43
+ async buildCollabToolsMenuText(ctx) {
44
+ const locale = await this.host.resolveLocaleForContext(ctx);
45
+ const principal = this.host.getPrincipalFromContext(ctx);
46
+ if (!principal || !this.host.config.distributed.gatewayPublicUrl) {
47
+ return this.host.t(locale, "menu:collab.screen.gateway_not_configured");
48
+ }
49
+ const { session } = await this.host.loadProjectsContext(ctx);
50
+ if (!session) {
51
+ return this.host.t(locale, "common:errors.no_active_session");
52
+ }
53
+ const projects = await this.host.listGatewayProjects(principal);
54
+ if (projects.length === 0) {
55
+ return [
56
+ this.host.t(locale, "menu:collab.screen.tools_title"),
57
+ "",
58
+ this.host.t(locale, "menu:collab.screen.active_session", {
59
+ sessionName: session.label ?? session.sessionId,
60
+ }),
61
+ "",
62
+ this.host.t(locale, "menu:collab.screen.tools_empty"),
63
+ ].join("\n");
64
+ }
65
+ const targets = await this.host.collectCollabBroadcastTargets(principal, session.sessionId);
66
+ const uniqueCount = targets.localTargetSessionIds.length + targets.remoteTargets.length;
67
+ return (0, transportMenuText_1.buildCollabToolsMenuText)({
68
+ title: this.host.t(locale, "menu:collab.screen.tools_title"),
69
+ activeSessionLine: this.host.t(locale, "menu:collab.screen.active_session", {
70
+ sessionName: session.label ?? session.sessionId,
71
+ }),
72
+ projectCountLine: this.host.t(locale, "menu:collab.screen.tools_project_count", {
73
+ count: projects.length,
74
+ }),
75
+ sessionCountLine: this.host.t(locale, "menu:collab.screen.tools_session_count", {
76
+ count: uniqueCount,
77
+ }),
78
+ broadcastLine: this.host.t(locale, "menu:collab.screen.tools_broadcast"),
79
+ historyLine: this.host.t(locale, "menu:collab.screen.tools_history"),
80
+ hintLine: this.host.t(locale, "menu:broadcast.collab_hint"),
81
+ });
82
+ }
83
+ async buildCollabDeleteMenuText(ctx) {
84
+ const locale = await this.host.resolveLocaleForContext(ctx);
85
+ const { session, projects } = await this.host.loadProjectsContext(ctx);
86
+ if (!this.host.config.distributed.gatewayPublicUrl) {
87
+ return this.host.t(locale, "menu:collab.screen.gateway_not_configured");
88
+ }
89
+ if (!session || !projects) {
90
+ return this.host.t(locale, "menu:collab.screen.unavailable");
91
+ }
92
+ const ownerCount = projects.filter((project) => project.role === "owner").length;
93
+ return (0, transportMenuText_1.buildCollabDeleteMenuText)({
94
+ title: this.host.t(locale, "menu:project.delete_menu_title"),
95
+ activeSessionLine: this.host.t(locale, "menu:project.active_session", {
96
+ sessionName: session.label ?? session.sessionId,
97
+ }),
98
+ totalCountLine: this.host.t(locale, "menu:project.total_count", {
99
+ count: projects.length,
100
+ }),
101
+ ownerCountLine: this.host.t(locale, "menu:project.owner_count", {
102
+ count: ownerCount,
103
+ }),
104
+ chooseLine: this.host.t(locale, "menu:project.delete_choose"),
105
+ bodyLine: this.host.t(locale, "menu:project.delete_body"),
106
+ ownerHintLine: this.host.t(locale, "menu:project.delete_owner_hint"),
107
+ });
108
+ }
109
+ async showProjectsMenu(ctx, introText) {
110
+ this.host.setCurrentAttachmentTargetForContext(ctx, null);
111
+ const text = await this.buildProjectsMenuText(ctx);
112
+ await this.host.renderMenuScreen(ctx, introText ? `${introText}\n\n${text}` : text, { kind: "menu" }, this.host.projectsMenu);
113
+ }
114
+ async showCollabToolsMenu(ctx, introText) {
115
+ const text = await this.buildCollabToolsMenuText(ctx);
116
+ await this.host.renderMenuScreen(ctx, introText ? `${introText}\n\n${text}` : text, { kind: "menu" }, this.host.collabToolsMenu);
117
+ }
118
+ async showCollabDeleteMenu(ctx, introText) {
119
+ const text = await this.buildCollabDeleteMenuText(ctx);
120
+ await this.host.renderMenuScreen(ctx, introText ? `${introText}\n\n${text}` : text, { kind: "menu" }, this.host.collabDeleteMenu);
121
+ }
122
+ buildCollabHistoryMarkdown(input) {
123
+ const locale = input.locale ?? "en";
124
+ const lines = [
125
+ this.host.t(locale, "menu:history.title"),
126
+ "",
127
+ this.host.t(locale, "menu:history.session", {
128
+ sessionName: input.sessionLabel,
129
+ }),
130
+ `Generated at: ${new Date().toISOString()}`,
131
+ "",
132
+ ];
133
+ if (input.history.length === 0) {
134
+ lines.push(this.host.t(locale, "menu:history.empty"));
135
+ lines.push("");
136
+ return lines.join("\n");
137
+ }
138
+ lines.push("Last 5 events:");
139
+ lines.push("");
140
+ for (const item of input.history) {
141
+ lines.push(`## ${item.kind}`);
142
+ lines.push(`- Time: ${item.created_at}`);
143
+ lines.push(`- Direction: ${item.direction}`);
144
+ lines.push(`- Route: ${item.from_label} -> ${item.to_label}`);
145
+ if (item.project_name) {
146
+ lines.push(this.host.t(locale, "menu:history.project", {
147
+ projectName: item.project_name,
148
+ }));
149
+ }
150
+ if (item.delivery_status) {
151
+ lines.push(`- Status: ${item.delivery_status}`);
152
+ }
153
+ lines.push(`- Summary: ${item.summary || "(empty)"}`);
154
+ lines.push("");
155
+ }
156
+ return lines.join("\n");
157
+ }
158
+ async handleCollabHistoryExport(ctx) {
159
+ const locale = await this.host.resolveLocaleForContext(ctx);
160
+ const { principal, session } = await this.host.loadProjectsContext(ctx);
161
+ if (!this.host.config.distributed.gatewayPublicUrl || !principal || !session) {
162
+ await ctx.answerCallbackQuery({
163
+ text: this.host.t(locale, "menu:collab.screen.unavailable"),
164
+ show_alert: true,
165
+ });
166
+ return;
167
+ }
168
+ const history = await this.host.listGatewaySessionHistory(principal, session.sessionId);
169
+ const markdown = this.buildCollabHistoryMarkdown({
170
+ locale,
171
+ sessionLabel: session.label ?? session.sessionId,
172
+ history,
173
+ });
174
+ const fileName = `collab-history-${(0, transportUtils_1.slugifyFilenamePart)(session.label ?? session.sessionId) || "session"}.md`;
175
+ await this.host.replyDocumentWithRetry(ctx, new grammy_1.InputFile(node_buffer_1.Buffer.from(markdown, "utf8"), fileName), {
176
+ caption: this.host.t(locale, "menu:history.caption", {
177
+ sessionName: session.label ?? session.sessionId,
178
+ }),
179
+ }, {
180
+ kind: "menu",
181
+ sessionId: session.sessionId,
182
+ });
183
+ await ctx.answerCallbackQuery({
184
+ text: this.host.t(locale, "menu:collab.buttons.history"),
185
+ });
186
+ }
187
+ async showProjectDetail(ctx, input) {
188
+ await this.showProjectMembers(ctx, input);
189
+ }
190
+ async showProjectMembers(ctx, input, options) {
191
+ this.host.setCurrentAttachmentTargetForContext(ctx, null);
192
+ const principal = this.host.getPrincipalFromContext(ctx);
193
+ if (!principal) {
194
+ throw new Error("Telegram identity is unavailable.");
195
+ }
196
+ await this.host.ensureOpenedProjectIsActive({
197
+ principal,
198
+ sessionId: input.sessionId,
199
+ projectUuid: input.projectUuid,
200
+ projectName: input.projectName,
201
+ });
202
+ const screen = await this.buildProjectMembersScreen(input, options);
203
+ if (ctx.callbackQuery?.message) {
204
+ await this.host.editText(ctx, screen.text, { kind: "menu", sessionId: input.sessionId }, { parse_mode: "HTML", reply_markup: screen.keyboard });
205
+ if (ctx.chat && "message_id" in ctx.callbackQuery.message) {
206
+ await this.host.maintenanceStore.setProjectMenuViewState({
207
+ sessionId: input.sessionId,
208
+ projectUuid: input.projectUuid,
209
+ telegramChatId: ctx.chat.id,
210
+ telegramMessageId: ctx.callbackQuery.message.message_id,
211
+ updatedAt: new Date().toISOString(),
212
+ });
213
+ }
214
+ return;
215
+ }
216
+ const sent = await this.host.replyText(ctx, screen.text, { kind: "menu", sessionId: input.sessionId }, { parse_mode: "HTML", reply_markup: screen.keyboard });
217
+ if (sent && "message_id" in sent && ctx.chat) {
218
+ await this.host.maintenanceStore.setProjectMenuViewState({
219
+ sessionId: input.sessionId,
220
+ projectUuid: input.projectUuid,
221
+ telegramChatId: ctx.chat.id,
222
+ telegramMessageId: sent.message_id,
223
+ updatedAt: new Date().toISOString(),
224
+ });
225
+ }
226
+ }
227
+ async showProjectMemberDetail(ctx, input) {
228
+ const locale = await this.host.resolveLocaleForContext(ctx);
229
+ const principal = this.host.getPrincipalFromContext(ctx);
230
+ if (principal) {
231
+ await this.host.ensureOpenedProjectIsActive({
232
+ principal,
233
+ sessionId: input.sessionId,
234
+ projectUuid: input.projectUuid,
235
+ projectName: input.projectName,
236
+ });
237
+ this.host.setCurrentAttachmentTargetForContext(ctx, {
238
+ sessionId: input.sessionId,
239
+ targetSessionId: input.targetSessionId,
240
+ targetSessionLabel: input.targetSessionLabel,
241
+ projectUuid: input.projectUuid,
242
+ });
243
+ }
244
+ const session = await this.host.sessionStore.getSession(input.sessionId);
245
+ const actor = this.host.getGatewayActorFromContext(ctx);
246
+ const sourceClientUuid = this.host.config.distributed.gatewayPublicUrl && principal
247
+ ? await this.host.ensureGatewayClientUuid(principal, actor)
248
+ : null;
249
+ const text = (0, collabUi_1.buildProjectMemberDetailText)({
250
+ projectName: input.projectName,
251
+ sourceLabel: session?.label ?? input.sessionId,
252
+ targetLabel: input.targetSessionLabel,
253
+ });
254
+ const payloadKey = await this.host.createProjectMemberMenuPayload(input.sessionId, input.projectUuid, input.targetSessionId, input.targetSessionLabel, {
255
+ ...(input.targetClientUuid
256
+ ? { targetClientUuid: input.targetClientUuid }
257
+ : {}),
258
+ ...(input.targetLocalSessionId
259
+ ? { targetLocalSessionId: input.targetLocalSessionId }
260
+ : {}),
261
+ });
262
+ const keyboard = new grammy_1.InlineKeyboard()
263
+ .text(this.host.t(locale, "menu:project.ask"), `project-member-note:question:${payloadKey}`)
264
+ .text(this.host.t(locale, "menu:project.share_button"), `project-member-note:share:${payloadKey}`)
265
+ .row();
266
+ if (this.host.config.webapp.enabled &&
267
+ this.host.config.distributed.gatewayPublicUrl &&
268
+ sourceClientUuid &&
269
+ input.targetClientUuid &&
270
+ input.targetLocalSessionId) {
271
+ keyboard.text("🖥 Live", `project-member-live:${payloadKey}`).row();
272
+ }
273
+ keyboard.text(this.host.t(locale, "menu:project.back_to_members"), `project-members:${input.projectUuid}`);
274
+ if (ctx.callbackQuery?.message) {
275
+ if (principal && ctx.chat && "message_id" in ctx.callbackQuery.message) {
276
+ this.host.webAppLaunchRegistry.set(principal.telegramUserId, input.sessionId, this.host.config.webapp.initDataTtlSeconds, {
277
+ telegramChatId: ctx.chat.id,
278
+ telegramMessageId: ctx.callbackQuery.message.message_id,
279
+ });
280
+ }
281
+ try {
282
+ await this.host.editText(ctx, text, { kind: "menu", sessionId: input.sessionId }, { parse_mode: "HTML", reply_markup: keyboard });
283
+ }
284
+ catch {
285
+ await this.host.replyText(ctx, text, { kind: "menu", sessionId: input.sessionId }, { parse_mode: "HTML", reply_markup: keyboard });
286
+ }
287
+ return;
288
+ }
289
+ const sent = await this.host.replyText(ctx, text, { kind: "menu", sessionId: input.sessionId }, { parse_mode: "HTML", reply_markup: keyboard });
290
+ if (principal) {
291
+ this.host.webAppLaunchRegistry.set(principal.telegramUserId, input.sessionId, this.host.config.webapp.initDataTtlSeconds, {
292
+ ...(ctx.chat ? { telegramChatId: ctx.chat.id } : {}),
293
+ ...(sent && "message_id" in sent
294
+ ? { telegramMessageId: sent.message_id }
295
+ : {}),
296
+ });
297
+ }
298
+ }
299
+ async showProjectMemberFiles(ctx, input) {
300
+ const locale = await this.host.resolveLocaleForContext(ctx);
301
+ const principal = this.host.getPrincipalFromContext(ctx);
302
+ if (principal) {
303
+ await this.host.ensureOpenedProjectIsActive({
304
+ principal,
305
+ sessionId: input.sessionId,
306
+ projectUuid: input.projectUuid,
307
+ projectName: input.projectName,
308
+ });
309
+ }
310
+ const files = await this.host.listActiveSessionFiles(input.sessionId);
311
+ const lines = [
312
+ this.host.t(locale, "menu:project.file_title"),
313
+ "",
314
+ this.host.t(locale, "menu:project.file_project", {
315
+ projectName: input.projectName,
316
+ }),
317
+ this.host.t(locale, "menu:project.file_recipient", {
318
+ label: input.targetSessionLabel,
319
+ }),
320
+ "",
321
+ files.length > 0
322
+ ? this.host.t(locale, "menu:project.file_choose")
323
+ : this.host.t(locale, "menu:project.file_none"),
324
+ ];
325
+ const keyboard = new grammy_1.InlineKeyboard();
326
+ for (const filePath of files) {
327
+ const meta = await this.host.xchangeFileMetaStore.getXchangeFileMeta(input.sessionId, filePath);
328
+ const label = this.host.formatFilePreviewLabel(filePath, meta).slice(0, 56);
329
+ const payloadKey = await this.host.createProjectMemberMenuPayload(input.sessionId, input.projectUuid, input.targetSessionId, input.targetSessionLabel, {
330
+ filePath,
331
+ ...(input.targetClientUuid
332
+ ? { targetClientUuid: input.targetClientUuid }
333
+ : {}),
334
+ ...(input.targetLocalSessionId
335
+ ? { targetLocalSessionId: input.targetLocalSessionId }
336
+ : {}),
337
+ });
338
+ keyboard.text(label, `project-member-open:${payloadKey}`).row();
339
+ }
340
+ keyboard.text(this.host.t(locale, "menu:project.back_to_session"), `project-member-open:${await this.host.createProjectMemberMenuPayload(input.sessionId, input.projectUuid, input.targetSessionId, input.targetSessionLabel, {
341
+ ...(input.targetClientUuid
342
+ ? { targetClientUuid: input.targetClientUuid }
343
+ : {}),
344
+ ...(input.targetLocalSessionId
345
+ ? { targetLocalSessionId: input.targetLocalSessionId }
346
+ : {}),
347
+ })}`);
348
+ const text = lines.join("\n");
349
+ if (ctx.callbackQuery?.message) {
350
+ try {
351
+ await this.host.editText(ctx, text, { kind: "menu", sessionId: input.sessionId }, { reply_markup: keyboard });
352
+ }
353
+ catch {
354
+ await this.host.replyText(ctx, text, { kind: "menu", sessionId: input.sessionId }, { reply_markup: keyboard });
355
+ }
356
+ return;
357
+ }
358
+ await this.host.replyText(ctx, text, { kind: "menu", sessionId: input.sessionId }, { reply_markup: keyboard });
359
+ }
360
+ async buildProjectMembersScreen(input, options) {
361
+ const session = await this.host.sessionStore.getSession(input.sessionId);
362
+ const binding = await this.host.bindingStore.getBinding(input.sessionId);
363
+ if (!binding) {
364
+ throw new Error("Binding is missing for project members screen.");
365
+ }
366
+ const locale = await this.host.resolveLocaleForTelegramUserId(binding.telegramUserId);
367
+ const sessions = await this.host.listGatewayProjectSessions({
368
+ telegramChatId: binding.telegramChatId,
369
+ telegramUserId: binding.telegramUserId,
370
+ }, input.projectUuid);
371
+ const activeRelay = (0, relay_1.parseLiveRelaySessionId)(input.sessionId);
372
+ const activeSessionId = activeRelay?.localSessionId ?? session?.sessionId ?? null;
373
+ const activeClientUuid = activeRelay?.clientUuid ?? null;
374
+ const selectableMembers = sessions.filter((item) => item.local_session_id !== activeSessionId &&
375
+ item.client_uuid !== activeClientUuid);
376
+ const lines = [
377
+ this.host.t(locale, "menu:project.members_title", {
378
+ projectName: (0, transportUtils_1.escapeHtml)(input.projectName),
379
+ }),
380
+ "",
381
+ `UUID: ${input.projectUuid}`,
382
+ `Invite: <code>${(0, transportUtils_1.escapeHtml)(input.inviteToken)}</code>`,
383
+ "",
384
+ this.host.t(locale, "menu:project.current_session", {
385
+ sessionName: (0, transportUtils_1.escapeHtml)(session?.label ?? input.sessionId),
386
+ }),
387
+ this.host.t(locale, "menu:project.other_sessions", {
388
+ count: selectableMembers.length,
389
+ }),
390
+ "",
391
+ selectableMembers.length > 0
392
+ ? options?.filePath
393
+ ? this.host.t(locale, "menu:project.choose_file_target")
394
+ : this.host.t(locale, "menu:project.choose_member_action")
395
+ : this.host.t(locale, "menu:project.no_other_active"),
396
+ ];
397
+ const keyboard = new grammy_1.InlineKeyboard();
398
+ for (const member of selectableMembers) {
399
+ const sessionLabel = member.label?.trim() || member.local_session_id;
400
+ const displayNameRaw = member.display_name?.trim() || null;
401
+ const telegramUsernameRaw = member.telegram_username?.trim() || null;
402
+ const systemUsernameRaw = member.system_username?.trim() || null;
403
+ const clientLabelRaw = member.client_label?.trim() || null;
404
+ const normalizedTelegramUsername = telegramUsernameRaw?.replace(/^@/u, "") || null;
405
+ const primaryIdentity = displayNameRaw ||
406
+ (normalizedTelegramUsername ? `@${normalizedTelegramUsername}` : null) ||
407
+ clientLabelRaw ||
408
+ systemUsernameRaw ||
409
+ sessionLabel;
410
+ const targetDisplayLabel = primaryIdentity !== sessionLabel
411
+ ? `${primaryIdentity}/${sessionLabel}`
412
+ : primaryIdentity;
413
+ const payloadKey = await this.host.createProjectMemberMenuPayload(input.sessionId, input.projectUuid, member.session_uuid, targetDisplayLabel, {
414
+ ...(options?.filePath ? { filePath: options.filePath } : {}),
415
+ targetClientUuid: member.client_uuid,
416
+ targetLocalSessionId: member.local_session_id,
417
+ });
418
+ keyboard.text(targetDisplayLabel.slice(0, 56), `project-member-open:${payloadKey}`).row();
419
+ }
420
+ keyboard
421
+ .text(this.host.t(locale, "menu:project.leave"), `project-leave:${input.projectUuid}`)
422
+ .text(this.host.t(locale, "menu:project.back_to_projects"), "project-back");
423
+ return { text: lines.join("\n"), keyboard };
424
+ }
425
+ }
426
+ exports.TransportProjectView = TransportProjectView;