reqwest_get_string() was hand-rolling HTTP/1.1 over raw TCP despite reqwest
being an existing dependency. The hand-rolled implementation had two bugs:
1. URL path parsing: url.find('/') matched the first '/' in 'http://',
producing path '//127.0.0.1:9222/json/version' instead of '/json/version'
2. read_to_end() hangs: Chrome's DevTools HTTP server ignores Connection: close
and keeps the socket open, so read_to_end() waits for EOF that never comes
This caused 'agent-browser --cdp <port>' to always timeout when AGENT_BROWSER_NATIVE=1.
Fix: replace 49 lines of broken TCP code with reqwest::get(), which was
already in Cargo.toml.
Fixes#600
Three improvements to `--native` Chrome launching:
- `find_chrome()` now falls back to Playwright's browser cache (`~/.cache/ms-playwright/`) when no system Chrome is found
- Auto-detect containers/VMs (root, Docker, Podman, cgroups) and inject `--no-sandbox`
- Chrome stderr is now captured and included in launch error messages, with a hint when sandbox errors are detected
The native PR introduced tokio-tungstenite and reqwest with native-tls,
which depends on openssl-sys (C library). This breaks the release
workflow's cargo-zigbuild cross-compilation on Linux because zig's C
compiler can't find the system OpenSSL headers.
Switch to rustls (pure Rust TLS) which has zero C dependencies and
cross-compiles trivially. Also shrinks the dependency tree.
* fix(windows): resolve daemon startup failures and Git Bash compatibility
Three root causes behind 27 open Windows issues:
1. Path::canonicalize() returns \\?\ prefixed paths on Windows that
Node.js cannot parse, preventing daemon startup. Strip the prefix
before passing to Node. (fixes#522, #390, #56, #25, #37, #89)
2. Git Bash/MSYS2 translates Unix-style paths and resolves node to
a shell wrapper script. Use node.exe explicitly and set
MSYS_NO_PATHCONV/MSYS2_ARG_CONV_EXCL to prevent argument mangling.
(fixes#148, #108, #171)
3. postinstall fixWindowsShims() hardcoded x64 arch and did not verify
the native binary exists before rewriting shims. Now detects arch
dynamically and validates the binary path. (fixes#262)
Also:
- Error messages now show TCP port on Windows instead of Unix socket path
- Windows CI expanded to test full daemon lifecycle (open, snapshot, close)
* fix(windows): strip \\?\ prefix in auth-cli path (fixes#579)
Same canonicalize() issue as the daemon spawn path, but in
run_auth_cli() which passes the script path to Node.js.
Bug 1: `cookies clear` printed 'Request log cleared' instead of 'Cookies cleared'
because the output handler matched the generic `{ cleared: true }` response shape
without checking the action context. Now uses the `action` parameter to distinguish
`cookies_clear` from `requests --clear`.
Bug 2: `tab close` printed 'Browser closed' instead of 'Tab closed' because the
output handler matched the generic `{ closed: ... }` response shape without checking
the action context. Now uses the `action` parameter to distinguish `tab_close` from
`close` (full browser close).
Closes#556
Per POSIX, kill(pid, 0) returns EPERM when the process exists but the
caller lacks permission to signal it, and ESRCH when it does not exist.
The daemon liveness checks in both the Rust CLI and TypeScript daemon
treated any kill failure as "not running", which is incorrect when
running inside a macOS sandbox that restricts signal delivery to
(target self). This caused the CLI to delete the real daemon's socket
and PID files, then spawn a duplicate daemon.
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* fix: resolve unnamed element refs matching multiple elements (#500)
When a page has one unnamed button among several named buttons,
clicking its ref fails with "matched N elements" because the
locator `getByRole('button')` matches all buttons on the page.
Normalize unnamed interactive elements to `name: ""` so the
selector becomes `getByRole('button', { name: "", exact: true })`
which matches only buttons with empty accessible names.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* refactor: remove dead code branch in buildSelector
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* refactor: make RefMap.name required string, remove dead code branches
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: hyunjinee <leehj0110@kakao.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>