browsertrack 0.2.0 → 0.2.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 (39) hide show
  1. package/AGENTS.md +2 -0
  2. package/dist/{chunk-UP5JKCFY.js → chunk-464D4U2U.js} +3 -2
  3. package/dist/chunk-464D4U2U.js.map +1 -0
  4. package/dist/{chunk-WB7ZKWK7.js → chunk-INXDWPJW.js} +354 -9
  5. package/dist/chunk-INXDWPJW.js.map +1 -0
  6. package/dist/cli/index.js +2 -1
  7. package/dist/cli/index.js.map +1 -1
  8. package/dist/client/index.cjs +357 -10
  9. package/dist/client/index.d.ts +36 -4
  10. package/dist/client/index.js +7 -3
  11. package/dist/client.iife.js +42 -19
  12. package/dist/{notes-BMnonq46.d.ts → commands-fjuqKzkm.d.ts} +125 -114
  13. package/dist/core/index.d.ts +2 -2
  14. package/dist/daemon/index.d.ts +3 -3
  15. package/dist/{engine-B43IohQY.d.ts → engine-CmchnMDq.d.ts} +2 -2
  16. package/dist/index.d.ts +4 -4
  17. package/dist/index.js +2 -2
  18. package/dist/mcp/index.d.ts +4 -4
  19. package/dist/mcp/index.js +1 -1
  20. package/dist/{projects-D5J-egVN.d.ts → projects-DB7S312i.d.ts} +1 -1
  21. package/dist/{server-BztYp1Zc.d.ts → server-DiVmTrIR.d.ts} +1 -1
  22. package/docs/component-resolver.md +108 -0
  23. package/docs/index.md +1 -0
  24. package/docs/mcp-reference.md +2 -2
  25. package/docs/visual-notes.md +36 -0
  26. package/package.json +1 -1
  27. package/packages/client/src/client.ts +18 -1
  28. package/packages/client/src/config.ts +84 -1
  29. package/packages/client/src/index.ts +4 -1
  30. package/packages/client/src/interceptors/interaction.ts +3 -0
  31. package/packages/client/src/notes/inspector.ts +107 -5
  32. package/packages/client/src/source/resolver.ts +272 -0
  33. package/packages/core/src/types/events.ts +3 -0
  34. package/packages/core/src/types/notes.ts +11 -0
  35. package/packages/mcp/src/handlers.ts +1 -0
  36. package/test/client/component-resolver.test.ts +141 -0
  37. package/test/client/interceptors.test.ts +56 -0
  38. package/dist/chunk-UP5JKCFY.js.map +0 -1
  39. package/dist/chunk-WB7ZKWK7.js.map +0 -1
@@ -1,3 +1,126 @@
1
+ type NoteType = 'element' | 'region' | 'page';
2
+ type NoteStatus = 'OPEN' | 'IN_PROGRESS' | 'VERIFYING' | 'READY_FOR_REVIEW' | 'VERIFIED' | 'RESOLVED' | 'FAILED' | 'INCONCLUSIVE';
3
+ interface ViewportContext {
4
+ width: number;
5
+ height: number;
6
+ devicePixelRatio: number;
7
+ }
8
+ interface ScrollContext {
9
+ scrollX: number;
10
+ scrollY: number;
11
+ }
12
+ interface DOMRectJson {
13
+ x: number;
14
+ y: number;
15
+ width: number;
16
+ height: number;
17
+ top: number;
18
+ left: number;
19
+ bottom: number;
20
+ right: number;
21
+ }
22
+ interface NoteTarget {
23
+ selector: string;
24
+ boundingRect: DOMRectJson;
25
+ visible: boolean;
26
+ confidence?: 'high' | 'medium' | 'low';
27
+ }
28
+ interface ComponentSourceInfo {
29
+ framework?: 'react' | 'vue' | 'svelte' | 'web-component' | 'vanilla';
30
+ componentName?: string;
31
+ sourceFile?: string;
32
+ sourceLine?: number;
33
+ sourceColumn?: number;
34
+ hierarchy?: string[];
35
+ props?: Record<string, any>;
36
+ }
37
+ interface ElementContext {
38
+ selector: string;
39
+ tag: string;
40
+ attributes?: Record<string, string>;
41
+ outerHTML?: string;
42
+ innerText?: string;
43
+ componentSource?: ComponentSourceInfo;
44
+ parent?: {
45
+ selector: string;
46
+ tag: string;
47
+ };
48
+ }
49
+ interface RegionContext {
50
+ x: number;
51
+ y: number;
52
+ width: number;
53
+ height: number;
54
+ }
55
+ interface VisualNote {
56
+ id: string;
57
+ projectId: string;
58
+ sessionId: string;
59
+ type: NoteType;
60
+ message: string;
61
+ route: string;
62
+ url: string;
63
+ viewport: ViewportContext;
64
+ scroll: ScrollContext;
65
+ target?: NoteTarget;
66
+ elementContext?: ElementContext;
67
+ region?: RegionContext;
68
+ status: NoteStatus;
69
+ incidentId?: string;
70
+ scenarioId?: string;
71
+ stepNumber?: number;
72
+ scenarioTitle?: string;
73
+ screenshots?: {
74
+ original?: string;
75
+ after?: string;
76
+ };
77
+ createdAt: string;
78
+ updatedAt: string;
79
+ resolvedAt?: string;
80
+ }
81
+ interface ScenarioOverview {
82
+ id: string;
83
+ projectId: string;
84
+ title: string;
85
+ stepsCount: number;
86
+ status: NoteStatus;
87
+ route: string;
88
+ firstStepAt: string;
89
+ lastStepAt: string;
90
+ }
91
+ interface ScenarioDetail {
92
+ id: string;
93
+ projectId: string;
94
+ title: string;
95
+ stepsCount: number;
96
+ status: NoteStatus;
97
+ steps: VisualNote[];
98
+ createdAt: string;
99
+ updatedAt: string;
100
+ }
101
+ interface NoteVerificationResult {
102
+ noteId: string;
103
+ status: NoteStatus;
104
+ checks: Array<{
105
+ type: string;
106
+ passed: boolean;
107
+ details?: string;
108
+ }>;
109
+ geometryDiff?: {
110
+ before?: DOMRectJson;
111
+ current?: DOMRectJson;
112
+ viewportWidth?: number;
113
+ overflowFixed?: boolean;
114
+ overflowPx?: number;
115
+ };
116
+ screenshots?: {
117
+ before?: string;
118
+ after?: string;
119
+ };
120
+ timestamp: string;
121
+ message?: string;
122
+ }
123
+
1
124
  type EventType = 'runtime_error' | 'unhandled_rejection' | 'console' | 'fetch' | 'xhr' | 'navigation' | 'interaction';
2
125
  type ConsoleLevel = 'error' | 'warn' | 'info' | 'log' | 'debug';
3
126
  interface ElementSummary {
@@ -8,6 +131,7 @@ interface ElementSummary {
8
131
  attributes?: Record<string, string>;
9
132
  outerHTML?: string;
10
133
  innerText?: string;
134
+ componentSource?: ComponentSourceInfo;
11
135
  boundingRect?: {
12
136
  x: number;
13
137
  y: number;
@@ -167,117 +291,4 @@ interface CommandResponse<T = any> {
167
291
  reason?: string;
168
292
  }
169
293
 
170
- type NoteType = 'element' | 'region' | 'page';
171
- type NoteStatus = 'OPEN' | 'IN_PROGRESS' | 'VERIFYING' | 'READY_FOR_REVIEW' | 'VERIFIED' | 'RESOLVED' | 'FAILED' | 'INCONCLUSIVE';
172
- interface ViewportContext {
173
- width: number;
174
- height: number;
175
- devicePixelRatio: number;
176
- }
177
- interface ScrollContext {
178
- scrollX: number;
179
- scrollY: number;
180
- }
181
- interface DOMRectJson {
182
- x: number;
183
- y: number;
184
- width: number;
185
- height: number;
186
- top: number;
187
- left: number;
188
- bottom: number;
189
- right: number;
190
- }
191
- interface NoteTarget {
192
- selector: string;
193
- boundingRect: DOMRectJson;
194
- visible: boolean;
195
- confidence?: 'high' | 'medium' | 'low';
196
- }
197
- interface ElementContext {
198
- selector: string;
199
- tag: string;
200
- attributes?: Record<string, string>;
201
- outerHTML?: string;
202
- innerText?: string;
203
- parent?: {
204
- selector: string;
205
- tag: string;
206
- };
207
- }
208
- interface RegionContext {
209
- x: number;
210
- y: number;
211
- width: number;
212
- height: number;
213
- }
214
- interface VisualNote {
215
- id: string;
216
- projectId: string;
217
- sessionId: string;
218
- type: NoteType;
219
- message: string;
220
- route: string;
221
- url: string;
222
- viewport: ViewportContext;
223
- scroll: ScrollContext;
224
- target?: NoteTarget;
225
- elementContext?: ElementContext;
226
- region?: RegionContext;
227
- status: NoteStatus;
228
- incidentId?: string;
229
- scenarioId?: string;
230
- stepNumber?: number;
231
- scenarioTitle?: string;
232
- screenshots?: {
233
- original?: string;
234
- after?: string;
235
- };
236
- createdAt: string;
237
- updatedAt: string;
238
- resolvedAt?: string;
239
- }
240
- interface ScenarioOverview {
241
- id: string;
242
- projectId: string;
243
- title: string;
244
- stepsCount: number;
245
- status: NoteStatus;
246
- route: string;
247
- firstStepAt: string;
248
- lastStepAt: string;
249
- }
250
- interface ScenarioDetail {
251
- id: string;
252
- projectId: string;
253
- title: string;
254
- stepsCount: number;
255
- status: NoteStatus;
256
- steps: VisualNote[];
257
- createdAt: string;
258
- updatedAt: string;
259
- }
260
- interface NoteVerificationResult {
261
- noteId: string;
262
- status: NoteStatus;
263
- checks: Array<{
264
- type: string;
265
- passed: boolean;
266
- details?: string;
267
- }>;
268
- geometryDiff?: {
269
- before?: DOMRectJson;
270
- current?: DOMRectJson;
271
- viewportWidth?: number;
272
- overflowFixed?: boolean;
273
- overflowPx?: number;
274
- };
275
- screenshots?: {
276
- before?: string;
277
- after?: string;
278
- };
279
- timestamp: string;
280
- message?: string;
281
- }
282
-
283
- export type { Breadcrumb as B, CaptureElementParams as C, DOMRectJson as D, ElementContext as E, HelloMessage as H, NavigateParams as N, OverflowCheckResult as O, PageStateResult as P, QueryElementParams as Q, RegionContext as R, ScenarioDetail as S, ViewportContext as V, CaptureElementResult as a, ClientCommand as b, ClientEventMessage as c, CommandResponse as d, CommandType as e, ConsoleEvent as f, ConsoleLevel as g, ElementStyleResult as h, ElementSummary as i, EventType as j, NavigationEvent as k, NetworkEvent as l, NoteStatus as m, NoteTarget as n, NoteType as o, NoteVerificationResult as p, QueryElementResult as q, ReloadParams as r, RuntimeErrorEvent as s, ScenarioOverview as t, ScrollContext as u, VisualNote as v };
294
+ export type { Breadcrumb as B, CaptureElementParams as C, DOMRectJson as D, ElementContext as E, HelloMessage as H, NavigateParams as N, OverflowCheckResult as O, PageStateResult as P, QueryElementParams as Q, RegionContext as R, ScenarioDetail as S, ViewportContext as V, CaptureElementResult as a, ClientCommand as b, ClientEventMessage as c, CommandResponse as d, CommandType as e, ComponentSourceInfo as f, ConsoleEvent as g, ConsoleLevel as h, ElementStyleResult as i, ElementSummary as j, EventType as k, NavigationEvent as l, NetworkEvent as m, NoteStatus as n, NoteTarget as o, NoteType as p, NoteVerificationResult as q, QueryElementResult as r, ReloadParams as s, RuntimeErrorEvent as t, ScenarioOverview as u, ScrollContext as v, VisualNote as w };
@@ -1,5 +1,5 @@
1
- export { B as Breadcrumb, C as CaptureElementParams, a as CaptureElementResult, b as ClientCommand, c as ClientEventMessage, d as CommandResponse, e as CommandType, f as ConsoleEvent, g as ConsoleLevel, D as DOMRectJson, E as ElementContext, h as ElementStyleResult, i as ElementSummary, j as EventType, H as HelloMessage, N as NavigateParams, k as NavigationEvent, l as NetworkEvent, m as NoteStatus, n as NoteTarget, o as NoteType, p as NoteVerificationResult, O as OverflowCheckResult, P as PageStateResult, Q as QueryElementParams, q as QueryElementResult, R as RegionContext, r as ReloadParams, s as RuntimeErrorEvent, S as ScenarioDetail, t as ScenarioOverview, u as ScrollContext, V as ViewportContext, v as VisualNote } from '../notes-BMnonq46.js';
2
- export { I as Incident, a as IncidentOccurrence, b as IncidentSeverity, c as IncidentSource, d as IncidentStatus, P as ProbeResult, e as ProbeType, f as Project, S as Session, V as VerificationProbe, g as VerificationRecipe, h as VerificationResult } from '../projects-D5J-egVN.js';
1
+ export { B as Breadcrumb, C as CaptureElementParams, a as CaptureElementResult, b as ClientCommand, c as ClientEventMessage, d as CommandResponse, e as CommandType, f as ComponentSourceInfo, g as ConsoleEvent, h as ConsoleLevel, D as DOMRectJson, E as ElementContext, i as ElementStyleResult, j as ElementSummary, k as EventType, H as HelloMessage, N as NavigateParams, l as NavigationEvent, m as NetworkEvent, n as NoteStatus, o as NoteTarget, p as NoteType, q as NoteVerificationResult, O as OverflowCheckResult, P as PageStateResult, Q as QueryElementParams, r as QueryElementResult, R as RegionContext, s as ReloadParams, t as RuntimeErrorEvent, S as ScenarioDetail, u as ScenarioOverview, v as ScrollContext, V as ViewportContext, w as VisualNote } from '../commands-fjuqKzkm.js';
2
+ export { I as Incident, a as IncidentOccurrence, b as IncidentSeverity, c as IncidentSource, d as IncidentStatus, P as ProbeResult, e as ProbeType, f as Project, S as Session, V as VerificationProbe, g as VerificationRecipe, h as VerificationResult } from '../projects-DB7S312i.js';
3
3
  import { Rules } from '@visulima/redact';
4
4
  export { Rules, standardRules, redact as visulimaRedact } from '@visulima/redact';
5
5
 
@@ -1,6 +1,6 @@
1
- import { S as StorageDB, b as ScreenshotStore, a as SessionManager, c as NotesEngine, V as VerificationEngine, N as NoteVerificationEngine } from '../engine-B43IohQY.js';
2
- import { c as ClientEventMessage } from '../notes-BMnonq46.js';
3
- import { I as Incident } from '../projects-D5J-egVN.js';
1
+ import { S as StorageDB, b as ScreenshotStore, a as SessionManager, c as NotesEngine, V as VerificationEngine, N as NoteVerificationEngine } from '../engine-CmchnMDq.js';
2
+ import { c as ClientEventMessage } from '../commands-fjuqKzkm.js';
3
+ import { I as Incident } from '../projects-DB7S312i.js';
4
4
  import http from 'node:http';
5
5
  import { WebSocketServer } from 'ws';
6
6
 
@@ -1,5 +1,5 @@
1
- import { B as Breadcrumb, i as ElementSummary, v as VisualNote, m as NoteStatus, t as ScenarioOverview, S as ScenarioDetail, p as NoteVerificationResult, d as CommandResponse, b as ClientCommand } from './notes-BMnonq46.js';
2
- import { f as Project, S as Session, I as Incident, d as IncidentStatus, b as IncidentSeverity, a as IncidentOccurrence, h as VerificationResult, g as VerificationRecipe } from './projects-D5J-egVN.js';
1
+ import { B as Breadcrumb, j as ElementSummary, w as VisualNote, n as NoteStatus, u as ScenarioOverview, S as ScenarioDetail, q as NoteVerificationResult, d as CommandResponse, b as ClientCommand } from './commands-fjuqKzkm.js';
2
+ import { f as Project, S as Session, I as Incident, d as IncidentStatus, b as IncidentSeverity, a as IncidentOccurrence, h as VerificationResult, g as VerificationRecipe } from './projects-DB7S312i.js';
3
3
  import { WebSocket } from 'ws';
4
4
 
5
5
  declare class StorageDB {
package/dist/index.d.ts CHANGED
@@ -1,11 +1,11 @@
1
- export { B as Breadcrumb, C as CaptureElementParams, a as CaptureElementResult, b as ClientCommand, c as ClientEventMessage, d as CommandResponse, e as CommandType, f as ConsoleEvent, g as ConsoleLevel, D as DOMRectJson, E as ElementContext, h as ElementStyleResult, i as ElementSummary, j as EventType, H as HelloMessage, N as NavigateParams, k as NavigationEvent, l as NetworkEvent, m as NoteStatus, n as NoteTarget, o as NoteType, p as NoteVerificationResult, O as OverflowCheckResult, P as PageStateResult, Q as QueryElementParams, q as QueryElementResult, R as RegionContext, r as ReloadParams, s as RuntimeErrorEvent, S as ScenarioDetail, t as ScenarioOverview, u as ScrollContext, V as ViewportContext, v as VisualNote } from './notes-BMnonq46.js';
2
- export { I as Incident, a as IncidentOccurrence, b as IncidentSeverity, c as IncidentSource, d as IncidentStatus, P as ProbeResult, e as ProbeType, f as Project, S as Session, V as VerificationProbe, g as VerificationRecipe, h as VerificationResult } from './projects-D5J-egVN.js';
1
+ export { B as Breadcrumb, C as CaptureElementParams, a as CaptureElementResult, b as ClientCommand, c as ClientEventMessage, d as CommandResponse, e as CommandType, f as ComponentSourceInfo, g as ConsoleEvent, h as ConsoleLevel, D as DOMRectJson, E as ElementContext, i as ElementStyleResult, j as ElementSummary, k as EventType, H as HelloMessage, N as NavigateParams, l as NavigationEvent, m as NetworkEvent, n as NoteStatus, o as NoteTarget, p as NoteType, q as NoteVerificationResult, O as OverflowCheckResult, P as PageStateResult, Q as QueryElementParams, r as QueryElementResult, R as RegionContext, s as ReloadParams, t as RuntimeErrorEvent, S as ScenarioDetail, u as ScenarioOverview, v as ScrollContext, V as ViewportContext, w as VisualNote } from './commands-fjuqKzkm.js';
2
+ export { I as Incident, a as IncidentOccurrence, b as IncidentSeverity, c as IncidentSource, d as IncidentStatus, P as ProbeResult, e as ProbeType, f as Project, S as Session, V as VerificationProbe, g as VerificationRecipe, h as VerificationResult } from './projects-DB7S312i.js';
3
3
  export { BROWSER_SECURITY_RULES, FingerprintInput, REDACTED_PLACEHOLDER, SENSITIVE_KEY_PATTERNS, SENSITIVE_QUERY_PARAMS, SelectorOptions, computeFingerprint, extractSourceFromStack, getSemanticSelector, isSensitiveKey, normalizeErrorMessage, normalizeSourceFile, redactHeaders, redactSensitiveData, redactUrl, truncate } from './core/index.js';
4
4
  export { BrowserTrackClient, getClient, init as initClient } from './client/index.js';
5
5
  export { BrowserTrackDaemon, createDaemon } from './daemon/index.js';
6
- export { c as createMcpServer } from './server-BztYp1Zc.js';
6
+ export { c as createMcpServer } from './server-DiVmTrIR.js';
7
7
  export { Rules, standardRules, redact as visulimaRedact } from '@visulima/redact';
8
- import './engine-B43IohQY.js';
8
+ import './engine-CmchnMDq.js';
9
9
  import 'ws';
10
10
  import 'node:http';
11
11
  import '@modelcontextprotocol/sdk/server/index.js';
package/dist/index.js CHANGED
@@ -2,7 +2,7 @@ import {
2
2
  BrowserTrackClient,
3
3
  getClient,
4
4
  init
5
- } from "./chunk-WB7ZKWK7.js";
5
+ } from "./chunk-INXDWPJW.js";
6
6
  import {
7
7
  BrowserTrackDaemon,
8
8
  createDaemon
@@ -27,7 +27,7 @@ import {
27
27
  } from "./chunk-6VA7GBAO.js";
28
28
  import {
29
29
  createMcpServer
30
- } from "./chunk-UP5JKCFY.js";
30
+ } from "./chunk-464D4U2U.js";
31
31
  import "./chunk-3HOXPTM2.js";
32
32
  export {
33
33
  BROWSER_SECURITY_RULES,
@@ -1,9 +1,9 @@
1
1
  import { Tool } from '@modelcontextprotocol/sdk/types.js';
2
- export { M as McpContext, a as McpServerOptions, c as createMcpServer, h as handleToolCall } from '../server-BztYp1Zc.js';
2
+ export { M as McpContext, a as McpServerOptions, c as createMcpServer, h as handleToolCall } from '../server-DiVmTrIR.js';
3
3
  import '@modelcontextprotocol/sdk/server/index.js';
4
- import '../engine-B43IohQY.js';
5
- import '../notes-BMnonq46.js';
6
- import '../projects-D5J-egVN.js';
4
+ import '../engine-CmchnMDq.js';
5
+ import '../commands-fjuqKzkm.js';
6
+ import '../projects-DB7S312i.js';
7
7
  import 'ws';
8
8
 
9
9
  declare const TOOLS: Tool[];
package/dist/mcp/index.js CHANGED
@@ -2,7 +2,7 @@ import {
2
2
  TOOLS,
3
3
  createMcpServer,
4
4
  handleToolCall
5
- } from "../chunk-UP5JKCFY.js";
5
+ } from "../chunk-464D4U2U.js";
6
6
  import "../chunk-3HOXPTM2.js";
7
7
  export {
8
8
  TOOLS,
@@ -1,4 +1,4 @@
1
- import { B as Breadcrumb, l as NetworkEvent, i as ElementSummary } from './notes-BMnonq46.js';
1
+ import { B as Breadcrumb, m as NetworkEvent, j as ElementSummary } from './commands-fjuqKzkm.js';
2
2
 
3
3
  type IncidentStatus = 'OPEN' | 'FIX_ATTEMPTED' | 'VERIFYING' | 'VERIFIED' | 'FAILED' | 'INCONCLUSIVE';
4
4
  type IncidentSeverity = 'error' | 'warn' | 'fatal';
@@ -1,5 +1,5 @@
1
1
  import { Server } from '@modelcontextprotocol/sdk/server/index.js';
2
- import { S as StorageDB, a as SessionManager, V as VerificationEngine, N as NoteVerificationEngine } from './engine-B43IohQY.js';
2
+ import { S as StorageDB, a as SessionManager, V as VerificationEngine, N as NoteVerificationEngine } from './engine-CmchnMDq.js';
3
3
 
4
4
  interface McpContext {
5
5
  db: StorageDB;
@@ -0,0 +1,108 @@
1
+ ---
2
+ title: Component & Source Resolver
3
+ description: Map live browser DOM elements to React Fiber, Vue VNode, Svelte metadata, and exact source file locations for AI coding agents
4
+ order: 5
5
+ ---
6
+
7
+ # Component & Source-Map Resolver 🧬
8
+
9
+ A core challenge for AI coding agents during frontend debugging is bridging the gap between what the browser renders (e.g., `<button class="sc-bdVaJa bDwzTH">`) and the actual source code file in the repository (e.g., `src/components/CheckoutButton.tsx:42`).
10
+
11
+ BrowserTrack includes an automated **Component & Source-Map Resolver** that inspects internal framework virtual DOM instances in real time and attaches exact component and source locations to visual notes, user interaction breadcrumbs, and error incidents.
12
+
13
+ ---
14
+
15
+ ## ⚡ Supported Frameworks
16
+
17
+ | Framework | Inspection Technique | Resolved Metadata |
18
+ | :--- | :--- | :--- |
19
+ | **React (v16–19)** | `__reactFiber$`, `_debugSource`, `_debugOwner` | Component Name, Source File, Line, Column, Component Hierarchy, Props |
20
+ | **Vue 3** | `__vueParentComponent`, `__vnode` | Component Name (`__name`), SFC File (`__file`), Hierarchy, Props |
21
+ | **Vue 2** | `__vue__.$options` | Component Tag, SFC File (`__file`) |
22
+ | **Svelte** | `__svelte_meta.loc` | Svelte Component Name, File Path, Line, Column |
23
+ | **Web Components** | Hyphenated custom element tags | Custom Element Tag Name |
24
+ | **Generic / Vanilla** | `data-component`, `data-source-file`, `data-source-line` | Explicit Component & File Annotation |
25
+
26
+ ---
27
+
28
+ ## 🔍 How It Works
29
+
30
+ ```mermaid
31
+ graph LR
32
+ A[Target DOM Element] --> B[BrowserTrack Resolver]
33
+ B -->|React Fiber| C[Extract _debugSource & _debugOwner]
34
+ B -->|Vue VNode| D[Extract __file & type.__name]
35
+ B -->|Svelte Meta| E[Extract loc.file & loc.line]
36
+ C & D & E --> F[ComponentSourceInfo]
37
+ F --> G[Visual Notes, Breadcrumbs & Incidents]
38
+ G --> H[AI Agent opens exact file:line via MCP]
39
+ ```
40
+
41
+ ### Development Mode Source Maps
42
+ Modern bundlers (Vite, Next.js, Create React App, Nuxt, SvelteKit) automatically populate `_debugSource` and `__file` on virtual DOM nodes during local development. BrowserTrack reads this data directly without requiring additional build plugins.
43
+
44
+ ---
45
+
46
+ ## 📦 Resolved Metadata Structure
47
+
48
+ Whenever a visual note is taken, or when user interactions precede a crash:
49
+
50
+ ```typescript
51
+ export interface ComponentSourceInfo {
52
+ framework?: 'react' | 'vue' | 'svelte' | 'web-component' | 'vanilla';
53
+ componentName?: string; // e.g. "CheckoutButton"
54
+ sourceFile?: string; // e.g. "src/components/CheckoutButton.tsx"
55
+ sourceLine?: number; // e.g. 42
56
+ sourceColumn?: number; // e.g. 8
57
+ hierarchy?: string[]; // e.g. ["App", "ShopLayout", "CartDrawer", "CheckoutButton"]
58
+ props?: Record<string, any>;// Sanitized component props
59
+ }
60
+ ```
61
+
62
+ ---
63
+
64
+ ## 🤖 AI Agent MCP Usage
65
+
66
+ When an agent retrieves an incident or visual note:
67
+
68
+ ### In `get_incident`:
69
+ The `lastInteractedElement` provides direct source coordinates:
70
+ ```json
71
+ {
72
+ "lastInteractedElement": {
73
+ "selector": "button#checkout-btn",
74
+ "tag": "button",
75
+ "componentSource": {
76
+ "framework": "react",
77
+ "componentName": "CheckoutButton",
78
+ "sourceFile": "src/components/CheckoutButton.tsx",
79
+ "sourceLine": 42,
80
+ "hierarchy": ["App", "ShopLayout", "CheckoutButton"]
81
+ }
82
+ }
83
+ }
84
+ ```
85
+
86
+ ### In `get_note`:
87
+ ```json
88
+ {
89
+ "elementContext": {
90
+ "selector": ".user-profile-card",
91
+ "componentSource": {
92
+ "framework": "vue",
93
+ "componentName": "UserProfileCard",
94
+ "sourceFile": "src/components/UserProfileCard.vue"
95
+ }
96
+ }
97
+ }
98
+ ```
99
+
100
+ The AI agent can immediately edit the exact file and line without running codebase searches or guessing CSS selectors!
101
+
102
+ ---
103
+
104
+ ## 🎨 Interactive Visual Badges in Browser
105
+
106
+ When inspecting elements or viewing saved notes on screen:
107
+ - The Note Editor modal displays a purple pill: `🧬 <CheckoutButton> (src/components/CheckoutButton.tsx:42)`.
108
+ - The Note Details Card popover displays the component badge and framework tag (`REACT`, `VUE`, `SVELTE`).
package/docs/index.md CHANGED
@@ -40,6 +40,7 @@ graph TD
40
40
  - [Getting Started](./getting-started.md) — Quick installation and setup in under 2 minutes.
41
41
  - [Visual Notes & Annotations](./visual-notes.md) — Screen notes, region selection, and persistent markers.
42
42
  - [Multi-Step Scenarios & Flows](./scenarios-flows.md) — Sequential reproduction flows, Save & Next Step, and stepper walk-throughs.
43
+ - [Component & Source Resolver](./component-resolver.md) — Map live DOM elements to React Fiber, Vue VNode, Svelte, and exact source file locations.
43
44
  - [Incidents & Error Diagnostics](./incidents-diagnostics.md) — Ingest runtime errors, stack traces, and breadcrumbs.
44
45
  - [Closed-Loop Verification](./closed-loop-verification.md) — Automated bug-fix and layout verification.
45
46
  - [MCP Tool Reference](./mcp-reference.md) — Complete guide to all MCP tools.
@@ -24,7 +24,7 @@ Lists recorded browser runtime errors, unhandled rejections, and console errors
24
24
  Retrieves compact, high-signal debugging context for an error incident.
25
25
  - **Arguments**:
26
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.
27
+ - **Returns**: Stack trace, normalized error message, breadcrumbs timeline, failed network calls, last interacted element (with `componentSource`: component name, source file, line number, hierarchy), and error screenshot.
28
28
 
29
29
  ### `get_console`
30
30
  Fetches recent console logs, warnings, and errors from a browser session.
@@ -84,7 +84,7 @@ Retrieves full chronological step-by-step reproduction flow with selectors, rout
84
84
  Retrieves full debugging context for a visual note.
85
85
  - **Arguments**:
86
86
  - `noteId` (`string`, *required*): The unique ID of the visual note (e.g. `note_30a89599`).
87
- - **Returns**: Note message, route, viewport dimensions, target element selector, DOM context, screenshot file path, scenario metadata.
87
+ - **Returns**: Note message, route, viewport dimensions, target element selector, DOM context (including `componentSource` with framework, component name, source file path, and line number), screenshot file path, scenario metadata.
88
88
 
89
89
  ### `capture_note_context`
90
90
  Inspects live DOM context, bounding box, overflow, and computed styles for a target element.
@@ -64,4 +64,40 @@ The bottom-right floating toolbar gives quick access:
64
64
  - **`🎯 Element`**: Toggle element inspection mode.
65
65
  - **`📐 Region`**: Activate rectangle drag mode.
66
66
  - **`📄 Page`**: Open full-page note modal.
67
+ - **`🎬 Flow`**: Start/finish sequential scenario recording.
67
68
  - **`📌 Notes (N)`**: Toggle visibility of all note markers on screen.
69
+
70
+ ---
71
+
72
+ ## 🙈 Hiding the Tool via Query String (Headless / Clean Mode)
73
+
74
+ When running automated visual regression tests, Cypress, Playwright, or giving clean demo presentations, you can hide the visible BrowserTrack UI (dock, pins, overlays) completely using URL query parameters:
75
+
76
+ ### 1. Built-in Query Parameters
77
+ Simply append any of the following to your page URL:
78
+ - `?bt=0` or `?bt=false` or `?bt=hidden` or `?bt=off`
79
+ - `?browsertrack=false` or `?browsertrack=0` or `?browsertrack=hidden`
80
+ - `?no_bt` / `?no_bt=1` or `?no_browsertrack=1`
81
+ - `?hide_bt=1` or `?hide_browsertrack=1`
82
+
83
+ ```text
84
+ http://localhost:3000/dashboard?bt=false
85
+ ```
86
+
87
+ ### 2. Custom Query Parameter Configuration
88
+ You can also define your own custom query parameters in client options:
89
+ ```typescript
90
+ import { init } from 'browsertrack/client';
91
+
92
+ init({
93
+ hideQueryParam: ['cypress', 'clean_view', 'no_ui'],
94
+ // or hide by default in specific environments:
95
+ hidden: process.env.NODE_ENV === 'test',
96
+ });
97
+ ```
98
+
99
+ When hidden:
100
+ - The floating toolbar and on-screen note pins are not displayed.
101
+ - Alt+Click hover highlights and selection shortcuts are inactive.
102
+ - Background diagnostics (runtime errors, console capture, network logging, MCP command execution) continue working seamlessly in headless mode.
103
+ - Programmatic visibility can be restored anytime via `client.setUIVisible(true)`.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "browsertrack",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "description": "Local browser diagnostics + MCP bridge for coding agents",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -22,7 +22,10 @@ import { WebSocketTransport } from './transport/websocket.js';
22
22
  import { NoteInspector } from './notes/inspector.js';
23
23
 
24
24
  export class BrowserTrackClient {
25
- public options: Required<Omit<BrowserDiagClientOptions, 'notes'>> & { notes: Required<NonNullable<BrowserDiagClientOptions['notes']>> };
25
+ public options: Required<Omit<BrowserDiagClientOptions, 'notes' | 'hideQueryParam'>> & {
26
+ hideQueryParam?: string | string[];
27
+ notes: Required<NonNullable<BrowserDiagClientOptions['notes']>>;
28
+ };
26
29
  private breadcrumbs: BreadcrumbBuffer;
27
30
  private transport: WebSocketTransport;
28
31
  private screenshotDriver: ScreenshotDriver;
@@ -56,6 +59,10 @@ export class BrowserTrackClient {
56
59
  this.inspector = new NoteInspector(this.transport, this.screenshotDriver, {
57
60
  shortcut: this.options.notes.shortcut,
58
61
  maskSelectors: this.options.notes.maskSelectors,
62
+ showToolbar: this.options.notes.showToolbar,
63
+ showBadges: this.options.notes.showBadges,
64
+ hidden: this.options.hidden,
65
+ hideQueryParam: this.options.hideQueryParam,
59
66
  });
60
67
  }
61
68
  }
@@ -142,6 +149,16 @@ export class BrowserTrackClient {
142
149
  }
143
150
  }
144
151
 
152
+ public isUIVisible(): boolean {
153
+ return this.inspector ? this.inspector.isVisible() : false;
154
+ }
155
+
156
+ public setUIVisible(visible: boolean): void {
157
+ if (this.inspector) {
158
+ this.inspector.setVisible(visible);
159
+ }
160
+ }
161
+
145
162
  public setInspectMode(mode: 'element' | 'region' | 'page' | 'idle'): void {
146
163
  if (this.inspector) {
147
164
  this.inspector.setMode(mode);