Skip to content

Commit 6bdb384

Browse files
committed
Initial release — Chrome extension for capturing debug context
Captures DOM events, console logs, network requests, and screenshots during browsing sessions. Exports structured reports (JSON, Markdown, TOON) for AI coding assistants. Includes screenshot annotator, manual notes, auto-redaction, and ZIP export.
0 parents  commit 6bdb384

31 files changed

Lines changed: 4447 additions & 0 deletions

.gitignore

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# OS
2+
.DS_Store
3+
Thumbs.db
4+
5+
# IDE
6+
.vscode/
7+
.idea/
8+
*.swp
9+
*.swo
10+
11+
# Debug artifacts
12+
debug-report-*.json
13+
debug-report-*.zip
14+
*.toon
15+
16+
# Node (if ever added)
17+
node_modules/
18+
package-lock.json

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2025 Vibery Studio
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
# Debug Helper
2+
3+
Chrome extension that captures browser debug context (DOM events, console logs, network requests, screenshots) and exports structured reports for coding agents.
4+
5+
![Chrome Extension](https://img.shields.io/badge/Manifest-V3-blue) ![No Dependencies](https://img.shields.io/badge/Dependencies-None-green)
6+
7+
## What it does
8+
9+
Record a browsing session — every click, input, scroll, console error, and network request gets captured with timestamps. Take annotated screenshots along the way. Add manual notes. Export everything as a structured report that AI coding assistants can read and act on.
10+
11+
## Install
12+
13+
1. Clone this repo
14+
2. Open `chrome://extensions`
15+
3. Enable **Developer mode**
16+
4. Click **Load unpacked** → select the repo folder
17+
5. Pin the extension for quick access
18+
19+
## Usage
20+
21+
**Start recording:** Click the extension icon → **Start Recording** (or `Cmd+Shift+R` / `Ctrl+Shift+R`)
22+
23+
**During recording:**
24+
- Browse normally — all interactions are captured automatically
25+
- Take screenshots: `Cmd+Shift+S` / `Ctrl+Shift+S`
26+
- Add notes: type in the note bar that appears in the popup or side panel
27+
- Open the side panel for live feed of captured events
28+
29+
**Export:** Stop recording → choose format → copy or download ZIP
30+
31+
## Export Formats
32+
33+
| Format | Best for |
34+
|--------|----------|
35+
| **Markdown** | Pasting into chat with AI assistants |
36+
| **JSON** | Programmatic consumption, CI pipelines |
37+
| **TOON** | Token-efficient format optimized for LLMs |
38+
39+
All formats include: step timeline, console errors, network failures, screenshot references, and auto-generated summary.
40+
41+
## Features
42+
43+
- **DOM event capture** — clicks, inputs, scrolls, form submissions with element context
44+
- **Console capture** — errors, warnings, logs with stack traces
45+
- **Network capture** — fetch & XHR with status, duration, response bodies for errors
46+
- **Screenshots** — capture + annotate with rectangles, arrows, text, freehand, counters, crop
47+
- **Manual notes** — add text annotations to the step timeline during recording
48+
- **Auto-redaction** — strips Bearer tokens, API keys, passwords before storage
49+
- **Deduplication** — collapses rapid duplicate clicks and input/change/submit overlaps
50+
- **Storage management** — chunked event storage, auto-cleanup at 80% quota
51+
- **ZIP export** — report + screenshot files bundled together
52+
53+
## Keyboard Shortcuts
54+
55+
| Shortcut | Action |
56+
|----------|--------|
57+
| `Cmd/Ctrl+Shift+R` | Toggle recording |
58+
| `Cmd/Ctrl+Shift+S` | Capture screenshot |
59+
60+
## Architecture
61+
62+
```
63+
Content Scripts (page) → Bridge → Service Worker → Storage → UI
64+
↓ ↓
65+
DOM events IndexedDB (screenshots)
66+
Console logs chrome.storage (events, sessions)
67+
Network requests
68+
```
69+
70+
**Content scripts** run in two worlds:
71+
- ISOLATED: `recorder.js` (DOM events), `bridge.js` (message relay)
72+
- MAIN: `console-capture.js`, `network-capture.js` (intercept native APIs)
73+
74+
**Service worker** buffers events (flushes every 2s or 50 events), manages sessions, handles exports.
75+
76+
**No external dependencies.** ZIP builder, TOON encoder, and all utilities are built-in.
77+
78+
## File Structure
79+
80+
```
81+
├── manifest.json # Extension config (MV3)
82+
├── background/
83+
│ └── service-worker.js # Session, event, export management
84+
├── content/
85+
│ ├── recorder.js # DOM event capture (ISOLATED)
86+
│ ├── bridge.js # MAIN→ISOLATED relay
87+
│ ├── console-capture.js # Console interception (MAIN)
88+
│ └── network-capture.js # Network interception (MAIN)
89+
├── popup/
90+
│ ├── popup.html/js/css # Extension popup UI
91+
├── sidepanel/
92+
│ ├── sidepanel.html/js/css # Side panel with live feed, history, export
93+
├── annotator/
94+
│ ├── annotator.html/js/css # Screenshot annotation tool
95+
├── devtools/
96+
│ ├── devtools.html/js # DevTools integration
97+
│ └── panel.html/js
98+
├── lib/
99+
│ ├── storage.js # Chrome storage + IndexedDB wrapper
100+
│ ├── export.js # Report generation (JSON/MD/TOON)
101+
│ ├── toon.js # TOON format encoder
102+
│ ├── zip.js # Minimal ZIP builder
103+
│ └── utils.js # Shared utilities
104+
├── styles/
105+
│ └── common.css # Global theme and components
106+
└── icons/
107+
└── icon{16,48,128}.png
108+
```
109+
110+
## Export Example
111+
112+
```markdown
113+
# Debug Report
114+
**URL:** https://example.com
115+
**Duration:** 12400ms
116+
117+
> Clicked "Login". Entered "user@test.com". Submitted form. Note: "Check validation error".
118+
119+
## Steps
120+
1. `+0.3s` Clicked "Login"
121+
2. `+1.2s` Typed "user@test.com" in input#email
122+
3. `+2.8s` Submitted form
123+
4. `+3.1s` 📝 Check validation error — see [Screenshot 1](#screenshot-1)
124+
125+
## Console Errors
126+
- **[ERROR]** `+3.2s`: TypeError: Cannot read property 'value' of null
127+
128+
## Network Errors
129+
- **POST /api/login** → 422 (180ms)
130+
```
131+
132+
## License
133+
134+
MIT

annotator/annotator.css

Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
body {
2+
display: flex;
3+
flex-direction: column;
4+
height: 100vh;
5+
overflow: hidden;
6+
margin: 0;
7+
}
8+
9+
.toolbar {
10+
display: flex;
11+
align-items: center;
12+
gap: 12px;
13+
padding: 8px 12px;
14+
background: var(--bg-secondary);
15+
border-bottom: 1px solid var(--border);
16+
flex-wrap: wrap;
17+
flex-shrink: 0;
18+
}
19+
20+
.tool-group {
21+
display: flex;
22+
align-items: center;
23+
gap: 6px;
24+
}
25+
26+
.tool-btn {
27+
width: 32px;
28+
height: 32px;
29+
border: 1px solid var(--border);
30+
border-radius: var(--radius);
31+
background: var(--bg);
32+
font-size: 16px;
33+
cursor: pointer;
34+
display: flex;
35+
align-items: center;
36+
justify-content: center;
37+
padding: 0;
38+
}
39+
40+
.tool-btn svg {
41+
width: 16px;
42+
height: 16px;
43+
flex-shrink: 0;
44+
}
45+
46+
.tool-btn.active {
47+
background: var(--primary);
48+
color: #fff;
49+
border-color: var(--primary);
50+
}
51+
52+
#color { width: 32px; height: 32px; border: none; cursor: pointer; }
53+
54+
#lineWidth {
55+
padding: 4px;
56+
border: 1px solid var(--border);
57+
border-radius: var(--radius);
58+
font-size: 12px;
59+
}
60+
61+
#zoom-level {
62+
font-size: 12px;
63+
min-width: 40px;
64+
text-align: center;
65+
color: var(--text-secondary);
66+
}
67+
68+
/* Workspace = canvas + layers side-by-side */
69+
.workspace {
70+
flex: 1;
71+
display: flex;
72+
overflow: hidden;
73+
}
74+
75+
.canvas-container {
76+
flex: 1;
77+
overflow: auto;
78+
display: flex;
79+
justify-content: center;
80+
align-items: flex-start;
81+
padding: 12px;
82+
background: #e5e7eb;
83+
position: relative;
84+
}
85+
86+
canvas {
87+
box-shadow: 0 2px 8px rgba(0,0,0,0.15);
88+
}
89+
90+
canvas.cursor-crosshair { cursor: crosshair; }
91+
canvas.cursor-move { cursor: move; }
92+
canvas.cursor-default { cursor: default; }
93+
94+
/* Layers panel */
95+
.layers-panel {
96+
width: 180px;
97+
flex-shrink: 0;
98+
background: var(--bg);
99+
border-left: 1px solid var(--border);
100+
display: flex;
101+
flex-direction: column;
102+
font-size: 12px;
103+
}
104+
105+
.layers-panel.collapsed { width: 0; overflow: hidden; border: none; }
106+
.layers-panel.collapsed + .canvas-reopen { display: block; }
107+
108+
/* Floating reopen button when layers panel is collapsed */
109+
.canvas-reopen-btn {
110+
position: absolute;
111+
top: 8px;
112+
right: 8px;
113+
z-index: 10;
114+
width: 28px;
115+
height: 28px;
116+
border: 1px solid var(--border);
117+
border-radius: var(--radius);
118+
background: var(--bg);
119+
cursor: pointer;
120+
font-size: 14px;
121+
display: none;
122+
align-items: center;
123+
justify-content: center;
124+
box-shadow: 0 1px 4px rgba(0,0,0,0.15);
125+
}
126+
127+
.canvas-reopen-btn.visible { display: flex; }
128+
129+
.layers-header {
130+
display: flex;
131+
align-items: center;
132+
justify-content: space-between;
133+
padding: 8px 10px;
134+
font-weight: 600;
135+
border-bottom: 1px solid var(--border);
136+
font-size: 11px;
137+
text-transform: uppercase;
138+
color: var(--text-secondary);
139+
}
140+
141+
.layers-list {
142+
flex: 1;
143+
overflow-y: auto;
144+
}
145+
146+
.layer-item {
147+
display: flex;
148+
align-items: center;
149+
gap: 6px;
150+
padding: 6px 10px;
151+
cursor: pointer;
152+
border-bottom: 1px solid var(--border);
153+
font-size: 11px;
154+
user-select: none;
155+
}
156+
157+
.layer-item:hover { background: var(--bg-secondary); }
158+
.layer-item.selected { background: #dbeafe; }
159+
160+
.layer-item .layer-icon {
161+
width: 16px;
162+
text-align: center;
163+
flex-shrink: 0;
164+
font-size: 13px;
165+
}
166+
167+
.layer-item .layer-label {
168+
flex: 1;
169+
overflow: hidden;
170+
text-overflow: ellipsis;
171+
white-space: nowrap;
172+
}
173+
174+
.layer-item .layer-vis {
175+
width: 16px;
176+
text-align: center;
177+
cursor: pointer;
178+
opacity: 0.5;
179+
flex-shrink: 0;
180+
}
181+
182+
.layer-item .layer-vis:hover { opacity: 1; }
183+
.layer-item .layer-vis.hidden-layer { opacity: 0.2; }
184+
185+
.layers-actions {
186+
display: flex;
187+
gap: 4px;
188+
padding: 6px 10px;
189+
border-top: 1px solid var(--border);
190+
}
191+
192+
.layers-actions .btn { flex: 1; font-size: 12px; }

0 commit comments

Comments
 (0)