debug-toolkit 0.4.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 +236 -0
- package/SKILL.md +104 -0
- package/dist/capture.d.ts +46 -0
- package/dist/capture.js +246 -0
- package/dist/capture.js.map +1 -0
- package/dist/cleanup.d.ts +12 -0
- package/dist/cleanup.js +103 -0
- package/dist/cleanup.js.map +1 -0
- package/dist/cli.d.ts +40 -0
- package/dist/cli.js +109 -0
- package/dist/cli.js.map +1 -0
- package/dist/context.d.ts +59 -0
- package/dist/context.js +338 -0
- package/dist/context.js.map +1 -0
- package/dist/demo.d.ts +12 -0
- package/dist/demo.js +347 -0
- package/dist/demo.js.map +1 -0
- package/dist/hook.d.ts +17 -0
- package/dist/hook.js +106 -0
- package/dist/hook.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +203 -0
- package/dist/index.js.map +1 -0
- package/dist/injected.js +151 -0
- package/dist/instrument.d.ts +15 -0
- package/dist/instrument.js +87 -0
- package/dist/instrument.js.map +1 -0
- package/dist/mcp.d.ts +14 -0
- package/dist/mcp.js +420 -0
- package/dist/mcp.js.map +1 -0
- package/dist/memory.d.ts +73 -0
- package/dist/memory.js +291 -0
- package/dist/memory.js.map +1 -0
- package/dist/methodology.d.ts +7 -0
- package/dist/methodology.js +100 -0
- package/dist/methodology.js.map +1 -0
- package/dist/proxy.d.ts +12 -0
- package/dist/proxy.js +168 -0
- package/dist/proxy.js.map +1 -0
- package/dist/security.d.ts +27 -0
- package/dist/security.js +158 -0
- package/dist/security.js.map +1 -0
- package/dist/session.d.ts +53 -0
- package/dist/session.js +94 -0
- package/dist/session.js.map +1 -0
- package/package.json +33 -0
package/README.md
ADDED
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
# debug-toolkit
|
|
2
|
+
|
|
3
|
+
Closed-loop debugging for AI coding agents. One MCP server gives your agent the ability to **see code running** — not just read and write it.
|
|
4
|
+
|
|
5
|
+
```
|
|
6
|
+
npx debug-toolkit demo # see it work (no AI needed)
|
|
7
|
+
npx debug-toolkit init # install in your project
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
## The Problem
|
|
11
|
+
|
|
12
|
+
When an AI agent hits a bug, it reads code and guesses a fix. You run it, paste the error back, the agent guesses again. Repeat 5-8 times.
|
|
13
|
+
|
|
14
|
+
debug-toolkit eliminates that loop. The agent investigates the error, instruments the code, captures runtime output, verifies the fix, and cleans up — all through MCP tool calls. No copy-pasting. No manual log hunting.
|
|
15
|
+
|
|
16
|
+
## How It Works
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
investigate → instrument → capture → fix → verify → cleanup
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
One debug session. Full context. Diagnosis saved for next time.
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
┌─────────────────────────────────────────────────────────┐
|
|
26
|
+
│ Agent gets error from user │
|
|
27
|
+
│ ↓ │
|
|
28
|
+
│ debug_investigate → error type, source code, git, │
|
|
29
|
+
│ environment, past solutions │
|
|
30
|
+
│ ↓ │
|
|
31
|
+
│ debug_instrument → adds tagged logging to source │
|
|
32
|
+
│ ↓ │
|
|
33
|
+
│ debug_capture → collects runtime output │
|
|
34
|
+
│ ↓ │
|
|
35
|
+
│ Agent applies fix │
|
|
36
|
+
│ ↓ │
|
|
37
|
+
│ debug_verify → runs tests, confirms fix │
|
|
38
|
+
│ ↓ │
|
|
39
|
+
│ debug_cleanup → removes markers, saves diagnosis │
|
|
40
|
+
│ + causal chain to memory │
|
|
41
|
+
│ ↓ │
|
|
42
|
+
│ Next session: debug_investigate auto-recalls the fix │
|
|
43
|
+
└─────────────────────────────────────────────────────────┘
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Setup
|
|
47
|
+
|
|
48
|
+
### Any project (JS/TS/Python/Go)
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
npx debug-toolkit init
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Generates `.claude/mcp.json`, installs a pre-commit safety hook, detects your dev command. Restart Claude Code and you're done.
|
|
55
|
+
|
|
56
|
+
### Tauri projects (auto-detected)
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
cd my-tauri-app
|
|
60
|
+
npx debug-toolkit init
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
If `src-tauri/` exists, debug-toolkit automatically:
|
|
64
|
+
- Sets dev command to `cargo tauri dev`
|
|
65
|
+
- Enables `RUST_BACKTRACE=1` and `RUST_LOG=info`
|
|
66
|
+
- Parses Rust panics, backtraces, and cargo build errors
|
|
67
|
+
- Discovers and tails `tauri-plugin-log` files from platform-specific paths
|
|
68
|
+
- Detects Tauri-specific errors (invoke, capability, plugin, window, asset)
|
|
69
|
+
|
|
70
|
+
### Manual MCP config
|
|
71
|
+
|
|
72
|
+
Add to `.claude/mcp.json`:
|
|
73
|
+
|
|
74
|
+
```json
|
|
75
|
+
{
|
|
76
|
+
"mcpServers": {
|
|
77
|
+
"debug-toolkit": {
|
|
78
|
+
"command": "npx",
|
|
79
|
+
"args": ["-y", "debug-toolkit"]
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Two Modes
|
|
86
|
+
|
|
87
|
+
**Pure MCP** (default) — Just the MCP server on stdio. Agent gets all tools. No wrapper needed.
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
npx debug-toolkit
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
**Serve** — Wraps your dev server. Adds browser console/network capture via HTTP proxy + WebSocket.
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
npx debug-toolkit serve -- npm run dev
|
|
97
|
+
npx debug-toolkit serve -- cargo tauri dev
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## Tools
|
|
101
|
+
|
|
102
|
+
### debug_investigate
|
|
103
|
+
|
|
104
|
+
**Start here.** Give it an error message or stack trace. Returns:
|
|
105
|
+
|
|
106
|
+
- Error classification (type, category, severity, suggestion)
|
|
107
|
+
- Source code at the exact crash site (highlighted)
|
|
108
|
+
- Git context (branch, commit, recent changes to those files)
|
|
109
|
+
- Runtime environment (Node/Rust version, frameworks, env vars — secrets redacted)
|
|
110
|
+
- Past solutions from memory (with staleness info and causal chains)
|
|
111
|
+
|
|
112
|
+
```
|
|
113
|
+
Input: { error: "TypeError: Cannot read properties of undefined (reading 'map')" }
|
|
114
|
+
Output: { error, sourceCode, git, environment, pastSolutions, nextStep }
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### debug_recall
|
|
118
|
+
|
|
119
|
+
Search past debug sessions for similar errors. Returns diagnoses ranked by relevance, with staleness tracking (has the code changed since?) and causal chains (where was the actual bug?).
|
|
120
|
+
|
|
121
|
+
```
|
|
122
|
+
Input: { query: "TypeError undefined map" }
|
|
123
|
+
Output: { matches: [{ diagnosis, stale, rootCause }] }
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### debug_patterns
|
|
127
|
+
|
|
128
|
+
Detect systemic issues across all past sessions:
|
|
129
|
+
|
|
130
|
+
| Pattern | What it finds |
|
|
131
|
+
|---------|--------------|
|
|
132
|
+
| **Recurring error** | Same error type in same file, 3+ times |
|
|
133
|
+
| **Hot file** | Files in 15%+ of debug sessions |
|
|
134
|
+
| **Regression** | Bug fixed once, came back |
|
|
135
|
+
| **Error cluster** | Multiple errors within 2 hours |
|
|
136
|
+
|
|
137
|
+
### debug_instrument
|
|
138
|
+
|
|
139
|
+
Add tagged logging to source files. Supports JS/TS, Python, Go, and Rust:
|
|
140
|
+
|
|
141
|
+
| Language | Output |
|
|
142
|
+
|----------|--------|
|
|
143
|
+
| JS/TS | `console.log("[DBG_001]", expr)` |
|
|
144
|
+
| Python | `print(f"[DBG_001] {expr}")` |
|
|
145
|
+
| Go | `fmt.Printf("[DBG_001] %v\n", expr)` |
|
|
146
|
+
| Rust | `eprintln!("[DBG_001] {:?}", expr)` |
|
|
147
|
+
|
|
148
|
+
Each marker links to a hypothesis. Respects indentation. Auto-cleans on cleanup.
|
|
149
|
+
|
|
150
|
+
### debug_capture
|
|
151
|
+
|
|
152
|
+
Run a command and capture output, or drain buffered events from terminal, browser, and Tauri log files. Tagged output is linked to hypotheses. Results are paginated.
|
|
153
|
+
|
|
154
|
+
### debug_verify
|
|
155
|
+
|
|
156
|
+
After applying a fix, run the test command and get a clear pass/fail with exit code and error output.
|
|
157
|
+
|
|
158
|
+
### debug_cleanup
|
|
159
|
+
|
|
160
|
+
Remove ALL instrumentation, verify files are restored, and save the diagnosis + causal chain to memory. Provide `rootCause` to teach the system where the actual bug was:
|
|
161
|
+
|
|
162
|
+
```json
|
|
163
|
+
{
|
|
164
|
+
"diagnosis": "getUsers() returns undefined when db not connected",
|
|
165
|
+
"rootCause": {
|
|
166
|
+
"trigger": "missing db.connect() call",
|
|
167
|
+
"errorFile": "src/api.ts",
|
|
168
|
+
"causeFile": "src/db.ts",
|
|
169
|
+
"fixDescription": "added connect() before query"
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
### debug_session
|
|
175
|
+
|
|
176
|
+
Lightweight view of current state: hypotheses, active instruments, recent captures.
|
|
177
|
+
|
|
178
|
+
## Memory System
|
|
179
|
+
|
|
180
|
+
debug-toolkit learns from every session:
|
|
181
|
+
|
|
182
|
+
**Recall** — When you investigate a new error, it auto-searches past diagnoses. If a similar error was solved before, the agent gets the previous diagnosis, which files were involved, and the causal chain.
|
|
183
|
+
|
|
184
|
+
**Staleness** — Every diagnosis is tagged with the git SHA. When recalled, the system checks if the referenced files have changed. Stale diagnoses are flagged but still shown.
|
|
185
|
+
|
|
186
|
+
**Causal chains** — Records where the error appeared vs. where the actual bug was. Next time, the agent goes straight to the cause file instead of the symptom.
|
|
187
|
+
|
|
188
|
+
**Patterns** — Detects recurring errors, hot files, regressions, and error clusters across all sessions.
|
|
189
|
+
|
|
190
|
+
## Language Support
|
|
191
|
+
|
|
192
|
+
| Feature | JS/TS | Python | Go | Rust/Tauri |
|
|
193
|
+
|---------|-------|--------|----|------------|
|
|
194
|
+
| Stack trace parsing | Node.js frames | Python tracebacks | — | Panics, backtraces, cargo errors |
|
|
195
|
+
| Error classification | TypeError, ReferenceError, etc. | — | — | Panic, borrow, Tauri IPC/capability/plugin |
|
|
196
|
+
| Code instrumentation | `console.log` | `print()` | `fmt.Printf` | `eprintln!` |
|
|
197
|
+
| Source extraction | Yes | Yes | Yes | Yes |
|
|
198
|
+
| Log file tailing | — | — | — | `tauri-plugin-log` auto-discovery |
|
|
199
|
+
| Environment detection | package.json, frameworks | Python version | — | Cargo.toml, tauri.conf.json, plugins |
|
|
200
|
+
|
|
201
|
+
## Security
|
|
202
|
+
|
|
203
|
+
- **Path traversal protection** — all file operations validated against project root
|
|
204
|
+
- **Expression validation** — blocks `eval`, `require`, `exec` in instrumentation
|
|
205
|
+
- **Secret redaction** — tokens, API keys, passwords, JWTs auto-redacted before storage
|
|
206
|
+
- **Localhost-only proxy** — binds to 127.0.0.1
|
|
207
|
+
- **Pre-commit hook** — blocks commits containing debug markers
|
|
208
|
+
- **Atomic writes** — temp file + rename, no corruption on crash
|
|
209
|
+
- **`.debug/` auto-gitignored**
|
|
210
|
+
|
|
211
|
+
## Architecture
|
|
212
|
+
|
|
213
|
+
15 files, 3,451 lines of TypeScript. 4 npm dependencies.
|
|
214
|
+
|
|
215
|
+
```
|
|
216
|
+
src/
|
|
217
|
+
mcp.ts 473 lines — 8 tools + 1 resource + MCP server
|
|
218
|
+
context.ts 420 lines — Investigation engine (stack parsing, source, git, env)
|
|
219
|
+
demo.ts 398 lines — Self-contained interactive demo
|
|
220
|
+
memory.ts 369 lines — Cross-session memory with staleness + patterns
|
|
221
|
+
capture.ts 276 lines — Ring buffers, terminal pipe, Tauri log tailing
|
|
222
|
+
proxy.ts 200 lines — HTTP proxy + HTML injection + WebSocket
|
|
223
|
+
index.ts 204 lines — CLI entry point (mcp, serve, init, demo, clean)
|
|
224
|
+
security.ts 185 lines — Path traversal, expression validation, redaction
|
|
225
|
+
session.ts 162 lines — Data model, atomic persistence, marker index
|
|
226
|
+
injected.js 151 lines — Browser console/network/error capture script
|
|
227
|
+
instrument.ts 140 lines — Language-aware instrumentation (JS/TS/Py/Go/Rust)
|
|
228
|
+
cleanup.ts 126 lines — Single-pass marker removal with verification
|
|
229
|
+
cli.ts 125 lines — ANSI terminal UI
|
|
230
|
+
hook.ts 122 lines — Git pre-commit hook
|
|
231
|
+
methodology.ts 100 lines — Always-available debugging guide
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
## License
|
|
235
|
+
|
|
236
|
+
MIT
|
package/SKILL.md
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: debug-toolkit
|
|
3
|
+
description: Closed-loop debugging for AI agents with cross-session memory. Investigate errors, recall past fixes, detect patterns, instrument code, capture output, verify fixes, auto-cleanup with causal chains. Start every debugging task with debug_investigate.
|
|
4
|
+
tools: ["debug_investigate", "debug_recall", "debug_patterns", "debug_instrument", "debug_capture", "debug_verify", "debug_cleanup", "debug_session"]
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# debug-toolkit
|
|
8
|
+
|
|
9
|
+
You have access to a debugging toolkit via MCP. These tools let you SEE code running — not just read and write it. They also learn from every debug session and get smarter over time.
|
|
10
|
+
|
|
11
|
+
## When to Use
|
|
12
|
+
|
|
13
|
+
Use these tools whenever you encounter:
|
|
14
|
+
- A runtime error or stack trace
|
|
15
|
+
- A test failure
|
|
16
|
+
- Code that runs but produces wrong output
|
|
17
|
+
- A bug report from the user
|
|
18
|
+
|
|
19
|
+
## The Workflow
|
|
20
|
+
|
|
21
|
+
**ALWAYS start with `debug_investigate`.** It auto-recalls past solutions.
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
1. debug_investigate → understand the error + auto-recall past fixes
|
|
25
|
+
2. debug_instrument → add logging if investigation wasn't enough
|
|
26
|
+
3. debug_capture → collect runtime output
|
|
27
|
+
4. (apply fix) → edit the code
|
|
28
|
+
5. debug_verify → confirm the fix works
|
|
29
|
+
6. debug_cleanup → remove markers, save diagnosis + causal chain
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Tool Reference
|
|
33
|
+
|
|
34
|
+
### debug_investigate
|
|
35
|
+
**Start here.** Parses error text, finds source files, shows the exact lines, gets git context. Auto-searches memory for past solutions with staleness info.
|
|
36
|
+
```
|
|
37
|
+
Input: { error: "<stack trace>", problem?: "description" }
|
|
38
|
+
Output: { error, sourceCode, git, environment, pastSolutions?, nextStep }
|
|
39
|
+
```
|
|
40
|
+
Past solutions include `stale` (has code changed?) and `rootCause` (causal chain from last fix).
|
|
41
|
+
|
|
42
|
+
### debug_recall
|
|
43
|
+
Explicitly search past debug sessions. Returns diagnoses with staleness and causal chains.
|
|
44
|
+
```
|
|
45
|
+
Input: { query: "TypeError Cannot read properties email" }
|
|
46
|
+
Output: { matches: [{ problem, diagnosis, stale, staleness?, rootCause? }] }
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### debug_patterns
|
|
50
|
+
Detect patterns across ALL past sessions. Use periodically.
|
|
51
|
+
```
|
|
52
|
+
Input: {}
|
|
53
|
+
Output: { patterns: [{ type, severity, message }] }
|
|
54
|
+
```
|
|
55
|
+
Pattern types: `recurring_error`, `hot_file`, `regression`, `error_cluster`.
|
|
56
|
+
|
|
57
|
+
### debug_instrument
|
|
58
|
+
Add tagged logging. Each marker links to a hypothesis.
|
|
59
|
+
```
|
|
60
|
+
Input: { sessionId, filePath, lineNumber, expression: "req.body", hypothesis?: "body is undefined" }
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### debug_capture
|
|
64
|
+
Run a command and capture output, or drain buffered events.
|
|
65
|
+
```
|
|
66
|
+
Input: { sessionId, command?: "npm test", limit?: 30 }
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### debug_verify
|
|
70
|
+
After applying a fix, run the test command and check pass/fail.
|
|
71
|
+
```
|
|
72
|
+
Input: { sessionId, command: "npm test" }
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### debug_cleanup
|
|
76
|
+
Remove ALL instrumentation, save diagnosis + causal chain to memory.
|
|
77
|
+
```
|
|
78
|
+
Input: {
|
|
79
|
+
sessionId,
|
|
80
|
+
diagnosis?: "root cause was...",
|
|
81
|
+
rootCause?: {
|
|
82
|
+
trigger: "missing null check",
|
|
83
|
+
errorFile: "src/api.ts",
|
|
84
|
+
causeFile: "src/db.ts",
|
|
85
|
+
fixDescription: "added null check before .map()"
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
```
|
|
89
|
+
**Always provide rootCause** — it's the most valuable data for future sessions.
|
|
90
|
+
|
|
91
|
+
### debug_session
|
|
92
|
+
Lightweight view of current session state.
|
|
93
|
+
```
|
|
94
|
+
Input: { sessionId }
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## Rules
|
|
98
|
+
1. NEVER skip debug_investigate. It's the highest-leverage step.
|
|
99
|
+
2. Read `nextStep` in every response — it tells you what to do.
|
|
100
|
+
3. If past solutions are found, check `stale` — fresh solutions can be trusted.
|
|
101
|
+
4. Instrument 1-2 files, not 10. Narrow first.
|
|
102
|
+
5. ALWAYS run debug_verify before claiming a fix works.
|
|
103
|
+
6. ALWAYS provide `rootCause` in debug_cleanup — it teaches the system.
|
|
104
|
+
7. Run debug_patterns periodically to spot systemic issues.
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { type ChildProcess } from "node:child_process";
|
|
2
|
+
import { type Capture, type DebugSession } from "./session.js";
|
|
3
|
+
declare class RingBuffer<T> {
|
|
4
|
+
private buf;
|
|
5
|
+
private head;
|
|
6
|
+
private count;
|
|
7
|
+
private cap;
|
|
8
|
+
constructor(capacity: number);
|
|
9
|
+
push(item: T): void;
|
|
10
|
+
drain(): T[];
|
|
11
|
+
get length(): number;
|
|
12
|
+
}
|
|
13
|
+
export declare const terminalBuffer: RingBuffer<Capture>;
|
|
14
|
+
export declare const browserBuffer: RingBuffer<Capture>;
|
|
15
|
+
export declare function pipeProcess(child: ChildProcess): void;
|
|
16
|
+
export declare function runAndCapture(command: string, timeoutMs?: number): Promise<Capture[]>;
|
|
17
|
+
export declare function onBrowserEvent(event: {
|
|
18
|
+
type: string;
|
|
19
|
+
data: unknown;
|
|
20
|
+
ts: number;
|
|
21
|
+
}): void;
|
|
22
|
+
export declare function drainCaptures(cwd: string, session: DebugSession): Capture[];
|
|
23
|
+
/**
|
|
24
|
+
* Discover Tauri log files for a project.
|
|
25
|
+
* Searches platform-specific log directories based on the bundle identifier.
|
|
26
|
+
*/
|
|
27
|
+
export declare function discoverTauriLogs(cwd: string): {
|
|
28
|
+
logDir: string | null;
|
|
29
|
+
logFiles: string[];
|
|
30
|
+
identifier: string | null;
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* Read recent lines from Tauri log files.
|
|
34
|
+
* Returns captures from the most recent log file.
|
|
35
|
+
*/
|
|
36
|
+
export declare function readTauriLogs(cwd: string, tailLines?: number): Capture[];
|
|
37
|
+
export declare function getRecentCaptures(session: DebugSession, opts?: {
|
|
38
|
+
limit?: number;
|
|
39
|
+
source?: string;
|
|
40
|
+
markerOnly?: boolean;
|
|
41
|
+
}): {
|
|
42
|
+
captures: Capture[];
|
|
43
|
+
total: number;
|
|
44
|
+
showing: number;
|
|
45
|
+
};
|
|
46
|
+
export {};
|
package/dist/capture.js
ADDED
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
import { existsSync, readFileSync, readdirSync, statSync } from "node:fs";
|
|
3
|
+
import { join, basename } from "node:path";
|
|
4
|
+
import { redactSensitiveData } from "./security.js";
|
|
5
|
+
import { newCaptureId, lookupHypothesis, saveSession, } from "./session.js";
|
|
6
|
+
// --- Marker tag extraction ---
|
|
7
|
+
const MARKER_RE = /\[DBG_(\d{3})\]/;
|
|
8
|
+
function extractMarkerTag(text) {
|
|
9
|
+
const m = MARKER_RE.exec(text);
|
|
10
|
+
return m ? `DBG_${m[1]}` : null;
|
|
11
|
+
}
|
|
12
|
+
// --- Ring buffer: fixed-size, no allocation on push ---
|
|
13
|
+
class RingBuffer {
|
|
14
|
+
buf;
|
|
15
|
+
head = 0;
|
|
16
|
+
count = 0;
|
|
17
|
+
cap;
|
|
18
|
+
constructor(capacity) {
|
|
19
|
+
this.cap = capacity;
|
|
20
|
+
this.buf = new Array(capacity);
|
|
21
|
+
}
|
|
22
|
+
push(item) {
|
|
23
|
+
this.buf[this.head] = item;
|
|
24
|
+
this.head = (this.head + 1) % this.cap;
|
|
25
|
+
if (this.count < this.cap)
|
|
26
|
+
this.count++;
|
|
27
|
+
}
|
|
28
|
+
drain() {
|
|
29
|
+
if (this.count === 0)
|
|
30
|
+
return [];
|
|
31
|
+
const start = (this.head - this.count + this.cap) % this.cap;
|
|
32
|
+
const result = [];
|
|
33
|
+
for (let i = 0; i < this.count; i++) {
|
|
34
|
+
result.push(this.buf[(start + i) % this.cap]);
|
|
35
|
+
}
|
|
36
|
+
this.count = 0;
|
|
37
|
+
this.head = 0;
|
|
38
|
+
return result;
|
|
39
|
+
}
|
|
40
|
+
get length() { return this.count; }
|
|
41
|
+
}
|
|
42
|
+
// --- Buffers ---
|
|
43
|
+
export const terminalBuffer = new RingBuffer(500);
|
|
44
|
+
export const browserBuffer = new RingBuffer(200);
|
|
45
|
+
// --- Terminal pipe ---
|
|
46
|
+
export function pipeProcess(child) {
|
|
47
|
+
const pipe = (stream, isErr) => {
|
|
48
|
+
if (!stream)
|
|
49
|
+
return;
|
|
50
|
+
stream.on("data", (chunk) => {
|
|
51
|
+
const text = chunk.toString();
|
|
52
|
+
(isErr ? process.stderr : process.stdout).write(chunk);
|
|
53
|
+
for (const line of text.split("\n")) {
|
|
54
|
+
const t = line.trim();
|
|
55
|
+
if (!t)
|
|
56
|
+
continue;
|
|
57
|
+
terminalBuffer.push({
|
|
58
|
+
id: newCaptureId(),
|
|
59
|
+
timestamp: new Date().toISOString(),
|
|
60
|
+
source: "terminal",
|
|
61
|
+
markerTag: extractMarkerTag(t),
|
|
62
|
+
data: { text: redactSensitiveData(t), stream: isErr ? "stderr" : "stdout" },
|
|
63
|
+
hypothesisId: null,
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
};
|
|
68
|
+
pipe(child.stdout, false);
|
|
69
|
+
pipe(child.stderr, true);
|
|
70
|
+
}
|
|
71
|
+
// --- Run command and capture ---
|
|
72
|
+
export function runAndCapture(command, timeoutMs = 30_000) {
|
|
73
|
+
return new Promise((resolve, reject) => {
|
|
74
|
+
const out = [];
|
|
75
|
+
const child = spawn(command, { shell: true, stdio: "pipe" });
|
|
76
|
+
const timer = setTimeout(() => { child.kill(); resolve(out); }, timeoutMs);
|
|
77
|
+
const handle = (stream, name) => {
|
|
78
|
+
if (!stream)
|
|
79
|
+
return;
|
|
80
|
+
stream.on("data", (chunk) => {
|
|
81
|
+
for (const line of chunk.toString().split("\n")) {
|
|
82
|
+
const t = line.trim();
|
|
83
|
+
if (!t)
|
|
84
|
+
continue;
|
|
85
|
+
out.push({
|
|
86
|
+
id: newCaptureId(),
|
|
87
|
+
timestamp: new Date().toISOString(),
|
|
88
|
+
source: "terminal",
|
|
89
|
+
markerTag: extractMarkerTag(t),
|
|
90
|
+
data: { text: redactSensitiveData(t), stream: name },
|
|
91
|
+
hypothesisId: null,
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
};
|
|
96
|
+
handle(child.stdout, "stdout");
|
|
97
|
+
handle(child.stderr, "stderr");
|
|
98
|
+
child.on("close", (code) => {
|
|
99
|
+
clearTimeout(timer);
|
|
100
|
+
out.push({
|
|
101
|
+
id: newCaptureId(), timestamp: new Date().toISOString(),
|
|
102
|
+
source: "terminal", markerTag: null,
|
|
103
|
+
data: { text: `exit:${code}`, stream: "meta" }, hypothesisId: null,
|
|
104
|
+
});
|
|
105
|
+
resolve(out);
|
|
106
|
+
});
|
|
107
|
+
child.on("error", (e) => { clearTimeout(timer); reject(e); });
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
// --- Browser event handler ---
|
|
111
|
+
export function onBrowserEvent(event) {
|
|
112
|
+
const srcMap = {
|
|
113
|
+
console: "browser-console", network: "browser-network", error: "browser-error",
|
|
114
|
+
};
|
|
115
|
+
const src = srcMap[event.type] ?? "browser-console";
|
|
116
|
+
const str = typeof event.data === "object" ? JSON.stringify(event.data) : String(event.data);
|
|
117
|
+
browserBuffer.push({
|
|
118
|
+
id: newCaptureId(),
|
|
119
|
+
timestamp: new Date(event.ts).toISOString(),
|
|
120
|
+
source: src,
|
|
121
|
+
markerTag: extractMarkerTag(str),
|
|
122
|
+
data: event.data,
|
|
123
|
+
hypothesisId: null,
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
// --- Drain + link (O(n) using pre-built index, not O(n*m)) ---
|
|
127
|
+
export function drainCaptures(cwd, session) {
|
|
128
|
+
const all = [...terminalBuffer.drain(), ...browserBuffer.drain()];
|
|
129
|
+
for (const c of all) {
|
|
130
|
+
if (c.markerTag) {
|
|
131
|
+
// O(1) lookup via pre-built index instead of O(m) scan
|
|
132
|
+
const hypId = lookupHypothesis(session, c.markerTag);
|
|
133
|
+
if (hypId) {
|
|
134
|
+
c.hypothesisId = hypId;
|
|
135
|
+
const hyp = session.hypotheses.find((h) => h.id === hypId);
|
|
136
|
+
if (hyp && !hyp.evidence.includes(c.id))
|
|
137
|
+
hyp.evidence.push(c.id);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
session.captures.push(...all);
|
|
142
|
+
saveSession(cwd, session);
|
|
143
|
+
return all;
|
|
144
|
+
}
|
|
145
|
+
// --- Tauri log file discovery and reading ---
|
|
146
|
+
/**
|
|
147
|
+
* Discover Tauri log files for a project.
|
|
148
|
+
* Searches platform-specific log directories based on the bundle identifier.
|
|
149
|
+
*/
|
|
150
|
+
export function discoverTauriLogs(cwd) {
|
|
151
|
+
// Read bundle identifier from tauri.conf.json
|
|
152
|
+
let identifier = null;
|
|
153
|
+
const confPath = join(cwd, "src-tauri", "tauri.conf.json");
|
|
154
|
+
if (existsSync(confPath)) {
|
|
155
|
+
try {
|
|
156
|
+
const conf = JSON.parse(readFileSync(confPath, "utf-8"));
|
|
157
|
+
identifier = conf.identifier ?? conf.bundle?.identifier ?? null;
|
|
158
|
+
}
|
|
159
|
+
catch { }
|
|
160
|
+
}
|
|
161
|
+
if (!identifier)
|
|
162
|
+
return { logDir: null, logFiles: [], identifier: null };
|
|
163
|
+
// Platform-specific log directories
|
|
164
|
+
const home = process.env.HOME ?? process.env.USERPROFILE ?? "";
|
|
165
|
+
const candidates = [];
|
|
166
|
+
if (process.platform === "darwin") {
|
|
167
|
+
candidates.push(join(home, "Library", "Logs", identifier));
|
|
168
|
+
}
|
|
169
|
+
else if (process.platform === "win32") {
|
|
170
|
+
const appdata = process.env.APPDATA ?? join(home, "AppData", "Roaming");
|
|
171
|
+
candidates.push(join(appdata, identifier, "logs"));
|
|
172
|
+
}
|
|
173
|
+
else {
|
|
174
|
+
// Linux
|
|
175
|
+
candidates.push(join(home, ".config", identifier, "logs"));
|
|
176
|
+
}
|
|
177
|
+
for (const dir of candidates) {
|
|
178
|
+
if (existsSync(dir)) {
|
|
179
|
+
try {
|
|
180
|
+
const files = readdirSync(dir)
|
|
181
|
+
.filter((f) => f.endsWith(".log"))
|
|
182
|
+
.map((f) => join(dir, f))
|
|
183
|
+
.sort((a, b) => {
|
|
184
|
+
// Most recently modified first
|
|
185
|
+
try {
|
|
186
|
+
return statSync(b).mtimeMs - statSync(a).mtimeMs;
|
|
187
|
+
}
|
|
188
|
+
catch {
|
|
189
|
+
return 0;
|
|
190
|
+
}
|
|
191
|
+
});
|
|
192
|
+
return { logDir: dir, logFiles: files, identifier };
|
|
193
|
+
}
|
|
194
|
+
catch { }
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
return { logDir: null, logFiles: [], identifier };
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Read recent lines from Tauri log files.
|
|
201
|
+
* Returns captures from the most recent log file.
|
|
202
|
+
*/
|
|
203
|
+
export function readTauriLogs(cwd, tailLines = 50) {
|
|
204
|
+
const { logFiles } = discoverTauriLogs(cwd);
|
|
205
|
+
if (logFiles.length === 0)
|
|
206
|
+
return [];
|
|
207
|
+
const captures = [];
|
|
208
|
+
const logFile = logFiles[0]; // Most recent
|
|
209
|
+
try {
|
|
210
|
+
const content = readFileSync(logFile, "utf-8");
|
|
211
|
+
const lines = content.split("\n").slice(-tailLines);
|
|
212
|
+
for (const line of lines) {
|
|
213
|
+
const t = line.trim();
|
|
214
|
+
if (!t)
|
|
215
|
+
continue;
|
|
216
|
+
captures.push({
|
|
217
|
+
id: newCaptureId(),
|
|
218
|
+
timestamp: new Date().toISOString(),
|
|
219
|
+
source: "tauri-log",
|
|
220
|
+
markerTag: extractMarkerTag(t),
|
|
221
|
+
data: { text: redactSensitiveData(t), file: basename(logFile), stream: "log" },
|
|
222
|
+
hypothesisId: null,
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
catch { }
|
|
227
|
+
return captures;
|
|
228
|
+
}
|
|
229
|
+
// --- Paginated capture retrieval (avoids dumping entire session) ---
|
|
230
|
+
export function getRecentCaptures(session, opts = {}) {
|
|
231
|
+
let filtered = session.captures;
|
|
232
|
+
if (opts.source) {
|
|
233
|
+
filtered = filtered.filter((c) => c.source === opts.source);
|
|
234
|
+
}
|
|
235
|
+
if (opts.markerOnly) {
|
|
236
|
+
filtered = filtered.filter((c) => c.markerTag !== null);
|
|
237
|
+
}
|
|
238
|
+
const limit = opts.limit ?? 50;
|
|
239
|
+
const recent = filtered.slice(-limit);
|
|
240
|
+
return {
|
|
241
|
+
captures: recent,
|
|
242
|
+
total: filtered.length,
|
|
243
|
+
showing: recent.length,
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
//# sourceMappingURL=capture.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capture.js","sourceRoot":"","sources":["../src/capture.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type DebugSession } from "./session.js";
|
|
2
|
+
export interface CleanupResult {
|
|
3
|
+
cleaned: number;
|
|
4
|
+
verified: boolean;
|
|
5
|
+
errors: string[];
|
|
6
|
+
filesProcessed: string[];
|
|
7
|
+
}
|
|
8
|
+
export declare function cleanupSession(cwd: string, session: DebugSession): CleanupResult;
|
|
9
|
+
/**
|
|
10
|
+
* Emergency cleanup from manifest-less scan of session files.
|
|
11
|
+
*/
|
|
12
|
+
export declare function cleanupFromManifest(cwd: string): CleanupResult;
|