@arvoretech/runtime-lens-mcp 1.0.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.
Files changed (42) hide show
  1. package/.vscodeignore +21 -0
  2. package/README.md +136 -0
  3. package/agent/index.ts +263 -0
  4. package/agent/tsconfig.json +17 -0
  5. package/dist/index.d.ts +7 -0
  6. package/dist/index.d.ts.map +1 -0
  7. package/dist/index.js +17 -0
  8. package/dist/index.js.map +1 -0
  9. package/dist/log-collector.d.ts +73 -0
  10. package/dist/log-collector.d.ts.map +1 -0
  11. package/dist/log-collector.js +349 -0
  12. package/dist/log-collector.js.map +1 -0
  13. package/dist/process-inspector.d.ts +44 -0
  14. package/dist/process-inspector.d.ts.map +1 -0
  15. package/dist/process-inspector.js +190 -0
  16. package/dist/process-inspector.js.map +1 -0
  17. package/dist/runtime-interceptor.d.ts +18 -0
  18. package/dist/runtime-interceptor.d.ts.map +1 -0
  19. package/dist/runtime-interceptor.js +133 -0
  20. package/dist/runtime-interceptor.js.map +1 -0
  21. package/dist/server.d.ts +26 -0
  22. package/dist/server.d.ts.map +1 -0
  23. package/dist/server.js +301 -0
  24. package/dist/server.js.map +1 -0
  25. package/dist/types.d.ts +280 -0
  26. package/dist/types.d.ts.map +1 -0
  27. package/dist/types.js +102 -0
  28. package/dist/types.js.map +1 -0
  29. package/eslint.config.js +41 -0
  30. package/extension/decorator.ts +144 -0
  31. package/extension/extension.ts +98 -0
  32. package/extension/runtime-bridge.ts +206 -0
  33. package/extension/tsconfig.json +17 -0
  34. package/package.json +134 -0
  35. package/src/index.ts +18 -0
  36. package/src/log-collector.ts +441 -0
  37. package/src/process-inspector.ts +235 -0
  38. package/src/runtime-interceptor.ts +152 -0
  39. package/src/server.ts +387 -0
  40. package/src/types.ts +128 -0
  41. package/tsconfig.json +20 -0
  42. package/vitest.config.ts +13 -0
package/.vscodeignore ADDED
@@ -0,0 +1,21 @@
1
+ src/**
2
+ extension/**/*.ts
3
+ agent/**/*.ts
4
+ node_modules/**
5
+ coverage/**
6
+ examples/**
7
+ .gitignore
8
+ *.tsbuildinfo
9
+ tsconfig.json
10
+ **/tsconfig.json
11
+ vitest.config.ts
12
+ eslint.config.js
13
+ pnpm-lock.yaml
14
+ **/*.map
15
+ dist/index.d.ts
16
+ dist/log-collector.d.ts
17
+ dist/process-inspector.d.ts
18
+ dist/runtime-interceptor.d.ts
19
+ dist/server.d.ts
20
+ dist/types.d.ts
21
+ dist/agent/index.debug.js
package/README.md ADDED
@@ -0,0 +1,136 @@
1
+ # @arvoretech/runtime-lens-mcp
2
+
3
+ Runtime Lens — Runtime inspection with inline values for React, NestJS and Next.js.
4
+
5
+ Two components in one package:
6
+ 1. VS Code/Cursor/Kiro extension with inline value display
7
+ 2. MCP server for AI-assisted debugging
8
+
9
+ ## Setup
10
+
11
+ ### 1. Build
12
+
13
+ ```bash
14
+ cd packages/runtime-lens
15
+ pnpm install
16
+ pnpm build:all # builds MCP server + extension + agent
17
+ ```
18
+
19
+ ### 2. Install the Extension
20
+
21
+ After building, package and install the `.vsix`:
22
+
23
+ ```bash
24
+ pnpm package # generates runtime-lens-1.0.0.vsix
25
+ code --install-extension runtime-lens-1.0.0.vsix # VS Code
26
+ cursor --install-extension runtime-lens-1.0.0.vsix # Cursor
27
+ ```
28
+
29
+ For Kiro, use the Extensions panel to install from VSIX.
30
+
31
+ ### 3. Configure the MCP Server
32
+
33
+ Add to your editor's MCP config (`.kiro/settings/mcp.json`, `.cursor/mcp.json`, etc.):
34
+
35
+ ```json
36
+ {
37
+ "mcpServers": {
38
+ "runtime-lens": {
39
+ "command": "npx",
40
+ "args": ["-y", "@arvoretech/runtime-lens-mcp"],
41
+ "env": {
42
+ "RUNTIME_LENS_PROJECT_ROOT": "."
43
+ }
44
+ }
45
+ }
46
+ }
47
+ ```
48
+
49
+ ## Usage
50
+
51
+ ### Option A — Command Palette (per session)
52
+
53
+ 1. Open the command palette and run `Runtime Lens: Start`
54
+ 2. Then run `Runtime Lens: Inject Environment into Terminal`
55
+ 3. Start your app normally in that terminal (`pnpm dev`, `npm start`, etc.)
56
+ 4. Runtime values appear inline in the editor
57
+
58
+ ### Option B — Permanent Setup (recommended)
59
+
60
+ Add this to your `~/.zshrc` (or `~/.bashrc`):
61
+
62
+ ```bash
63
+ # Runtime Lens — inject agent into all Node.js processes
64
+ export RUNTIME_LENS_AGENT_PATH="/Users/$USER/path-to/arvore-mcp-servers/packages/runtime-lens/dist/agent/index.js"
65
+ export NODE_OPTIONS="--require $RUNTIME_LENS_AGENT_PATH"
66
+ export RUNTIME_LENS_PORT="9500"
67
+ ```
68
+
69
+ Then reload your shell:
70
+
71
+ ```bash
72
+ source ~/.zshrc
73
+ ```
74
+
75
+ 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
+
77
+ > **Note:** If `NODE_OPTIONS` conflicts with other tools, you can wrap it in a function:
78
+ >
79
+ > ```bash
80
+ > lens() {
81
+ > NODE_OPTIONS="--require $RUNTIME_LENS_AGENT_PATH" RUNTIME_LENS_PORT=9500 "$@"
82
+ > }
83
+ > # Usage: lens pnpm dev
84
+ > ```
85
+
86
+ ## Extension Commands
87
+
88
+ | Command | Description |
89
+ |---------|-------------|
90
+ | `Runtime Lens: Start` | Start listening for runtime values |
91
+ | `Runtime Lens: Stop` | Stop and clear decorations |
92
+ | `Runtime Lens: Toggle` | Toggle on/off (status bar) |
93
+ | `Runtime Lens: Clear Inline Values` | Clear all inline decorations |
94
+ | `Runtime Lens: Connect to Running App` | Connect to an already running agent |
95
+ | `Runtime Lens: Inject Environment into Terminal` | Set NODE_OPTIONS in the active terminal |
96
+ | `Runtime Lens: Show Output` | Show the output channel |
97
+
98
+ ## Extension Settings
99
+
100
+ | Setting | Default | Description |
101
+ |---------|---------|-------------|
102
+ | `runtimeLens.port` | `9500` | WebSocket port for the agent |
103
+ | `runtimeLens.autoStart` | `false` | Auto-start on workspace open |
104
+ | `runtimeLens.maxInlineLength` | `80` | Max inline text length |
105
+ | `runtimeLens.showTimestamp` | `false` | Show timestamp in inline values |
106
+
107
+ ## MCP Tools
108
+
109
+ 14 tools for AI-assisted runtime inspection:
110
+
111
+ | Tool | Description |
112
+ |------|-------------|
113
+ | `tail_logs` | Recent log entries with filtering |
114
+ | `search_logs` | Regex search through logs |
115
+ | `get_errors` | Errors with stack traces, groupable |
116
+ | `inspect_requests` | HTTP request/response inspection |
117
+ | `get_performance` | Memory, CPU metrics |
118
+ | `get_env_info` | Processes, ports, framework detection |
119
+ | `get_stats` | Log statistics by level/framework |
120
+ | `clear_logs` | Clear log buffer |
121
+ | `start_interceptor` / `stop_interceptor` | Real-time console capture |
122
+ | `collect_from_files` | Collect from log files |
123
+ | `scan_project` | Detect framework and configs |
124
+ | `find_processes` | Running Node.js processes |
125
+ | `get_listening_ports` | TCP ports in use |
126
+
127
+ ## Development
128
+
129
+ ```bash
130
+ pnpm install
131
+ pnpm build # MCP server (tsc)
132
+ pnpm build:ext # VS Code extension (esbuild)
133
+ pnpm build:agent # Runtime agent (esbuild)
134
+ pnpm build:all # Everything
135
+ pnpm test # Run tests
136
+ ```
package/agent/index.ts ADDED
@@ -0,0 +1,263 @@
1
+ import { createServer } from "node:http";
2
+ import { createHash } from "node:crypto";
3
+ import type { IncomingMessage } from "node:http";
4
+ import type { Socket } from "node:net";
5
+
6
+ const PORT = parseInt(process.env.RUNTIME_LENS_PORT || "9500", 10);
7
+
8
+ interface LogMessage {
9
+ type: "log" | "error" | "warn" | "info" | "debug" | "result";
10
+ file: string;
11
+ line: number;
12
+ column: number;
13
+ values: string[];
14
+ timestamp: number;
15
+ expression?: string;
16
+ }
17
+
18
+ let client: Socket | null = null;
19
+ const buffer: LogMessage[] = [];
20
+ const MAX_BUFFER = 500;
21
+
22
+ function serialize(value: unknown, depth = 0): string {
23
+ if (depth > 3) return "[...]";
24
+ if (value === null) return "null";
25
+ if (value === undefined) return "undefined";
26
+ if (typeof value === "string") return value.length > 100 ? `"${value.slice(0, 100)}..."` : `"${value}"`;
27
+ if (typeof value === "number" || typeof value === "boolean") return String(value);
28
+ if (typeof value === "function") return `fn ${value.name || "anonymous"}()`;
29
+ if (typeof value === "symbol") return value.toString();
30
+ if (typeof value === "bigint") return `${value}n`;
31
+ if (value instanceof Error) return `${value.name}: ${value.message}`;
32
+ if (value instanceof Date) return value.toISOString();
33
+ if (value instanceof RegExp) return value.toString();
34
+ if (value instanceof Map) return `Map(${value.size})`;
35
+ if (value instanceof Set) return `Set(${value.size})`;
36
+ if (value instanceof Promise) return "Promise";
37
+ if (Array.isArray(value)) {
38
+ if (value.length === 0) return "[]";
39
+ const items = value.slice(0, 5).map(v => serialize(v, depth + 1));
40
+ const suffix = value.length > 5 ? `, ...+${value.length - 5}` : "";
41
+ return `[${items.join(", ")}${suffix}]`;
42
+ }
43
+ if (typeof value === "object") {
44
+ const keys = Object.keys(value);
45
+ if (keys.length === 0) return "{}";
46
+ const entries = keys.slice(0, 5).map(k => `${k}: ${serialize((value as Record<string, unknown>)[k], depth + 1)}`);
47
+ const suffix = keys.length > 5 ? `, ...+${keys.length - 5}` : "";
48
+ return `{${entries.join(", ")}${suffix}}`;
49
+ }
50
+ return typeof value === "object" ? Object.prototype.toString.call(value) : String(value);
51
+ }
52
+
53
+ function wsSend(msg: LogMessage): void {
54
+ const payload = JSON.stringify(msg);
55
+ if (client && !client.destroyed) {
56
+ const buf = Buffer.from(payload, "utf-8");
57
+ const frame = buildWsFrame(buf);
58
+ client.write(frame);
59
+ } else {
60
+ buffer.push(msg);
61
+ if (buffer.length > MAX_BUFFER) buffer.shift();
62
+ }
63
+ }
64
+
65
+ function flushBuffer(): void {
66
+ while (buffer.length > 0 && client && !client.destroyed) {
67
+ const msg = buffer.shift();
68
+ if (msg) {
69
+ const buf = Buffer.from(JSON.stringify(msg), "utf-8");
70
+ client.write(buildWsFrame(buf));
71
+ }
72
+ }
73
+ }
74
+
75
+ function buildWsFrame(data: Buffer): Buffer {
76
+ const len = data.length;
77
+ let header: Buffer;
78
+ if (len < 126) {
79
+ header = Buffer.alloc(2);
80
+ header[0] = 0x81;
81
+ header[1] = len;
82
+ } else if (len < 65536) {
83
+ header = Buffer.alloc(4);
84
+ header[0] = 0x81;
85
+ header[1] = 126;
86
+ header.writeUInt16BE(len, 2);
87
+ } else {
88
+ header = Buffer.alloc(10);
89
+ header[0] = 0x81;
90
+ header[1] = 127;
91
+ header.writeBigUInt64BE(BigInt(len), 2);
92
+ }
93
+ return Buffer.concat([header, data]);
94
+ }
95
+
96
+ function parseWsFrame(data: Buffer): string | null {
97
+ if (data.length < 2) return null;
98
+ const masked = (data[1] & 0x80) !== 0;
99
+ let payloadLen = data[1] & 0x7f;
100
+ let offset = 2;
101
+
102
+ if (payloadLen === 126) {
103
+ payloadLen = data.readUInt16BE(2);
104
+ offset = 4;
105
+ } else if (payloadLen === 127) {
106
+ payloadLen = Number(data.readBigUInt64BE(2));
107
+ offset = 10;
108
+ }
109
+
110
+ let maskKey: Buffer | null = null;
111
+ if (masked) {
112
+ maskKey = data.subarray(offset, offset + 4);
113
+ offset += 4;
114
+ }
115
+
116
+ const payload = data.subarray(offset, offset + payloadLen);
117
+ if (maskKey) {
118
+ for (let i = 0; i < payload.length; i++) {
119
+ payload[i] ^= maskKey[i % 4];
120
+ }
121
+ }
122
+ return payload.toString("utf-8");
123
+ }
124
+
125
+ function extractCallSite(): { file: string; line: number; column: number } {
126
+ const stack = new Error().stack || "";
127
+ const lines = stack.split("\n");
128
+ for (let i = 2; i < lines.length; i++) {
129
+ const line = lines[i];
130
+ if (line.includes("node:") || line.includes("dist/agent/index.js")) continue;
131
+ const match = /\((.+):(\d+):(\d+)\)/.exec(line) || /at (.+):(\d+):(\d+)/.exec(line);
132
+ if (match) {
133
+ return { file: match[1], line: parseInt(match[2], 10), column: parseInt(match[3], 10) };
134
+ }
135
+ }
136
+ return { file: "unknown", line: 0, column: 0 };
137
+ }
138
+
139
+ type ConsoleMethod = "log" | "info" | "warn" | "error" | "debug";
140
+ const originalConsole: Record<ConsoleMethod, (...args: unknown[]) => void> = {
141
+ log: console.log.bind(console),
142
+ info: console.info.bind(console),
143
+ warn: console.warn.bind(console),
144
+ error: console.error.bind(console),
145
+ debug: console.debug.bind(console),
146
+ };
147
+
148
+ function patchConsole(): void {
149
+ const methods: ConsoleMethod[] = ["log", "info", "warn", "error", "debug"];
150
+ for (const method of methods) {
151
+ console[method] = (...args: unknown[]) => {
152
+ const site = extractCallSite();
153
+ wsSend({
154
+ type: method,
155
+ file: site.file,
156
+ line: site.line,
157
+ column: site.column,
158
+ values: args.map(a => serialize(a)),
159
+ timestamp: Date.now(),
160
+ });
161
+ originalConsole[method](...args);
162
+ };
163
+ }
164
+ }
165
+
166
+ const server = createServer((_req, res) => {
167
+ res.writeHead(200, { "Content-Type": "application/json" });
168
+ res.end(JSON.stringify({ status: "ok", pid: process.pid, uptime: process.uptime() }));
169
+ });
170
+
171
+ server.on("upgrade", (req: IncomingMessage, socket: Socket) => {
172
+ const key = req.headers["sec-websocket-key"];
173
+ if (!key) {
174
+ socket.destroy();
175
+ return;
176
+ }
177
+
178
+ const acceptKey = createHash("sha1")
179
+ .update(key + "258EAFA5-E914-47DA-95CA-5AB5DC11650B")
180
+ .digest("base64");
181
+
182
+ socket.write(
183
+ "HTTP/1.1 101 Switching Protocols\r\n" +
184
+ "Upgrade: websocket\r\n" +
185
+ "Connection: Upgrade\r\n" +
186
+ `Sec-WebSocket-Accept: ${acceptKey}\r\n` +
187
+ "\r\n"
188
+ );
189
+
190
+ client = socket;
191
+ flushBuffer();
192
+
193
+ socket.on("data", (data: Buffer) => {
194
+ const text = parseWsFrame(data);
195
+ if (!text) return;
196
+ try {
197
+ const msg = JSON.parse(text);
198
+ if (msg.type === "eval") {
199
+ try {
200
+ const fn = new Function(`return (${msg.expression})`);
201
+ const result = fn();
202
+ wsSend({
203
+ type: "result",
204
+ file: msg.file || "eval",
205
+ line: msg.line || 0,
206
+ column: msg.column || 0,
207
+ values: [serialize(result)],
208
+ timestamp: Date.now(),
209
+ expression: msg.expression,
210
+ });
211
+ } catch (err: unknown) {
212
+ wsSend({
213
+ type: "error",
214
+ file: msg.file || "eval",
215
+ line: msg.line || 0,
216
+ column: msg.column || 0,
217
+ values: [err instanceof Error ? err.message : String(err)],
218
+ timestamp: Date.now(),
219
+ expression: msg.expression,
220
+ });
221
+ }
222
+ }
223
+ } catch {
224
+ // invalid JSON
225
+ }
226
+ });
227
+
228
+ socket.on("close", () => {
229
+ client = null;
230
+ });
231
+
232
+ socket.on("error", () => {
233
+ client = null;
234
+ });
235
+ });
236
+
237
+ server.on("error", (err: NodeJS.ErrnoException) => {
238
+ if (err.code === "EADDRINUSE") {
239
+ originalConsole.log(`[runtime-lens] port ${PORT} in use, skipping agent server`);
240
+ }
241
+ });
242
+
243
+ server.listen(PORT, () => {
244
+ originalConsole.log(`[runtime-lens] agent listening on ws://localhost:${PORT}`);
245
+ });
246
+
247
+ server.unref();
248
+
249
+ patchConsole();
250
+
251
+ (globalThis as Record<string, unknown>).__runtimeLens = {
252
+ log: (...args: unknown[]) => {
253
+ const site = extractCallSite();
254
+ wsSend({
255
+ type: "result",
256
+ file: site.file,
257
+ line: site.line,
258
+ column: site.column,
259
+ values: args.map(a => serialize(a)),
260
+ timestamp: Date.now(),
261
+ });
262
+ },
263
+ };
@@ -0,0 +1,17 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "CommonJS",
5
+ "moduleResolution": "Node",
6
+ "strict": true,
7
+ "esModuleInterop": true,
8
+ "skipLibCheck": true,
9
+ "forceConsistentCasingInFileNames": true,
10
+ "declaration": false,
11
+ "sourceMap": true,
12
+ "outDir": "../dist/agent",
13
+ "rootDir": "."
14
+ },
15
+ "include": ["./**/*.ts"],
16
+ "exclude": ["node_modules"]
17
+ }
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env node
2
+ export { RuntimeLensMCPServer } from "./server.js";
3
+ export { LogCollector } from "./log-collector.js";
4
+ export { ProcessInspector } from "./process-inspector.js";
5
+ export { RuntimeInterceptor } from "./runtime-interceptor.js";
6
+ export * from "./types.js";
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAaA,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9D,cAAc,YAAY,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env node
2
+ import { RuntimeLensMCPServer } from "./server.js";
3
+ try {
4
+ const server = RuntimeLensMCPServer.fromEnvironment();
5
+ server.setupGracefulShutdown();
6
+ await server.start();
7
+ }
8
+ catch (error) {
9
+ console.error("Failed to start Runtime Lens MCP Server:", error);
10
+ process.exit(1);
11
+ }
12
+ export { RuntimeLensMCPServer } from "./server.js";
13
+ export { LogCollector } from "./log-collector.js";
14
+ export { ProcessInspector } from "./process-inspector.js";
15
+ export { RuntimeInterceptor } from "./runtime-interceptor.js";
16
+ export * from "./types.js";
17
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAEnD,IAAI,CAAC;IACH,MAAM,MAAM,GAAG,oBAAoB,CAAC,eAAe,EAAE,CAAC;IACtD,MAAM,CAAC,qBAAqB,EAAE,CAAC;IAC/B,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;AACvB,CAAC;AAAC,OAAO,KAAK,EAAE,CAAC;IACf,OAAO,CAAC,KAAK,CAAC,0CAA0C,EAAE,KAAK,CAAC,CAAC;IACjE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9D,cAAc,YAAY,CAAC"}
@@ -0,0 +1,73 @@
1
+ import { LogEntry, LogLevel, Framework, HttpRequest, PerformanceMetric } from "./types.js";
2
+ export declare class LogCollector {
3
+ private buffer;
4
+ private logPaths;
5
+ private projectRoot;
6
+ constructor(projectRoot?: string, logPaths?: string[]);
7
+ collectFromFiles(): Promise<void>;
8
+ collectFromProcess(): Promise<void>;
9
+ scanProjectStructure(): Promise<{
10
+ framework: Framework;
11
+ logFiles: string[];
12
+ configFiles: string[];
13
+ }>;
14
+ addLog(entry: Omit<LogEntry, "id" | "timestamp">): void;
15
+ addLogs(entries: LogEntry[]): void;
16
+ addRequest(request: Omit<HttpRequest, "id" | "timestamp">): void;
17
+ addMetric(metric: PerformanceMetric): void;
18
+ getLogs(options?: {
19
+ lines?: number;
20
+ level?: LogLevel;
21
+ framework?: Framework;
22
+ source?: string;
23
+ }): LogEntry[];
24
+ searchLogs(options: {
25
+ query: string;
26
+ level?: LogLevel;
27
+ framework?: Framework;
28
+ limit?: number;
29
+ since?: string;
30
+ }): LogEntry[];
31
+ getErrors(options?: {
32
+ limit?: number;
33
+ framework?: Framework;
34
+ grouped?: boolean;
35
+ }): LogEntry[] | {
36
+ message: string;
37
+ count: number;
38
+ lastSeen: string;
39
+ sample: LogEntry;
40
+ }[];
41
+ getRequests(options?: {
42
+ id?: string;
43
+ method?: string;
44
+ urlPattern?: string;
45
+ statusCode?: number;
46
+ limit?: number;
47
+ }): HttpRequest[];
48
+ getMetrics(options?: {
49
+ metric?: string;
50
+ since?: string;
51
+ limit?: number;
52
+ }): PerformanceMetric[];
53
+ clearLogs(): {
54
+ cleared: number;
55
+ };
56
+ getStats(): {
57
+ totalLogs: number;
58
+ totalRequests: number;
59
+ totalMetrics: number;
60
+ byLevel: Record<string, number>;
61
+ byFramework: Record<string, number>;
62
+ };
63
+ private parseLogFile;
64
+ private parseLogLine;
65
+ private tryParseJson;
66
+ private normalizeLevel;
67
+ private inferFramework;
68
+ private detectFramework;
69
+ private discoverLogFiles;
70
+ private discoverConfigFiles;
71
+ private trimBuffer;
72
+ }
73
+ //# sourceMappingURL=log-collector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"log-collector.d.ts","sourceRoot":"","sources":["../src/log-collector.ts"],"names":[],"mappings":"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"}