@deadragdoll/tellymcp 0.0.11 → 0.0.13

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 (62) hide show
  1. package/README-ru.md +48 -0
  2. package/README.md +47 -0
  3. package/TOOLS.md +232 -3
  4. package/VERSION.md +2 -2
  5. package/dist/cli.js +109 -1
  6. package/dist/services/features/telegram-mcp/browser.service.js +38 -1
  7. package/dist/services/features/telegram-mcp/gateway-socket.service.js +10 -0
  8. package/dist/services/features/telegram-mcp/mcp-server.service.js +12 -0
  9. package/dist/services/features/telegram-mcp/src/app/bootstrap/runtime.js +14 -0
  10. package/dist/services/features/telegram-mcp/src/app/config/env.js +13 -0
  11. package/dist/services/features/telegram-mcp/src/entities/request/model/schema.js +151 -2
  12. package/dist/services/features/telegram-mcp/src/features/browser/model/browserClickTool.js +1 -1
  13. package/dist/services/features/telegram-mcp/src/features/browser/model/browserDomTool.js +1 -1
  14. package/dist/services/features/telegram-mcp/src/features/browser/model/browserFillTool.js +1 -1
  15. package/dist/services/features/telegram-mcp/src/features/browser/model/browserInjectScriptTool.js +28 -0
  16. package/dist/services/features/telegram-mcp/src/features/browser/model/browserListAttachedInstancesTool.js +33 -0
  17. package/dist/services/features/telegram-mcp/src/features/browser/model/browserListTabsTool.js +33 -0
  18. package/dist/services/features/telegram-mcp/src/features/browser/model/browserOpenTool.js +1 -1
  19. package/dist/services/features/telegram-mcp/src/features/browser/model/browserPressTool.js +1 -1
  20. package/dist/services/features/telegram-mcp/src/features/browser/model/browserRecordingStartTool.js +28 -0
  21. package/dist/services/features/telegram-mcp/src/features/browser/model/browserRecordingStatusTool.js +28 -0
  22. package/dist/services/features/telegram-mcp/src/features/browser/model/browserRecordingStopTool.js +28 -0
  23. package/dist/services/features/telegram-mcp/src/features/browser/model/browserScreenshotTool.js +1 -1
  24. package/dist/services/features/telegram-mcp/src/features/browser/model/browserService.js +543 -9
  25. package/dist/services/features/telegram-mcp/src/features/browser-attach/model/browserRecordingBundle.js +502 -0
  26. package/dist/services/features/telegram-mcp/src/features/browser-attach/model/firefoxAttachRegistry.js +79 -0
  27. package/dist/services/features/telegram-mcp/src/features/browser-attach/model/firefoxAttachServer.js +559 -0
  28. package/dist/services/features/telegram-mcp/src/features/browser-attach/model/types.js +2 -0
  29. package/dist/services/features/telegram-mcp/src/features/distributed-gateway/model/gatewayHttpService.js +48 -0
  30. package/dist/services/features/telegram-mcp/src/shared/i18n/resources/en.js +5 -1
  31. package/dist/services/features/telegram-mcp/src/shared/i18n/resources/ru.js +5 -1
  32. package/dist/services/features/telegram-mcp/src/shared/integrations/redis/stateStore.js +56 -0
  33. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transport.js +37 -0
  34. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportConsoleRegistry.js +13 -7
  35. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportConstructorWiring.js +9 -0
  36. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportMenuShell.js +3 -0
  37. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportPayloadState.js +7 -0
  38. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportTerminalActions.js +231 -34
  39. package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportTerminalRuntime.js +61 -6
  40. package/dist/services/features/telegram-mcp/src/shared/lib/terminalPromptDetection.js +200 -28
  41. package/docs/STANDALONE-ru.md +42 -6
  42. package/docs/STANDALONE.md +42 -6
  43. package/package.json +6 -3
  44. package/packages/chrome-attach-extension/dist/background.js +1326 -0
  45. package/packages/chrome-attach-extension/dist/icon.svg +6 -0
  46. package/packages/chrome-attach-extension/dist/manifest.json +36 -0
  47. package/packages/chrome-attach-extension/dist/options.html +312 -0
  48. package/packages/chrome-attach-extension/dist/options.js +593 -0
  49. package/packages/chrome-attach-extension/dist/popup.html +93 -0
  50. package/packages/chrome-attach-extension/dist/popup.js +79 -0
  51. package/packages/chrome-attach-extension/dist/recorder-content.js +83 -0
  52. package/packages/chrome-attach-extension/dist/recorder-page.js +266 -0
  53. package/packages/firefox-attach-extension/README.md +13 -0
  54. package/packages/firefox-attach-extension/dist/background.js +1242 -0
  55. package/packages/firefox-attach-extension/dist/icon.svg +6 -0
  56. package/packages/firefox-attach-extension/dist/manifest.json +56 -0
  57. package/packages/firefox-attach-extension/dist/options.html +312 -0
  58. package/packages/firefox-attach-extension/dist/options.js +527 -0
  59. package/packages/firefox-attach-extension/dist/popup.html +93 -0
  60. package/packages/firefox-attach-extension/dist/popup.js +64 -0
  61. package/packages/firefox-attach-extension/dist/recorder-content.js +77 -0
  62. package/packages/firefox-attach-extension/dist/recorder-page.js +302 -0
@@ -0,0 +1,77 @@
1
+ (() => {
2
+ if (window.__tellyRecorderContentInstalled === true) {
3
+ return;
4
+ }
5
+ window.__tellyRecorderContentInstalled = true;
6
+
7
+ function emit(payload) {
8
+ try {
9
+ browser.runtime.sendMessage({
10
+ type: "telly_recording_page_event",
11
+ event: payload,
12
+ });
13
+ } catch {
14
+ // ignore
15
+ }
16
+ }
17
+
18
+ function snapshot(reason) {
19
+ if (window.top !== window) {
20
+ return;
21
+ }
22
+ emit({
23
+ kind: "page_snapshot",
24
+ source: "content",
25
+ reason,
26
+ at: new Date().toISOString(),
27
+ url: location.href,
28
+ title: document.title,
29
+ ready_state: document.readyState,
30
+ html: document.documentElement?.outerHTML || "",
31
+ });
32
+ }
33
+
34
+ window.addEventListener("message", (event) => {
35
+ if (event.source !== window) {
36
+ return;
37
+ }
38
+ if (!event.data || event.data.__tellyRecorderPageEvent !== true) {
39
+ return;
40
+ }
41
+ emit(event.data.payload);
42
+ });
43
+
44
+ const injection = document.createElement("script");
45
+ injection.src = browser.runtime.getURL("recorder-page.js");
46
+ injection.async = false;
47
+ (document.documentElement || document.head || document.body).appendChild(injection);
48
+ injection.addEventListener(
49
+ "load",
50
+ () => {
51
+ injection.remove();
52
+ },
53
+ { once: true },
54
+ );
55
+ injection.addEventListener(
56
+ "error",
57
+ () => {
58
+ emit({
59
+ kind: "console_event",
60
+ source: "content",
61
+ level: "error",
62
+ text: "Failed to load recorder-page.js",
63
+ url: location.href,
64
+ title: document.title,
65
+ });
66
+ injection.remove();
67
+ },
68
+ { once: true },
69
+ );
70
+
71
+ snapshot("recording-script-installed");
72
+ if (window.top === window) {
73
+ window.addEventListener("load", () => {
74
+ snapshot("window-load");
75
+ });
76
+ }
77
+ })();
@@ -0,0 +1,302 @@
1
+ (() => {
2
+ if (window.__tellyRecorderPageInstalled === true) {
3
+ return;
4
+ }
5
+ window.__tellyRecorderPageInstalled = true;
6
+
7
+ const MAX_TEXT_CHARS = 64 * 1024;
8
+ const truncateText = (value) => {
9
+ const text = String(value ?? "");
10
+ return text.length > MAX_TEXT_CHARS ? text.slice(0, MAX_TEXT_CHARS) : text;
11
+ };
12
+ const serializeValue = (value, depth = 0) => {
13
+ if (depth >= 2) return truncateText(value);
14
+ if (value === null || value === undefined) return value;
15
+ if (typeof value === "string") return truncateText(value);
16
+ if (typeof value === "number" || typeof value === "boolean") return value;
17
+ if (value instanceof Error) {
18
+ return {
19
+ name: value.name,
20
+ message: truncateText(value.message),
21
+ stack: truncateText(value.stack || ""),
22
+ };
23
+ }
24
+ if (Array.isArray(value)) {
25
+ return value.slice(0, 20).map((item) => serializeValue(item, depth + 1));
26
+ }
27
+ if (typeof value === "object") {
28
+ const output = {};
29
+ for (const [key, nested] of Object.entries(value).slice(0, 20)) {
30
+ output[key] = serializeValue(nested, depth + 1);
31
+ }
32
+ return output;
33
+ }
34
+ return truncateText(value);
35
+ };
36
+ const emit = (payload) => {
37
+ window.postMessage({ __tellyRecorderPageEvent: true, payload }, "*");
38
+ };
39
+ const emitConsole = (level, args, textOverride) => {
40
+ emit({
41
+ kind: "console_event",
42
+ source: "page",
43
+ at: new Date().toISOString(),
44
+ level,
45
+ text:
46
+ textOverride ||
47
+ truncateText(
48
+ args
49
+ .map((item) => {
50
+ if (typeof item === "string") return item;
51
+ try {
52
+ return JSON.stringify(item);
53
+ } catch {
54
+ return String(item);
55
+ }
56
+ })
57
+ .join(" "),
58
+ ),
59
+ args: args.map((item) => serializeValue(item)),
60
+ url: location.href,
61
+ title: document.title,
62
+ });
63
+ };
64
+ const headersToArray = (headers) => {
65
+ try {
66
+ return Array.from(headers.entries()).map(([name, value]) => ({ name, value }));
67
+ } catch {
68
+ return [];
69
+ }
70
+ };
71
+ const serializeRequestBody = async (request) => {
72
+ try {
73
+ const text = await request.clone().text();
74
+ if (!text) return { body_text: "" };
75
+ return {
76
+ body_text: truncateText(text),
77
+ body_truncated: text.length > MAX_TEXT_CHARS,
78
+ };
79
+ } catch {
80
+ return {};
81
+ }
82
+ };
83
+
84
+ for (const level of [
85
+ "log",
86
+ "info",
87
+ "warn",
88
+ "error",
89
+ "debug",
90
+ "trace",
91
+ "dir",
92
+ "dirxml",
93
+ "table",
94
+ ]) {
95
+ const original = console[level];
96
+ if (typeof original !== "function") {
97
+ continue;
98
+ }
99
+ console[level] = function patchedConsole(...args) {
100
+ try {
101
+ const textOverride =
102
+ level === "trace"
103
+ ? truncateText(new Error(args[0] ? String(args[0]) : "console.trace").stack || "")
104
+ : undefined;
105
+ emitConsole(level, args, textOverride);
106
+ } catch {
107
+ // ignore
108
+ }
109
+ return original.apply(this, args);
110
+ };
111
+ }
112
+
113
+ if (typeof console.assert === "function") {
114
+ const originalAssert = console.assert;
115
+ console.assert = function patchedAssert(condition, ...args) {
116
+ try {
117
+ if (!condition) {
118
+ emitConsole("assert", args, truncateText(args[0] ? String(args[0]) : "Assertion failed"));
119
+ }
120
+ } catch {
121
+ // ignore
122
+ }
123
+ return originalAssert.call(this, condition, ...args);
124
+ };
125
+ }
126
+
127
+ window.addEventListener("error", (event) => {
128
+ emit({
129
+ kind: "console_event",
130
+ source: "page",
131
+ at: new Date().toISOString(),
132
+ level: "error",
133
+ text: truncateText(event.message || "window error"),
134
+ args: [
135
+ {
136
+ filename: event.filename || "",
137
+ lineno: event.lineno || 0,
138
+ colno: event.colno || 0,
139
+ },
140
+ ],
141
+ url: location.href,
142
+ title: document.title,
143
+ });
144
+ });
145
+
146
+ window.addEventListener("unhandledrejection", (event) => {
147
+ emit({
148
+ kind: "console_event",
149
+ source: "page",
150
+ at: new Date().toISOString(),
151
+ level: "error",
152
+ text: "Unhandled promise rejection",
153
+ args: [serializeValue(event.reason)],
154
+ url: location.href,
155
+ title: document.title,
156
+ });
157
+ });
158
+
159
+ const originalFetch = window.fetch.bind(window);
160
+ window.fetch = async (...args) => {
161
+ const startedAt = new Date().toISOString();
162
+ const request = new Request(...args);
163
+ const requestId = `page-fetch-${Date.now()}-${Math.random().toString(36).slice(2, 10)}`;
164
+ const body = await serializeRequestBody(request);
165
+ emit({
166
+ kind: "network_request",
167
+ source: "page",
168
+ at: startedAt,
169
+ request_id: requestId,
170
+ url: request.url,
171
+ method: request.method,
172
+ resource_type: "fetch",
173
+ headers: headersToArray(request.headers),
174
+ ...body,
175
+ });
176
+
177
+ const response = await originalFetch(...args);
178
+ emit({
179
+ kind: "network_response_complete",
180
+ source: "page",
181
+ at: new Date().toISOString(),
182
+ request_id: requestId,
183
+ url: request.url,
184
+ method: request.method,
185
+ resource_type: "fetch",
186
+ status_code: response.status,
187
+ headers: headersToArray(response.headers),
188
+ });
189
+
190
+ try {
191
+ const bodyText = await response.clone().text();
192
+ emit({
193
+ kind: "network_response_body",
194
+ source: "page",
195
+ at: new Date().toISOString(),
196
+ request_id: requestId,
197
+ url: request.url,
198
+ body_text: truncateText(bodyText),
199
+ body_truncated: bodyText.length > MAX_TEXT_CHARS,
200
+ });
201
+ } catch {
202
+ // ignore
203
+ }
204
+
205
+ return response;
206
+ };
207
+
208
+ const originalOpen = XMLHttpRequest.prototype.open;
209
+ const originalSend = XMLHttpRequest.prototype.send;
210
+ const originalSetHeader = XMLHttpRequest.prototype.setRequestHeader;
211
+ XMLHttpRequest.prototype.open = function patchedOpen(method, url, async, user, password) {
212
+ this.__tellyRecorder = {
213
+ request_id: `page-xhr-${Date.now()}-${Math.random().toString(36).slice(2, 10)}`,
214
+ method: String(method || "GET"),
215
+ url: String(url || ""),
216
+ headers: [],
217
+ };
218
+ return originalOpen.call(this, method, url, async, user, password);
219
+ };
220
+ XMLHttpRequest.prototype.setRequestHeader = function patchedSetHeader(name, value) {
221
+ if (this.__tellyRecorder?.headers) {
222
+ this.__tellyRecorder.headers.push({ name: String(name), value: String(value) });
223
+ }
224
+ return originalSetHeader.call(this, name, value);
225
+ };
226
+ XMLHttpRequest.prototype.send = function patchedSend(body) {
227
+ const startedAt = new Date().toISOString();
228
+ const meta = this.__tellyRecorder || {
229
+ request_id: `page-xhr-${Date.now()}-${Math.random().toString(36).slice(2, 10)}`,
230
+ method: "GET",
231
+ url: "",
232
+ headers: [],
233
+ };
234
+ const bodyText =
235
+ typeof body === "string"
236
+ ? body
237
+ : body instanceof URLSearchParams
238
+ ? body.toString()
239
+ : body instanceof FormData
240
+ ? Array.from(body.entries())
241
+ .map(([k, v]) => `${String(k)}=${String(v)}`)
242
+ .join("&")
243
+ : "";
244
+ emit({
245
+ kind: "network_request",
246
+ source: "page",
247
+ at: startedAt,
248
+ request_id: meta.request_id,
249
+ url: meta.url,
250
+ method: meta.method,
251
+ resource_type: "xmlhttprequest",
252
+ headers: meta.headers,
253
+ body_text: truncateText(bodyText),
254
+ body_truncated: bodyText.length > MAX_TEXT_CHARS,
255
+ });
256
+
257
+ this.addEventListener(
258
+ "loadend",
259
+ () => {
260
+ const headersRaw = this.getAllResponseHeaders() || "";
261
+ const headers = headersRaw
262
+ .split(/\r?\n/)
263
+ .map((line) => line.trim())
264
+ .filter(Boolean)
265
+ .map((line) => {
266
+ const separatorIndex = line.indexOf(":");
267
+ return separatorIndex <= 0
268
+ ? { name: line, value: "" }
269
+ : {
270
+ name: line.slice(0, separatorIndex).trim(),
271
+ value: line.slice(separatorIndex + 1).trim(),
272
+ };
273
+ });
274
+ emit({
275
+ kind: "network_response_complete",
276
+ source: "page",
277
+ at: new Date().toISOString(),
278
+ request_id: meta.request_id,
279
+ url: meta.url,
280
+ method: meta.method,
281
+ resource_type: "xmlhttprequest",
282
+ status_code: this.status,
283
+ headers,
284
+ });
285
+ if (typeof this.responseText === "string") {
286
+ emit({
287
+ kind: "network_response_body",
288
+ source: "page",
289
+ at: new Date().toISOString(),
290
+ request_id: meta.request_id,
291
+ url: meta.url,
292
+ body_text: truncateText(this.responseText),
293
+ body_truncated: this.responseText.length > MAX_TEXT_CHARS,
294
+ });
295
+ }
296
+ },
297
+ { once: true },
298
+ );
299
+
300
+ return originalSend.call(this, body);
301
+ };
302
+ })();