browser-devtools-mcp 0.2.27 → 0.3.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.
package/README.md CHANGED
@@ -127,8 +127,6 @@ Non-blocking debugging tools that capture snapshots without pausing execution. I
127
127
  - **Tracepoint**: Captures call stack, local variables, and async stack traces at a code location
128
128
  - **Logpoint**: Evaluates and logs expressions without full debug context (lightweight)
129
129
  - **Exceptionpoint**: Captures snapshots when exceptions occur (uncaught or all)
130
- - **Dompoint**: Monitors DOM mutations (subtree-modified, attribute-modified, node-removed)
131
- - **Netpoint**: Monitors network requests/responses matching a URL pattern
132
130
 
133
131
  **Core Operations (per probe type):**
134
132
  - `put-*`: Create a probe at a location
@@ -581,7 +579,7 @@ node-devtools-cli
581
579
  ├── run # Script execution commands
582
580
  │ └── js-in-node # Run JavaScript in the connected Node process
583
581
  └── debug # Debug commands
584
- ├── connect # Connect to Node.js process (pid, processName, port, containerId, etc.)
582
+ ├── connect # Connect to Node.js process (pid, processName, inspectorPort, containerId, etc.)
585
583
  ├── disconnect # Disconnect from current process
586
584
  ├── status # Show connection status
587
585
  ├── put-tracepoint # Set a tracepoint
@@ -618,8 +616,7 @@ browser-devtools-cli
618
616
  ├── update # Check for and install updates
619
617
  ├── navigation # Navigation commands
620
618
  │ ├── go-to # Navigate to a URL
621
- │ ├── go-back # Navigate backward
622
- │ ├── go-forward # Navigate forward
619
+ │ ├── go-back-or-forward # Navigate back or forward in history (direction: back | forward)
623
620
  │ └── reload # Reload the page
624
621
  ├── content # Content extraction commands
625
622
  │ ├── take-screenshot # Take a screenshot
@@ -662,36 +659,14 @@ browser-devtools-cli
662
659
  │ └── wait-for-network-idle # Wait for network idle
663
660
  ├── debug # Non-blocking debugging commands
664
661
  │ ├── put-tracepoint # Set a tracepoint (captures call stack)
665
- │ ├── remove-tracepoint # Remove a tracepoint
666
- │ ├── list-tracepoints # List all tracepoints
667
- │ ├── clear-tracepoints # Clear all tracepoints
662
+ │ ├── remove-probe # Remove a tracepoint, logpoint, or watch by ID (type + id)
663
+ │ ├── list-probes # List tracepoints, logpoints, and/or watches (optional types; omit to list all)
668
664
  │ ├── put-logpoint # Set a logpoint (evaluates expression)
669
- │ ├── remove-logpoint # Remove a logpoint
670
- │ ├── list-logpoints # List all logpoints
671
- │ ├── clear-logpoints # Clear all logpoints
672
665
  │ ├── put-exceptionpoint # Enable exception catching
673
- │ ├── put-dompoint # Set DOM mutation breakpoint
674
- │ ├── remove-dompoint # Remove a DOM breakpoint
675
- │ ├── list-dompoints # List all DOM breakpoints
676
- │ ├── clear-dompoints # Clear all DOM breakpoints
677
- │ ├── put-netpoint # Set network request breakpoint
678
- │ ├── remove-netpoint # Remove a network breakpoint
679
- │ ├── list-netpoints # List all network breakpoints
680
- │ ├── clear-netpoints # Clear all network breakpoints
681
666
  │ ├── add-watch # Add a watch expression
682
- │ ├── remove-watch # Remove a watch expression
683
- │ ├── list-watches # List all watch expressions
684
- │ ├── clear-watches # Clear all watch expressions
685
- │ ├── get-tracepoint-snapshots # Get tracepoint snapshots
686
- │ ├── clear-tracepoint-snapshots # Clear tracepoint snapshots
687
- │ ├── get-logpoint-snapshots # Get logpoint snapshots
688
- │ ├── clear-logpoint-snapshots # Clear logpoint snapshots
689
- │ ├── get-exceptionpoint-snapshots # Get exception snapshots
690
- │ ├── clear-exceptionpoint-snapshots # Clear exception snapshots
691
- │ ├── get-dompoint-snapshots # Get DOM mutation snapshots
692
- │ ├── clear-dompoint-snapshots # Clear DOM snapshots
693
- │ ├── get-netpoint-snapshots # Get network snapshots
694
- │ ├── clear-netpoint-snapshots # Clear network snapshots
667
+ │ ├── clear-probes # Clear tracepoints, logpoints, and/or watches (optional types; omit to clear all)
668
+ │ ├── get-probe-snapshots # Get tracepoint/logpoint/exceptionpoint snapshots (optional types; response: tracepointSnapshots, logpointSnapshots, exceptionpointSnapshots)
669
+ │ ├── clear-probe-snapshots # Clear tracepoint/logpoint/exceptionpoint snapshots (optional types; omit to clear all)
695
670
  │ └── status # Get debugging status
696
671
  └── figma # Figma integration commands
697
672
  └── compare-page-with-design
@@ -827,7 +802,7 @@ browser-devtools-cli tools list
827
802
  #
828
803
  # navigation:
829
804
  # go-to Navigate the browser to the given URL...
830
- # go-back Navigate back in browser history
805
+ # go-back-or-forward Navigate back or forward in history (direction: back | forward)
831
806
  # ...
832
807
 
833
808
  # Filter tools by domain
@@ -1131,7 +1106,7 @@ The server can be configured using environment variables. Configuration is divid
1131
1106
  | Variable | Description | Default |
1132
1107
  |----------|-------------|---------|
1133
1108
  | `NODE_CONSOLE_MESSAGES_BUFFER_SIZE` | Maximum console messages to buffer from Node.js process | `1000` |
1134
- | `NODE_INSPECTOR_HOST` | Inspector host for `debug_connect` when MCP runs in Docker (e.g. `host.docker.internal`). Use with host-mapped `port` so the MCP connects to the right address. | `127.0.0.1` |
1109
+ | `NODE_INSPECTOR_HOST` | Inspector host for `debug_connect` when MCP runs in Docker (e.g. `host.docker.internal`). Use with host-mapped `inspectorPort` so the MCP connects to the right address. | `127.0.0.1` |
1135
1110
  | `PLATFORM` | Platform to use: `browser` or `node` | `browser` |
1136
1111
 
1137
1112
  ### Browser Platform Configuration
@@ -1387,17 +1362,9 @@ The server can be configured using environment variables. Configuration is divid
1387
1362
  </details>
1388
1363
 
1389
1364
  <details>
1390
- <summary><code>navigation_go-back</code> - Navigates backward in browser history.</summary>
1365
+ <summary><code>navigation_go-back-or-forward</code> - Navigates back or forward in browser history.</summary>
1391
1366
 
1392
- **Parameters:** `timeout`, `waitUntil`, `includeSnapshot` (default true), `snapshotInteractiveOnly`, `snapshotCursorInteractive` — same semantics as navigation_go-to for snapshot/refs.
1393
-
1394
- **Returns:** `url`, `status`, `statusText`, `ok`; when includeSnapshot is true also `output` and `refs` (ARIA snapshot with refs).
1395
- </details>
1396
-
1397
- <details>
1398
- <summary><code>navigation_go-forward</code> - Navigates forward in browser history.</summary>
1399
-
1400
- **Parameters:** `timeout`, `waitUntil`, `includeSnapshot` (default true), `snapshotInteractiveOnly`, `snapshotCursorInteractive` — same semantics as navigation_go-to for snapshot/refs.
1367
+ **Parameters:** `direction` (required: `"back"` or `"forward"`), `timeout`, `waitUntil`, `includeSnapshot` (default true), `snapshotInteractiveOnly`, `snapshotCursorInteractive` — same semantics as navigation_go-to for snapshot/refs.
1401
1368
 
1402
1369
  **Returns:** `url`, `status`, `statusText`, `ok`; when includeSnapshot is true also `output` and `refs` (ARIA snapshot with refs).
1403
1370
  </details>
@@ -1675,13 +1642,13 @@ The server can be configured using environment variables. Configuration is divid
1675
1642
  - `output` (string): Includes the page URL, title, and a YAML-formatted accessibility tree
1676
1643
 
1677
1644
  **Usage:**
1678
- - Use in combination with `accessibility_take-ax-tree-snapshot` for comprehensive UI analysis
1645
+ - Use in combination with `a11y_take-ax-tree-snapshot` for comprehensive UI analysis
1679
1646
  - Provides semantic structure and accessibility roles
1680
1647
  - Helps identify accessibility issues and page hierarchy problems
1681
1648
  </details>
1682
1649
 
1683
1650
  <details>
1684
- <summary><code>accessibility_take-ax-tree-snapshot</code> - Captures a UI-focused snapshot by combining Chromium's Accessibility (AX) tree with runtime visual diagnostics.</summary>
1651
+ <summary><code>a11y_take-ax-tree-snapshot</code> - Captures a UI-focused snapshot by combining Chromium's Accessibility (AX) tree with runtime visual diagnostics.</summary>
1685
1652
 
1686
1653
  **Parameters:**
1687
1654
  - `roles` (array, optional): Optional role allowlist (button, link, textbox, checkbox, radio, combobox, switch, tab, menuitem, dialog, heading, listbox, listitem, option). If omitted, a built-in set of interactive roles is used
@@ -2007,6 +1974,52 @@ npm run build
2007
1974
  - `npm run inspector:http` - Run MCP Inspector (HTTP)
2008
1975
  - `npm run lint:check` - Check code formatting
2009
1976
  - `npm run lint:format` - Format code
1977
+ - `npm run tools:token-report` - Generate tool definition token consumption report (see below)
1978
+
1979
+ #### Tool definition token report
1980
+
1981
+ The script counts tokens for each tool’s MCP definition (name, description, inputSchema, outputSchema) using **gpt-tokenizer** (OpenAI-style BPE). Useful for understanding context size when clients load the tool list.
1982
+
1983
+ When run without `--platform`, **both browser and node** are measured (default). The script starts the MCP server separately for each platform (`PLATFORM=browser` then `PLATFORM=node`), connects as an MCP client, calls `tools/list` for each, and counts characters from the **actual payload** (so the report matches what clients receive per platform). **Requires a built server** (`npm run build`). Run from the repo root.
1984
+
1985
+ ```bash
1986
+ # Via npm (recommended): MCP-based, writes to docs/TOOL-DEFINITION-TOKENS.md
1987
+ npm run tools:token-report
1988
+ ```
1989
+
1990
+ **Options:**
1991
+
1992
+ | Option | Description |
1993
+ |--------|-------------|
1994
+ | *(default)* | Run server with output schema disabled (measure name + description + inputSchema only; Output schema column omitted); write to `docs/TOOL-DEFINITION-TOKENS.md` |
1995
+ | `--platform browser` or `--platform node` | Run only one platform (faster; report has a single section) |
1996
+ | `--output-schema` | Run server with output schema enabled (include output schema in measurement and table) |
1997
+ | `--no-output-schema` | Explicitly run without output schema (same as default) |
1998
+ | `--stdout` | Print report to stdout instead of writing to the default file |
1999
+ | `--output=path` or `-o path` | Write report to the given file path |
2000
+
2001
+ Examples:
2002
+
2003
+ ```bash
2004
+ # Default: measure without output schema, write to docs/TOOL-DEFINITION-TOKENS.md
2005
+ npm run tools:token-report
2006
+
2007
+ # Include output schema in the report
2008
+ npm run tools:token-report -- --output-schema
2009
+
2010
+ # Print to console
2011
+ npm run tools:token-report -- --stdout
2012
+
2013
+ # Only browser or only node platform
2014
+ npm run tools:token-report -- --platform browser
2015
+ npm run tools:token-report -- --platform node
2016
+
2017
+ # Write to a custom file
2018
+ npm run tools:token-report -- --output=./my-report.md
2019
+ npm run tools:token-report -- -o reports/tokens.md
2020
+ ```
2021
+
2022
+ The generated report is [docs/TOOL-DEFINITION-TOKENS.md](docs/TOOL-DEFINITION-TOKENS.md).
2010
2023
 
2011
2024
  ## Use Cases
2012
2025
 
@@ -2017,7 +2030,7 @@ The Node platform enables AI assistants to:
2017
2030
  1. **Debug Node.js APIs**: Connect to a running server, set tracepoints at API handlers, capture request/response context
2018
2031
  2. **Inspect Backend State**: Use watch expressions and tracepoints to understand variable values, call stacks
2019
2032
  3. **Catch Exceptions**: Enable exception breakpoints to capture uncaught errors with full stack traces
2020
- 4. **Docker Debugging**: Connect to Node.js processes running inside Docker containers. When the MCP runs in a container, set `NODE_INSPECTOR_HOST=host.docker.internal` and pass the host-mapped debug port to `debug_connect` (e.g. `debug_connect({ containerName: "my-service", port: 30019 })`).
2033
+ 4. **Docker Debugging**: Connect to Node.js processes running inside Docker containers. When the MCP runs in a container, set `NODE_INSPECTOR_HOST=host.docker.internal` and pass the host-mapped debug port to `debug_connect` (e.g. `debug_connect({ containerName: "my-service", inspectorPort: 30019 })`).
2021
2034
 
2022
2035
  ### Browser Platform Use Cases
2023
2036
 
@@ -2040,7 +2053,7 @@ The Browser platform enables AI assistants to:
2040
2053
  3. Take a screenshot with `content_take-screenshot` to see the current state
2041
2054
  4. Check console messages with `o11y_get-console-messages` for errors
2042
2055
  5. Monitor HTTP requests with `o11y_get-http-requests` to see API calls
2043
- 6. Capture accessibility snapshots with `a11y_take-aria-snapshot` and `accessibility_take-ax-tree-snapshot` to understand page structure
2056
+ 6. Capture accessibility snapshots with `a11y_take-aria-snapshot` and `a11y_take-ax-tree-snapshot` to understand page structure
2044
2057
  7. Compare page with Figma design using `figma_compare-page-with-design` to validate design parity
2045
2058
  8. Interact with elements using `interaction_click`, `interaction_fill`, etc.
2046
2059
  9. Extract content using `content_get-as-html` or `content_get-as-text`
package/SECURITY.md CHANGED
@@ -66,8 +66,6 @@ Browser DevTools MCP provides powerful browser automation capabilities. Users sh
66
66
  - Tracepoints capture call stack and local variables (may include sensitive data)
67
67
  - Logpoints evaluate expressions in page context
68
68
  - Exception snapshots capture error state and stack traces
69
- - Network monitors (netpoints) capture request/response bodies
70
- - DOM monitors (dompoints) capture element mutations
71
69
  - Snapshots are stored in memory and cleared on session end
72
70
 
73
71
  ### API Keys and Secrets
@@ -1,12 +1,12 @@
1
1
  #!/usr/bin/env node
2
- import{platformInfo}from"../core-GIHDFCBF.js";import{AMAZON_BEDROCK_ENABLE,AMAZON_BEDROCK_IMAGE_EMBED_MODEL_ID,AMAZON_BEDROCK_TEXT_EMBED_MODEL_ID,AMAZON_BEDROCK_VISION_MODEL_ID,AWS_PROFILE,AWS_REGION,DAEMON_PORT,DAEMON_SESSION_IDLE_CHECK_SECONDS,DAEMON_SESSION_IDLE_SECONDS,FIGMA_ACCESS_TOKEN,FIGMA_API_BASE_URL,OTEL_ENABLE,OTEL_EXPORTER_HTTP_URL,OTEL_EXPORTER_TYPE,OTEL_SERVICE_NAME,OTEL_SERVICE_VERSION}from"../core-247YVH6X.js";import{Command,Option}from"commander";import{ZodFirstPartyTypeKind}from"zod";function _unwrapZodType(zodType){let current=zodType,isOptional=!1,defaultValue;for(;;){let typeName=current._def.typeName;if(typeName===ZodFirstPartyTypeKind.ZodOptional)isOptional=!0,current=current._def.innerType;else if(typeName===ZodFirstPartyTypeKind.ZodDefault)isOptional=!0,defaultValue=current._def.defaultValue(),current=current._def.innerType;else if(typeName===ZodFirstPartyTypeKind.ZodNullable)isOptional=!0,current=current._def.innerType;else break}return{innerType:current,isOptional,defaultValue}}function _getDescription(zodType){return zodType._def.description}function _toCamelCase(str){return str.replace(/[-_]([a-z])/g,(_,letter)=>letter.toUpperCase())}function _toKebabCase(str){return str.replace(/([a-z])([A-Z])/g,"$1-$2").toLowerCase()}function _createOption(name,zodType){let{innerType,isOptional,defaultValue}=_unwrapZodType(zodType),description=_getDescription(zodType)||`The ${name} value`,flagName=_toKebabCase(name),typeName=innerType._def.typeName,option;switch(typeName){case ZodFirstPartyTypeKind.ZodString:option=new Option(`--${flagName} <string>`,description);break;case ZodFirstPartyTypeKind.ZodNumber:option=new Option(`--${flagName} <number>`,description),option.argParser(value=>{let n=Number(value);if(!Number.isFinite(n))throw new Error(`Invalid number: ${value}`);return n});break;case ZodFirstPartyTypeKind.ZodBoolean:option=new Option(`--${flagName}`,description);break;case ZodFirstPartyTypeKind.ZodEnum:let enumValues=innerType._def.values;option=new Option(`--${flagName} <choice>`,description).choices(enumValues);break;case ZodFirstPartyTypeKind.ZodArray:option=new Option(`--${flagName} <value...>`,description);break;case ZodFirstPartyTypeKind.ZodObject:case ZodFirstPartyTypeKind.ZodRecord:option=new Option(`--${flagName} <json>`,description),option.argParser(value=>{try{return JSON.parse(value)}catch{throw new Error(`Invalid JSON: ${value}`)}});break;case ZodFirstPartyTypeKind.ZodAny:case ZodFirstPartyTypeKind.ZodUnknown:option=new Option(`--${flagName} <value>`,description),option.argParser(value=>{try{return JSON.parse(value)}catch{return value}});break;case ZodFirstPartyTypeKind.ZodLiteral:let literalValue=innerType._def.value;typeof literalValue=="boolean"?option=new Option(`--${flagName}`,description):(option=new Option(`--${flagName} <value>`,description),option.default(literalValue));break;case ZodFirstPartyTypeKind.ZodUnion:let unionOptions=innerType._def.options;if(unionOptions.every(opt=>opt._def.typeName===ZodFirstPartyTypeKind.ZodLiteral)){let choices=unionOptions.map(opt=>String(opt._def.value));option=new Option(`--${flagName} <choice>`,description).choices(choices)}else option=new Option(`--${flagName} <value>`,description),option.argParser(value=>{try{return JSON.parse(value)}catch{return value}});break;default:option=new Option(`--${flagName} <value>`,description);break}return defaultValue!==void 0&&option.default(defaultValue),!isOptional&&defaultValue===void 0&&option.makeOptionMandatory(!0),option}function _generateOptionsFromSchema(schema){let options=[];for(let[name,zodType]of Object.entries(schema)){let option=_createOption(name,zodType);option&&options.push(option)}return options}function _parseOptionsToToolInput(options){let result={};for(let[key,value]of Object.entries(options)){let camelKey=_toCamelCase(key);value!==void 0&&(result[camelKey]=value)}return result}function _parseToolName(toolName){let underscoreIndex=toolName.indexOf("_");return underscoreIndex===-1?{domain:"default",commandName:toolName}:{domain:toolName.substring(0,underscoreIndex),commandName:toolName.substring(underscoreIndex+1)}}function registerToolCommands(program,tools2,handler){let domainCommands=new Map;for(let tool of tools2){let{domain,commandName}=_parseToolName(tool.name()),domainCommand=domainCommands.get(domain);domainCommand||(domainCommand=new Command(domain).description(`${domain.charAt(0).toUpperCase()+domain.slice(1)} commands`),domainCommands.set(domain,domainCommand),program.addCommand(domainCommand));let toolCommand=new Command(commandName).description(tool.description().trim()),options=_generateOptionsFromSchema(tool.inputSchema());for(let option of options)toolCommand.addOption(option);toolCommand.action(async opts=>{let toolInput=_parseOptionsToToolInput(opts),globalOptions=program.opts();await handler(tool.name(),toolInput,globalOptions)}),domainCommand.addCommand(toolCommand)}}import{spawn,execSync}from"node:child_process";import{createRequire}from"node:module";import*as path from"node:path";import*as readline from"node:readline";import{fileURLToPath}from"node:url";import{Command as Command2,Option as Option2}from"commander";var require2=createRequire(import.meta.url),__filename=fileURLToPath(import.meta.url),__dirname=path.dirname(__filename),cliProvider=platformInfo.cliInfo.cliProvider,tools=cliProvider.tools,DEFAULT_TIMEOUT=3e4,verboseEnabled=!1,quietEnabled=!1;function _debug(message,data){if(verboseEnabled){let timestamp=new Date().toISOString();data!==void 0?console.error(`[${timestamp}] [DEBUG] ${message}`,data):console.error(`[${timestamp}] [DEBUG] ${message}`)}}function _output(message){quietEnabled||console.log(message)}function _error(message){console.error(message)}async function _isDaemonRunning(port){_debug(`Checking if daemon is running on port ${port}`);try{let response=await fetch(`http://localhost:${port}/health`,{method:"GET",signal:AbortSignal.timeout(3e3)});if(response.ok){let isRunning=(await response.json()).status==="ok";return _debug(`Daemon health check result: ${isRunning?"running":"not running"}`),isRunning}return _debug(`Daemon health check failed: HTTP ${response.status}`),!1}catch(err){return _debug(`Daemon health check error: ${err.message}`),!1}}function _buildDaemonEnv(opts){return cliProvider.buildEnv(opts)}function _startDaemonDetached(opts){let daemonServerPath=path.join(__dirname,"..","daemon-server.js"),env=_buildDaemonEnv(opts);_debug(`Starting daemon server from: ${daemonServerPath}`),_debug(`Daemon port: ${opts.port}`);let child=spawn(process.execPath,[daemonServerPath,"--port",String(opts.port)],{detached:!0,stdio:"ignore",env});child.unref(),_debug(`Daemon process spawned with PID: ${child.pid}`),_output(`Started daemon server as detached process (PID: ${child.pid})`)}async function _ensureDaemonRunning(opts){if(await _isDaemonRunning(opts.port))_debug("Daemon is already running");else{_output(`Daemon server is not running on port ${opts.port}, starting...`),_startDaemonDetached(opts);let maxRetries=10,retryDelay=500;_debug(`Waiting for daemon to be ready (max ${maxRetries} retries, ${retryDelay}ms delay)`);for(let i=0;i<maxRetries;i++)if(await new Promise(resolve=>setTimeout(resolve,retryDelay)),_debug(`Retry ${i+1}/${maxRetries}: checking daemon status...`),await _isDaemonRunning(opts.port)){_debug("Daemon is now ready"),_output("Daemon server is ready");return}throw new Error(`Daemon server failed to start within ${maxRetries*retryDelay/1e3} seconds`)}}async function _stopDaemon(port,timeout){try{return(await fetch(`http://localhost:${port}/shutdown`,{method:"POST",signal:AbortSignal.timeout(timeout)})).ok}catch{return!1}}async function _callTool(port,toolName,toolInput,sessionId,timeout){let headers={"Content-Type":"application/json"};sessionId&&(headers["session-id"]=sessionId);let request={toolName,toolInput};_debug(`Calling tool: ${toolName}`),_debug("Tool input:",toolInput),_debug(`Session ID: ${sessionId||"(default)"}`),_debug(`Timeout: ${timeout||"none"}`);let startTime=Date.now(),response=await fetch(`http://localhost:${port}/call`,{method:"POST",headers,body:JSON.stringify(request),signal:timeout?AbortSignal.timeout(timeout):void 0}),duration=Date.now()-startTime;if(_debug(`Tool call completed in ${duration}ms, status: ${response.status}`),!response.ok){let errorBody=await response.json().catch(()=>({}));throw _debug("Tool call error:",errorBody),new Error(errorBody?.error?.message||`HTTP ${response.status}: ${response.statusText}`)}let result=await response.json();return _debug("Tool call result:",result.toolError?{error:result.toolError}:{success:!0}),result}async function _deleteSession(port,sessionId,timeout){try{return(await fetch(`http://localhost:${port}/session`,{method:"DELETE",headers:{"session-id":sessionId},signal:AbortSignal.timeout(timeout)})).ok}catch{return!1}}async function _getDaemonInfo(port,timeout){try{let response=await fetch(`http://localhost:${port}/info`,{method:"GET",signal:AbortSignal.timeout(timeout)});return response.ok?await response.json():null}catch{return null}}async function _listSessions(port,timeout){try{let response=await fetch(`http://localhost:${port}/sessions`,{method:"GET",signal:AbortSignal.timeout(timeout)});return response.ok?await response.json():null}catch{return null}}async function _getSessionInfo(port,sessionId,timeout){try{let response=await fetch(`http://localhost:${port}/session`,{method:"GET",headers:{"session-id":sessionId},signal:AbortSignal.timeout(timeout)});return response.ok?await response.json():null}catch{return null}}function _formatUptime(seconds){let days=Math.floor(seconds/86400),hours=Math.floor(seconds%86400/3600),minutes=Math.floor(seconds%3600/60),secs=seconds%60,parts=[];return days>0&&parts.push(`${days}d`),hours>0&&parts.push(`${hours}h`),minutes>0&&parts.push(`${minutes}m`),parts.push(`${secs}s`),parts.join(" ")}function _formatTimestamp(timestamp){return new Date(timestamp).toISOString()}function _getZodTypeName(schema){let typeName=schema._def.typeName;return typeName==="ZodOptional"||typeName==="ZodNullable"||typeName==="ZodDefault"?_getZodTypeName(schema._def.innerType):typeName==="ZodArray"?`${_getZodTypeName(schema._def.type)}[]`:typeName==="ZodEnum"?schema._def.values.join(" | "):typeName==="ZodLiteral"?JSON.stringify(schema._def.value):typeName==="ZodUnion"?schema._def.options.map(opt=>_getZodTypeName(opt)).join(" | "):{ZodString:"string",ZodNumber:"number",ZodBoolean:"boolean",ZodObject:"object",ZodRecord:"Record<string, any>",ZodAny:"any"}[typeName]||typeName.replace("Zod","").toLowerCase()}function _getZodDescription(schema){if(schema._def.description)return schema._def.description;if(schema._def.typeName==="ZodOptional"||schema._def.typeName==="ZodNullable"||schema._def.typeName==="ZodDefault")return _getZodDescription(schema._def.innerType)}function _isZodOptional(schema){let typeName=schema._def.typeName;return typeName==="ZodOptional"||typeName==="ZodNullable"}function _hasZodDefault(schema){return schema._def.typeName==="ZodDefault"?!0:schema._def.typeName==="ZodOptional"||schema._def.typeName==="ZodNullable"?_hasZodDefault(schema._def.innerType):!1}function _getZodDefault(schema){if(schema._def.typeName==="ZodDefault")return schema._def.defaultValue();if(schema._def.typeName==="ZodOptional"||schema._def.typeName==="ZodNullable")return _getZodDefault(schema._def.innerType)}function _formatOutput(output,indent=0){let prefix=" ".repeat(indent);if(output==null)return`${prefix}(empty)`;if(typeof output=="string")return output.split(`
2
+ import{isToolEnabled,platformInfo}from"../core-RRWTV5B5.js";import{AMAZON_BEDROCK_ENABLE,AMAZON_BEDROCK_IMAGE_EMBED_MODEL_ID,AMAZON_BEDROCK_TEXT_EMBED_MODEL_ID,AMAZON_BEDROCK_VISION_MODEL_ID,AWS_PROFILE,AWS_REGION,DAEMON_PORT,DAEMON_SESSION_IDLE_CHECK_SECONDS,DAEMON_SESSION_IDLE_SECONDS,FIGMA_ACCESS_TOKEN,FIGMA_API_BASE_URL,OTEL_ENABLE,OTEL_EXPORTER_HTTP_URL,OTEL_EXPORTER_TYPE,OTEL_SERVICE_NAME,OTEL_SERVICE_VERSION}from"../core-DOXUXYCD.js";import{Command,Option}from"commander";import{ZodFirstPartyTypeKind}from"zod";function _unwrapZodType(zodType){let current=zodType,isOptional=!1,defaultValue;for(;;){let typeName=current._def.typeName;if(typeName===ZodFirstPartyTypeKind.ZodOptional)isOptional=!0,current=current._def.innerType;else if(typeName===ZodFirstPartyTypeKind.ZodDefault)isOptional=!0,defaultValue=current._def.defaultValue(),current=current._def.innerType;else if(typeName===ZodFirstPartyTypeKind.ZodNullable)isOptional=!0,current=current._def.innerType;else break}return{innerType:current,isOptional,defaultValue}}function _getDescription(zodType){return zodType._def.description}function _toCamelCase(str){return str.replace(/[-_]([a-z])/g,(_,letter)=>letter.toUpperCase())}function _toKebabCase(str){return str.replace(/([a-z])([A-Z])/g,"$1-$2").toLowerCase()}function _createOption(name,zodType){let{innerType,isOptional,defaultValue}=_unwrapZodType(zodType),description=_getDescription(zodType)||`The ${name} value`,flagName=_toKebabCase(name),typeName=innerType._def.typeName,option;switch(typeName){case ZodFirstPartyTypeKind.ZodString:option=new Option(`--${flagName} <string>`,description);break;case ZodFirstPartyTypeKind.ZodNumber:option=new Option(`--${flagName} <number>`,description),option.argParser(value=>{let n=Number(value);if(!Number.isFinite(n))throw new Error(`Invalid number: ${value}`);return n});break;case ZodFirstPartyTypeKind.ZodBoolean:option=new Option(`--${flagName}`,description);break;case ZodFirstPartyTypeKind.ZodEnum:let enumValues=innerType._def.values;option=new Option(`--${flagName} <choice>`,description).choices(enumValues);break;case ZodFirstPartyTypeKind.ZodArray:option=new Option(`--${flagName} <value...>`,description);break;case ZodFirstPartyTypeKind.ZodObject:case ZodFirstPartyTypeKind.ZodRecord:option=new Option(`--${flagName} <json>`,description),option.argParser(value=>{try{return JSON.parse(value)}catch{throw new Error(`Invalid JSON: ${value}`)}});break;case ZodFirstPartyTypeKind.ZodAny:case ZodFirstPartyTypeKind.ZodUnknown:option=new Option(`--${flagName} <value>`,description),option.argParser(value=>{try{return JSON.parse(value)}catch{return value}});break;case ZodFirstPartyTypeKind.ZodLiteral:let literalValue=innerType._def.value;typeof literalValue=="boolean"?option=new Option(`--${flagName}`,description):(option=new Option(`--${flagName} <value>`,description),option.default(literalValue));break;case ZodFirstPartyTypeKind.ZodUnion:let unionOptions=innerType._def.options;if(unionOptions.every(opt=>opt._def.typeName===ZodFirstPartyTypeKind.ZodLiteral)){let choices=unionOptions.map(opt=>String(opt._def.value));option=new Option(`--${flagName} <choice>`,description).choices(choices)}else option=new Option(`--${flagName} <value>`,description),option.argParser(value=>{try{return JSON.parse(value)}catch{return value}});break;default:option=new Option(`--${flagName} <value>`,description);break}return defaultValue!==void 0&&option.default(defaultValue),!isOptional&&defaultValue===void 0&&option.makeOptionMandatory(!0),option}function _generateOptionsFromSchema(schema,toolName){let options=[];for(let[name,zodType]of Object.entries(schema)){let option=_createOption(name,zodType);option&&options.push(option)}return options}function _parseOptionsToToolInput(options){let result={};for(let[key,value]of Object.entries(options)){let camelKey=_toCamelCase(key);value!==void 0&&(result[camelKey]=value)}return result}function _parseToolName(toolName){let underscoreIndex=toolName.indexOf("_");return underscoreIndex===-1?{domain:"default",commandName:toolName}:{domain:toolName.substring(0,underscoreIndex),commandName:toolName.substring(underscoreIndex+1)}}function registerToolCommands(program,tools2,handler){let domainCommands=new Map;for(let tool of tools2){let{domain,commandName}=_parseToolName(tool.name()),domainCommand=domainCommands.get(domain);domainCommand||(domainCommand=new Command(domain).description(`${domain.charAt(0).toUpperCase()+domain.slice(1)} commands`),domainCommands.set(domain,domainCommand),program.addCommand(domainCommand));let toolCommand=new Command(commandName).description(tool.description().trim()),options=_generateOptionsFromSchema(tool.inputSchema(),tool.name());for(let option of options)toolCommand.addOption(option);toolCommand.action(async opts=>{let toolInput=_parseOptionsToToolInput(opts),globalOptions=program.opts();await handler(tool.name(),toolInput,globalOptions)}),domainCommand.addCommand(toolCommand)}}import{spawn,execSync}from"node:child_process";import{createRequire}from"node:module";import*as path from"node:path";import*as readline from"node:readline";import{fileURLToPath}from"node:url";import{Command as Command2,Option as Option2}from"commander";var require2=createRequire(import.meta.url),__filename=fileURLToPath(import.meta.url),__dirname=path.dirname(__filename),cliProvider=platformInfo.cliInfo.cliProvider,tools=cliProvider.tools.filter(isToolEnabled),DEFAULT_TIMEOUT=3e4,verboseEnabled=!1,quietEnabled=!1;function _debug(message,data){if(verboseEnabled){let timestamp=new Date().toISOString();data!==void 0?console.error(`[${timestamp}] [DEBUG] ${message}`,data):console.error(`[${timestamp}] [DEBUG] ${message}`)}}function _output(message){quietEnabled||console.log(message)}function _error(message){console.error(message)}async function _isDaemonRunning(port){_debug(`Checking if daemon is running on port ${port}`);try{let response=await fetch(`http://localhost:${port}/health`,{method:"GET",signal:AbortSignal.timeout(3e3)});if(response.ok){let isRunning=(await response.json()).status==="ok";return _debug(`Daemon health check result: ${isRunning?"running":"not running"}`),isRunning}return _debug(`Daemon health check failed: HTTP ${response.status}`),!1}catch(err){return _debug(`Daemon health check error: ${err.message}`),!1}}function _buildDaemonEnv(opts){return cliProvider.buildEnv(opts)}function _startDaemonDetached(opts){let daemonServerPath=path.join(__dirname,"..","daemon-server.js"),env=_buildDaemonEnv(opts);_debug(`Starting daemon server from: ${daemonServerPath}`),_debug(`Daemon port: ${opts.port}`);let child=spawn(process.execPath,[daemonServerPath,"--port",String(opts.port)],{detached:!0,stdio:"ignore",env});child.unref(),_debug(`Daemon process spawned with PID: ${child.pid}`),_output(`Started daemon server as detached process (PID: ${child.pid})`)}async function _ensureDaemonRunning(opts){if(await _isDaemonRunning(opts.port))_debug("Daemon is already running");else{_output(`Daemon server is not running on port ${opts.port}, starting...`),_startDaemonDetached(opts);let maxRetries=10,retryDelay=500;_debug(`Waiting for daemon to be ready (max ${maxRetries} retries, ${retryDelay}ms delay)`);for(let i=0;i<maxRetries;i++)if(await new Promise(resolve=>setTimeout(resolve,retryDelay)),_debug(`Retry ${i+1}/${maxRetries}: checking daemon status...`),await _isDaemonRunning(opts.port)){_debug("Daemon is now ready"),_output("Daemon server is ready");return}throw new Error(`Daemon server failed to start within ${maxRetries*retryDelay/1e3} seconds`)}}async function _stopDaemon(port,timeout){try{return(await fetch(`http://localhost:${port}/shutdown`,{method:"POST",signal:AbortSignal.timeout(timeout)})).ok}catch{return!1}}async function _callTool(port,toolName,toolInput,sessionId,timeout){let headers={"Content-Type":"application/json"};sessionId&&(headers["session-id"]=sessionId);let request={toolName,toolInput};_debug(`Calling tool: ${toolName}`),_debug("Tool input:",toolInput),_debug(`Session ID: ${sessionId||"(default)"}`),_debug(`Timeout: ${timeout||"none"}`);let startTime=Date.now(),response=await fetch(`http://localhost:${port}/call`,{method:"POST",headers,body:JSON.stringify(request),signal:timeout?AbortSignal.timeout(timeout):void 0}),duration=Date.now()-startTime;if(_debug(`Tool call completed in ${duration}ms, status: ${response.status}`),!response.ok){let errorBody=await response.json().catch(()=>({}));_debug("Tool call error:",errorBody);let message=errorBody?.toolError?.message||errorBody?.error?.message||`HTTP ${response.status}: ${response.statusText}`;throw new Error(message)}let result=await response.json();return _debug("Tool call result:",result.toolError?{error:result.toolError}:{success:!0}),result}async function _deleteSession(port,sessionId,timeout){try{return(await fetch(`http://localhost:${port}/session`,{method:"DELETE",headers:{"session-id":sessionId},signal:AbortSignal.timeout(timeout)})).ok}catch{return!1}}async function _getDaemonInfo(port,timeout){try{let response=await fetch(`http://localhost:${port}/info`,{method:"GET",signal:AbortSignal.timeout(timeout)});return response.ok?await response.json():null}catch{return null}}async function _listSessions(port,timeout){try{let response=await fetch(`http://localhost:${port}/sessions`,{method:"GET",signal:AbortSignal.timeout(timeout)});return response.ok?await response.json():null}catch{return null}}async function _getSessionInfo(port,sessionId,timeout){try{let response=await fetch(`http://localhost:${port}/session`,{method:"GET",headers:{"session-id":sessionId},signal:AbortSignal.timeout(timeout)});return response.ok?await response.json():null}catch{return null}}function _formatUptime(seconds){let days=Math.floor(seconds/86400),hours=Math.floor(seconds%86400/3600),minutes=Math.floor(seconds%3600/60),secs=seconds%60,parts=[];return days>0&&parts.push(`${days}d`),hours>0&&parts.push(`${hours}h`),minutes>0&&parts.push(`${minutes}m`),parts.push(`${secs}s`),parts.join(" ")}function _formatTimestamp(timestamp){return new Date(timestamp).toISOString()}function _getZodTypeName(schema){let typeName=schema._def.typeName;return typeName==="ZodOptional"||typeName==="ZodNullable"||typeName==="ZodDefault"?_getZodTypeName(schema._def.innerType):typeName==="ZodArray"?`${_getZodTypeName(schema._def.type)}[]`:typeName==="ZodEnum"?schema._def.values.join(" | "):typeName==="ZodLiteral"?JSON.stringify(schema._def.value):typeName==="ZodUnion"?schema._def.options.map(opt=>_getZodTypeName(opt)).join(" | "):{ZodString:"string",ZodNumber:"number",ZodBoolean:"boolean",ZodObject:"object",ZodRecord:"Record<string, any>",ZodAny:"any"}[typeName]||typeName.replace("Zod","").toLowerCase()}function _getZodDescription(schema){if(schema._def.description)return schema._def.description;if(schema._def.typeName==="ZodOptional"||schema._def.typeName==="ZodNullable"||schema._def.typeName==="ZodDefault")return _getZodDescription(schema._def.innerType)}function _isZodOptional(schema){let typeName=schema._def.typeName;return typeName==="ZodOptional"||typeName==="ZodNullable"}function _hasZodDefault(schema){return schema._def.typeName==="ZodDefault"?!0:schema._def.typeName==="ZodOptional"||schema._def.typeName==="ZodNullable"?_hasZodDefault(schema._def.innerType):!1}function _getZodDefault(schema){if(schema._def.typeName==="ZodDefault")return schema._def.defaultValue();if(schema._def.typeName==="ZodOptional"||schema._def.typeName==="ZodNullable")return _getZodDefault(schema._def.innerType)}function _formatOutput(output,indent=0){let prefix=" ".repeat(indent);if(output==null)return`${prefix}(empty)`;if(typeof output=="string")return output.split(`
3
3
  `).map(line=>`${prefix}${line}`).join(`
4
4
  `);if(typeof output=="number"||typeof output=="boolean")return`${prefix}${output}`;if(Array.isArray(output))return output.length===0?`${prefix}[]`:output.map(item=>_formatOutput(item,indent)).join(`
5
5
  `);if(typeof output=="object"){let lines=[];for(let[key,value]of Object.entries(output))value!==void 0&&(typeof value=="object"&&value!==null&&!Array.isArray(value)?(lines.push(`${prefix}${key}:`),lines.push(_formatOutput(value,indent+1))):Array.isArray(value)?(lines.push(`${prefix}${key}:`),lines.push(_formatOutput(value,indent+1))):lines.push(`${prefix}${key}: ${value}`));return lines.join(`
6
6
  `)}return`${prefix}${String(output)}`}function _printOutput(data,json,isError=!1){let output=json?JSON.stringify(data,null,2):String(data);isError?console.error(output):console.log(output)}function _addGlobalOptions(cmd){return cmd.addOption(new Option2("--port <number>","Daemon server port").argParser(value=>{let n=Number(value);if(!Number.isInteger(n)||n<1||n>65535)throw new Error("Port must be an integer between 1 and 65535");return n}).default(DAEMON_PORT)).addOption(new Option2("--session-id <string>","Session ID for maintaining state across commands")).addOption(new Option2("--json","Output results as JSON")).addOption(new Option2("--quiet","Suppress log messages, only show output")).addOption(new Option2("--verbose","Enable verbose/debug output")).addOption(new Option2("--timeout <ms>","Timeout for operations in milliseconds").argParser(value=>{let n=Number(value);if(!Number.isFinite(n)||n<0)throw new Error("Timeout must be a positive number");return n}).default(DEFAULT_TIMEOUT)),cliProvider.addOptions(cmd)}async function main(){let program=_addGlobalOptions(new Command2(cliProvider.cliName).description(cliProvider.cliDescription).version(require2("../../package.json").version));program.hook("preAction",thisCommand=>{let opts=thisCommand.opts();opts.verbose&&(verboseEnabled=!0),opts.quiet&&(quietEnabled=!0),_debug("Verbose mode enabled"),_debug("CLI version:",require2("../../package.json").version),_debug("Node version:",process.version),_debug("Platform:",process.platform)});let daemonCmd=new Command2("daemon").description("Manage the daemon server");daemonCmd.command("start").description("Start the daemon server").action(async()=>{let opts=program.opts();if(await _isDaemonRunning(opts.port)){opts.json?_printOutput({status:"already_running",port:opts.port},!0):_output(`Daemon server is already running on port ${opts.port}`);return}_startDaemonDetached(opts);let maxRetries=10,retryDelay=500;for(let i=0;i<maxRetries;i++)if(await new Promise(resolve=>setTimeout(resolve,retryDelay)),await _isDaemonRunning(opts.port)){opts.json?_printOutput({status:"started",port:opts.port},!0):_output(`Daemon server started on port ${opts.port}`);return}opts.json?_printOutput({status:"failed",error:"Daemon server failed to start"},!0,!0):_error("Failed to start daemon server"),process.exit(1)}),daemonCmd.command("stop").description("Stop the daemon server").action(async()=>{let opts=program.opts();if(!await _isDaemonRunning(opts.port)){opts.json?_printOutput({status:"not_running",port:opts.port},!0):_output(`Daemon server is not running on port ${opts.port}`);return}await _stopDaemon(opts.port,opts.timeout??DEFAULT_TIMEOUT)?opts.json?_printOutput({status:"stopped",port:opts.port},!0):_output(`Daemon server stopped on port ${opts.port}`):(opts.json?_printOutput({status:"failed",error:"Failed to stop daemon server"},!0,!0):_error("Failed to stop daemon server"),process.exit(1))}),daemonCmd.command("restart").description("Restart the daemon server (stop + start)").action(async()=>{let opts=program.opts(),wasRunning=await _isDaemonRunning(opts.port);wasRunning&&(_debug("Stopping daemon server..."),await _stopDaemon(opts.port,opts.timeout??DEFAULT_TIMEOUT)||(opts.json?_printOutput({status:"failed",error:"Failed to stop daemon server"},!0,!0):_error("Failed to stop daemon server"),process.exit(1)),_debug("Waiting for port to be released..."),await new Promise(resolve=>setTimeout(resolve,1e3))),_debug("Starting daemon server..."),_startDaemonDetached(opts);let maxRetries=10,retryDelay=500;for(let i=0;i<maxRetries;i++)if(await new Promise(resolve=>setTimeout(resolve,retryDelay)),await _isDaemonRunning(opts.port)){opts.json?_printOutput({status:"restarted",port:opts.port},!0):_output(`Daemon server ${wasRunning?"restarted":"started"} on port ${opts.port}`);return}opts.json?_printOutput({status:"failed",error:"Daemon server failed to start"},!0,!0):_error("Failed to start daemon server"),process.exit(1)}),daemonCmd.command("status").description("Check daemon server status").action(async()=>{let opts=program.opts(),isRunning=await _isDaemonRunning(opts.port);opts.json?_printOutput({status:isRunning?"running":"stopped",port:opts.port},!0):_output(isRunning?`Daemon server is running on port ${opts.port}`:`Daemon server is not running on port ${opts.port}`)}),daemonCmd.command("info").description("Get detailed daemon server information").action(async()=>{let opts=program.opts();await _isDaemonRunning(opts.port)||(opts.json?_printOutput({status:"not_running",port:opts.port},!0,!0):_error(`Daemon server is not running on port ${opts.port}`),process.exit(1));let info=await _getDaemonInfo(opts.port,opts.timeout??DEFAULT_TIMEOUT);info?opts.json?_printOutput(info,!0):(_output("Daemon Server Information:"),_output(` Version: ${info.version}`),_output(` Port: ${info.port}`),_output(` Uptime: ${_formatUptime(info.uptime)}`),_output(` Sessions: ${info.sessionCount}`)):(opts.json?_printOutput({status:"error",error:"Failed to get daemon info"},!0,!0):_error("Failed to get daemon info"),process.exit(1))}),program.addCommand(daemonCmd);let sessionCmd=new Command2("session").description(cliProvider.sessionDescription);sessionCmd.command("list").description("List all active sessions").action(async()=>{let opts=program.opts();try{await _ensureDaemonRunning(opts);let result=await _listSessions(opts.port,opts.timeout??DEFAULT_TIMEOUT);if(result)if(opts.json)_printOutput(result,!0);else if(result.sessions.length===0)_output("No active sessions");else{_output(`Active Sessions (${result.sessions.length}):`);for(let session of result.sessions)_output(` ${session.id}`),_output(` Created: ${_formatTimestamp(session.createdAt)}`),_output(` Last Active: ${_formatTimestamp(session.lastActiveAt)}`),_output(` Idle: ${_formatUptime(session.idleSeconds)}`)}else opts.json?_printOutput({status:"error",error:"Failed to list sessions"},!0,!0):_error("Failed to list sessions"),process.exit(1)}catch(err){opts.json?_printOutput({status:"error",error:err.message},!0,!0):_error(`Error: ${err.message}`),process.exit(1)}}),sessionCmd.command("info <session-id>").description("Get information about a specific session").action(async sessionId=>{let opts=program.opts();try{await _ensureDaemonRunning(opts);let info=await _getSessionInfo(opts.port,sessionId,opts.timeout??DEFAULT_TIMEOUT);info?opts.json?_printOutput(info,!0):(_output(`Session: ${info.id}`),_output(` Created: ${_formatTimestamp(info.createdAt)}`),_output(` Last Active: ${_formatTimestamp(info.lastActiveAt)}`),_output(` Idle: ${_formatUptime(info.idleSeconds)}`)):(opts.json?_printOutput({status:"not_found",sessionId},!0,!0):_error(`Session '${sessionId}' not found`),process.exit(1))}catch(err){opts.json?_printOutput({status:"error",error:err.message},!0,!0):_error(`Error: ${err.message}`),process.exit(1)}}),sessionCmd.command("delete <session-id>").description("Delete a specific session").action(async sessionId=>{let opts=program.opts();try{await _ensureDaemonRunning(opts),await _deleteSession(opts.port,sessionId,opts.timeout??DEFAULT_TIMEOUT)?opts.json?_printOutput({status:"deleted",sessionId},!0):_output(`Session '${sessionId}' deleted`):(opts.json?_printOutput({status:"not_found",sessionId},!0,!0):_error(`Session '${sessionId}' not found or already deleted`),process.exit(1))}catch(err){opts.json?_printOutput({status:"error",error:err.message},!0,!0):_error(`Error: ${err.message}`),process.exit(1)}}),program.addCommand(sessionCmd);let toolsCmd=new Command2("tools").description("List and inspect available tools");toolsCmd.command("list").description("List all available tools").option("--domain <domain>","Filter by domain (e.g., navigation, content, interaction)").action(cmdOpts=>{let opts=program.opts(),toolsByDomain=new Map;for(let tool of tools){let domain=tool.name().split("_")[0];cmdOpts.domain&&domain!==cmdOpts.domain||(toolsByDomain.has(domain)||toolsByDomain.set(domain,[]),toolsByDomain.get(domain).push(tool))}if(opts.json){let result=[];for(let[domain,domainTools]of toolsByDomain)result.push({domain,tools:domainTools.map(t=>({name:t.name(),description:t.description().trim().split(`
7
7
  `)[0]}))});_printOutput(result,!0)}else{if(toolsByDomain.size===0){_output("No tools found");return}_output(`Available Tools (${tools.length} total):
8
8
  `);for(let[domain,domainTools]of toolsByDomain){_output(` ${domain}:`);for(let tool of domainTools){let name=tool.name().split("_")[1]||tool.name(),desc=tool.description().trim().split(`
9
- `)[0];_output(` ${name.padEnd(30)} ${desc}`)}_output("")}}}),toolsCmd.command("info <tool-name>").description("Get detailed information about a specific tool").action(toolName=>{let opts=program.opts(),tool=tools.find(t=>t.name()===toolName);tool||(tool=tools.find(t=>t.name().split("_")[1]===toolName)),tool||(opts.json?_printOutput({status:"not_found",toolName},!0,!0):_error(`Tool '${toolName}' not found`),process.exit(1));let inputSchema=tool.inputSchema(),params=[];for(let[key,schema]of Object.entries(inputSchema))params.push({name:key,type:_getZodTypeName(schema),required:!_isZodOptional(schema),description:_getZodDescription(schema),default:_hasZodDefault(schema)?_getZodDefault(schema):void 0});if(opts.json)_printOutput({name:tool.name(),description:tool.description().trim(),parameters:params},!0);else{let nameParts=tool.name().split("_");if(_output(`Tool: ${tool.name()}`),_output(`Domain: ${nameParts[0]}`),_output(`
9
+ `)[0];_output(` ${name.padEnd(30)} ${desc}`)}_output("")}}}),toolsCmd.command("info <tool-name> [other-parts...]").description('Get detailed information about a specific tool (e.g. "tools info navigation go-to" or "tools info navigation_go-to")').action((toolName,otherParts=[])=>{let opts=program.opts(),resolvedName=otherParts.length>0?[toolName,...otherParts].join("_"):toolName,tool=tools.find(t=>t.name()===resolvedName);tool||(tool=tools.find(t=>t.name().split("_")[1]===resolvedName)),tool||(opts.json?_printOutput({status:"not_found",toolName:resolvedName},!0,!0):_error(`Tool '${resolvedName}' not found`),process.exit(1));let inputSchema=tool.inputSchema(),params=[];for(let[key,schema]of Object.entries(inputSchema))params.push({name:key,type:_getZodTypeName(schema),required:!_isZodOptional(schema),description:_getZodDescription(schema),default:_hasZodDefault(schema)?_getZodDefault(schema):void 0});if(opts.json)_printOutput({name:tool.name(),description:tool.description().trim(),parameters:params},!0);else{let nameParts=tool.name().split("_");if(_output(`Tool: ${tool.name()}`),_output(`Domain: ${nameParts[0]}`),_output(`
10
10
  Description:`),_output(tool.description().trim().split(`
11
11
  `).map(line=>` ${line}`).join(`
12
12
  `)),_output(`
@@ -146,7 +146,7 @@ A new version is available!`),cmdOpts.check||_output(`Run: npm install -g ${pack
146
146
  `);try{await _ensureDaemonRunning(opts)}catch(err){_error(`Error: ${err.message}`),process.exit(1)}let replProgram=_createReplProgram(opts),rl=readline.createInterface({input:process.stdin,output:process.stdout,prompt:cliProvider.replPrompt});rl.prompt(),rl.on("line",async line=>{let input=line.trim();if(!input){rl.prompt();return}if((input==="exit"||input==="quit")&&(_output("Goodbye!"),rl.close(),process.exit(0)),input==="help"){_output(`
147
147
  REPL Commands:`),_output(" help Show this help"),_output(" exit, quit Exit interactive mode"),_output(`
148
148
  Available Commands:`),_output(" status Show daemon status summary"),_output(" config Show current configuration"),_output(" update Check for CLI updates"),_output(" daemon <cmd> Daemon management (start, stop, restart, status, info)"),_output(" session <cmd> Session management (list, info, delete)"),_output(" tools <cmd> Tool discovery (list, search, info)"),_output(" <domain> <tool> Execute a tool (e.g., navigation go-to --url ...)"),_output(`
149
- Examples:`),_output(" # Daemon & Session"),_output(" daemon status"),_output(" daemon info"),_output(" session list"),_output(" session delete my-session"),_output(""),_output(" # Tool Discovery"),_output(" tools list"),_output(" tools search screenshot"),_output(" tools info navigation_go-to"),_output(""),_output(" # Navigation"),_output(' navigation go-to --url "https://example.com"'),_output(" navigation go-back"),_output(" navigation reload"),_output(""),_output(" # Content"),_output(' content take-screenshot --name "test"'),_output(" content get-as-text"),_output(' content get-as-html --selector "#main"'),_output(""),_output(" # Interaction"),_output(' interaction click --ref "Submit"'),_output(' interaction fill --ref "Email" --value "test@example.com"'),_output(' interaction hover --ref "Menu"'),_output(""),_output(" # Accessibility"),_output(" a11y get-snapshot"),_output(" a11y get-ax-tree-snapshot"),_output(`
149
+ Examples:`),_output(" # Daemon & Session"),_output(" daemon status"),_output(" daemon info"),_output(" session list"),_output(" session delete my-session"),_output(""),_output(" # Tool Discovery"),_output(" tools list"),_output(" tools search screenshot"),_output(" tools info navigation_go-to"),_output(""),_output(" # Navigation"),_output(' navigation go-to --url "https://example.com"'),_output(" navigation go-back-or-forward --direction back"),_output(" navigation reload"),_output(""),_output(" # Content"),_output(' content take-screenshot --name "test"'),_output(" content get-as-text"),_output(' content get-as-html --selector "#main"'),_output(""),_output(" # Interaction"),_output(' interaction click --ref "Submit"'),_output(' interaction fill --ref "Email" --value "test@example.com"'),_output(' interaction hover --ref "Menu"'),_output(""),_output(" # Accessibility"),_output(" a11y get-snapshot"),_output(" a11y get-ax-tree-snapshot"),_output(`
150
150
  Tip: Use global options when starting interactive mode:`);for(let example of cliProvider.cliExamples)_output(` ${example}`);_output(""),rl.prompt();return}try{let args=_parseReplInput(input);await replProgram.parseAsync(["node","repl",...args])}catch(err){err.code==="commander.help"||(err.code==="commander.unknownCommand"?(_output(`Unknown command: ${input}`),_output('Type "help" for available commands')):err.code==="commander.missingArgument"?_error(`Missing argument: ${err.message}`):err.code==="commander.invalidArgument"?_error(`Invalid argument: ${err.message}`):err.code&&err.code.startsWith("commander.")||_error(`Error: ${err.message}`))}rl.prompt()}),rl.on("close",()=>{process.exit(0)})});program.addCommand(interactiveCmd);let updateCmd=new Command2("update").description("Check for updates and optionally install them").option("--check","Only check for updates without installing").action(async cmdOpts=>{let opts=program.opts(),currentVersion=require2("../../package.json").version,packageName=cliProvider.packageName;_output(`Checking for updates...
151
151
  `);try{let response=await fetch(`https://registry.npmjs.org/${packageName}/latest`,{method:"GET",signal:AbortSignal.timeout(1e4)});if(!response.ok)throw new Error(`Failed to check npm registry: HTTP ${response.status}`);let latestVersion=(await response.json()).version;if(opts.json){_printOutput({currentVersion,latestVersion,updateAvailable:latestVersion!==currentVersion},!0);return}if(_output(` Current version: ${currentVersion}`),_output(` Latest version: ${latestVersion}`),_output(""),latestVersion===currentVersion){_output("\x1B[32m\u2713 You are using the latest version!\x1B[0m");return}let currentParts=currentVersion.split(".").map(Number),latestParts=latestVersion.split(".").map(Number),isNewer=!1;for(let i=0;i<3;i++)if(latestParts[i]>currentParts[i]){isNewer=!0;break}else if(latestParts[i]<currentParts[i])break;if(!isNewer){_output("\x1B[32m\u2713 You are using a newer version than published!\x1B[0m");return}if(_output(`\x1B[33m\u26A0 Update available: ${currentVersion} \u2192 ${latestVersion}\x1B[0m
152
152
  `),cmdOpts.check){_output("To update, run:"),_output(` npm install -g ${packageName}@latest`),_output("or"),_output(` npx ${packageName}@latest`);return}let rl=readline.createInterface({input:process.stdin,output:process.stdout}),answer=await new Promise(resolve=>{rl.question("Do you want to update now? (y/N) ",ans=>{rl.close(),resolve(ans.toLowerCase())})});if(answer!=="y"&&answer!=="yes"){_output(`
@@ -1,6 +1,6 @@
1
- import path from"node:path";function _envStr(name){let v=process.env[name];if(!v)return;let t=v.trim();return t||void 0}function _envInt(name){let v=_envStr(name);if(!v)return;let n=Number(v);if(Number.isFinite(n))return Math.floor(n)}function _envBool(name){let v=_envStr(name);if(v)return v==="true"}function _parseKeyValueFromEnv(envValue){let headers={};if(!envValue)return headers;let pairs=envValue.split(",");for(let pair of pairs){let trimmed=pair.trim();if(!trimmed)continue;let eqIndex=trimmed.indexOf("=");if(eqIndex===-1)continue;let key=trimmed.slice(0,eqIndex).trim(),value=trimmed.slice(eqIndex+1).trim();!key||!value||(headers[key]=value)}return headers}var PORT=_envInt("PORT")??3e3,TOOL_OUTPUT_SCHEMA_DISABLE=_envBool("TOOL_OUTPUT_SCHEMA_DISABLE")??!1,AVAILABLE_TOOL_DOMAINS=(()=>{let v=_envStr("AVAILABLE_TOOL_DOMAINS");if(!v)return;let set=new Set(v.split(",").map(s=>s.trim().toLowerCase()).filter(Boolean));return set.size>0?set:void 0})(),_PLATFORM_RAW=_envStr("PLATFORM"),PLATFORM=_PLATFORM_RAW==="browser"||_PLATFORM_RAW==="node"?_PLATFORM_RAW:"browser",SESSION_IDLE_SECONDS=_envInt("SESSION_IDLE_SECONDS")??300,SESSION_IDLE_CHECK_SECONDS=_envInt("SESSION_IDLE_CHECK_SECONDS")??30,SESSION_CLOSE_ON_SOCKET_CLOSE=_envBool("SESSION_CLOSE_ON_SOCKET_CLOSE")??!1,BROWSER_HEADLESS_ENABLE=_envBool("BROWSER_HEADLESS_ENABLE")??!0,BROWSER_PERSISTENT_ENABLE=_envBool("BROWSER_PERSISTENT_ENABLE")??!1,BROWSER_PERSISTENT_USER_DATA_DIR=_envStr("BROWSER_PERSISTENT_USER_DATA_DIR")??path.join(process.cwd(),"browser-devtools-mcp"),BROWSER_USE_INSTALLED_ON_SYSTEM=_envBool("BROWSER_USE_INSTALLED_ON_SYSTEM")??!1,BROWSER_EXECUTABLE_PATH=_envStr("BROWSER_EXECUTABLE_PATH"),BROWSER_LOCALE=_envStr("BROWSER_LOCALE"),BROWSER_CONSOLE_MESSAGES_BUFFER_SIZE=_envInt("BROWSER_CONSOLE_MESSAGES_BUFFER_SIZE")??1e3,BROWSER_HTTP_REQUESTS_BUFFER_SIZE=_envInt("BROWSER_HTTP_REQUESTS_BUFFER_SIZE")??1e3,NODE_CONSOLE_MESSAGES_BUFFER_SIZE=_envInt("NODE_CONSOLE_MESSAGES_BUFFER_SIZE")??1e3,NODE_INSPECTOR_HOST=_envStr("NODE_INSPECTOR_HOST"),OTEL_ENABLE=_envBool("OTEL_ENABLE")??!1,OTEL_SERVICE_NAME=_envStr("OTEL_SERVICE_NAME")??"frontend",OTEL_SERVICE_VERSION=_envStr("OTEL_SERVICE_VERSION"),OTEL_ASSETS_DIR=_envStr("OTEL_ASSETS_DIR"),OTEL_INSTRUMENTATION_USER_INTERACTION_EVENTS=_envStr("OTEL_INSTRUMENTATION_USER_INTERACTION_EVENTS")?.split(",")??["click"],OTEL_EXPORTER_TYPE=_envStr("OTEL_EXPORTER_TYPE")??"none",OTEL_EXPORTER_HTTP_URL=_envStr("OTEL_EXPORTER_HTTP_URL"),OTEL_EXPORTER_HTTP_HEADERS=_parseKeyValueFromEnv(_envStr("OTEL_EXPORTER_HTTP_HEADERS")),AWS_REGION=_envStr("AWS_REGION"),AWS_PROFILE=_envStr("AWS_PROFILE"),AMAZON_BEDROCK_ENABLE=_envBool("AMAZON_BEDROCK_ENABLE")??!1,AMAZON_BEDROCK_IMAGE_EMBED_MODEL_ID=_envStr("AMAZON_BEDROCK_IMAGE_EMBED_MODEL_ID"),AMAZON_BEDROCK_TEXT_EMBED_MODEL_ID=_envStr("AMAZON_BEDROCK_TEXT_EMBED_MODEL_ID"),AMAZON_BEDROCK_VISION_MODEL_ID=_envStr("AMAZON_BEDROCK_VISION_MODEL_ID"),FIGMA_ACCESS_TOKEN=_envStr("FIGMA_ACCESS_TOKEN")??"",FIGMA_API_BASE_URL=_envStr("FIGMA_API_BASE_URL")??"https://api.figma.com/v1",DAEMON_PORT=_envInt("DAEMON_PORT")??2020,DAEMON_SESSION_IDLE_SECONDS=_envInt("DAEMON_SESSION_IDLE_SECONDS")??300,DAEMON_SESSION_IDLE_CHECK_SECONDS=_envInt("DAEMON_SESSION_IDLE_CHECK_SECONDS")??30;var ConsoleMessageLevelName=(ConsoleMessageLevelName2=>(ConsoleMessageLevelName2.ALL="all",ConsoleMessageLevelName2.DEBUG="debug",ConsoleMessageLevelName2.INFO="info",ConsoleMessageLevelName2.WARNING="warning",ConsoleMessageLevelName2.ERROR="error",ConsoleMessageLevelName2))(ConsoleMessageLevelName||{});var ConsoleMessageLevel={all:{code:-1},debug:{code:0},info:{code:1},warning:{code:2},error:{code:3}};var BANNER_TEXT="[BROWSER-DEVTOOLS]",enabled=!0,debugEnabled=process.env.DEBUG_ENABLE==="true";function _timeAsString(){return`${new Date().toLocaleTimeString(void 0,{hour:"numeric",minute:"numeric",second:"numeric",hour12:!1,timeZoneName:"short"})}`}function _normalizeArgs(...args){return isDebugEnabled()?args:(args||[]).map(arg=>arg?arg instanceof Error||arg.name&&arg.message&&arg.stack?`${arg.name}: ${arg.message}`:arg:"")}function enable(){enabled=!0}function disable(){enabled=!1}function isDebugEnabled(){return debugEnabled}function debug(...args){enabled&&isDebugEnabled()&&console.debug(BANNER_TEXT,_timeAsString(),"|","DEBUG","-",..._normalizeArgs(...args))}function info(...args){enabled&&console.info(BANNER_TEXT,_timeAsString(),"|","INFO ","-",..._normalizeArgs(...args))}function warn(...args){enabled&&console.warn(BANNER_TEXT,_timeAsString(),"|","WARN ","-",..._normalizeArgs(...args))}function error(...args){enabled&&console.error(BANNER_TEXT,_timeAsString(),"|","ERROR","-",..._normalizeArgs(...args))}function _getCircularReplacer(){let seen=new WeakSet;return(key,value)=>{if(typeof value=="object"&&value!==null){if(seen.has(value))return;seen.add(value)}return value}}function toJson(obj){return JSON.stringify(obj,_getCircularReplacer())}var BASE64_CHARS="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",BASE64_MAP=new Map;for(let i=0;i<BASE64_CHARS.length;i++)BASE64_MAP.set(BASE64_CHARS[i],i);function _decodeVLQ(encoded){let values=[],shift=0,value=0;for(let char of encoded){let digit=BASE64_MAP.get(char);if(digit===void 0)throw new Error(`Invalid base64 character: ${char}`);let hasContinuation=(digit&32)!==0;if(value+=(digit&31)<<shift,hasContinuation)shift+=5;else{let isNegative=(value&1)!==0;value=value>>1,isNegative&&(value=-value),values.push(value),value=0,shift=0}}return values}function _parseMappings(mappings,sources){let entries=[],lines=mappings.split(";"),generatedLine=0,sourceIndex=0,originalLine=0,originalColumn=0,nameIndex=0;for(let line of lines){let generatedColumn=0,segments=line.split(",");for(let segment of segments){if(!segment)continue;let values=_decodeVLQ(segment);if(values.length===0)continue;generatedColumn+=values[0];let entry={generatedLine,generatedColumn};values.length>=4&&(sourceIndex+=values[1],originalLine+=values[2],originalColumn+=values[3],entry.source=sources[sourceIndex],entry.originalLine=originalLine,entry.originalColumn=originalColumn,values.length>=5&&(nameIndex+=values[4])),entries.push(entry)}generatedLine++}return entries}var SourceMapResolver=class{scripts=new Map;scriptsByUrl=new Map;sourceToScripts=new Map;fetchCache=new Map;page;customFetcher;constructor(source){typeof source=="function"?this.customFetcher=source:this.page=source}registerScript(script){let resolved={scriptId:script.scriptId,url:script.url,sourceMapURL:script.sourceMapURL,originalSources:[]};if(this.scripts.set(script.scriptId,resolved),script.url){let existing=this.scriptsByUrl.get(script.url)||[];existing.push(resolved),this.scriptsByUrl.set(script.url,existing)}}getScriptUrl(scriptId){return this.scripts.get(scriptId)?.url}async loadSourceMap(scriptId){let script=this.scripts.get(scriptId);if(!script||!script.sourceMapURL)return!1;if(script.sourceMap)return!0;try{let sourceMap=await this._fetchSourceMap(script.sourceMapURL,script.url);if(!sourceMap)return!1;script.sourceMap=sourceMap,script.mappings=_parseMappings(sourceMap.mappings,sourceMap.sources),script.originalSources=sourceMap.sources.map(s=>this._resolveSourcePath(s,sourceMap.sourceRoot,script.url));for(let source of script.originalSources){let existing=this.sourceToScripts.get(source)||[];existing.push(script),this.sourceToScripts.set(source,existing)}return!0}catch(error2){return debug(`Failed to load source map for ${script.url}:`,error2),!1}}async loadAllSourceMaps(){let loaded=0;for(let scriptId of this.scripts.keys())await this.loadSourceMap(scriptId)&&loaded++;return loaded}originalToGenerated(originalSource,line,column=0){let normalizedSource=this._normalizeSourcePath(originalSource),scripts=this._findScriptsForSource(normalizedSource);if(scripts.length!==0)for(let script of scripts){if(!script.mappings)continue;let sourceIndex=script.originalSources.findIndex(s=>this._normalizeSourcePath(s)===normalizedSource||s.endsWith(normalizedSource)||normalizedSource.endsWith(s));if(sourceIndex===-1)continue;let bestMatch,bestDistance=1/0;for(let mapping of script.mappings)if(mapping.source===script.sourceMap?.sources[sourceIndex]&&mapping.originalLine!==void 0&&mapping.originalLine===line){let colDist=mapping.originalColumn!==void 0?Math.abs(mapping.originalColumn-column):0;colDist<bestDistance&&(bestDistance=colDist,bestMatch=mapping)}if(bestMatch)return{scriptId:script.scriptId,location:{line:bestMatch.generatedLine,column:bestMatch.generatedColumn}}}}async resolveLocationByUrl(url,line,column=1){let line0=Math.max(0,line-1),column0=Math.max(0,column-1),candidates=this.scriptsByUrl.get(url)||[];if(candidates.length===0)for(let script of this.scripts.values())(script.url===url||script.url.endsWith(url)||url.endsWith(script.url))&&candidates.push(script);for(let script of candidates){if(!await this.loadSourceMap(script.scriptId)||!script.mappings)continue;let resolved=this.generatedToOriginal(script.scriptId,line0,column0);if(resolved)return resolved}return null}generatedToOriginal(scriptId,line,column=0){let script=this.scripts.get(scriptId);if(!script?.mappings)return;let bestMatch,bestDistance=1/0;for(let mapping of script.mappings){if(mapping.generatedLine!==line||mapping.source===void 0)continue;let colDist=Math.abs(mapping.generatedColumn-column);colDist<bestDistance&&(bestDistance=colDist,bestMatch=mapping)}if(bestMatch&&bestMatch.source!==void 0&&bestMatch.originalLine!==void 0){let sourceIndex=script.sourceMap?.sources.indexOf(bestMatch.source);return{source:sourceIndex!==void 0&&sourceIndex>=0?script.originalSources[sourceIndex]:bestMatch.source,line:bestMatch.originalLine,column:bestMatch.originalColumn??0,name:bestMatch.name}}}getOriginalSources(){return Array.from(this.sourceToScripts.keys())}findScriptsForSource(sourcePattern){let normalized=this._normalizeSourcePath(sourcePattern);return this._findScriptsForSource(normalized)}hasSourceMaps(){for(let script of this.scripts.values())if(script.sourceMap)return!0;return!1}clear(){this.scripts.clear(),this.scriptsByUrl.clear(),this.sourceToScripts.clear(),this.fetchCache.clear()}_findScriptsForSource(normalizedSource){let exact=this.sourceToScripts.get(normalizedSource);if(exact&&exact.length>0)return exact;let results=[];for(let[source,scripts]of this.sourceToScripts.entries()){let normalizedKey=this._normalizeSourcePath(source);(normalizedKey.endsWith(normalizedSource)||normalizedSource.endsWith(normalizedKey))&&results.push(...scripts)}return results}_normalizeSourcePath(path3){let normalized=path3.replace(/^webpack:\/\/[^/]*\//,"").replace(/^file:\/\//,"").replace(/^\.*\//,"");for(normalized=normalized.replace(/\\/g,"/");normalized.startsWith("./");)normalized=normalized.slice(2);return normalized}_resolveSourcePath(source,sourceRoot,scriptUrl){return source.startsWith("webpack://")||source.startsWith("http://")||source.startsWith("https://")||sourceRoot&&(source=sourceRoot.replace(/\/$/,"")+"/"+source),source}async _fetchSourceMap(sourceMapURL,scriptUrl){if(sourceMapURL.startsWith("data:"))return this._parseDataUrl(sourceMapURL);let absoluteUrl=this._resolveUrl(sourceMapURL,scriptUrl);if(this.fetchCache.has(absoluteUrl))return this.fetchCache.get(absoluteUrl)||null;try{let sourceMap=null;if(this.customFetcher){let content=await this.customFetcher(absoluteUrl,scriptUrl);content&&(sourceMap=JSON.parse(content))}else this.page&&(sourceMap=await this._fetchViaBrowser(absoluteUrl));return this.fetchCache.set(absoluteUrl,sourceMap),sourceMap}catch(error2){return debug(`Failed to fetch source map from ${absoluteUrl}:`,error2),this.fetchCache.set(absoluteUrl,null),null}}_parseDataUrl(dataUrl){try{let match=dataUrl.match(/^data:[^,]*(?:;base64)?,(.*)$/);if(!match)return null;let isBase64=dataUrl.includes(";base64,"),data=match[1],json=isBase64?Buffer.from(data,"base64").toString("utf-8"):decodeURIComponent(data);return JSON.parse(json)}catch{return null}}_resolveUrl(url,baseUrl){if(url.startsWith("http://")||url.startsWith("https://"))return url;try{return new URL(url,baseUrl).href}catch{return baseUrl.replace(/[^/]*$/,"")+url}}async _fetchViaBrowser(url){if(!this.page)return null;try{let result=await this.page.evaluate(async fetchUrl=>{try{let response=await fetch(fetchUrl);return response.ok?{data:await response.text()}:{error:`HTTP ${response.status}`}}catch(err){return{error:err.message||"Fetch failed"}}},url);return"error"in result?(debug(`Browser fetch error for ${url}: ${result.error}`),null):JSON.parse(result.data)}catch(error2){return debug(`Failed to fetch ${url} via browser:`,error2),null}}};var V8API_DEFAULT_OPTIONS={maxDepth:3,maxProperties:50,maxArrayLength:100,maxStringLength:1e3},V8Api=class{cdp=null;enabled=!1;scripts=new Map;scriptsByUrl=new Map;eventHandlers={};options;cdpProvider;constructor(source,options){if(this.options={...V8API_DEFAULT_OPTIONS,...options},typeof source=="function")this.cdpProvider=source;else if(source&&typeof source.context=="function"){let page=source;this.cdpProvider=async()=>await page.context().newCDPSession(page)}else if(source&&typeof source.send=="function"){let session=source;this.cdp=session,this.cdpProvider=async()=>session}else throw new Error("V8Api: Invalid source. Expected Page, CDPSessionProvider, or ICDPSession.")}getOptions(){return{...this.options}}isEnabled(){return this.enabled}async getCdp(){return this.cdp||(this.cdp=await this.cdpProvider()),this.cdp}on(event,handler){this.eventHandlers[event]=handler}off(event){delete this.eventHandlers[event]}async enable(){if(this.enabled)return;let cdp=await this.getCdp();cdp.on("Debugger.scriptParsed",event=>{let parsed=event;if(this.scripts.set(parsed.scriptId,parsed),parsed.url){let existing=this.scriptsByUrl.get(parsed.url)||[];existing.push(parsed),this.scriptsByUrl.set(parsed.url,existing)}this.eventHandlers.scriptParsed&&this.eventHandlers.scriptParsed(parsed)}),cdp.on("Debugger.paused",event=>{let pausedEvent=event;this.eventHandlers.paused&&this.eventHandlers.paused(pausedEvent)}),cdp.on("Debugger.resumed",()=>{this.eventHandlers.resumed&&this.eventHandlers.resumed()}),await cdp.send("Debugger.enable",{maxScriptsCacheSize:1e8}),await cdp.send("Runtime.enable"),this.enabled=!0}async disable(){if(!(!this.enabled||!this.cdp)){try{await this.cdp.send("Debugger.disable"),await this.cdp.send("Runtime.disable")}catch{}this.scripts.clear(),this.scriptsByUrl.clear(),this.enabled=!1}}async detach(){if(await this.disable(),this.cdp){try{await this.cdp.detach()}catch{}this.cdp=null}}getScripts(){return Array.from(this.scripts.values())}getScript(scriptId){return this.scripts.get(scriptId)}findScriptsByUrl(urlPattern){let regex=new RegExp(urlPattern),results=[];for(let script of this.scripts.values())script.url&&regex.test(script.url)&&results.push(script);return results}async setBreakpointByUrl(options){let cdp=await this.getCdp(),params={lineNumber:options.lineNumber};options.urlRegex?params.urlRegex=options.urlRegex:options.url&&(params.url=options.url),options.columnNumber!==void 0&&(params.columnNumber=options.columnNumber),options.condition&&(params.condition=options.condition);let result=await cdp.send("Debugger.setBreakpointByUrl",params);return{breakpointId:result.breakpointId,locations:result.locations||[]}}async setBreakpoint(location,condition){let cdp=await this.getCdp(),params={location:{scriptId:location.scriptId,lineNumber:location.lineNumber,columnNumber:location.columnNumber}};condition&&(params.condition=condition);let result=await cdp.send("Debugger.setBreakpoint",params);return{breakpointId:result.breakpointId,actualLocation:result.actualLocation}}async removeBreakpoint(breakpointId){await(await this.getCdp()).send("Debugger.removeBreakpoint",{breakpointId})}async resume(){await(await this.getCdp()).send("Debugger.resume")}async stepOver(){await(await this.getCdp()).send("Debugger.stepOver")}async stepInto(){await(await this.getCdp()).send("Debugger.stepInto")}async stepOut(){await(await this.getCdp()).send("Debugger.stepOut")}async pause(){await(await this.getCdp()).send("Debugger.pause")}async setPauseOnExceptions(state){await(await this.getCdp()).send("Debugger.setPauseOnExceptions",{state})}async evaluateOnCallFrame(callFrameId,expression,options){let result=await(await this.getCdp()).send("Debugger.evaluateOnCallFrame",{callFrameId,expression,returnByValue:options?.returnByValue??!0,generatePreview:options?.generatePreview??!0,throwOnSideEffect:options?.throwOnSideEffect??!1});return{result:result.result,exceptionDetails:result.exceptionDetails}}async getProperties(objectId,options){let result=await(await this.getCdp()).send("Runtime.getProperties",{objectId,ownProperties:options?.ownProperties??!0,accessorPropertiesOnly:options?.accessorPropertiesOnly??!1,generatePreview:options?.generatePreview??!0});return{result:result.result||[],internalProperties:result.internalProperties,privateProperties:result.privateProperties}}async getScopeVariables(scope,options){if(!scope.object.objectId)return{};let opts={maxDepth:options?.maxDepth??this.options.maxDepth,maxProperties:options?.maxProperties??this.options.maxProperties,maxArrayLength:options?.maxArrayLength??this.options.maxArrayLength},{result}=await this.getProperties(scope.object.objectId,{ownProperties:!0,generatePreview:!0}),variables={},visited=new Set,propCount=0;for(let prop of result){if(propCount>=opts.maxProperties){variables.__truncated__=`${result.length-propCount} more properties`;break}prop.value&&(variables[prop.name]=await this.extractValueDeep(prop.value,opts.maxDepth,opts.maxProperties,opts.maxArrayLength,visited),propCount++)}return variables}extractValue(obj){return this._extractValueShallow(obj)}async extractValueDeep(obj,maxDepth,maxProperties,maxArrayLength,visited=new Set){let depth=maxDepth??this.options.maxDepth,props=maxProperties??this.options.maxProperties,arrLen=maxArrayLength??this.options.maxArrayLength;if(obj.value!==void 0)return typeof obj.value=="string"&&obj.value.length>this.options.maxStringLength?obj.value.slice(0,this.options.maxStringLength)+`... (${obj.value.length} chars)`:obj.value;if(obj.unserializableValue)return obj.unserializableValue==="NaN"?NaN:obj.unserializableValue==="Infinity"?1/0:obj.unserializableValue==="-Infinity"?-1/0:obj.unserializableValue==="-0"?-0:obj.unserializableValue.endsWith("n")?`BigInt(${obj.unserializableValue.slice(0,-1)})`:obj.unserializableValue;if(obj.subtype==="null")return null;if(obj.type!=="undefined"){if(obj.type==="function")return`[function${obj.description?`: ${obj.description.split(`
1
+ import path from"node:path";function _envStr(name){let v=process.env[name];if(!v)return;let t=v.trim();return t||void 0}function _envInt(name){let v=_envStr(name);if(!v)return;let n=Number(v);if(Number.isFinite(n))return Math.floor(n)}function _envBool(name){let v=_envStr(name);if(v)return v==="true"}function _parseKeyValueFromEnv(envValue){let headers={};if(!envValue)return headers;let pairs=envValue.split(",");for(let pair of pairs){let trimmed=pair.trim();if(!trimmed)continue;let eqIndex=trimmed.indexOf("=");if(eqIndex===-1)continue;let key=trimmed.slice(0,eqIndex).trim(),value=trimmed.slice(eqIndex+1).trim();!key||!value||(headers[key]=value)}return headers}var PORT=_envInt("PORT")??3e3,TOOL_OUTPUT_SCHEMA_DISABLE=_envBool("TOOL_OUTPUT_SCHEMA_DISABLE")??!1,AVAILABLE_TOOL_DOMAINS=(()=>{let v=_envStr("AVAILABLE_TOOL_DOMAINS");if(!v)return;let set=new Set(v.split(",").map(s=>s.trim().toLowerCase()).filter(Boolean));return set.size>0?set:void 0})(),_PLATFORM_RAW=_envStr("PLATFORM"),PLATFORM=_PLATFORM_RAW==="browser"||_PLATFORM_RAW==="node"?_PLATFORM_RAW:"browser",SESSION_IDLE_SECONDS=_envInt("SESSION_IDLE_SECONDS")??300,SESSION_IDLE_CHECK_SECONDS=_envInt("SESSION_IDLE_CHECK_SECONDS")??30,SESSION_CLOSE_ON_SOCKET_CLOSE=_envBool("SESSION_CLOSE_ON_SOCKET_CLOSE")??!1,BROWSER_HEADLESS_ENABLE=_envBool("BROWSER_HEADLESS_ENABLE")??!0,BROWSER_PERSISTENT_ENABLE=_envBool("BROWSER_PERSISTENT_ENABLE")??!1,BROWSER_PERSISTENT_USER_DATA_DIR=_envStr("BROWSER_PERSISTENT_USER_DATA_DIR")??path.join(process.cwd(),"browser-devtools-mcp"),BROWSER_USE_INSTALLED_ON_SYSTEM=_envBool("BROWSER_USE_INSTALLED_ON_SYSTEM")??!1,BROWSER_EXECUTABLE_PATH=_envStr("BROWSER_EXECUTABLE_PATH"),BROWSER_LOCALE=_envStr("BROWSER_LOCALE"),BROWSER_CONSOLE_MESSAGES_BUFFER_SIZE=_envInt("BROWSER_CONSOLE_MESSAGES_BUFFER_SIZE")??1e3,BROWSER_HTTP_REQUESTS_BUFFER_SIZE=_envInt("BROWSER_HTTP_REQUESTS_BUFFER_SIZE")??1e3,NODE_CONSOLE_MESSAGES_BUFFER_SIZE=_envInt("NODE_CONSOLE_MESSAGES_BUFFER_SIZE")??1e3,NODE_INSPECTOR_HOST=_envStr("NODE_INSPECTOR_HOST"),OTEL_ENABLE=_envBool("OTEL_ENABLE")??!1,OTEL_SERVICE_NAME=_envStr("OTEL_SERVICE_NAME")??"frontend",OTEL_SERVICE_VERSION=_envStr("OTEL_SERVICE_VERSION"),OTEL_ASSETS_DIR=_envStr("OTEL_ASSETS_DIR"),OTEL_INSTRUMENTATION_USER_INTERACTION_EVENTS=_envStr("OTEL_INSTRUMENTATION_USER_INTERACTION_EVENTS")?.split(",")??["click"],OTEL_EXPORTER_TYPE=_envStr("OTEL_EXPORTER_TYPE")??"none",OTEL_EXPORTER_HTTP_URL=_envStr("OTEL_EXPORTER_HTTP_URL"),OTEL_EXPORTER_HTTP_HEADERS=_parseKeyValueFromEnv(_envStr("OTEL_EXPORTER_HTTP_HEADERS")),AWS_REGION=_envStr("AWS_REGION"),AWS_PROFILE=_envStr("AWS_PROFILE"),AMAZON_BEDROCK_ENABLE=_envBool("AMAZON_BEDROCK_ENABLE")??!1,AMAZON_BEDROCK_IMAGE_EMBED_MODEL_ID=_envStr("AMAZON_BEDROCK_IMAGE_EMBED_MODEL_ID"),AMAZON_BEDROCK_TEXT_EMBED_MODEL_ID=_envStr("AMAZON_BEDROCK_TEXT_EMBED_MODEL_ID"),AMAZON_BEDROCK_VISION_MODEL_ID=_envStr("AMAZON_BEDROCK_VISION_MODEL_ID"),FIGMA_ACCESS_TOKEN=_envStr("FIGMA_ACCESS_TOKEN")??"",FIGMA_API_BASE_URL=_envStr("FIGMA_API_BASE_URL")??"https://api.figma.com/v1",DAEMON_PORT=_envInt("DAEMON_PORT")??2020,DAEMON_SESSION_IDLE_SECONDS=_envInt("DAEMON_SESSION_IDLE_SECONDS")??300,DAEMON_SESSION_IDLE_CHECK_SECONDS=_envInt("DAEMON_SESSION_IDLE_CHECK_SECONDS")??30;var ConsoleMessageLevelName=(ConsoleMessageLevelName2=>(ConsoleMessageLevelName2.ALL="all",ConsoleMessageLevelName2.DEBUG="debug",ConsoleMessageLevelName2.INFO="info",ConsoleMessageLevelName2.WARNING="warning",ConsoleMessageLevelName2.ERROR="error",ConsoleMessageLevelName2))(ConsoleMessageLevelName||{});var ConsoleMessageLevel={all:{code:-1},debug:{code:0},info:{code:1},warning:{code:2},error:{code:3}};var BANNER_TEXT="[BROWSER-DEVTOOLS]",enabled=!0,debugEnabled=process.env.DEBUG_ENABLE==="true";function _timeAsString(){return`${new Date().toLocaleTimeString(void 0,{hour:"numeric",minute:"numeric",second:"numeric",hour12:!1,timeZoneName:"short"})}`}function _normalizeArgs(...args){return isDebugEnabled()?args:(args||[]).map(arg=>arg?arg instanceof Error||arg.name&&arg.message&&arg.stack?`${arg.name}: ${arg.message}`:arg:"")}function enable(){enabled=!0}function disable(){enabled=!1}function isDebugEnabled(){return debugEnabled}function debug(...args){enabled&&isDebugEnabled()&&console.debug(BANNER_TEXT,_timeAsString(),"|","DEBUG","-",..._normalizeArgs(...args))}function info(...args){enabled&&console.info(BANNER_TEXT,_timeAsString(),"|","INFO ","-",..._normalizeArgs(...args))}function warn(...args){enabled&&console.warn(BANNER_TEXT,_timeAsString(),"|","WARN ","-",..._normalizeArgs(...args))}function error(...args){enabled&&console.error(BANNER_TEXT,_timeAsString(),"|","ERROR","-",..._normalizeArgs(...args))}function _getCircularReplacer(){let seen=new WeakSet;return(key,value)=>{if(typeof value=="object"&&value!==null){if(seen.has(value))return;seen.add(value)}return value}}function toJson(obj){return JSON.stringify(obj,_getCircularReplacer())}var BASE64_CHARS="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",BASE64_MAP=new Map;for(let i=0;i<BASE64_CHARS.length;i++)BASE64_MAP.set(BASE64_CHARS[i],i);function _decodeVLQ(encoded){let values=[],shift=0,value=0;for(let char of encoded){let digit=BASE64_MAP.get(char);if(digit===void 0)throw new Error(`Invalid base64 character: ${char}`);let hasContinuation=(digit&32)!==0;if(value+=(digit&31)<<shift,hasContinuation)shift+=5;else{let isNegative=(value&1)!==0;value=value>>1,isNegative&&(value=-value),values.push(value),value=0,shift=0}}return values}function _parseMappings(mappings,sources){let entries=[],lines=mappings.split(";"),generatedLine=0,sourceIndex=0,originalLine=0,originalColumn=0,nameIndex=0;for(let line of lines){let generatedColumn=0,segments=line.split(",");for(let segment of segments){if(!segment)continue;let values=_decodeVLQ(segment);if(values.length===0)continue;generatedColumn+=values[0];let entry={generatedLine,generatedColumn};values.length>=4&&(sourceIndex+=values[1],originalLine+=values[2],originalColumn+=values[3],entry.source=sources[sourceIndex],entry.originalLine=originalLine,entry.originalColumn=originalColumn,values.length>=5&&(nameIndex+=values[4])),entries.push(entry)}generatedLine++}return entries}var SourceMapResolver=class{scripts=new Map;scriptsByUrl=new Map;sourceToScripts=new Map;fetchCache=new Map;page;customFetcher;constructor(source){typeof source=="function"?this.customFetcher=source:this.page=source}registerScript(script){let resolved={scriptId:script.scriptId,url:script.url,sourceMapURL:script.sourceMapURL,originalSources:[]};if(this.scripts.set(script.scriptId,resolved),script.url){let existing=this.scriptsByUrl.get(script.url)||[];existing.push(resolved),this.scriptsByUrl.set(script.url,existing)}}getScriptUrl(scriptId){return this.scripts.get(scriptId)?.url}async loadSourceMap(scriptId){let script=this.scripts.get(scriptId);if(!script||!script.sourceMapURL)return!1;if(script.sourceMap)return!0;try{let sourceMap=await this._fetchSourceMap(script.sourceMapURL,script.url);if(!sourceMap)return!1;script.sourceMap=sourceMap,script.mappings=_parseMappings(sourceMap.mappings,sourceMap.sources),script.originalSources=sourceMap.sources.map(s=>this._resolveSourcePath(s,sourceMap.sourceRoot,script.url));for(let source of script.originalSources){let existing=this.sourceToScripts.get(source)||[];existing.push(script),this.sourceToScripts.set(source,existing)}return!0}catch(error2){return debug(`Failed to load source map for ${script.url}:`,error2),!1}}async loadAllSourceMaps(){let loaded=0;for(let scriptId of this.scripts.keys())await this.loadSourceMap(scriptId)&&loaded++;return loaded}originalToGenerated(originalSource,line,column=0){let normalizedSource=this._normalizeSourcePath(originalSource),scripts=this._findScriptsForSource(normalizedSource);if(scripts.length!==0)for(let script of scripts){if(!script.mappings)continue;let sourceIndex=script.originalSources.findIndex(s=>this._normalizeSourcePath(s)===normalizedSource||s.endsWith(normalizedSource)||normalizedSource.endsWith(s));if(sourceIndex===-1)continue;let bestMatch,bestDistance=1/0;for(let mapping of script.mappings)if(mapping.source===script.sourceMap?.sources[sourceIndex]&&mapping.originalLine!==void 0&&mapping.originalLine===line){let colDist=mapping.originalColumn!==void 0?Math.abs(mapping.originalColumn-column):0;colDist<bestDistance&&(bestDistance=colDist,bestMatch=mapping)}if(bestMatch)return{scriptId:script.scriptId,location:{line:bestMatch.generatedLine,column:bestMatch.generatedColumn}}}}async resolveLocationByUrl(url,line,column=1){let line0=Math.max(0,line-1),column0=Math.max(0,column-1),candidates=this.scriptsByUrl.get(url)||[];if(candidates.length===0)for(let script of this.scripts.values())(script.url===url||script.url.endsWith(url)||url.endsWith(script.url))&&candidates.push(script);for(let script of candidates){if(!await this.loadSourceMap(script.scriptId)||!script.mappings)continue;let resolved=this.generatedToOriginal(script.scriptId,line0,column0);if(resolved)return resolved}return null}generatedToOriginal(scriptId,line,column=0){let script=this.scripts.get(scriptId);if(!script?.mappings)return;let bestMatch,bestDistance=1/0;for(let mapping of script.mappings){if(mapping.generatedLine!==line||mapping.source===void 0)continue;let colDist=Math.abs(mapping.generatedColumn-column);colDist<bestDistance&&(bestDistance=colDist,bestMatch=mapping)}if(bestMatch&&bestMatch.source!==void 0&&bestMatch.originalLine!==void 0){let sourceIndex=script.sourceMap?.sources.indexOf(bestMatch.source);return{source:sourceIndex!==void 0&&sourceIndex>=0?script.originalSources[sourceIndex]:bestMatch.source,line:bestMatch.originalLine,column:bestMatch.originalColumn??0,name:bestMatch.name}}}getOriginalSources(){return Array.from(this.sourceToScripts.keys())}findScriptsForSource(sourcePattern){let normalized=this._normalizeSourcePath(sourcePattern);return this._findScriptsForSource(normalized)}hasSourceMaps(){for(let script of this.scripts.values())if(script.sourceMap)return!0;return!1}clear(){this.scripts.clear(),this.scriptsByUrl.clear(),this.sourceToScripts.clear(),this.fetchCache.clear()}_findScriptsForSource(normalizedSource){let exact=this.sourceToScripts.get(normalizedSource);if(exact&&exact.length>0)return exact;let results=[];for(let[source,scripts]of this.sourceToScripts.entries()){let normalizedKey=this._normalizeSourcePath(source);(normalizedKey.endsWith(normalizedSource)||normalizedSource.endsWith(normalizedKey))&&results.push(...scripts)}return results}_normalizeSourcePath(path3){let normalized=path3.replace(/^webpack:\/\/[^/]*\//,"").replace(/^file:\/\//,"").replace(/^\.*\//,"");for(normalized=normalized.replace(/\\/g,"/");normalized.startsWith("./");)normalized=normalized.slice(2);return normalized}_resolveSourcePath(source,sourceRoot,scriptUrl){return source.startsWith("webpack://")||source.startsWith("http://")||source.startsWith("https://")||sourceRoot&&(source=sourceRoot.replace(/\/$/,"")+"/"+source),source}async _fetchSourceMap(sourceMapURL,scriptUrl){if(sourceMapURL.startsWith("data:"))return this._parseDataUrl(sourceMapURL);let absoluteUrl=this._resolveUrl(sourceMapURL,scriptUrl);if(this.fetchCache.has(absoluteUrl))return this.fetchCache.get(absoluteUrl)||null;try{let sourceMap=null;if(this.customFetcher){let content=await this.customFetcher(absoluteUrl,scriptUrl);content&&(sourceMap=JSON.parse(content))}else this.page&&(sourceMap=await this._fetchViaBrowser(absoluteUrl));return this.fetchCache.set(absoluteUrl,sourceMap),sourceMap}catch(error2){return debug(`Failed to fetch source map from ${absoluteUrl}:`,error2),this.fetchCache.set(absoluteUrl,null),null}}_parseDataUrl(dataUrl){try{let match=dataUrl.match(/^data:[^,]*(?:;base64)?,(.*)$/);if(!match)return null;let isBase64=dataUrl.includes(";base64,"),data=match[1],json=isBase64?Buffer.from(data,"base64").toString("utf-8"):decodeURIComponent(data);return JSON.parse(json)}catch{return null}}_resolveUrl(url,baseUrl){if(url.startsWith("http://")||url.startsWith("https://"))return url;try{return new URL(url,baseUrl).href}catch{return baseUrl.replace(/[^/]*$/,"")+url}}async _fetchViaBrowser(url){if(!this.page)return null;try{let typedResult=await this.page.evaluate(async fetchUrl=>{try{let response=await fetch(fetchUrl);return response.ok?{data:await response.text()}:{error:`HTTP ${response.status}`}}catch(err){return{error:err.message||"Fetch failed"}}},url);return"error"in typedResult?(debug(`Browser fetch error for ${url}: ${typedResult.error}`),null):JSON.parse(typedResult.data)}catch(error2){return debug(`Failed to fetch ${url} via browser:`,error2),null}}};var V8API_DEFAULT_OPTIONS={maxDepth:3,maxProperties:50,maxArrayLength:100,maxStringLength:1e3},V8Api=class{cdp=null;enabled=!1;scripts=new Map;scriptsByUrl=new Map;eventHandlers={};options;cdpProvider;constructor(source,options){if(this.options={...V8API_DEFAULT_OPTIONS,...options},typeof source=="function")this.cdpProvider=source;else if(source&&typeof source.context=="function"){let page=source;this.cdpProvider=async()=>await page.context().newCDPSession(page)}else if(source&&typeof source.send=="function"){let session=source;this.cdp=session,this.cdpProvider=async()=>session}else throw new Error("V8Api: Invalid source. Expected Page, CDPSessionProvider, or ICDPSession.")}getOptions(){return{...this.options}}isEnabled(){return this.enabled}async getCdp(){return this.cdp||(this.cdp=await this.cdpProvider()),this.cdp}on(event,handler){this.eventHandlers[event]=handler}off(event){delete this.eventHandlers[event]}async enable(){if(this.enabled)return;let cdp=await this.getCdp();cdp.on("Debugger.scriptParsed",event=>{let parsed=event;if(this.scripts.set(parsed.scriptId,parsed),parsed.url){let existing=this.scriptsByUrl.get(parsed.url)||[];existing.push(parsed),this.scriptsByUrl.set(parsed.url,existing)}this.eventHandlers.scriptParsed&&this.eventHandlers.scriptParsed(parsed)}),cdp.on("Debugger.paused",event=>{let pausedEvent=event;this.eventHandlers.paused&&this.eventHandlers.paused(pausedEvent)}),cdp.on("Debugger.resumed",()=>{this.eventHandlers.resumed&&this.eventHandlers.resumed()}),await cdp.send("Debugger.enable",{maxScriptsCacheSize:1e8}),await cdp.send("Runtime.enable"),this.enabled=!0}async disable(){if(!(!this.enabled||!this.cdp)){try{await this.cdp.send("Debugger.disable"),await this.cdp.send("Runtime.disable")}catch{}this.scripts.clear(),this.scriptsByUrl.clear(),this.enabled=!1}}async detach(){if(await this.disable(),this.cdp){try{await this.cdp.detach()}catch{}this.cdp=null}}getScripts(){return Array.from(this.scripts.values())}getScript(scriptId){return this.scripts.get(scriptId)}findScriptsByUrl(urlPattern){let regex=new RegExp(urlPattern),results=[];for(let script of this.scripts.values())script.url&&regex.test(script.url)&&results.push(script);return results}async setBreakpointByUrl(options){let cdp=await this.getCdp(),params={lineNumber:options.lineNumber};options.urlRegex?params.urlRegex=options.urlRegex:options.url&&(params.url=options.url),options.columnNumber!==void 0&&(params.columnNumber=options.columnNumber),options.condition&&(params.condition=options.condition);let result=await cdp.send("Debugger.setBreakpointByUrl",params);return{breakpointId:result.breakpointId,locations:result.locations||[]}}async setBreakpoint(location,condition){let cdp=await this.getCdp(),params={location:{scriptId:location.scriptId,lineNumber:location.lineNumber,columnNumber:location.columnNumber}};condition&&(params.condition=condition);let result=await cdp.send("Debugger.setBreakpoint",params);return{breakpointId:result.breakpointId,actualLocation:result.actualLocation}}async removeBreakpoint(breakpointId){await(await this.getCdp()).send("Debugger.removeBreakpoint",{breakpointId})}async resume(){await(await this.getCdp()).send("Debugger.resume")}async stepOver(){await(await this.getCdp()).send("Debugger.stepOver")}async stepInto(){await(await this.getCdp()).send("Debugger.stepInto")}async stepOut(){await(await this.getCdp()).send("Debugger.stepOut")}async pause(){await(await this.getCdp()).send("Debugger.pause")}async setPauseOnExceptions(state){await(await this.getCdp()).send("Debugger.setPauseOnExceptions",{state})}async evaluateOnCallFrame(callFrameId,expression,options){let result=await(await this.getCdp()).send("Debugger.evaluateOnCallFrame",{callFrameId,expression,returnByValue:options?.returnByValue??!0,generatePreview:options?.generatePreview??!0,throwOnSideEffect:options?.throwOnSideEffect??!1});return{result:result.result,exceptionDetails:result.exceptionDetails}}async getProperties(objectId,options){let result=await(await this.getCdp()).send("Runtime.getProperties",{objectId,ownProperties:options?.ownProperties??!0,accessorPropertiesOnly:options?.accessorPropertiesOnly??!1,generatePreview:options?.generatePreview??!0});return{result:result.result||[],internalProperties:result.internalProperties,privateProperties:result.privateProperties}}async getScopeVariables(scope,options){if(!scope.object.objectId)return{};let opts={maxDepth:options?.maxDepth??this.options.maxDepth,maxProperties:options?.maxProperties??this.options.maxProperties,maxArrayLength:options?.maxArrayLength??this.options.maxArrayLength},{result}=await this.getProperties(scope.object.objectId,{ownProperties:!0,generatePreview:!0}),variables={},visited=new Set,propCount=0;for(let prop of result){if(propCount>=opts.maxProperties){variables.__truncated__=`${result.length-propCount} more properties`;break}prop.value&&(variables[prop.name]=await this.extractValueDeep(prop.value,opts.maxDepth,opts.maxProperties,opts.maxArrayLength,visited),propCount++)}return variables}extractValue(obj){return this._extractValueShallow(obj)}async extractValueDeep(obj,maxDepth,maxProperties,maxArrayLength,visited=new Set){let depth=maxDepth??this.options.maxDepth,props=maxProperties??this.options.maxProperties,arrLen=maxArrayLength??this.options.maxArrayLength;if(obj.value!==void 0)return typeof obj.value=="string"&&obj.value.length>this.options.maxStringLength?obj.value.slice(0,this.options.maxStringLength)+`... (${obj.value.length} chars)`:obj.value;if(obj.unserializableValue)return obj.unserializableValue==="NaN"?NaN:obj.unserializableValue==="Infinity"?1/0:obj.unserializableValue==="-Infinity"?-1/0:obj.unserializableValue==="-0"?-0:obj.unserializableValue.endsWith("n")?`BigInt(${obj.unserializableValue.slice(0,-1)})`:obj.unserializableValue;if(obj.subtype==="null")return null;if(obj.type!=="undefined"){if(obj.type==="function")return`[function${obj.description?`: ${obj.description.split(`
2
2
  `)[0]}`:""}]`;if(!obj.objectId)return this._extractValueShallow(obj);if(depth<=0)return this._getShallowDescription(obj);if(visited.has(obj.objectId))return"[Circular]";visited.add(obj.objectId);try{return obj.subtype==="array"?await this._extractArray(obj.objectId,depth-1,props,arrLen,visited):obj.subtype==="map"?await this._extractMap(obj.objectId,depth-1,props,arrLen,visited):obj.subtype==="set"?await this._extractSet(obj.objectId,depth-1,arrLen,visited):obj.subtype==="date"?obj.description||"[Date]":obj.subtype==="regexp"?obj.description||"[RegExp]":obj.subtype==="error"?obj.description||"[Error]":obj.subtype==="promise"?`[Promise: ${obj.description||"pending"}]`:obj.subtype==="node"||obj.className?.includes("Element")||obj.className?.includes("Node")?`[DOM: ${obj.description||obj.className||"Node"}]`:obj.type==="object"?await this._extractObject(obj.objectId,depth-1,props,arrLen,visited,obj.className):this._extractValueShallow(obj)}catch{return this._getShallowDescription(obj)}}}async _extractArray(objectId,maxDepth,maxProperties,maxArrayLength,visited){let{result}=await this.getProperties(objectId,{ownProperties:!0,generatePreview:!0}),arr=[],length=0;for(let prop of result)if(prop.name==="length"&&prop.value?.value!==void 0){length=prop.value.value;break}for(let prop of result){let index=parseInt(prop.name,10);if(!(isNaN(index)||index<0)){if(arr.length>=maxArrayLength)break;prop.value&&(arr[index]=await this.extractValueDeep(prop.value,maxDepth,maxProperties,maxArrayLength,visited))}}return length>maxArrayLength&&(arr.__truncated__=`${length-maxArrayLength} more items`),arr}async _extractMap(objectId,maxDepth,maxProperties,maxArrayLength,visited){let{internalProperties}=await this.getProperties(objectId,{ownProperties:!0,generatePreview:!0}),mapObj={__type__:"Map"},entries=[],entriesProp=internalProperties?.find(p=>p.name==="[[Entries]]");if(entriesProp?.value?.objectId){let{result:entryResults}=await this.getProperties(entriesProp.value.objectId,{ownProperties:!0,generatePreview:!0}),count=0;for(let entry of entryResults){if(count>=maxArrayLength)break;let index=parseInt(entry.name,10);if(isNaN(index)||!entry.value?.objectId)continue;let{result:kvResult}=await this.getProperties(entry.value.objectId,{ownProperties:!0,generatePreview:!0}),keyProp=kvResult.find(p=>p.name==="key"),valueProp=kvResult.find(p=>p.name==="value");if(keyProp?.value&&valueProp?.value){let key=await this.extractValueDeep(keyProp.value,maxDepth,maxProperties,maxArrayLength,visited),value=await this.extractValueDeep(valueProp.value,maxDepth,maxProperties,maxArrayLength,visited);entries.push([key,value])}count++}}return mapObj.entries=entries,mapObj}async _extractSet(objectId,maxDepth,maxArrayLength,visited){let{internalProperties}=await this.getProperties(objectId,{ownProperties:!0,generatePreview:!0}),setObj={__type__:"Set"},values=[],entriesProp=internalProperties?.find(p=>p.name==="[[Entries]]");if(entriesProp?.value?.objectId){let{result:entryResults}=await this.getProperties(entriesProp.value.objectId,{ownProperties:!0,generatePreview:!0}),count=0;for(let entry of entryResults){if(count>=maxArrayLength)break;let index=parseInt(entry.name,10);isNaN(index)||(entry.value&&values.push(await this.extractValueDeep(entry.value,maxDepth,50,maxArrayLength,visited)),count++)}}return setObj.values=values,setObj}async _extractObject(objectId,maxDepth,maxProperties,maxArrayLength,visited,className){let{result}=await this.getProperties(objectId,{ownProperties:!0,generatePreview:!0}),obj={};className&&className!=="Object"&&(obj.__class__=className);let count=0;for(let prop of result){if(count>=maxProperties){obj.__truncated__=`${result.length-count} more properties`;break}prop.isOwn&&(prop.name.startsWith("__")&&prop.name.endsWith("__")||prop.value&&(obj[prop.name]=await this.extractValueDeep(prop.value,maxDepth,maxProperties,maxArrayLength,visited),count++))}return obj}_extractValueShallow(obj){if(obj.value!==void 0)return obj.value;if(obj.unserializableValue)return obj.unserializableValue==="NaN"?NaN:obj.unserializableValue==="Infinity"?1/0:obj.unserializableValue==="-Infinity"?-1/0:obj.unserializableValue==="-0"?-0:obj.unserializableValue.endsWith("n")?`BigInt(${obj.unserializableValue.slice(0,-1)})`:obj.unserializableValue;if(obj.subtype==="null")return null;if(obj.type!=="undefined")return this._getShallowDescription(obj)}_getShallowDescription(obj){if(obj.description){let desc=obj.description.split(`
3
- `)[0];return desc.length>100?`[${obj.type}${obj.subtype?`:${obj.subtype}`:""}] ${desc.slice(0,100)}...`:`[${obj.type}${obj.subtype?`:${obj.subtype}`:""}] ${desc}`}return`[${obj.type}${obj.subtype?`:${obj.subtype}`:""}]`}async getScriptSource(scriptId){return await(await this.getCdp()).send("Debugger.getScriptSource",{scriptId})}async setScriptSource(scriptId,scriptSource,dryRun){let result=await(await this.getCdp()).send("Debugger.setScriptSource",{scriptId,scriptSource,dryRun:dryRun??!1});return{callFrames:result.callFrames,stackChanged:result.stackChanged,asyncStackTrace:result.asyncStackTrace,exceptionDetails:result.exceptionDetails}}};import*as fs from"node:fs";import*as http from"node:http";import*as https from"node:https";import*as path2 from"node:path";var ProbeKind=(ProbeKind2=>(ProbeKind2.TRACEPOINT="tracepoint",ProbeKind2.LOGPOINT="logpoint",ProbeKind2))(ProbeKind||{}),DEFAULT_NODE_DEBUG_CONFIG={maxSnapshots:1e3,maxCallStackDepth:20,maxFramesWithScopes:5,maxAsyncStackSegments:10,maxFramesPerAsyncSegment:10},STORES=new Map;function _generateId(){let t=Date.now(),r=Math.floor(Math.random()*1e6);return`${t.toString(36)}-${r.toString(36)}`}function _locationKey(urlPattern,lineNumber,columnNumber){return`${urlPattern}:${lineNumber}:${columnNumber}`}function _cdpConsoleTypeToLevelName(type){switch(type){case"error":return"error";case"warning":case"warn":return"warning";case"info":return"info";case"debug":return"debug";default:return"info"}}function _cdpArgsToText(args){return!args||args.length===0?"":args.map(a=>a.type==="string"&&a.value!==void 0||a.value!==void 0?String(a.value):a.description?a.description:"[object]").join(" ")}function _evaluateHitCondition(hitCondition,hitCount){try{let condition=hitCondition.trim();return/^[=<>!%]/.test(condition)&&(condition=`hitCount ${condition}`),!!new Function("hitCount",`return (${condition});`)(hitCount)}catch{return!1}}async function _getOtelTraceContext(session){let expression=`(function(){
3
+ `)[0];return desc.length>100?`[${obj.type}${obj.subtype?`:${obj.subtype}`:""}] ${desc.slice(0,100)}...`:`[${obj.type}${obj.subtype?`:${obj.subtype}`:""}] ${desc}`}return`[${obj.type}${obj.subtype?`:${obj.subtype}`:""}]`}async getScriptSource(scriptId){return await(await this.getCdp()).send("Debugger.getScriptSource",{scriptId})}async setScriptSource(scriptId,scriptSource,dryRun){let result=await(await this.getCdp()).send("Debugger.setScriptSource",{scriptId,scriptSource,dryRun:dryRun??!1});return{callFrames:result.callFrames,stackChanged:result.stackChanged,asyncStackTrace:result.asyncStackTrace,exceptionDetails:result.exceptionDetails}}};import*as fs from"node:fs";import*as http from"node:http";import*as https from"node:https";import*as path2 from"node:path";var ProbeKind=(ProbeKind2=>(ProbeKind2.TRACEPOINT="tracepoint",ProbeKind2.LOGPOINT="logpoint",ProbeKind2))(ProbeKind||{}),DEFAULT_NODE_DEBUG_CONFIG={maxSnapshots:1e3,maxCallStackDepth:20,maxFramesWithScopes:5,maxAsyncStackSegments:10,maxFramesPerAsyncSegment:10},STORES=new Map;function _generateId(){let t=Date.now(),r=Math.floor(Math.random()*1e6);return`${t.toString(36)}-${r.toString(36)}`}function _columnForLocationKey(column){return column==null||column===0?1:column}function _locationKey(urlPattern,lineNumber,columnNumber){return`${urlPattern}:${lineNumber}:${columnNumber}`}function _cdpConsoleTypeToLevelName(type){switch(type){case"error":return"error";case"warning":case"warn":return"warning";case"info":return"info";case"debug":return"debug";default:return"info"}}function _cdpArgsToText(args){return!args||args.length===0?"":args.map(a=>a.type==="string"&&a.value!==void 0||a.value!==void 0?String(a.value):a.description?a.description:"[object]").join(" ")}function _evaluateHitCondition(hitCondition,hitCount){try{let condition=hitCondition.trim();return/^[=<>!%]/.test(condition)&&(condition=`hitCount ${condition}`),!!new Function("hitCount",`return (${condition});`)(hitCount)}catch{return!1}}async function _getOtelTraceContext(session){let expression=`(function(){
4
4
  try {
5
5
  var api = require('@opentelemetry/api');
6
6
  var span = api.trace.getActiveSpan();
@@ -10,6 +10,6 @@ try {
10
10
  } catch (e) {
11
11
  return null;
12
12
  }
13
- })()`;try{let result=await session.send("Runtime.evaluate",{expression,returnByValue:!0,timeout:500});if(result.exceptionDetails)return null;let value=result.result?.value;if(value&&typeof value.traceId=="string"&&typeof value.spanId=="string")return{traceId:value.traceId,spanId:value.spanId}}catch{}return null}function _createNodeSourceMapFetcher(){return async(url,baseUrl)=>{let filePath=null;if(url.startsWith("file://"))filePath=url.replace("file://","");else if(url.startsWith("/")||url.match(/^[a-zA-Z]:\\/))filePath=url;else if(baseUrl.startsWith("file://")){let baseDir=path2.dirname(baseUrl.replace("file://",""));filePath=path2.resolve(baseDir,url)}else if(!url.startsWith("http://")&&!url.startsWith("https://")){let baseDir=path2.dirname(baseUrl.replace(/^file:\/\//,""));filePath=path2.resolve(baseDir,url)}if(filePath)try{return fs.readFileSync(filePath,"utf-8")}catch{}return url.startsWith("http://")||url.startsWith("https://")?new Promise(resolve2=>{let req=(url.startsWith("https://")?https:http).get(url,res=>{if(res.statusCode!==200){resolve2(null);return}let data="";res.on("data",chunk=>{data+=chunk}),res.on("end",()=>resolve2(data))});req.on("error",()=>resolve2(null)),req.setTimeout(5e3,()=>{req.destroy(),resolve2(null)})}):null}}async function _captureScopes(v8Api,callFrame,maxDepth=3){let scopeSnapshots=[];for(let scope of callFrame.scopeChain)if(!(scope.type==="global"||scope.type==="script"||scope.type==="with"||scope.type==="eval"||scope.type==="wasm-expression-stack")){if(scopeSnapshots.length>=maxDepth)break;try{let variables=await v8Api.getScopeVariables(scope),scopeVariables=[];for(let[name,value]of Object.entries(variables))scopeVariables.push({name,value,type:typeof value});scopeSnapshots.push({type:scope.type,name:scope.name,variables:scopeVariables})}catch{}}return scopeSnapshots}async function _callFrameToSnapshot(v8Api,frame,captureScopes,sourceMapResolver){let scopes=[];captureScopes&&(scopes=await _captureScopes(v8Api,frame));let originalLocation;if(sourceMapResolver){let resolved=sourceMapResolver.generatedToOriginal(frame.location.scriptId,frame.location.lineNumber,frame.location.columnNumber??0);resolved&&(originalLocation={source:resolved.source,line:resolved.line+1,column:resolved.column!==void 0?resolved.column+1:void 0,name:resolved.name})}return{functionName:frame.functionName||"(anonymous)",url:frame.url||"",lineNumber:frame.location.lineNumber+1,columnNumber:frame.location.columnNumber!==void 0?frame.location.columnNumber+1:void 0,scriptId:frame.location.scriptId,scopes,originalLocation}}function _convertAsyncStackTrace(asyncTrace,sourceMapResolver,maxSegments,maxFramesPerSegment){if(!asyncTrace)return;let maxSegs=maxSegments??DEFAULT_NODE_DEBUG_CONFIG.maxAsyncStackSegments,maxFrames=maxFramesPerSegment??DEFAULT_NODE_DEBUG_CONFIG.maxFramesPerAsyncSegment,segments=[],currentTrace=asyncTrace,segmentCount=0;for(;currentTrace&&segmentCount<maxSegs;){let asyncFrames=[];for(let frame of currentTrace.callFrames.slice(0,maxFrames)){let originalLocation;if(sourceMapResolver){let resolved=sourceMapResolver.generatedToOriginal(frame.location.scriptId,frame.location.lineNumber,frame.location.columnNumber??0);resolved&&(originalLocation={source:resolved.source,line:resolved.line+1,column:resolved.column!==void 0?resolved.column+1:void 0,name:resolved.name})}asyncFrames.push({functionName:frame.functionName||"(anonymous)",url:frame.url||"",lineNumber:frame.location.lineNumber+1,columnNumber:frame.location.columnNumber!==void 0?frame.location.columnNumber+1:void 0,originalLocation})}asyncFrames.length>0&&segments.push({description:currentTrace.description,callFrames:asyncFrames}),currentTrace=currentTrace.parent,segmentCount++}return segments.length===0?void 0:{segments}}async function _evaluateWatchExpressionsOnFrame(v8Api,callFrameId,watchExpressions){let results={};for(let watch of watchExpressions.values())try{let result=await v8Api.evaluateOnCallFrame(callFrameId,watch.expression);result.exceptionDetails?results[watch.expression]=`[Error: ${result.exceptionDetails.text||"Evaluation failed"}]`:results[watch.expression]=await v8Api.extractValueDeep(result.result,2)}catch(e){results[watch.expression]=`[Error: ${e.message||"Unknown error"}]`}return results}function getStoreKey(pid,wsUrl){return wsUrl||`pid:${pid}`}async function enableDebugging(storeKey,session,processInfo,v8Options,config){if(STORES.get(storeKey)?.enabled)return;let v8Api=new V8Api(session,v8Options),sourceMapResolver=new SourceMapResolver(_createNodeSourceMapFetcher()),mergedConfig={...DEFAULT_NODE_DEBUG_CONFIG,...config},store={v8Api,sourceMapResolver,probes:new Map,locationIndex:new Map,watchExpressions:new Map,snapshots:[],snapshotSequence:0,consoleMessages:[],consoleMessageSequence:0,config:mergedConfig,enabled:!1,sourceMapsLoaded:!1,exceptionBreakpoint:"none",session,processInfo};STORES.set(storeKey,store),await store.v8Api.enable(),session.on("Runtime.consoleAPICalled",params=>{let type=params.type||"log",args=params.args||[],text=_cdpArgsToText(args),levelName=_cdpConsoleTypeToLevelName(type),levelCode=ConsoleMessageLevel[levelName]?.code??1,location,stackTrace=params.stackTrace;if(stackTrace?.callFrames?.length){let frame=stackTrace.callFrames[0];location={url:frame.url||"",lineNumber:frame.lineNumber??0,columnNumber:frame.columnNumber??0}}store.consoleMessageSequence++,store.consoleMessages.push({type,text,level:{name:levelName,code:levelCode},location,timestamp:Date.now(),sequenceNumber:store.consoleMessageSequence}),store.consoleMessages.length>NODE_CONSOLE_MESSAGES_BUFFER_SIZE&&store.consoleMessages.splice(0,store.consoleMessages.length-NODE_CONSOLE_MESSAGES_BUFFER_SIZE)}),store.v8Api.on("scriptParsed",script=>{store.sourceMapResolver.registerScript(script)});for(let script of store.v8Api.getScripts())store.sourceMapResolver.registerScript(script);store.v8Api.on("paused",async event=>{let startTime=Date.now();try{let isException=event.reason==="exception"||event.reason==="promiseRejection",hitBreakpointIds=event.hitBreakpoints||[],hitProbes=[];for(let probe of store.probes.values()){if(!probe.enabled)continue;if(probe.v8BreakpointIds.some(id=>hitBreakpointIds.includes(id))){let conditionMet=!0;probe.hitCondition&&(conditionMet=_evaluateHitCondition(probe.hitCondition,probe.hitCount+1)),hitProbes.push({probe,conditionMet})}}let shouldCaptureBreakpoint=hitProbes.some(p=>p.conditionMet),shouldCaptureException=isException&&store.exceptionBreakpoint!=="none";for(let{probe}of hitProbes)probe.hitCount++,probe.lastHitAt=Date.now();if((shouldCaptureBreakpoint||shouldCaptureException)&&event.callFrames.length>0){let topFrame=event.callFrames[0],exceptionInfo;if(isException&&event.data){let excData=event.data;exceptionInfo={type:event.reason==="promiseRejection"?"promiseRejection":"exception",message:excData.description||excData.value||String(excData),name:excData.className,stack:excData.description}}let originalLocation,resolvedLoc=store.sourceMapResolver.generatedToOriginal(topFrame.location.scriptId,topFrame.location.lineNumber,topFrame.location.columnNumber??0);resolvedLoc&&(originalLocation={source:resolvedLoc.source,line:resolvedLoc.line+1,column:resolvedLoc.column!==void 0?resolvedLoc.column+1:void 0,name:resolvedLoc.name});let callStackFull=[],framesToProcess=event.callFrames.slice(0,store.config.maxCallStackDepth);for(let i=0;i<framesToProcess.length;i++)callStackFull.push(await _callFrameToSnapshot(store.v8Api,framesToProcess[i],i<store.config.maxFramesWithScopes,store.sourceMapResolver));let asyncStackTraceFull=_convertAsyncStackTrace(event.asyncStackTrace,store.sourceMapResolver,store.config.maxAsyncStackSegments,store.config.maxFramesPerAsyncSegment),traceContext=await _getOtelTraceContext(store.session),probesToCapture=hitProbes.filter(p=>p.conditionMet),snapshotCount=probesToCapture.length+(shouldCaptureException?1:0);for(let s=0;s<snapshotCount;s++){let probeId,isLogpoint,logResult,callStack,asyncStackTrace,watchResults;if(s<probesToCapture.length){let{probe}=probesToCapture[s];if(probeId=probe.id,isLogpoint=probe.kind==="logpoint",isLogpoint&&probe.logExpression)try{let evalResult=await store.v8Api.evaluateOnCallFrame(topFrame.callFrameId,probe.logExpression,{returnByValue:!0,generatePreview:!0});logResult=store.v8Api.extractValue(evalResult.result)}catch{logResult="[evaluation error]"}else logResult=void 0;isLogpoint?(callStack=[],asyncStackTrace=void 0,watchResults=void 0):(callStack=callStackFull,asyncStackTrace=asyncStackTraceFull,watchResults=store.watchExpressions.size>0?await _evaluateWatchExpressionsOnFrame(store.v8Api,topFrame.callFrameId,store.watchExpressions):void 0)}else probeId="__exception__",isLogpoint=!1,logResult=void 0,callStack=callStackFull,asyncStackTrace=asyncStackTraceFull,watchResults=store.watchExpressions.size>0?await _evaluateWatchExpressionsOnFrame(store.v8Api,topFrame.callFrameId,store.watchExpressions):void 0;let snapshot={id:_generateId(),probeId,timestamp:Date.now(),sequenceNumber:++store.snapshotSequence,url:topFrame.url||"",lineNumber:topFrame.location.lineNumber+1,columnNumber:topFrame.location.columnNumber!==void 0?topFrame.location.columnNumber+1:void 0,originalLocation,exception:exceptionInfo,callStack,asyncStackTrace,logResult,watchResults,captureTimeMs:Date.now()-startTime,traceContext:traceContext??void 0};store.snapshots.push(snapshot)}store.snapshots.length>store.config.maxSnapshots&&store.snapshots.splice(0,store.snapshots.length-store.config.maxSnapshots)}}finally{await store.v8Api.resume()}}),store.enabled=!0,store.sourceMapResolver.loadAllSourceMaps().then(()=>{store.sourceMapsLoaded=!0}).catch(()=>{})}async function disableDebugging(storeKey){let store=STORES.get(storeKey);if(store?.enabled){for(let entry of store.locationIndex.values())try{await store.v8Api.removeBreakpoint(entry.breakpointId)}catch{}store.locationIndex.clear(),store.probes.clear(),store.snapshots.length=0,store.snapshotSequence=0,store.consoleMessages.length=0,store.consoleMessageSequence=0,await store.v8Api.disable(),store.enabled=!1}}async function detachDebugging(storeKey){let store=STORES.get(storeKey);store&&(await disableDebugging(storeKey),await store.v8Api.detach(),STORES.delete(storeKey))}function isDebuggingEnabled(storeKey){return STORES.get(storeKey)?.enabled??!1}function getStore(storeKey){return STORES.get(storeKey)}async function resolveSourceLocation(storeKey,url,line,column=1){let store=STORES.get(storeKey);if(!store?.enabled)throw new Error("Not connected to Node.js process or debugging not enabled. Call debug_connect first.");let resolved=await store.sourceMapResolver.resolveLocationByUrl(url,line,column);return resolved?{source:resolved.source,line:resolved.line+1,column:resolved.column+1,name:resolved.name}:null}function listStoreKeys(){return Array.from(STORES.keys())}async function setExceptionBreakpoint(storeKey,state){let store=STORES.get(storeKey);if(!store?.enabled)throw new Error("Debugging is not enabled");await store.v8Api.setPauseOnExceptions(state),store.exceptionBreakpoint=state}function getExceptionBreakpoint(storeKey){return STORES.get(storeKey)?.exceptionBreakpoint??"none"}async function createProbe(storeKey,options){let store=STORES.get(storeKey);if(!store?.enabled)throw new Error("Debugging is not enabled");let probeId=_generateId(),columnNormalized=options.columnNumber??1,locationKey=_locationKey(options.urlPattern,options.lineNumber,columnNormalized),existingEntry=store.locationIndex.get(locationKey);if(existingEntry){existingEntry.refCount++;let probe2={id:probeId,kind:options.kind,enabled:!0,urlPattern:options.urlPattern,lineNumber:options.lineNumber,columnNumber:options.columnNumber,condition:options.condition,logExpression:options.logExpression,hitCondition:options.hitCondition,v8BreakpointIds:[existingEntry.breakpointId],resolvedLocations:existingEntry.resolvedLocations,hitCount:0,createdAt:Date.now()};return store.probes.set(probeId,probe2),probe2}let fullCondition=options.condition?`(${options.condition})`:"true",line0based=options.lineNumber-1,column0based=columnNormalized-1,resolved=store.sourceMapResolver.originalToGenerated(options.urlPattern,line0based,column0based),breakpointId,resolvedLocationsCount=0;if(resolved)try{breakpointId=(await store.v8Api.setBreakpoint({scriptId:resolved.scriptId,lineNumber:resolved.location.line,columnNumber:resolved.location.column},fullCondition)).breakpointId,resolvedLocationsCount=1}catch{let scriptUrl=store.sourceMapResolver.getScriptUrl(resolved.scriptId);if(scriptUrl){let result=await store.v8Api.setBreakpointByUrl({url:scriptUrl,lineNumber:resolved.location.line,columnNumber:resolved.location.column,condition:fullCondition});breakpointId=result.breakpointId,resolvedLocationsCount=result.locations.length}else throw new Error("Failed to set breakpoint at resolved location and could not fall back (script URL unknown). A probe may already exist at this line; remove it first or use a different line.")}else{let urlRegex=options.urlPattern.replace(/\\([.*+?^${}()|[\]\\/-])/g,"$1").replace(/[.*+?^${}()|[\]\\]/g,"\\$&").replace(/\\\*/g,".*").replace(/\\\?/g,"."),result=await store.v8Api.setBreakpointByUrl({urlRegex,lineNumber:options.lineNumber-1,columnNumber:options.columnNumber?options.columnNumber-1:void 0,condition:fullCondition});breakpointId=result.breakpointId,resolvedLocationsCount=result.locations.length}store.locationIndex.set(locationKey,{breakpointId,resolvedLocations:resolvedLocationsCount,refCount:1});let probe={id:probeId,kind:options.kind,enabled:!0,urlPattern:options.urlPattern,lineNumber:options.lineNumber,columnNumber:options.columnNumber,condition:options.condition,logExpression:options.logExpression,hitCondition:options.hitCondition,v8BreakpointIds:[breakpointId],resolvedLocations:resolvedLocationsCount,hitCount:0,createdAt:Date.now()};return store.probes.set(probeId,probe),probe}async function removeProbe(storeKey,probeId){let store=STORES.get(storeKey);if(!store)return!1;let probe=store.probes.get(probeId);if(!probe)return!1;let locationKey=_locationKey(probe.urlPattern,probe.lineNumber,probe.columnNumber??1),entry=store.locationIndex.get(locationKey);if(entry&&(entry.refCount--,entry.refCount===0)){try{await store.v8Api.removeBreakpoint(entry.breakpointId)}catch{}store.locationIndex.delete(locationKey)}return store.probes.delete(probeId),!0}function listProbes(storeKey){return Array.from(STORES.get(storeKey)?.probes.values()??[])}async function clearProbes(storeKey){let store=STORES.get(storeKey);if(!store)return 0;let count=store.probes.size;for(let entry of store.locationIndex.values())try{await store.v8Api.removeBreakpoint(entry.breakpointId)}catch{}return store.locationIndex.clear(),store.probes.clear(),count}function getSnapshots(storeKey){return[...STORES.get(storeKey)?.snapshots??[]]}function getSnapshotsByProbe(storeKey,probeId){return(STORES.get(storeKey)?.snapshots??[]).filter(s=>s.probeId===probeId)}function clearSnapshots(storeKey){let store=STORES.get(storeKey);if(!store)return 0;let count=store.snapshots.length;return store.snapshots.length=0,count}function clearSnapshotsByProbe(storeKey,probeId){let store=STORES.get(storeKey);if(!store)return 0;let before=store.snapshots.length;return store.snapshots=store.snapshots.filter(s=>s.probeId!==probeId),before-store.snapshots.length}function getSnapshotStats(storeKey){let store=STORES.get(storeKey);if(!store||store.snapshots.length===0)return{totalSnapshots:0,snapshotsByProbe:{},averageCaptureTimeMs:0};let snapshotsByProbe={},totalCaptureTime=0;for(let s of store.snapshots)snapshotsByProbe[s.probeId]=(snapshotsByProbe[s.probeId]||0)+1,totalCaptureTime+=s.captureTimeMs;return{totalSnapshots:store.snapshots.length,snapshotsByProbe,oldestTimestamp:store.snapshots[0].timestamp,newestTimestamp:store.snapshots[store.snapshots.length-1].timestamp,averageCaptureTimeMs:totalCaptureTime/store.snapshots.length}}function getConsoleMessages(storeKey){return[...STORES.get(storeKey)?.consoleMessages??[]]}function addWatchExpression(storeKey,expression){let store=STORES.get(storeKey);if(!store)throw new Error("Debug store not initialized");let id=_generateId(),watchExpr={id,expression,createdAt:Date.now()};return store.watchExpressions.set(id,watchExpr),watchExpr}function removeWatchExpression(storeKey,watchExpressionId){return STORES.get(storeKey)?.watchExpressions.delete(watchExpressionId)??!1}function listWatchExpressions(storeKey){return Array.from(STORES.get(storeKey)?.watchExpressions.values()??[])}function clearWatchExpressions(storeKey){let store=STORES.get(storeKey);if(!store)return 0;let count=store.watchExpressions.size;return store.watchExpressions.clear(),count}async function loadSourceMaps(storeKey){let store=STORES.get(storeKey);if(!store?.enabled)throw new Error("Debugging is not enabled");let loaded=await store.sourceMapResolver.loadAllSourceMaps(),sources=store.sourceMapResolver.getOriginalSources();return store.sourceMapsLoaded=!0,{loaded,sources}}function hasSourceMaps(storeKey){return STORES.get(storeKey)?.sourceMapResolver.hasSourceMaps()??!1}function getOriginalSources(storeKey){return STORES.get(storeKey)?.sourceMapResolver.getOriginalSources()??[]}function getScripts(storeKey){return STORES.get(storeKey)?.v8Api.getScripts()??[]}function wrapScriptInAsyncIIFE(script){return`(async function() { ${script} })()`}function formatEvaluationException(exc){let parts=[],text=exc.text??exc.description;text&&parts.push(text);let desc=exc.exception?.description;desc&&desc!==text&&parts.push(desc);let className=exc.exception?.className;className&&!parts.some(p=>p.includes(className))&&parts.push(className),parts.length===0&&parts.push(JSON.stringify(exc));let stack=exc.stackTrace?.callFrames?.slice(0,5).map(f=>` at ${f.functionName??"?"} (${f.url??"?"}:${f.lineNumber??0})`).join(`
13
+ })()`;try{let result=await session.send("Runtime.evaluate",{expression,returnByValue:!0,timeout:500});if(result.exceptionDetails)return null;let value=result.result?.value;if(value&&typeof value.traceId=="string"&&typeof value.spanId=="string")return{traceId:value.traceId,spanId:value.spanId}}catch{}return null}function _createNodeSourceMapFetcher(){return async(url,baseUrl)=>{let filePath=null;if(url.startsWith("file://"))filePath=url.replace("file://","");else if(url.startsWith("/")||url.match(/^[a-zA-Z]:\\/))filePath=url;else if(baseUrl.startsWith("file://")){let baseDir=path2.dirname(baseUrl.replace("file://",""));filePath=path2.resolve(baseDir,url)}else if(!url.startsWith("http://")&&!url.startsWith("https://")){let baseDir=path2.dirname(baseUrl.replace(/^file:\/\//,""));filePath=path2.resolve(baseDir,url)}if(filePath)try{return fs.readFileSync(filePath,"utf-8")}catch{}return url.startsWith("http://")||url.startsWith("https://")?new Promise(resolve2=>{let req=(url.startsWith("https://")?https:http).get(url,res=>{if(res.statusCode!==200){resolve2(null);return}let data="";res.on("data",chunk=>{data+=chunk}),res.on("end",()=>resolve2(data))});req.on("error",()=>resolve2(null)),req.setTimeout(5e3,()=>{req.destroy(),resolve2(null)})}):null}}async function _captureScopes(v8Api,callFrame,maxDepth=3){let scopeSnapshots=[];for(let scope of callFrame.scopeChain)if(!(scope.type==="global"||scope.type==="script"||scope.type==="with"||scope.type==="eval"||scope.type==="wasm-expression-stack")){if(scopeSnapshots.length>=maxDepth)break;try{let variables=await v8Api.getScopeVariables(scope),scopeVariables=[];for(let[name,value]of Object.entries(variables))scopeVariables.push({name,value,type:typeof value});scopeSnapshots.push({type:scope.type,name:scope.name,variables:scopeVariables})}catch{}}return scopeSnapshots}async function _callFrameToSnapshot(v8Api,frame,captureScopes,sourceMapResolver){let scopes=[];captureScopes&&(scopes=await _captureScopes(v8Api,frame));let originalLocation;if(sourceMapResolver){let resolved=sourceMapResolver.generatedToOriginal(frame.location.scriptId,frame.location.lineNumber,frame.location.columnNumber??0);resolved&&(originalLocation={source:resolved.source,line:resolved.line+1,column:resolved.column!==void 0?resolved.column+1:void 0,name:resolved.name})}return{functionName:frame.functionName||"(anonymous)",url:frame.url||"",lineNumber:frame.location.lineNumber+1,columnNumber:frame.location.columnNumber!==void 0?frame.location.columnNumber+1:void 0,scriptId:frame.location.scriptId,scopes,originalLocation}}function _convertAsyncStackTrace(asyncTrace,sourceMapResolver,maxSegments,maxFramesPerSegment){if(!asyncTrace)return;let maxSegs=maxSegments??DEFAULT_NODE_DEBUG_CONFIG.maxAsyncStackSegments,maxFrames=maxFramesPerSegment??DEFAULT_NODE_DEBUG_CONFIG.maxFramesPerAsyncSegment,segments=[],currentTrace=asyncTrace,segmentCount=0;for(;currentTrace&&segmentCount<maxSegs;){let asyncFrames=[];for(let frame of currentTrace.callFrames.slice(0,maxFrames)){let originalLocation;if(sourceMapResolver){let resolved=sourceMapResolver.generatedToOriginal(frame.location.scriptId,frame.location.lineNumber,frame.location.columnNumber??0);resolved&&(originalLocation={source:resolved.source,line:resolved.line+1,column:resolved.column!==void 0?resolved.column+1:void 0,name:resolved.name})}asyncFrames.push({functionName:frame.functionName||"(anonymous)",url:frame.url||"",lineNumber:frame.location.lineNumber+1,columnNumber:frame.location.columnNumber!==void 0?frame.location.columnNumber+1:void 0,originalLocation})}asyncFrames.length>0&&segments.push({description:currentTrace.description,callFrames:asyncFrames}),currentTrace=currentTrace.parent,segmentCount++}return segments.length===0?void 0:{segments}}async function _evaluateWatchExpressionsOnFrame(v8Api,callFrameId,watchExpressions){let results={};for(let watch of watchExpressions.values())try{let result=await v8Api.evaluateOnCallFrame(callFrameId,watch.expression);result.exceptionDetails?results[watch.expression]=`[Error: ${result.exceptionDetails.text||"Evaluation failed"}]`:results[watch.expression]=await v8Api.extractValueDeep(result.result,2)}catch(e){results[watch.expression]=`[Error: ${e.message||"Unknown error"}]`}return results}function getStoreKey(pid,wsUrl){return wsUrl||`pid:${pid}`}async function enableDebugging(storeKey,session,processInfo,v8Options,config){if(STORES.get(storeKey)?.enabled)return;let v8Api=new V8Api(session,v8Options),sourceMapResolver=new SourceMapResolver(_createNodeSourceMapFetcher()),mergedConfig={...DEFAULT_NODE_DEBUG_CONFIG,...config},store={v8Api,sourceMapResolver,probes:new Map,locationIndex:new Map,watchExpressions:new Map,snapshots:[],snapshotSequence:0,consoleMessages:[],consoleMessageSequence:0,config:mergedConfig,enabled:!1,sourceMapsLoaded:!1,exceptionBreakpoint:"none",session,processInfo};STORES.set(storeKey,store),await store.v8Api.enable(),session.on("Runtime.consoleAPICalled",params=>{let type=params.type||"log",args=params.args||[],text=_cdpArgsToText(args),levelName=_cdpConsoleTypeToLevelName(type),levelCode=ConsoleMessageLevel[levelName]?.code??1,location,stackTrace=params.stackTrace;if(stackTrace?.callFrames?.length){let frame=stackTrace.callFrames[0];location={url:frame.url||"",lineNumber:frame.lineNumber??0,columnNumber:frame.columnNumber??0}}store.consoleMessageSequence++,store.consoleMessages.push({type,text,level:{name:levelName,code:levelCode},location,timestamp:Date.now(),sequenceNumber:store.consoleMessageSequence}),store.consoleMessages.length>NODE_CONSOLE_MESSAGES_BUFFER_SIZE&&store.consoleMessages.splice(0,store.consoleMessages.length-NODE_CONSOLE_MESSAGES_BUFFER_SIZE)}),store.v8Api.on("scriptParsed",script=>{store.sourceMapResolver.registerScript(script)});for(let script of store.v8Api.getScripts())store.sourceMapResolver.registerScript(script);store.v8Api.on("paused",async event=>{let startTime=Date.now();try{let isException=event.reason==="exception"||event.reason==="promiseRejection",hitBreakpointIds=event.hitBreakpoints||[],hitProbes=[];for(let probe of store.probes.values()){if(!probe.enabled)continue;if(probe.v8BreakpointIds.some(id=>hitBreakpointIds.includes(id))){let conditionMet=!0;probe.hitCondition&&(conditionMet=_evaluateHitCondition(probe.hitCondition,probe.hitCount+1)),hitProbes.push({probe,conditionMet})}}let shouldCaptureBreakpoint=hitProbes.some(p=>p.conditionMet),shouldCaptureException=isException&&store.exceptionBreakpoint!=="none";for(let{probe}of hitProbes)probe.hitCount++,probe.lastHitAt=Date.now();if((shouldCaptureBreakpoint||shouldCaptureException)&&event.callFrames.length>0){let topFrame=event.callFrames[0],exceptionInfo;if(isException&&event.data){let excData=event.data;exceptionInfo={type:event.reason==="promiseRejection"?"promiseRejection":"exception",message:excData.description||excData.value||String(excData),name:excData.className,stack:excData.description}}let originalLocation,resolvedLoc=store.sourceMapResolver.generatedToOriginal(topFrame.location.scriptId,topFrame.location.lineNumber,topFrame.location.columnNumber??0);resolvedLoc&&(originalLocation={source:resolvedLoc.source,line:resolvedLoc.line+1,column:resolvedLoc.column!==void 0?resolvedLoc.column+1:void 0,name:resolvedLoc.name});let callStackFull=[],framesToProcess=event.callFrames.slice(0,store.config.maxCallStackDepth);for(let i=0;i<framesToProcess.length;i++)callStackFull.push(await _callFrameToSnapshot(store.v8Api,framesToProcess[i],i<store.config.maxFramesWithScopes,store.sourceMapResolver));let asyncStackTraceFull=_convertAsyncStackTrace(event.asyncStackTrace,store.sourceMapResolver,store.config.maxAsyncStackSegments,store.config.maxFramesPerAsyncSegment),traceContext=await _getOtelTraceContext(store.session),probesToCapture=hitProbes.filter(p=>p.conditionMet),snapshotCount=probesToCapture.length+(shouldCaptureException?1:0);for(let s=0;s<snapshotCount;s++){let probeId,isLogpoint,logResult,callStack,asyncStackTrace,watchResults;if(s<probesToCapture.length){let{probe}=probesToCapture[s];if(probeId=probe.id,isLogpoint=probe.kind==="logpoint",isLogpoint&&probe.logExpression)try{let evalResult=await store.v8Api.evaluateOnCallFrame(topFrame.callFrameId,probe.logExpression,{returnByValue:!0,generatePreview:!0});logResult=store.v8Api.extractValue(evalResult.result)}catch{logResult="[evaluation error]"}else logResult=void 0;isLogpoint?(callStack=[],asyncStackTrace=void 0,watchResults=void 0):(callStack=callStackFull,asyncStackTrace=asyncStackTraceFull,watchResults=store.watchExpressions.size>0?await _evaluateWatchExpressionsOnFrame(store.v8Api,topFrame.callFrameId,store.watchExpressions):void 0)}else probeId="__exception__",isLogpoint=!1,logResult=void 0,callStack=callStackFull,asyncStackTrace=asyncStackTraceFull,watchResults=store.watchExpressions.size>0?await _evaluateWatchExpressionsOnFrame(store.v8Api,topFrame.callFrameId,store.watchExpressions):void 0;let snapshot={id:_generateId(),probeId,timestamp:Date.now(),sequenceNumber:++store.snapshotSequence,url:topFrame.url||"",lineNumber:topFrame.location.lineNumber+1,columnNumber:topFrame.location.columnNumber!==void 0?topFrame.location.columnNumber+1:void 0,originalLocation,exception:exceptionInfo,callStack,asyncStackTrace,logResult,watchResults,captureTimeMs:Date.now()-startTime,traceContext:traceContext??void 0};store.snapshots.push(snapshot)}store.snapshots.length>store.config.maxSnapshots&&store.snapshots.splice(0,store.snapshots.length-store.config.maxSnapshots)}}finally{await store.v8Api.resume()}}),store.enabled=!0,store.sourceMapResolver.loadAllSourceMaps().then(()=>{store.sourceMapsLoaded=!0}).catch(()=>{})}async function disableDebugging(storeKey){let store=STORES.get(storeKey);if(store?.enabled){for(let entry of store.locationIndex.values())try{await store.v8Api.removeBreakpoint(entry.breakpointId)}catch{}store.locationIndex.clear(),store.probes.clear(),store.snapshots.length=0,store.snapshotSequence=0,store.consoleMessages.length=0,store.consoleMessageSequence=0,await store.v8Api.disable(),store.enabled=!1}}async function detachDebugging(storeKey){let store=STORES.get(storeKey);store&&(await disableDebugging(storeKey),await store.v8Api.detach(),STORES.delete(storeKey))}function isDebuggingEnabled(storeKey){return STORES.get(storeKey)?.enabled??!1}function getStore(storeKey){return STORES.get(storeKey)}async function resolveSourceLocation(storeKey,url,line,column=1){let store=STORES.get(storeKey);if(!store?.enabled)throw new Error("Not connected to Node.js process or debugging not enabled. Call debug_connect first.");let resolved=await store.sourceMapResolver.resolveLocationByUrl(url,line,column);return resolved?{source:resolved.source,line:resolved.line+1,column:resolved.column+1,name:resolved.name}:null}function listStoreKeys(){return Array.from(STORES.keys())}async function setExceptionBreakpoint(storeKey,state){let store=STORES.get(storeKey);if(!store?.enabled)throw new Error("Debugging is not enabled");await store.v8Api.setPauseOnExceptions(state),store.exceptionBreakpoint=state}function getExceptionBreakpoint(storeKey){return STORES.get(storeKey)?.exceptionBreakpoint??"none"}async function createProbe(storeKey,options){let store=STORES.get(storeKey);if(!store?.enabled)throw new Error("Debugging is not enabled");let probeId=_generateId(),columnForKey=_columnForLocationKey(options.columnNumber),locationKey=_locationKey(options.urlPattern,options.lineNumber,columnForKey),existingEntry=store.locationIndex.get(locationKey);if(existingEntry){existingEntry.refCount++;let probe2={id:probeId,kind:options.kind,enabled:!0,urlPattern:options.urlPattern,lineNumber:options.lineNumber,columnNumber:options.columnNumber,condition:options.condition,logExpression:options.logExpression,hitCondition:options.hitCondition,v8BreakpointIds:[existingEntry.breakpointId],resolvedLocations:existingEntry.resolvedLocations,hitCount:0,createdAt:Date.now()};return store.probes.set(probeId,probe2),probe2}let fullCondition=options.condition?`(${options.condition})`:"true",line0based=options.lineNumber-1,column0based=columnForKey-1,resolved=store.sourceMapResolver.originalToGenerated(options.urlPattern,line0based,column0based),breakpointId,resolvedLocationsCount=0;if(resolved)try{breakpointId=(await store.v8Api.setBreakpoint({scriptId:resolved.scriptId,lineNumber:resolved.location.line,columnNumber:resolved.location.column},fullCondition)).breakpointId,resolvedLocationsCount=1}catch{let scriptUrl=store.sourceMapResolver.getScriptUrl(resolved.scriptId);if(scriptUrl){let result=await store.v8Api.setBreakpointByUrl({url:scriptUrl,lineNumber:resolved.location.line,columnNumber:resolved.location.column,condition:fullCondition});breakpointId=result.breakpointId,resolvedLocationsCount=result.locations.length}else throw new Error("Failed to set breakpoint at resolved location and could not fall back (script URL unknown). A probe may already exist at this line; remove it first or use a different line.")}else{let urlRegex=options.urlPattern.replace(/\\([.*+?^${}()|[\]\\/-])/g,"$1").replace(/[.*+?^${}()|[\]\\]/g,"\\$&").replace(/\\\*/g,".*").replace(/\\\?/g,"."),result=await store.v8Api.setBreakpointByUrl({urlRegex,lineNumber:options.lineNumber-1,columnNumber:options.columnNumber!=null?Math.max(0,options.columnNumber-1):void 0,condition:fullCondition});breakpointId=result.breakpointId,resolvedLocationsCount=result.locations.length}store.locationIndex.set(locationKey,{breakpointId,resolvedLocations:resolvedLocationsCount,refCount:1});let probe={id:probeId,kind:options.kind,enabled:!0,urlPattern:options.urlPattern,lineNumber:options.lineNumber,columnNumber:options.columnNumber,condition:options.condition,logExpression:options.logExpression,hitCondition:options.hitCondition,v8BreakpointIds:[breakpointId],resolvedLocations:resolvedLocationsCount,hitCount:0,createdAt:Date.now()};return store.probes.set(probeId,probe),probe}async function removeProbe(storeKey,probeId){let store=STORES.get(storeKey);if(!store)return!1;let probe=store.probes.get(probeId);if(!probe)return!1;let locationKey=_locationKey(probe.urlPattern,probe.lineNumber,_columnForLocationKey(probe.columnNumber)),entry=store.locationIndex.get(locationKey);if(entry&&(entry.refCount--,entry.refCount===0)){try{await store.v8Api.removeBreakpoint(entry.breakpointId)}catch{}store.locationIndex.delete(locationKey)}return store.probes.delete(probeId),!0}function listProbes(storeKey){return Array.from(STORES.get(storeKey)?.probes.values()??[])}async function clearProbes(storeKey){let store=STORES.get(storeKey);if(!store)return 0;let count=store.probes.size;for(let entry of store.locationIndex.values())try{await store.v8Api.removeBreakpoint(entry.breakpointId)}catch{}return store.locationIndex.clear(),store.probes.clear(),count}function getSnapshots(storeKey){return[...STORES.get(storeKey)?.snapshots??[]]}function getSnapshotsByProbe(storeKey,probeId){return(STORES.get(storeKey)?.snapshots??[]).filter(s=>s.probeId===probeId)}function clearSnapshots(storeKey){let store=STORES.get(storeKey);if(!store)return 0;let count=store.snapshots.length;return store.snapshots.length=0,count}function clearSnapshotsByProbe(storeKey,probeId){let store=STORES.get(storeKey);if(!store)return 0;let before=store.snapshots.length;return store.snapshots=store.snapshots.filter(s=>s.probeId!==probeId),before-store.snapshots.length}function getSnapshotStats(storeKey){let store=STORES.get(storeKey);if(!store||store.snapshots.length===0)return{totalSnapshots:0,snapshotsByProbe:{},averageCaptureTimeMs:0};let snapshotsByProbe={},totalCaptureTime=0;for(let s of store.snapshots)snapshotsByProbe[s.probeId]=(snapshotsByProbe[s.probeId]||0)+1,totalCaptureTime+=s.captureTimeMs;return{totalSnapshots:store.snapshots.length,snapshotsByProbe,oldestTimestamp:store.snapshots[0].timestamp,newestTimestamp:store.snapshots[store.snapshots.length-1].timestamp,averageCaptureTimeMs:totalCaptureTime/store.snapshots.length}}function getConsoleMessages(storeKey){return[...STORES.get(storeKey)?.consoleMessages??[]]}function addWatchExpression(storeKey,expression){let store=STORES.get(storeKey);if(!store)throw new Error("Debug store not initialized");let id=_generateId(),watchExpr={id,expression,createdAt:Date.now()};return store.watchExpressions.set(id,watchExpr),watchExpr}function removeWatchExpression(storeKey,watchExpressionId){return STORES.get(storeKey)?.watchExpressions.delete(watchExpressionId)??!1}function listWatchExpressions(storeKey){return Array.from(STORES.get(storeKey)?.watchExpressions.values()??[])}function clearWatchExpressions(storeKey){let store=STORES.get(storeKey);if(!store)return 0;let count=store.watchExpressions.size;return store.watchExpressions.clear(),count}async function loadSourceMaps(storeKey){let store=STORES.get(storeKey);if(!store?.enabled)throw new Error("Debugging is not enabled");let loaded=await store.sourceMapResolver.loadAllSourceMaps(),sources=store.sourceMapResolver.getOriginalSources();return store.sourceMapsLoaded=!0,{loaded,sources}}function hasSourceMaps(storeKey){return STORES.get(storeKey)?.sourceMapResolver.hasSourceMaps()??!1}function getOriginalSources(storeKey){return STORES.get(storeKey)?.sourceMapResolver.getOriginalSources()??[]}function getScripts(storeKey){return STORES.get(storeKey)?.v8Api.getScripts()??[]}function wrapScriptInAsyncIIFE(script){return`(async function() { ${script} })()`}function formatEvaluationException(exc){let parts=[],text=exc.text??exc.description;text&&parts.push(text);let desc=exc.exception?.description;desc&&desc!==text&&parts.push(desc);let className=exc.exception?.className;className&&!parts.some(p=>p.includes(className))&&parts.push(className),parts.length===0&&parts.push(JSON.stringify(exc));let stack=exc.stackTrace?.callFrames?.slice(0,5).map(f=>` at ${f.functionName??"?"} (${f.url??"?"}:${f.lineNumber??0})`).join(`
14
14
  `);return stack&&parts.push(`Stack:
15
15
  ${stack}`),parts.join(" \u2014 ")}async function evaluateInNode(storeKey,expression,timeoutMs=5e3){let store=STORES.get(storeKey);if(!store?.enabled)throw new Error("Not connected to Node.js process or debugging not enabled. Call debug_connect first.");let codeToRun=wrapScriptInAsyncIIFE(expression),result=await store.session.send("Runtime.evaluate",{expression:codeToRun,returnByValue:!0,awaitPromise:!0,timeout:Math.min(timeoutMs,3e4)});if(result.exceptionDetails){let exc=result.exceptionDetails,message=formatEvaluationException(exc);throw new Error(`Node evaluation failed: ${message}`)}return store.v8Api.extractValue(result.result)}export{PORT,TOOL_OUTPUT_SCHEMA_DISABLE,AVAILABLE_TOOL_DOMAINS,PLATFORM,SESSION_IDLE_SECONDS,SESSION_IDLE_CHECK_SECONDS,SESSION_CLOSE_ON_SOCKET_CLOSE,BROWSER_HEADLESS_ENABLE,BROWSER_PERSISTENT_ENABLE,BROWSER_PERSISTENT_USER_DATA_DIR,BROWSER_USE_INSTALLED_ON_SYSTEM,BROWSER_EXECUTABLE_PATH,BROWSER_LOCALE,BROWSER_CONSOLE_MESSAGES_BUFFER_SIZE,BROWSER_HTTP_REQUESTS_BUFFER_SIZE,NODE_CONSOLE_MESSAGES_BUFFER_SIZE,NODE_INSPECTOR_HOST,OTEL_ENABLE,OTEL_SERVICE_NAME,OTEL_SERVICE_VERSION,OTEL_ASSETS_DIR,OTEL_INSTRUMENTATION_USER_INTERACTION_EVENTS,OTEL_EXPORTER_TYPE,OTEL_EXPORTER_HTTP_URL,OTEL_EXPORTER_HTTP_HEADERS,AWS_REGION,AWS_PROFILE,AMAZON_BEDROCK_ENABLE,AMAZON_BEDROCK_IMAGE_EMBED_MODEL_ID,AMAZON_BEDROCK_TEXT_EMBED_MODEL_ID,AMAZON_BEDROCK_VISION_MODEL_ID,FIGMA_ACCESS_TOKEN,FIGMA_API_BASE_URL,DAEMON_PORT,DAEMON_SESSION_IDLE_SECONDS,DAEMON_SESSION_IDLE_CHECK_SECONDS,enable,disable,isDebugEnabled,debug,info,warn,error,toJson,V8Api,SourceMapResolver,ConsoleMessageLevelName,ConsoleMessageLevel,ProbeKind,DEFAULT_NODE_DEBUG_CONFIG,getStoreKey,enableDebugging,disableDebugging,detachDebugging,isDebuggingEnabled,getStore,resolveSourceLocation,listStoreKeys,setExceptionBreakpoint,getExceptionBreakpoint,createProbe,removeProbe,listProbes,clearProbes,getSnapshots,getSnapshotsByProbe,clearSnapshots,clearSnapshotsByProbe,getSnapshotStats,getConsoleMessages,addWatchExpression,removeWatchExpression,listWatchExpressions,clearWatchExpressions,loadSourceMaps,hasSourceMaps,getOriginalSources,getScripts,evaluateInNode};
@@ -1 +1 @@
1
- import{DEFAULT_NODE_DEBUG_CONFIG,ProbeKind,addWatchExpression,clearProbes,clearSnapshots,clearSnapshotsByProbe,clearWatchExpressions,createProbe,detachDebugging,disableDebugging,enableDebugging,evaluateInNode,getConsoleMessages,getExceptionBreakpoint,getOriginalSources,getScripts,getSnapshotStats,getSnapshots,getSnapshotsByProbe,getStore,getStoreKey,hasSourceMaps,isDebuggingEnabled,listProbes,listStoreKeys,listWatchExpressions,loadSourceMaps,removeProbe,removeWatchExpression,resolveSourceLocation,setExceptionBreakpoint}from"./core-247YVH6X.js";export{DEFAULT_NODE_DEBUG_CONFIG,ProbeKind,addWatchExpression,clearProbes,clearSnapshots,clearSnapshotsByProbe,clearWatchExpressions,createProbe,detachDebugging,disableDebugging,enableDebugging,evaluateInNode,getConsoleMessages,getExceptionBreakpoint,getOriginalSources,getScripts,getSnapshotStats,getSnapshots,getSnapshotsByProbe,getStore,getStoreKey,hasSourceMaps,isDebuggingEnabled,listProbes,listStoreKeys,listWatchExpressions,loadSourceMaps,removeProbe,removeWatchExpression,resolveSourceLocation,setExceptionBreakpoint};
1
+ import{DEFAULT_NODE_DEBUG_CONFIG,ProbeKind,addWatchExpression,clearProbes,clearSnapshots,clearSnapshotsByProbe,clearWatchExpressions,createProbe,detachDebugging,disableDebugging,enableDebugging,evaluateInNode,getConsoleMessages,getExceptionBreakpoint,getOriginalSources,getScripts,getSnapshotStats,getSnapshots,getSnapshotsByProbe,getStore,getStoreKey,hasSourceMaps,isDebuggingEnabled,listProbes,listStoreKeys,listWatchExpressions,loadSourceMaps,removeProbe,removeWatchExpression,resolveSourceLocation,setExceptionBreakpoint}from"./core-DOXUXYCD.js";export{DEFAULT_NODE_DEBUG_CONFIG,ProbeKind,addWatchExpression,clearProbes,clearSnapshots,clearSnapshotsByProbe,clearWatchExpressions,createProbe,detachDebugging,disableDebugging,enableDebugging,evaluateInNode,getConsoleMessages,getExceptionBreakpoint,getOriginalSources,getScripts,getSnapshotStats,getSnapshots,getSnapshotsByProbe,getStore,getStoreKey,hasSourceMaps,isDebuggingEnabled,listProbes,listStoreKeys,listWatchExpressions,loadSourceMaps,removeProbe,removeWatchExpression,resolveSourceLocation,setExceptionBreakpoint};