@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,543 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.isPtyTarget = isPtyTarget;
40
+ exports.buildPtyTarget = buildPtyTarget;
41
+ exports.getPtyShellDisplayName = getPtyShellDisplayName;
42
+ exports.hasPtyTarget = hasPtyTarget;
43
+ exports.listPtyTargets = listPtyTargets;
44
+ exports.ensurePtySession = ensurePtySession;
45
+ exports.getPtyWindowHeight = getPtyWindowHeight;
46
+ exports.getPtyWindowSize = getPtyWindowSize;
47
+ exports.capturePtyRange = capturePtyRange;
48
+ exports.captureVisiblePty = captureVisiblePty;
49
+ exports.renderVisiblePtyHtml = renderVisiblePtyHtml;
50
+ exports.renderVisiblePtyAnsi = renderVisiblePtyAnsi;
51
+ exports.sendPtyAction = sendPtyAction;
52
+ exports.sendPtyText = sendPtyText;
53
+ exports.resizePtyTarget = resizePtyTarget;
54
+ exports.subscribePtyTarget = subscribePtyTarget;
55
+ exports.stopPtyTarget = stopPtyTarget;
56
+ exports.stopAllPtyTargets = stopAllPtyTargets;
57
+ const node_path_1 = __importDefault(require("node:path"));
58
+ const node_pty_1 = require("node-pty");
59
+ const XtermHeadless = __importStar(require("@xterm/headless"));
60
+ const PTY_TARGET_PREFIX = "pty:";
61
+ const sessions = new Map();
62
+ function getShellDisplayName(shell) {
63
+ const baseName = node_path_1.default.basename(shell.trim());
64
+ return baseName || shell.trim() || "bash";
65
+ }
66
+ function buildExitLine(record) {
67
+ const parts = ["[pty exited"];
68
+ if (typeof record.exitCode === "number") {
69
+ parts.push(`code=${record.exitCode}`);
70
+ }
71
+ if (typeof record.signal === "number") {
72
+ parts.push(`signal=${record.signal}`);
73
+ }
74
+ return `${parts.join(" ")}]`;
75
+ }
76
+ function createHeadlessTerminal(config) {
77
+ return new XtermHeadless.Terminal({
78
+ cols: config.cols,
79
+ rows: config.rows,
80
+ scrollback: config.scrollbackLines,
81
+ allowProposedApi: true,
82
+ });
83
+ }
84
+ function createSessionRecord(config, input) {
85
+ const target = input.target?.trim() || buildPtyTarget(input.sessionId);
86
+ const cwd = input.cwd?.trim() || process.cwd();
87
+ const terminal = createHeadlessTerminal(config);
88
+ const record = {
89
+ target,
90
+ sessionId: input.sessionId.trim(),
91
+ cwd,
92
+ shell: config.shell,
93
+ cols: config.cols,
94
+ rows: config.rows,
95
+ scrollbackLines: config.scrollbackLines,
96
+ terminal,
97
+ pendingWrite: Promise.resolve(),
98
+ pty: null,
99
+ exited: false,
100
+ };
101
+ const pty = (0, node_pty_1.spawn)(record.shell, [], {
102
+ name: "xterm-color",
103
+ cols: record.cols,
104
+ rows: record.rows,
105
+ cwd: record.cwd,
106
+ env: process.env,
107
+ });
108
+ pty.onData((data) => {
109
+ record.pendingWrite = record.pendingWrite.then(() => new Promise((resolve) => {
110
+ record.terminal.write(data, resolve);
111
+ }));
112
+ });
113
+ pty.onExit(({ exitCode, signal }) => {
114
+ record.pty = null;
115
+ record.exited = true;
116
+ record.exitCode = exitCode;
117
+ record.signal = signal;
118
+ record.pendingWrite = record.pendingWrite.then(() => new Promise((resolve) => {
119
+ record.terminal.writeln(buildExitLine(record), resolve);
120
+ }));
121
+ });
122
+ record.pty = pty;
123
+ return record;
124
+ }
125
+ function getSessionRecord(target) {
126
+ const record = sessions.get(target);
127
+ if (!record) {
128
+ throw new Error(`pty target is unavailable: ${target}`);
129
+ }
130
+ return record;
131
+ }
132
+ function ensureRunningPty(record) {
133
+ if (!record.pty || record.exited) {
134
+ throw new Error(`pty target is unavailable: ${record.target}`);
135
+ }
136
+ return record.pty;
137
+ }
138
+ function parseCaptureStart(start) {
139
+ const parsed = Number.parseInt(start.trim(), 10);
140
+ return Number.isFinite(parsed) ? parsed : null;
141
+ }
142
+ function snapshotTerminalLines(record) {
143
+ const buffer = record.terminal.buffer.active;
144
+ const lines = [];
145
+ for (let index = 0; index < buffer.length; index += 1) {
146
+ lines.push(buffer.getLine(index)?.translateToString(true) ?? "");
147
+ }
148
+ return lines;
149
+ }
150
+ function snapshotTerminalContentLines(record) {
151
+ const lines = snapshotTerminalLines(record);
152
+ while (lines.length > 0 && lines[lines.length - 1] === "") {
153
+ lines.pop();
154
+ }
155
+ return lines;
156
+ }
157
+ function escapeHtml(text) {
158
+ return text
159
+ .replace(/&/gu, "&amp;")
160
+ .replace(/</gu, "&lt;")
161
+ .replace(/>/gu, "&gt;");
162
+ }
163
+ function xtermColor(index) {
164
+ const base = [
165
+ "#000000",
166
+ "#800000",
167
+ "#008000",
168
+ "#808000",
169
+ "#000080",
170
+ "#800080",
171
+ "#008080",
172
+ "#c0c0c0",
173
+ "#808080",
174
+ "#ff0000",
175
+ "#00ff00",
176
+ "#ffff00",
177
+ "#0000ff",
178
+ "#ff00ff",
179
+ "#00ffff",
180
+ "#ffffff",
181
+ ];
182
+ if (index < 16) {
183
+ return base[index] ?? null;
184
+ }
185
+ if (index >= 16 && index <= 231) {
186
+ const value = index - 16;
187
+ const r = Math.floor(value / 36);
188
+ const g = Math.floor((value % 36) / 6);
189
+ const b = value % 6;
190
+ const steps = [0, 95, 135, 175, 215, 255];
191
+ return `rgb(${steps[r]},${steps[g]},${steps[b]})`;
192
+ }
193
+ if (index >= 232 && index <= 255) {
194
+ const gray = 8 + (index - 232) * 10;
195
+ return `rgb(${gray},${gray},${gray})`;
196
+ }
197
+ return null;
198
+ }
199
+ function rgbColor(value) {
200
+ const r = (value >> 16) & 0xff;
201
+ const g = (value >> 8) & 0xff;
202
+ const b = value & 0xff;
203
+ return `rgb(${r},${g},${b})`;
204
+ }
205
+ function cellColor(isDefault, isPalette, colorValue) {
206
+ if (isDefault) {
207
+ return null;
208
+ }
209
+ if (isPalette) {
210
+ return xtermColor(colorValue);
211
+ }
212
+ return rgbColor(colorValue);
213
+ }
214
+ function styleStateEquals(left, right) {
215
+ return (left.fg === right.fg &&
216
+ left.bg === right.bg &&
217
+ left.bold === right.bold &&
218
+ left.underline === right.underline &&
219
+ left.italic === right.italic &&
220
+ left.inverse === right.inverse);
221
+ }
222
+ function styleStateToHtml(state) {
223
+ const fg = state.inverse ? state.bg : state.fg;
224
+ const bg = state.inverse ? state.fg : state.bg;
225
+ const classes = [];
226
+ const styles = [];
227
+ if (state.bold) {
228
+ classes.push("ansi-bold");
229
+ }
230
+ if (state.underline) {
231
+ classes.push("ansi-underline");
232
+ }
233
+ if (state.italic) {
234
+ styles.push("font-style:italic");
235
+ }
236
+ if (fg) {
237
+ styles.push(`color:${fg}`);
238
+ }
239
+ if (bg) {
240
+ styles.push(`background:${bg}`);
241
+ }
242
+ if (classes.length === 0 && styles.length === 0) {
243
+ return "";
244
+ }
245
+ const attrs = [];
246
+ if (classes.length > 0) {
247
+ attrs.push(`class="${classes.join(" ")}"`);
248
+ }
249
+ if (styles.length > 0) {
250
+ attrs.push(`style="${styles.join(";")}"`);
251
+ }
252
+ return attrs.join(" ");
253
+ }
254
+ function getVisibleWindowRange(record, fallbackLines, visibleScreens) {
255
+ const buffer = record.terminal.buffer.active;
256
+ const lineCount = Math.max(1, (record.rows > 0 ? record.rows : fallbackLines) * Math.max(1, visibleScreens));
257
+ const start = Math.max(0, buffer.viewportY + record.rows - lineCount);
258
+ const end = Math.min(buffer.length, start + lineCount);
259
+ return { start, end };
260
+ }
261
+ function renderVisiblePtyHtmlFromRecord(record, fallbackLines, visibleScreens) {
262
+ const buffer = record.terminal.buffer.active;
263
+ const { start, end } = getVisibleWindowRange(record, fallbackLines, visibleScreens);
264
+ const lines = [];
265
+ for (let y = start; y < end; y += 1) {
266
+ const line = buffer.getLine(y);
267
+ if (!line) {
268
+ lines.push("");
269
+ continue;
270
+ }
271
+ const parts = [];
272
+ let chunk = "";
273
+ let currentStyle = null;
274
+ const flushChunk = () => {
275
+ if (!chunk) {
276
+ return;
277
+ }
278
+ const escaped = escapeHtml(chunk);
279
+ if (!currentStyle) {
280
+ parts.push(escaped);
281
+ }
282
+ else {
283
+ const attrs = styleStateToHtml(currentStyle);
284
+ parts.push(attrs ? `<span ${attrs}>${escaped}</span>` : escaped);
285
+ }
286
+ chunk = "";
287
+ };
288
+ for (let x = 0; x < record.cols; x += 1) {
289
+ const cell = line.getCell(x);
290
+ if (!cell || cell.getWidth() === 0) {
291
+ continue;
292
+ }
293
+ const nextStyle = {
294
+ fg: cellColor(cell.isFgDefault(), cell.isFgPalette(), cell.getFgColor()),
295
+ bg: cellColor(cell.isBgDefault(), cell.isBgPalette(), cell.getBgColor()),
296
+ bold: cell.isBold() > 0,
297
+ underline: cell.isUnderline() > 0,
298
+ italic: cell.isItalic() > 0,
299
+ inverse: cell.isInverse() > 0,
300
+ };
301
+ if (!currentStyle || !styleStateEquals(currentStyle, nextStyle)) {
302
+ flushChunk();
303
+ currentStyle = nextStyle;
304
+ }
305
+ chunk += cell.getChars() || " ";
306
+ }
307
+ flushChunk();
308
+ lines.push(parts.join(""));
309
+ }
310
+ return lines.join("\n");
311
+ }
312
+ function styleStateToSgrCodes(state) {
313
+ const codes = [0];
314
+ if (state.bold) {
315
+ codes.push(1);
316
+ }
317
+ if (state.italic) {
318
+ codes.push(3);
319
+ }
320
+ if (state.underline) {
321
+ codes.push(4);
322
+ }
323
+ if (state.inverse) {
324
+ codes.push(7);
325
+ }
326
+ const pushColor = (value, isBackground) => {
327
+ if (!value) {
328
+ return;
329
+ }
330
+ if (value.startsWith("#")) {
331
+ const normalized = value.slice(1);
332
+ if (normalized.length === 6) {
333
+ const numeric = Number.parseInt(normalized, 16);
334
+ const r = (numeric >> 16) & 0xff;
335
+ const g = (numeric >> 8) & 0xff;
336
+ const b = numeric & 0xff;
337
+ codes.push(isBackground ? 48 : 38, 2, r, g, b);
338
+ }
339
+ return;
340
+ }
341
+ const match = /^rgb\((\d+),(\d+),(\d+)\)$/u.exec(value);
342
+ if (!match) {
343
+ return;
344
+ }
345
+ codes.push(isBackground ? 48 : 38, 2, Number(match[1]), Number(match[2]), Number(match[3]));
346
+ };
347
+ pushColor(state.fg, false);
348
+ pushColor(state.bg, true);
349
+ return codes;
350
+ }
351
+ function renderVisiblePtyAnsiFromRecord(record, fallbackLines, visibleScreens) {
352
+ const buffer = record.terminal.buffer.active;
353
+ const { start, end } = getVisibleWindowRange(record, fallbackLines, visibleScreens);
354
+ const lines = [];
355
+ for (let y = start; y < end; y += 1) {
356
+ const line = buffer.getLine(y);
357
+ if (!line) {
358
+ lines.push("");
359
+ continue;
360
+ }
361
+ let row = "";
362
+ let currentStyle = null;
363
+ for (let x = 0; x < record.cols; x += 1) {
364
+ const cell = line.getCell(x);
365
+ if (!cell || cell.getWidth() === 0) {
366
+ continue;
367
+ }
368
+ const nextStyle = {
369
+ fg: cellColor(cell.isFgDefault(), cell.isFgPalette(), cell.getFgColor()),
370
+ bg: cellColor(cell.isBgDefault(), cell.isBgPalette(), cell.getBgColor()),
371
+ bold: cell.isBold() > 0,
372
+ underline: cell.isUnderline() > 0,
373
+ italic: cell.isItalic() > 0,
374
+ inverse: cell.isInverse() > 0,
375
+ };
376
+ if (!currentStyle || !styleStateEquals(currentStyle, nextStyle)) {
377
+ row += `\u001b[${styleStateToSgrCodes(nextStyle).join(";")}m`;
378
+ currentStyle = nextStyle;
379
+ }
380
+ row += cell.getChars() || " ";
381
+ }
382
+ if (currentStyle) {
383
+ row += "\u001b[0m";
384
+ }
385
+ lines.push(row.trimEnd());
386
+ }
387
+ return lines.join("\n");
388
+ }
389
+ function isPtyTarget(target) {
390
+ return typeof target === "string" && target.startsWith(PTY_TARGET_PREFIX);
391
+ }
392
+ function buildPtyTarget(sessionId) {
393
+ return `${PTY_TARGET_PREFIX}${sessionId.trim()}`;
394
+ }
395
+ function getPtyShellDisplayName(config) {
396
+ return getShellDisplayName(config.shell);
397
+ }
398
+ function hasPtyTarget(target) {
399
+ return sessions.has(target);
400
+ }
401
+ function listPtyTargets() {
402
+ return [...sessions.keys()];
403
+ }
404
+ function ensurePtySession(config, input) {
405
+ const target = input.target?.trim() || buildPtyTarget(input.sessionId);
406
+ const existing = sessions.get(target);
407
+ if (existing && existing.pty && !existing.exited) {
408
+ return target;
409
+ }
410
+ if (existing) {
411
+ existing.terminal.dispose();
412
+ }
413
+ const record = createSessionRecord(config, {
414
+ ...input,
415
+ target,
416
+ });
417
+ sessions.set(target, record);
418
+ return target;
419
+ }
420
+ function getPtyWindowHeight(target) {
421
+ const record = getSessionRecord(target);
422
+ return record.rows;
423
+ }
424
+ function getPtyWindowSize(target) {
425
+ const record = sessions.get(target);
426
+ if (!record) {
427
+ return null;
428
+ }
429
+ return {
430
+ cols: record.cols,
431
+ rows: record.rows,
432
+ };
433
+ }
434
+ async function capturePtyRange(target, start) {
435
+ const record = getSessionRecord(target);
436
+ await record.pendingWrite;
437
+ const captureStart = parseCaptureStart(start);
438
+ const lines = snapshotTerminalContentLines(record);
439
+ if (lines.length === 0) {
440
+ return "";
441
+ }
442
+ if (captureStart === null) {
443
+ return lines.join("\n");
444
+ }
445
+ if (captureStart < 0) {
446
+ return lines.slice(Math.max(0, lines.length + captureStart)).join("\n");
447
+ }
448
+ return lines.slice(captureStart).join("\n");
449
+ }
450
+ async function captureVisiblePty(target, fallbackLines, visibleScreens) {
451
+ const record = getSessionRecord(target);
452
+ await record.pendingWrite;
453
+ const buffer = record.terminal.buffer.active;
454
+ const lineCount = Math.max(1, (record.rows > 0 ? record.rows : fallbackLines) * Math.max(1, visibleScreens));
455
+ const start = Math.max(0, buffer.viewportY + record.rows - lineCount);
456
+ const end = Math.min(buffer.length, start + lineCount);
457
+ const lines = [];
458
+ for (let index = start; index < end; index += 1) {
459
+ lines.push(buffer.getLine(index)?.translateToString(true) ?? "");
460
+ }
461
+ return lines.join("\r\n");
462
+ }
463
+ async function renderVisiblePtyHtml(target, fallbackLines, visibleScreens) {
464
+ const record = getSessionRecord(target);
465
+ await record.pendingWrite;
466
+ return renderVisiblePtyHtmlFromRecord(record, fallbackLines, visibleScreens);
467
+ }
468
+ async function renderVisiblePtyAnsi(target, fallbackLines, visibleScreens) {
469
+ const record = getSessionRecord(target);
470
+ await record.pendingWrite;
471
+ return renderVisiblePtyAnsiFromRecord(record, fallbackLines, visibleScreens);
472
+ }
473
+ function sendPtyAction(target, action) {
474
+ const pty = ensureRunningPty(getSessionRecord(target));
475
+ const input = action === "up"
476
+ ? "\u001b[A"
477
+ : action === "down"
478
+ ? "\u001b[B"
479
+ : action === "enter"
480
+ ? "\r"
481
+ : action === "slash"
482
+ ? "/"
483
+ : action === "delete"
484
+ ? "\u007f"
485
+ : action === "tab"
486
+ ? "\t"
487
+ : action === "escape"
488
+ ? "\u001b"
489
+ : "\u0003";
490
+ pty.write(input);
491
+ }
492
+ function sendPtyText(target, text) {
493
+ const pty = ensureRunningPty(getSessionRecord(target));
494
+ pty.write(text);
495
+ }
496
+ function resizePtyTarget(target, cols, rows) {
497
+ const record = getSessionRecord(target);
498
+ const pty = ensureRunningPty(record);
499
+ record.cols = cols;
500
+ record.rows = rows;
501
+ record.terminal.resize(cols, rows);
502
+ pty.resize(cols, rows);
503
+ }
504
+ function subscribePtyTarget(target, input) {
505
+ const record = getSessionRecord(target);
506
+ const pty = ensureRunningPty(record);
507
+ const disposers = [];
508
+ if (input.onData) {
509
+ const disposable = pty.onData(input.onData);
510
+ disposers.push(() => {
511
+ disposable.dispose();
512
+ });
513
+ }
514
+ if (input.onExit) {
515
+ const disposable = pty.onExit(({ exitCode, signal, }) => {
516
+ input.onExit?.({ exitCode, signal });
517
+ });
518
+ disposers.push(() => {
519
+ disposable.dispose();
520
+ });
521
+ }
522
+ return () => {
523
+ for (const dispose of disposers) {
524
+ dispose();
525
+ }
526
+ };
527
+ }
528
+ function stopPtyTarget(target) {
529
+ const record = sessions.get(target);
530
+ if (!record) {
531
+ return false;
532
+ }
533
+ record.pty?.kill();
534
+ record.pty = null;
535
+ record.exited = true;
536
+ record.terminal.dispose();
537
+ return true;
538
+ }
539
+ function stopAllPtyTargets() {
540
+ for (const target of listPtyTargets()) {
541
+ stopPtyTarget(target);
542
+ }
543
+ }