browsertrack 0.1.2 → 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 (52) hide show
  1. package/AGENTS.md +6 -2
  2. package/dist/{chunk-ILRYKMME.js → chunk-3HOXPTM2.js} +97 -3
  3. package/dist/chunk-3HOXPTM2.js.map +1 -0
  4. package/dist/{chunk-G2Y3CXCY.js → chunk-464D4U2U.js} +86 -3
  5. package/dist/chunk-464D4U2U.js.map +1 -0
  6. package/dist/{chunk-SPCIROIU.js → chunk-7OCOQGDN.js} +24 -5
  7. package/dist/chunk-7OCOQGDN.js.map +1 -0
  8. package/dist/{chunk-SKCMT2DE.js → chunk-INXDWPJW.js} +806 -160
  9. package/dist/chunk-INXDWPJW.js.map +1 -0
  10. package/dist/cli/index.js +202 -6
  11. package/dist/cli/index.js.map +1 -1
  12. package/dist/client/index.cjs +809 -161
  13. package/dist/client/index.d.ts +62 -11
  14. package/dist/client/index.js +7 -3
  15. package/dist/client.iife.js +206 -27
  16. package/dist/{notes-CBvN91Wf.d.ts → commands-fjuqKzkm.d.ts} +125 -91
  17. package/dist/core/index.d.ts +2 -2
  18. package/dist/daemon/index.d.ts +3 -3
  19. package/dist/daemon/index.js +2 -2
  20. package/dist/{engine-CeT9URuN.d.ts → engine-CmchnMDq.d.ts} +13 -2
  21. package/dist/index.d.ts +4 -4
  22. package/dist/index.js +4 -4
  23. package/dist/mcp/index.d.ts +4 -4
  24. package/dist/mcp/index.js +2 -2
  25. package/dist/{projects-CY8ungMt.d.ts → projects-DB7S312i.d.ts} +1 -1
  26. package/dist/{server-Dd8NX2Mk.d.ts → server-DiVmTrIR.d.ts} +1 -1
  27. package/docs/component-resolver.md +108 -0
  28. package/docs/index.md +3 -1
  29. package/docs/mcp-reference.md +15 -2
  30. package/docs/scenarios-flows.md +86 -0
  31. package/docs/visual-notes.md +36 -0
  32. package/package.json +1 -1
  33. package/packages/client/src/client.ts +18 -1
  34. package/packages/client/src/config.ts +84 -1
  35. package/packages/client/src/index.ts +4 -1
  36. package/packages/client/src/interceptors/interaction.ts +3 -0
  37. package/packages/client/src/notes/inspector.ts +640 -166
  38. package/packages/client/src/source/resolver.ts +272 -0
  39. package/packages/core/src/types/events.ts +3 -0
  40. package/packages/core/src/types/notes.ts +36 -0
  41. package/packages/daemon/src/notes/engine.ts +6 -0
  42. package/packages/daemon/src/server/ws.ts +23 -1
  43. package/packages/daemon/src/storage/db.ts +106 -3
  44. package/packages/mcp/src/handlers.ts +59 -0
  45. package/packages/mcp/src/tools.ts +28 -0
  46. package/test/client/component-resolver.test.ts +141 -0
  47. package/test/client/interceptors.test.ts +120 -0
  48. package/test/daemon/scenario-storage.test.ts +158 -0
  49. package/dist/chunk-G2Y3CXCY.js.map +0 -1
  50. package/dist/chunk-ILRYKMME.js.map +0 -1
  51. package/dist/chunk-SKCMT2DE.js.map +0 -1
  52. package/dist/chunk-SPCIROIU.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../packages/daemon/src/config.ts","../packages/daemon/src/storage/db.ts","../packages/daemon/src/storage/screenshot-store.ts","../packages/daemon/src/session/manager.ts","../packages/daemon/src/notes/engine.ts","../packages/daemon/src/notes/verification.ts","../packages/daemon/src/verification/engine.ts"],"sourcesContent":["import os from 'node:os';\nimport path from 'node:path';\n\nexport interface DaemonConfig {\n host: string;\n port: number;\n dataDir: string;\n dbPath: string;\n screenshotsDir: string;\n maxEventsPerSession: number;\n verbose: boolean;\n}\n\nexport function getDaemonConfig(overrides: Partial<DaemonConfig> = {}): DaemonConfig {\n const homeDir = os.homedir();\n const dataDir = overrides.dataDir || path.join(homeDir, '.browsertrack');\n const dbPath = overrides.dbPath || path.join(dataDir, 'browsertrack.db');\n const screenshotsDir = overrides.screenshotsDir || path.join(dataDir, 'projects');\n\n return {\n host: overrides.host || '127.0.0.1',\n port: overrides.port || 7331,\n dataDir,\n dbPath,\n screenshotsDir,\n maxEventsPerSession: overrides.maxEventsPerSession || 1000,\n verbose: !!overrides.verbose,\n };\n}\n","import Database from 'better-sqlite3';\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport type {\n Breadcrumb,\n ElementSummary,\n Incident,\n IncidentOccurrence,\n IncidentSeverity,\n IncidentStatus,\n NetworkEvent,\n Project,\n Session,\n VerificationResult,\n VisualNote,\n NoteStatus,\n NoteVerificationResult,\n} from '../../../core/src/index.js';\n\nexport class StorageDB {\n private db: Database.Database;\n\n constructor(dbPath: string) {\n const dir = path.dirname(dbPath);\n fs.mkdirSync(dir, { recursive: true });\n\n this.db = new Database(dbPath);\n this.db.pragma('journal_mode = WAL');\n this.db.pragma('synchronous = NORMAL');\n this.initTables();\n }\n\n private initTables(): void {\n this.db.exec(`\n CREATE TABLE IF NOT EXISTS projects (\n id TEXT PRIMARY KEY,\n name TEXT UNIQUE,\n origin TEXT,\n path TEXT,\n created_at TEXT,\n updated_at TEXT\n );\n\n CREATE TABLE IF NOT EXISTS sessions (\n id TEXT PRIMARY KEY,\n project_id TEXT,\n origin TEXT,\n url TEXT,\n title TEXT,\n user_agent TEXT,\n connected_at TEXT,\n last_seen_at TEXT,\n active INTEGER DEFAULT 1\n );\n\n CREATE TABLE IF NOT EXISTS events (\n id TEXT PRIMARY KEY,\n session_id TEXT,\n event_type TEXT,\n payload TEXT,\n timestamp INTEGER,\n route TEXT,\n url TEXT\n );\n\n CREATE TABLE IF NOT EXISTS incidents (\n id TEXT PRIMARY KEY,\n project_id TEXT,\n session_id TEXT,\n type TEXT,\n severity TEXT,\n message TEXT,\n source_file TEXT,\n source_line INTEGER,\n source_col INTEGER,\n fingerprint TEXT UNIQUE,\n route TEXT,\n first_seen TEXT,\n last_seen TEXT,\n occurrences INTEGER DEFAULT 1,\n status TEXT DEFAULT 'OPEN',\n stack TEXT,\n breadcrumbs TEXT,\n network_failures TEXT,\n last_element TEXT,\n screenshot_path TEXT\n );\n\n CREATE TABLE IF NOT EXISTS incident_occurrences (\n id TEXT PRIMARY KEY,\n incident_id TEXT,\n session_id TEXT,\n timestamp TEXT,\n route TEXT,\n url TEXT,\n stack TEXT,\n breadcrumbs TEXT,\n last_element TEXT\n );\n\n CREATE TABLE IF NOT EXISTS screenshots (\n id TEXT PRIMARY KEY,\n incident_id TEXT,\n file_path TEXT,\n format TEXT,\n width INTEGER,\n height INTEGER,\n created_at TEXT\n );\n\n CREATE TABLE IF NOT EXISTS verifications (\n id TEXT PRIMARY KEY,\n incident_id TEXT,\n status TEXT,\n checks TEXT,\n before_screenshot TEXT,\n after_screenshot TEXT,\n message TEXT,\n created_at TEXT\n );\n\n CREATE TABLE IF NOT EXISTS notes (\n id TEXT PRIMARY KEY,\n project_id TEXT,\n session_id TEXT,\n type TEXT,\n message TEXT,\n route TEXT,\n url TEXT,\n viewport_json TEXT,\n scroll_json TEXT,\n target_json TEXT,\n element_context_json TEXT,\n region_json TEXT,\n screenshot_path TEXT,\n incident_id TEXT,\n status TEXT DEFAULT 'OPEN',\n created_at TEXT,\n updated_at TEXT,\n resolved_at TEXT\n );\n\n CREATE TABLE IF NOT EXISTS note_verifications (\n id TEXT PRIMARY KEY,\n note_id TEXT,\n status TEXT,\n checks TEXT,\n geometry_diff TEXT,\n before_screenshot TEXT,\n after_screenshot TEXT,\n message TEXT,\n created_at TEXT\n );\n\n CREATE INDEX IF NOT EXISTS idx_events_session ON events(session_id, timestamp);\n CREATE INDEX IF NOT EXISTS idx_incidents_project ON incidents(project_id, status);\n CREATE INDEX IF NOT EXISTS idx_incidents_fp ON incidents(fingerprint);\n CREATE INDEX IF NOT EXISTS idx_notes_project ON notes(project_id, status);\n `);\n }\n\n // --- PROJECTS ---\n public upsertProject(project: { id: string; name: string; origin: string; path?: string }): Project {\n const now = new Date().toISOString();\n const existing = this.db.prepare('SELECT * FROM projects WHERE name = ? OR origin = ?').get(project.name, project.origin) as any;\n\n if (existing) {\n this.db\n .prepare('UPDATE projects SET name = ?, origin = ?, path = COALESCE(?, path), updated_at = ? WHERE id = ?')\n .run(project.name, project.origin, project.path || null, now, existing.id);\n return {\n id: existing.id,\n name: project.name,\n origin: project.origin,\n path: project.path || existing.path,\n createdAt: existing.created_at,\n updatedAt: now,\n };\n }\n\n this.db\n .prepare('INSERT INTO projects (id, name, origin, path, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?)')\n .run(project.id, project.name, project.origin, project.path || null, now, now);\n\n return {\n id: project.id,\n name: project.name,\n origin: project.origin,\n path: project.path,\n createdAt: now,\n updatedAt: now,\n };\n }\n\n public getProject(idOrName: string): Project | null {\n const row = this.db.prepare('SELECT * FROM projects WHERE id = ? OR name = ?').get(idOrName, idOrName) as any;\n if (!row) return null;\n return {\n id: row.id,\n name: row.name,\n origin: row.origin,\n path: row.path,\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n };\n }\n\n public getProjectByOrigin(origin: string): Project | null {\n const row = this.db.prepare('SELECT * FROM projects WHERE origin = ?').get(origin) as any;\n if (!row) return null;\n return {\n id: row.id,\n name: row.name,\n origin: row.origin,\n path: row.path,\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n };\n }\n\n public listProjects(): Project[] {\n const rows = this.db.prepare('SELECT * FROM projects ORDER BY updated_at DESC').all() as any[];\n return rows.map((row) => ({\n id: row.id,\n name: row.name,\n origin: row.origin,\n path: row.path,\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n }));\n }\n\n // --- SESSIONS ---\n public upsertSession(session: Session): void {\n const existing = this.db.prepare('SELECT id FROM sessions WHERE id = ?').get(session.id);\n if (existing) {\n this.db\n .prepare('UPDATE sessions SET url = ?, title = ?, last_seen_at = ?, active = ? WHERE id = ?')\n .run(session.url, session.title, session.lastSeenAt, session.active ? 1 : 0, session.id);\n } else {\n this.db\n .prepare(\n 'INSERT INTO sessions (id, project_id, origin, url, title, user_agent, connected_at, last_seen_at, active) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)'\n )\n .run(\n session.id,\n session.projectId,\n session.origin,\n session.url,\n session.title,\n session.userAgent,\n session.connectedAt,\n session.lastSeenAt,\n session.active ? 1 : 0\n );\n }\n }\n\n public getSession(id: string): Session | null {\n const row = this.db.prepare('SELECT * FROM sessions WHERE id = ?').get(id) as any;\n if (!row) return null;\n return {\n id: row.id,\n projectId: row.project_id,\n origin: row.origin,\n url: row.url,\n title: row.title,\n userAgent: row.user_agent,\n connectedAt: row.connected_at,\n lastSeenAt: row.last_seen_at,\n active: row.active === 1,\n };\n }\n\n public listSessions(projectId?: string, activeOnly = false): Session[] {\n let sql = 'SELECT * FROM sessions WHERE 1=1';\n const params: any[] = [];\n\n if (projectId) {\n sql += ' AND project_id = ?';\n params.push(projectId);\n }\n if (activeOnly) {\n sql += ' AND active = 1';\n }\n sql += ' ORDER BY last_seen_at DESC';\n\n const rows = this.db.prepare(sql).all(...params) as any[];\n return rows.map((row) => ({\n id: row.id,\n projectId: row.project_id,\n origin: row.origin,\n url: row.url,\n title: row.title,\n userAgent: row.user_agent,\n connectedAt: row.connected_at,\n lastSeenAt: row.last_seen_at,\n active: row.active === 1,\n }));\n }\n\n public deactivateSession(id: string): void {\n this.db.prepare('UPDATE sessions SET active = 0, last_seen_at = ? WHERE id = ?').run(new Date().toISOString(), id);\n }\n\n // --- EVENTS & RETENTION ---\n public insertEvent(event: {\n id: string;\n sessionId: string;\n eventType: string;\n payload: any;\n timestamp: number;\n route?: string;\n url?: string;\n }): void {\n this.db\n .prepare('INSERT INTO events (id, session_id, event_type, payload, timestamp, route, url) VALUES (?, ?, ?, ?, ?, ?, ?)')\n .run(\n event.id,\n event.sessionId,\n event.eventType,\n JSON.stringify(event.payload),\n event.timestamp,\n event.route || '',\n event.url || ''\n );\n }\n\n public pruneSessionEvents(sessionId: string, maxEvents = 1000): void {\n this.db\n .prepare(\n `DELETE FROM events \n WHERE session_id = ? AND id NOT IN (\n SELECT id FROM events WHERE session_id = ? ORDER BY timestamp DESC LIMIT ?\n )`\n )\n .run(sessionId, sessionId, maxEvents);\n }\n\n public getEvents(options: { sessionId?: string; eventType?: string; limit?: number }): any[] {\n let sql = 'SELECT * FROM events WHERE 1=1';\n const params: any[] = [];\n\n if (options.sessionId) {\n sql += ' AND session_id = ?';\n params.push(options.sessionId);\n }\n if (options.eventType) {\n sql += ' AND event_type = ?';\n params.push(options.eventType);\n }\n\n sql += ' ORDER BY timestamp DESC LIMIT ?';\n params.push(options.limit || 50);\n\n const rows = this.db.prepare(sql).all(...params) as any[];\n return rows.map((r) => ({\n id: r.id,\n sessionId: r.session_id,\n eventType: r.event_type,\n payload: JSON.parse(r.payload),\n timestamp: r.timestamp,\n route: r.route,\n url: r.url,\n }));\n }\n\n // --- INCIDENTS ---\n public findIncidentByFingerprint(fingerprint: string): Incident | null {\n const row = this.db.prepare('SELECT * FROM incidents WHERE fingerprint = ?').get(fingerprint) as any;\n if (!row) return null;\n return this.mapIncidentRow(row);\n }\n\n public getIncident(id: string): Incident | null {\n const row = this.db.prepare('SELECT * FROM incidents WHERE id = ?').get(id) as any;\n if (!row) return null;\n return this.mapIncidentRow(row);\n }\n\n public listIncidents(options: { projectId?: string; status?: IncidentStatus; severity?: IncidentSeverity; limit?: number } = {}): Incident[] {\n let sql = 'SELECT * FROM incidents WHERE 1=1';\n const params: any[] = [];\n\n if (options.projectId) {\n sql += ' AND project_id = ?';\n params.push(options.projectId);\n }\n if (options.status) {\n sql += ' AND status = ?';\n params.push(options.status);\n }\n if (options.severity) {\n sql += ' AND severity = ?';\n params.push(options.severity);\n }\n\n sql += ' ORDER BY last_seen DESC LIMIT ?';\n params.push(options.limit || 50);\n\n const rows = this.db.prepare(sql).all(...params) as any[];\n return rows.map((r) => this.mapIncidentRow(r));\n }\n\n public insertIncident(incident: Incident): void {\n this.db\n .prepare(\n `INSERT INTO incidents (\n id, project_id, session_id, type, severity, message, source_file, source_line, source_col,\n fingerprint, route, first_seen, last_seen, occurrences, status, stack, breadcrumbs,\n network_failures, last_element, screenshot_path\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`\n )\n .run(\n incident.id,\n incident.projectId,\n incident.sessionId,\n incident.type,\n incident.severity,\n incident.message,\n incident.source.file,\n incident.source.line,\n incident.source.column || null,\n incident.fingerprint,\n incident.route,\n incident.firstSeen,\n incident.lastSeen,\n incident.occurrences,\n incident.status,\n incident.stack || null,\n JSON.stringify(incident.breadcrumbs || []),\n JSON.stringify(incident.networkFailures || []),\n incident.lastElement ? JSON.stringify(incident.lastElement) : null,\n incident.screenshots?.error || null\n );\n }\n\n public updateIncidentOccurrence(\n incidentId: string,\n update: {\n sessionId: string;\n lastSeen: string;\n occurrences: number;\n route: string;\n breadcrumbs: Breadcrumb[];\n lastElement?: ElementSummary;\n stack?: string;\n }\n ): void {\n this.db\n .prepare(\n `UPDATE incidents \n SET session_id = ?, last_seen = ?, occurrences = ?, route = ?, breadcrumbs = ?, last_element = COALESCE(?, last_element), stack = COALESCE(?, stack)\n WHERE id = ?`\n )\n .run(\n update.sessionId,\n update.lastSeen,\n update.occurrences,\n update.route,\n JSON.stringify(update.breadcrumbs || []),\n update.lastElement ? JSON.stringify(update.lastElement) : null,\n update.stack || null,\n incidentId\n );\n }\n\n public updateIncidentStatus(id: string, status: IncidentStatus): void {\n this.db.prepare('UPDATE incidents SET status = ? WHERE id = ?').run(status, id);\n }\n\n public insertIncidentOccurrence(occurrence: IncidentOccurrence): void {\n this.db\n .prepare(\n `INSERT INTO incident_occurrences (id, incident_id, session_id, timestamp, route, url, stack, breadcrumbs, last_element)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`\n )\n .run(\n occurrence.id,\n occurrence.incidentId,\n occurrence.sessionId,\n occurrence.timestamp,\n occurrence.route,\n occurrence.url,\n occurrence.stack || null,\n JSON.stringify(occurrence.breadcrumbs || []),\n occurrence.lastElement ? JSON.stringify(occurrence.lastElement) : null\n );\n }\n\n // --- VERIFICATIONS ---\n public insertVerification(v: {\n id: string;\n incidentId: string;\n status: IncidentStatus;\n checks: any[];\n beforeScreenshot?: string;\n afterScreenshot?: string;\n message?: string;\n createdAt: string;\n }): void {\n this.db\n .prepare(\n `INSERT INTO verifications (id, incident_id, status, checks, before_screenshot, after_screenshot, message, created_at)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?)`\n )\n .run(\n v.id,\n v.incidentId,\n v.status,\n JSON.stringify(v.checks),\n v.beforeScreenshot || null,\n v.afterScreenshot || null,\n v.message || null,\n v.createdAt\n );\n }\n\n public getLatestVerification(incidentId: string): VerificationResult | null {\n const row = this.db.prepare('SELECT * FROM verifications WHERE incident_id = ? ORDER BY created_at DESC LIMIT 1').get(incidentId) as any;\n if (!row) return null;\n return {\n incidentId: row.incident_id,\n status: row.status as IncidentStatus,\n checks: JSON.parse(row.checks || '[]'),\n screenshots: {\n before: row.before_screenshot || undefined,\n after: row.after_screenshot || undefined,\n },\n timestamp: row.created_at,\n message: row.message || undefined,\n };\n }\n\n // --- VISUAL NOTES ---\n public insertNote(note: VisualNote): void {\n this.db\n .prepare(\n `INSERT INTO notes (\n id, project_id, session_id, type, message, route, url,\n viewport_json, scroll_json, target_json, element_context_json, region_json,\n screenshot_path, incident_id, status, created_at, updated_at, resolved_at\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`\n )\n .run(\n note.id,\n note.projectId,\n note.sessionId,\n note.type,\n note.message,\n note.route,\n note.url,\n JSON.stringify(note.viewport),\n JSON.stringify(note.scroll),\n note.target ? JSON.stringify(note.target) : null,\n note.elementContext ? JSON.stringify(note.elementContext) : null,\n note.region ? JSON.stringify(note.region) : null,\n note.screenshots?.original || null,\n note.incidentId || null,\n note.status,\n note.createdAt,\n note.updatedAt,\n note.resolvedAt || null\n );\n }\n\n public getNote(id: string): VisualNote | null {\n const row = this.db.prepare('SELECT * FROM notes WHERE id = ?').get(id) as any;\n if (!row) return null;\n return this.mapNoteRow(row);\n }\n\n public listNotes(options: { projectId?: string; status?: NoteStatus; route?: string; limit?: number } = {}): VisualNote[] {\n let sql = 'SELECT * FROM notes WHERE 1=1';\n const params: any[] = [];\n\n if (options.projectId) {\n sql += ' AND project_id = ?';\n params.push(options.projectId);\n }\n if (options.status) {\n sql += ' AND status = ?';\n params.push(options.status);\n }\n if (options.route) {\n sql += ' AND route = ?';\n params.push(options.route);\n }\n\n sql += ' ORDER BY created_at DESC LIMIT ?';\n params.push(options.limit || 50);\n\n const rows = this.db.prepare(sql).all(...params) as any[];\n return rows.map((r) => this.mapNoteRow(r));\n }\n\n public deleteNote(id: string): void {\n this.db.prepare('DELETE FROM note_verifications WHERE note_id = ?').run(id);\n this.db.prepare('DELETE FROM notes WHERE id = ?').run(id);\n }\n\n public updateNoteStatus(id: string, status: NoteStatus): void {\n const now = new Date().toISOString();\n const resolvedAt = status === 'RESOLVED' ? now : null;\n this.db\n .prepare('UPDATE notes SET status = ?, updated_at = ?, resolved_at = COALESCE(?, resolved_at) WHERE id = ?')\n .run(status, now, resolvedAt, id);\n }\n\n public updateNote(id: string, updates: Partial<VisualNote>): void {\n const now = new Date().toISOString();\n const current = this.getNote(id);\n if (!current) return;\n\n this.db\n .prepare(\n `UPDATE notes \n SET message = COALESCE(?, message), status = COALESCE(?, status),\n screenshot_path = COALESCE(?, screenshot_path), updated_at = ?\n WHERE id = ?`\n )\n .run(\n updates.message || null,\n updates.status || null,\n updates.screenshots?.original || updates.screenshots?.after || null,\n now,\n id\n );\n }\n\n public insertNoteVerification(v: NoteVerificationResult): void {\n this.db\n .prepare(\n `INSERT INTO note_verifications (\n id, note_id, status, checks, geometry_diff, before_screenshot, after_screenshot, message, created_at\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`\n )\n .run(\n `nver_${Date.now()}_${Math.random().toString(36).slice(2, 6)}`,\n v.noteId,\n v.status,\n JSON.stringify(v.checks),\n v.geometryDiff ? JSON.stringify(v.geometryDiff) : null,\n v.screenshots?.before || null,\n v.screenshots?.after || null,\n v.message || null,\n v.timestamp\n );\n }\n\n public getLatestNoteVerification(noteId: string): NoteVerificationResult | null {\n const row = this.db.prepare('SELECT * FROM note_verifications WHERE note_id = ? ORDER BY created_at DESC LIMIT 1').get(noteId) as any;\n if (!row) return null;\n return {\n noteId: row.note_id,\n status: row.status as NoteStatus,\n checks: JSON.parse(row.checks || '[]'),\n geometryDiff: row.geometry_diff ? JSON.parse(row.geometry_diff) : undefined,\n screenshots: {\n before: row.before_screenshot || undefined,\n after: row.after_screenshot || undefined,\n },\n timestamp: row.created_at,\n message: row.message || undefined,\n };\n }\n\n public clearAll(): void {\n this.db.exec(`\n DELETE FROM events;\n DELETE FROM incident_occurrences;\n DELETE FROM incidents;\n DELETE FROM screenshots;\n DELETE FROM verifications;\n DELETE FROM notes;\n DELETE FROM note_verifications;\n DELETE FROM sessions;\n `);\n }\n\n private mapIncidentRow(row: any): Incident {\n return {\n id: row.id,\n projectId: row.project_id,\n sessionId: row.session_id,\n type: row.type,\n severity: row.severity as IncidentSeverity,\n message: row.message,\n source: {\n file: row.source_file,\n line: row.source_line,\n column: row.source_col || undefined,\n },\n fingerprint: row.fingerprint,\n route: row.route,\n firstSeen: row.first_seen,\n lastSeen: row.last_seen,\n occurrences: row.occurrences,\n status: row.status as IncidentStatus,\n stack: row.stack || undefined,\n breadcrumbs: JSON.parse(row.breadcrumbs || '[]'),\n networkFailures: JSON.parse(row.network_failures || '[]'),\n lastElement: row.last_element ? JSON.parse(row.last_element) : undefined,\n screenshots: row.screenshot_path\n ? {\n error: row.screenshot_path,\n }\n : undefined,\n };\n }\n\n private mapNoteRow(row: any): VisualNote {\n return {\n id: row.id,\n projectId: row.project_id,\n sessionId: row.session_id,\n type: row.type,\n message: row.message,\n route: row.route,\n url: row.url,\n viewport: JSON.parse(row.viewport_json || '{}'),\n scroll: JSON.parse(row.scroll_json || '{}'),\n target: row.target_json ? JSON.parse(row.target_json) : undefined,\n elementContext: row.element_context_json ? JSON.parse(row.element_context_json) : undefined,\n region: row.region_json ? JSON.parse(row.region_json) : undefined,\n status: row.status as NoteStatus,\n incidentId: row.incident_id || undefined,\n screenshots: row.screenshot_path\n ? {\n original: row.screenshot_path,\n }\n : undefined,\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n resolvedAt: row.resolved_at || undefined,\n };\n }\n\n public close(): void {\n this.db.close();\n }\n}\n","import fs from 'node:fs';\nimport path from 'node:path';\n\nexport class ScreenshotStore {\n private baseDir: string;\n\n constructor(baseDir: string) {\n this.baseDir = baseDir;\n fs.mkdirSync(this.baseDir, { recursive: true });\n }\n\n public saveScreenshot(projectId: string, incidentId: string, name: string, dataUrl: string): { filePath: string; format: string } | null {\n try {\n if (!dataUrl || !dataUrl.startsWith('data:image/')) return null;\n\n const match = dataUrl.match(/^data:image\\/([a-zA-Z0-9+]+);base64,(.+)$/);\n if (!match) return null;\n\n let format = match[1].toLowerCase();\n if (format === 'jpeg') format = 'jpg';\n const base64Data = match[2];\n const buffer = Buffer.from(base64Data, 'base64');\n\n const targetDir = path.join(this.baseDir, projectId || 'default', 'incidents', incidentId);\n fs.mkdirSync(targetDir, { recursive: true });\n\n const fileName = `${name}.${format}`;\n const filePath = path.join(targetDir, fileName);\n\n fs.writeFileSync(filePath, buffer);\n\n return { filePath, format };\n } catch {\n return null;\n }\n }\n\n public getScreenshotPath(projectId: string, incidentId: string, name: string): string | null {\n const targetDir = path.join(this.baseDir, projectId || 'default', 'incidents', incidentId);\n if (!fs.existsSync(targetDir)) return null;\n\n const files = fs.readdirSync(targetDir);\n const match = files.find((f) => f.startsWith(`${name}.`));\n if (match) {\n return path.join(targetDir, match);\n }\n return null;\n }\n}\n","import type { WebSocket } from 'ws';\nimport type { ClientCommand, CommandResponse, Session } from '../../../core/src/index.js';\nimport type { StorageDB } from '../storage/db.js';\n\ninterface ActiveSessionSocket {\n sessionId: string;\n ws: WebSocket;\n origin: string;\n projectId: string;\n pendingCommands: Map<\n string,\n {\n resolve: (res: CommandResponse) => void;\n reject: (err: Error) => void;\n timer: any;\n }\n >;\n}\n\nexport class SessionManager {\n private activeSockets: Map<string, ActiveSessionSocket> = new Map();\n private db: StorageDB;\n\n constructor(db: StorageDB) {\n this.db = db;\n }\n\n public registerSocket(sessionId: string, ws: WebSocket, origin: string, projectId: string): void {\n this.activeSockets.set(sessionId, {\n sessionId,\n ws,\n origin,\n projectId,\n pendingCommands: new Map(),\n });\n }\n\n public unregisterSocket(sessionId: string): void {\n const active = this.activeSockets.get(sessionId);\n if (active) {\n for (const pending of active.pendingCommands.values()) {\n clearTimeout(pending.timer);\n pending.reject(new Error('Session disconnected before command completed'));\n }\n active.pendingCommands.clear();\n this.activeSockets.delete(sessionId);\n this.db.deactivateSession(sessionId);\n }\n }\n\n public handleCommandResponse(sessionId: string, response: CommandResponse): void {\n const active = this.activeSockets.get(sessionId);\n if (!active) return;\n\n const pending = active.pendingCommands.get(response.id);\n if (pending) {\n clearTimeout(pending.timer);\n active.pendingCommands.delete(response.id);\n pending.resolve(response);\n }\n }\n\n public async sendCommand<T = any>(sessionId: string, command: ClientCommand<T>, timeoutMs = 5000): Promise<CommandResponse> {\n const active = this.activeSockets.get(sessionId);\n if (!active || active.ws.readyState !== 1 /* WebSocket.OPEN */) {\n return {\n id: command.id,\n ok: false,\n error: `Session ${sessionId} is not actively connected`,\n };\n }\n\n return new Promise<CommandResponse>((resolve, reject) => {\n const timer = setTimeout(() => {\n active.pendingCommands.delete(command.id);\n resolve({\n id: command.id,\n ok: false,\n error: `Command ${command.type} timed out after ${timeoutMs}ms`,\n });\n }, timeoutMs);\n\n active.pendingCommands.set(command.id, {\n resolve,\n reject,\n timer,\n });\n\n try {\n active.ws.send(\n JSON.stringify({\n type: 'command',\n command,\n })\n );\n } catch (err: any) {\n clearTimeout(timer);\n active.pendingCommands.delete(command.id);\n resolve({\n id: command.id,\n ok: false,\n error: err?.message || 'Failed to send command over WebSocket',\n });\n }\n });\n }\n\n public getActiveSessionForProject(projectId: string): Session | null {\n for (const active of this.activeSockets.values()) {\n if (active.projectId === projectId) {\n return this.db.getSession(active.sessionId);\n }\n }\n return null;\n }\n\n public getAnyActiveSession(): Session | null {\n const first = this.activeSockets.keys().next().value;\n if (!first) return null;\n return this.db.getSession(first);\n }\n\n public getActiveCount(): number {\n return this.activeSockets.size;\n }\n\n public broadcastToProject(projectId: string, message: any): void {\n const raw = typeof message === 'string' ? message : JSON.stringify(message);\n for (const active of this.activeSockets.values()) {\n if (active.projectId === projectId && active.ws.readyState === 1 /* OPEN */) {\n try {\n active.ws.send(raw);\n } catch {}\n }\n }\n }\n\n public sendToSession(sessionId: string, message: any): void {\n const active = this.activeSockets.get(sessionId);\n if (active && active.ws.readyState === 1) {\n try {\n const raw = typeof message === 'string' ? message : JSON.stringify(message);\n active.ws.send(raw);\n } catch {}\n }\n }\n}\n","import crypto from 'node:crypto';\nimport path from 'node:path';\nimport fs from 'node:fs';\nimport type { VisualNote } from '../../../core/src/index.js';\nimport type { StorageDB } from '../storage/db.js';\nimport type { ScreenshotStore } from '../storage/screenshot-store.js';\n\nexport class NotesEngine {\n private db: StorageDB;\n private screenshotStore: ScreenshotStore;\n\n constructor(db: StorageDB, screenshotStore: ScreenshotStore) {\n this.db = db;\n this.screenshotStore = screenshotStore;\n }\n\n public createNoteFromClient(payload: {\n sessionId: string;\n noteType?: 'element' | 'region' | 'page';\n message: string;\n route?: string;\n url?: string;\n viewport?: { width: number; height: number; devicePixelRatio: number };\n scroll?: { scrollX: number; scrollY: number };\n target?: any;\n elementContext?: any;\n region?: any;\n screenshot?: string;\n incidentId?: string;\n }): VisualNote {\n const session = this.db.getSession(payload.sessionId);\n const projectId = session?.projectId || 'default';\n const noteId = `note_${crypto.randomUUID().slice(0, 8)}`;\n const now = new Date().toISOString();\n\n let screenshotPath: string | undefined;\n if (payload.screenshot) {\n const saved = this.saveNoteScreenshot(projectId, noteId, 'original', payload.screenshot);\n if (saved) {\n screenshotPath = saved;\n }\n }\n\n const note: VisualNote = {\n id: noteId,\n projectId,\n sessionId: payload.sessionId,\n type: payload.noteType || 'element',\n message: payload.message,\n route: payload.route || '/',\n url: payload.url || '',\n viewport: payload.viewport || { width: 1280, height: 800, devicePixelRatio: 1 },\n scroll: payload.scroll || { scrollX: 0, scrollY: 0 },\n target: payload.target,\n elementContext: payload.elementContext,\n region: payload.region,\n status: 'OPEN',\n incidentId: payload.incidentId,\n screenshots: screenshotPath ? { original: screenshotPath } : undefined,\n createdAt: now,\n updatedAt: now,\n };\n\n this.db.insertNote(note);\n return note;\n }\n\n public saveNoteScreenshot(projectId: string, noteId: string, name: string, dataUrl: string): string | null {\n try {\n if (!dataUrl || !dataUrl.startsWith('data:image/')) return null;\n\n const match = dataUrl.match(/^data:image\\/([a-zA-Z0-9+]+);base64,(.+)$/);\n if (!match) return null;\n\n let format = match[1].toLowerCase();\n if (format === 'jpeg') format = 'jpg';\n const base64Data = match[2];\n const buffer = Buffer.from(base64Data, 'base64');\n\n const targetDir = path.join((this.screenshotStore as any).baseDir, projectId || 'default', 'notes', noteId);\n fs.mkdirSync(targetDir, { recursive: true });\n\n const fileName = `${name}.${format}`;\n const filePath = path.join(targetDir, fileName);\n\n fs.writeFileSync(filePath, buffer);\n return filePath;\n } catch {\n return null;\n }\n }\n}\n","import crypto from 'node:crypto';\nimport type { DOMRectJson, NoteStatus, NoteVerificationResult, OverflowCheckResult, VisualNote } from '../../../core/src/index.js';\nimport type { NotesEngine } from './engine.js';\nimport type { SessionManager } from '../session/manager.js';\nimport type { StorageDB } from '../storage/db.js';\n\nexport class NoteVerificationEngine {\n private db: StorageDB;\n private sessionManager: SessionManager;\n private notesEngine: NotesEngine;\n\n constructor(db: StorageDB, sessionManager: SessionManager, notesEngine: NotesEngine) {\n this.db = db;\n this.sessionManager = sessionManager;\n this.notesEngine = notesEngine;\n }\n\n public async verifyNote(noteId: string, options: { observationWindowMs?: number } = {}): Promise<NoteVerificationResult> {\n const note = this.db.getNote(noteId);\n if (!note) {\n return {\n noteId,\n status: 'FAILED',\n checks: [{ type: 'note_exists', passed: false, details: `Note ${noteId} not found` }],\n timestamp: new Date().toISOString(),\n message: `Note ${noteId} not found in database`,\n };\n }\n\n // 1. Find active session\n let session = this.sessionManager.getActiveSessionForProject(note.projectId);\n if (!session) {\n session = this.sessionManager.getAnyActiveSession();\n }\n\n if (!session) {\n const result: NoteVerificationResult = {\n noteId,\n status: 'INCONCLUSIVE',\n checks: [],\n timestamp: new Date().toISOString(),\n message: 'No active browser session currently connected to verify visual note.',\n };\n this.recordNoteVerification(result, note);\n return result;\n }\n\n // 2. Set status to VERIFYING\n this.db.updateNoteStatus(noteId, 'VERIFYING');\n\n // 3. Navigation check / route sync\n const pageStateCmd = await this.sessionManager.sendCommand(session.id, {\n id: `cmd_${crypto.randomUUID().slice(0, 8)}`,\n type: 'get_page_state',\n });\n\n const currentRoute = pageStateCmd.result?.route || '/';\n const isRouteMatch = currentRoute === note.route || currentRoute.startsWith(note.route);\n\n if (!isRouteMatch && note.route) {\n await this.sessionManager.sendCommand(session.id, {\n id: `cmd_${crypto.randomUUID().slice(0, 8)}`,\n type: 'navigate',\n params: { url: note.route },\n });\n // Wait for navigation observation window\n await new Promise((r) => setTimeout(r, options.observationWindowMs || 1000));\n }\n\n const checks: Array<{ type: string; passed: boolean; details?: string }> = [];\n\n checks.push({\n type: 'route_loaded',\n passed: true,\n details: `Route ${note.route || '/'} loaded`,\n });\n\n // 4. Target element checks\n const targetSelector = note.target?.selector || (note.type === 'page' ? 'body' : 'body');\n let elementExists = true;\n let elementVisible = true;\n let currentRect: DOMRectJson | undefined;\n let overflowResult: OverflowCheckResult | undefined;\n\n if (note.type === 'element' && targetSelector) {\n const queryCmd = await this.sessionManager.sendCommand(session.id, {\n id: `cmd_${crypto.randomUUID().slice(0, 8)}`,\n type: 'query_element',\n params: { selector: targetSelector },\n });\n\n elementExists = queryCmd.ok && !!queryCmd.result?.exists;\n elementVisible = queryCmd.ok && !!queryCmd.result?.visible;\n currentRect = queryCmd.result?.boundingRect;\n\n checks.push({\n type: 'element_exists',\n passed: elementExists,\n details: elementExists ? `Element ${targetSelector} exists in DOM` : `Element ${targetSelector} not found`,\n });\n\n checks.push({\n type: 'element_visible',\n passed: elementVisible,\n details: elementVisible ? `Element ${targetSelector} is visible` : `Element ${targetSelector} is hidden`,\n });\n\n // 5. Layout Overflow Probe\n const overflowCmd = await this.sessionManager.sendCommand(session.id, {\n id: `cmd_${crypto.randomUUID().slice(0, 8)}`,\n type: 'check_overflow',\n params: { selector: targetSelector },\n });\n\n if (overflowCmd.ok && overflowCmd.result) {\n const ovf = overflowCmd.result as OverflowCheckResult;\n overflowResult = ovf;\n const isOverflowingNow = !!ovf.overflow;\n\n checks.push({\n type: 'no_viewport_overflow',\n passed: !isOverflowingNow,\n details: !isOverflowingNow\n ? `Element fits within viewport (width: ${ovf.viewportWidth}px, rect right: ${ovf.rect?.right}px)`\n : `Element overflows viewport by ${ovf.overflowRightPx}px (rect right: ${ovf.rect?.right}px, viewport: ${ovf.viewportWidth}px)`,\n });\n }\n }\n\n // 6. Capture \"after\" screenshot\n let afterScreenshotPath: string | undefined;\n const captureCmd = await this.sessionManager.sendCommand(session.id, {\n id: `cmd_${crypto.randomUUID().slice(0, 8)}`,\n type: 'capture_element',\n params: { selector: targetSelector },\n });\n\n if (captureCmd.ok && captureCmd.result?.dataUrl) {\n const saved = this.notesEngine.saveNoteScreenshot(note.projectId, note.id, 'after', captureCmd.result.dataUrl);\n if (saved) {\n afterScreenshotPath = saved;\n }\n }\n\n // 7. Calculate Geometry Difference\n const beforeRect = note.target?.boundingRect;\n const overflowFixed = overflowResult ? !overflowResult.overflow : undefined;\n\n const geometryDiff = {\n before: beforeRect,\n current: currentRect || (overflowResult?.rect as DOMRectJson),\n viewportWidth: overflowResult?.viewportWidth || note.viewport.width,\n overflowFixed,\n overflowPx: overflowResult?.overflowRightPx || 0,\n };\n\n // 8. Verdict\n const anyFailed = checks.some((c) => !c.passed);\n let status: NoteStatus = 'VERIFIED';\n\n if (anyFailed) {\n status = 'FAILED';\n } else {\n status = 'VERIFIED';\n }\n\n const verificationResult: NoteVerificationResult = {\n noteId,\n status,\n checks,\n geometryDiff,\n screenshots: {\n before: note.screenshots?.original,\n after: afterScreenshotPath,\n },\n timestamp: new Date().toISOString(),\n message:\n status === 'VERIFIED'\n ? 'Visual note verified: target element is present, visible, and layout checks (including viewport overflow) passed.'\n : 'Visual note verification failed: target element missing, hidden, or still overflowing.',\n };\n\n this.recordNoteVerification(verificationResult, note);\n return verificationResult;\n }\n\n private recordNoteVerification(result: NoteVerificationResult, note: VisualNote): void {\n this.db.updateNoteStatus(note.id, result.status);\n this.db.insertNoteVerification(result);\n }\n}\n","import crypto from 'node:crypto';\nimport type {\n Incident,\n IncidentStatus,\n ProbeResult,\n VerificationProbe,\n VerificationRecipe,\n VerificationResult,\n} from '../../../core/src/index.js';\nimport type { SessionManager } from '../session/manager.js';\nimport type { StorageDB } from '../storage/db.js';\nimport type { ScreenshotStore } from '../storage/screenshot-store.js';\n\nexport class VerificationEngine {\n private db: StorageDB;\n private sessionManager: SessionManager;\n private screenshotStore: ScreenshotStore;\n\n constructor(db: StorageDB, sessionManager: SessionManager, screenshotStore: ScreenshotStore) {\n this.db = db;\n this.sessionManager = sessionManager;\n this.screenshotStore = screenshotStore;\n }\n\n public async verifyIncident(incidentId: string, recipe?: VerificationRecipe): Promise<VerificationResult> {\n const incident = this.db.getIncident(incidentId);\n if (!incident) {\n return {\n incidentId,\n status: 'FAILED',\n checks: [{ type: 'no_incident', passed: false, details: `Incident ${incidentId} not found` }],\n timestamp: new Date().toISOString(),\n message: `Incident ${incidentId} not found in database`,\n };\n }\n\n // 1. Find active session\n let session = this.sessionManager.getActiveSessionForProject(incident.projectId);\n if (!session) {\n session = this.sessionManager.getAnyActiveSession();\n }\n\n if (!session) {\n const result: VerificationResult = {\n incidentId,\n status: 'INCONCLUSIVE',\n checks: [],\n timestamp: new Date().toISOString(),\n message: 'No active browser session currently connected to verify the fix.',\n };\n this.recordVerification(result, incident);\n return result;\n }\n\n // 2. Set status to VERIFYING and record baseline\n this.db.updateIncidentStatus(incidentId, 'VERIFYING');\n const baselineOccurrences = incident.occurrences;\n\n // 3. Initiate browser reload or navigation\n const targetRoute = recipe?.route || incident.route;\n const observationMs = recipe?.observationWindowMs || 2000;\n\n if (recipe?.route && recipe.route !== incident.route) {\n await this.sessionManager.sendCommand(session.id, {\n id: `cmd_${crypto.randomUUID().slice(0, 8)}`,\n type: 'navigate',\n params: { url: recipe.route },\n });\n } else {\n await this.sessionManager.sendCommand(session.id, {\n id: `cmd_${crypto.randomUUID().slice(0, 8)}`,\n type: 'reload',\n params: { force: true },\n });\n }\n\n // 4. Observation window\n await new Promise((resolve) => setTimeout(resolve, observationMs));\n\n // 5. Check if incident re-occurred\n const freshIncident = this.db.getIncident(incidentId);\n const hasReoccurred = freshIncident ? freshIncident.occurrences > baselineOccurrences : false;\n\n const checks: ProbeResult[] = [];\n checks.push({\n type: 'no_incident',\n passed: !hasReoccurred,\n details: hasReoccurred\n ? `Incident reoccurred (${freshIncident?.occurrences} occurrences vs baseline ${baselineOccurrences})`\n : 'No recurring error observed during verification window',\n });\n\n // 6. Run additional probes\n const probes = recipe?.expect || [];\n for (const probe of probes) {\n const probeRes = await this.evaluateProbe(session.id, probe);\n checks.push(probeRes);\n }\n\n // 7. Check target element or last element for after-screenshot\n let afterScreenshotPath: string | undefined;\n const targetSelector = recipe?.targetSelector || incident.lastElement?.selector;\n\n if (targetSelector) {\n const captureCmd = await this.sessionManager.sendCommand(session.id, {\n id: `cmd_${crypto.randomUUID().slice(0, 8)}`,\n type: 'capture_element',\n params: { selector: targetSelector },\n });\n\n if (captureCmd.ok && captureCmd.result?.dataUrl) {\n const saved = this.screenshotStore.saveScreenshot(\n incident.projectId,\n incident.id,\n 'verified',\n captureCmd.result.dataUrl\n );\n if (saved) {\n afterScreenshotPath = saved.filePath;\n }\n }\n }\n\n // 8. Calculate verdict\n let verdict: IncidentStatus = 'VERIFIED';\n const anyCheckFailed = checks.some((c) => !c.passed);\n\n if (anyCheckFailed || hasReoccurred) {\n verdict = 'FAILED';\n } else {\n // Check if incident required an explicit interaction (like button click) that wasn't covered by probes\n const wasInteractionError = incident.breadcrumbs.some((b) => b.type === 'click' || b.type === 'submit');\n if (wasInteractionError && probes.length === 0) {\n verdict = 'INCONCLUSIVE';\n }\n }\n\n const verificationResult: VerificationResult = {\n incidentId,\n status: verdict,\n checks,\n screenshots: {\n before: incident.screenshots?.error,\n after: afterScreenshotPath,\n },\n timestamp: new Date().toISOString(),\n message:\n verdict === 'VERIFIED'\n ? 'Fix verified: Error did not reoccur and all checks passed.'\n : verdict === 'FAILED'\n ? 'Verification failed: Error reoccurred or probe expectation was not met.'\n : 'Verification inconclusive: Error did not appear on reload, but specific interaction may need manual verification or custom probes.',\n };\n\n this.recordVerification(verificationResult, incident);\n return verificationResult;\n }\n\n private async evaluateProbe(sessionId: string, probe: VerificationProbe): Promise<ProbeResult> {\n try {\n switch (probe.type) {\n case 'element_exists': {\n if (!probe.selector) {\n return { type: probe.type, passed: false, details: 'Missing selector in probe' };\n }\n const res = await this.sessionManager.sendCommand(sessionId, {\n id: `cmd_${crypto.randomUUID().slice(0, 8)}`,\n type: 'query_element',\n params: { selector: probe.selector },\n });\n const exists = res.ok && !!res.result?.exists;\n return {\n type: probe.type,\n passed: exists,\n details: exists ? `Element ${probe.selector} exists in DOM` : `Element ${probe.selector} does not exist`,\n };\n }\n\n case 'element_visible': {\n if (!probe.selector) {\n return { type: probe.type, passed: false, details: 'Missing selector in probe' };\n }\n const res = await this.sessionManager.sendCommand(sessionId, {\n id: `cmd_${crypto.randomUUID().slice(0, 8)}`,\n type: 'query_element',\n params: { selector: probe.selector },\n });\n const visible = res.ok && !!res.result?.exists && !!res.result?.visible;\n return {\n type: probe.type,\n passed: visible,\n details: visible ? `Element ${probe.selector} is visible` : `Element ${probe.selector} is not visible`,\n };\n }\n\n case 'text_contains': {\n if (!probe.selector || !probe.text) {\n return { type: probe.type, passed: false, details: 'Missing selector or text in probe' };\n }\n const res = await this.sessionManager.sendCommand(sessionId, {\n id: `cmd_${crypto.randomUUID().slice(0, 8)}`,\n type: 'query_element',\n params: { selector: probe.selector },\n });\n const innerText = res.result?.innerText || '';\n const contains = res.ok && innerText.includes(probe.text);\n return {\n type: probe.type,\n passed: contains,\n details: contains\n ? `Element ${probe.selector} contains text \"${probe.text}\"`\n : `Element text \"${innerText}\" did not contain \"${probe.text}\"`,\n };\n }\n\n case 'route_is': {\n if (!probe.route) {\n return { type: probe.type, passed: false, details: 'Missing route in probe' };\n }\n const res = await this.sessionManager.sendCommand(sessionId, {\n id: `cmd_${crypto.randomUUID().slice(0, 8)}`,\n type: 'get_page_state',\n });\n const currentRoute = res.result?.route || '';\n const matches = res.ok && (currentRoute === probe.route || currentRoute.startsWith(probe.route));\n return {\n type: probe.type,\n passed: matches,\n details: matches\n ? `Current route matches ${probe.route}`\n : `Current route is \"${currentRoute}\", expected \"${probe.route}\"`,\n };\n }\n\n default:\n return {\n type: probe.type,\n passed: true,\n details: `Probe ${probe.type} evaluated`,\n };\n }\n } catch (err: any) {\n return {\n type: probe.type,\n passed: false,\n details: err?.message || 'Probe execution error',\n };\n }\n }\n\n private recordVerification(result: VerificationResult, incident: Incident): void {\n this.db.updateIncidentStatus(incident.id, result.status);\n this.db.insertVerification({\n id: `ver_${crypto.randomUUID().slice(0, 8)}`,\n incidentId: incident.id,\n status: result.status,\n checks: result.checks,\n beforeScreenshot: result.screenshots?.before,\n afterScreenshot: result.screenshots?.after,\n message: result.message,\n createdAt: result.timestamp,\n });\n }\n}\n"],"mappings":"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","names":["path","fs","path","path","fs","crypto","crypto"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../packages/client/src/breadcrumbs.ts","../packages/client/src/interceptors/interaction.ts","../packages/client/src/commands/handler.ts","../packages/client/src/config.ts","../packages/client/src/interceptors/console.ts","../packages/client/src/interceptors/navigation.ts","../packages/client/src/interceptors/network.ts","../packages/client/src/interceptors/runtime.ts","../packages/client/src/screenshot/browser-script-driver.ts","../packages/client/src/transport/websocket.ts","../packages/client/src/notes/inspector.ts","../packages/client/src/client.ts","../packages/client/src/index.ts"],"sourcesContent":["import type { Breadcrumb } from '@browserdiag/core';\n\nexport class BreadcrumbBuffer {\n private capacity: number;\n private buffer: Breadcrumb[] = [];\n\n constructor(capacity = 50) {\n this.capacity = capacity;\n }\n\n public add(breadcrumb: Omit<Breadcrumb, 'timestamp'> & { timestamp?: number }): void {\n const item: Breadcrumb = {\n ...breadcrumb,\n timestamp: breadcrumb.timestamp || Date.now(),\n };\n\n this.buffer.push(item);\n if (this.buffer.length > this.capacity) {\n this.buffer.shift();\n }\n }\n\n public getRecent(): Breadcrumb[] {\n return [...this.buffer];\n }\n\n public clear(): void {\n this.buffer = [];\n }\n}\n","import type { Breadcrumb, ElementSummary } from '../../../core/src/index.js';\nimport { getSemanticSelector, truncate } from '../../../core/src/index.js';\n\nexport type InteractionCallback = (breadcrumb: Breadcrumb, elementSummary?: ElementSummary) => void;\n\n/**\n * Extracts a concise ElementSummary from a DOM element.\n * Never collects sensitive user input values.\n */\nexport function extractElementSummary(el: HTMLElement | Element): ElementSummary {\n const selector = getSemanticSelector(el);\n const tag = el.tagName.toLowerCase();\n const id = el.id || undefined;\n const classes = Array.from(el.classList || []);\n\n let boundingRect: ElementSummary['boundingRect'] = undefined;\n let visible = true;\n\n try {\n const rect = el.getBoundingClientRect();\n boundingRect = {\n x: Math.round(rect.x),\n y: Math.round(rect.y),\n width: Math.round(rect.width),\n height: Math.round(rect.height),\n top: Math.round(rect.top),\n left: Math.round(rect.left),\n bottom: Math.round(rect.bottom),\n right: Math.round(rect.right),\n };\n\n const style = window.getComputedStyle(el);\n visible = style.display !== 'none' && style.visibility !== 'hidden' && style.opacity !== '0' && rect.width > 0 && rect.height > 0;\n } catch {\n // Defensive\n }\n\n // Safe innerText (truncate to 80 chars, ignore password/sensitive elements)\n let innerText: string | undefined;\n if (tag !== 'input' && tag !== 'textarea' && tag !== 'select') {\n innerText = truncate(el.textContent?.trim(), 80);\n }\n\n // Safe outerHTML (truncate to 200 chars)\n const outerHTML = truncate(el.outerHTML?.trim(), 200);\n\n return {\n selector,\n tag,\n id,\n classes,\n boundingRect,\n visible,\n innerText,\n outerHTML,\n };\n}\n\n/**\n * Sets up global click and submit event tracking.\n */\nexport function setupInteractionInterceptors(onInteraction: InteractionCallback): () => void {\n if (typeof document === 'undefined') return () => {};\n\n const onClick = (event: MouseEvent) => {\n try {\n const target = event.target as HTMLElement | null;\n if (!target || !(target instanceof Element)) return;\n\n const summary = extractElementSummary(target);\n const message = `click ${summary.selector}${summary.innerText ? ` (\"${summary.innerText}\")` : ''}`;\n\n onInteraction(\n {\n type: 'click',\n category: 'ui',\n message,\n timestamp: Date.now(),\n element: summary,\n },\n summary\n );\n } catch {\n // Defensive\n }\n };\n\n const onSubmit = (event: SubmitEvent) => {\n try {\n const target = event.target as HTMLFormElement | null;\n if (!target || !(target instanceof Element)) return;\n\n const summary = extractElementSummary(target);\n const formAction = target.getAttribute('action') || '';\n const message = `submit form ${summary.selector}${formAction ? ` (action: ${formAction})` : ''}`;\n\n onInteraction(\n {\n type: 'submit',\n category: 'ui',\n message,\n timestamp: Date.now(),\n element: summary,\n },\n summary\n );\n } catch {\n // Defensive\n }\n };\n\n document.addEventListener('click', onClick, { capture: true, passive: true });\n document.addEventListener('submit', onSubmit, { capture: true, passive: true });\n\n return () => {\n document.removeEventListener('click', onClick, { capture: true });\n document.removeEventListener('submit', onSubmit, { capture: true });\n };\n}\n","import type {\n ClientCommand,\n CommandResponse,\n PageStateResult,\n QueryElementResult,\n CaptureElementResult,\n} from '../../../core/src/index.js';\nimport { truncate } from '../../../core/src/index.js';\nimport { extractElementSummary } from '../interceptors/interaction.js';\nimport type { ScreenshotDriver } from '../screenshot/driver.js';\n\nexport class ClientCommandHandler {\n private screenshotDriver: ScreenshotDriver;\n\n constructor(screenshotDriver: ScreenshotDriver) {\n this.screenshotDriver = screenshotDriver;\n }\n\n public async executeCommand(command: ClientCommand): Promise<CommandResponse> {\n try {\n switch (command.type) {\n case 'reload':\n return this.handleReload(command);\n\n case 'navigate':\n return this.handleNavigate(command);\n\n case 'get_page_state':\n return this.handleGetPageState(command);\n\n case 'query_element':\n return this.handleQueryElement(command);\n\n case 'capture_element':\n return await this.handleCaptureElement(command);\n\n case 'check_overflow':\n return this.handleCheckOverflow(command);\n\n case 'get_element_rect':\n return this.handleGetElementRect(command);\n\n case 'get_element_style':\n return this.handleGetElementStyle(command);\n\n default:\n return {\n id: command.id,\n ok: false,\n error: `Unsupported command type: ${(command as any).type}`,\n };\n }\n } catch (err: any) {\n return {\n id: command.id,\n ok: false,\n error: err?.message || 'Command execution failed',\n };\n }\n }\n\n private handleReload(command: ClientCommand): CommandResponse {\n if (typeof window !== 'undefined' && window.location) {\n setTimeout(() => {\n window.location.reload();\n }, 50);\n return { id: command.id, ok: true, result: { message: 'Reload initiated' } };\n }\n return { id: command.id, ok: false, error: 'No browser window available' };\n }\n\n private handleNavigate(command: ClientCommand<{ url: string }>): CommandResponse {\n const targetUrl = command.params?.url;\n if (!targetUrl) {\n return { id: command.id, ok: false, error: 'Missing target url parameter' };\n }\n\n if (typeof window !== 'undefined' && window.location) {\n setTimeout(() => {\n window.location.href = targetUrl;\n }, 50);\n return { id: command.id, ok: true, result: { message: `Navigating to ${targetUrl}` } };\n }\n return { id: command.id, ok: false, error: 'No browser window available' };\n }\n\n private handleGetPageState(command: ClientCommand): CommandResponse<PageStateResult> {\n if (typeof window === 'undefined' || typeof document === 'undefined') {\n return { id: command.id, ok: false, error: 'No browser document available' };\n }\n\n const activeEl = document.activeElement && document.activeElement !== document.body ? extractElementSummary(document.activeElement) : undefined;\n\n return {\n id: command.id,\n ok: true,\n result: {\n url: window.location.href,\n route: window.location.pathname + window.location.search + window.location.hash,\n title: document.title,\n readyState: document.readyState,\n activeElement: activeEl,\n },\n };\n }\n\n private handleQueryElement(command: ClientCommand<{ selector: string }>): CommandResponse<QueryElementResult> {\n if (typeof document === 'undefined') {\n return { id: command.id, ok: false, error: 'No browser document available' };\n }\n\n const selector = command.params?.selector;\n if (!selector) {\n return { id: command.id, ok: false, error: 'Missing selector parameter' };\n }\n\n const element = document.querySelector(selector);\n if (!element) {\n return {\n id: command.id,\n ok: true,\n result: { exists: false },\n };\n }\n\n const summary = extractElementSummary(element);\n\n return {\n id: command.id,\n ok: true,\n result: {\n exists: true,\n visible: summary.visible,\n tag: summary.tag,\n id: summary.id,\n classes: summary.classes,\n boundingRect: summary.boundingRect,\n innerText: summary.innerText,\n outerHTML: summary.outerHTML,\n },\n };\n }\n\n private async handleCaptureElement(command: ClientCommand<{ selector?: string }>): Promise<CommandResponse<CaptureElementResult>> {\n const selector = command.params?.selector;\n let targetEl: Element | null = null;\n\n if (selector) {\n targetEl = document.querySelector(selector);\n if (!targetEl) {\n return {\n id: command.id,\n ok: false,\n reason: `ELEMENT_NOT_FOUND: ${selector}`,\n error: `Element not found for selector: ${selector}`,\n };\n }\n } else {\n targetEl = document.body || document.documentElement;\n }\n\n const captureRes = await this.screenshotDriver.captureElement(targetEl);\n if (!captureRes.ok) {\n return {\n id: command.id,\n ok: false,\n reason: captureRes.reason || 'CAPTURE_FAILED',\n error: captureRes.reason || 'Failed to capture element screenshot',\n };\n }\n\n return {\n id: command.id,\n ok: true,\n result: {\n dataUrl: captureRes.dataUrl,\n format: captureRes.format,\n width: captureRes.width,\n height: captureRes.height,\n },\n };\n }\n\n private handleCheckOverflow(command: ClientCommand<{ selector: string }>): CommandResponse {\n if (typeof window === 'undefined' || typeof document === 'undefined') {\n return { id: command.id, ok: false, error: 'No browser window available' };\n }\n\n const selector = command.params?.selector;\n if (!selector) {\n return { id: command.id, ok: false, error: 'Missing selector parameter' };\n }\n\n const el = document.querySelector(selector);\n if (!el) {\n return { id: command.id, ok: false, error: `Element not found: ${selector}` };\n }\n\n const rect = el.getBoundingClientRect();\n const vw = window.innerWidth;\n const vh = window.innerHeight;\n\n const overflowRightPx = Math.max(0, Math.round(rect.right - vw));\n const overflowBottomPx = Math.max(0, Math.round(rect.bottom - vh));\n const isViewportOverflow = overflowRightPx > 0 || rect.left < 0;\n\n let parentOverflow = false;\n if (el.parentElement) {\n parentOverflow = el.parentElement.scrollWidth > el.parentElement.clientWidth;\n }\n\n return {\n id: command.id,\n ok: true,\n result: {\n selector,\n overflow: isViewportOverflow || parentOverflow,\n viewportWidth: vw,\n viewportHeight: vh,\n rect: {\n x: Math.round(rect.x),\n y: Math.round(rect.y),\n width: Math.round(rect.width),\n height: Math.round(rect.height),\n top: Math.round(rect.top),\n left: Math.round(rect.left),\n bottom: Math.round(rect.bottom),\n right: Math.round(rect.right),\n },\n overflowRightPx,\n overflowBottomPx,\n parentOverflow,\n },\n };\n }\n\n private handleGetElementRect(command: ClientCommand<{ selector: string }>): CommandResponse {\n if (typeof document === 'undefined') {\n return { id: command.id, ok: false, error: 'No browser document available' };\n }\n\n const selector = command.params?.selector;\n if (!selector) {\n return { id: command.id, ok: false, error: 'Missing selector parameter' };\n }\n\n const el = document.querySelector(selector);\n if (!el) {\n return { id: command.id, ok: false, error: `Element not found: ${selector}` };\n }\n\n const rect = el.getBoundingClientRect();\n return {\n id: command.id,\n ok: true,\n result: {\n x: Math.round(rect.x),\n y: Math.round(rect.y),\n width: Math.round(rect.width),\n height: Math.round(rect.height),\n top: Math.round(rect.top),\n left: Math.round(rect.left),\n bottom: Math.round(rect.bottom),\n right: Math.round(rect.right),\n },\n };\n }\n\n private handleGetElementStyle(command: ClientCommand<{ selector: string; properties?: string[] }>): CommandResponse {\n if (typeof window === 'undefined' || typeof document === 'undefined') {\n return { id: command.id, ok: false, error: 'No browser window available' };\n }\n\n const selector = command.params?.selector;\n if (!selector) {\n return { id: command.id, ok: false, error: 'Missing selector parameter' };\n }\n\n const el = document.querySelector(selector);\n if (!el) {\n return { id: command.id, ok: false, error: `Element not found: ${selector}` };\n }\n\n const computed = window.getComputedStyle(el);\n const properties = command.params?.properties || ['overflow', 'overflowX', 'overflowY', 'width', 'maxWidth', 'display', 'position'];\n const styles: Record<string, string> = {};\n\n for (const prop of properties) {\n styles[prop] = computed.getPropertyValue(prop) || (computed as any)[prop] || '';\n }\n\n return {\n id: command.id,\n ok: true,\n result: {\n selector,\n styles,\n },\n };\n }\n}\n","export interface BrowserDiagClientOptions {\n daemonUrl?: string;\n projectId?: string;\n maxBreadcrumbs?: number;\n captureErrors?: boolean;\n captureConsole?: boolean;\n captureNetwork?: boolean;\n captureNavigation?: boolean;\n captureInteractions?: boolean;\n onErrorScreenshot?: boolean;\n notes?: {\n enabled?: boolean;\n shortcut?: string;\n showBadges?: boolean;\n maskSelectors?: string[];\n };\n debug?: boolean;\n}\n\nexport const DEFAULT_OPTIONS: Required<Omit<BrowserDiagClientOptions, 'notes'>> & { notes: Required<NonNullable<BrowserDiagClientOptions['notes']>> } = {\n daemonUrl: 'ws://127.0.0.1:7331',\n projectId: '',\n maxBreadcrumbs: 50,\n captureErrors: true,\n captureConsole: true,\n captureNetwork: true,\n captureNavigation: true,\n captureInteractions: true,\n onErrorScreenshot: true,\n notes: {\n enabled: true,\n shortcut: 'Alt+Click',\n showBadges: true,\n maskSelectors: ['input[type=\"password\"]', '[data-sensitive]'],\n },\n debug: false,\n};\n","import type { ConsoleEvent, ConsoleLevel } from '../../../core/src/index.js';\n\nexport type ConsoleCallback = (event: ConsoleEvent) => void;\n\n/**\n * Patches console methods without modifying original behavior.\n */\nexport function setupConsoleInterceptors(onConsole: ConsoleCallback): () => void {\n if (typeof console === 'undefined') return () => {};\n\n const originalError = console.error;\n const originalWarn = console.warn;\n\n function formatArgs(args: any[]): string {\n return args\n .map((arg) => {\n if (arg instanceof Error) {\n return arg.stack || `${arg.name}: ${arg.message}`;\n }\n if (typeof arg === 'object' && arg !== null) {\n try {\n return JSON.stringify(arg);\n } catch {\n return String(arg);\n }\n }\n return String(arg);\n })\n .join(' ');\n }\n\n console.error = function (...args: any[]) {\n try {\n const message = formatArgs(args);\n const stack = new Error().stack;\n onConsole({\n level: 'error',\n message,\n stack,\n timestamp: Date.now(),\n });\n } catch {\n // Defensive\n }\n return originalError.apply(console, args);\n };\n\n console.warn = function (...args: any[]) {\n try {\n const message = formatArgs(args);\n const stack = new Error().stack;\n onConsole({\n level: 'warn',\n message,\n stack,\n timestamp: Date.now(),\n });\n } catch {\n // Defensive\n }\n return originalWarn.apply(console, args);\n };\n\n return () => {\n console.error = originalError;\n console.warn = originalWarn;\n };\n}\n","import type { NavigationEvent } from '../../../core/src/index.js';\nimport { redactUrl } from '../../../core/src/index.js';\n\nexport type NavigationCallback = (event: NavigationEvent) => void;\n\n/**\n * Tracks browser SPA routing and history navigation.\n */\nexport function setupNavigationInterceptors(onNavigation: NavigationCallback): () => void {\n if (typeof window === 'undefined' || typeof history === 'undefined') return () => {};\n\n let currentUrl = redactUrl(window.location.href);\n\n // Initial navigation\n onNavigation({\n to: currentUrl,\n type: 'initial',\n timestamp: Date.now(),\n });\n\n const originalPushState = history.pushState;\n const originalReplaceState = history.replaceState;\n\n history.pushState = function (data: any, unused: string, url?: string | URL | null) {\n const from = currentUrl;\n const result = originalPushState.apply(history, [data, unused, url]);\n try {\n const to = redactUrl(window.location.href);\n currentUrl = to;\n onNavigation({\n from,\n to,\n type: 'pushState',\n timestamp: Date.now(),\n });\n } catch {\n // Defensive\n }\n return result;\n };\n\n history.replaceState = function (data: any, unused: string, url?: string | URL | null) {\n const from = currentUrl;\n const result = originalReplaceState.apply(history, [data, unused, url]);\n try {\n const to = redactUrl(window.location.href);\n currentUrl = to;\n onNavigation({\n from,\n to,\n type: 'replaceState',\n timestamp: Date.now(),\n });\n } catch {\n // Defensive\n }\n return result;\n };\n\n const onPopState = () => {\n const from = currentUrl;\n const to = redactUrl(window.location.href);\n currentUrl = to;\n onNavigation({\n from,\n to,\n type: 'popstate',\n timestamp: Date.now(),\n });\n };\n\n const onHashChange = () => {\n const from = currentUrl;\n const to = redactUrl(window.location.href);\n currentUrl = to;\n onNavigation({\n from,\n to,\n type: 'hashchange',\n timestamp: Date.now(),\n });\n };\n\n window.addEventListener('popstate', onPopState);\n window.addEventListener('hashchange', onHashChange);\n\n return () => {\n history.pushState = originalPushState;\n history.replaceState = originalReplaceState;\n window.removeEventListener('popstate', onPopState);\n window.removeEventListener('hashchange', onHashChange);\n };\n}\n","import type { NetworkEvent } from '../../../core/src/index.js';\nimport { redactUrl } from '../../../core/src/index.js';\n\nexport type NetworkCallback = (event: NetworkEvent) => void;\n\n/**\n * Patches window.fetch and XMLHttpRequest to track network requests and failures.\n */\nexport function setupNetworkInterceptors(onNetwork: NetworkCallback): () => void {\n const cleanups: (() => void)[] = [];\n\n // 1. Patch window.fetch\n if (typeof window !== 'undefined' && typeof window.fetch === 'function') {\n const originalFetch = window.fetch;\n\n window.fetch = async function (input: RequestInfo | URL, init?: RequestInit): Promise<Response> {\n const startTime = Date.now();\n let urlStr = '';\n let method = 'GET';\n\n try {\n if (typeof input === 'string') {\n urlStr = input;\n } else if (input instanceof URL) {\n urlStr = input.toString();\n } else if (input && typeof input === 'object' && 'url' in input) {\n urlStr = input.url;\n method = input.method || 'GET';\n }\n\n if (init && init.method) {\n method = init.method.toUpperCase();\n }\n } catch {\n urlStr = 'unknown_url';\n }\n\n const safeUrl = redactUrl(urlStr);\n\n try {\n const response = await originalFetch.apply(window, [input as any, init]);\n const durationMs = Date.now() - startTime;\n\n onNetwork({\n url: safeUrl,\n method,\n status: response.status,\n statusText: response.statusText,\n durationMs,\n timestamp: startTime,\n });\n\n return response;\n } catch (err: any) {\n const durationMs = Date.now() - startTime;\n const isAbort = err?.name === 'AbortError';\n\n onNetwork({\n url: safeUrl,\n method,\n durationMs,\n error: err?.message || 'Network request failed',\n aborted: isAbort,\n timestamp: startTime,\n });\n\n throw err;\n }\n };\n\n cleanups.push(() => {\n window.fetch = originalFetch;\n });\n }\n\n // 2. Patch XMLHttpRequest\n if (typeof window !== 'undefined' && typeof window.XMLHttpRequest === 'function') {\n const originalOpen = XMLHttpRequest.prototype.open;\n const originalSend = XMLHttpRequest.prototype.send;\n const originalAbort = XMLHttpRequest.prototype.abort;\n\n const xhrMap = new WeakMap<XMLHttpRequest, { url: string; method: string; startTime: number; aborted?: boolean }>();\n\n XMLHttpRequest.prototype.open = function (this: XMLHttpRequest, ...args: any[]) {\n try {\n const method = String(args[0] || 'GET').toUpperCase();\n const rawUrl = String(args[1] || '');\n xhrMap.set(this, {\n url: redactUrl(rawUrl),\n method,\n startTime: Date.now(),\n });\n } catch {\n // Defensive\n }\n return originalOpen.apply(this, args as any);\n };\n\n XMLHttpRequest.prototype.abort = function (this: XMLHttpRequest) {\n const meta = xhrMap.get(this);\n if (meta) {\n meta.aborted = true;\n }\n return originalAbort.apply(this);\n };\n\n XMLHttpRequest.prototype.send = function (this: XMLHttpRequest, body?: any) {\n const meta = xhrMap.get(this) || { url: 'unknown_url', method: 'GET', startTime: Date.now() };\n\n const onComplete = () => {\n try {\n const durationMs = Date.now() - meta.startTime;\n onNetwork({\n url: meta.url,\n method: meta.method,\n status: this.status,\n statusText: this.statusText,\n durationMs,\n aborted: meta.aborted,\n timestamp: meta.startTime,\n });\n } catch {\n // Defensive\n }\n };\n\n const onError = () => {\n try {\n const durationMs = Date.now() - meta.startTime;\n onNetwork({\n url: meta.url,\n method: meta.method,\n status: this.status || 0,\n durationMs,\n error: 'XHR Network Error',\n aborted: meta.aborted,\n timestamp: meta.startTime,\n });\n } catch {\n // Defensive\n }\n };\n\n this.addEventListener('load', onComplete, { once: true });\n this.addEventListener('error', onError, { once: true });\n this.addEventListener('timeout', onError, { once: true });\n\n return originalSend.apply(this, [body]);\n };\n\n cleanups.push(() => {\n XMLHttpRequest.prototype.open = originalOpen;\n XMLHttpRequest.prototype.send = originalSend;\n XMLHttpRequest.prototype.abort = originalAbort;\n });\n }\n\n return () => {\n for (const cleanup of cleanups) {\n try {\n cleanup();\n } catch {}\n }\n };\n}\n","import type { RuntimeErrorEvent } from '@browserdiag/core';\n\nexport type RuntimeErrorCallback = (event: RuntimeErrorEvent, error?: any) => void;\n\nexport function setupRuntimeInterceptors(onRuntimeError: RuntimeErrorCallback): () => void {\n if (typeof window === 'undefined') return () => {};\n\n const errorHandler = (event: ErrorEvent) => {\n try {\n const errorEvent: RuntimeErrorEvent = {\n message: event.message || (event.error && event.error.message) || 'Script error',\n stack: (event.error && event.error.stack) || undefined,\n filename: event.filename || undefined,\n lineno: event.lineno || undefined,\n colno: event.colno || undefined,\n errorType: (event.error && event.error.name) || 'Error',\n timestamp: Date.now(),\n };\n onRuntimeError(errorEvent, event.error);\n } catch {\n // Defensive: never let diagnostic handler crash host app\n }\n };\n\n const unhandledRejectionHandler = (event: PromiseRejectionEvent) => {\n try {\n const reason = event.reason;\n let message = 'Unhandled Promise Rejection';\n let stack: string | undefined;\n let errorType = 'UnhandledRejection';\n\n if (reason instanceof Error) {\n message = reason.message;\n stack = reason.stack;\n errorType = reason.name || 'UnhandledRejection';\n } else if (typeof reason === 'string') {\n message = reason;\n } else if (reason && typeof reason === 'object') {\n try {\n message = JSON.stringify(reason);\n } catch {\n message = String(reason);\n }\n }\n\n const errorEvent: RuntimeErrorEvent = {\n message,\n stack,\n errorType,\n timestamp: Date.now(),\n };\n onRuntimeError(errorEvent, reason);\n } catch {\n // Defensive\n }\n };\n\n window.addEventListener('error', errorHandler);\n window.addEventListener('unhandledrejection', unhandledRejectionHandler);\n\n return () => {\n window.removeEventListener('error', errorHandler);\n window.removeEventListener('unhandledrejection', unhandledRejectionHandler);\n };\n}\n","import { snapdom } from '@zumer/snapdom';\nimport type { ScreenshotDriver, ScreenshotResult } from './driver.js';\n\n/**\n * Modern DOM snapshot driver using @zumer/snapdom with graceful fallbacks.\n * Converts DOM subtrees and elements into WebP / PNG data URLs.\n */\nexport class BrowserScriptScreenshotDriver implements ScreenshotDriver {\n public name = 'BrowserScriptScreenshotDriver';\n\n public async captureSelector(selector: string): Promise<ScreenshotResult> {\n try {\n if (typeof document === 'undefined') {\n return { ok: false, reason: 'NO_DOCUMENT_ENVIRONMENT' };\n }\n\n const el = document.querySelector(selector);\n if (!el) {\n return { ok: false, reason: `ELEMENT_NOT_FOUND: ${selector}` };\n }\n\n return await this.captureElement(el);\n } catch (err: any) {\n return { ok: false, reason: err?.message || 'UNKNOWN_CAPTURE_ERROR' };\n }\n }\n\n public async captureElement(element: HTMLElement | Element): Promise<ScreenshotResult> {\n try {\n if (typeof window === 'undefined' || typeof document === 'undefined') {\n return { ok: false, reason: 'NO_BROWSER_ENVIRONMENT' };\n }\n\n const rect = element.getBoundingClientRect();\n const width = Math.max(Math.round(rect.width), 10);\n const height = Math.max(Math.round(rect.height), 10);\n\n // Attempt capture with snapdom\n const capturePromise = (async () => {\n try {\n // Prefer WebP export if supported, otherwise fallback to PNG\n let imgElement: HTMLImageElement | undefined = undefined;\n let format: 'webp' | 'png' = 'webp';\n\n try {\n if (typeof snapdom === 'function') {\n const captureRes = await snapdom(element as any, { scale: 1, embedFonts: false });\n if (captureRes && typeof captureRes.toWebp === 'function') {\n imgElement = await captureRes.toWebp();\n } else if (captureRes && typeof captureRes.toPng === 'function') {\n imgElement = await captureRes.toPng();\n format = 'png';\n } else if (captureRes?.url) {\n return {\n ok: true,\n dataUrl: captureRes.url,\n format: 'webp' as const,\n width,\n height,\n };\n }\n } else if ((snapdom as any)?.toWebp) {\n imgElement = await (snapdom as any).toWebp(element, {\n scale: 1,\n embedFonts: false,\n });\n } else if ((snapdom as any)?.toPng) {\n imgElement = await (snapdom as any).toPng(element, {\n scale: 1,\n embedFonts: false,\n });\n format = 'png';\n }\n } catch {\n // Fall through to fallback\n }\n\n if (imgElement && imgElement.src) {\n return {\n ok: true,\n dataUrl: imgElement.src,\n format: imgElement.src.startsWith('data:image/webp') ? ('webp' as const) : format,\n width: imgElement.naturalWidth || width,\n height: imgElement.naturalHeight || height,\n };\n }\n } catch (snapErr: any) {\n const errMsg = String(snapErr?.message || snapErr);\n if (errMsg.includes('CORS') || errMsg.includes('SecurityError') || errMsg.includes('tainted')) {\n return { ok: false, reason: 'CROSS_ORIGIN_RESOURCE' };\n }\n // Fallback to minimal canvas capture below\n }\n\n // Fallback: minimal inline SVG ForeignObject capture\n return await this.captureWithSvgFallback(element, width, height);\n })();\n\n // 3 second timeout protection\n const timeoutPromise = new Promise<ScreenshotResult>((resolve) => {\n setTimeout(() => resolve({ ok: false, reason: 'CAPTURE_TIMEOUT' }), 3000);\n });\n\n return await Promise.race([capturePromise, timeoutPromise]);\n } catch (err: any) {\n return { ok: false, reason: err?.message || 'CAPTURE_EXCEPTION' };\n }\n }\n\n private async captureWithSvgFallback(\n element: HTMLElement | Element,\n width: number,\n height: number\n ): Promise<ScreenshotResult> {\n try {\n const clone = element.cloneNode(true) as HTMLElement;\n const computed = window.getComputedStyle(element);\n let cssText = '';\n for (let i = 0; i < computed.length; i++) {\n const prop = computed[i];\n cssText += `${prop}:${computed.getPropertyValue(prop)};`;\n }\n clone.style.cssText = cssText;\n clone.style.margin = '0';\n clone.style.position = 'static';\n\n const svg = `\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"${width}\" height=\"${height}\">\n <foreignObject width=\"100%\" height=\"100%\">\n <div xmlns=\"http://www.w3.org/1999/xhtml\" style=\"width:${width}px;height:${height}px;\">\n ${clone.outerHTML}\n </div>\n </foreignObject>\n </svg>\n `.trim();\n\n const svgBlob = new Blob([svg], { type: 'image/svg+xml;charset=utf-8' });\n const url = URL.createObjectURL(svgBlob);\n\n return await new Promise<ScreenshotResult>((resolve) => {\n const img = new Image();\n img.onload = () => {\n try {\n const canvas = document.createElement('canvas');\n canvas.width = width;\n canvas.height = height;\n const ctx = canvas.getContext('2d');\n if (!ctx) {\n URL.revokeObjectURL(url);\n resolve({ ok: false, reason: 'CANVAS_CONTEXT_UNAVAILABLE' });\n return;\n }\n\n ctx.drawImage(img, 0, 0);\n URL.revokeObjectURL(url);\n\n let dataUrl: string;\n try {\n dataUrl = canvas.toDataURL('image/webp', 0.85);\n } catch {\n dataUrl = canvas.toDataURL('image/png');\n }\n\n resolve({\n ok: true,\n dataUrl,\n format: dataUrl.startsWith('data:image/webp') ? 'webp' : 'png',\n width,\n height,\n });\n } catch (e: any) {\n URL.revokeObjectURL(url);\n if (e?.name === 'SecurityError' || String(e).includes('tainted')) {\n resolve({ ok: false, reason: 'CROSS_ORIGIN_RESOURCE' });\n } else {\n resolve({ ok: false, reason: e?.message || 'CANVAS_EXPORT_FAILED' });\n }\n }\n };\n\n img.onerror = () => {\n URL.revokeObjectURL(url);\n resolve({ ok: false, reason: 'IMAGE_LOAD_FAILED' });\n };\n\n img.src = url;\n });\n } catch (e: any) {\n return { ok: false, reason: e?.message || 'FALLBACK_CAPTURE_FAILED' };\n }\n }\n}\n","import type { HelloMessage, ClientCommand, CommandResponse } from '../../../core/src/index.js';\nimport type { ClientCommandHandler } from '../commands/handler.js';\n\nexport interface TransportOptions {\n url: string;\n projectId?: string;\n debug?: boolean;\n}\n\nexport class WebSocketTransport {\n private wsUrl: string;\n private projectId?: string;\n private debug: boolean;\n private ws: WebSocket | null = null;\n private sessionId: string | null = null;\n private queue: string[] = [];\n private maxQueueSize = 50;\n private reconnectAttempts = 0;\n private maxReconnectDelay = 10000;\n private reconnectTimer: any = null;\n private commandHandler?: ClientCommandHandler;\n private messageListeners: ((msg: any) => void)[] = [];\n private isDestroyed = false;\n\n constructor(options: TransportOptions) {\n this.wsUrl = options.url || 'ws://127.0.0.1:7331';\n this.projectId = options.projectId;\n this.debug = !!options.debug;\n }\n\n public setCommandHandler(handler: ClientCommandHandler): void {\n this.commandHandler = handler;\n }\n\n public onMessage(listener: (msg: any) => void): () => void {\n this.messageListeners.push(listener);\n return () => {\n this.messageListeners = this.messageListeners.filter((l) => l !== listener);\n };\n }\n\n public getSessionId(): string | null {\n return this.sessionId;\n }\n\n public isConnected(): boolean {\n return this.ws !== null && this.ws.readyState === (typeof WebSocket !== 'undefined' ? WebSocket.OPEN : 1);\n }\n\n public connect(): void {\n if (this.isDestroyed || typeof WebSocket === 'undefined') return;\n if (this.ws && (this.ws.readyState === WebSocket.CONNECTING || this.ws.readyState === WebSocket.OPEN)) {\n return;\n }\n\n try {\n this.ws = new WebSocket(this.wsUrl);\n\n this.ws.onopen = () => {\n this.reconnectAttempts = 0;\n this.sendHello();\n this.flushQueue();\n };\n\n this.ws.onmessage = async (event: MessageEvent) => {\n try {\n const raw = typeof event.data === 'string' ? event.data : '';\n if (!raw) return;\n const msg = JSON.parse(raw);\n\n // Dispatch to subscribers (e.g. NoteInspector for notes_sync)\n for (const listener of this.messageListeners) {\n try {\n listener(msg);\n } catch {}\n }\n\n if (msg.type === 'hello_ack') {\n this.sessionId = msg.sessionId;\n if (this.debug) {\n console.log('[BrowserTrack] Connected, session ID:', this.sessionId);\n }\n return;\n }\n\n if (msg.type === 'command' && this.commandHandler) {\n const command: ClientCommand = msg.command;\n const res: CommandResponse = await this.commandHandler.executeCommand(command);\n this.send({\n type: 'command_response',\n sessionId: this.sessionId,\n response: res,\n });\n }\n } catch {\n // Defensive\n }\n };\n\n this.ws.onerror = () => {\n // Silent fail if daemon is offline\n };\n\n this.ws.onclose = () => {\n this.ws = null;\n this.scheduleReconnect();\n };\n } catch {\n this.scheduleReconnect();\n }\n }\n\n public send(payload: any): void {\n const raw = JSON.stringify(payload);\n if (this.isConnected()) {\n try {\n this.ws!.send(raw);\n } catch {\n this.enqueue(raw);\n }\n } else {\n this.enqueue(raw);\n }\n }\n\n private enqueue(raw: string): void {\n if (this.queue.length >= this.maxQueueSize) {\n this.queue.shift();\n }\n this.queue.push(raw);\n }\n\n private flushQueue(): void {\n if (!this.isConnected()) return;\n while (this.queue.length > 0) {\n const item = this.queue.shift();\n if (item) {\n try {\n this.ws!.send(item);\n } catch {\n this.queue.unshift(item);\n break;\n }\n }\n }\n }\n\n private sendHello(): void {\n if (typeof window === 'undefined') return;\n\n const hello: HelloMessage = {\n type: 'hello',\n origin: window.location.origin,\n url: window.location.href,\n title: document.title,\n userAgent: navigator.userAgent,\n timestamp: Date.now(),\n projectId: this.projectId,\n };\n\n try {\n this.ws!.send(JSON.stringify(hello));\n } catch {\n // Defensive\n }\n }\n\n private scheduleReconnect(): void {\n if (this.isDestroyed || this.reconnectTimer) return;\n\n this.reconnectAttempts++;\n const delay = Math.min(1000 * Math.pow(1.5, this.reconnectAttempts), this.maxReconnectDelay);\n\n this.reconnectTimer = setTimeout(() => {\n this.reconnectTimer = null;\n this.connect();\n }, delay);\n }\n\n public destroy(): void {\n this.isDestroyed = true;\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = null;\n }\n if (this.ws) {\n try {\n this.ws.close();\n } catch {}\n this.ws = null;\n }\n this.queue = [];\n }\n}\n","import type { ElementContext, NoteTarget, RegionContext, VisualNote } from '../../../core/src/index.js';\nimport { getSemanticSelector, truncate } from '../../../core/src/index.js';\nimport type { ScreenshotDriver } from '../screenshot/driver.js';\nimport type { WebSocketTransport } from '../transport/websocket.js';\n\nexport type NoteInspectMode = 'element' | 'region' | 'page' | 'idle';\n\nexport interface InspectorOptions {\n shortcut?: string; // e.g. \"Alt+Click\"\n maskSelectors?: string[];\n showToolbar?: boolean;\n onNoteCreated?: (note: Partial<VisualNote>) => void;\n}\n\n/**\n * Isolated Visual Note Inspector rendering in Shadow DOM.\n * Supports:\n * 1. Element selection (hover highlight & click)\n * 2. Region / Area selection (drag-and-drop rectangle on screen with cancel banner)\n * 3. Whole page note\n * 4. Real-time Saved Note Markers (pins on elements/regions when page loads or syncs)\n * 5. Interactive Note Detail Card (view message, target, resolve/delete actions)\n * 6. Floating quick dock / toolbar in bottom-right corner with Notes count toggle\n */\nexport class NoteInspector {\n private transport: WebSocketTransport;\n private screenshotDriver: ScreenshotDriver;\n private options: InspectorOptions;\n\n private container: HTMLDivElement | null = null;\n private shadowRoot: ShadowRoot | null = null;\n private highlightOverlay: HTMLDivElement | null = null;\n private regionOverlay: HTMLDivElement | null = null;\n private regionBox: HTMLDivElement | null = null;\n private regionBanner: HTMLDivElement | null = null;\n private markersContainer: HTMLDivElement | null = null;\n private toolbarElement: HTMLDivElement | null = null;\n private modalOverlay: HTMLDivElement | null = null;\n private cardOverlay: HTMLDivElement | null = null;\n\n private activeMode: NoteInspectMode = 'idle';\n private hoveredElement: HTMLElement | null = null;\n private selectedElement: HTMLElement | null = null;\n private selectedRegion: RegionContext | null = null;\n\n private isDraggingRegion = false;\n private dragStartX = 0;\n private dragStartY = 0;\n\n private savedNotes: VisualNote[] = [];\n private showMarkers = true;\n private cleanups: (() => void)[] = [];\n\n constructor(transport: WebSocketTransport, screenshotDriver: ScreenshotDriver, options: InspectorOptions = {}) {\n this.transport = transport;\n this.screenshotDriver = screenshotDriver;\n this.options = {\n shortcut: 'Alt+Click',\n maskSelectors: ['input[type=\"password\"]', '[data-sensitive]'],\n showToolbar: true,\n ...options,\n };\n }\n\n public init(): void {\n if (typeof window === 'undefined' || typeof document === 'undefined') return;\n\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', () => {\n this.ensureContainer();\n });\n } else {\n this.ensureContainer();\n }\n\n // Subscribe to incoming notes synchronization from daemon\n const unsubscribe = this.transport.onMessage((msg) => {\n if (msg && msg.type === 'notes_sync' && Array.isArray(msg.notes)) {\n this.syncNotes(msg.notes);\n }\n });\n this.cleanups.push(unsubscribe);\n\n this.setupListeners();\n }\n\n public syncNotes(notes: VisualNote[]): void {\n this.savedNotes = notes;\n this.updateToolbarCount();\n this.renderMarkers();\n }\n\n public setMode(mode: NoteInspectMode): void {\n this.activeMode = mode;\n this.updateToolbarState();\n\n if (mode === 'element') {\n this.hideRegionOverlay();\n } else if (mode === 'region') {\n this.hideHighlight();\n this.showRegionOverlay();\n } else if (mode === 'page') {\n this.hideRegionOverlay();\n this.hideHighlight();\n this.openNoteEditor(document.body, 'page');\n } else {\n this.hideRegionOverlay();\n this.hideHighlight();\n }\n }\n\n private ensureContainer(): ShadowRoot | null {\n if (typeof document === 'undefined') return null;\n\n if (!this.container) {\n this.container = document.createElement('div');\n this.container.id = 'browsertrack-inspector-host';\n this.container.style.cssText =\n 'all: initial; position: fixed; top: 0; left: 0; width: 0; height: 0; z-index: 2147483647; pointer-events: none;';\n\n this.shadowRoot = this.container.attachShadow({ mode: 'open' });\n\n // Styles for highlight overlay, region drag box, markers, floating toolbar and modals\n const style = document.createElement('style');\n style.textContent = `\n :host {\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif;\n color-scheme: dark;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n }\n \n /* 1. Element Highlight Overlay */\n .bt-highlight {\n position: fixed;\n border: 2px solid #3b82f6;\n background: rgba(59, 130, 246, 0.16);\n border-radius: 4px;\n pointer-events: none;\n transition: all 0.05s ease-out;\n z-index: 2147483640;\n box-sizing: border-box;\n }\n\n .bt-badge {\n position: absolute;\n top: -26px;\n left: 0;\n background: #0f172a;\n color: #38bdf8;\n border: 1px solid #3b82f6;\n font-size: 11px;\n font-weight: 600;\n font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;\n padding: 2px 7px;\n border-radius: 4px;\n white-space: nowrap;\n pointer-events: none;\n box-shadow: 0 4px 6px -1px rgba(0,0,0,0.5);\n }\n\n /* 2. Region Selection Overlay */\n .bt-region-overlay {\n position: fixed;\n inset: 0;\n width: 100vw;\n height: 100vh;\n cursor: crosshair;\n z-index: 2147483642;\n pointer-events: auto;\n background: rgba(15, 23, 42, 0.25);\n user-select: none;\n }\n\n .bt-region-box {\n position: fixed;\n border: 2px dashed #38bdf8;\n background: rgba(56, 189, 248, 0.2);\n box-sizing: border-box;\n pointer-events: none;\n z-index: 2147483643;\n }\n\n .bt-region-badge {\n position: absolute;\n top: -26px;\n left: 0;\n background: #0f172a;\n color: #38bdf8;\n border: 1px solid #0284c7;\n font-size: 11px;\n font-weight: 600;\n font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;\n padding: 2px 7px;\n border-radius: 4px;\n white-space: nowrap;\n pointer-events: none;\n box-shadow: 0 4px 6px -1px rgba(0,0,0,0.5);\n }\n\n .bt-region-banner {\n position: fixed;\n top: 20px;\n left: 50%;\n transform: translateX(-50%);\n background: #0f172a;\n color: #f8fafc;\n border: 1px solid #0284c7;\n border-radius: 30px;\n padding: 8px 16px;\n display: flex;\n align-items: center;\n gap: 12px;\n box-shadow: 0 10px 25px -5px rgba(0,0,0,0.6);\n font-size: 12.5px;\n font-weight: 500;\n pointer-events: auto;\n z-index: 2147483645;\n user-select: none;\n }\n\n .bt-region-cancel-btn {\n background: rgba(239, 68, 68, 0.15);\n color: #fca5a5;\n border: 1px solid rgba(239, 68, 68, 0.4);\n padding: 3px 10px;\n border-radius: 20px;\n font-size: 11px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.15s ease;\n display: inline-flex;\n align-items: center;\n gap: 4px;\n font-family: inherit;\n }\n\n .bt-region-cancel-btn:hover {\n background: rgba(239, 68, 68, 0.3);\n color: #ffffff;\n }\n\n /* 3. Note Markers on Page */\n .bt-markers-layer {\n position: fixed;\n top: 0;\n left: 0;\n width: 0;\n height: 0;\n pointer-events: none;\n z-index: 2147483638;\n }\n\n .bt-note-marker {\n position: fixed;\n pointer-events: auto;\n background: linear-gradient(135deg, #2563eb, #1d4ed8);\n color: #ffffff;\n border: 2px solid #ffffff;\n box-shadow: 0 4px 12px rgba(0,0,0,0.5), 0 0 0 1px rgba(37,99,235,0.4);\n border-radius: 999px;\n height: 26px;\n min-width: 26px;\n padding: 0 7px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 4px;\n cursor: pointer;\n font-size: 11px;\n font-weight: 700;\n user-select: none;\n transition: transform 0.15s cubic-bezier(0.16, 1, 0.3, 1), box-shadow 0.15s ease;\n animation: bt-pop-in 0.2s ease-out;\n box-sizing: border-box;\n z-index: 2147483641;\n }\n\n @keyframes bt-pop-in {\n 0% { transform: scale(0.6); opacity: 0; }\n 100% { transform: scale(1); opacity: 1; }\n }\n\n .bt-note-marker:hover {\n transform: scale(1.15) translateY(-2px);\n box-shadow: 0 8px 20px rgba(37,99,235,0.6), 0 0 0 2px #60a5fa;\n }\n\n .bt-marker-resolved {\n background: linear-gradient(135deg, #475569, #334155);\n border-color: #94a3b8;\n opacity: 0.75;\n }\n\n .bt-region-marker-box {\n position: fixed;\n border: 2px dashed #0284c7;\n background: rgba(14, 165, 233, 0.08);\n pointer-events: none;\n box-sizing: border-box;\n border-radius: 6px;\n z-index: 2147483639;\n }\n\n .bt-page-notes-dock {\n position: fixed;\n top: 16px;\n right: 16px;\n display: flex;\n flex-direction: column;\n gap: 6px;\n pointer-events: none;\n z-index: 2147483641;\n }\n\n .bt-page-note-pill {\n background: #0f172a;\n color: #c084fc;\n border: 1px solid #7e22ce;\n border-radius: 20px;\n padding: 5px 12px;\n font-size: 11.5px;\n font-weight: 600;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n box-shadow: 0 4px 12px rgba(0,0,0,0.5);\n cursor: pointer;\n pointer-events: auto;\n transition: all 0.15s ease;\n }\n\n .bt-page-note-pill:hover {\n background: #1e1b4b;\n transform: translateY(-1px);\n }\n\n /* 4. Floating Quick Toolbar */\n .bt-toolbar {\n position: fixed;\n bottom: 20px;\n right: 20px;\n background: #0f172a;\n border: 1px solid #334155;\n border-radius: 30px;\n padding: 4px 6px;\n display: flex;\n align-items: center;\n gap: 4px;\n box-shadow: 0 10px 25px -3px rgba(0,0,0,0.6), 0 4px 6px -4px rgba(0,0,0,0.4);\n pointer-events: auto;\n z-index: 2147483646;\n user-select: none;\n transition: all 0.2s ease;\n }\n\n .bt-toolbar-btn {\n background: transparent;\n border: none;\n color: #94a3b8;\n font-size: 12px;\n font-weight: 500;\n padding: 6px 12px;\n border-radius: 20px;\n cursor: pointer;\n display: flex;\n align-items: center;\n gap: 6px;\n transition: all 0.15s ease;\n font-family: inherit;\n }\n\n .bt-toolbar-btn:hover {\n background: #1e293b;\n color: #f8fafc;\n }\n\n .bt-toolbar-btn.active {\n background: #2563eb;\n color: #ffffff;\n font-weight: 600;\n box-shadow: 0 2px 6px rgba(37, 99, 235, 0.35);\n }\n\n .bt-count-pill {\n background: rgba(255, 255, 255, 0.2);\n color: #ffffff;\n font-size: 10px;\n font-weight: 700;\n padding: 1px 6px;\n border-radius: 10px;\n line-height: 1.2;\n }\n\n .bt-toolbar-divider {\n width: 1px;\n height: 16px;\n background: #334155;\n margin: 0 2px;\n }\n\n /* 5. Modals & Popover Card */\n .bt-modal-backdrop {\n position: fixed;\n top: 0;\n left: 0;\n width: 100vw;\n height: 100vh;\n background: rgba(15, 23, 42, 0.75);\n backdrop-filter: blur(6px);\n display: flex;\n align-items: center;\n justify-content: center;\n pointer-events: auto;\n z-index: 2147483647;\n opacity: 1;\n box-sizing: border-box;\n animation: bt-fade-in 0.15s ease-out;\n }\n\n @keyframes bt-fade-in {\n from { opacity: 0; transform: scale(0.98); }\n to { opacity: 1; transform: scale(1); }\n }\n\n .bt-modal {\n background: #0f172a;\n color: #f8fafc;\n border: 1px solid #334155;\n border-radius: 14px;\n padding: 20px;\n width: 450px;\n max-width: 92vw;\n box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.8), 0 0 0 1px rgba(255, 255, 255, 0.05);\n display: flex;\n flex-direction: column;\n gap: 14px;\n box-sizing: border-box;\n }\n\n .bt-modal-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n }\n\n .bt-modal-title {\n font-size: 14.5px;\n font-weight: 600;\n letter-spacing: -0.01em;\n display: flex;\n align-items: center;\n gap: 8px;\n color: #f8fafc;\n }\n\n .bt-mode-badge {\n font-size: 10px;\n font-weight: 700;\n letter-spacing: 0.05em;\n text-transform: uppercase;\n padding: 2px 7px;\n border-radius: 6px;\n }\n\n .bt-badge-element {\n background: rgba(59, 130, 246, 0.15);\n color: #60a5fa;\n border: 1px solid rgba(59, 130, 246, 0.4);\n }\n\n .bt-badge-region {\n background: rgba(14, 165, 233, 0.15);\n color: #38bdf8;\n border: 1px solid rgba(14, 165, 233, 0.4);\n }\n\n .bt-badge-page {\n background: rgba(168, 85, 247, 0.15);\n color: #c084fc;\n border: 1px solid rgba(168, 85, 247, 0.4);\n }\n\n .bt-badge-status-open {\n background: rgba(16, 185, 129, 0.15);\n color: #34d399;\n border: 1px solid rgba(16, 185, 129, 0.4);\n }\n\n .bt-badge-status-resolved {\n background: rgba(100, 116, 139, 0.2);\n color: #94a3b8;\n border: 1px solid rgba(100, 116, 139, 0.4);\n }\n\n .bt-close-btn {\n background: transparent;\n border: none;\n color: #94a3b8;\n font-size: 15px;\n cursor: pointer;\n padding: 3px 7px;\n border-radius: 6px;\n transition: all 0.12s ease;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n .bt-close-btn:hover {\n background: #1e293b;\n color: #ffffff;\n }\n\n .bt-target-pill {\n background: #090d16;\n color: #94a3b8;\n border: 1px solid #1e293b;\n border-radius: 8px;\n padding: 8px 12px;\n font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;\n font-size: 11.5px;\n display: flex;\n align-items: center;\n gap: 8px;\n overflow: hidden;\n }\n\n .bt-pill-content {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n color: #cbd5e1;\n }\n\n .bt-note-message-box {\n background: #090d16;\n border: 1px solid #1e293b;\n border-radius: 8px;\n padding: 12px 14px;\n font-size: 13.5px;\n line-height: 1.5;\n color: #f1f5f9;\n white-space: pre-wrap;\n word-break: break-word;\n max-height: 180px;\n overflow-y: auto;\n }\n\n .bt-textarea {\n background: #090d16;\n color: #f8fafc;\n border: 1px solid #334155;\n border-radius: 8px;\n padding: 12px;\n font-size: 13.5px;\n line-height: 1.5;\n resize: vertical;\n min-height: 95px;\n outline: none;\n box-sizing: border-box;\n width: 100%;\n font-family: inherit;\n transition: border-color 0.15s ease, box-shadow 0.15s ease;\n }\n\n .bt-textarea::placeholder {\n color: #64748b;\n }\n\n .bt-textarea:focus {\n border-color: #3b82f6;\n box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.25);\n }\n\n .bt-modal-footer {\n display: flex;\n justify-content: space-between;\n align-items: center;\n gap: 12px;\n margin-top: 2px;\n }\n\n .bt-kbd-hint {\n font-size: 11px;\n color: #64748b;\n display: flex;\n align-items: center;\n gap: 4px;\n user-select: none;\n }\n\n .bt-kbd-hint kbd {\n background: #1e293b;\n color: #94a3b8;\n border: 1px solid #334155;\n border-radius: 4px;\n padding: 1px 5px;\n font-family: inherit;\n font-size: 10px;\n font-weight: 600;\n }\n\n .bt-modal-actions {\n display: flex;\n justify-content: flex-end;\n align-items: center;\n gap: 8px;\n }\n\n .bt-btn {\n padding: 8px 16px;\n border-radius: 7px;\n font-size: 12.5px;\n font-weight: 600;\n cursor: pointer;\n border: 1px solid transparent;\n transition: all 0.15s ease;\n font-family: inherit;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n }\n\n .bt-btn-cancel {\n background: transparent;\n color: #94a3b8;\n }\n .bt-btn-cancel:hover {\n background: #1e293b;\n color: #f8fafc;\n }\n\n .bt-btn-save {\n background: #2563eb;\n color: #ffffff;\n box-shadow: 0 2px 6px rgba(37, 99, 235, 0.35);\n }\n .bt-btn-save:hover {\n background: #1d4ed8;\n box-shadow: 0 4px 10px rgba(37, 99, 235, 0.45);\n }\n\n .bt-btn-resolve {\n background: rgba(16, 185, 129, 0.15);\n color: #6ee7b7;\n border: 1px solid rgba(16, 185, 129, 0.35);\n }\n .bt-btn-resolve:hover {\n background: rgba(16, 185, 129, 0.3);\n color: #ffffff;\n }\n\n .bt-btn-delete {\n background: rgba(239, 68, 68, 0.15);\n color: #fca5a5;\n border: 1px solid rgba(239, 68, 68, 0.35);\n }\n .bt-btn-delete:hover {\n background: rgba(239, 68, 68, 0.3);\n color: #ffffff;\n }\n `;\n\n this.shadowRoot.appendChild(style);\n\n // Element Highlight Overlay\n this.highlightOverlay = document.createElement('div');\n this.highlightOverlay.className = 'bt-highlight';\n this.highlightOverlay.style.display = 'none';\n this.shadowRoot.appendChild(this.highlightOverlay);\n\n // Markers container layer\n this.markersContainer = document.createElement('div');\n this.markersContainer.className = 'bt-markers-layer';\n this.shadowRoot.appendChild(this.markersContainer);\n\n // Floating Toolbar\n if (this.options.showToolbar) {\n this.createToolbar();\n }\n }\n\n if (this.container && !this.container.isConnected) {\n const mountParent = document.body || document.documentElement;\n if (mountParent) {\n mountParent.appendChild(this.container);\n }\n }\n\n return this.shadowRoot;\n }\n\n private createToolbar(): void {\n if (!this.shadowRoot || this.toolbarElement) return;\n\n this.toolbarElement = document.createElement('div');\n this.toolbarElement.className = 'bt-toolbar';\n this.toolbarElement.innerHTML = `\n <button class=\"bt-toolbar-btn\" id=\"bt-mode-element\" title=\"Inspect element (or hold Alt+Click)\">\n <span>🎯</span> Element\n </button>\n <button class=\"bt-toolbar-btn\" id=\"bt-mode-region\" title=\"Drag to select screen region\">\n <span>📐</span> Region\n </button>\n <button class=\"bt-toolbar-btn\" id=\"bt-mode-page\" title=\"Leave full-page note\">\n <span>📄</span> Page\n </button>\n <div class=\"bt-toolbar-divider\"></div>\n <button class=\"bt-toolbar-btn active\" id=\"bt-toggle-notes\" title=\"Toggle visible note markers on screen\">\n <span>📌</span> Notes <span class=\"bt-count-pill\" id=\"bt-notes-count\">0</span>\n </button>\n `;\n\n const btnElement = this.toolbarElement.querySelector('#bt-mode-element') as HTMLButtonElement;\n const btnRegion = this.toolbarElement.querySelector('#bt-mode-region') as HTMLButtonElement;\n const btnPage = this.toolbarElement.querySelector('#bt-mode-page') as HTMLButtonElement;\n const btnToggleNotes = this.toolbarElement.querySelector('#bt-toggle-notes') as HTMLButtonElement;\n\n btnElement.onclick = (e: MouseEvent) => {\n e.stopPropagation();\n this.setMode(this.activeMode === 'element' ? 'idle' : 'element');\n };\n\n btnRegion.onclick = (e: MouseEvent) => {\n e.stopPropagation();\n this.setMode(this.activeMode === 'region' ? 'idle' : 'region');\n };\n\n btnPage.onclick = (e: MouseEvent) => {\n e.stopPropagation();\n this.setMode('page');\n };\n\n btnToggleNotes.onclick = (e: MouseEvent) => {\n e.stopPropagation();\n this.showMarkers = !this.showMarkers;\n btnToggleNotes.classList.toggle('active', this.showMarkers);\n this.renderMarkers();\n };\n\n this.shadowRoot.appendChild(this.toolbarElement);\n }\n\n private updateToolbarState(): void {\n if (!this.toolbarElement) return;\n\n const btnElement = this.toolbarElement.querySelector('#bt-mode-element');\n const btnRegion = this.toolbarElement.querySelector('#bt-mode-region');\n const btnPage = this.toolbarElement.querySelector('#bt-mode-page');\n\n btnElement?.classList.toggle('active', this.activeMode === 'element');\n btnRegion?.classList.toggle('active', this.activeMode === 'region');\n btnPage?.classList.toggle('active', this.activeMode === 'page');\n }\n\n private updateToolbarCount(): void {\n if (!this.toolbarElement) return;\n const countEl = this.toolbarElement.querySelector('#bt-notes-count');\n if (countEl) {\n const openCount = this.savedNotes.filter((n) => n.status === 'OPEN').length;\n countEl.textContent = String(openCount);\n }\n }\n\n public renderMarkers(): void {\n const root = this.ensureContainer();\n if (!root || !this.markersContainer) return;\n\n this.markersContainer.innerHTML = '';\n if (!this.showMarkers) return;\n\n const currentPath = window.location.pathname;\n // Filter open notes on this route or global\n const activeNotes = this.savedNotes.filter(\n (n) => n.status === 'OPEN' && (n.route === currentPath || !n.route || n.route === '/' || window.location.href.includes(n.route))\n );\n\n const pageNotes: VisualNote[] = [];\n\n activeNotes.forEach((note, index) => {\n if (note.type === 'page') {\n pageNotes.push(note);\n return;\n }\n\n if (note.type === 'region' && note.region) {\n // Region box\n const regBox = document.createElement('div');\n regBox.className = 'bt-region-marker-box';\n regBox.style.left = `${note.region.x}px`;\n regBox.style.top = `${note.region.y}px`;\n regBox.style.width = `${note.region.width}px`;\n regBox.style.height = `${note.region.height}px`;\n this.markersContainer!.appendChild(regBox);\n\n // Pin on top-left of region\n const pin = document.createElement('div');\n pin.className = 'bt-note-marker';\n pin.style.left = `${Math.max(4, note.region.x - 12)}px`;\n pin.style.top = `${Math.max(4, note.region.y - 12)}px`;\n pin.title = note.message;\n pin.innerHTML = `<span>📐</span> <span>#${index + 1}</span>`;\n pin.onclick = (e) => {\n e.stopPropagation();\n this.openNoteCard(note);\n };\n this.markersContainer!.appendChild(pin);\n return;\n }\n\n // Element note\n let targetEl: HTMLElement | null = null;\n if (note.target?.selector) {\n try {\n targetEl = document.querySelector(note.target.selector) as HTMLElement | null;\n } catch {}\n }\n\n const rect = targetEl ? targetEl.getBoundingClientRect() : note.target?.boundingRect;\n if (rect) {\n const pin = document.createElement('div');\n pin.className = 'bt-note-marker';\n pin.setAttribute('data-note-id', note.id);\n pin.title = note.message;\n pin.style.left = `${Math.max(4, rect.left - 10)}px`;\n pin.style.top = `${Math.max(4, rect.top - 12)}px`;\n pin.innerHTML = `<span>📝</span> <span>#${index + 1}</span>`;\n\n pin.onclick = (e) => {\n e.stopPropagation();\n this.openNoteCard(note);\n };\n\n if (targetEl) {\n pin.onmouseenter = () => this.updateHighlight(targetEl!);\n pin.onmouseleave = () => this.hideHighlight();\n }\n\n this.markersContainer!.appendChild(pin);\n }\n });\n\n // Page notes docked in top-right\n if (pageNotes.length > 0) {\n const pageDock = document.createElement('div');\n pageDock.className = 'bt-page-notes-dock';\n pageNotes.forEach((pNote, idx) => {\n const pill = document.createElement('div');\n pill.className = 'bt-page-note-pill';\n pill.innerHTML = `<span>📄</span> <span>Page Note (${truncate(pNote.message, 25)})</span>`;\n pill.onclick = (e) => {\n e.stopPropagation();\n this.openNoteCard(pNote);\n };\n pageDock.appendChild(pill);\n });\n this.markersContainer.appendChild(pageDock);\n }\n }\n\n private updateMarkerPositions(): void {\n if (!this.showMarkers || !this.markersContainer) return;\n this.renderMarkers();\n }\n\n public openNoteCard(note: VisualNote): void {\n const root = this.ensureContainer();\n if (!root) return;\n\n if (this.cardOverlay && this.cardOverlay.parentElement) {\n this.cardOverlay.parentElement.removeChild(this.cardOverlay);\n this.cardOverlay = null;\n }\n\n const backdrop = document.createElement('div');\n backdrop.className = 'bt-modal-backdrop';\n this.cardOverlay = backdrop;\n\n const badgeClass = `bt-badge-${note.type.toLowerCase()}`;\n const statusClass = note.status === 'OPEN' ? 'bt-badge-status-open' : 'bt-badge-status-resolved';\n const icon = note.type === 'region' ? '📐' : note.type === 'page' ? '📄' : '🎯';\n const contextText =\n note.type === 'region' && note.region\n ? `Region: ${note.region.width} × ${note.region.height} px · Route: ${note.route}`\n : note.type === 'page'\n ? `Page Note · Route: ${note.route}`\n : `${note.target?.selector || 'Element'} (${note.target?.boundingRect?.width || 0}×${note.target?.boundingRect?.height || 0}px) · ${note.route}`;\n\n const formattedDate = new Date(note.createdAt).toLocaleString();\n\n backdrop.innerHTML = `\n <div class=\"bt-modal\">\n <div class=\"bt-modal-header\">\n <div class=\"bt-modal-title\">\n <span>${icon} Visual Note Details</span>\n <span class=\"bt-mode-badge ${badgeClass}\">${note.type.toUpperCase()}</span>\n <span class=\"bt-mode-badge ${statusClass}\">${note.status}</span>\n </div>\n <button class=\"bt-close-btn\" id=\"btn-card-close\" title=\"Close (Esc)\">✕</button>\n </div>\n\n <div class=\"bt-target-pill\" title=\"${contextText}\">\n <span>🏷️</span>\n <span class=\"bt-pill-content\">${contextText}</span>\n </div>\n\n <div class=\"bt-note-message-box\">${note.message}</div>\n\n <div style=\"font-size: 11px; color: #64748b; display: flex; justify-content: space-between; padding: 0 2px;\">\n <span>Created: ${formattedDate}</span>\n <span>ID: <code style=\"font-family: monospace; color: #94a3b8;\">${note.id}</code></span>\n </div>\n\n <div class=\"bt-modal-footer\">\n <button class=\"bt-btn bt-btn-delete\" id=\"btn-card-delete\" title=\"Delete this note\">\n <span>🗑️</span> Delete\n </button>\n <div class=\"bt-modal-actions\">\n <button class=\"bt-btn bt-btn-cancel\" id=\"btn-card-dismiss\">Close</button>\n <button class=\"bt-btn ${note.status === 'OPEN' ? 'bt-btn-resolve' : 'bt-btn-save'}\" id=\"btn-card-resolve\">\n ${note.status === 'OPEN' ? '<span>✅</span> Resolve Note' : '<span>↺</span> Reopen'}\n </button>\n </div>\n </div>\n </div>\n `;\n\n const btnClose = backdrop.querySelector('#btn-card-close') as HTMLButtonElement;\n const btnDismiss = backdrop.querySelector('#btn-card-dismiss') as HTMLButtonElement;\n const btnResolve = backdrop.querySelector('#btn-card-resolve') as HTMLButtonElement;\n const btnDelete = backdrop.querySelector('#btn-card-delete') as HTMLButtonElement;\n\n const closeCard = () => {\n if (this.cardOverlay) {\n root.removeChild(this.cardOverlay);\n this.cardOverlay = null;\n this.hideHighlight();\n }\n };\n\n btnClose.onclick = closeCard;\n btnDismiss.onclick = closeCard;\n backdrop.onclick = (e) => {\n if (e.target === backdrop) closeCard();\n };\n\n btnResolve.onclick = () => {\n if (note.status === 'OPEN') {\n this.transport.send({ type: 'resolve_note', noteId: note.id });\n } else {\n this.transport.send({ type: 'reopen_note', noteId: note.id });\n }\n closeCard();\n };\n\n btnDelete.onclick = () => {\n this.transport.send({ type: 'delete_note', noteId: note.id });\n closeCard();\n };\n\n root.appendChild(backdrop);\n }\n\n private setupListeners(): void {\n // 1. Mouse move: hover highlight in element mode or with Alt key\n const onMouseMove = (e: MouseEvent) => {\n if (this.modalOverlay || this.cardOverlay || this.isDraggingRegion || this.activeMode === 'region') return;\n\n // Don't highlight elements if mouse is over our own inspector UI\n const path = e.composedPath ? e.composedPath() : [];\n if (this.container && path.includes(this.container)) {\n this.hideHighlight();\n return;\n }\n\n if (e.altKey || this.activeMode === 'element') {\n const target = document.elementFromPoint(e.clientX, e.clientY) as HTMLElement | null;\n if (target && target !== this.container && !this.container?.contains(target)) {\n this.hoveredElement = target;\n this.updateHighlight(target);\n return;\n }\n }\n\n if (!e.altKey && this.activeMode !== 'element') {\n this.hideHighlight();\n }\n };\n\n // 2. Click: Alt+Click or Element mode click selects element and opens editor\n const onClick = (e: MouseEvent) => {\n if (this.modalOverlay || this.cardOverlay) return;\n\n // If clicking inside inspector toolbar or container, do NOT intercept\n const path = e.composedPath ? e.composedPath() : [];\n if (this.container && path.includes(this.container)) {\n return;\n }\n\n if (this.activeMode === 'region') return;\n\n if (e.altKey || this.activeMode === 'element') {\n e.preventDefault();\n e.stopPropagation();\n\n const target = (this.hoveredElement || document.elementFromPoint(e.clientX, e.clientY)) as HTMLElement | null;\n if (target && target !== this.container && !this.container?.contains(target)) {\n this.selectedElement = target;\n this.openNoteEditor(target, 'element');\n if (this.activeMode === 'element') {\n this.setMode('idle');\n }\n }\n }\n };\n\n // 3. Key handling: Escape cancels active modes, Alt release hides highlight\n const onKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Escape') {\n if (this.cardOverlay && this.cardOverlay.parentElement && this.shadowRoot) {\n this.shadowRoot.removeChild(this.cardOverlay);\n this.cardOverlay = null;\n } else if (this.activeMode === 'region' || this.activeMode === 'element') {\n this.setMode('idle');\n }\n }\n };\n\n const onKeyUp = (e: KeyboardEvent) => {\n if (e.key === 'Alt' && !this.modalOverlay && !this.cardOverlay && this.activeMode !== 'element') {\n this.hideHighlight();\n }\n };\n\n // 4. Scroll & resize: reposition markers accurately\n const onScrollOrResize = () => {\n requestAnimationFrame(() => {\n this.updateMarkerPositions();\n });\n };\n\n window.addEventListener('mousemove', onMouseMove, { capture: true, passive: true });\n window.addEventListener('click', onClick, { capture: true });\n window.addEventListener('keydown', onKeyDown, { capture: true });\n window.addEventListener('keyup', onKeyUp, { capture: true });\n window.addEventListener('scroll', onScrollOrResize, { capture: true, passive: true });\n window.addEventListener('resize', onScrollOrResize, { passive: true });\n\n this.cleanups.push(() => {\n window.removeEventListener('mousemove', onMouseMove, { capture: true });\n window.removeEventListener('click', onClick, { capture: true });\n window.removeEventListener('keydown', onKeyDown, { capture: true });\n window.removeEventListener('keyup', onKeyUp, { capture: true });\n window.removeEventListener('scroll', onScrollOrResize, { capture: true });\n window.removeEventListener('resize', onScrollOrResize);\n });\n }\n\n private showRegionOverlay(): void {\n const root = this.ensureContainer();\n if (!root) return;\n\n if (!this.regionOverlay) {\n this.regionOverlay = document.createElement('div');\n this.regionOverlay.className = 'bt-region-overlay';\n\n this.regionBox = document.createElement('div');\n this.regionBox.className = 'bt-region-box';\n this.regionBox.style.display = 'none';\n this.regionOverlay.appendChild(this.regionBox);\n\n // Top helper & cancel banner\n this.regionBanner = document.createElement('div');\n this.regionBanner.className = 'bt-region-banner';\n this.regionBanner.innerHTML = `\n <span>📐 Drag rectangle on screen to select region</span>\n <button class=\"bt-region-cancel-btn\" id=\"bt-region-cancel\">✕ Cancel (Esc)</button>\n `;\n\n const btnCancel = this.regionBanner.querySelector('#bt-region-cancel') as HTMLButtonElement;\n btnCancel.onclick = (e: MouseEvent) => {\n e.stopPropagation();\n this.setMode('idle');\n };\n\n this.regionOverlay.appendChild(this.regionBanner);\n\n // Right-click cancels region mode\n this.regionOverlay.oncontextmenu = (e: MouseEvent) => {\n e.preventDefault();\n this.setMode('idle');\n };\n\n // Drag events\n this.regionOverlay.onmousedown = (e: MouseEvent) => {\n const path = e.composedPath ? e.composedPath() : [];\n if (this.regionBanner && path.includes(this.regionBanner)) return;\n if (this.toolbarElement && path.includes(this.toolbarElement)) return;\n\n this.isDraggingRegion = true;\n this.dragStartX = e.clientX;\n this.dragStartY = e.clientY;\n if (this.regionBox) {\n this.regionBox.style.display = 'block';\n this.regionBox.style.left = `${e.clientX}px`;\n this.regionBox.style.top = `${e.clientY}px`;\n this.regionBox.style.width = '0px';\n this.regionBox.style.height = '0px';\n }\n };\n\n this.regionOverlay.onmousemove = (e: MouseEvent) => {\n if (!this.isDraggingRegion || !this.regionBox) return;\n\n const currentX = e.clientX;\n const currentY = e.clientY;\n\n const left = Math.min(this.dragStartX, currentX);\n const top = Math.min(this.dragStartY, currentY);\n const width = Math.abs(currentX - this.dragStartX);\n const height = Math.abs(currentY - this.dragStartY);\n\n this.regionBox.style.left = `${left}px`;\n this.regionBox.style.top = `${top}px`;\n this.regionBox.style.width = `${width}px`;\n this.regionBox.style.height = `${height}px`;\n\n let badge = this.regionBox.querySelector('.bt-region-badge') as HTMLDivElement | null;\n if (!badge) {\n badge = document.createElement('div');\n badge.className = 'bt-region-badge';\n this.regionBox.appendChild(badge);\n }\n badge.textContent = `Region: ${Math.round(width)} × ${Math.round(height)} px`;\n };\n\n this.regionOverlay.onmouseup = (e: MouseEvent) => {\n if (!this.isDraggingRegion) return;\n this.isDraggingRegion = false;\n\n const currentX = e.clientX;\n const currentY = e.clientY;\n const left = Math.min(this.dragStartX, currentX);\n const top = Math.min(this.dragStartY, currentY);\n const width = Math.abs(currentX - this.dragStartX);\n const height = Math.abs(currentY - this.dragStartY);\n\n if (width > 15 && height > 15) {\n this.selectedRegion = {\n x: Math.round(left),\n y: Math.round(top),\n width: Math.round(width),\n height: Math.round(height),\n };\n this.hideRegionOverlay();\n this.setMode('idle');\n this.openRegionNoteEditor(this.selectedRegion);\n } else {\n this.hideRegionOverlay();\n this.setMode('idle');\n }\n };\n }\n\n // Always ensure regionOverlay is mounted before toolbar so toolbar is interactable\n if (this.toolbarElement && this.toolbarElement.parentNode === root) {\n root.insertBefore(this.regionOverlay, this.toolbarElement);\n } else {\n root.appendChild(this.regionOverlay);\n }\n }\n\n private hideRegionOverlay(): void {\n this.isDraggingRegion = false;\n if (this.regionOverlay && this.regionOverlay.parentNode) {\n this.regionOverlay.parentNode.removeChild(this.regionOverlay);\n }\n if (this.regionBox) {\n this.regionBox.style.display = 'none';\n }\n }\n\n private updateHighlight(el: HTMLElement): void {\n const root = this.ensureContainer();\n if (!root || !this.highlightOverlay) return;\n\n const rect = el.getBoundingClientRect();\n this.highlightOverlay.style.display = 'block';\n this.highlightOverlay.style.top = `${rect.top}px`;\n this.highlightOverlay.style.left = `${rect.left}px`;\n this.highlightOverlay.style.width = `${rect.width}px`;\n this.highlightOverlay.style.height = `${rect.height}px`;\n\n const selector = getSemanticSelector(el);\n const badgeText = `${selector} · ${Math.round(rect.width)}×${Math.round(rect.height)}`;\n\n let badge = this.highlightOverlay.querySelector('.bt-badge') as HTMLDivElement | null;\n if (!badge) {\n badge = document.createElement('div');\n badge.className = 'bt-badge';\n this.highlightOverlay.appendChild(badge);\n }\n badge.textContent = badgeText;\n }\n\n private hideHighlight(): void {\n if (this.highlightOverlay) {\n this.highlightOverlay.style.display = 'none';\n }\n }\n\n public openNoteEditor(el?: HTMLElement, noteType: 'element' | 'page' = 'element'): void {\n const root = this.ensureContainer();\n if (!root) return;\n\n const targetEl = el || document.body;\n this.selectedElement = targetEl;\n if (noteType === 'element') {\n this.updateHighlight(targetEl);\n }\n\n this.renderNoteModal({\n title: 'Add Visual Note',\n modeBadge: noteType.toUpperCase(),\n pillText:\n noteType === 'page'\n ? `Page Viewport: ${window.innerWidth} × ${window.innerHeight} px`\n : `${getSemanticSelector(targetEl)} (${Math.round(targetEl.getBoundingClientRect().width)}×${Math.round(targetEl.getBoundingClientRect().height)}) · Viewport: ${window.innerWidth}×${window.innerHeight}`,\n onSave: async (message) => {\n await this.saveVisualNote(targetEl, message, noteType);\n },\n });\n }\n\n public openRegionNoteEditor(region: RegionContext): void {\n this.renderNoteModal({\n title: 'Add Region Note',\n modeBadge: 'REGION',\n pillText: `Selected Area: x:${region.x}, y:${region.y} (${region.width} × ${region.height} px)`,\n onSave: async (message) => {\n await this.saveRegionVisualNote(region, message);\n },\n });\n }\n\n private renderNoteModal(options: {\n title: string;\n modeBadge: string;\n pillText: string;\n onSave: (message: string) => Promise<void>;\n }): void {\n const root = this.ensureContainer();\n if (!root) return;\n\n // Remove existing modal if any\n if (this.modalOverlay && this.modalOverlay.parentElement) {\n this.modalOverlay.parentElement.removeChild(this.modalOverlay);\n this.modalOverlay = null;\n }\n\n const backdrop = document.createElement('div');\n backdrop.className = 'bt-modal-backdrop';\n this.modalOverlay = backdrop;\n\n const badgeClass = `bt-badge-${options.modeBadge.toLowerCase()}`;\n const icon = options.modeBadge === 'REGION' ? '📐' : options.modeBadge === 'PAGE' ? '📄' : '🎯';\n const isMac = typeof navigator !== 'undefined' && /Mac|iPod|iPhone|iPad/.test(navigator.platform);\n\n backdrop.innerHTML = `\n <div class=\"bt-modal\">\n <div class=\"bt-modal-header\">\n <div class=\"bt-modal-title\">\n <span>📝 ${options.title}</span>\n <span class=\"bt-mode-badge ${badgeClass}\">${options.modeBadge}</span>\n </div>\n <button class=\"bt-close-btn\" id=\"btn-close\" title=\"Close (Esc)\">✕</button>\n </div>\n <div class=\"bt-target-pill\" title=\"${options.pillText}\">\n <span>${icon}</span>\n <span class=\"bt-pill-content\">${options.pillText}</span>\n </div>\n <textarea class=\"bt-textarea\" placeholder=\"Describe the layout issue, styling bug, or note for AI agent...\" autofocus></textarea>\n <div class=\"bt-modal-footer\">\n <div class=\"bt-kbd-hint\">\n <kbd>${isMac ? '⌘' : 'Ctrl'}+Enter</kbd> save · <kbd>Esc</kbd> cancel\n </div>\n <div class=\"bt-modal-actions\">\n <button class=\"bt-btn bt-btn-cancel\" id=\"btn-cancel\">Cancel</button>\n <button class=\"bt-btn bt-btn-save\" id=\"btn-save\">Save Note</button>\n </div>\n </div>\n </div>\n `;\n\n const textarea = backdrop.querySelector('textarea') as HTMLTextAreaElement;\n const btnClose = backdrop.querySelector('#btn-close') as HTMLButtonElement;\n const btnCancel = backdrop.querySelector('#btn-cancel') as HTMLButtonElement;\n const btnSave = backdrop.querySelector('#btn-save') as HTMLButtonElement;\n\n const closeModal = () => {\n if (this.modalOverlay) {\n root.removeChild(this.modalOverlay);\n this.modalOverlay = null;\n this.hideHighlight();\n this.hideRegionOverlay();\n }\n };\n\n btnClose.onclick = closeModal;\n btnCancel.onclick = closeModal;\n\n backdrop.onclick = (e: MouseEvent) => {\n if (e.target === backdrop) {\n closeModal();\n }\n };\n\n const submitNote = async () => {\n const message = textarea.value.trim();\n if (!message) return;\n\n btnSave.textContent = 'Saving...';\n btnSave.disabled = true;\n\n try {\n await options.onSave(message);\n } finally {\n closeModal();\n }\n };\n\n btnSave.onclick = submitNote;\n\n textarea.onkeydown = (e: KeyboardEvent) => {\n if (e.key === 'Enter' && (e.metaKey || e.ctrlKey || !e.shiftKey)) {\n e.preventDefault();\n submitNote();\n }\n if (e.key === 'Escape') {\n closeModal();\n }\n };\n\n root.appendChild(backdrop);\n setTimeout(() => textarea?.focus(), 50);\n }\n\n public async saveVisualNote(targetEl: HTMLElement, message: string, noteType: 'element' | 'page' = 'element'): Promise<void> {\n const rect = targetEl.getBoundingClientRect();\n const selector = noteType === 'page' ? 'body' : getSemanticSelector(targetEl);\n\n // 1. Capture screenshot via screenshotDriver\n let screenshotDataUrl: string | undefined;\n try {\n const snap = await this.screenshotDriver.captureElement(targetEl);\n if (snap.ok) {\n screenshotDataUrl = snap.dataUrl;\n }\n } catch {\n // Defensive\n }\n\n // 2. Extract DOM Context\n const elementContext = this.extractElementContext(targetEl);\n\n // 3. Extract Target\n const target: NoteTarget = {\n selector,\n boundingRect: {\n x: Math.round(rect.x),\n y: Math.round(rect.y),\n width: Math.round(rect.width),\n height: Math.round(rect.height),\n top: Math.round(rect.top),\n left: Math.round(rect.left),\n bottom: Math.round(rect.bottom),\n right: Math.round(rect.right),\n },\n visible: rect.width > 0 && rect.height > 0,\n confidence: selector.startsWith('[data-test') ? 'high' : selector.startsWith('#') ? 'medium' : 'low',\n };\n\n const notePayload = {\n type: 'create_note',\n sessionId: this.transport.getSessionId() || '',\n noteType,\n message,\n route: window.location.pathname + window.location.search,\n url: window.location.href,\n viewport: {\n width: window.innerWidth,\n height: window.innerHeight,\n devicePixelRatio: window.devicePixelRatio || 1,\n },\n scroll: {\n scrollX: window.scrollX,\n scrollY: window.scrollY,\n },\n target,\n elementContext,\n screenshot: screenshotDataUrl,\n timestamp: Date.now(),\n };\n\n this.transport.send(notePayload);\n if (this.options.onNoteCreated) {\n this.options.onNoteCreated(notePayload as any);\n }\n }\n\n public async saveRegionVisualNote(region: RegionContext, message: string): Promise<void> {\n // 1. Capture full page screenshot and crop to region\n let screenshotDataUrl: string | undefined;\n try {\n const snap = await this.screenshotDriver.captureElement(document.body || document.documentElement);\n if (snap.ok && snap.dataUrl) {\n screenshotDataUrl = await this.cropDataUrl(snap.dataUrl, region);\n }\n } catch {\n // Defensive\n }\n\n const notePayload = {\n type: 'create_note',\n sessionId: this.transport.getSessionId() || '',\n noteType: 'region',\n message,\n route: window.location.pathname + window.location.search,\n url: window.location.href,\n viewport: {\n width: window.innerWidth,\n height: window.innerHeight,\n devicePixelRatio: window.devicePixelRatio || 1,\n },\n scroll: {\n scrollX: window.scrollX,\n scrollY: window.scrollY,\n },\n region,\n screenshot: screenshotDataUrl,\n timestamp: Date.now(),\n };\n\n this.transport.send(notePayload);\n if (this.options.onNoteCreated) {\n this.options.onNoteCreated(notePayload as any);\n }\n }\n\n private async cropDataUrl(dataUrl: string, region: RegionContext): Promise<string> {\n return new Promise((resolve) => {\n const img = new Image();\n img.onload = () => {\n try {\n const canvas = document.createElement('canvas');\n canvas.width = region.width;\n canvas.height = region.height;\n const ctx = canvas.getContext('2d');\n if (!ctx) {\n resolve(dataUrl);\n return;\n }\n\n const dpr = window.devicePixelRatio || 1;\n ctx.drawImage(\n img,\n region.x * dpr,\n region.y * dpr,\n region.width * dpr,\n region.height * dpr,\n 0,\n 0,\n region.width,\n region.height\n );\n resolve(canvas.toDataURL('image/webp', 0.9));\n } catch {\n resolve(dataUrl);\n }\n };\n img.onerror = () => resolve(dataUrl);\n img.src = dataUrl;\n });\n }\n\n private extractElementContext(el: HTMLElement): ElementContext {\n const selector = getSemanticSelector(el);\n const tag = el.tagName.toLowerCase();\n\n // Attributes (sanitize passwords/tokens)\n const attributes: Record<string, string> = {};\n for (let i = 0; i < el.attributes.length; i++) {\n const attr = el.attributes[i];\n if (attr.name === 'value' && (el as HTMLInputElement).type === 'password') {\n attributes[attr.name] = '[REDACTED]';\n } else {\n attributes[attr.name] = attr.value;\n }\n }\n\n // Clone element to sanitize inner sensitive fields\n let outerHTML = '';\n try {\n const clone = el.cloneNode(true) as HTMLElement;\n for (const passInput of Array.from(clone.querySelectorAll('input[type=\"password\"]'))) {\n passInput.setAttribute('value', '[REDACTED]');\n }\n outerHTML = truncate(clone.outerHTML, 10240); // 10 KB max\n } catch {\n outerHTML = truncate(el.outerHTML, 10240);\n }\n\n let parent: { selector: string; tag: string } | undefined;\n if (el.parentElement && el.parentElement !== document.body) {\n parent = {\n selector: getSemanticSelector(el.parentElement),\n tag: el.parentElement.tagName.toLowerCase(),\n };\n }\n\n return {\n selector,\n tag,\n attributes,\n outerHTML,\n innerText: truncate(el.textContent?.trim(), 200),\n parent,\n };\n }\n\n public destroy(): void {\n for (const cleanup of this.cleanups) {\n try {\n cleanup();\n } catch {}\n }\n this.cleanups = [];\n\n if (this.container && this.container.parentElement) {\n this.container.parentElement.removeChild(this.container);\n }\n this.container = null;\n this.shadowRoot = null;\n this.toolbarElement = null;\n this.regionOverlay = null;\n this.regionBox = null;\n this.regionBanner = null;\n this.markersContainer = null;\n this.modalOverlay = null;\n this.cardOverlay = null;\n }\n}\n","import type {\n Breadcrumb,\n ClientEventMessage,\n ConsoleEvent,\n ElementSummary,\n NavigationEvent,\n NetworkEvent,\n RuntimeErrorEvent,\n} from '../../core/src/index.js';\nimport { BreadcrumbBuffer } from './breadcrumbs.js';\nimport { ClientCommandHandler } from './commands/handler.js';\nimport type { BrowserDiagClientOptions } from './config.js';\nimport { DEFAULT_OPTIONS } from './config.js';\nimport { setupConsoleInterceptors } from './interceptors/console.js';\nimport { setupInteractionInterceptors } from './interceptors/interaction.js';\nimport { setupNavigationInterceptors } from './interceptors/navigation.js';\nimport { setupNetworkInterceptors } from './interceptors/network.js';\nimport { setupRuntimeInterceptors } from './interceptors/runtime.js';\nimport { BrowserScriptScreenshotDriver } from './screenshot/browser-script-driver.js';\nimport type { ScreenshotDriver } from './screenshot/driver.js';\nimport { WebSocketTransport } from './transport/websocket.js';\nimport { NoteInspector } from './notes/inspector.js';\n\nexport class BrowserTrackClient {\n public options: Required<Omit<BrowserDiagClientOptions, 'notes'>> & { notes: Required<NonNullable<BrowserDiagClientOptions['notes']>> };\n private breadcrumbs: BreadcrumbBuffer;\n private transport: WebSocketTransport;\n private screenshotDriver: ScreenshotDriver;\n private commandHandler: ClientCommandHandler;\n private inspector?: NoteInspector;\n private lastElement: ElementSummary | undefined;\n private currentRoute = '/';\n private cleanups: (() => void)[] = [];\n private isInitialized = false;\n\n constructor(options: BrowserDiagClientOptions = {}) {\n this.options = {\n ...DEFAULT_OPTIONS,\n ...options,\n notes: {\n ...DEFAULT_OPTIONS.notes,\n ...(options.notes || {}),\n },\n };\n this.breadcrumbs = new BreadcrumbBuffer(this.options.maxBreadcrumbs);\n this.transport = new WebSocketTransport({\n url: this.options.daemonUrl,\n projectId: this.options.projectId,\n debug: this.options.debug,\n });\n this.screenshotDriver = new BrowserScriptScreenshotDriver();\n this.commandHandler = new ClientCommandHandler(this.screenshotDriver);\n this.transport.setCommandHandler(this.commandHandler);\n\n if (this.options.notes.enabled) {\n this.inspector = new NoteInspector(this.transport, this.screenshotDriver, {\n shortcut: this.options.notes.shortcut,\n maskSelectors: this.options.notes.maskSelectors,\n });\n }\n }\n\n public init(): this {\n if (this.isInitialized || typeof window === 'undefined') return this;\n this.isInitialized = true;\n\n try {\n this.currentRoute = window.location.pathname + window.location.search;\n } catch {\n this.currentRoute = '/';\n }\n\n // 1. Connect WebSocket\n this.transport.connect();\n\n // 2. Setup Runtime error interceptor\n if (this.options.captureErrors) {\n const cleanupRuntime = setupRuntimeInterceptors(async (errEvent) => {\n await this.handleRuntimeError(errEvent);\n });\n this.cleanups.push(cleanupRuntime);\n }\n\n // 3. Setup Console interceptor\n if (this.options.captureConsole) {\n const cleanupConsole = setupConsoleInterceptors(async (consoleEvent) => {\n await this.handleConsole(consoleEvent);\n });\n this.cleanups.push(cleanupConsole);\n }\n\n // 4. Setup Network interceptor\n if (this.options.captureNetwork) {\n const cleanupNetwork = setupNetworkInterceptors((netEvent) => {\n this.handleNetwork(netEvent);\n });\n this.cleanups.push(cleanupNetwork);\n }\n\n // 5. Setup Navigation interceptor\n if (this.options.captureNavigation) {\n const cleanupNav = setupNavigationInterceptors((navEvent) => {\n this.handleNavigation(navEvent);\n });\n this.cleanups.push(cleanupNav);\n }\n\n // 6. Setup Interaction interceptor\n if (this.options.captureInteractions) {\n const cleanupInteraction = setupInteractionInterceptors((breadcrumb, elSummary) => {\n if (elSummary) {\n this.lastElement = elSummary;\n }\n this.breadcrumbs.add(breadcrumb);\n });\n this.cleanups.push(cleanupInteraction);\n }\n\n // 7. Setup Visual Note Inspector\n if (this.inspector) {\n this.inspector.init();\n }\n\n return this;\n }\n\n public openNoteEditor(el?: HTMLElement, noteType: 'element' | 'page' = 'element'): void {\n if (this.inspector) {\n this.inspector.openNoteEditor(el, noteType);\n }\n }\n\n public startRegionSelection(): void {\n if (this.inspector) {\n this.inspector.setMode('region');\n }\n }\n\n public startElementSelection(): void {\n if (this.inspector) {\n this.inspector.setMode('element');\n }\n }\n\n public setInspectMode(mode: 'element' | 'region' | 'page' | 'idle'): void {\n if (this.inspector) {\n this.inspector.setMode(mode);\n }\n }\n\n public async createNote(targetEl: HTMLElement, message: string, noteType: 'element' | 'page' = 'element'): Promise<void> {\n if (this.inspector) {\n await this.inspector.saveVisualNote(targetEl, message, noteType);\n }\n }\n\n private async handleRuntimeError(errorEvent: RuntimeErrorEvent): Promise<void> {\n // Add to breadcrumbs\n this.breadcrumbs.add({\n type: 'error',\n category: 'runtime',\n message: `${errorEvent.errorType}: ${errorEvent.message}`,\n timestamp: errorEvent.timestamp,\n level: 'error',\n data: {\n filename: errorEvent.filename,\n lineno: errorEvent.lineno,\n colno: errorEvent.colno,\n },\n });\n\n let screenshotDataUrl: string | undefined;\n if (this.options.onErrorScreenshot && this.lastElement?.selector) {\n try {\n const snap = await this.screenshotDriver.captureSelector(this.lastElement.selector);\n if (snap.ok) {\n screenshotDataUrl = snap.dataUrl;\n }\n } catch {\n // Defensive\n }\n }\n\n this.sendEvent('runtime_error', errorEvent, screenshotDataUrl);\n }\n\n private async handleConsole(consoleEvent: ConsoleEvent): Promise<void> {\n this.breadcrumbs.add({\n type: 'console',\n category: 'console',\n message: `console.${consoleEvent.level}: ${consoleEvent.message}`,\n timestamp: consoleEvent.timestamp,\n level: consoleEvent.level === 'error' ? 'error' : consoleEvent.level === 'warn' ? 'warn' : 'info',\n });\n\n if (consoleEvent.level === 'error' || consoleEvent.level === 'warn') {\n this.sendEvent('console', consoleEvent);\n }\n }\n\n private handleNetwork(netEvent: NetworkEvent): void {\n const isError = (netEvent.status && netEvent.status >= 400) || !!netEvent.error;\n const msg = `${netEvent.method} ${netEvent.url} -> ${netEvent.status || 'ERR'} (${netEvent.durationMs}ms)`;\n\n this.breadcrumbs.add({\n type: netEvent.id?.startsWith('xhr') ? 'xhr' : 'fetch',\n category: 'network',\n message: msg,\n timestamp: netEvent.timestamp,\n level: isError ? 'error' : 'info',\n data: {\n status: netEvent.status,\n durationMs: netEvent.durationMs,\n error: netEvent.error,\n aborted: netEvent.aborted,\n },\n });\n\n this.sendEvent('fetch', netEvent);\n }\n\n private handleNavigation(navEvent: NavigationEvent): void {\n this.currentRoute = navEvent.to;\n this.breadcrumbs.add({\n type: 'navigation',\n category: 'navigation',\n message: `navigate ${navEvent.to} (${navEvent.type})`,\n timestamp: navEvent.timestamp,\n level: 'info',\n data: { from: navEvent.from, to: navEvent.to, type: navEvent.type },\n });\n\n this.sendEvent('navigation', navEvent);\n }\n\n private sendEvent(eventType: any, payload: any, screenshotDataUrl?: string): void {\n if (typeof window === 'undefined') return;\n\n const message: ClientEventMessage & { screenshot?: string } = {\n type: 'event',\n sessionId: this.transport.getSessionId() || '',\n eventType,\n payload,\n breadcrumbs: this.breadcrumbs.getRecent(),\n lastElement: this.lastElement,\n route: this.currentRoute,\n url: window.location.href,\n title: document.title,\n timestamp: Date.now(),\n screenshot: screenshotDataUrl,\n };\n\n this.transport.send(message);\n }\n\n public getBreadcrumbs(): Breadcrumb[] {\n return this.breadcrumbs.getRecent();\n }\n\n public getLastElement(): ElementSummary | undefined {\n return this.lastElement;\n }\n\n public destroy(): void {\n for (const cleanup of this.cleanups) {\n try {\n cleanup();\n } catch {}\n }\n this.cleanups = [];\n this.transport.destroy();\n if (this.inspector) {\n this.inspector.destroy();\n }\n this.breadcrumbs.clear();\n this.isInitialized = false;\n }\n}\n","import { BrowserTrackClient } from './client.js';\nimport type { BrowserDiagClientOptions } from './config.js';\n\nexport * from './client.js';\nexport * from './config.js';\nexport * from './breadcrumbs.js';\nexport * from './screenshot/driver.js';\nexport * from './screenshot/browser-script-driver.js';\nexport * from './notes/inspector.js';\n\nlet defaultClient: BrowserTrackClient | null = null;\n\n/**\n * Initializes the BrowserTrack client.\n */\nexport function init(options: BrowserDiagClientOptions = {}): BrowserTrackClient {\n if (defaultClient) {\n return defaultClient;\n }\n\n defaultClient = new BrowserTrackClient(options);\n defaultClient.init();\n return defaultClient;\n}\n\nexport function getClient(): BrowserTrackClient | null {\n return defaultClient;\n}\n\n// Auto-initialize when injected via <script src=\"...\">\nif (typeof window !== 'undefined') {\n (window as any).__BROWSERTRACK__ = {\n init,\n getClient,\n };\n\n // Auto-start by default in browser if not explicitly disabled\n try {\n const currentScript = document.currentScript;\n const autoInit = currentScript?.getAttribute('data-auto-init') !== 'false';\n const daemonUrl = currentScript?.getAttribute('data-daemon-url') || undefined;\n const projectId = currentScript?.getAttribute('data-project-id') || undefined;\n\n if (autoInit) {\n init({ daemonUrl, projectId });\n }\n } catch {\n // If auto-start fails, don't crash\n }\n}\n"],"mappings":"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AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;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","names":["init"]}