@arvoretech/runtime-lens-mcp 1.0.0 → 1.2.0

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.
@@ -0,0 +1,282 @@
1
+ "use strict";
2
+
3
+ // agent/index.ts
4
+ var import_node_crypto = require("node:crypto");
5
+ var import_node_http = require("node:http");
6
+ var PORT = parseInt(process.env.RUNTIME_LENS_PORT || "9500", 10);
7
+ var clients = /* @__PURE__ */ new Set();
8
+ var buffer = [];
9
+ var MAX_BUFFER = 1e3;
10
+ function serialize(value, depth = 0) {
11
+ if (depth > 3) return "[...]";
12
+ if (value === null) return "null";
13
+ if (value === void 0) return "undefined";
14
+ if (typeof value === "string")
15
+ return value.length > 100 ? `"${value.slice(0, 100)}..."` : `"${value}"`;
16
+ if (typeof value === "number" || typeof value === "boolean")
17
+ return String(value);
18
+ if (typeof value === "function") return `fn ${value.name || "anonymous"}()`;
19
+ if (typeof value === "symbol") return value.toString();
20
+ if (typeof value === "bigint") return `${value}n`;
21
+ if (value instanceof Error)
22
+ return `${value.name}: ${value.message}${value.stack ? "\n" + value.stack : ""}`;
23
+ if (value instanceof Date) return value.toISOString();
24
+ if (value instanceof RegExp) return value.toString();
25
+ if (value instanceof Map) return `Map(${value.size})`;
26
+ if (value instanceof Set) return `Set(${value.size})`;
27
+ if (value instanceof Promise) return "Promise";
28
+ if (Array.isArray(value)) {
29
+ if (value.length === 0) return "[]";
30
+ const items = value.slice(0, 5).map((v) => serialize(v, depth + 1));
31
+ const suffix = value.length > 5 ? `, ...+${value.length - 5}` : "";
32
+ return `[${items.join(", ")}${suffix}]`;
33
+ }
34
+ if (typeof value === "object") {
35
+ const keys = Object.keys(value);
36
+ if (keys.length === 0) return "{}";
37
+ const entries = keys.slice(0, 5).map(
38
+ (k) => `${k}: ${serialize(value[k], depth + 1)}`
39
+ );
40
+ const suffix = keys.length > 5 ? `, ...+${keys.length - 5}` : "";
41
+ return `{${entries.join(", ")}${suffix}}`;
42
+ }
43
+ return typeof value === "object" ? Object.prototype.toString.call(value) : String(value);
44
+ }
45
+ function broadcast(msg) {
46
+ const payload = JSON.stringify(msg);
47
+ const buf = Buffer.from(payload, "utf-8");
48
+ const frame = buildWsFrame(buf);
49
+ for (const client of clients) {
50
+ if (!client.destroyed) {
51
+ client.write(frame);
52
+ } else {
53
+ clients.delete(client);
54
+ }
55
+ }
56
+ buffer.push(msg);
57
+ if (buffer.length > MAX_BUFFER) buffer.shift();
58
+ }
59
+ function flushBuffer(socket) {
60
+ for (const msg of buffer) {
61
+ const buf = Buffer.from(JSON.stringify(msg), "utf-8");
62
+ socket.write(buildWsFrame(buf));
63
+ }
64
+ }
65
+ function buildWsFrame(data) {
66
+ const len = data.length;
67
+ let header;
68
+ if (len < 126) {
69
+ header = Buffer.alloc(2);
70
+ header[0] = 129;
71
+ header[1] = len;
72
+ } else if (len < 65536) {
73
+ header = Buffer.alloc(4);
74
+ header[0] = 129;
75
+ header[1] = 126;
76
+ header.writeUInt16BE(len, 2);
77
+ } else {
78
+ header = Buffer.alloc(10);
79
+ header[0] = 129;
80
+ header[1] = 127;
81
+ header.writeBigUInt64BE(BigInt(len), 2);
82
+ }
83
+ return Buffer.concat([header, data]);
84
+ }
85
+ function parseWsFrame(data) {
86
+ if (data.length < 2) return null;
87
+ const masked = (data[1] & 128) !== 0;
88
+ let payloadLen = data[1] & 127;
89
+ let offset = 2;
90
+ if (payloadLen === 126) {
91
+ payloadLen = data.readUInt16BE(2);
92
+ offset = 4;
93
+ } else if (payloadLen === 127) {
94
+ payloadLen = Number(data.readBigUInt64BE(2));
95
+ offset = 10;
96
+ }
97
+ let maskKey = null;
98
+ if (masked) {
99
+ maskKey = data.subarray(offset, offset + 4);
100
+ offset += 4;
101
+ }
102
+ const payload = data.subarray(offset, offset + payloadLen);
103
+ if (maskKey) {
104
+ for (let i = 0; i < payload.length; i++) {
105
+ payload[i] ^= maskKey[i % 4];
106
+ }
107
+ }
108
+ return payload.toString("utf-8");
109
+ }
110
+ function extractCallSite() {
111
+ const stack = new Error().stack || "";
112
+ const lines = stack.split("\n");
113
+ for (let i = 2; i < lines.length; i++) {
114
+ const line = lines[i];
115
+ if (line.includes("node:") || line.includes("dist/agent/index.js"))
116
+ continue;
117
+ const match = /\((.+):(\d+):(\d+)\)/.exec(line) || /at (.+):(\d+):(\d+)/.exec(line);
118
+ if (match) {
119
+ return {
120
+ file: match[1],
121
+ line: parseInt(match[2], 10),
122
+ column: parseInt(match[3], 10)
123
+ };
124
+ }
125
+ }
126
+ return { file: "unknown", line: 0, column: 0 };
127
+ }
128
+ var originalConsole = {
129
+ log: console.log.bind(console),
130
+ info: console.info.bind(console),
131
+ warn: console.warn.bind(console),
132
+ error: console.error.bind(console),
133
+ debug: console.debug.bind(console)
134
+ };
135
+ function patchConsole() {
136
+ const methods = ["log", "info", "warn", "error", "debug"];
137
+ for (const method of methods) {
138
+ console[method] = (...args) => {
139
+ const site = extractCallSite();
140
+ broadcast({
141
+ type: method,
142
+ file: site.file,
143
+ line: site.line,
144
+ column: site.column,
145
+ values: args.map((a) => serialize(a)),
146
+ timestamp: Date.now()
147
+ });
148
+ originalConsole[method](...args);
149
+ };
150
+ }
151
+ }
152
+ var server = (0, import_node_http.createServer)((_req, res) => {
153
+ res.writeHead(200, { "Content-Type": "application/json" });
154
+ res.end(
155
+ JSON.stringify({
156
+ status: "ok",
157
+ pid: process.pid,
158
+ uptime: process.uptime(),
159
+ clients: clients.size,
160
+ buffered: buffer.length
161
+ })
162
+ );
163
+ });
164
+ server.on("upgrade", (req, socket) => {
165
+ const key = req.headers["sec-websocket-key"];
166
+ if (!key) {
167
+ socket.destroy();
168
+ return;
169
+ }
170
+ const acceptKey = (0, import_node_crypto.createHash)("sha1").update(key + "258EAFA5-E914-47DA-95CA-5AB5DC11650B").digest("base64");
171
+ socket.write(
172
+ `HTTP/1.1 101 Switching Protocols\r
173
+ Upgrade: websocket\r
174
+ Connection: Upgrade\r
175
+ Sec-WebSocket-Accept: ${acceptKey}\r
176
+ \r
177
+ `
178
+ );
179
+ clients.add(socket);
180
+ originalConsole.log(
181
+ `[runtime-lens] client connected (${clients.size} total)`
182
+ );
183
+ flushBuffer(socket);
184
+ socket.on("data", (data) => {
185
+ const text = parseWsFrame(data);
186
+ if (!text) return;
187
+ try {
188
+ const msg = JSON.parse(text);
189
+ if (msg.type === "eval") {
190
+ try {
191
+ const fn = new Function(`return (${msg.expression})`);
192
+ const result = fn();
193
+ broadcast({
194
+ type: "result",
195
+ file: msg.file || "eval",
196
+ line: msg.line || 0,
197
+ column: msg.column || 0,
198
+ values: [serialize(result)],
199
+ timestamp: Date.now(),
200
+ expression: msg.expression
201
+ });
202
+ } catch (err) {
203
+ broadcast({
204
+ type: "error",
205
+ file: msg.file || "eval",
206
+ line: msg.line || 0,
207
+ column: msg.column || 0,
208
+ values: [err instanceof Error ? err.message : String(err)],
209
+ timestamp: Date.now(),
210
+ expression: msg.expression
211
+ });
212
+ }
213
+ } else if (msg.type === "get_buffer") {
214
+ const payload = JSON.stringify({ type: "buffer", logs: buffer });
215
+ const buf = Buffer.from(payload, "utf-8");
216
+ socket.write(buildWsFrame(buf));
217
+ }
218
+ } catch {
219
+ }
220
+ });
221
+ socket.on("close", () => {
222
+ clients.delete(socket);
223
+ originalConsole.log(
224
+ `[runtime-lens] client disconnected (${clients.size} total)`
225
+ );
226
+ });
227
+ socket.on("error", () => {
228
+ clients.delete(socket);
229
+ });
230
+ });
231
+ server.on("error", (err) => {
232
+ if (err.code === "EADDRINUSE") {
233
+ originalConsole.log(
234
+ `[runtime-lens] port ${PORT} in use, skipping agent server`
235
+ );
236
+ }
237
+ });
238
+ server.listen(PORT, () => {
239
+ originalConsole.log(
240
+ `[runtime-lens] agent listening on ws://localhost:${PORT}`
241
+ );
242
+ });
243
+ var keepAliveTimer = null;
244
+ var KEEP_ALIVE_MS = parseInt(
245
+ process.env.RUNTIME_LENS_KEEP_ALIVE || "30000",
246
+ 10
247
+ );
248
+ function scheduleShutdown() {
249
+ if (keepAliveTimer) return;
250
+ keepAliveTimer = setTimeout(() => {
251
+ if (clients.size === 0) {
252
+ originalConsole.log(
253
+ `[runtime-lens] no clients connected, shutting down agent`
254
+ );
255
+ server.close();
256
+ process.exit(0);
257
+ } else {
258
+ keepAliveTimer = null;
259
+ scheduleShutdown();
260
+ }
261
+ }, KEEP_ALIVE_MS);
262
+ keepAliveTimer.unref();
263
+ }
264
+ process.on("beforeExit", () => {
265
+ server.ref();
266
+ scheduleShutdown();
267
+ });
268
+ patchConsole();
269
+ globalThis.__runtimeLens = {
270
+ log: (...args) => {
271
+ const site = extractCallSite();
272
+ broadcast({
273
+ type: "result",
274
+ file: site.file,
275
+ line: site.line,
276
+ column: site.column,
277
+ values: args.map((a) => serialize(a)),
278
+ timestamp: Date.now()
279
+ });
280
+ }
281
+ };
282
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../agent/index.ts"],
4
+ "sourcesContent": ["import { createHash } from \"node:crypto\";\nimport type { IncomingMessage } from \"node:http\";\nimport { createServer } from \"node:http\";\nimport type { Socket } from \"node:net\";\n\nconst PORT = parseInt(process.env.RUNTIME_LENS_PORT || \"9500\", 10);\n\ninterface LogMessage {\n\ttype: \"log\" | \"error\" | \"warn\" | \"info\" | \"debug\" | \"result\";\n\tfile: string;\n\tline: number;\n\tcolumn: number;\n\tvalues: string[];\n\ttimestamp: number;\n\texpression?: string;\n\tcount?: number;\n}\n\nconst clients: Set<Socket> = new Set();\nconst buffer: LogMessage[] = [];\nconst MAX_BUFFER = 1000;\n\nfunction serialize(value: unknown, depth = 0): string {\n\tif (depth > 3) return \"[...]\";\n\tif (value === null) return \"null\";\n\tif (value === undefined) return \"undefined\";\n\tif (typeof value === \"string\")\n\t\treturn value.length > 100 ? `\"${value.slice(0, 100)}...\"` : `\"${value}\"`;\n\tif (typeof value === \"number\" || typeof value === \"boolean\")\n\t\treturn String(value);\n\tif (typeof value === \"function\") return `fn ${value.name || \"anonymous\"}()`;\n\tif (typeof value === \"symbol\") return value.toString();\n\tif (typeof value === \"bigint\") return `${value}n`;\n\tif (value instanceof Error)\n\t\treturn `${value.name}: ${value.message}${value.stack ? \"\\n\" + value.stack : \"\"}`;\n\tif (value instanceof Date) return value.toISOString();\n\tif (value instanceof RegExp) return value.toString();\n\tif (value instanceof Map) return `Map(${value.size})`;\n\tif (value instanceof Set) return `Set(${value.size})`;\n\tif (value instanceof Promise) return \"Promise\";\n\tif (Array.isArray(value)) {\n\t\tif (value.length === 0) return \"[]\";\n\t\tconst items = value.slice(0, 5).map((v) => serialize(v, depth + 1));\n\t\tconst suffix = value.length > 5 ? `, ...+${value.length - 5}` : \"\";\n\t\treturn `[${items.join(\", \")}${suffix}]`;\n\t}\n\tif (typeof value === \"object\") {\n\t\tconst keys = Object.keys(value);\n\t\tif (keys.length === 0) return \"{}\";\n\t\tconst entries = keys\n\t\t\t.slice(0, 5)\n\t\t\t.map(\n\t\t\t\t(k) =>\n\t\t\t\t\t`${k}: ${serialize((value as Record<string, unknown>)[k], depth + 1)}`,\n\t\t\t);\n\t\tconst suffix = keys.length > 5 ? `, ...+${keys.length - 5}` : \"\";\n\t\treturn `{${entries.join(\", \")}${suffix}}`;\n\t}\n\treturn typeof value === \"object\"\n\t\t? Object.prototype.toString.call(value)\n\t\t: String(value);\n}\n\nfunction broadcast(msg: LogMessage): void {\n\tconst payload = JSON.stringify(msg);\n\tconst buf = Buffer.from(payload, \"utf-8\");\n\tconst frame = buildWsFrame(buf);\n\n\tfor (const client of clients) {\n\t\tif (!client.destroyed) {\n\t\t\tclient.write(frame);\n\t\t} else {\n\t\t\tclients.delete(client);\n\t\t}\n\t}\n\n\t// Always buffer for late-connecting clients (MCP server, extension)\n\tbuffer.push(msg);\n\tif (buffer.length > MAX_BUFFER) buffer.shift();\n}\n\nfunction flushBuffer(socket: Socket): void {\n\tfor (const msg of buffer) {\n\t\tconst buf = Buffer.from(JSON.stringify(msg), \"utf-8\");\n\t\tsocket.write(buildWsFrame(buf));\n\t}\n}\n\nfunction buildWsFrame(data: Buffer): Buffer {\n\tconst len = data.length;\n\tlet header: Buffer;\n\tif (len < 126) {\n\t\theader = Buffer.alloc(2);\n\t\theader[0] = 0x81;\n\t\theader[1] = len;\n\t} else if (len < 65536) {\n\t\theader = Buffer.alloc(4);\n\t\theader[0] = 0x81;\n\t\theader[1] = 126;\n\t\theader.writeUInt16BE(len, 2);\n\t} else {\n\t\theader = Buffer.alloc(10);\n\t\theader[0] = 0x81;\n\t\theader[1] = 127;\n\t\theader.writeBigUInt64BE(BigInt(len), 2);\n\t}\n\treturn Buffer.concat([header, data]);\n}\n\nfunction parseWsFrame(data: Buffer): string | null {\n\tif (data.length < 2) return null;\n\tconst masked = (data[1] & 0x80) !== 0;\n\tlet payloadLen = data[1] & 0x7f;\n\tlet offset = 2;\n\n\tif (payloadLen === 126) {\n\t\tpayloadLen = data.readUInt16BE(2);\n\t\toffset = 4;\n\t} else if (payloadLen === 127) {\n\t\tpayloadLen = Number(data.readBigUInt64BE(2));\n\t\toffset = 10;\n\t}\n\n\tlet maskKey: Buffer | null = null;\n\tif (masked) {\n\t\tmaskKey = data.subarray(offset, offset + 4);\n\t\toffset += 4;\n\t}\n\n\tconst payload = data.subarray(offset, offset + payloadLen);\n\tif (maskKey) {\n\t\tfor (let i = 0; i < payload.length; i++) {\n\t\t\tpayload[i] ^= maskKey[i % 4];\n\t\t}\n\t}\n\treturn payload.toString(\"utf-8\");\n}\n\nfunction extractCallSite(): { file: string; line: number; column: number } {\n\tconst stack = new Error().stack || \"\";\n\tconst lines = stack.split(\"\\n\");\n\tfor (let i = 2; i < lines.length; i++) {\n\t\tconst line = lines[i];\n\t\tif (line.includes(\"node:\") || line.includes(\"dist/agent/index.js\"))\n\t\t\tcontinue;\n\t\tconst match =\n\t\t\t/\\((.+):(\\d+):(\\d+)\\)/.exec(line) || /at (.+):(\\d+):(\\d+)/.exec(line);\n\t\tif (match) {\n\t\t\treturn {\n\t\t\t\tfile: match[1],\n\t\t\t\tline: parseInt(match[2], 10),\n\t\t\t\tcolumn: parseInt(match[3], 10),\n\t\t\t};\n\t\t}\n\t}\n\treturn { file: \"unknown\", line: 0, column: 0 };\n}\n\ntype ConsoleMethod = \"log\" | \"info\" | \"warn\" | \"error\" | \"debug\";\nconst originalConsole: Record<ConsoleMethod, (...args: unknown[]) => void> = {\n\tlog: console.log.bind(console),\n\tinfo: console.info.bind(console),\n\twarn: console.warn.bind(console),\n\terror: console.error.bind(console),\n\tdebug: console.debug.bind(console),\n};\n\nfunction patchConsole(): void {\n\tconst methods: ConsoleMethod[] = [\"log\", \"info\", \"warn\", \"error\", \"debug\"];\n\tfor (const method of methods) {\n\t\tconsole[method] = (...args: unknown[]) => {\n\t\t\tconst site = extractCallSite();\n\t\t\tbroadcast({\n\t\t\t\ttype: method,\n\t\t\t\tfile: site.file,\n\t\t\t\tline: site.line,\n\t\t\t\tcolumn: site.column,\n\t\t\t\tvalues: args.map((a) => serialize(a)),\n\t\t\t\ttimestamp: Date.now(),\n\t\t\t});\n\t\t\toriginalConsole[method](...args);\n\t\t};\n\t}\n}\n\nconst server = createServer((_req, res) => {\n\tres.writeHead(200, { \"Content-Type\": \"application/json\" });\n\tres.end(\n\t\tJSON.stringify({\n\t\t\tstatus: \"ok\",\n\t\t\tpid: process.pid,\n\t\t\tuptime: process.uptime(),\n\t\t\tclients: clients.size,\n\t\t\tbuffered: buffer.length,\n\t\t}),\n\t);\n});\n\nserver.on(\"upgrade\", (req: IncomingMessage, socket: Socket) => {\n\tconst key = req.headers[\"sec-websocket-key\"];\n\tif (!key) {\n\t\tsocket.destroy();\n\t\treturn;\n\t}\n\n\tconst acceptKey = createHash(\"sha1\")\n\t\t.update(key + \"258EAFA5-E914-47DA-95CA-5AB5DC11650B\")\n\t\t.digest(\"base64\");\n\n\tsocket.write(\n\t\t\"HTTP/1.1 101 Switching Protocols\\r\\n\" +\n\t\t\t\"Upgrade: websocket\\r\\n\" +\n\t\t\t\"Connection: Upgrade\\r\\n\" +\n\t\t\t`Sec-WebSocket-Accept: ${acceptKey}\\r\\n` +\n\t\t\t\"\\r\\n\",\n\t);\n\n\tclients.add(socket);\n\toriginalConsole.log(\n\t\t`[runtime-lens] client connected (${clients.size} total)`,\n\t);\n\n\tflushBuffer(socket);\n\n\tsocket.on(\"data\", (data: Buffer) => {\n\t\tconst text = parseWsFrame(data);\n\t\tif (!text) return;\n\t\ttry {\n\t\t\tconst msg = JSON.parse(text);\n\t\t\tif (msg.type === \"eval\") {\n\t\t\t\ttry {\n\t\t\t\t\tconst fn = new Function(`return (${msg.expression})`);\n\t\t\t\t\tconst result = fn();\n\t\t\t\t\tbroadcast({\n\t\t\t\t\t\ttype: \"result\",\n\t\t\t\t\t\tfile: msg.file || \"eval\",\n\t\t\t\t\t\tline: msg.line || 0,\n\t\t\t\t\t\tcolumn: msg.column || 0,\n\t\t\t\t\t\tvalues: [serialize(result)],\n\t\t\t\t\t\ttimestamp: Date.now(),\n\t\t\t\t\t\texpression: msg.expression,\n\t\t\t\t\t});\n\t\t\t\t} catch (err: unknown) {\n\t\t\t\t\tbroadcast({\n\t\t\t\t\t\ttype: \"error\",\n\t\t\t\t\t\tfile: msg.file || \"eval\",\n\t\t\t\t\t\tline: msg.line || 0,\n\t\t\t\t\t\tcolumn: msg.column || 0,\n\t\t\t\t\t\tvalues: [err instanceof Error ? err.message : String(err)],\n\t\t\t\t\t\ttimestamp: Date.now(),\n\t\t\t\t\t\texpression: msg.expression,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t} else if (msg.type === \"get_buffer\") {\n\t\t\t\tconst payload = JSON.stringify({ type: \"buffer\", logs: buffer });\n\t\t\t\tconst buf = Buffer.from(payload, \"utf-8\");\n\t\t\t\tsocket.write(buildWsFrame(buf));\n\t\t\t}\n\t\t} catch {\n\t\t\t// invalid JSON\n\t\t}\n\t});\n\n\tsocket.on(\"close\", () => {\n\t\tclients.delete(socket);\n\t\toriginalConsole.log(\n\t\t\t`[runtime-lens] client disconnected (${clients.size} total)`,\n\t\t);\n\t});\n\n\tsocket.on(\"error\", () => {\n\t\tclients.delete(socket);\n\t});\n});\n\nserver.on(\"error\", (err: NodeJS.ErrnoException) => {\n\tif (err.code === \"EADDRINUSE\") {\n\t\toriginalConsole.log(\n\t\t\t`[runtime-lens] port ${PORT} in use, skipping agent server`,\n\t\t);\n\t}\n});\n\nserver.listen(PORT, () => {\n\toriginalConsole.log(\n\t\t`[runtime-lens] agent listening on ws://localhost:${PORT}`,\n\t);\n});\n\nlet keepAliveTimer: ReturnType<typeof setTimeout> | null = null;\nconst KEEP_ALIVE_MS = parseInt(\n\tprocess.env.RUNTIME_LENS_KEEP_ALIVE || \"30000\",\n\t10,\n);\n\nfunction scheduleShutdown(): void {\n\tif (keepAliveTimer) return;\n\tkeepAliveTimer = setTimeout(() => {\n\t\tif (clients.size === 0) {\n\t\t\toriginalConsole.log(\n\t\t\t\t`[runtime-lens] no clients connected, shutting down agent`,\n\t\t\t);\n\t\t\tserver.close();\n\t\t\tprocess.exit(0);\n\t\t} else {\n\t\t\tkeepAliveTimer = null;\n\t\t\tscheduleShutdown();\n\t\t}\n\t}, KEEP_ALIVE_MS);\n\tkeepAliveTimer.unref();\n}\n\nprocess.on(\"beforeExit\", () => {\n\tserver.ref();\n\tscheduleShutdown();\n});\n\npatchConsole();\n\n(globalThis as Record<string, unknown>).__runtimeLens = {\n\tlog: (...args: unknown[]) => {\n\t\tconst site = extractCallSite();\n\t\tbroadcast({\n\t\t\ttype: \"result\",\n\t\t\tfile: site.file,\n\t\t\tline: site.line,\n\t\t\tcolumn: site.column,\n\t\t\tvalues: args.map((a) => serialize(a)),\n\t\t\ttimestamp: Date.now(),\n\t\t});\n\t},\n};\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,20 @@
1
+ import type { LogCollector } from "./log-collector.js";
2
+ export declare class AgentBridge {
3
+ private socket;
4
+ private reconnectTimer;
5
+ private connected;
6
+ private readonly port;
7
+ private readonly collector;
8
+ private dataBuffer;
9
+ private stopped;
10
+ constructor(collector: LogCollector, port?: number);
11
+ connect(): void;
12
+ disconnect(): void;
13
+ isConnected(): boolean;
14
+ private processFrames;
15
+ private handleMessage;
16
+ private ingestLog;
17
+ private sendFrame;
18
+ private scheduleReconnect;
19
+ }
20
+ //# sourceMappingURL=agent-bridge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-bridge.d.ts","sourceRoot":"","sources":["../src/agent-bridge.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAuBvD,qBAAa,WAAW;IACvB,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,cAAc,CAA8C;IACpE,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;IAC9B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAe;IACzC,OAAO,CAAC,UAAU,CAA2B;IAC7C,OAAO,CAAC,OAAO,CAAS;gBAEZ,SAAS,EAAE,YAAY,EAAE,IAAI,SAAO;IAKhD,OAAO,IAAI,IAAI;IAyDf,UAAU,IAAI,IAAI;IAalB,WAAW,IAAI,OAAO;IAItB,OAAO,CAAC,aAAa;IA2CrB,OAAO,CAAC,aAAa;IAWrB,OAAO,CAAC,SAAS;IAiBjB,OAAO,CAAC,SAAS;IAyBjB,OAAO,CAAC,iBAAiB;CAOzB"}
@@ -0,0 +1,185 @@
1
+ import { randomBytes } from "node:crypto";
2
+ import { request } from "node:http";
3
+ const LEVEL_MAP = {
4
+ log: "info",
5
+ info: "info",
6
+ warn: "warn",
7
+ error: "error",
8
+ debug: "debug",
9
+ result: "info",
10
+ };
11
+ export class AgentBridge {
12
+ socket = null;
13
+ reconnectTimer = null;
14
+ connected = false;
15
+ port;
16
+ collector;
17
+ dataBuffer = Buffer.alloc(0);
18
+ stopped = false;
19
+ constructor(collector, port = 9500) {
20
+ this.collector = collector;
21
+ this.port = parseInt(process.env.RUNTIME_LENS_PORT || String(port), 10);
22
+ }
23
+ connect() {
24
+ if (this.socket || this.stopped)
25
+ return;
26
+ const key = randomBytes(16).toString("base64");
27
+ const req = request({
28
+ hostname: "localhost",
29
+ port: this.port,
30
+ path: "/",
31
+ method: "GET",
32
+ timeout: 3000,
33
+ headers: {
34
+ Upgrade: "websocket",
35
+ Connection: "Upgrade",
36
+ "Sec-WebSocket-Key": key,
37
+ "Sec-WebSocket-Version": "13",
38
+ },
39
+ });
40
+ req.on("upgrade", (_res, socket) => {
41
+ this.socket = socket;
42
+ this.connected = true;
43
+ this.dataBuffer = Buffer.alloc(0);
44
+ console.error("[runtime-lens-mcp] Connected to agent on port", this.port);
45
+ // Request buffered logs
46
+ this.sendFrame(JSON.stringify({ type: "get_buffer" }));
47
+ socket.on("data", (data) => {
48
+ this.dataBuffer = Buffer.concat([this.dataBuffer, data]);
49
+ this.processFrames();
50
+ });
51
+ socket.on("close", () => {
52
+ this.connected = false;
53
+ this.socket = null;
54
+ this.scheduleReconnect();
55
+ });
56
+ socket.on("error", () => {
57
+ this.connected = false;
58
+ this.socket = null;
59
+ });
60
+ });
61
+ req.on("error", () => {
62
+ this.scheduleReconnect();
63
+ });
64
+ req.on("timeout", () => {
65
+ req.destroy();
66
+ this.scheduleReconnect();
67
+ });
68
+ req.end();
69
+ }
70
+ disconnect() {
71
+ this.stopped = true;
72
+ if (this.reconnectTimer) {
73
+ clearTimeout(this.reconnectTimer);
74
+ this.reconnectTimer = null;
75
+ }
76
+ if (this.socket) {
77
+ this.socket.end();
78
+ this.socket = null;
79
+ }
80
+ this.connected = false;
81
+ }
82
+ isConnected() {
83
+ return this.connected;
84
+ }
85
+ processFrames() {
86
+ while (this.dataBuffer.length >= 2) {
87
+ const firstByte = this.dataBuffer[0];
88
+ const secondByte = this.dataBuffer[1];
89
+ const isFin = (firstByte & 0x80) !== 0;
90
+ const opcode = firstByte & 0x0f;
91
+ if (opcode === 0x08) {
92
+ this.socket?.end();
93
+ return;
94
+ }
95
+ let payloadLen = secondByte & 0x7f;
96
+ let headerLen = 2;
97
+ if (payloadLen === 126) {
98
+ if (this.dataBuffer.length < 4)
99
+ return;
100
+ payloadLen = this.dataBuffer.readUInt16BE(2);
101
+ headerLen = 4;
102
+ }
103
+ else if (payloadLen === 127) {
104
+ if (this.dataBuffer.length < 10)
105
+ return;
106
+ payloadLen = Number(this.dataBuffer.readBigUInt64BE(2));
107
+ headerLen = 10;
108
+ }
109
+ const totalLen = headerLen + payloadLen;
110
+ if (this.dataBuffer.length < totalLen)
111
+ return;
112
+ const payload = this.dataBuffer.subarray(headerLen, totalLen);
113
+ this.dataBuffer = this.dataBuffer.subarray(totalLen);
114
+ if (isFin && (opcode === 0x01 || opcode === 0x02)) {
115
+ const text = payload.toString("utf-8");
116
+ try {
117
+ const msg = JSON.parse(text);
118
+ this.handleMessage(msg);
119
+ }
120
+ catch {
121
+ // invalid JSON
122
+ }
123
+ }
124
+ }
125
+ }
126
+ handleMessage(msg) {
127
+ if (msg.type === "buffer" && msg.logs) {
128
+ for (const log of msg.logs) {
129
+ this.ingestLog(log);
130
+ }
131
+ return;
132
+ }
133
+ this.ingestLog(msg);
134
+ }
135
+ ingestLog(msg) {
136
+ const level = LEVEL_MAP[msg.type] || "info";
137
+ this.collector.addLog({
138
+ level,
139
+ message: msg.values.join(", "),
140
+ source: msg.file || "agent",
141
+ framework: "unknown",
142
+ metadata: {
143
+ line: msg.line,
144
+ column: msg.column,
145
+ agentType: msg.type,
146
+ expression: msg.expression,
147
+ originalTimestamp: msg.timestamp,
148
+ },
149
+ });
150
+ }
151
+ sendFrame(text) {
152
+ if (!this.socket)
153
+ return;
154
+ const data = Buffer.from(text, "utf-8");
155
+ const len = data.length;
156
+ let header;
157
+ if (len < 126) {
158
+ header = Buffer.alloc(2);
159
+ header[0] = 0x81;
160
+ header[1] = len;
161
+ }
162
+ else if (len < 65536) {
163
+ header = Buffer.alloc(4);
164
+ header[0] = 0x81;
165
+ header[1] = 126;
166
+ header.writeUInt16BE(len, 2);
167
+ }
168
+ else {
169
+ header = Buffer.alloc(10);
170
+ header[0] = 0x81;
171
+ header[1] = 127;
172
+ header.writeBigUInt64BE(BigInt(len), 2);
173
+ }
174
+ this.socket.write(Buffer.concat([header, data]));
175
+ }
176
+ scheduleReconnect() {
177
+ if (this.reconnectTimer || this.stopped)
178
+ return;
179
+ this.reconnectTimer = setTimeout(() => {
180
+ this.reconnectTimer = null;
181
+ this.connect();
182
+ }, 5000);
183
+ }
184
+ }
185
+ //# sourceMappingURL=agent-bridge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-bridge.js","sourceRoot":"","sources":["../src/agent-bridge.ts"],"names":[],"mappings":"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"}