@arvoretech/runtime-lens-mcp 1.0.0 → 1.1.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.
- package/README.md +10 -3
- package/dist/agent/index.js +226 -0
- package/dist/agent/index.js.map +7 -0
- package/dist/extension/extension.js +407 -0
- package/dist/extension/extension.js.map +7 -0
- package/package.json +2 -2
- package/.vscodeignore +0 -21
- package/agent/tsconfig.json +0 -17
- package/eslint.config.js +0 -41
- package/extension/decorator.ts +0 -144
- package/extension/extension.ts +0 -98
- package/extension/runtime-bridge.ts +0 -206
- package/extension/tsconfig.json +0 -17
- package/tsconfig.json +0 -20
- package/vitest.config.ts +0 -13
package/README.md
CHANGED
|
@@ -61,11 +61,17 @@ Add this to your `~/.zshrc` (or `~/.bashrc`):
|
|
|
61
61
|
|
|
62
62
|
```bash
|
|
63
63
|
# Runtime Lens — inject agent into all Node.js processes
|
|
64
|
-
export RUNTIME_LENS_AGENT_PATH="
|
|
64
|
+
export RUNTIME_LENS_AGENT_PATH="$(npm root -g)/@arvoretech/runtime-lens-mcp/dist/agent/index.js"
|
|
65
65
|
export NODE_OPTIONS="--require $RUNTIME_LENS_AGENT_PATH"
|
|
66
66
|
export RUNTIME_LENS_PORT="9500"
|
|
67
67
|
```
|
|
68
68
|
|
|
69
|
+
Before using, install the package globally:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
npm install -g @arvoretech/runtime-lens-mcp
|
|
73
|
+
```
|
|
74
|
+
|
|
69
75
|
Then reload your shell:
|
|
70
76
|
|
|
71
77
|
```bash
|
|
@@ -74,11 +80,12 @@ source ~/.zshrc
|
|
|
74
80
|
|
|
75
81
|
Now every Node.js process you start will automatically connect to Runtime Lens. Just open the editor and run `Runtime Lens: Start` — no need to inject every time.
|
|
76
82
|
|
|
77
|
-
> **
|
|
83
|
+
> **Warning:** Setting `NODE_OPTIONS` globally affects all Node.js processes, including tools like `npx`, `npm`, and MCP servers. If you experience issues, use a wrapper function instead:
|
|
78
84
|
>
|
|
79
85
|
> ```bash
|
|
80
86
|
> lens() {
|
|
81
|
-
>
|
|
87
|
+
> local agent="$(npm root -g)/@arvoretech/runtime-lens-mcp/dist/agent/index.js"
|
|
88
|
+
> NODE_OPTIONS="--require $agent" RUNTIME_LENS_PORT=9500 "$@"
|
|
82
89
|
> }
|
|
83
90
|
> # Usage: lens pnpm dev
|
|
84
91
|
> ```
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
// agent/index.ts
|
|
4
|
+
var import_node_http = require("node:http");
|
|
5
|
+
var import_node_crypto = require("node:crypto");
|
|
6
|
+
var PORT = parseInt(process.env.RUNTIME_LENS_PORT || "9500", 10);
|
|
7
|
+
var client = null;
|
|
8
|
+
var buffer = [];
|
|
9
|
+
var MAX_BUFFER = 500;
|
|
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") return value.length > 100 ? `"${value.slice(0, 100)}..."` : `"${value}"`;
|
|
15
|
+
if (typeof value === "number" || typeof value === "boolean") return String(value);
|
|
16
|
+
if (typeof value === "function") return `fn ${value.name || "anonymous"}()`;
|
|
17
|
+
if (typeof value === "symbol") return value.toString();
|
|
18
|
+
if (typeof value === "bigint") return `${value}n`;
|
|
19
|
+
if (value instanceof Error) return `${value.name}: ${value.message}`;
|
|
20
|
+
if (value instanceof Date) return value.toISOString();
|
|
21
|
+
if (value instanceof RegExp) return value.toString();
|
|
22
|
+
if (value instanceof Map) return `Map(${value.size})`;
|
|
23
|
+
if (value instanceof Set) return `Set(${value.size})`;
|
|
24
|
+
if (value instanceof Promise) return "Promise";
|
|
25
|
+
if (Array.isArray(value)) {
|
|
26
|
+
if (value.length === 0) return "[]";
|
|
27
|
+
const items = value.slice(0, 5).map((v) => serialize(v, depth + 1));
|
|
28
|
+
const suffix = value.length > 5 ? `, ...+${value.length - 5}` : "";
|
|
29
|
+
return `[${items.join(", ")}${suffix}]`;
|
|
30
|
+
}
|
|
31
|
+
if (typeof value === "object") {
|
|
32
|
+
const keys = Object.keys(value);
|
|
33
|
+
if (keys.length === 0) return "{}";
|
|
34
|
+
const entries = keys.slice(0, 5).map((k) => `${k}: ${serialize(value[k], depth + 1)}`);
|
|
35
|
+
const suffix = keys.length > 5 ? `, ...+${keys.length - 5}` : "";
|
|
36
|
+
return `{${entries.join(", ")}${suffix}}`;
|
|
37
|
+
}
|
|
38
|
+
return typeof value === "object" ? Object.prototype.toString.call(value) : String(value);
|
|
39
|
+
}
|
|
40
|
+
function wsSend(msg) {
|
|
41
|
+
const payload = JSON.stringify(msg);
|
|
42
|
+
if (client && !client.destroyed) {
|
|
43
|
+
const buf = Buffer.from(payload, "utf-8");
|
|
44
|
+
const frame = buildWsFrame(buf);
|
|
45
|
+
client.write(frame);
|
|
46
|
+
} else {
|
|
47
|
+
buffer.push(msg);
|
|
48
|
+
if (buffer.length > MAX_BUFFER) buffer.shift();
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
function flushBuffer() {
|
|
52
|
+
while (buffer.length > 0 && client && !client.destroyed) {
|
|
53
|
+
const msg = buffer.shift();
|
|
54
|
+
if (msg) {
|
|
55
|
+
const buf = Buffer.from(JSON.stringify(msg), "utf-8");
|
|
56
|
+
client.write(buildWsFrame(buf));
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
function buildWsFrame(data) {
|
|
61
|
+
const len = data.length;
|
|
62
|
+
let header;
|
|
63
|
+
if (len < 126) {
|
|
64
|
+
header = Buffer.alloc(2);
|
|
65
|
+
header[0] = 129;
|
|
66
|
+
header[1] = len;
|
|
67
|
+
} else if (len < 65536) {
|
|
68
|
+
header = Buffer.alloc(4);
|
|
69
|
+
header[0] = 129;
|
|
70
|
+
header[1] = 126;
|
|
71
|
+
header.writeUInt16BE(len, 2);
|
|
72
|
+
} else {
|
|
73
|
+
header = Buffer.alloc(10);
|
|
74
|
+
header[0] = 129;
|
|
75
|
+
header[1] = 127;
|
|
76
|
+
header.writeBigUInt64BE(BigInt(len), 2);
|
|
77
|
+
}
|
|
78
|
+
return Buffer.concat([header, data]);
|
|
79
|
+
}
|
|
80
|
+
function parseWsFrame(data) {
|
|
81
|
+
if (data.length < 2) return null;
|
|
82
|
+
const masked = (data[1] & 128) !== 0;
|
|
83
|
+
let payloadLen = data[1] & 127;
|
|
84
|
+
let offset = 2;
|
|
85
|
+
if (payloadLen === 126) {
|
|
86
|
+
payloadLen = data.readUInt16BE(2);
|
|
87
|
+
offset = 4;
|
|
88
|
+
} else if (payloadLen === 127) {
|
|
89
|
+
payloadLen = Number(data.readBigUInt64BE(2));
|
|
90
|
+
offset = 10;
|
|
91
|
+
}
|
|
92
|
+
let maskKey = null;
|
|
93
|
+
if (masked) {
|
|
94
|
+
maskKey = data.subarray(offset, offset + 4);
|
|
95
|
+
offset += 4;
|
|
96
|
+
}
|
|
97
|
+
const payload = data.subarray(offset, offset + payloadLen);
|
|
98
|
+
if (maskKey) {
|
|
99
|
+
for (let i = 0; i < payload.length; i++) {
|
|
100
|
+
payload[i] ^= maskKey[i % 4];
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return payload.toString("utf-8");
|
|
104
|
+
}
|
|
105
|
+
function extractCallSite() {
|
|
106
|
+
const stack = new Error().stack || "";
|
|
107
|
+
const lines = stack.split("\n");
|
|
108
|
+
for (let i = 2; i < lines.length; i++) {
|
|
109
|
+
const line = lines[i];
|
|
110
|
+
if (line.includes("node:") || line.includes("dist/agent/index.js")) continue;
|
|
111
|
+
const match = /\((.+):(\d+):(\d+)\)/.exec(line) || /at (.+):(\d+):(\d+)/.exec(line);
|
|
112
|
+
if (match) {
|
|
113
|
+
return { file: match[1], line: parseInt(match[2], 10), column: parseInt(match[3], 10) };
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return { file: "unknown", line: 0, column: 0 };
|
|
117
|
+
}
|
|
118
|
+
var originalConsole = {
|
|
119
|
+
log: console.log.bind(console),
|
|
120
|
+
info: console.info.bind(console),
|
|
121
|
+
warn: console.warn.bind(console),
|
|
122
|
+
error: console.error.bind(console),
|
|
123
|
+
debug: console.debug.bind(console)
|
|
124
|
+
};
|
|
125
|
+
function patchConsole() {
|
|
126
|
+
const methods = ["log", "info", "warn", "error", "debug"];
|
|
127
|
+
for (const method of methods) {
|
|
128
|
+
console[method] = (...args) => {
|
|
129
|
+
const site = extractCallSite();
|
|
130
|
+
wsSend({
|
|
131
|
+
type: method,
|
|
132
|
+
file: site.file,
|
|
133
|
+
line: site.line,
|
|
134
|
+
column: site.column,
|
|
135
|
+
values: args.map((a) => serialize(a)),
|
|
136
|
+
timestamp: Date.now()
|
|
137
|
+
});
|
|
138
|
+
originalConsole[method](...args);
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
var server = (0, import_node_http.createServer)((_req, res) => {
|
|
143
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
144
|
+
res.end(JSON.stringify({ status: "ok", pid: process.pid, uptime: process.uptime() }));
|
|
145
|
+
});
|
|
146
|
+
server.on("upgrade", (req, socket) => {
|
|
147
|
+
const key = req.headers["sec-websocket-key"];
|
|
148
|
+
if (!key) {
|
|
149
|
+
socket.destroy();
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
const acceptKey = (0, import_node_crypto.createHash)("sha1").update(key + "258EAFA5-E914-47DA-95CA-5AB5DC11650B").digest("base64");
|
|
153
|
+
socket.write(
|
|
154
|
+
`HTTP/1.1 101 Switching Protocols\r
|
|
155
|
+
Upgrade: websocket\r
|
|
156
|
+
Connection: Upgrade\r
|
|
157
|
+
Sec-WebSocket-Accept: ${acceptKey}\r
|
|
158
|
+
\r
|
|
159
|
+
`
|
|
160
|
+
);
|
|
161
|
+
client = socket;
|
|
162
|
+
flushBuffer();
|
|
163
|
+
socket.on("data", (data) => {
|
|
164
|
+
const text = parseWsFrame(data);
|
|
165
|
+
if (!text) return;
|
|
166
|
+
try {
|
|
167
|
+
const msg = JSON.parse(text);
|
|
168
|
+
if (msg.type === "eval") {
|
|
169
|
+
try {
|
|
170
|
+
const fn = new Function(`return (${msg.expression})`);
|
|
171
|
+
const result = fn();
|
|
172
|
+
wsSend({
|
|
173
|
+
type: "result",
|
|
174
|
+
file: msg.file || "eval",
|
|
175
|
+
line: msg.line || 0,
|
|
176
|
+
column: msg.column || 0,
|
|
177
|
+
values: [serialize(result)],
|
|
178
|
+
timestamp: Date.now(),
|
|
179
|
+
expression: msg.expression
|
|
180
|
+
});
|
|
181
|
+
} catch (err) {
|
|
182
|
+
wsSend({
|
|
183
|
+
type: "error",
|
|
184
|
+
file: msg.file || "eval",
|
|
185
|
+
line: msg.line || 0,
|
|
186
|
+
column: msg.column || 0,
|
|
187
|
+
values: [err instanceof Error ? err.message : String(err)],
|
|
188
|
+
timestamp: Date.now(),
|
|
189
|
+
expression: msg.expression
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
} catch {
|
|
194
|
+
}
|
|
195
|
+
});
|
|
196
|
+
socket.on("close", () => {
|
|
197
|
+
client = null;
|
|
198
|
+
});
|
|
199
|
+
socket.on("error", () => {
|
|
200
|
+
client = null;
|
|
201
|
+
});
|
|
202
|
+
});
|
|
203
|
+
server.on("error", (err) => {
|
|
204
|
+
if (err.code === "EADDRINUSE") {
|
|
205
|
+
originalConsole.log(`[runtime-lens] port ${PORT} in use, skipping agent server`);
|
|
206
|
+
}
|
|
207
|
+
});
|
|
208
|
+
server.listen(PORT, () => {
|
|
209
|
+
originalConsole.log(`[runtime-lens] agent listening on ws://localhost:${PORT}`);
|
|
210
|
+
});
|
|
211
|
+
server.unref();
|
|
212
|
+
patchConsole();
|
|
213
|
+
globalThis.__runtimeLens = {
|
|
214
|
+
log: (...args) => {
|
|
215
|
+
const site = extractCallSite();
|
|
216
|
+
wsSend({
|
|
217
|
+
type: "result",
|
|
218
|
+
file: site.file,
|
|
219
|
+
line: site.line,
|
|
220
|
+
column: site.column,
|
|
221
|
+
values: args.map((a) => serialize(a)),
|
|
222
|
+
timestamp: Date.now()
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
};
|
|
226
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../agent/index.ts"],
|
|
4
|
+
"sourcesContent": ["import { createServer } from \"node:http\";\nimport { createHash } from \"node:crypto\";\nimport type { IncomingMessage } from \"node:http\";\nimport type { Socket } from \"node:net\";\n\nconst PORT = parseInt(process.env.RUNTIME_LENS_PORT || \"9500\", 10);\n\ninterface LogMessage {\n type: \"log\" | \"error\" | \"warn\" | \"info\" | \"debug\" | \"result\";\n file: string;\n line: number;\n column: number;\n values: string[];\n timestamp: number;\n expression?: string;\n}\n\nlet client: Socket | null = null;\nconst buffer: LogMessage[] = [];\nconst MAX_BUFFER = 500;\n\nfunction serialize(value: unknown, depth = 0): string {\n if (depth > 3) return \"[...]\";\n if (value === null) return \"null\";\n if (value === undefined) return \"undefined\";\n if (typeof value === \"string\") return value.length > 100 ? `\"${value.slice(0, 100)}...\"` : `\"${value}\"`;\n if (typeof value === \"number\" || typeof value === \"boolean\") return String(value);\n if (typeof value === \"function\") return `fn ${value.name || \"anonymous\"}()`;\n if (typeof value === \"symbol\") return value.toString();\n if (typeof value === \"bigint\") return `${value}n`;\n if (value instanceof Error) return `${value.name}: ${value.message}`;\n if (value instanceof Date) return value.toISOString();\n if (value instanceof RegExp) return value.toString();\n if (value instanceof Map) return `Map(${value.size})`;\n if (value instanceof Set) return `Set(${value.size})`;\n if (value instanceof Promise) return \"Promise\";\n if (Array.isArray(value)) {\n if (value.length === 0) return \"[]\";\n const items = value.slice(0, 5).map(v => serialize(v, depth + 1));\n const suffix = value.length > 5 ? `, ...+${value.length - 5}` : \"\";\n return `[${items.join(\", \")}${suffix}]`;\n }\n if (typeof value === \"object\") {\n const keys = Object.keys(value);\n if (keys.length === 0) return \"{}\";\n const entries = keys.slice(0, 5).map(k => `${k}: ${serialize((value as Record<string, unknown>)[k], depth + 1)}`);\n const suffix = keys.length > 5 ? `, ...+${keys.length - 5}` : \"\";\n return `{${entries.join(\", \")}${suffix}}`;\n }\n return typeof value === \"object\" ? Object.prototype.toString.call(value) : String(value);\n}\n\nfunction wsSend(msg: LogMessage): void {\n const payload = JSON.stringify(msg);\n if (client && !client.destroyed) {\n const buf = Buffer.from(payload, \"utf-8\");\n const frame = buildWsFrame(buf);\n client.write(frame);\n } else {\n buffer.push(msg);\n if (buffer.length > MAX_BUFFER) buffer.shift();\n }\n}\n\nfunction flushBuffer(): void {\n while (buffer.length > 0 && client && !client.destroyed) {\n const msg = buffer.shift();\n if (msg) {\n const buf = Buffer.from(JSON.stringify(msg), \"utf-8\");\n client.write(buildWsFrame(buf));\n }\n }\n}\n\nfunction buildWsFrame(data: Buffer): Buffer {\n const len = data.length;\n let header: Buffer;\n if (len < 126) {\n header = Buffer.alloc(2);\n header[0] = 0x81;\n header[1] = len;\n } else if (len < 65536) {\n header = Buffer.alloc(4);\n header[0] = 0x81;\n header[1] = 126;\n header.writeUInt16BE(len, 2);\n } else {\n header = Buffer.alloc(10);\n header[0] = 0x81;\n header[1] = 127;\n header.writeBigUInt64BE(BigInt(len), 2);\n }\n return Buffer.concat([header, data]);\n}\n\nfunction parseWsFrame(data: Buffer): string | null {\n if (data.length < 2) return null;\n const masked = (data[1] & 0x80) !== 0;\n let payloadLen = data[1] & 0x7f;\n let offset = 2;\n\n if (payloadLen === 126) {\n payloadLen = data.readUInt16BE(2);\n offset = 4;\n } else if (payloadLen === 127) {\n payloadLen = Number(data.readBigUInt64BE(2));\n offset = 10;\n }\n\n let maskKey: Buffer | null = null;\n if (masked) {\n maskKey = data.subarray(offset, offset + 4);\n offset += 4;\n }\n\n const payload = data.subarray(offset, offset + payloadLen);\n if (maskKey) {\n for (let i = 0; i < payload.length; i++) {\n payload[i] ^= maskKey[i % 4];\n }\n }\n return payload.toString(\"utf-8\");\n}\n\nfunction extractCallSite(): { file: string; line: number; column: number } {\n const stack = new Error().stack || \"\";\n const lines = stack.split(\"\\n\");\n for (let i = 2; i < lines.length; i++) {\n const line = lines[i];\n if (line.includes(\"node:\") || line.includes(\"dist/agent/index.js\")) continue;\n const match = /\\((.+):(\\d+):(\\d+)\\)/.exec(line) || /at (.+):(\\d+):(\\d+)/.exec(line);\n if (match) {\n return { file: match[1], line: parseInt(match[2], 10), column: parseInt(match[3], 10) };\n }\n }\n return { file: \"unknown\", line: 0, column: 0 };\n}\n\ntype ConsoleMethod = \"log\" | \"info\" | \"warn\" | \"error\" | \"debug\";\nconst originalConsole: Record<ConsoleMethod, (...args: unknown[]) => void> = {\n log: console.log.bind(console),\n info: console.info.bind(console),\n warn: console.warn.bind(console),\n error: console.error.bind(console),\n debug: console.debug.bind(console),\n};\n\nfunction patchConsole(): void {\n const methods: ConsoleMethod[] = [\"log\", \"info\", \"warn\", \"error\", \"debug\"];\n for (const method of methods) {\n console[method] = (...args: unknown[]) => {\n const site = extractCallSite();\n wsSend({\n type: method,\n file: site.file,\n line: site.line,\n column: site.column,\n values: args.map(a => serialize(a)),\n timestamp: Date.now(),\n });\n originalConsole[method](...args);\n };\n }\n}\n\nconst server = createServer((_req, res) => {\n res.writeHead(200, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ status: \"ok\", pid: process.pid, uptime: process.uptime() }));\n});\n\nserver.on(\"upgrade\", (req: IncomingMessage, socket: Socket) => {\n const key = req.headers[\"sec-websocket-key\"];\n if (!key) {\n socket.destroy();\n return;\n }\n\n const acceptKey = createHash(\"sha1\")\n .update(key + \"258EAFA5-E914-47DA-95CA-5AB5DC11650B\")\n .digest(\"base64\");\n\n socket.write(\n \"HTTP/1.1 101 Switching Protocols\\r\\n\" +\n \"Upgrade: websocket\\r\\n\" +\n \"Connection: Upgrade\\r\\n\" +\n `Sec-WebSocket-Accept: ${acceptKey}\\r\\n` +\n \"\\r\\n\"\n );\n\n client = socket;\n flushBuffer();\n\n socket.on(\"data\", (data: Buffer) => {\n const text = parseWsFrame(data);\n if (!text) return;\n try {\n const msg = JSON.parse(text);\n if (msg.type === \"eval\") {\n try {\n const fn = new Function(`return (${msg.expression})`);\n const result = fn();\n wsSend({\n type: \"result\",\n file: msg.file || \"eval\",\n line: msg.line || 0,\n column: msg.column || 0,\n values: [serialize(result)],\n timestamp: Date.now(),\n expression: msg.expression,\n });\n } catch (err: unknown) {\n wsSend({\n type: \"error\",\n file: msg.file || \"eval\",\n line: msg.line || 0,\n column: msg.column || 0,\n values: [err instanceof Error ? err.message : String(err)],\n timestamp: Date.now(),\n expression: msg.expression,\n });\n }\n }\n } catch {\n // invalid JSON\n }\n });\n\n socket.on(\"close\", () => {\n client = null;\n });\n\n socket.on(\"error\", () => {\n client = null;\n });\n});\n\nserver.on(\"error\", (err: NodeJS.ErrnoException) => {\n if (err.code === \"EADDRINUSE\") {\n originalConsole.log(`[runtime-lens] port ${PORT} in use, skipping agent server`);\n }\n});\n\nserver.listen(PORT, () => {\n originalConsole.log(`[runtime-lens] agent listening on ws://localhost:${PORT}`);\n});\n\nserver.unref();\n\npatchConsole();\n\n(globalThis as Record<string, unknown>).__runtimeLens = {\n log: (...args: unknown[]) => {\n const site = extractCallSite();\n wsSend({\n type: \"result\",\n file: site.file,\n line: site.line,\n column: site.column,\n values: args.map(a => serialize(a)),\n timestamp: Date.now(),\n });\n },\n};\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|