browsertrack 0.0.1 → 0.1.1

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 (110) hide show
  1. package/.github/workflows/docs.yml +54 -0
  2. package/AGENTS.md +133 -0
  3. package/README.md +143 -0
  4. package/dist/chunk-6VA7GBAO.js +246 -0
  5. package/dist/chunk-6VA7GBAO.js.map +1 -0
  6. package/dist/chunk-G2Y3CXCY.js +659 -0
  7. package/dist/chunk-G2Y3CXCY.js.map +1 -0
  8. package/dist/chunk-ILRYKMME.js +1228 -0
  9. package/dist/chunk-ILRYKMME.js.map +1 -0
  10. package/dist/chunk-SKCMT2DE.js +2641 -0
  11. package/dist/chunk-SKCMT2DE.js.map +1 -0
  12. package/dist/chunk-SPCIROIU.js +616 -0
  13. package/dist/chunk-SPCIROIU.js.map +1 -0
  14. package/dist/cli/index.js +2942 -0
  15. package/dist/cli/index.js.map +1 -0
  16. package/dist/client/index.cjs +2780 -0
  17. package/dist/client/index.d.ts +211 -0
  18. package/dist/client/index.js +20 -0
  19. package/dist/client/index.js.map +1 -0
  20. package/dist/client.iife.js +630 -0
  21. package/dist/core/index.d.ts +86 -0
  22. package/dist/core/index.js +37 -0
  23. package/dist/core/index.js.map +1 -0
  24. package/dist/daemon/index.d.ts +58 -0
  25. package/dist/daemon/index.js +32 -0
  26. package/dist/daemon/index.js.map +1 -0
  27. package/dist/engine-CeT9URuN.d.ts +161 -0
  28. package/dist/index.d.ts +11 -0
  29. package/dist/index.js +56 -0
  30. package/dist/index.js.map +1 -0
  31. package/dist/mcp/index.d.ts +11 -0
  32. package/dist/mcp/index.js +12 -0
  33. package/dist/mcp/index.js.map +1 -0
  34. package/dist/notes-CBvN91Wf.d.ts +260 -0
  35. package/dist/projects-CY8ungMt.d.ts +99 -0
  36. package/dist/server-Dd8NX2Mk.d.ts +55 -0
  37. package/docboot.config.js +16 -0
  38. package/docs/cli.md +51 -0
  39. package/docs/closed-loop-verification.md +57 -0
  40. package/docs/getting-started.md +122 -0
  41. package/docs/incidents-diagnostics.md +61 -0
  42. package/docs/index.md +46 -0
  43. package/docs/mcp-reference.md +128 -0
  44. package/docs/security-privacy.md +32 -0
  45. package/docs/visual-notes.md +67 -0
  46. package/examples/test-app/index.html +299 -0
  47. package/package.json +56 -7
  48. package/packages/cli/src/index.ts +413 -0
  49. package/packages/client/package.json +28 -0
  50. package/packages/client/src/breadcrumbs.ts +30 -0
  51. package/packages/client/src/client.ts +278 -0
  52. package/packages/client/src/commands/handler.ts +301 -0
  53. package/packages/client/src/config.ts +37 -0
  54. package/packages/client/src/index.ts +50 -0
  55. package/packages/client/src/interceptors/console.ts +68 -0
  56. package/packages/client/src/interceptors/interaction.ts +119 -0
  57. package/packages/client/src/interceptors/navigation.ts +93 -0
  58. package/packages/client/src/interceptors/network.ts +165 -0
  59. package/packages/client/src/interceptors/runtime.ts +65 -0
  60. package/packages/client/src/notes/inspector.ts +1553 -0
  61. package/packages/client/src/screenshot/browser-script-driver.ts +192 -0
  62. package/packages/client/src/screenshot/driver.ts +14 -0
  63. package/packages/client/src/transport/websocket.ts +194 -0
  64. package/packages/client/tsconfig.json +8 -0
  65. package/packages/core/package.json +26 -0
  66. package/packages/core/src/fingerprint.ts +120 -0
  67. package/packages/core/src/index.ts +9 -0
  68. package/packages/core/src/redaction.ts +174 -0
  69. package/packages/core/src/selector.ts +77 -0
  70. package/packages/core/src/types/commands.ts +101 -0
  71. package/packages/core/src/types/events.ts +108 -0
  72. package/packages/core/src/types/incidents.ts +54 -0
  73. package/packages/core/src/types/notes.ts +106 -0
  74. package/packages/core/src/types/probes.ts +44 -0
  75. package/packages/core/src/types/projects.ts +20 -0
  76. package/packages/core/tsconfig.json +8 -0
  77. package/packages/daemon/src/config.ts +29 -0
  78. package/packages/daemon/src/incidents/engine.ts +211 -0
  79. package/packages/daemon/src/index.ts +18 -0
  80. package/packages/daemon/src/notes/engine.ts +92 -0
  81. package/packages/daemon/src/notes/verification.ts +191 -0
  82. package/packages/daemon/src/server/daemon.ts +112 -0
  83. package/packages/daemon/src/server/http.ts +165 -0
  84. package/packages/daemon/src/server/ws.ts +246 -0
  85. package/packages/daemon/src/session/manager.ts +147 -0
  86. package/packages/daemon/src/storage/db.ts +742 -0
  87. package/packages/daemon/src/storage/screenshot-store.ts +49 -0
  88. package/packages/daemon/src/verification/engine.ts +264 -0
  89. package/packages/mcp/src/handlers.ts +398 -0
  90. package/packages/mcp/src/index.ts +3 -0
  91. package/packages/mcp/src/server.ts +86 -0
  92. package/packages/mcp/src/tools.ts +236 -0
  93. package/src/index.ts +4 -0
  94. package/test/client/interceptors.test.ts +130 -0
  95. package/test/core/fingerprint.test.ts +53 -0
  96. package/test/core/notes.test.ts +66 -0
  97. package/test/core/redaction.test.ts +60 -0
  98. package/test/daemon/incident-engine.test.ts +98 -0
  99. package/test/daemon/notes-storage.test.ts +130 -0
  100. package/test/daemon/notes-verification.test.ts +135 -0
  101. package/test/daemon/storage.test.ts +123 -0
  102. package/test/daemon/verification-engine.test.ts +88 -0
  103. package/test/e2e/daemon-mcp-e2e.test.ts +153 -0
  104. package/test/e2e/visual-notes-e2e.test.ts +205 -0
  105. package/test/mcp/handlers.test.ts +116 -0
  106. package/test/mcp/notes.test.ts +107 -0
  107. package/tsconfig.base.json +17 -0
  108. package/tsconfig.json +26 -0
  109. package/tsup.config.ts +54 -0
  110. package/vitest.config.ts +9 -0
@@ -0,0 +1,61 @@
1
+ ---
2
+ title: Incidents & Diagnostics
3
+ description: Automatic error grouping, runtime crash diagnostics, network tracking, and interaction breadcrumbs
4
+ order: 4
5
+ ---
6
+
7
+ # Incidents & Diagnostics ⚠️
8
+
9
+ BrowserTrack continuously captures runtime errors, unhandled promise rejections, console warnings/errors, failed network calls, and user interaction breadcrumbs.
10
+
11
+ ---
12
+
13
+ ## ⚡ Automatic Error Grouping (Incidents)
14
+
15
+ Instead of overwhelming AI agents with duplicate errors, BrowserTrack uses intelligent fingerprinting:
16
+ - Grouped by `errorType`, normalized message, and source file line/column.
17
+ - Tracks `occurrences`, `firstSeen`, and `lastSeen` timestamps.
18
+ - Captures stack traces, route, and surrounding DOM state.
19
+
20
+ ---
21
+
22
+ ## 🍞 User Interaction Breadcrumbs
23
+
24
+ BrowserTrack maintains a bounded chronological timeline of events leading up to an error:
25
+ - **User Clicks**: Target selector, tag, text, and timestamp.
26
+ - **Form Focus/Blur**: Inputs engaged prior to crash (values are never recorded).
27
+ - **SPA & Browser Navigation**: `history.pushState` and URL route changes.
28
+ - **Console Logs**: `console.log`, `console.warn`, `console.error`.
29
+ - **Network Requests**: Method, URL, status code, and duration.
30
+
31
+ ---
32
+
33
+ ## 🌐 Network Failure Tracking
34
+
35
+ Failed HTTP requests (`4xx`, `5xx`, timeouts, and aborts) are captured with:
36
+ - Request method and sanitized URL (sensitive query parameters redacted by `@visulima/redact`).
37
+ - HTTP status code and response duration in ms.
38
+ - Error status and aborted flags.
39
+
40
+ ---
41
+
42
+ ## 🤖 Diagnostics Workflow for Coding Agents
43
+
44
+ ```mermaid
45
+ sequenceDiagram
46
+ participant Agent as AI Coding Agent
47
+ participant MCP as BrowserTrack MCP
48
+ participant Daemon as Local Daemon
49
+ participant Browser as Browser Client
50
+
51
+ Agent->>MCP: list_incidents({ status: "OPEN" })
52
+ MCP->>Daemon: Query incidents from SQLite
53
+ Daemon-->>Agent: Returns grouped incidents
54
+ Agent->>MCP: get_incident({ incidentId: "inc_xxx" })
55
+ MCP-->>Agent: Stack trace, source line, breadcrumbs, screenshot
56
+ Agent->>Agent: Modifies code to fix bug
57
+ Agent->>MCP: verify_incident({ incidentId: "inc_xxx" })
58
+ MCP->>Browser: Dispatches reload & executes probes
59
+ Browser-->>Daemon: Reports runtime status & captures screenshot
60
+ Daemon-->>Agent: Verdict (VERIFIED / FAILED)
61
+ ```
package/docs/index.md ADDED
@@ -0,0 +1,46 @@
1
+ ---
2
+ title: Introduction
3
+ description: Overview of BrowserTrack - local browser diagnostics bridge for AI coding agents via MCP
4
+ order: 1
5
+ ---
6
+
7
+ # BrowserTrack 🔍
8
+
9
+ > **Local browser diagnostics shared with AI coding agents through Model Context Protocol (MCP).**
10
+
11
+ BrowserTrack is a lightweight, framework-agnostic local development daemon and MCP bridge. It continuously captures browser runtime errors, unhandled promise rejections, console logs, network failures (4xx/5xx), user interaction breadcrumbs, live DOM snapshots, and visual design annotations—making them instantly accessible to AI coding assistants (Antigravity, Cursor, Claude Code, Windsurf) for autonomous debugging and closed-loop verification.
12
+
13
+ ---
14
+
15
+ ## ⚡ Why BrowserTrack?
16
+
17
+ Traditional browser debugging with AI coding agents relies on manual copy-pasting of truncated error messages or sending cropped screenshots. BrowserTrack removes the human in the middle:
18
+
19
+ - 🚀 **Real-time Diagnostics Pipeline**: Your browser communicates with the local daemon via WebSockets.
20
+ - 🎯 **Visual Annotations & Notes**: Hold <kbd>Alt</kbd> and click any element (or drag a region) to leave notes with DOM context and screenshots directly for coding agents.
21
+ - 📌 **Persistent On-Screen Markers**: Visual note pins appear directly on your web pages and can be inspected or resolved with a single click.
22
+ - 🤖 **Closed-Loop Verification**: After an agent edits your code, it automatically reloads the browser, executes verification probes, checks for regressions, and captures before/after screenshots.
23
+ - 🛡️ **Zero-Leak Security**: Integrated with `@visulima/redact` to automatically sanitize passwords, auth tokens, cookies, credit cards, and secret query parameters.
24
+
25
+ ---
26
+
27
+ ## 🏗️ Architecture Overview
28
+
29
+ ```mermaid
30
+ graph TD
31
+ A[Browser Client<br>Vanilla / React / Vue / Vite] <-->|WebSocket ws://127.0.0.1:7331| B[Local Daemon<br>SQLite Storage + Verification Engine]
32
+ B <-->|Model Context Protocol / stdio| C[AI Coding Agents<br>Antigravity / Cursor / Claude Code]
33
+ B -->|Static Docs & Web UI| D[Local Dashboard / Dev Server]
34
+ ```
35
+
36
+ ---
37
+
38
+ ## 🚀 Quick Navigation
39
+
40
+ - [Getting Started](./getting-started.md) — Quick installation and setup in under 2 minutes.
41
+ - [Visual Notes & Annotations](./visual-notes.md) — Screen notes, region selection, and persistent markers.
42
+ - [Incidents & Error Diagnostics](./incidents-diagnostics.md) — Ingest runtime errors, stack traces, and breadcrumbs.
43
+ - [Closed-Loop Verification](./closed-loop-verification.md) — Automated bug-fix and layout verification.
44
+ - [MCP Tool Reference](./mcp-reference.md) — Complete guide to all 16 MCP tools.
45
+ - [Security & Redaction](./security-privacy.md) — Privacy architecture and `@visulima/redact` integration.
46
+ - [CLI Reference](./cli.md) — Command-line interface usage.
@@ -0,0 +1,128 @@
1
+ ---
2
+ title: MCP Tool Reference
3
+ description: Complete reference for all 16 Model Context Protocol (MCP) tools exposed to AI coding agents
4
+ order: 6
5
+ ---
6
+
7
+ # MCP Tool Reference 🛠️
8
+
9
+ BrowserTrack exposes 16 specialized Model Context Protocol (MCP) tools for AI agents.
10
+
11
+ ---
12
+
13
+ ## 📋 Incidents & Error Diagnostics
14
+
15
+ ### `list_incidents`
16
+ Lists recorded browser runtime errors, unhandled rejections, and console errors grouped into incidents.
17
+ - **Arguments**:
18
+ - `status` (`string`): Filter by `OPEN`, `FIX_ATTEMPTED`, `VERIFYING`, `VERIFIED`, `FAILED`, `INCONCLUSIVE`.
19
+ - `severity` (`string`): Filter by `error`, `warn`, `fatal`.
20
+ - `projectId` (`string`): Filter by project ID or name.
21
+ - `limit` (`number`): Max number of incidents (default: 20).
22
+
23
+ ### `get_incident`
24
+ Retrieves compact, high-signal debugging context for an error incident.
25
+ - **Arguments**:
26
+ - `incidentId` (`string`, *required*): The unique ID of the incident (e.g. `inc_19a31a28`).
27
+ - **Returns**: Stack trace, normalized error message, breadcrumbs timeline, failed network calls, last interacted element, error screenshot.
28
+
29
+ ### `get_console`
30
+ Fetches recent console logs, warnings, and errors from a browser session.
31
+ - **Arguments**:
32
+ - `sessionId` (`string`): Browser session ID (optional, defaults to active session).
33
+ - `limit` (`number`): Number of logs to retrieve (default: 30).
34
+
35
+ ### `get_network_failures`
36
+ Retrieves recent failed HTTP requests (4xx, 5xx, timeouts, aborts).
37
+ - **Arguments**:
38
+ - `sessionId` (`string`): Browser session ID (optional).
39
+ - `limit` (`number`): Maximum number of failed requests (default: 20).
40
+
41
+ ### `get_breadcrumbs`
42
+ Retrieves the chronological user interaction timeline leading up to an error.
43
+ - **Arguments**:
44
+ - `incidentId` (`string`): Associated incident ID.
45
+ - `sessionId` (`string`): Browser session ID.
46
+ - `limit` (`number`): Max breadcrumbs (default: 50).
47
+
48
+ ### `get_page_state`
49
+ Queries live DOM and URL state from the connected browser tab.
50
+ - **Arguments**:
51
+ - `sessionId` (`string`): Target session ID (optional).
52
+
53
+ ### `capture_element`
54
+ Captures an on-demand screenshot of a specific DOM element or the entire visible page.
55
+ - **Arguments**:
56
+ - `selector` (`string`): CSS selector of the target element.
57
+ - `sessionId` (`string`): Browser session ID (optional).
58
+
59
+ ---
60
+
61
+ ## 📝 Visual Notes & Layout Tools
62
+
63
+ ### `list_notes`
64
+ Lists visual annotations left on elements, regions, or pages during development.
65
+ - **Arguments**:
66
+ - `status` (`string`): `OPEN`, `IN_PROGRESS`, `VERIFYING`, `RESOLVED`, `FAILED`, `INCONCLUSIVE` (default: `OPEN`).
67
+ - `projectId` (`string`): Filter by project ID or name.
68
+ - `limit` (`number`): Max notes (default: 20).
69
+
70
+ ### `get_note`
71
+ Retrieves full debugging context for a visual note.
72
+ - **Arguments**:
73
+ - `noteId` (`string`, *required*): The unique ID of the visual note (e.g. `note_30a89599`).
74
+ - **Returns**: Note message, route, viewport dimensions, target element selector, DOM context, screenshot file path.
75
+
76
+ ### `capture_note_context`
77
+ Inspects live DOM context, bounding box, overflow, and computed styles for a target element.
78
+ - **Arguments**:
79
+ - `selector` (`string`, *required*): CSS selector of target element.
80
+ - `sessionId` (`string`): Browser session ID (optional).
81
+
82
+ ### `verify_note`
83
+ Runs closed-loop layout verification (visibility, viewport overflow, geometry delta, after-screenshot).
84
+ - **Arguments**:
85
+ - `noteId` (`string`, *required*): The ID of the visual note to verify.
86
+ - `observationWindowMs` (`number`): Observation window in ms (default: 1000).
87
+
88
+ ### `get_note_verification`
89
+ Retrieves latest layout verification verdict, screenshots, and geometry diff.
90
+ - **Arguments**:
91
+ - `noteId` (`string`, *required*): The ID of the visual note.
92
+
93
+ ### `resolve_note`
94
+ Marks a visual note as `RESOLVED`.
95
+ - **Arguments**:
96
+ - `noteId` (`string`, *required*): The ID of the visual note.
97
+
98
+ ### `reopen_note`
99
+ Reopens a previously resolved visual note.
100
+ - **Arguments**:
101
+ - `noteId` (`string`, *required*): The ID of the visual note.
102
+
103
+ ---
104
+
105
+ ## 🎛️ Session & Project Management
106
+
107
+ ### `list_projects`
108
+ Lists all registered development projects and mapped filesystem paths.
109
+
110
+ ### `list_sessions`
111
+ Lists active and recent browser tabs connected to the local development daemon.
112
+ - **Arguments**:
113
+ - `projectId` (`string`): Filter sessions by project ID or name.
114
+ - `activeOnly` (`boolean`): Show only active WebSocket sessions (default: `true`).
115
+
116
+ ### `verify_incident`
117
+ Triggers closed-loop bug fix verification (reloads browser, evaluates probes, captures after-screenshot).
118
+ - **Arguments**:
119
+ - `incidentId` (`string`, *required*): The ID of the incident.
120
+ - `route` (`string`): Optional route to navigate to.
121
+ - `targetSelector` (`string`): Optional element selector to inspect.
122
+ - `expect` (`array`): Optional verification probes (`no_incident`, `element_exists`, `element_visible`, `text_contains`, `route_is`).
123
+ - `observationWindowMs` (`number`): Observation window in ms (default: 2000).
124
+
125
+ ### `get_verification`
126
+ Retrieves latest verification result and before/after screenshots for an incident.
127
+ - **Arguments**:
128
+ - `incidentId` (`string`, *required*): The ID of the incident.
@@ -0,0 +1,32 @@
1
+ ---
2
+ title: Security & Privacy
3
+ description: Security architecture, localhost binding, form value exclusion, and @visulima/redact sensitive data sanitization
4
+ order: 7
5
+ ---
6
+
7
+ # Security & Privacy 🛡️
8
+
9
+ BrowserTrack is built with privacy-by-design principles to ensure sensitive developer tokens, credentials, and user data never leak to AI models or external servers.
10
+
11
+ ---
12
+
13
+ ## 🔒 Core Security Principles
14
+
15
+ ### 1. Strictly Localhost Bound
16
+ - The daemon binds exclusively to `127.0.0.1`.
17
+ - It cannot be reached from the public internet or external local network devices.
18
+
19
+ ### 2. Comprehensive Sensitive Data Masking (@visulima/redact)
20
+ BrowserTrack integrates `@visulima/redact` to automatically scan and sanitize payloads before saving to SQLite or returning to MCP:
21
+ - **Authentication & Headers**: `Authorization` (Bearer tokens, Basic auth), `Cookie`, `Set-Cookie`.
22
+ - **API Keys & Credentials**: AWS Access Keys (`AKIA...`), Slack tokens (`xoxb-...`), JWTs (`eyJ...`), `private_key`, `secret`.
23
+ - **Financial & Personal Data**: Credit card numbers, CVV/CVD, SSN / Social Security Numbers.
24
+ - **Sensitive URL Parameters**: Query strings containing `token`, `key`, `apiKey`, `auth`, `secret`, `password`, `signature` are converted to `[REDACTED]`.
25
+
26
+ ### 3. No Form Input Recording
27
+ - Values inside `<input>` and `<textarea>` fields are never read or stored.
28
+ - Password inputs (`<input type="password">`) in DOM snapshot clones are explicitly sanitized to `value="[REDACTED]"`.
29
+
30
+ ### 4. Zero Request/Response Payloads
31
+ - Network event interceptors capture only URL endpoints, HTTP methods, status codes, and latency.
32
+ - Request and response body payloads are disabled by default.
@@ -0,0 +1,67 @@
1
+ ---
2
+ title: Visual Notes & Annotations
3
+ description: Visual annotations, element hover notes, drag-and-drop region notes, and persistent on-screen pins
4
+ order: 3
5
+ ---
6
+
7
+ # Visual Notes & Screen Annotations 📝
8
+
9
+ BrowserTrack enables developers and designers to leave visual feedback directly on DOM elements, custom screen regions, or full pages without leaving the browser.
10
+
11
+ ---
12
+
13
+ ## 🎯 Annotation Modes
14
+
15
+ ### 1. Element Notes (Alt + Click)
16
+ - **How to use**: Hold <kbd>Alt</kbd> and hover over any element on the page. The element will highlight with its semantic CSS selector and dimensions. Click to open the note editor.
17
+ - Alternatively, click the **🎯 Element** button in the floating toolbar.
18
+ - **Context captured**:
19
+ - Semantic CSS selector (e.g. `[data-testid="stats-banner"]` or `#user-card`)
20
+ - Element dimensions and bounding rectangle (`x`, `y`, `width`, `height`)
21
+ - Sanitized outerHTML and DOM hierarchy
22
+ - Viewport dimensions and scroll offsets
23
+ - Element screenshot snapshot
24
+
25
+ ### 2. Region / Area Notes (Drag & Drop)
26
+ - **How to use**: Click the **📐 Region** button in the floating toolbar.
27
+ - Drag a bounding rectangle over any area on the screen.
28
+ - A top banner will appear with a **✕ Cancel (Esc)** button.
29
+ - Releasing the mouse opens the note modal with the cropped region screenshot and coordinates.
30
+
31
+ ### 3. Full-Page Notes
32
+ - **How to use**: Click the **📄 Page** button in the toolbar.
33
+ - Captures the entire page viewport state, URL route, and document context.
34
+
35
+ ---
36
+
37
+ ## 📌 Persistent On-Screen Markers
38
+
39
+ When your application loads or syncs with the daemon:
40
+ - BrowserTrack automatically fetches all open notes for the project.
41
+ - **Element Pins (`📝 #1`)**: Placed at the top-left of each annotated element. Hovering highlights the element.
42
+ - **Region Outlines (`📐 #2`)**: Renders a clean dashed boundary box around the selected area.
43
+ - **Page Notes (`📄`)**: Pinned at the top right of the viewport.
44
+ - **Responsive Tracking**: Markers dynamically stay anchored to elements as the page scrolls or resizes.
45
+
46
+ ---
47
+
48
+ ## 🔍 Interactive Popover Details Card
49
+
50
+ Clicking on any note marker opens the Note Details Card:
51
+
52
+ - **Full Message**: Displays the complete text/instruction.
53
+ - **Target Metadata**: Viewport dimensions, target selector, and creation timestamp.
54
+ - **Action Buttons**:
55
+ - **`✅ Resolve Note`**: Marks the note as `RESOLVED` in real time.
56
+ - **`🗑️ Delete Note`**: Removes the note permanently from the database.
57
+ - **`✕ Close`**: Closes the popover.
58
+
59
+ ---
60
+
61
+ ## 🛠️ Toolbar Controls
62
+
63
+ The bottom-right floating toolbar gives quick access:
64
+ - **`🎯 Element`**: Toggle element inspection mode.
65
+ - **`📐 Region`**: Activate rectangle drag mode.
66
+ - **`📄 Page`**: Open full-page note modal.
67
+ - **`📌 Notes (N)`**: Toggle visibility of all note markers on screen.
@@ -0,0 +1,299 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>BrowserTrack Fixture App</title>
7
+ <style>
8
+ :root {
9
+ --bg: #0f172a;
10
+ --card-bg: #1e293b;
11
+ --text: #f8fafc;
12
+ --muted: #94a3b8;
13
+ --primary: #3b82f6;
14
+ --danger: #ef4444;
15
+ --warning: #f59e0b;
16
+ --success: #10b981;
17
+ --border: #334155;
18
+ }
19
+
20
+ * { box-sizing: border-box; margin: 0; padding: 0; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; }
21
+ body { background-color: var(--bg); color: var(--text); padding: 2rem; display: flex; flex-direction: column; align-items: center; min-height: 100vh; }
22
+ .container { max-width: 800px; width: 100%; display: flex; flex-direction: column; gap: 1.5rem; }
23
+
24
+ header { border-bottom: 1px solid var(--border); padding-bottom: 1rem; display: flex; justify-content: space-between; align-items: center; }
25
+ h1 { font-size: 1.5rem; font-weight: 600; display: flex; align-items: center; gap: 0.5rem; }
26
+ .badge { font-size: 0.75rem; padding: 0.2rem 0.6rem; border-radius: 999px; background: rgba(59, 130, 246, 0.2); color: var(--primary); border: 1px solid var(--primary); }
27
+
28
+ .card { background: var(--card-bg); border: 1px solid var(--border); border-radius: 0.75rem; padding: 1.25rem; }
29
+ .card-title { font-size: 1rem; font-weight: 600; margin-bottom: 0.75rem; color: var(--muted); text-transform: uppercase; letter-spacing: 0.05em; }
30
+
31
+ .grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 0.75rem; }
32
+
33
+ button {
34
+ padding: 0.75rem 1rem;
35
+ border-radius: 0.5rem;
36
+ border: 1px solid transparent;
37
+ font-weight: 500;
38
+ cursor: pointer;
39
+ transition: all 0.15s ease-in-out;
40
+ display: flex;
41
+ align-items: center;
42
+ justify-content: center;
43
+ gap: 0.5rem;
44
+ font-size: 0.9rem;
45
+ }
46
+ button:hover { filter: brightness(1.1); transform: translateY(-1px); }
47
+ button:active { transform: translateY(0); }
48
+
49
+ .btn-danger { background: rgba(239, 68, 68, 0.15); color: #fca5a5; border-color: rgba(239, 68, 68, 0.3); }
50
+ .btn-warning { background: rgba(245, 158, 11, 0.15); color: #fcd34d; border-color: rgba(245, 158, 11, 0.3); }
51
+ .btn-primary { background: rgba(59, 130, 246, 0.15); color: #93c5fd; border-color: rgba(59, 130, 246, 0.3); }
52
+ .btn-success { background: rgba(16, 185, 129, 0.15); color: #6ee7b7; border-color: rgba(16, 185, 129, 0.3); }
53
+
54
+ .element-card {
55
+ border: 2px dashed rgba(239, 68, 68, 0.4);
56
+ background: rgba(239, 68, 68, 0.05);
57
+ padding: 1rem;
58
+ border-radius: 0.5rem;
59
+ margin-top: 0.5rem;
60
+ display: flex;
61
+ justify-content: space-between;
62
+ align-items: center;
63
+ }
64
+
65
+ #log-panel {
66
+ background: #090d16;
67
+ border: 1px solid var(--border);
68
+ border-radius: 0.5rem;
69
+ padding: 0.75rem;
70
+ font-family: monospace;
71
+ font-size: 0.8rem;
72
+ max-height: 180px;
73
+ overflow-y: auto;
74
+ color: #38bdf8;
75
+ }
76
+ .log-item { margin-bottom: 0.3rem; }
77
+ </style>
78
+
79
+ <!-- BrowserTrack Client Auto-Injection -->
80
+ <script src="http://127.0.0.1:7331/client.js"></script>
81
+ </head>
82
+ <body>
83
+ <div class="container">
84
+ <header>
85
+ <h1>🧪 BrowserTrack Fixture App</h1>
86
+ <span class="badge" id="status-badge">Connecting...</span>
87
+ </header>
88
+
89
+ <!-- Error Triggers Card -->
90
+ <div class="card">
91
+ <div class="card-title">1. Runtime & Console Triggers</div>
92
+ <div class="grid">
93
+ <button class="btn-danger" id="btn-throw-error" data-testid="throw-error-btn">
94
+ 💥 Throw Error
95
+ </button>
96
+ <button class="btn-danger" id="btn-unhandled-promise" data-testid="unhandled-promise-btn">
97
+ ⚠️ Unhandled Promise
98
+ </button>
99
+ <button class="btn-warning" id="btn-console-error" data-testid="console-error-btn">
100
+ 📝 Console Error
101
+ </button>
102
+ <button class="btn-warning" id="btn-console-warn" data-testid="console-warn-btn">
103
+ ⚠️ Console Warn
104
+ </button>
105
+ </div>
106
+ </div>
107
+
108
+ <!-- Network Triggers Card -->
109
+ <div class="card">
110
+ <div class="card-title">2. Network & Async Triggers</div>
111
+ <div class="grid">
112
+ <button class="btn-danger" id="btn-500-request" data-testid="fail-500-btn">
113
+ 🌐 500 Network Request
114
+ </button>
115
+ <button class="btn-danger" id="btn-delayed-error" data-testid="delayed-error-btn">
116
+ ⏱️ Delayed Error (1s)
117
+ </button>
118
+ <button class="btn-primary" id="btn-navigate" data-testid="navigate-btn">
119
+ 🔀 Navigate /users/42
120
+ </button>
121
+ </div>
122
+ </div>
123
+
124
+ <!-- Element Error with Visual Card -->
125
+ <div class="card">
126
+ <div class="card-title">3. Element Target & Verification Probe</div>
127
+ <div class="element-card" id="user-card" data-testid="user-card">
128
+ <div>
129
+ <strong id="user-name">User: John Doe (#42)</strong>
130
+ <p style="color: var(--muted); font-size: 0.85rem;" id="user-status">Status: Active</p>
131
+ </div>
132
+ <button class="btn-danger" id="btn-element-error" data-testid="element-error-btn">
133
+ Trigger Element Error
134
+ </button>
135
+ </div>
136
+ </div>
137
+
138
+ <!-- Visual Notes & Layout Cards -->
139
+ <div class="card">
140
+ <div class="card-title">4. Visual Notes & Responsive Layout (Alt+Click to Annotate)</div>
141
+ <p style="font-size: 0.85rem; color: var(--muted); margin-bottom: 0.75rem;">
142
+ Hold <kbd style="background:#334155;padding:2px 5px;border-radius:3px;">Alt</kbd> and click any element below to leave a visual note for coding agents.
143
+ </p>
144
+
145
+ <!-- Overflowing Stats Card (Simulating mobile layout issue) -->
146
+ <div class="stats-card" id="stats-banner" data-testid="stats-banner" style="background:#1e1b4b;border:1px solid #4338ca;padding:1rem;border-radius:0.5rem;display:flex;gap:1.5rem;min-width:600px;overflow-x:auto;">
147
+ <div>
148
+ <div style="font-size:0.75rem;color:#a5b4fc;">MONTHLY ACTIVE USERS</div>
149
+ <div style="font-size:1.4rem;font-weight:700;color:#e0e7ff;">142,890</div>
150
+ </div>
151
+ <div>
152
+ <div style="font-size:0.75rem;color:#a5b4fc;">PAGEVIEWS (30D)</div>
153
+ <div style="font-size:1.4rem;font-weight:700;color:#e0e7ff;">1,249,000</div>
154
+ </div>
155
+ <div>
156
+ <div style="font-size:0.75rem;color:#a5b4fc;">SERVER RESPONSE TIME</div>
157
+ <div style="font-size:1.4rem;font-weight:700;color:#e0e7ff;">42ms</div>
158
+ </div>
159
+ </div>
160
+
161
+ <!-- Sensitive Input masking demonstration -->
162
+ <div style="margin-top:1rem;display:flex;gap:0.75rem;align-items:center;flex-wrap:wrap;">
163
+ <input type="password" id="admin-pass" value="super-secret-password" data-testid="admin-pass-input" style="background:#0f172a;color:#f8fafc;border:1px solid #334155;border-radius:4px;padding:6px 10px;font-size:12px;" />
164
+ <button class="btn-primary" id="btn-manual-note" style="padding:6px 12px;font-size:12px;">
165
+ 📝 Note on Stats
166
+ </button>
167
+ <button class="btn-primary" id="btn-select-element" style="padding:6px 12px;font-size:12px;background:rgba(59,130,246,0.25);">
168
+ 🎯 Element Seç
169
+ </button>
170
+ <button class="btn-primary" id="btn-select-region" style="padding:6px 12px;font-size:12px;background:rgba(56,189,248,0.25);color:#38bdf8;">
171
+ 📐 Alan / Bölge Seç (Drag)
172
+ </button>
173
+ <button class="btn-primary" id="btn-page-note" style="padding:6px 12px;font-size:12px;background:rgba(168,85,247,0.25);color:#c084fc;">
174
+ 📄 Tüm Sayfa
175
+ </button>
176
+ </div>
177
+ </div>
178
+
179
+ <!-- Live Event Log -->
180
+ <div class="card">
181
+ <div class="card-title">Event Log</div>
182
+ <div id="log-panel">
183
+ <div class="log-item">[Init] Fixture app loaded. Ready for diagnostics testing.</div>
184
+ </div>
185
+ </div>
186
+ </div>
187
+
188
+ <script>
189
+ const logPanel = document.getElementById('log-panel');
190
+ function appendLog(msg) {
191
+ const div = document.createElement('div');
192
+ div.className = 'log-item';
193
+ div.textContent = `[${new Date().toLocaleTimeString()}] ${msg}`;
194
+ logPanel.appendChild(div);
195
+ logPanel.scrollTop = logPanel.scrollHeight;
196
+ }
197
+
198
+ // 1. Throw Error
199
+ document.getElementById('btn-throw-error').addEventListener('click', () => {
200
+ appendLog('Throwing synchronous Error');
201
+ throw new TypeError("Cannot read properties of undefined (reading 'calculateTotal')");
202
+ });
203
+
204
+ // 2. Unhandled Promise
205
+ document.getElementById('btn-unhandled-promise').addEventListener('click', () => {
206
+ appendLog('Triggering Unhandled Promise Rejection');
207
+ new Promise((_, reject) => {
208
+ reject(new Error("API authentication session expired (token expired)"));
209
+ });
210
+ });
211
+
212
+ // 3. Console Error
213
+ document.getElementById('btn-console-error').addEventListener('click', () => {
214
+ appendLog('Logging console.error');
215
+ console.error("Failed to render UserProfileComponent: missing user data", { id: 42, role: 'developer' });
216
+ });
217
+
218
+ // 4. Console Warn
219
+ document.getElementById('btn-console-warn').addEventListener('click', () => {
220
+ appendLog('Logging console.warn');
221
+ console.warn("Component UserCard is using deprecated prop 'legacyFormat'");
222
+ });
223
+
224
+ // 5. 500 Network Request
225
+ document.getElementById('btn-500-request').addEventListener('click', async () => {
226
+ appendLog('Sending fetch request to failing endpoint');
227
+ try {
228
+ await fetch('http://127.0.0.1:7331/api/invalid-endpoint-trigger-404?token=secret123');
229
+ } catch (e) {
230
+ console.error('Fetch threw error:', e);
231
+ }
232
+ });
233
+
234
+ // 6. Delayed Error
235
+ document.getElementById('btn-delayed-error').addEventListener('click', () => {
236
+ appendLog('Scheduled delayed error in 1000ms');
237
+ setTimeout(() => {
238
+ throw new ReferenceError("UserProfileService is not defined at background poll");
239
+ }, 1000);
240
+ });
241
+
242
+ // 7. SPA Navigation
243
+ document.getElementById('btn-navigate').addEventListener('click', () => {
244
+ const newUrl = '/users/42';
245
+ history.pushState({ page: 42 }, 'User Profile', newUrl);
246
+ appendLog(`Navigated history.pushState to ${newUrl}`);
247
+ });
248
+
249
+ // 8. Element Error
250
+ document.getElementById('btn-element-error').addEventListener('click', () => {
251
+ appendLog('Triggering error on user-card element');
252
+ throw new Error("Element user-card encountered unexpected state rendering card");
253
+ });
254
+
255
+ // 9. Manual Visual Note triggers
256
+ document.getElementById('btn-manual-note').addEventListener('click', () => {
257
+ appendLog('Opening visual note editor on stats-banner');
258
+ const stats = document.getElementById('stats-banner');
259
+ if (window.__BROWSERTRACK__?.getClient()) {
260
+ window.__BROWSERTRACK__.getClient().openNoteEditor(stats);
261
+ }
262
+ });
263
+
264
+ document.getElementById('btn-select-element').addEventListener('click', () => {
265
+ appendLog('Activated Element selection mode (click any element)');
266
+ if (window.__BROWSERTRACK__?.getClient()) {
267
+ window.__BROWSERTRACK__.getClient().startElementSelection();
268
+ }
269
+ });
270
+
271
+ document.getElementById('btn-select-region').addEventListener('click', () => {
272
+ appendLog('Activated Region selection mode (drag rectangle on screen)');
273
+ if (window.__BROWSERTRACK__?.getClient()) {
274
+ window.__BROWSERTRACK__.getClient().startRegionSelection();
275
+ }
276
+ });
277
+
278
+ document.getElementById('btn-page-note').addEventListener('click', () => {
279
+ appendLog('Opening full page note editor');
280
+ if (window.__BROWSERTRACK__?.getClient()) {
281
+ window.__BROWSERTRACK__.getClient().openNoteEditor(document.body, 'page');
282
+ }
283
+ });
284
+
285
+ // Check client status
286
+ setInterval(() => {
287
+ const badge = document.getElementById('status-badge');
288
+ if (window.__BROWSERTRACK__ && window.__BROWSERTRACK__.getClient()) {
289
+ badge.textContent = '🟢 BrowserTrack Active';
290
+ badge.style.borderColor = 'var(--success)';
291
+ badge.style.color = 'var(--success)';
292
+ badge.style.background = 'rgba(16, 185, 129, 0.2)';
293
+ } else {
294
+ badge.textContent = '⚪ Daemon Offline (Safe)';
295
+ }
296
+ }, 1000);
297
+ </script>
298
+ </body>
299
+ </html>