Skip to content

Releases: obra/superpowers-chrome

v2.1.0 - Dialog handling

14 May 05:13

Choose a tag to compare

Added

  • Dialog handling. JS dialogs (alert / confirm / prompt / beforeunload), WebUSB / Bluetooth / Serial / HID device choosers, permission prompts (camera / microphone / notifications / geolocation / clipboard — via a document_start JS-API shim), and HTTP basic-auth challenges no longer wedge the CDP connection. Each dialog is surfaced as a synthetic "page" that the agent interacts with using the existing click and type actions against a small dialog::* selector grammar: dialog::accept, dialog::dismiss, dialog::prompt, dialog::device[id="..."], dialog::username, dialog::password. While a dialog is open, page-targeted actions (extract, screenshot, eval, click <real-selector>, etc.) return a clear refusal that includes the dialog content and handling instructions; browser-targeted actions (list_tabs, new_tab, close_tab, etc.) pass through unaffected. See docs/superpowers/specs/2026-05-13-dialog-handling-design.md for the full design.

Changed

  • The pooled CDP connection now enables Runtime (in addition to Page / DeviceAccess / Fetch) so that Runtime.addBinding can plumb the permission-shim binding into page main worlds. Required for Chrome 148+.
  • Page-targeted actions that encounter an open dialog throw a typed DialogRefusedError from the session-boundary wrapper; the MCP top-level handler catches and formats it as a synthetic-dialog tool response. Internal architecture: every page-targeted session method (29 of them, enumerated in one Set) is gated at the chrome-ws-lib session boundary by a single wrapper, instead of relying on per-action middleware.

v1.12.0

14 Apr 17:50

Choose a tag to compare

Merge human_type into type

type now uses humanType() internally — all text input gets realistic keystroke timing (~80-160ms/char) by default.

Changed

  • type now uses realistic keystroke timing: Types with natural inter-key delays and per-keystroke keyDown/keyUp events in headed mode

Removed

  • human_type action: No longer a separate action. Use type for all text input.

v1.11.0

13 Apr 20:31

Choose a tag to compare

[1.11.0] - 2026-04-13 - Visibility-aware element selection, async eval, crash fix

Fixed

  • Element selection prefers visible elements over hidden ones: getElementSelector() now uses querySelectorAll() to find all matches and picks the first with a non-zero bounding rect. Previously, querySelector() returned the first DOM match regardless of visibility, causing CDP clicks on responsive pages to hit hidden mobile-layout elements at coordinates (0,0) instead of the visible desktop element. Falls back to first DOM match with a console.warn when all matches have zero dimensions
  • evaluate() now awaits async expressions: Added awaitPromise: true to the Runtime.evaluate CDP call. Previously, async expressions (fetch, async IIFEs) returned the Promise object as undefined or [object Object] instead of the resolved value. evaluateJson() already had this — now evaluate() does too
  • tabs.filter is not a function crash: resolveWsUrl() and closeTab() now check Array.isArray() before calling .filter()/.find() on chromeHttp('/json') results. When Chrome returns a non-array response (empty object, error), this previously crashed. getTabs() already had this guard (#27)

Added

  • Test suite: First project-level tests using Node.js built-in test runner (node:test) with jsdom for DOM simulation. Covers element visibility selection, async evaluate behavior, and array guards on CDP responses