Repository navigation
Releases
Releases · DevinoSolutions/stealth-chrome-devtools-mcp
v2.1.59
Commits
- 5347720 release: 2.1.59 notes name why each Dependabot update failed and why starlette 1.10.0 is off our path (Opus high review of 22c9cbc: LOW, NIT x2)
- 69abfa5 release: 2.1.59
- 8d9e625 build(deps): bump the minor-and-patch group with 8 updates
- def63d5 test(T-11955): the pin also records each release's bound, so a retry pass or a group-scaled wait fails it; two 0.15 s guards become hang guards (Opus high review of 6dedb0b: MED, LOW x2, NIT)
- 1eac88f test(T-11955): the leftover-release pin counts overlapping waits instead of racing the clock (0.684 s on a loaded macOS py3.11 runner, main CI 41226520572)
v2.1.58
Commits
- 91e5b2f release: 2.1.58 notes name the unusable configured seed too (Opus high review of 0f197af: LOW)
- d510e7c release: 2.1.58
- 47f95f7 fix(T-11911): the listening-port probe logs why it answers unknown, so the no-silent-excepts gate passes (pre-push lane on c6a9ec7: 1 failed)
- e803a61 docs(T-11911): the notes say any read failure gives unknown and name the two reap-path pins (Opus high re-review of 9988bd1: NIT x2)
- 3d3475a fix(T-11911): the reap WARNING's port field is pinned through the reap, a probe failure never skips the kill, notes name both seedless cases (Opus high review of 4ec7769: MED, LOW x3)
- ef8dc6b fix(T-11911): a seedless disposable clone retries a failed launch like a seeded one
v2.1.57
Commits
- ce68003 release: 2.1.57 notes match the code (Opus high review of 0205b4c: MED, LOW, NIT x3): a cancelled close's first wait is at most PREF_TIMEOUT_SECONDS + _CANCEL_GRACE_SECONDS = 62 s, not 17 s; the psutil doubles are new; three wordings
- a8dd105 release: 2.1.57
- 9793c48 fix(T-11618): a skipped process name read is logged, and the walk's docstrings say what they claim (Opus high review of c037ced: LOW x2, NIT x2)
- 6b538c8 fix(T-11618): one walk of the process table that skips a process psutil cannot name, so a macOS SystemError no longer fails spawn_browser
- 6b4e5a7 fix(T-11617): review of 8e43513: say plainly what the list_instances description change was, document the new keys in NAVMAP, singular "1 round", "as of the last probe round"
- 5c02e2c fix(T-11617): a disposable clone that stays hung logs "still unresponsive" again, and list_instances shows it
- cd6543c docs(T-11521): the entry goes under Unreleased, not the 2.1.56 it rebased into (rebase onto a4628ff)
- cda0e65 docs(T-11521): the Phase 2b comment names the waits a cancel covers (the exchange wait, Phase 2, 2b) (confirm review of 2aba570: LOW)
- d944912 fix(T-11521): a cancelled close lets the session-restore exchange wind down before Browser.close, the cancel arm logs the lost-cookies warning, and the tests replace the settle's own wait seam instead of asyncio.wait
- 517a6df fix(T-11521): a close cancelled while it waits for the session-restore exchange kills nothing: it re-raises at once and the held background task gives Chrome its own exit before Phase 3
v2.1.56
Commits
- a4628ff release: 2.1.56 notes match the code on main (Opus high review of 10f9379: LOW x3): T-10690's src count is what shipped (25 files, +167 -183), and its Phase 3 and Browser.close sentences name where T-10842 moved them
- 783aafe release: 2.1.56
- 691da52 fix(T-10842): a shutdown during a cancelled close's grace kills nothing (Phase 3 only after the grace returns); the skipped second Browser.close is logged
- 185b938 fix(T-10842): a close cancelled in Phase 2 or 2b ends like a normal close, after Chrome's own exit: Phase 3 runs in the background task, settle no longer kills on a cancel, no second Browser.close over a dropped socket (round-2 review of 6fbf96d)
- b09c56a fix(T-10842): a close cancelled in Phase 2 gives Chrome its own exit before any kill: Browser.close and settle run in a held background task (Opus review of bf90fed)
- ba12382 fix(T-10842): a close_instance cancelled in Phase 2 ends the browser it claimed (process_exit.kill_on_cancel)
- ee4a9dc test(T-10690): test_zero_timeout_uses_default (T-10957, merged after this branch's base) records the bound handed to asyncio.timeout, which _with_cdp_timeout now uses (rebase onto ef2ebcb)
- 9bcb92c fix(T-10690): a non-positive bound means the default or is refused at load, since asyncio.timeout(<=0) starts the call it cancels; the F-164 scan sees timeout_at; the census sees every alias of asyncio.tasks; the health pin keeps exactly-one (review of f3bafbe: LOW x4)
- 79a1f32 test(T-10690): a click cancelled as its arm, read, synthetic click or mouse event answers ends cancelled and sends no input (RED on Python 3.11.14 against the previous source: 5 of 5)
- 1a2efb9 fix(T-10690): every bounded await is async with asyncio.timeout, so on Python 3.11 a cancellation that lands after the inner call answered is not lost (54 asyncio.wait_for in 22 modules; a client_roots bound of 0 still sends nothing)
- b4c20ca test(T-10690): a census that fails when any module under src/ bounds an await with asyncio.wait_for (RED: 54 sites in 22 modules)
- ef2ebcb test(T-9542): the fixture clears _browserless_caller_owned, the set paint_hold keeps since T-10848 moved caller-owned marks onto the tab's browser (rebase onto 8c1b9b9)
- 54baa26 test(T-9542): name tab_for_caller, and leave the cleanup between tests to the one conftest fixture (Opus review of 63af011: LOW x2)
- a610530 test(T-9542): paint_hold state is reset around every test, so the closed-tab pin no longer depends on the -k selection
v2.1.55
Commits
- 8c1b9b9 fix(T-11363): joserfc 1.7.7 in the lock; the security audit found CVE-2026-119284 in 1.7.5 (fixed in 1.7.6)
- 123cb3b release: 2.1.55 notes match their PRs (Opus high review of e7b8c45: LOW x3)
- 4e746fb release: 2.1.55
- 5713011 test(T-10957): instant_element_wait is the one home for zeroing the element waits (five file-local copies folded in); the zero-timeout test pins CDP_OPERATION_TIMEOUT itself (review of 15ca5d2: LOW x2)
- 82d81a9 test(T-10957): hermetic cloner tests no longer sit out the 10 s selector wait or the 30 s CDP default
- 63cee10 test(T-10848): the close_tab tool clears the caller-owned mark on the browser it closed (review of fdcd718: MED)
- 943c3a9 fix(T-10848): close_tab clears the caller-screencast mark on its live browser (re-review of 453ad1b)
- b41c221 fix(T-10848): caller-owned screencast ids live on the tab's browser, so they go with it on close, crash and relaunch (Opus review of 5043478)
- 914b198 fix(T-10848): a screencast tab closed any way but close_tab leaves paint_hold's caller-owned set (browser closed or target destroyed)
- 888f0a4 fix(T-11043): pin the departure fingerprint on the chain click_element really builds (ToolError>ToolError>departure), state it in the CHANGELOG, and a cause whose text cannot be read is not a departure (Opus review of dcec80b)
- ca89c2c fix(T-11043): an element that left the page is one Sentry issue whichever way Chrome said so; the fingerprint asks detached_element and names one cause (-EY 12 events, -EZ 3 under 2.1.54)
- dd0fbbc fix(T-9478): a resource_type validates and matches by one lookup (CDP value or member name, any case); null is no filter; the paused event is read through resource_type_of
- 2717c15 test(T-9478): E2E shows a hook naming the type Chrome reports fulfills a real fetch; the paused-event path and the CHANGELOG say XHR
- 05ab6a1 fix(T-9478): a bad resource_type in a dynamic hook is a CallerError naming the valid types, raised before the hook is stored; create_hook logs once; a resource_type requirement now matches
- b05a502 test(T-10841): the grace test pins the back-date the product writes, so a product that stops back-dating (or back-dates by another amount) fails it
- ac5704a test(T-10841): the failed-launch grace test ages its marker from the clock at the check, not from a stale mtime; a 2.2 s gap between write and check is pinned
- a724f82 docs(T-9675): the entry goes under Unreleased, not the 2.1.54 it merged into (rebase onto 8dd893b)
- 8de76e0 test(T-9675): a child that exits as the deadline kill lands is read once more, not an error (Opus review of 24077eb: LOW)
- 706499d test(T-9675): the boot-log wait checks the child's identity, kills a stuck child, retries a transient read error, and is shared with test_backend_launch
- 82082c3 test(T-9675): the boot-crash test waits for the child's output or exit, not a fixed 10 s window
- f74c4c3 test(T-9551): the spawn-budget Browser double lists its pages as nodriver's Browser.tabs does, since spawn now reads them through tab_open.initial_tab
- d566eed test(T-9551): the every-version forwarder close test runs under a 0.3 s budget, so its margin is several times the budget on a slow runner (Opus review of b06a594: LOW)
- 9145156 test(T-9551): the forwarder's open-client close test is valid below Python 3.13; browser_connect's leaf note names tab_open
- 63be988 fix(T-9551): the re-attach keeps nodriver's pick unless it is Chrome's own tab; spawn reads the same helper; the forwarder's close is bounded
- a7d4ae1 fix(T-9551): a re-attach adopts the original page, not the newest tab; a cancelled close still closes the proxy forwarder
v2.1.54
Commits
- 8dd893b release: 2.1.54 notes describe only what changed since 2.1.53 (Codex review of 8cfd54d: MED)
- 9b422e0 release: 2.1.54
- fd4b0ce docs(T-10284): one CHANGELOG entry, not one heading per draft (rebase onto c591515)
- db73641 fix(T-10284): the release waits under asyncio.timeout, so on Python 3.11 a cancellation that lands after the reply is not lost; the cap's docstring claims only what it orders (Opus xhigh review of 38dee82: LOW x2)
- 58bc151 fix(T-10284): a read cancelled during its own release leaves its group for the next read (Codex review of 3b9e890: LOW)
- aed04bb fix(T-10284): leftovers carry the order they were first left in, so overlapping releasers cancelled in any order still drop the oldest (Codex review of 941766f: LOW)
- 7e2e8a9 fix(T-10284): groups put back by a cancelled leftover release go ahead of newer ones, so the cap still drops the oldest (Codex review of 03f018c: LOW)
- 79506b7 fix(T-10284): a read cancelled while releasing earlier leftovers puts back the groups not yet released; the CHANGELOG drops a failure breakdown that was not re-measured (Codex review of 8c19f72: LOW x2)
- 4aca986 fix(T-10284): a failed or cancelled read leaves its object group on the tab for the next read instead of handing the release to a task that can outlive the loop (review of f7734fa: LOW)
- 9c1c2d1 fix(T-10284): the frame search classifies per frame, the object-group release never holds the caller, and a listing reads each row's connectivity once (review of 3f9cc1d: HIGH, MED, LOW)
- 4fa3deb fix(T-10284): the click and listing reads run in an isolated world; a failed read is never an answer; reads release what they resolve (Codex round 8 findings 1-5; closes T-10299)
- 5251df1 fix(T-10284): native reads take the farthest owner on the node's chain; a failed visibility read raises; the read-only scripts send no user gesture; census and docs (review round 2 findings 1-6)
- 13a2fe2 fix(T-10284): native reads walk the node's own prototype chain, so a page's own global Node breaks nothing; the synthetic click has its own answer for an unread connectivity; wait_for_element uses VISIBLE_JS (review findings 1-5)
- c9f9f29 fix(T-10284): one token-returning connectivity read; a failed read is a ToolError, never a departure or a connected node (Codex findings 1-4)
- 0f6a0f2 fix(T-10284): refresh_element also reads isConnected, so a node the page removed but still references is dropped from query_elements and refused by get_element_state
- c591515 fix(T-10522): one retry budget per call; a refusal claims a holder check only when one ran (Codex round 3 MED, MED)
- f05a0e1 fix(T-10522): never sleep while the target is displaced; report only what was observed (Codex round 2 HIGH, MED)
- 7d1c623 fix(T-10522): a copy refused for a lock something else holds no longer reports target-in-use
- 4756bc4 ci(T-10499): pin DevinoSolutions/artifact v1.2.2 (67676f3): a Cloudflare 520-524 from the store is retried, not a failed release
- df25153 test(T-10034): the fingerprint's compile of the package's own source is declared as never executed, so the host-exec inventory stays exact (lane: test_security_boundary)
- 5b88ceb fix(T-10034): a declared fingerprint must be an exact tuple of exact strings, so a caller's str subclass that equals every word ships nothing (Codex review of 200ab62: HIGH)
- f4f62a1 fix(T-10034): the class map covers whole modules of the libraries the package handles, a thread that cannot start cannot stop sentry_init, and an empty map is said once (review of e03fd55: MED, LOW, LOW)
- 7bfee36 fix(T-10034): third-party exceptions our code handles keep their names, and the code map is warmed off the event path
- 6f6121e fix(T-10034): identity, not self-description, decides what a fingerprint may name (Codex round 4: HIGH x3, MED)
- c102474 fix(T-10034): the ToolError fingerprint reads no name a caller's code can set: types, frames and tool names are allowlisted by where they live
- 0534119 fix(T-10034): a ToolError is fingerprinted by tool, error types and our innermost frame, never by its message
- ff8d00c fix(T-10034): the ToolError fingerprint is redacted before it is templated, keeps quoted causes, and names the tool
- 1585362 fix(T-10034): a freeze or a tool error is one Sentry issue, not one per message: a stable fingerprint names the kind and its stable cause
v2.1.53
Commits
- f9fe86e release: 2.1.53
- 395c351 docs(T-10034): the ER entry goes under Unreleased with the T-10363 entry, not 2.1.52 (the rebase over the release placed it there)
- d8d83af docs(T-10034): the post-scroll wait and the settle are not bounded by the deadline, and their time shortens what the next resolution is handed (Codex round 7 LOW)
- 2c45e64 fix(T-10034): the fake decides JS-side branches by JS truthiness, and the deadline claim names only the shared resolution budget (Codex round 6 LOW, LOW)
- 78e8d15 fix(T-10034): the click scripts read the target only through native accessors, and connected() accepts only a literal true (Codex round 5 MED, LOW)
- b956258 docs(T-10034): the ER entry claims only what the code enforces; a page whose own isConnected getter clicks is the accepted boundary until T-10299 (Codex round 4 HIGH)
- d4904e1 fix(T-10034): the synthetic click answers with its own tokens, so a click() that throws false is never re-run (Codex re-review HIGH, LOW)
- 0c2a487 fix(T-10034): the synthetic click checks isConnected and clicks in ONE page-side call; its false is re-resolved, a failed call is never re-run (Codex review HIGH)
- 6db1b6f fix(T-10034): a node the page removed but still references is the element leaving, not a display:none target; re-resolved before any input, never clicked synthetically
- e27d93f fix(T-10034): the synthetic fallback and the re-run need ZERO input sent, recorded by click_target.InputSent; the re-runs spend one deadline (Codex review HIGH, MED)
- ae1ce91 fix(T-10034): an element the page replaced before any input is re-resolved and clicked once; one that leaves after input is never clicked twice; a listing drops a departed element without an ERROR (Sentry ER, EP)
- 3d931b8 fix(T-10363): an editable install reports Sentry environment=development; every other install passes production explicitly
v2.1.52
Commits
- 1b69ae1 release: 2.1.52
- 3f41c1b test(T-10026): a release counts only when Chrome answered the stop within its bound, and the pair is retried over the same windows (Codex review MEDs)
- e65b5ed test(T-10026): decide the background tab's fall back on a pair read at the same time, and check the release without frames on every platform
- cbf83da fix(T-10195): a leaked sse_starlette shutdown flag no longer hangs the session-hygiene pin; its client conversation fails in 20 s naming the step
- 3f541dc docs(T-10034): the EN entry goes under a new Unreleased, not 2.1.51 (the rebase over the release placed it there)
- 408a930 fix(T-10034): the group-mode exception walk mirrors the SDK's truthiness guards (re-review MED)
- 70d0e7b fix(T-10034): the live exception walk selects exactly the links sentry-sdk serializes (re-review MED)
- 1f8a5a3 fix(T-10034): a chain past the classifier's bound ships on both paths instead of dropping a judged prefix (review HIGH)
- 0359d23 fix(T-10034): a session that crashed telling a departed client about its disconnect is dropped as client-disconnect (Sentry EN)
v2.1.50
Commits
- 8e8062e release: 2.1.50
- 4a43ef8 fix(T-9742): write the lock bump with uv 0.13.6 so only authlib and dnspython change (0.9.29 rewrote the revision and two marker lines)
- 98e95ff fix(T-9742): bump authlib 1.7.2 -> 1.9.1 and dnspython 2.8.0 -> 2.9.0 in the lock; the security audit finds 8 known vulnerabilities in them
- 5c0b676 docs(T-9479): name Linux as where a covered headless page misreports its height; drop an unmeasured headed-focus claim
- b87e5dd fix(T-9479): the settings exchange's tab opens behind the caller's page, so a named headless spawn keeps reporting its 600px window
- fd6d30e fix(T-9479): a named spawn no longer waits on the chrome://settings exchange: skipped when the pref is already on disk, run off the spawn path otherwise
- 3e0fcee fix(T-9477): a relaunch in the same second gets its own Chrome log instead of writing into the dead browser's
- e7fde98 fix(T-9464): a bug of ours behind a dynamic-hook tool propagates, not a {"success": False} dict
- ecb289e test(T-9468): the settle-deadline test drives a fake clock instead of fitting four probes into 0.3s of wall time
- a05c7b0 fix(T-9431): the hook validator and remove_hook let our own bugs propagate instead of reading them as a caller refusal
v2.1.48
Commits
- 9444a33 release: 2.1.48
- 454da0c fix(T-9135): delete DynamicHook.process, refuse hook code that does not load, cap the warning text (rev9135 LOWs)
- 41ecc6a fix(T-9135): an error in the caller's hook code is a warning they can read back on the hook
- e83e4eb ci(T-9190): pin DevinoSolutions/artifact to 5bb08e7, whose OIDC and STS calls wait out a GitHub 503
- f0be511 test(T-9135): the closed-tab reap pins the binding's own handler, beside the hook system's one listener per instance
- 1e51328 fix(T-9135): create_dynamic_hook raises the armed-nowhere ToolError instead of answering success:false (rev9135)
- 29bb108 fix(T-9135): a tab with no browser connection is debug-logged, not silently skipped (rev8501)
- 5ce8c06 fix(T-9135): the host-exec inventory follows DynamicHook to dynamic_hook_model.py
- f538998 fix(T-9135): hooks follow the live tab; a response body is asked for only when there is one
- 08dff74 test(T-9132): the held window is timed from before the holding call (review nit)
- b111178 test(T-9132): the held-tab frames reading no longer outruns its own linger
- ab39ec0 fix(T-9117): close_tab relies on Chrome's targetDestroyed report, not its own cancel
- 84fd901 fix(T-9117): a hooked target's paused handlers end whenever Chrome reports it gone
- 4718dc6 fix(T-8944): changelog entry under a new Unreleased heading above 2.1.47
- c625d19 fix(T-8944): close_tab ends the paused-request handlers waiting on the closed tab
- c3adc0a chore(deps): bump websockets from 16.0 to 17.3
- d95bac9 chore(T-8941): drop the unused jsbeautifier dependency