Back to docs

Changelog

Version history for CBrowser. See What-Is-CBrowser for an overview. Every release, including v18.80 to v19.3, which this page does not cover yet, is listed on GitHub Releases.


v20.0.0 (October 2026)

20.0 is a breaking release. Most of it makes commands that used to report success without doing the work either do it or fail with a non-zero exit. CLI-Reference describes every command as it now behaves.

Breaking changes

Install

  • cbrowser needs Node.js 20.9 or newer. Node 18 has been end of life since April 2025, and sharp 0.35, the image library cbrowser uses, no longer supports it. Stay on cbrowser 19.x if you need Node 18

Defaults

  • Pages render at 1920x1080 by default (was 1280x800), the size desktop means everywhere else. To keep the old size, set CBROWSER_VIEWPORT_WIDTH and CBROWSER_VIEWPORT_HEIGHT, or viewport in the config file. Visual baselines already captured compare at their recorded size, and personas keep their own screen sizes
  • There is no built-in locale or timezone. Pages render in the host's locale and timezone unless --locale, --timezone, CBROWSER_LOCALE, CBROWSER_TIMEZONE or the config file sets one. Before, en-US and America/Denver applied wherever defaults did
  • A one-off --device or --geo no longer carries over to later commands. Only device set and geo set persist
  • Size names mean the same size in every tool: mobile is 393x852, tablet 834x1194 and desktop 1920x1080. The old sizes keep names: tablet-sm is 768x1024 and desktop-md 1440x900. desktop-xl is 2560x1440, and the visual_baseline tool's desktop-lg is now 1920x1080 (was 2560x1440)
  • responsive (the CLI, the library and the responsive_test MCP tool) renders the mobile and tablet presets as their device: user agent, touch and pixel ratio. They no longer set reduced motion. Pages that adapt to touch or to the user agent look different than before
  • diff renders at 1920x1080 (was 1280x720), like cross-browser
  • Journeys in compare-personas, competitive-benchmark and empathy-audit start with a fresh browser profile, so each persona arrives as a new visitor. cognitive-journey does the same unless you pass --persistent

An Anthropic API key is required

  • explore, competitive-benchmark (the CLI, the library and the competitive_benchmark MCP tool) and the library's CBrowser.journey() refuse without an Anthropic API key. Their keyless modes are removed. They reported a goal as reached whenever a goal word appeared on the page: "sign up for free trial" on a lamp shop with no sign-up came back as achieved
  • A cognitive journey that fails now fails, instead of falling back to the keyless mode. In competitive-benchmark, that site's result names the error

Exit codes

  • Commands that fail exit 1 where they used to exit 0: a failed perf audit or visual compare, any failed parallel run, a failed script step, a failed chaos run, a failed --step-through step, an unsuccessful explore, an ai-benchmark site that could not be scored, a navigate that landed on a different page, a daemon stop that failed, session commands on an unknown name, an ai click that was refused or missed, and repair-tests --auto-apply that leaves tests failing
  • An unknown subcommand exits 1 for persona, session, cookie, device, geo, visual, ai-visual, record, webhook, parallel, ai, a11y, har and network
  • daemon status exits 1 when no daemon is running
  • With a daemon running, a click, fill, hover, run or navigate that fails exits 1 (it exited 0). A click through the daemon no longer hovers menu parents first
  • While a daemon runs, script, ai, explore, analyze, generate, hunt-bugs, chaos, a11y, perf, visual and reset exit 1 and ask you to stop it, since they would open a second browser on its profile
  • record start, record stop and record save exit 1. Each command is its own process, so they never recorded anything. Write the flow as a test instead. record list and record generate still work

Flags

  • Commands that check their flags reject flags they never read. --quiet is gone, since nothing read it. test-suite and cognitive-journey reject the flags they do not read, for example test-suite --persona
  • An out-of-range or non-numeric --threshold, or a --sensitivity other than low, medium or high, exits 1. flaky-check --threshold is a percentage from 0 to 100; visual compare and ai-visual take 0 to 1
  • extract accepts only text, links, headings, images or forms. Anything else used to return the whole page text. generate rejects an unknown --format
  • Commands that cannot honour a browser flag refuse it and say why:
    • cross-browser and diff refuse --browser (use --browsers)
    • responsive refuses --device and --viewport (use --viewports)
    • ai-visual test and ai-visual suite refuse --browser, --device and --viewport: a test renders as its baseline was captured
    • parallel devices refuses --device and --viewport
    • perf-baseline save, compare-personas and competitive-benchmark refuse --browser
    • ai-benchmark refuses --viewport and --browser
    • perf-regression refuses --device, --viewport and --browser: it renders as its baseline was captured
    • coverage --sitemap refuses all four, since no browser runs
  • capture start through a running daemon exits 1 on --viewport, --device or --browser. The daemon's browser keeps the settings it started with
  • agent-ready-audit --geo-region exits 1 when no proxy is configured, instead of running from your own address
  • repair-tests --output needs --auto-apply, and is refused before anything runs
  • A malformed --width or --height is an error instead of falling back to 1920x1080
  • ai-visual capture with both --device and --viewport uses the viewport's size. The device's size used to win
  • cognitive-journey runs headless when there is no display, unless you pass --no-headless

Output

  • --plain and --json-output turn pass, fail and warning marks into [PASS], [FAIL] and [WARN] instead of deleting them, and keep line breaks
  • With --json-output, extract returns its data in data. It used to return text lines in data.output
  • With --html and an --output file whose name ends in .html, the HTML report goes to <name>.report.html instead of overwriting the JSON report
  • Commands run through the daemon print their status lines, such as "Connected to running daemon", on stderr instead of stdout. evaluate through the daemon prints a string bare, as it does without one
  • repair-tests saves its report with --json-out <file>. --json now prints the report

Webhooks and export

  • webhook add defaults to --events test.fail (was test.fail,journey.complete). It refuses a URL that is not http or https, a URL with a user name or password, an event no command sends, and an unknown --format
  • The JUnit export marks every failed test as a failure, including one with no error message

MCP tools

  • The local stdio server (npx cbrowser mcp-server) registers the same tools as the hosted servers: 130, plus 7 that keep their state in the local process. It used to serve its own copy of 82 tools. Its responses now have the hosted shapes, so navigate can report success: false
  • compare_personas_record_result and compare_personas_summarize are removed. Nothing could create the session they needed, so both always answered "Session not found"
  • Red-zone refusals from click, smart_click, press_key, type_text, drag and evaluate_script share one shape: isError: true, success: false, the tool name, zone: "red", the reason, and howToRun naming force: true. click and smart_click refusals are now tool errors, and on the hosted servers a refused call is refunded
  • get_network_requests returns the newest 50 requests (was the oldest 50)
  • manage_cookies set writes a session cookie unless you pass expires (it wrote a 24-hour cookie). delete with a domain leaves cookies of the same name on other domains
  • In visual_baseline, the device names mobile, tablet and desktop emulate the device (user agent, touch, pixel ratio) instead of only sizing the page, and an unknown device name is an error
  • empathy_audit reports device: null when no device was set. It used to say "desktop"
  • The five Enterprise marketing placeholder tools in the public package now use the names the Enterprise server serves, and their parameters changed: marketing_influence_matrix, marketing_lever_analysis, marketing_funnel_analyze, marketing_compete and marketing_discover_status. They were marketing_campaign_influence_matrix, marketing_campaign_levers, marketing_funnel_analysis, marketing_competitive_compare and marketing_audience_discover_status

CI

  • The GitHub Action's sensitivity input is removed. test-suite never read it

Added

  • cbrowser ask "<question>" sends a question to cbrowser.ai and prints an answer grounded in these docs, with its sources (--context, --json). The question_answer MCP tool now works the same way from the local stdio server
  • cbrowser scroll <top|bottom|up|down> [px]. It runs through the daemon when one is running
  • network list lists the newest requests first and takes --filter, --all and --json
  • daemon start --timeout sets the idle timeout (minutes, or 90s, 45m, 2h), and daemon status shows it. daemon start also passes --browser, --no-headless, --locale, --timezone and --geo to the daemon's browser
  • test-suite saves each run, so export junit and export tap have results to export, and sends test.pass or test.fail to the webhooks subscribed to it. cognitive-journey sends journey.complete
  • --viewport takes size names (mobile, tablet, desktop-md and the rest) on every command
  • Flags can be written --flag=value
  • explore and cognitive-journey accept --url for the start URL
  • cognitive-journey --replay-trace replays a recorded journey with no model calls and no API key. --trace prints where the trace was written
  • test-suite uses --browser, --geo, --locale and --timezone
  • empathy-audit: --goal is optional (without it the page is checked and no key is needed), --scope is checked, and --device reaches the audit. agent-ready-audit passes --device and --locale to the audit
  • analyze --output <file> saves the analysis as JSON, and with --json-output the analysis is in data. The GitHub Action's url mode now writes it
  • perf-baseline save records the device and size, and perf-regression renders with them
  • New device presets from Playwright 1.64: the iPhone 17 family, iPhone Air and Pixel 10 Pro
  • MCP: list_devices lists the device presets and the size presets
  • MCP: navigate takes device and viewport, on the hosted servers too. A hosted call with an existing session token refuses instead of relaunching a browser that may hold a login; the local server relaunches its browser with the new settings
  • MCP: evaluate_script runs scripts the way cbrowser evaluate does (expressions, statements, functions, a top-level return) and takes args
  • MCP: smart_click takes force and retryDelay
  • MCP: capture_start takes the CLI's start and stop triggers (after, afterElement, afterDelay, untilElement, untilElementGone, untilIdle, timeout) and device. Its options have camelCase names; the snake_case names still work. capture_stop reports which trigger started and stopped the capture and whether a trigger timed out
  • MCP: assert takes caseSensitive, responsive_test takes wait, waitFor and sensitivity, chaos_test takes failApis, and manage_cookies set takes expires

Fixed

  • Environment variables and the config file apply. Every CLI command ignored CBROWSER_DEVICE, CBROWSER_LOCALE, CBROWSER_TIMEZONE, CBROWSER_BROWSER, CBROWSER_HEADLESS, CBROWSER_RECORD_VIDEO and a config file's device
  • Restoring the session no longer puts the last run's page size back over an explicit --device or --viewport
  • geo set persists for later commands. Before, it changed nothing and reported success
  • A flag that takes no value no longer swallows the next word: screenshot --no-restore out.png kept restore on and lost the path
  • Commands that check their flags accept --no-color, --plain and --json-output. Before, --no-color failed with "does not support --color"
  • evaluate through the daemon keeps --arg, --url, --wait-for, --timeout, --raw, --json and --expect-truthy. Before, an --expect-truthy check passed on a falsy result
  • Every millisecond --timeout reads 30s as 30 seconds. It was 30 milliseconds
  • type --delay works. It was always 50 ms
  • flaky-check --threshold 0.2 was read as 0, which flagged every test
  • empathy-audit reads --personas. It used to run every persona
  • cognitive-journey --replay-trace replays the trace. It used to start a live, paid run
  • ab, flaky-check, diff, cross-browser, responsive, ai-visual, coverage, parallel, repair-tests, perf-baseline and compare-personas use --headless, --browser, --device and --viewport where they can. Before, ab --viewport 400x700 rendered 1920 wide
  • competitive-benchmark passes --device and --viewport to every journey, and ai-benchmark passes --device to every audit
  • run handles back, forward, reload, select, wait for and scroll, and a failed click or fill inside run is a failure
  • install-skill and sync-skill download first and change nothing when the download fails. They used to delete the installed skill first
  • Through the daemon, every routed command honours --url, eval works, a relative screenshot path is saved where you ran the command, extract prints its data, and one missed health check no longer orphans a running daemon
  • cognitive-journey exits non-zero when its capture fails, even if the goal was reached
  • capture through the daemon applies --attention-overlay and records with the daemon's own browser engine
  • cookie delete --domain treats .example.com and example.com as the same domain
  • Smart visual baselines record their device and size, and smart regression and transport-map comparisons render at them. They always rendered at 1920x1080
  • MCP: press_key goes through the same keyboard safety check as type_text, the CLI and the daemon, and writes an audit entry. type_text with delay: 0 types with no delay (it used 50 ms). press_key, type_text, drag and upload_file report success: true
  • MCP: a device name means the same preset in every tool, in any case
  • MCP: visual_cognitive_story, site_cognitive_assessment and empathy_audit report the device and page size they rendered at
  • MCP: security_audit on the local stdio server scans every registered tool
  • Errors from ai find, ai click, smart-click and script go to stderr
  • The help no longer lists smart-baseline or transport-map commands (they are the MCP tools visual_baseline, visual_regression and transport_map) and names the commands the daemon runs
  • The Dockerfile builds on the Playwright 1.64.1 image, matching the browsers cbrowser expects

v19.4 to v19.6 (October 2026)

Devices and viewport (v19.6)

  • About 200 device presets, up from 12: the iPhone 16 family, Pixel 8 to 10, Galaxy foldables, iPad Pro 13, iPad mini, Surface and laptops from Chrome DevTools' device list, plus Playwright's own list. Phones and tablets have landscape presets too
  • Device names ignore case and spaces: --device "iPhone 16" is iphone-16
  • An unknown device name is an error naming the closest presets, in the CLI, the MCP tools' device parameter, CBROWSER_DEVICE and the config file. Before, it rendered at the 1280x800 desktop size and reported success
  • device list prints one line per preset and takes a filter: cbrowser device list pixel
  • --viewport WIDTHxHEIGHT is a global flag. It works wherever --device does: the browser commands (navigate, screenshot, evaluate, keyboard and the rest), test-suite, cognitive-journey and daemon start. With --device, it sets the size and the device keeps its pixel ratio, touch and user agent. Before, evaluate and keyboard refused it, and with a device the preset's size silently won
  • test-suite and cognitive-journey now use --device; before, they ignored it
  • daemon start takes --device and --viewport

evaluate (v19.6)

  • Scripts that contain functions return their value: function t() { return document.title }; t(), a function expression called later, .map(a => a.pathname), and immediately invoked functions. Before, they threw or printed nothing
  • Through the daemon, evaluate handles scripts the same way, and results such as 0, false and "" print

Console and terminal output (v19.5)

  • cbrowser console lists the daemon tab's console messages, with --filter, --clear and --json
  • Text from a page can no longer drive your terminal: control and bidirectional-override characters in CLI output are printed as visible escapes

HAR, network and the daemon (v19.4.3)

  • har and network record through the daemon. Without one they exit 1 and say so; before, har start printed "started" and recorded nothing
  • The daemon accepts commands only with a token from its private state file. Stop and restart a daemon started by an older version

MCP tools (v19.4.1, v19.4.2)

  • responsive_test and empathy_audit apply WCAG 2.5.8's spacing exception, counting inline links as neighbours
  • page_understand reads word breaks from the gaps actually drawn on screen
  • list_baselines includes smart baselines
  • Buttons styled as dangerous get no exploratory click
  • Motion barriers are typed as timing problems
  • Performance averages are rounded where they are computed

Hosting and releases (v19.4.0)

  • Hosted Enterprise has unlimited tool use
  • npm releases are published from GitHub Actions with provenance

v18.79 (August 2026)

  • Sequential Transport Chain expanded from six layers to eight
  • motorProcedure (Motor Procedure) β€” split out of Motor, because hitting a target and completing a sequence fail for different reasons; scored against the proceduralFluency trait
  • readingAttention (Reading Attention) β€” split out of Readability, because decoding text and holding your place in it are different abilities; scored against the sustainedAttention trait
  • Chain order is now: saliency, cognitive load, decision, motor, motor procedure, frustration, readability, reading attention

v18.70 (July 2026)

  • Screen capture β€” capture start / capture stop / capture status records the screen to GIF, animated WebP or WebM (MP4 needs a full ffmpeg; the bundled one does WebM)
  • Capture targets: the whole viewport, a device preset, a fixed --region rect, or --element, whose crop follows the element as it moves
  • Declarative bounds β€” --duration, --after, --after-element, --after-delay, --until-element, --until-element-gone, --until-idle, all under --timeout; a trigger that never fires still writes the manifest and exits non-zero
  • Frame manifest β€” manifest.json beside the JPEG frames, with per-frame timestamp, crop rect and SSIM against the previous frame, plus change points, frame gaps and correlated console/network events
  • --capture on test-suite and cognitive-journey, with --capture-fps, --capture-format and --capture-out
  • capture_start, capture_stop and capture_status MCP tools (screen_capture category, tier 2)
  • Daemon-routed live capture β€” navigate, click, fill, keyboard and press from separate invocations drive the recorded page; an open-ended capture requires cbrowser daemon start
  • keyboard command β€” key sequences of chords, named keys and literal text, with --selector, --hold, --repeat and --delay
  • evaluate upgraded β€” --file, --arg, --json, --raw, --wait-for and --expect-truthy
  • Fixed: daemon start was broken by a bare require() in an ESM module

v18.60+ (April 2026)

  • question_answer tool β€” ask questions about CBrowser docs
  • device parameter on empathy_audit and agent_ready_audit for mobile WCAG testing
  • WCAG-accurate scoring: proper contrast ratio calculation, AA vs AAA touch target thresholds
  • Skip link exemption in barrier detection
  • Centralized tool result auto-save via tier-gate wrapper
  • Per-site analytics dashboard with 6 report tabs
  • AI interpretation on all dashboard widgets
  • FTS5 knowledge base (291 pages indexed)
  • Prompt library with voting and copy tracking
  • Visual report image interpretation via Claude Vision

v18.35 (March 2026)

v18.24–18.28 (February 2026)

  • Cognitive Optimal Transport β€” Wasserstein-based persona distance and attention maps
  • Visual Transport Map (Tool-Transport-Map) β€” shows WHERE content moved between screenshots
  • Attention analysis with saliency heatmaps (Tool-Attention-Analysis)
  • 6-layer Sequential CTC: saliency, cognitive load, decision, motor, frustration, readability

v17.x (January 2026)

  • 25 cognitive traits (expanded from 12) with research citations
  • Trait reference matrix β€” 5 behavioral levels per trait
  • Trait correlations β€” automatic adjustment of related traits
  • Schwartz's 10 universal values framework (Values-Framework)
  • Custom persona creation via questionnaire (Persona-Questionnaire)
  • 130 MCP tools total

v16.x (December 2025)

  • Persona questionnaire β€” research-backed custom persona creation
  • AskUserQuestion integration for persona creation
  • Tool count: 107 MCP tools

v11.x (October 2025)

  • Self-efficacy trait β€” Bandura (1977) belief in problem-solving ability
  • Satisficing trait β€” Simon (1956) "good enough" decisions
  • Trust calibration β€” Fogg (2003) website trust with 8 signal types
  • Interrupt recovery β€” Mark (2005) task resumption after distraction
  • 12 core cognitive traits

v10.x (September 2025)

  • Persona aliases for empathy audit (motor-tremor, low-vision, adhd)
  • Research-grounded scoring with 13+ academic citations
  • Banner blindness and tunnel vision simulation
  • WebGazer saliency for gaze prediction
  • Dual-process theory (System 1/2) simulation
  • GOMS/KLM keystroke-level timing

v9.x (August 2025)

  • Agent-ready audit, competitive benchmark, accessibility empathy mode
  • Chrome extension for hybrid automation
  • Deterministic cognitive journeys (all AI-driven)
  • API-free persona comparison via session bridge

v8.x (July 2025)

  • Cognitive user simulation with traits
  • Vision mode for screenshot understanding
  • Hover-before-click for dropdown navigation
  • Daemon mode for persistent browser sessions
  • Abandonment detection

v7.x (June 2025)

  • Claude skill system
  • AI visual regression
  • Cross-browser testing (Chrome, Firefox, Safari)
  • Responsive testing (mobile, tablet, desktop)
  • A/B comparison
  • Auth0 OAuth for claude.ai

v6.x (May 2025)

From the Blog