A Chrome DevTools extension that acts as a privacy-first "flight data recorder" for web developers. It captures a chronological narrative of a debugging session—including user interactions, network metadata, and console logs—and exports them as a structured bug report.
Core Philosophy:
- Intent over Noise: Filter out framework churn; capture only developer actions.
- Privacy by Default: Capture metadata only. No bodies, cookies, or passwords.
- Ephemeral: Data lives in memory/IndexedDB and is wiped on navigation unless "Sticky Mode" is active.
The extension utilizes the standard Chrome Extension MV3 architecture with a specific focus on the DevTools API.
- DevTools Page (
devtools.html/js):- The primary UI.
- Connects to the
backgroundworker. - Visualizes the current recording state.
- Handles ZIP generation and "Send to Service" logic.
- Background Service Worker (
background.js):- The Coordinator. Manages the "Sticky Mode" state machine using
chrome.storage.session(to handle MV3 ephemeral lifecycle). - Persists recording state flags across navigations.
- Note: Data buffering is delegated to IndexedDB directly from contexts to avoid memory pressure in the ephemeral worker.
- The Coordinator. Manages the "Sticky Mode" state machine using
- Content Script (
content.js):- Injects the
InteractionListener(clicks, keys). - Parses HTML
<head>for "Send to Service" configuration. - Handles the actual
POSTrequest for "Send to Service" to respect page CORS policies.
- Injects the
- Injected Script (Page Context):
- Hooks
console.*methods. - Crucial: Must communicate back to Content Script via
window.postMessage.
- Hooks
Goal: Record human actions to reproduce the bug. Privacy Filter:
- Clicks: Capture Selector + Coordinates.
- Keys: Capture only navigation keys (Enter, Esc, Tab, Arrows). Ignore alphanumeric keys to prevent password/PII leakage.
- Paste: Capture the "Paste" action event, but redact the clipboard payload entirely.
- Focus/Blur: Capture target selector.
Selector Strategy: Generate stable selectors in this priority order:
iddata-testid/data-cyaria-label/role- Unique Class combination
tagName:nth-child(fallback) Note: Must support Shadow DOM traversal for selectors.
Goal: Capture the "shape" of traffic without the payload. Captured Data:
- Method (GET/POST)
- URL (Sanitized: Query params allowed, but flagged if suspicious)
- Status Code
- Timing (Duration)
- Headers (Allowlist:
content-type,cache-control, etc. Blocklist:cookie,authorization).
Goal: Allow recording to persist across page reloads and navigations.
State Machine:
- Idle: Buffer is empty.
- Recording (Single): Buffer fills. On Navigation → Wipe Buffer.
- Recording (Sticky): Buffer fills. On Navigation → Keep Buffer + Insert
NavigationEvent.
Visual Indicators:
- Badge: Extension icon turns Green (Sticky) or Red (Recording).
- Panel: A persistent banner in the DevTools panel: "Sticky Mode Active: Capturing across navigations."
To accommodate varying system capabilities and site complexity, the extension supports profiles:
- Standard Mode (Default): Records Console, Network, and Clicks.
- Snapshotting: Optional toggle to capture HTML snapshots on navigation (High memory usage).
The extension looks for specific metadata in the document <head> to enable direct bug reporting.
The extension scans for either specific <meta> tags or a JSON configuration script.
Option A: Meta Tags (Simple)
<meta name="debug-report:endpoint" content="https://api.myapp.com/bugs/ingest">
<meta name="debug-report:features" content="dom,network,console">
<meta name="debug-report:session-id" content="sess_12345"> <!-- Optional Correlation ID -->Option B: JSON Config (Advanced)
<script type="application/json" id="debug-report-config">
{
"endpoint": "https://api.myapp.com/bugs/ingest",
"features": ["dom", "network", "interactions"],
"env": "staging",
"publicKey": "-----BEGIN PUBLIC KEY... (for encryption)"
}
</script>- If detected, the DevTools panel renders a "Send to Service" button.
- On click, a confirmation modal appears.
- Security Requirement: Must display the Target URL and Current Page Origin prominently.
- Preview: User must be able to expand and inspect the JSON payload.
- On confirmation, the extension performs a
POSTrequest.- Context: Request is executed via the Content Script to enforce the page's CORS policy (preventing exfiltration to arbitrary domains).
Whether downloaded as a ZIP or sent to a service, the data structure is normalized.
File Structure (ZIP):
bug-report/
├── metadata.json # Browser, Viewport, Extension Version, Timestamp
├── timeline.json # The Master Event Stream (Merged)
├── console.json # Raw Console Logs
└── network.json # Network Metadata
Timeline Event Object (JSON):
Every event in timeline.json shares a base interface:
interface TimelineEvent {
id: string;
timestamp: number;
type: 'interaction' | 'network' | 'console' | 'navigation' | 'snapshot';
data: any; // Payload specific to type
}Example Payload:
[
{
"timestamp": 167890001,
"type": "interaction",
"data": {
"action": "click",
"selector": "button#submit"
}
},
{
"timestamp": 167890002,
"type": "snapshot",
"data": {
"trigger": "click",
"html": "<body...>...</body>"
}
},
{
"timestamp": 167890010,
"type": "network",
"data": {
"method": "POST",
"url": "/api/login",
"status": 500
}
}
]- Sanitization:
- Input Fields: Values are never recorded.
- Passwords: Fields with
type="password"are ignored entirely. - Clipboard: No access requested.
- Storage:
- Data is stored in
IndexedDBwithin the extension's origin. - Data is never sent to a third party unless the user clicks "Send to Service" AND the page explicitly opts-in via HTML headers.
- Data is stored in
- Retention:
- Default: Cleared on every page load.
- Sticky Mode: Cleared on "Stop Recording" or Tab Close.
- Set up Manifest V3 structure with
chrome.storage.session(The Coordinator). - Implement IndexedDB buffering (bypassing the ephemeral Service Worker).
- Implement "Sticky Mode" state persistence.
- Implement Console and Network listeners.
- Implement
InteractionListener(clicks/keys/paste). - Implement Shadow DOM traversal for selector generation.
- Implement HTML
<head>parser. - Build "Send to Service" UI and POST logic.
- Implement ZIP generation (using
JSZip). - Final polish of selectors and visual indicators.