v0.53.1
feder-cr/invisible_dotsv0.53.1Sep 14, 2026by github-actions[bot]
Upgrading?
AI Summary
This release fixes a critical bug where externally killed browser processes were incorrectly reported as running, resulting in stale UI states. It refines logic for handling dead targets across `Work.gone()`, `listing`, and `StealthSession` to accurately reflect process status.
Key Highlights
- Fixed incorrect reporting of dead browsers where processes killed externally were still listed as running.
- Renamed `StealthSession.is_alive` to `is_usable` to accurately reflect its local limitations.
- Updated `Work.gone(role)` and its callers (`session`, `acting`, `status`) to correctly handle `TargetClosedError`.
- Improved `swallow()` logic to distinguish between mid-navigation failures and closed target errors.
- Added engine tests to verify process death handling and the order of events.
Breaking Changes
- Renamed `StealthSession.is_alive` to `is_usable`.
Full Release Notes
Writing the engine test that 0.53.0 was missing - kill Firefox under the server and check the sentence a model acts on - found that half of it was not true. Measured against firefox-30, with the process ended from outside: `is_connected()` answers true for at least six seconds, and `page.url` answers from cache the whole time. Nothing local can see a process that is gone. What sees it is the first round trip, which raises TargetClosedError since wrapper 0.15.0 - `page.title()` and `context.new_page()` both. So a browser whose engine had been killed answered `browser_status` with the identity and the page, as though somebody were browsing, and `browser_list` listed it as running. The live panes draw that listing: a pane over a browser that no longer exists is the frozen picture of [B202], one layer up. Fixed where the fact is one: - `swallow(why, unless=...)` names the failures a silence is not for. `describe_pages` swallows a title a page mid-navigation will not give and lets a closed target out, because that is the browser being gone. The comment beside it says which of the two fields is cached and which is the round trip. - `Work.gone(role)` is the one place that forgets the browser and composes the sentence. Three callers notice: `session` locally, `acting` under an action, `status` under the question. - `listing` drops a browser whose round trip says it is gone instead of reporting it as running; `status` answers the sentence instead of the identity it still holds in memory. - `StealthSession.is_alive` is `is_usable`, with the measurement in its docstring: the old name promised what no local question can answer, and it is what made me write a known-bad that does not happen. Two engine tests, one per path, because a killed process reaches them in a definite order: an action raises the closed target (the aliveness check does not fire first), and the status is what holds the other path. They kill only the pids born after their own launch. Six mutations, six killed: acting re-raising; the round trip swallowed again; the status answering anyway; the local check dropped; the listing keeping the row; the status reporting the identity.
Related Repositories
The AI that really does things. Any OS. Any Platform. The lobster way. 🦞
Interactive roadmaps, guides and other educational content to help developers grow in their careers.
Reverse engineer anything with agents, from app behavior down to native binaries.
The open source coding agent.
Fair-code workflow automation platform with native AI capabilities. Combine visual building with custom code, self-host or cloud, 400+ integrations.