browsertrack 0.0.1 → 0.1.0

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 (101) hide show
  1. package/README.md +143 -0
  2. package/dist/chunk-6A7FFDIB.js +221 -0
  3. package/dist/chunk-6A7FFDIB.js.map +1 -0
  4. package/dist/chunk-ANMR5WBH.js +659 -0
  5. package/dist/chunk-ANMR5WBH.js.map +1 -0
  6. package/dist/chunk-BSKNG4V7.js +1199 -0
  7. package/dist/chunk-BSKNG4V7.js.map +1 -0
  8. package/dist/chunk-X7C5CHBO.js +2080 -0
  9. package/dist/chunk-X7C5CHBO.js.map +1 -0
  10. package/dist/chunk-ZLNGOOH2.js +554 -0
  11. package/dist/chunk-ZLNGOOH2.js.map +1 -0
  12. package/dist/cli/index.js +2829 -0
  13. package/dist/cli/index.js.map +1 -0
  14. package/dist/client/index.cjs +2218 -0
  15. package/dist/client/index.d.ts +197 -0
  16. package/dist/client/index.js +20 -0
  17. package/dist/client/index.js.map +1 -0
  18. package/dist/client.iife.js +309 -0
  19. package/dist/core/index.d.ts +78 -0
  20. package/dist/core/index.js +31 -0
  21. package/dist/core/index.js.map +1 -0
  22. package/dist/daemon/index.d.ts +58 -0
  23. package/dist/daemon/index.js +32 -0
  24. package/dist/daemon/index.js.map +1 -0
  25. package/dist/engine-DKloFjvs.d.ts +157 -0
  26. package/dist/index.d.ts +10 -0
  27. package/dist/index.js +50 -0
  28. package/dist/index.js.map +1 -0
  29. package/dist/mcp/index.d.ts +11 -0
  30. package/dist/mcp/index.js +12 -0
  31. package/dist/mcp/index.js.map +1 -0
  32. package/dist/notes-CBvN91Wf.d.ts +260 -0
  33. package/dist/projects-CY8ungMt.d.ts +99 -0
  34. package/dist/server-CN-se8td.d.ts +55 -0
  35. package/examples/test-app/index.html +299 -0
  36. package/package.json +52 -7
  37. package/packages/cli/src/index.ts +413 -0
  38. package/packages/client/package.json +28 -0
  39. package/packages/client/src/breadcrumbs.ts +30 -0
  40. package/packages/client/src/client.ts +278 -0
  41. package/packages/client/src/commands/handler.ts +301 -0
  42. package/packages/client/src/config.ts +37 -0
  43. package/packages/client/src/index.ts +50 -0
  44. package/packages/client/src/interceptors/console.ts +68 -0
  45. package/packages/client/src/interceptors/interaction.ts +119 -0
  46. package/packages/client/src/interceptors/navigation.ts +93 -0
  47. package/packages/client/src/interceptors/network.ts +165 -0
  48. package/packages/client/src/interceptors/runtime.ts +65 -0
  49. package/packages/client/src/notes/inspector.ts +943 -0
  50. package/packages/client/src/screenshot/browser-script-driver.ts +192 -0
  51. package/packages/client/src/screenshot/driver.ts +14 -0
  52. package/packages/client/src/transport/websocket.ts +179 -0
  53. package/packages/client/tsconfig.json +8 -0
  54. package/packages/core/dist/index.d.ts +317 -0
  55. package/packages/core/dist/index.js +221 -0
  56. package/packages/core/package.json +23 -0
  57. package/packages/core/src/fingerprint.ts +120 -0
  58. package/packages/core/src/index.ts +9 -0
  59. package/packages/core/src/redaction.ts +139 -0
  60. package/packages/core/src/selector.ts +77 -0
  61. package/packages/core/src/types/commands.ts +101 -0
  62. package/packages/core/src/types/events.ts +108 -0
  63. package/packages/core/src/types/incidents.ts +54 -0
  64. package/packages/core/src/types/notes.ts +106 -0
  65. package/packages/core/src/types/probes.ts +44 -0
  66. package/packages/core/src/types/projects.ts +20 -0
  67. package/packages/core/tsconfig.json +8 -0
  68. package/packages/daemon/src/config.ts +29 -0
  69. package/packages/daemon/src/incidents/engine.ts +211 -0
  70. package/packages/daemon/src/index.ts +18 -0
  71. package/packages/daemon/src/notes/engine.ts +92 -0
  72. package/packages/daemon/src/notes/verification.ts +191 -0
  73. package/packages/daemon/src/server/daemon.ts +112 -0
  74. package/packages/daemon/src/server/http.ts +165 -0
  75. package/packages/daemon/src/server/ws.ts +175 -0
  76. package/packages/daemon/src/session/manager.ts +126 -0
  77. package/packages/daemon/src/storage/db.ts +733 -0
  78. package/packages/daemon/src/storage/screenshot-store.ts +49 -0
  79. package/packages/daemon/src/verification/engine.ts +264 -0
  80. package/packages/mcp/src/handlers.ts +398 -0
  81. package/packages/mcp/src/index.ts +3 -0
  82. package/packages/mcp/src/server.ts +86 -0
  83. package/packages/mcp/src/tools.ts +236 -0
  84. package/src/index.ts +4 -0
  85. package/test/client/interceptors.test.ts +69 -0
  86. package/test/core/fingerprint.test.ts +53 -0
  87. package/test/core/notes.test.ts +66 -0
  88. package/test/core/redaction.test.ts +48 -0
  89. package/test/daemon/incident-engine.test.ts +98 -0
  90. package/test/daemon/notes-storage.test.ts +130 -0
  91. package/test/daemon/notes-verification.test.ts +135 -0
  92. package/test/daemon/storage.test.ts +123 -0
  93. package/test/daemon/verification-engine.test.ts +88 -0
  94. package/test/e2e/daemon-mcp-e2e.test.ts +153 -0
  95. package/test/e2e/visual-notes-e2e.test.ts +205 -0
  96. package/test/mcp/handlers.test.ts +116 -0
  97. package/test/mcp/notes.test.ts +107 -0
  98. package/tsconfig.base.json +17 -0
  99. package/tsconfig.json +26 -0
  100. package/tsup.config.ts +54 -0
  101. package/vitest.config.ts +9 -0
@@ -0,0 +1,299 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>BrowserTrack Fixture App</title>
7
+ <style>
8
+ :root {
9
+ --bg: #0f172a;
10
+ --card-bg: #1e293b;
11
+ --text: #f8fafc;
12
+ --muted: #94a3b8;
13
+ --primary: #3b82f6;
14
+ --danger: #ef4444;
15
+ --warning: #f59e0b;
16
+ --success: #10b981;
17
+ --border: #334155;
18
+ }
19
+
20
+ * { box-sizing: border-box; margin: 0; padding: 0; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; }
21
+ body { background-color: var(--bg); color: var(--text); padding: 2rem; display: flex; flex-direction: column; align-items: center; min-height: 100vh; }
22
+ .container { max-width: 800px; width: 100%; display: flex; flex-direction: column; gap: 1.5rem; }
23
+
24
+ header { border-bottom: 1px solid var(--border); padding-bottom: 1rem; display: flex; justify-content: space-between; align-items: center; }
25
+ h1 { font-size: 1.5rem; font-weight: 600; display: flex; align-items: center; gap: 0.5rem; }
26
+ .badge { font-size: 0.75rem; padding: 0.2rem 0.6rem; border-radius: 999px; background: rgba(59, 130, 246, 0.2); color: var(--primary); border: 1px solid var(--primary); }
27
+
28
+ .card { background: var(--card-bg); border: 1px solid var(--border); border-radius: 0.75rem; padding: 1.25rem; }
29
+ .card-title { font-size: 1rem; font-weight: 600; margin-bottom: 0.75rem; color: var(--muted); text-transform: uppercase; letter-spacing: 0.05em; }
30
+
31
+ .grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 0.75rem; }
32
+
33
+ button {
34
+ padding: 0.75rem 1rem;
35
+ border-radius: 0.5rem;
36
+ border: 1px solid transparent;
37
+ font-weight: 500;
38
+ cursor: pointer;
39
+ transition: all 0.15s ease-in-out;
40
+ display: flex;
41
+ align-items: center;
42
+ justify-content: center;
43
+ gap: 0.5rem;
44
+ font-size: 0.9rem;
45
+ }
46
+ button:hover { filter: brightness(1.1); transform: translateY(-1px); }
47
+ button:active { transform: translateY(0); }
48
+
49
+ .btn-danger { background: rgba(239, 68, 68, 0.15); color: #fca5a5; border-color: rgba(239, 68, 68, 0.3); }
50
+ .btn-warning { background: rgba(245, 158, 11, 0.15); color: #fcd34d; border-color: rgba(245, 158, 11, 0.3); }
51
+ .btn-primary { background: rgba(59, 130, 246, 0.15); color: #93c5fd; border-color: rgba(59, 130, 246, 0.3); }
52
+ .btn-success { background: rgba(16, 185, 129, 0.15); color: #6ee7b7; border-color: rgba(16, 185, 129, 0.3); }
53
+
54
+ .element-card {
55
+ border: 2px dashed rgba(239, 68, 68, 0.4);
56
+ background: rgba(239, 68, 68, 0.05);
57
+ padding: 1rem;
58
+ border-radius: 0.5rem;
59
+ margin-top: 0.5rem;
60
+ display: flex;
61
+ justify-content: space-between;
62
+ align-items: center;
63
+ }
64
+
65
+ #log-panel {
66
+ background: #090d16;
67
+ border: 1px solid var(--border);
68
+ border-radius: 0.5rem;
69
+ padding: 0.75rem;
70
+ font-family: monospace;
71
+ font-size: 0.8rem;
72
+ max-height: 180px;
73
+ overflow-y: auto;
74
+ color: #38bdf8;
75
+ }
76
+ .log-item { margin-bottom: 0.3rem; }
77
+ </style>
78
+
79
+ <!-- BrowserTrack Client Auto-Injection -->
80
+ <script src="http://127.0.0.1:7331/client.js"></script>
81
+ </head>
82
+ <body>
83
+ <div class="container">
84
+ <header>
85
+ <h1>🧪 BrowserTrack Fixture App</h1>
86
+ <span class="badge" id="status-badge">Connecting...</span>
87
+ </header>
88
+
89
+ <!-- Error Triggers Card -->
90
+ <div class="card">
91
+ <div class="card-title">1. Runtime & Console Triggers</div>
92
+ <div class="grid">
93
+ <button class="btn-danger" id="btn-throw-error" data-testid="throw-error-btn">
94
+ 💥 Throw Error
95
+ </button>
96
+ <button class="btn-danger" id="btn-unhandled-promise" data-testid="unhandled-promise-btn">
97
+ ⚠️ Unhandled Promise
98
+ </button>
99
+ <button class="btn-warning" id="btn-console-error" data-testid="console-error-btn">
100
+ 📝 Console Error
101
+ </button>
102
+ <button class="btn-warning" id="btn-console-warn" data-testid="console-warn-btn">
103
+ ⚠️ Console Warn
104
+ </button>
105
+ </div>
106
+ </div>
107
+
108
+ <!-- Network Triggers Card -->
109
+ <div class="card">
110
+ <div class="card-title">2. Network & Async Triggers</div>
111
+ <div class="grid">
112
+ <button class="btn-danger" id="btn-500-request" data-testid="fail-500-btn">
113
+ 🌐 500 Network Request
114
+ </button>
115
+ <button class="btn-danger" id="btn-delayed-error" data-testid="delayed-error-btn">
116
+ ⏱️ Delayed Error (1s)
117
+ </button>
118
+ <button class="btn-primary" id="btn-navigate" data-testid="navigate-btn">
119
+ 🔀 Navigate /users/42
120
+ </button>
121
+ </div>
122
+ </div>
123
+
124
+ <!-- Element Error with Visual Card -->
125
+ <div class="card">
126
+ <div class="card-title">3. Element Target & Verification Probe</div>
127
+ <div class="element-card" id="user-card" data-testid="user-card">
128
+ <div>
129
+ <strong id="user-name">User: John Doe (#42)</strong>
130
+ <p style="color: var(--muted); font-size: 0.85rem;" id="user-status">Status: Active</p>
131
+ </div>
132
+ <button class="btn-danger" id="btn-element-error" data-testid="element-error-btn">
133
+ Trigger Element Error
134
+ </button>
135
+ </div>
136
+ </div>
137
+
138
+ <!-- Visual Notes & Layout Cards -->
139
+ <div class="card">
140
+ <div class="card-title">4. Visual Notes & Responsive Layout (Alt+Click to Annotate)</div>
141
+ <p style="font-size: 0.85rem; color: var(--muted); margin-bottom: 0.75rem;">
142
+ Hold <kbd style="background:#334155;padding:2px 5px;border-radius:3px;">Alt</kbd> and click any element below to leave a visual note for coding agents.
143
+ </p>
144
+
145
+ <!-- Overflowing Stats Card (Simulating mobile layout issue) -->
146
+ <div class="stats-card" id="stats-banner" data-testid="stats-banner" style="background:#1e1b4b;border:1px solid #4338ca;padding:1rem;border-radius:0.5rem;display:flex;gap:1.5rem;min-width:600px;overflow-x:auto;">
147
+ <div>
148
+ <div style="font-size:0.75rem;color:#a5b4fc;">MONTHLY ACTIVE USERS</div>
149
+ <div style="font-size:1.4rem;font-weight:700;color:#e0e7ff;">142,890</div>
150
+ </div>
151
+ <div>
152
+ <div style="font-size:0.75rem;color:#a5b4fc;">PAGEVIEWS (30D)</div>
153
+ <div style="font-size:1.4rem;font-weight:700;color:#e0e7ff;">1,249,000</div>
154
+ </div>
155
+ <div>
156
+ <div style="font-size:0.75rem;color:#a5b4fc;">SERVER RESPONSE TIME</div>
157
+ <div style="font-size:1.4rem;font-weight:700;color:#e0e7ff;">42ms</div>
158
+ </div>
159
+ </div>
160
+
161
+ <!-- Sensitive Input masking demonstration -->
162
+ <div style="margin-top:1rem;display:flex;gap:0.75rem;align-items:center;flex-wrap:wrap;">
163
+ <input type="password" id="admin-pass" value="super-secret-password" data-testid="admin-pass-input" style="background:#0f172a;color:#f8fafc;border:1px solid #334155;border-radius:4px;padding:6px 10px;font-size:12px;" />
164
+ <button class="btn-primary" id="btn-manual-note" style="padding:6px 12px;font-size:12px;">
165
+ 📝 Note on Stats
166
+ </button>
167
+ <button class="btn-primary" id="btn-select-element" style="padding:6px 12px;font-size:12px;background:rgba(59,130,246,0.25);">
168
+ 🎯 Element Seç
169
+ </button>
170
+ <button class="btn-primary" id="btn-select-region" style="padding:6px 12px;font-size:12px;background:rgba(56,189,248,0.25);color:#38bdf8;">
171
+ 📐 Alan / Bölge Seç (Drag)
172
+ </button>
173
+ <button class="btn-primary" id="btn-page-note" style="padding:6px 12px;font-size:12px;background:rgba(168,85,247,0.25);color:#c084fc;">
174
+ 📄 Tüm Sayfa
175
+ </button>
176
+ </div>
177
+ </div>
178
+
179
+ <!-- Live Event Log -->
180
+ <div class="card">
181
+ <div class="card-title">Event Log</div>
182
+ <div id="log-panel">
183
+ <div class="log-item">[Init] Fixture app loaded. Ready for diagnostics testing.</div>
184
+ </div>
185
+ </div>
186
+ </div>
187
+
188
+ <script>
189
+ const logPanel = document.getElementById('log-panel');
190
+ function appendLog(msg) {
191
+ const div = document.createElement('div');
192
+ div.className = 'log-item';
193
+ div.textContent = `[${new Date().toLocaleTimeString()}] ${msg}`;
194
+ logPanel.appendChild(div);
195
+ logPanel.scrollTop = logPanel.scrollHeight;
196
+ }
197
+
198
+ // 1. Throw Error
199
+ document.getElementById('btn-throw-error').addEventListener('click', () => {
200
+ appendLog('Throwing synchronous Error');
201
+ throw new TypeError("Cannot read properties of undefined (reading 'calculateTotal')");
202
+ });
203
+
204
+ // 2. Unhandled Promise
205
+ document.getElementById('btn-unhandled-promise').addEventListener('click', () => {
206
+ appendLog('Triggering Unhandled Promise Rejection');
207
+ new Promise((_, reject) => {
208
+ reject(new Error("API authentication session expired (token expired)"));
209
+ });
210
+ });
211
+
212
+ // 3. Console Error
213
+ document.getElementById('btn-console-error').addEventListener('click', () => {
214
+ appendLog('Logging console.error');
215
+ console.error("Failed to render UserProfileComponent: missing user data", { id: 42, role: 'developer' });
216
+ });
217
+
218
+ // 4. Console Warn
219
+ document.getElementById('btn-console-warn').addEventListener('click', () => {
220
+ appendLog('Logging console.warn');
221
+ console.warn("Component UserCard is using deprecated prop 'legacyFormat'");
222
+ });
223
+
224
+ // 5. 500 Network Request
225
+ document.getElementById('btn-500-request').addEventListener('click', async () => {
226
+ appendLog('Sending fetch request to failing endpoint');
227
+ try {
228
+ await fetch('http://127.0.0.1:7331/api/invalid-endpoint-trigger-404?token=secret123');
229
+ } catch (e) {
230
+ console.error('Fetch threw error:', e);
231
+ }
232
+ });
233
+
234
+ // 6. Delayed Error
235
+ document.getElementById('btn-delayed-error').addEventListener('click', () => {
236
+ appendLog('Scheduled delayed error in 1000ms');
237
+ setTimeout(() => {
238
+ throw new ReferenceError("UserProfileService is not defined at background poll");
239
+ }, 1000);
240
+ });
241
+
242
+ // 7. SPA Navigation
243
+ document.getElementById('btn-navigate').addEventListener('click', () => {
244
+ const newUrl = '/users/42';
245
+ history.pushState({ page: 42 }, 'User Profile', newUrl);
246
+ appendLog(`Navigated history.pushState to ${newUrl}`);
247
+ });
248
+
249
+ // 8. Element Error
250
+ document.getElementById('btn-element-error').addEventListener('click', () => {
251
+ appendLog('Triggering error on user-card element');
252
+ throw new Error("Element user-card encountered unexpected state rendering card");
253
+ });
254
+
255
+ // 9. Manual Visual Note triggers
256
+ document.getElementById('btn-manual-note').addEventListener('click', () => {
257
+ appendLog('Opening visual note editor on stats-banner');
258
+ const stats = document.getElementById('stats-banner');
259
+ if (window.__BROWSERTRACK__?.getClient()) {
260
+ window.__BROWSERTRACK__.getClient().openNoteEditor(stats);
261
+ }
262
+ });
263
+
264
+ document.getElementById('btn-select-element').addEventListener('click', () => {
265
+ appendLog('Activated Element selection mode (click any element)');
266
+ if (window.__BROWSERTRACK__?.getClient()) {
267
+ window.__BROWSERTRACK__.getClient().startElementSelection();
268
+ }
269
+ });
270
+
271
+ document.getElementById('btn-select-region').addEventListener('click', () => {
272
+ appendLog('Activated Region selection mode (drag rectangle on screen)');
273
+ if (window.__BROWSERTRACK__?.getClient()) {
274
+ window.__BROWSERTRACK__.getClient().startRegionSelection();
275
+ }
276
+ });
277
+
278
+ document.getElementById('btn-page-note').addEventListener('click', () => {
279
+ appendLog('Opening full page note editor');
280
+ if (window.__BROWSERTRACK__?.getClient()) {
281
+ window.__BROWSERTRACK__.getClient().openNoteEditor(document.body, 'page');
282
+ }
283
+ });
284
+
285
+ // Check client status
286
+ setInterval(() => {
287
+ const badge = document.getElementById('status-badge');
288
+ if (window.__BROWSERTRACK__ && window.__BROWSERTRACK__.getClient()) {
289
+ badge.textContent = '🟢 BrowserTrack Active';
290
+ badge.style.borderColor = 'var(--success)';
291
+ badge.style.color = 'var(--success)';
292
+ badge.style.background = 'rgba(16, 185, 129, 0.2)';
293
+ } else {
294
+ badge.textContent = '⚪ Daemon Offline (Safe)';
295
+ }
296
+ }, 1000);
297
+ </script>
298
+ </body>
299
+ </html>
package/package.json CHANGED
@@ -1,12 +1,57 @@
1
1
  {
2
2
  "name": "browsertrack",
3
- "version": "0.0.1",
4
- "description": "",
5
- "license": "ISC",
6
- "author": "",
7
- "type": "commonjs",
8
- "main": "index.js",
3
+ "version": "0.1.0",
4
+ "description": "Local browser diagnostics + MCP bridge for coding agents",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "bin": {
9
+ "browsertrack": "./dist/cli/index.js",
10
+ "browserdiag": "./dist/cli/index.js"
11
+ },
12
+ "exports": {
13
+ ".": {
14
+ "types": "./dist/index.d.ts",
15
+ "import": "./dist/index.js"
16
+ },
17
+ "./client": {
18
+ "types": "./dist/client/index.d.ts",
19
+ "import": "./dist/client/index.js",
20
+ "require": "./dist/client/index.cjs"
21
+ },
22
+ "./core": {
23
+ "types": "./dist/core/index.d.ts",
24
+ "import": "./dist/core/index.js"
25
+ },
26
+ "./daemon": {
27
+ "types": "./dist/daemon/index.d.ts",
28
+ "import": "./dist/daemon/index.js"
29
+ },
30
+ "./mcp": {
31
+ "types": "./dist/mcp/index.d.ts",
32
+ "import": "./dist/mcp/index.js"
33
+ }
34
+ },
9
35
  "scripts": {
10
- "test": "echo \"Error: no test specified\" && exit 1"
36
+ "build": "tsup",
37
+ "dev": "tsup --watch",
38
+ "test": "vitest run",
39
+ "test:watch": "vitest",
40
+ "clean": "rm -rf dist"
41
+ },
42
+ "dependencies": {
43
+ "@modelcontextprotocol/sdk": "^1.6.1",
44
+ "@zumer/snapdom": "^2.24.15",
45
+ "better-sqlite3": "^11.8.1",
46
+ "commander": "^13.1.0",
47
+ "ws": "^8.18.1"
48
+ },
49
+ "devDependencies": {
50
+ "@types/better-sqlite3": "^7.6.12",
51
+ "@types/node": "^20.17.19",
52
+ "@types/ws": "^8.5.14",
53
+ "tsup": "^8.3.6",
54
+ "typescript": "^5.7.3",
55
+ "vitest": "^2.1.8"
11
56
  }
12
57
  }