Skip to content

Releases: aeroxy/chrome-devtools-cli

chrome-devtools-cli v0.2.1

16 May 07:48

Choose a tag to compare

1. High-Level Summary (TL;DR)

  • Impact: High - This is a major structural refactoring of how commands are executed, how results are bubbled up, and how the tool provides observability.
  • Key Changes:
    • Structured Results: Commands now return a typed CommandResult containing metadata like navigated_to and error_code instead of plain strings.
    • Centralized Execution: Introduced executor.rs to handle target resolution, session attachment, and unified command dispatching.
    • Telemetry Logging: Added an asynchronous background worker to record CLI command metrics (success/fail, duration) to local files.
    • Direct File Output: Added --output (-o) flags to commands (screenshot, snapshot, evaluate, navigate) for saving output directly to disk via tokio::fs.
    • Stable Error Codes: Introduced ErrorCode for machine-parseable error identification.

2. Visual Overview (Code & Logic Map)

This diagram illustrates the new execution pipeline, highlighting the centralized execution loop and the flow of the new structured CommandResult.

Daemon Command Execution-2026-05-16-074724

3. Detailed Change Analysis

🎯 Core Execution Pipeline

  • What Changed: Replaced disparate target-resolution and CDP session-attachment logic across commands with a unified entry point in src/commands/executor.rs.
    • Source: executor.rs, commands/mod.rs
    • The execute_command() function automatically clears stale CdpClient events to prevent memory leaks in daemon mode, attaches to targets, runs inner_execute(), and safely detaches upon completion.
  • What Changed: Added CdpClientTrait in src/cdp.rs to abstract CDP operations. This is a foundational step for dependency injection and mocking CDP connections in future testing.

📦 Structured Returns & Error Handling

  • What Changed: Instead of commands returning Result<String>, they now return Result<CommandResult>. This struct encapsulates the text output, target ID, and navigation changes.
    • Source: result.rs, protocol.rs
  • What Changed: Added a standardized ErrorCode enum and typed CliError to replace generic anyhow errors in key paths. This enables downstream consumers (like an MCP server) to programmatically handle errors (e.g., ErrorCode::ChromeConnection = 2).
    • Source: error.rs

💾 File Output & Command Flags

  • What Changed: Enhanced commands to support writing their outputs directly to disk instead of exclusively printing to stdout. tokio::fs::write is utilized for async I/O. Added a -t flag to evaluate to track URL changes triggered by script execution.
Command New Flags Description
screenshot --output, -o Saves the Base64/binary image directly to the specified path.
snapshot --output, -o Saves the JSON/text accessibility tree directly to the specified path.
evaluate --output, -o, -t Saves result to file. Tracks navigations with -t (--track-navigation).
navigate --output, -o Writes the success/result message to a file.

📊 Telemetry & Daemon Reliability

  • What Changed: Created a best-effort, non-blocking telemetry system utilizing an MPSC channel. A background worker thread opens log files in ~/.chrome-devtools-cli/logs and flushes command usage statistics (duration, success/failure).
    • Source: telemetry.rs
  • What Changed: Exposed Daemon timeouts as environment variables to allow fine-tuning for slower environments (e.g., CI/CD).

Daemon Configuration:

Environment Variable Default Value Description
DAEMON_WAIT_TIMEOUT_SECS 5 Maximum seconds to wait for a daemon to spawn.
DAEMON_IDLE_TIMEOUT_SECS 300 Maximum idle seconds before the daemon terminates itself.

Dependencies Added:

Package Old Version New Version Purpose
chrono None 0.4.44 Used in telemetry.rs for timestamping log entries.

4. Impact & Risk Assessment

  • ⚠️ Breaking Changes (Protocol): The DaemonResponse JSON structure has been modified. Two new fields (navigated_to and error_code) have been added. Any external script strictly parsing the IPC socket responses might need updates, although the changes are additive.
  • 🐛 Testing Suggestions:
    • File I/O Verification: Test the --output flag on screenshot and snapshot with both valid and invalid (permission denied) file paths to ensure the async write handles errors gracefully.
    • Telemetry Logs: Run a few commands and inspect ~/.chrome-devtools-cli/logs to verify that the MPSC worker successfully writes log lines and doesn't block execution.
    • Navigation Tracking: Use evaluate -t "window.location.href = 'https://example.com'" and verify that the navigated_to field in the response accurately captures the URL change.

chrome-devtools-cli v0.2.0

12 May 16:41

Choose a tag to compare

1. High-Level Summary (TL;DR)

  • Impact: Medium - Introduces cross-platform support for the background daemon and improves connection stability.
  • Key Changes:
    • ✨ Added Windows support by replacing Unix domain sockets with local TCP loops for Windows environments.
    • 🛡️ Improved daemon startup resiliency by implementing an exponential backoff with jitter strategy in wait_for_daemon().
    • ♻️ Refactored the daemon loop in src/daemon.rs by extracting request handling into handle_connection().
    • 🛠️ Enhanced fallback execution in src/main.rs by routing failures cleanly through run_direct_fallback().

2. Visual Overview (Code & Logic Map)

Daemon-Client Connection

3. Detailed Change Analysis

🖥️ Cross-Platform IPC Architecture

  • What Changed: The application historically relied on UnixStream for CLI-to-daemon communication. This PR introduces conditional compilation (#[cfg(windows)] and #[cfg(unix)]) to use a TcpStream bound to 127.0.0.1:0 on Windows, while preserving UnixStream for Linux/macOS. Additionally, the daemon process on Windows is now spawned with the CREATE_NO_WINDOW flag (0x08000000).
  • Source Files: src/client.rs, src/daemon.rs, src/protocol.rs.
Platform Protocol Connection Artifact Process Flag
Unix UnixStream / UnixListener /tmp/chrome-devtools-daemon.sock Default
Windows TcpStream / TcpListener /tmp/chrome-devtools-daemon.addr 0x08000000 (No Window)

⏳ Resilient Daemon Connections

  • What Changed: Updated the polling logic inside wait_for_daemon(). Instead of a static 100ms delay, the client now utilizes an exponential backoff (starting at 50ms, doubling up to 500ms) paired with sub-millisecond jitter derived from SystemTime::now().
  • Source File: src/client.rs.

♻️ Daemon Loop Refactoring

  • What Changed: Extracted the massive inline loop body of run_daemon() into a new state-driven function called handle_connection(). A run_accept_loop_body! macro was created to orchestrate connection acceptance. A new ConnectionOutcome enum controls whether the loop should Continue or exit via Fatal.
  • Source File: src/daemon.rs.

⚙️ CLI Execution & Fallback Routing

  • What Changed: Added run_direct_fallback() to cleanly handle scenarios where the daemon fails to boot (e.g. timeout or permission issues). Error handling for CLI help and version output (ErrorKind::DisplayHelp / ErrorKind::DisplayVersion) was streamlined to exit immediately without noisy error rendering.
  • Source File: src/main.rs.

4. Impact & Risk Assessment

  • Breaking Changes: None. This is a purely architectural and platform-support improvement.
  • Testing Suggestions:
    • Windows Environment: Validate that the daemon successfully spawns invisibly and communicates via TCP over localhost.
    • Fallback Logic: Intentionally block the daemon port/socket creation and verify that the CLI correctly warns the user and completes the command using run_direct_fallback().
    • Concurrency: Trigger multiple CLI commands concurrently in a fresh environment to ensure the exponential backoff jitter prevents thundering herd issues on daemon spawn.

chrome-devtools-cli v0.1.3

09 May 07:51

Choose a tag to compare

New commands

  • list-3p-tools — lists custom developer tools exposed by the page via window.__dtmcp.toolGroup
  • execute-3p-tool <name> <params> — executes a named tool via window.__dtmcp.executeTool(name, params) with a JSON params string

Improvements

Client-Server Data Transfer-2026-05-09-080509
  • Automatic dialog handlingevaluate no longer hangs or fails when a script triggers alert, confirm, or prompt. Pass --dialog-action accept, --dialog-action dismiss, or a custom string (used as the prompt input) to handle dialogs automatically.
Client-Server Data Transfer-2026-05-09-080537
  • Native <option> clickingclick now detects <option> elements and selects them by updating the parent <select> value and dispatching native input/change events, instead of attempting a synthetic mouse click that browsers ignore.
  • Environment variable support--ws-endpoint, --user-data-dir, and --channel can now be set via CHROME_WS_ENDPOINT, CHROME_USER_DATA_DIR, and CHROME_CHANNEL environment variables.

chrome-devtools-cli v0.1.2

29 Apr 15:34

Choose a tag to compare

This release focuses on significantly improving reliability, interaction robustness, and the Developer/AI Agent Experience (Agent UX).

What's new

  • Agent UX & Help Improvements: Automatically dumps the full help menu to stderr on invalid commands, preventing AI agents from wasting tokens on "guess-and-check" loops.
  • In-band Agent Hints: The evaluate command now detects common DOM traversal scripts (querySelector, etc.) and JavaScript exceptions, providing dynamic hints to use the token-efficient snapshot, click, and fill commands instead.
  • Rock-solid Daemon: The background daemon now binds its Unix socket instantly and connects to Chrome lazily. This eliminates timeouts caused by macOS "Allow Incoming Network Connections" dialogs. The daemon also automatically shuts down and recovers if Chrome crashes or the WebSocket closes.
  • Advanced Form Filling: The fill command natively handles <select> dropdowns (by value or text) and toggles <input type="checkbox"> and <input type="radio"> using "true"/"false" strings.
  • Global Dialog Prevention: Proactively detects open JavaScript dialogs (alerts, confirms). Commands like click or fill will now fail immediately with a helpful error rather than hanging indefinitely, and evaluate suggests using --dialog-action.

chrome-devtools-cli v0.1.1

23 Apr 02:32

Choose a tag to compare

This release introduces new interaction capabilities and improves asynchronous event handling.

What's new

  • Coordinate clicking: New click-at <x> <y> command for precise interaction when element selectors aren't sufficient.
  • Auto-dialog handling: New --dialog-action <accept|dismiss|text> flag for the evaluate command to automatically handle JavaScript alerts, confirms, and prompts.
  • Enhanced typing: Added --submit-key <key> flag to type-text to press keys like Enter or Tab immediately after typing.
  • Asynchronous events: Refactored the internal CDP client to support listening for protocol events (like dialogs) during command execution.

Core benefits

  • Native performance: Lightweight native binary with zero runtime dependencies.
  • Agent-first architecture: Deterministic [target:word-pair] page pinning and accessibility tree snapshot command for low-token-cost context.
  • Persistent connection: Background daemon maintains a single WebSocket connection to Chrome.

chrome-devtools-cli v0.1.0

15 Apr 13:24

Choose a tag to compare

Control Chrome from the terminal.

How it works

The CLI auto-connects to an existing Chrome browser by reading DevToolsActivePort from Chrome's user data directory — no manual WebSocket URL needed. On first run it spawns a background daemon that holds a persistent connection, so Chrome only prompts for DevTools access once. Subsequent commands reuse that connection with near-zero latency.

Page targeting

Every command prints a [target:red-snake]-style name — a deterministic word-pair derived from the page's internal ID. Pass --target red-snake to subsequent commands to stay on the same tab regardless of how Chrome reorders its pages.

Commands

Navigation: navigate, navigate --back/--forward/--reload, new-page, close-page, select-page, list-pages

Inspection: screenshot, screenshot --full-page, evaluate, snapshot

Interaction: click, fill, type-text, press-key, hover

Viewport: resize, wait-for

Prerequisites

Enable remote debugging in Chrome: open chrome://inspect/#remote-debugging and turn on the remote debugging server.

Installation

Homebrew (macOS)

brew tap aeroxy/chrome-devtools-cli
brew install chrome-devtools

Cargo

cargo install chrome-devtools-cli

Build from source

cargo build --release