browsertrack 0.2.0 → 0.2.2
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/AGENTS.md +11 -6
- package/README.md +2 -0
- package/dist/{chunk-WB7ZKWK7.js → chunk-4HRLW6YF.js} +509 -109
- package/dist/chunk-4HRLW6YF.js.map +1 -0
- package/dist/{chunk-3HOXPTM2.js → chunk-AYSVE6NG.js} +808 -53
- package/dist/chunk-AYSVE6NG.js.map +1 -0
- package/dist/{chunk-6VA7GBAO.js → chunk-QRZ57ME3.js} +70 -2
- package/dist/chunk-QRZ57ME3.js.map +1 -0
- package/dist/{chunk-UP5JKCFY.js → chunk-TWEYRBDU.js} +281 -44
- package/dist/chunk-TWEYRBDU.js.map +1 -0
- package/dist/cli/index.js +1040 -546
- package/dist/cli/index.js.map +1 -1
- package/dist/client/index.cjs +536 -109
- package/dist/client/index.d.ts +36 -4
- package/dist/client/index.js +8 -4
- package/dist/client.iife.js +42 -19
- package/dist/{notes-BMnonq46.d.ts → commands-fjuqKzkm.d.ts} +125 -114
- package/dist/core/index.d.ts +26 -3
- package/dist/core/index.js +9 -1
- package/dist/daemon/index.d.ts +4 -4
- package/dist/daemon/index.js +6 -8
- package/dist/{engine-B43IohQY.d.ts → engine-CmchnMDq.d.ts} +2 -2
- package/dist/index.d.ts +5 -5
- package/dist/index.js +14 -7
- package/dist/mcp/index.d.ts +4 -4
- package/dist/mcp/index.js +7 -4
- package/dist/{projects-D5J-egVN.d.ts → projects-DB7S312i.d.ts} +1 -1
- package/dist/{server-BztYp1Zc.d.ts → server-DjV7RWQM.d.ts} +10 -2
- package/docs/cli.md +4 -1
- package/docs/component-resolver.md +108 -0
- package/docs/getting-started.md +60 -6
- package/docs/index.md +1 -0
- package/docs/mcp-reference.md +44 -2
- package/docs/visual-notes.md +36 -0
- package/package.json +1 -1
- package/packages/cli/src/index.ts +247 -151
- package/packages/client/src/client.ts +18 -1
- package/packages/client/src/config.ts +84 -1
- package/packages/client/src/index.ts +4 -1
- package/packages/client/src/interceptors/interaction.ts +3 -0
- package/packages/client/src/interceptors/navigation.ts +38 -26
- package/packages/client/src/interceptors/network.ts +22 -17
- package/packages/client/src/notes/inspector.ts +186 -51
- package/packages/client/src/source/resolver.ts +278 -0
- package/packages/client/src/transport/websocket.ts +23 -18
- package/packages/core/src/index.ts +1 -0
- package/packages/core/src/safety.ts +86 -0
- package/packages/core/src/types/events.ts +3 -0
- package/packages/core/src/types/notes.ts +11 -0
- package/packages/daemon/src/server/daemon.ts +7 -1
- package/packages/daemon/src/server/http.ts +125 -5
- package/packages/daemon/src/server/ws.ts +33 -29
- package/packages/daemon/src/storage/db.ts +57 -35
- package/packages/mcp/src/handlers.ts +115 -45
- package/packages/mcp/src/server.ts +202 -2
- package/test/client/component-resolver.test.ts +141 -0
- package/test/client/interceptors.test.ts +56 -0
- package/test/core/safety.test.ts +106 -0
- package/test/daemon/storage.test.ts +36 -0
- package/test/e2e/daemon-mcp-e2e.test.ts +10 -0
- package/test/mcp/auto-start.test.ts +87 -0
- package/dist/chunk-3HOXPTM2.js.map +0 -1
- package/dist/chunk-6VA7GBAO.js.map +0 -1
- package/dist/chunk-7OCOQGDN.js +0 -635
- package/dist/chunk-7OCOQGDN.js.map +0 -1
- package/dist/chunk-UP5JKCFY.js.map +0 -1
- 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
|
|
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 };
|
package/dist/core/index.d.ts
CHANGED
|
@@ -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
|
|
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-
|
|
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
|
|
|
@@ -83,4 +83,27 @@ declare function getSemanticSelector(element: HTMLElement | Element, options?: S
|
|
|
83
83
|
*/
|
|
84
84
|
declare function truncate(str: string | undefined | null, maxLength?: number): string;
|
|
85
85
|
|
|
86
|
-
|
|
86
|
+
/**
|
|
87
|
+
* BrowserTrack Safety & Error-Resilience Utilities
|
|
88
|
+
* Provides bulletproof try/catch wrappers, circular-safe JSON serialization, and defensive helpers.
|
|
89
|
+
*/
|
|
90
|
+
/**
|
|
91
|
+
* Safely parses a JSON string with fallback. Never throws.
|
|
92
|
+
*/
|
|
93
|
+
declare function safeJsonParse<T>(raw: any, fallback: T): T;
|
|
94
|
+
/**
|
|
95
|
+
* Safely serializes an object to JSON, handling circular references and non-serializable values.
|
|
96
|
+
* Never throws "TypeError: Converting circular structure to JSON".
|
|
97
|
+
*/
|
|
98
|
+
declare function safeJsonStringify(val: any, fallback?: string): string;
|
|
99
|
+
/**
|
|
100
|
+
* Executes a synchronous function within an isolated try/catch block.
|
|
101
|
+
* Returns the function result, or fallback if an exception was thrown.
|
|
102
|
+
*/
|
|
103
|
+
declare function safeExecute<T>(fn: () => T, fallback: T, onError?: (err: any) => void): T;
|
|
104
|
+
/**
|
|
105
|
+
* Executes an asynchronous promise or async function safely without unhandled rejection.
|
|
106
|
+
*/
|
|
107
|
+
declare function safeAsync<T>(action: Promise<T> | (() => Promise<T>), fallback: T, onError?: (err: any) => void): Promise<T>;
|
|
108
|
+
|
|
109
|
+
export { BROWSER_SECURITY_RULES, type FingerprintInput, REDACTED_PLACEHOLDER, SENSITIVE_KEY_PATTERNS, SENSITIVE_QUERY_PARAMS, type SelectorOptions, computeFingerprint, extractSourceFromStack, getSemanticSelector, isSensitiveKey, normalizeErrorMessage, normalizeSourceFile, redactHeaders, redactSensitiveData, redactUrl, safeAsync, safeExecute, safeJsonParse, safeJsonStringify, truncate };
|
package/dist/core/index.js
CHANGED
|
@@ -12,10 +12,14 @@ import {
|
|
|
12
12
|
redactHeaders,
|
|
13
13
|
redactSensitiveData,
|
|
14
14
|
redactUrl,
|
|
15
|
+
safeAsync,
|
|
16
|
+
safeExecute,
|
|
17
|
+
safeJsonParse,
|
|
18
|
+
safeJsonStringify,
|
|
15
19
|
standardRules,
|
|
16
20
|
truncate,
|
|
17
21
|
visulimaRedact
|
|
18
|
-
} from "../chunk-
|
|
22
|
+
} from "../chunk-QRZ57ME3.js";
|
|
19
23
|
export {
|
|
20
24
|
BROWSER_SECURITY_RULES,
|
|
21
25
|
REDACTED_PLACEHOLDER,
|
|
@@ -30,6 +34,10 @@ export {
|
|
|
30
34
|
redactHeaders,
|
|
31
35
|
redactSensitiveData,
|
|
32
36
|
redactUrl,
|
|
37
|
+
safeAsync,
|
|
38
|
+
safeExecute,
|
|
39
|
+
safeJsonParse,
|
|
40
|
+
safeJsonStringify,
|
|
33
41
|
standardRules,
|
|
34
42
|
truncate,
|
|
35
43
|
visulimaRedact
|
package/dist/daemon/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { S as StorageDB, b as ScreenshotStore, a as SessionManager,
|
|
2
|
-
import { c as ClientEventMessage } from '../
|
|
3
|
-
import { I as Incident } from '../projects-
|
|
1
|
+
import { S as StorageDB, b as ScreenshotStore, a as SessionManager, V as VerificationEngine, N as NoteVerificationEngine, c as NotesEngine } 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
|
|
|
@@ -25,7 +25,7 @@ declare class IncidentEngine {
|
|
|
25
25
|
private handleErrorEvent;
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
declare function createHttpHandler(db: StorageDB, sessionManager: SessionManager, baseScreenshotsDir: string): (req: http.IncomingMessage, res: http.ServerResponse) => void
|
|
28
|
+
declare function createHttpHandler(db: StorageDB, sessionManager: SessionManager, baseScreenshotsDir: string, verificationEngine?: VerificationEngine, noteVerificationEngine?: NoteVerificationEngine): (req: http.IncomingMessage, res: http.ServerResponse) => Promise<void>;
|
|
29
29
|
|
|
30
30
|
declare function setupWebSocketServer(wss: WebSocketServer, db: StorageDB, sessionManager: SessionManager, incidentEngine: IncidentEngine, notesEngine?: NotesEngine, maxEventsPerSession?: number, verbose?: boolean): void;
|
|
31
31
|
|
package/dist/daemon/index.js
CHANGED
|
@@ -1,20 +1,18 @@
|
|
|
1
1
|
import {
|
|
2
2
|
BrowserTrackDaemon,
|
|
3
3
|
IncidentEngine,
|
|
4
|
-
createDaemon,
|
|
5
|
-
createHttpHandler,
|
|
6
|
-
setupWebSocketServer
|
|
7
|
-
} from "../chunk-7OCOQGDN.js";
|
|
8
|
-
import "../chunk-6VA7GBAO.js";
|
|
9
|
-
import {
|
|
10
4
|
NoteVerificationEngine,
|
|
11
5
|
NotesEngine,
|
|
12
6
|
ScreenshotStore,
|
|
13
7
|
SessionManager,
|
|
14
8
|
StorageDB,
|
|
15
9
|
VerificationEngine,
|
|
16
|
-
|
|
17
|
-
|
|
10
|
+
createDaemon,
|
|
11
|
+
createHttpHandler,
|
|
12
|
+
getDaemonConfig,
|
|
13
|
+
setupWebSocketServer
|
|
14
|
+
} from "../chunk-AYSVE6NG.js";
|
|
15
|
+
import "../chunk-QRZ57ME3.js";
|
|
18
16
|
export {
|
|
19
17
|
BrowserTrackDaemon,
|
|
20
18
|
IncidentEngine,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { B as Breadcrumb,
|
|
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-
|
|
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
|
|
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-
|
|
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';
|
|
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
|
+
export { BROWSER_SECURITY_RULES, FingerprintInput, REDACTED_PLACEHOLDER, SENSITIVE_KEY_PATTERNS, SENSITIVE_QUERY_PARAMS, SelectorOptions, computeFingerprint, extractSourceFromStack, getSemanticSelector, isSensitiveKey, normalizeErrorMessage, normalizeSourceFile, redactHeaders, redactSensitiveData, redactUrl, safeAsync, safeExecute, safeJsonParse, safeJsonStringify, 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-
|
|
6
|
+
export { c as createMcpServer } from './server-DjV7RWQM.js';
|
|
7
7
|
export { Rules, standardRules, redact as visulimaRedact } from '@visulima/redact';
|
|
8
|
-
import './engine-
|
|
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,11 +2,14 @@ import {
|
|
|
2
2
|
BrowserTrackClient,
|
|
3
3
|
getClient,
|
|
4
4
|
init
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-4HRLW6YF.js";
|
|
6
|
+
import {
|
|
7
|
+
createMcpServer
|
|
8
|
+
} from "./chunk-TWEYRBDU.js";
|
|
6
9
|
import {
|
|
7
10
|
BrowserTrackDaemon,
|
|
8
11
|
createDaemon
|
|
9
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-AYSVE6NG.js";
|
|
10
13
|
import {
|
|
11
14
|
BROWSER_SECURITY_RULES,
|
|
12
15
|
REDACTED_PLACEHOLDER,
|
|
@@ -21,14 +24,14 @@ import {
|
|
|
21
24
|
redactHeaders,
|
|
22
25
|
redactSensitiveData,
|
|
23
26
|
redactUrl,
|
|
27
|
+
safeAsync,
|
|
28
|
+
safeExecute,
|
|
29
|
+
safeJsonParse,
|
|
30
|
+
safeJsonStringify,
|
|
24
31
|
standardRules,
|
|
25
32
|
truncate,
|
|
26
33
|
visulimaRedact
|
|
27
|
-
} from "./chunk-
|
|
28
|
-
import {
|
|
29
|
-
createMcpServer
|
|
30
|
-
} from "./chunk-UP5JKCFY.js";
|
|
31
|
-
import "./chunk-3HOXPTM2.js";
|
|
34
|
+
} from "./chunk-QRZ57ME3.js";
|
|
32
35
|
export {
|
|
33
36
|
BROWSER_SECURITY_RULES,
|
|
34
37
|
BrowserTrackClient,
|
|
@@ -49,6 +52,10 @@ export {
|
|
|
49
52
|
redactHeaders,
|
|
50
53
|
redactSensitiveData,
|
|
51
54
|
redactUrl,
|
|
55
|
+
safeAsync,
|
|
56
|
+
safeExecute,
|
|
57
|
+
safeJsonParse,
|
|
58
|
+
safeJsonStringify,
|
|
52
59
|
standardRules,
|
|
53
60
|
truncate,
|
|
54
61
|
visulimaRedact
|
package/dist/mcp/index.d.ts
CHANGED
|
@@ -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-
|
|
2
|
+
export { M as McpContext, a as McpServerOptions, c as createMcpServer, h as handleToolCall, i as isDaemonRunning } from '../server-DjV7RWQM.js';
|
|
3
3
|
import '@modelcontextprotocol/sdk/server/index.js';
|
|
4
|
-
import '../engine-
|
|
5
|
-
import '../
|
|
6
|
-
import '../projects-
|
|
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
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
2
|
TOOLS,
|
|
3
3
|
createMcpServer,
|
|
4
|
-
handleToolCall
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
handleToolCall,
|
|
5
|
+
isDaemonRunning
|
|
6
|
+
} from "../chunk-TWEYRBDU.js";
|
|
7
|
+
import "../chunk-AYSVE6NG.js";
|
|
8
|
+
import "../chunk-QRZ57ME3.js";
|
|
7
9
|
export {
|
|
8
10
|
TOOLS,
|
|
9
11
|
createMcpServer,
|
|
10
|
-
handleToolCall
|
|
12
|
+
handleToolCall,
|
|
13
|
+
isDaemonRunning
|
|
11
14
|
};
|
|
12
15
|
//# sourceMappingURL=index.js.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { B as Breadcrumb,
|
|
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-
|
|
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;
|
|
@@ -10,9 +10,14 @@ interface McpContext {
|
|
|
10
10
|
}
|
|
11
11
|
declare function handleToolCall(name: string, args: any, ctx: McpContext): Promise<any>;
|
|
12
12
|
|
|
13
|
+
declare function isDaemonRunning(host: string, port: number): Promise<boolean>;
|
|
13
14
|
interface McpServerOptions {
|
|
14
15
|
dbPath?: string;
|
|
15
16
|
context?: Partial<McpContext>;
|
|
17
|
+
autoStartDaemon?: boolean;
|
|
18
|
+
port?: number;
|
|
19
|
+
host?: string;
|
|
20
|
+
detached?: boolean;
|
|
16
21
|
}
|
|
17
22
|
declare function createMcpServer(options?: McpServerOptions): {
|
|
18
23
|
server: Server<{
|
|
@@ -49,7 +54,10 @@ declare function createMcpServer(options?: McpServerOptions): {
|
|
|
49
54
|
} | undefined;
|
|
50
55
|
} | undefined;
|
|
51
56
|
}>;
|
|
57
|
+
ctx: McpContext;
|
|
58
|
+
ensureDaemon: () => Promise<void>;
|
|
59
|
+
stopDaemon(): Promise<void>;
|
|
52
60
|
startStdio(): Promise<void>;
|
|
53
61
|
};
|
|
54
62
|
|
|
55
|
-
export { type McpContext as M, type McpServerOptions as a, createMcpServer as c, handleToolCall as h };
|
|
63
|
+
export { type McpContext as M, type McpServerOptions as a, createMcpServer as c, handleToolCall as h, isDaemonRunning as i };
|
package/docs/cli.md
CHANGED
|
@@ -35,9 +35,12 @@ browsertrack clear # Wipe stored logs, screenshots, and incidents
|
|
|
35
35
|
|
|
36
36
|
### MCP Integration
|
|
37
37
|
```bash
|
|
38
|
-
browsertrack mcp # Start Model Context Protocol server over stdio
|
|
38
|
+
browsertrack mcp # Start Model Context Protocol server over stdio (auto-boots singleton daemon if offline)
|
|
39
|
+
browsertrack mcp --no-daemon # Start MCP server without auto-booting background daemon
|
|
39
40
|
```
|
|
40
41
|
|
|
42
|
+
> **⚡ Singleton Daemon Lifecycle**: When starting `browsertrack mcp`, BrowserTrack automatically checks if the daemon is already running. If offline, it starts a single, persistent background daemon on `http://127.0.0.1:7331`. All IDE windows, workspaces, and sub-sessions share this single daemon without spawning duplicates or conflicting on ports.
|
|
43
|
+
|
|
41
44
|
---
|
|
42
45
|
|
|
43
46
|
## 📖 Documentation Commands (Docboot)
|
|
@@ -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`).
|