browsertrack 0.2.1 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/AGENTS.md +9 -6
  2. package/README.md +2 -0
  3. package/dist/{chunk-INXDWPJW.js → chunk-4HRLW6YF.js} +161 -106
  4. package/dist/chunk-4HRLW6YF.js.map +1 -0
  5. package/dist/{chunk-3HOXPTM2.js → chunk-AYSVE6NG.js} +808 -53
  6. package/dist/chunk-AYSVE6NG.js.map +1 -0
  7. package/dist/{chunk-6VA7GBAO.js → chunk-QRZ57ME3.js} +70 -2
  8. package/dist/chunk-QRZ57ME3.js.map +1 -0
  9. package/dist/{chunk-464D4U2U.js → chunk-TWEYRBDU.js} +279 -43
  10. package/dist/chunk-TWEYRBDU.js.map +1 -0
  11. package/dist/cli/index.js +1038 -545
  12. package/dist/cli/index.js.map +1 -1
  13. package/dist/client/index.cjs +184 -104
  14. package/dist/client/index.js +2 -2
  15. package/dist/client.iife.js +9 -9
  16. package/dist/core/index.d.ts +24 -1
  17. package/dist/core/index.js +9 -1
  18. package/dist/daemon/index.d.ts +2 -2
  19. package/dist/daemon/index.js +6 -8
  20. package/dist/index.d.ts +2 -2
  21. package/dist/index.js +14 -7
  22. package/dist/mcp/index.d.ts +1 -1
  23. package/dist/mcp/index.js +7 -4
  24. package/dist/{server-DiVmTrIR.d.ts → server-DjV7RWQM.d.ts} +9 -1
  25. package/docs/cli.md +4 -1
  26. package/docs/getting-started.md +60 -6
  27. package/docs/mcp-reference.md +42 -0
  28. package/package.json +1 -1
  29. package/packages/cli/src/index.ts +247 -151
  30. package/packages/client/src/interceptors/navigation.ts +38 -26
  31. package/packages/client/src/interceptors/network.ts +22 -17
  32. package/packages/client/src/notes/inspector.ts +81 -48
  33. package/packages/client/src/source/resolver.ts +9 -3
  34. package/packages/client/src/transport/websocket.ts +23 -18
  35. package/packages/core/src/index.ts +1 -0
  36. package/packages/core/src/safety.ts +86 -0
  37. package/packages/daemon/src/server/daemon.ts +7 -1
  38. package/packages/daemon/src/server/http.ts +125 -5
  39. package/packages/daemon/src/server/ws.ts +33 -29
  40. package/packages/daemon/src/storage/db.ts +57 -35
  41. package/packages/mcp/src/handlers.ts +114 -45
  42. package/packages/mcp/src/server.ts +202 -2
  43. package/test/core/safety.test.ts +106 -0
  44. package/test/daemon/storage.test.ts +36 -0
  45. package/test/e2e/daemon-mcp-e2e.test.ts +10 -0
  46. package/test/mcp/auto-start.test.ts +87 -0
  47. package/dist/chunk-3HOXPTM2.js.map +0 -1
  48. package/dist/chunk-464D4U2U.js.map +0 -1
  49. package/dist/chunk-6VA7GBAO.js.map +0 -1
  50. package/dist/chunk-7OCOQGDN.js +0 -635
  51. package/dist/chunk-7OCOQGDN.js.map +0 -1
  52. package/dist/chunk-INXDWPJW.js.map +0 -1
@@ -83,4 +83,27 @@ declare function getSemanticSelector(element: HTMLElement | Element, options?: S
83
83
  */
84
84
  declare function truncate(str: string | undefined | null, maxLength?: number): string;
85
85
 
86
- export { BROWSER_SECURITY_RULES, type FingerprintInput, REDACTED_PLACEHOLDER, SENSITIVE_KEY_PATTERNS, SENSITIVE_QUERY_PARAMS, type SelectorOptions, computeFingerprint, extractSourceFromStack, getSemanticSelector, isSensitiveKey, normalizeErrorMessage, normalizeSourceFile, redactHeaders, redactSensitiveData, redactUrl, truncate };
86
+ /**
87
+ * BrowserTrack Safety & Error-Resilience Utilities
88
+ * Provides bulletproof try/catch wrappers, circular-safe JSON serialization, and defensive helpers.
89
+ */
90
+ /**
91
+ * Safely parses a JSON string with fallback. Never throws.
92
+ */
93
+ declare function safeJsonParse<T>(raw: any, fallback: T): T;
94
+ /**
95
+ * Safely serializes an object to JSON, handling circular references and non-serializable values.
96
+ * Never throws "TypeError: Converting circular structure to JSON".
97
+ */
98
+ declare function safeJsonStringify(val: any, fallback?: string): string;
99
+ /**
100
+ * Executes a synchronous function within an isolated try/catch block.
101
+ * Returns the function result, or fallback if an exception was thrown.
102
+ */
103
+ declare function safeExecute<T>(fn: () => T, fallback: T, onError?: (err: any) => void): T;
104
+ /**
105
+ * Executes an asynchronous promise or async function safely without unhandled rejection.
106
+ */
107
+ declare function safeAsync<T>(action: Promise<T> | (() => Promise<T>), fallback: T, onError?: (err: any) => void): Promise<T>;
108
+
109
+ export { BROWSER_SECURITY_RULES, type FingerprintInput, REDACTED_PLACEHOLDER, SENSITIVE_KEY_PATTERNS, SENSITIVE_QUERY_PARAMS, type SelectorOptions, computeFingerprint, extractSourceFromStack, getSemanticSelector, isSensitiveKey, normalizeErrorMessage, normalizeSourceFile, redactHeaders, redactSensitiveData, redactUrl, safeAsync, safeExecute, safeJsonParse, safeJsonStringify, truncate };
@@ -12,10 +12,14 @@ import {
12
12
  redactHeaders,
13
13
  redactSensitiveData,
14
14
  redactUrl,
15
+ safeAsync,
16
+ safeExecute,
17
+ safeJsonParse,
18
+ safeJsonStringify,
15
19
  standardRules,
16
20
  truncate,
17
21
  visulimaRedact
18
- } from "../chunk-6VA7GBAO.js";
22
+ } from "../chunk-QRZ57ME3.js";
19
23
  export {
20
24
  BROWSER_SECURITY_RULES,
21
25
  REDACTED_PLACEHOLDER,
@@ -30,6 +34,10 @@ export {
30
34
  redactHeaders,
31
35
  redactSensitiveData,
32
36
  redactUrl,
37
+ safeAsync,
38
+ safeExecute,
39
+ safeJsonParse,
40
+ safeJsonStringify,
33
41
  standardRules,
34
42
  truncate,
35
43
  visulimaRedact
@@ -1,4 +1,4 @@
1
- import { S as StorageDB, b as ScreenshotStore, a as SessionManager, c as NotesEngine, V as VerificationEngine, N as NoteVerificationEngine } from '../engine-CmchnMDq.js';
1
+ import { S as StorageDB, b as ScreenshotStore, a as SessionManager, V as VerificationEngine, N as NoteVerificationEngine, c as NotesEngine } from '../engine-CmchnMDq.js';
2
2
  import { c as ClientEventMessage } from '../commands-fjuqKzkm.js';
3
3
  import { I as Incident } from '../projects-DB7S312i.js';
4
4
  import http from 'node:http';
@@ -25,7 +25,7 @@ declare class IncidentEngine {
25
25
  private handleErrorEvent;
26
26
  }
27
27
 
28
- declare function createHttpHandler(db: StorageDB, sessionManager: SessionManager, baseScreenshotsDir: string): (req: http.IncomingMessage, res: http.ServerResponse) => void;
28
+ declare function createHttpHandler(db: StorageDB, sessionManager: SessionManager, baseScreenshotsDir: string, verificationEngine?: VerificationEngine, noteVerificationEngine?: NoteVerificationEngine): (req: http.IncomingMessage, res: http.ServerResponse) => Promise<void>;
29
29
 
30
30
  declare function setupWebSocketServer(wss: WebSocketServer, db: StorageDB, sessionManager: SessionManager, incidentEngine: IncidentEngine, notesEngine?: NotesEngine, maxEventsPerSession?: number, verbose?: boolean): void;
31
31
 
@@ -1,20 +1,18 @@
1
1
  import {
2
2
  BrowserTrackDaemon,
3
3
  IncidentEngine,
4
- createDaemon,
5
- createHttpHandler,
6
- setupWebSocketServer
7
- } from "../chunk-7OCOQGDN.js";
8
- import "../chunk-6VA7GBAO.js";
9
- import {
10
4
  NoteVerificationEngine,
11
5
  NotesEngine,
12
6
  ScreenshotStore,
13
7
  SessionManager,
14
8
  StorageDB,
15
9
  VerificationEngine,
16
- getDaemonConfig
17
- } from "../chunk-3HOXPTM2.js";
10
+ createDaemon,
11
+ createHttpHandler,
12
+ getDaemonConfig,
13
+ setupWebSocketServer
14
+ } from "../chunk-AYSVE6NG.js";
15
+ import "../chunk-QRZ57ME3.js";
18
16
  export {
19
17
  BrowserTrackDaemon,
20
18
  IncidentEngine,
package/dist/index.d.ts CHANGED
@@ -1,9 +1,9 @@
1
1
  export { B as Breadcrumb, C as CaptureElementParams, a as CaptureElementResult, b as ClientCommand, c as ClientEventMessage, d as CommandResponse, e as CommandType, f as ComponentSourceInfo, g as ConsoleEvent, h as ConsoleLevel, D as DOMRectJson, E as ElementContext, i as ElementStyleResult, j as ElementSummary, k as EventType, H as HelloMessage, N as NavigateParams, l as NavigationEvent, m as NetworkEvent, n as NoteStatus, o as NoteTarget, p as NoteType, q as NoteVerificationResult, O as OverflowCheckResult, P as PageStateResult, Q as QueryElementParams, r as QueryElementResult, R as RegionContext, s as ReloadParams, t as RuntimeErrorEvent, S as ScenarioDetail, u as ScenarioOverview, v as ScrollContext, V as ViewportContext, w as VisualNote } from './commands-fjuqKzkm.js';
2
2
  export { I as Incident, a as IncidentOccurrence, b as IncidentSeverity, c as IncidentSource, d as IncidentStatus, P as ProbeResult, e as ProbeType, f as Project, S as Session, V as VerificationProbe, g as VerificationRecipe, h as VerificationResult } from './projects-DB7S312i.js';
3
- export { BROWSER_SECURITY_RULES, FingerprintInput, REDACTED_PLACEHOLDER, SENSITIVE_KEY_PATTERNS, SENSITIVE_QUERY_PARAMS, SelectorOptions, computeFingerprint, extractSourceFromStack, getSemanticSelector, isSensitiveKey, normalizeErrorMessage, normalizeSourceFile, redactHeaders, redactSensitiveData, redactUrl, truncate } from './core/index.js';
3
+ export { BROWSER_SECURITY_RULES, FingerprintInput, REDACTED_PLACEHOLDER, SENSITIVE_KEY_PATTERNS, SENSITIVE_QUERY_PARAMS, SelectorOptions, computeFingerprint, extractSourceFromStack, getSemanticSelector, isSensitiveKey, normalizeErrorMessage, normalizeSourceFile, redactHeaders, redactSensitiveData, redactUrl, safeAsync, safeExecute, safeJsonParse, safeJsonStringify, truncate } from './core/index.js';
4
4
  export { BrowserTrackClient, getClient, init as initClient } from './client/index.js';
5
5
  export { BrowserTrackDaemon, createDaemon } from './daemon/index.js';
6
- export { c as createMcpServer } from './server-DiVmTrIR.js';
6
+ export { c as createMcpServer } from './server-DjV7RWQM.js';
7
7
  export { Rules, standardRules, redact as visulimaRedact } from '@visulima/redact';
8
8
  import './engine-CmchnMDq.js';
9
9
  import 'ws';
package/dist/index.js CHANGED
@@ -2,11 +2,14 @@ import {
2
2
  BrowserTrackClient,
3
3
  getClient,
4
4
  init
5
- } from "./chunk-INXDWPJW.js";
5
+ } from "./chunk-4HRLW6YF.js";
6
+ import {
7
+ createMcpServer
8
+ } from "./chunk-TWEYRBDU.js";
6
9
  import {
7
10
  BrowserTrackDaemon,
8
11
  createDaemon
9
- } from "./chunk-7OCOQGDN.js";
12
+ } from "./chunk-AYSVE6NG.js";
10
13
  import {
11
14
  BROWSER_SECURITY_RULES,
12
15
  REDACTED_PLACEHOLDER,
@@ -21,14 +24,14 @@ import {
21
24
  redactHeaders,
22
25
  redactSensitiveData,
23
26
  redactUrl,
27
+ safeAsync,
28
+ safeExecute,
29
+ safeJsonParse,
30
+ safeJsonStringify,
24
31
  standardRules,
25
32
  truncate,
26
33
  visulimaRedact
27
- } from "./chunk-6VA7GBAO.js";
28
- import {
29
- createMcpServer
30
- } from "./chunk-464D4U2U.js";
31
- import "./chunk-3HOXPTM2.js";
34
+ } from "./chunk-QRZ57ME3.js";
32
35
  export {
33
36
  BROWSER_SECURITY_RULES,
34
37
  BrowserTrackClient,
@@ -49,6 +52,10 @@ export {
49
52
  redactHeaders,
50
53
  redactSensitiveData,
51
54
  redactUrl,
55
+ safeAsync,
56
+ safeExecute,
57
+ safeJsonParse,
58
+ safeJsonStringify,
52
59
  standardRules,
53
60
  truncate,
54
61
  visulimaRedact
@@ -1,5 +1,5 @@
1
1
  import { Tool } from '@modelcontextprotocol/sdk/types.js';
2
- export { M as McpContext, a as McpServerOptions, c as createMcpServer, h as handleToolCall } from '../server-DiVmTrIR.js';
2
+ export { M as McpContext, a as McpServerOptions, c as createMcpServer, h as handleToolCall, i as isDaemonRunning } from '../server-DjV7RWQM.js';
3
3
  import '@modelcontextprotocol/sdk/server/index.js';
4
4
  import '../engine-CmchnMDq.js';
5
5
  import '../commands-fjuqKzkm.js';
package/dist/mcp/index.js CHANGED
@@ -1,12 +1,15 @@
1
1
  import {
2
2
  TOOLS,
3
3
  createMcpServer,
4
- handleToolCall
5
- } from "../chunk-464D4U2U.js";
6
- import "../chunk-3HOXPTM2.js";
4
+ handleToolCall,
5
+ isDaemonRunning
6
+ } from "../chunk-TWEYRBDU.js";
7
+ import "../chunk-AYSVE6NG.js";
8
+ import "../chunk-QRZ57ME3.js";
7
9
  export {
8
10
  TOOLS,
9
11
  createMcpServer,
10
- handleToolCall
12
+ handleToolCall,
13
+ isDaemonRunning
11
14
  };
12
15
  //# sourceMappingURL=index.js.map
@@ -10,9 +10,14 @@ interface McpContext {
10
10
  }
11
11
  declare function handleToolCall(name: string, args: any, ctx: McpContext): Promise<any>;
12
12
 
13
+ declare function isDaemonRunning(host: string, port: number): Promise<boolean>;
13
14
  interface McpServerOptions {
14
15
  dbPath?: string;
15
16
  context?: Partial<McpContext>;
17
+ autoStartDaemon?: boolean;
18
+ port?: number;
19
+ host?: string;
20
+ detached?: boolean;
16
21
  }
17
22
  declare function createMcpServer(options?: McpServerOptions): {
18
23
  server: Server<{
@@ -49,7 +54,10 @@ declare function createMcpServer(options?: McpServerOptions): {
49
54
  } | undefined;
50
55
  } | undefined;
51
56
  }>;
57
+ ctx: McpContext;
58
+ ensureDaemon: () => Promise<void>;
59
+ stopDaemon(): Promise<void>;
52
60
  startStdio(): Promise<void>;
53
61
  };
54
62
 
55
- export { type McpContext as M, type McpServerOptions as a, createMcpServer as c, handleToolCall as h };
63
+ export { type McpContext as M, type McpServerOptions as a, createMcpServer as c, handleToolCall as h, isDaemonRunning as i };
package/docs/cli.md CHANGED
@@ -35,9 +35,12 @@ browsertrack clear # Wipe stored logs, screenshots, and incidents
35
35
 
36
36
  ### MCP Integration
37
37
  ```bash
38
- browsertrack mcp # Start Model Context Protocol server over stdio
38
+ browsertrack mcp # Start Model Context Protocol server over stdio (auto-boots singleton daemon if offline)
39
+ browsertrack mcp --no-daemon # Start MCP server without auto-booting background daemon
39
40
  ```
40
41
 
42
+ > **⚡ Singleton Daemon Lifecycle**: When starting `browsertrack mcp`, BrowserTrack automatically checks if the daemon is already running. If offline, it starts a single, persistent background daemon on `http://127.0.0.1:7331`. All IDE windows, workspaces, and sub-sessions share this single daemon without spawning duplicates or conflicting on ports.
43
+
41
44
  ---
42
45
 
43
46
  ## 📖 Documentation Commands (Docboot)
@@ -26,6 +26,8 @@ browsertrack start
26
26
 
27
27
  This will initialize the local server at `http://127.0.0.1:7331` (WebSocket bridge on `ws://127.0.0.1:7331`) and SQLite database at `~/.browsertrack/browsertrack.db`.
28
28
 
29
+ > **⚡ Zero-Config Auto-Start**: If you configure BrowserTrack via MCP in your AI coding editor (Cursor, Antigravity, Claude Desktop), you do **not** need to manually run `browsertrack start`. The MCP server automatically launches and manages the HTTP and WebSocket background daemon on port `7331`!
30
+
29
31
  ---
30
32
 
31
33
  ## 2. Connect Your Web Application
@@ -80,25 +82,77 @@ const client = new BrowserTrackClient({
80
82
 
81
83
  Add BrowserTrack MCP server to your AI editor configuration:
82
84
 
83
- ### Antigravity (`~/.gemini/antigravity-ide/mcp_config.json`)
85
+ ### Standard Configuration
84
86
  ```json
85
87
  {
86
88
  "mcpServers": {
87
89
  "browsertrack": {
88
- "command": "browsertrack",
89
- "args": ["mcp"]
90
+ "command": "npx",
91
+ "args": ["-y", "browsertrack@latest", "mcp"]
90
92
  }
91
93
  }
92
94
  }
93
95
  ```
94
96
 
95
- ### Cursor (`~/.cursor/mcp.json`) & Claude Code
97
+ ---
98
+
99
+ ### ⚠️ Troubleshooting: `executable file not found in $PATH`
100
+
101
+ If your editor throws an error like:
102
+ ```text
103
+ Error: exec: "browsertrack": executable file not found in $PATH
104
+ # or
105
+ Error: exec: "npx": executable file not found in $PATH
106
+ ```
107
+
108
+ #### Why does this happen?
109
+ GUI applications on macOS and Linux (Antigravity, Cursor, Claude Desktop, VS Code) are launched by the desktop window manager (such as `launchd` on macOS), **not** from your terminal shell. Therefore, they do **not** automatically source your `~/.zshrc`, `~/.bashrc`, or environment managers like **NVM**, **fnm**, **asdf**, **Volta**, or **Homebrew** (`/opt/homebrew/bin`).
110
+
111
+ #### Solutions:
112
+
113
+ ##### Option A: Use Absolute Path to `npx` with `PATH` environment (Recommended)
114
+ Find your `npx` and `node` bin directory in your terminal:
115
+ ```bash
116
+ which npx
117
+ # Example output: /Users/username/.nvm/versions/node/v20.19.5/bin/npx
118
+ ```
119
+
120
+ Configure your MCP config with the full path, the `-y` flag (to prevent interactive installation prompts from stalling stdio), and the `PATH` environment variable:
96
121
  ```json
97
122
  {
98
123
  "mcpServers": {
99
124
  "browsertrack": {
100
- "command": "npx",
101
- "args": ["browsertrack", "mcp"]
125
+ "command": "/Users/username/.nvm/versions/node/v20.19.5/bin/npx",
126
+ "args": ["-y", "browsertrack@latest", "mcp"],
127
+ "env": {
128
+ "PATH": "/Users/username/.nvm/versions/node/v20.19.5/bin:/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin"
129
+ }
130
+ }
131
+ }
132
+ }
133
+ ```
134
+
135
+ ##### Option B: Run Directly via Node (Fastest for Local Development)
136
+ If you are developing or running BrowserTrack locally, bypass `npx` completely and execute the CLI entry script directly with `node`:
137
+ ```json
138
+ {
139
+ "mcpServers": {
140
+ "browsertrack": {
141
+ "command": "/Users/username/.nvm/versions/node/v20.19.5/bin/node",
142
+ "args": ["/absolute/path/to/browsertrack/dist/cli/index.js", "mcp"]
143
+ }
144
+ }
145
+ }
146
+ ```
147
+
148
+ ##### Option C: Wrap with Login Shell (`/bin/zsh -lc`)
149
+ Use your interactive login shell to automatically source your `~/.zshrc` and all environment variables:
150
+ ```json
151
+ {
152
+ "mcpServers": {
153
+ "browsertrack": {
154
+ "command": "/bin/zsh",
155
+ "args": ["-lc", "npx -y browsertrack mcp"]
102
156
  }
103
157
  }
104
158
  }
@@ -8,6 +8,8 @@ order: 6
8
8
 
9
9
  BrowserTrack exposes 16 specialized Model Context Protocol (MCP) tools for AI agents.
10
10
 
11
+ > **⚡ Automatic Server Lifecycle**: When your IDE starts the MCP server (`browsertrack mcp`), BrowserTrack automatically checks if the background daemon is already running. If not, it **automatically starts the HTTP (`http://127.0.0.1:7331`) and WebSocket (`ws://127.0.0.1:7331`) server** in the background, so your browser can connect immediately with zero manual terminal commands. If you already have a running daemon, MCP seamlessly connects to it.
12
+
11
13
  ---
12
14
 
13
15
  ## 📋 Incidents & Error Diagnostics
@@ -139,3 +141,43 @@ Triggers closed-loop bug fix verification (reloads browser, evaluates probes, ca
139
141
  Retrieves latest verification result and before/after screenshots for an incident.
140
142
  - **Arguments**:
141
143
  - `incidentId` (`string`, *required*): The ID of the incident.
144
+
145
+ ---
146
+
147
+ ## ⚠️ Troubleshooting MCP Client Setup
148
+
149
+ If your AI editor fails to launch the MCP server with:
150
+ ```text
151
+ Error: exec: "browsertrack": executable file not found in $PATH
152
+ ```
153
+
154
+ This occurs because GUI applications (Cursor, Antigravity, VS Code, Claude Desktop) run without loading terminal shell rc files (`~/.zshrc`, `~/.bashrc`), leaving version managers like **NVM**, **fnm**, **asdf**, or **Homebrew** out of `$PATH`.
155
+
156
+ ### Recommended Fix
157
+ Specify the absolute path to `npx` (find it with `which npx`), include `-y`, and explicitly set `PATH`:
158
+
159
+ ```json
160
+ {
161
+ "mcpServers": {
162
+ "browsertrack": {
163
+ "command": "/Users/username/.nvm/versions/node/v20.19.5/bin/npx",
164
+ "args": ["-y", "browsertrack@latest", "mcp"],
165
+ "env": {
166
+ "PATH": "/Users/username/.nvm/versions/node/v20.19.5/bin:/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin"
167
+ }
168
+ }
169
+ }
170
+ }
171
+ ```
172
+
173
+ Or run directly via `node` for local projects:
174
+ ```json
175
+ {
176
+ "mcpServers": {
177
+ "browsertrack": {
178
+ "command": "/Users/username/.nvm/versions/node/v20.19.5/bin/node",
179
+ "args": ["/path/to/browsertrack/dist/cli/index.js", "mcp"]
180
+ }
181
+ }
182
+ }
183
+ ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "browsertrack",
3
- "version": "0.2.1",
3
+ "version": "0.2.2",
4
4
  "description": "Local browser diagnostics + MCP bridge for coding agents",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",