Skip to content

Preserve fork behavior while adopting v0.2.9 and WSL Chromium selection - #3

Merged
ecochran76 merged 14 commits into
mainfrom
maintenance/v0.2.9-wsl
Sep 22, 2026
Merged

ecochran76 merged 14 commits into
mainfrom
maintenance/v0.2.9-wsl

Conversation

@ecochran76

@ecochran76 ecochran76 commented Sep 22, 2026 •

Copy link
Copy Markdown
Collaborator

The fork gains upstream v0.2.9 request/lifecycle improvements while retaining its WSL and agent-browser discovery behavior. WSL launches can select an explicit native Linux Chromium executable; an invalid configured path fails instead of silently choosing another browser.

Fixes #1. Base: main (e3a7174 at publication). Tested source head: 6a6f9d6. Merge-based upstream incorporation preserves existing fork ancestry.

Prior local validation recorded in docs/maintenance-v0.2.9.md and docs/wsl-browser-default.md includes 173 daemon tests, 12 Rust tests, rebuilt bundles, and installed Chromium 150 interaction smoke. Publication does not rerun or supersede those receipts. Current GitHub CI and maintainer review remain pending.

Native Windows live attachment was not tested. v1 and Chromium 153 compatibility repairs are excluded. The operator's installed runtime was already verified in the earlier work; this PR does not perform another installation or release.


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.

SawyerHood and others added 14 commits April 9, 2026 14:07
…Hood#114)

* fix: surface guest error messages dropped by headerless QuickJS stacks

QuickJS Error.stack contains only frame lines (no "Name: message"
header, unlike V8), so formatError's stack-first formatting dropped the
thrown message entirely from stderr. Compose the header in formatError
(extracted to format-error.ts), after #toError has applied its prefix,
and skip it when the stack already carries one. Also add Buffer.isBuffer
to the QuickJS Buffer polyfill.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* feat: add page.cua pixel/vision toolset

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* feat: add page.domCua DOM-id toolset

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* docs: document cua and domCua toolsets

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix: address review findings on cua/domCua toolsets

- start the public id counter at a random high base whenever no inherited
  counter exists, so cross-origin navigations (empty sessionStorage) never
  reuse pre-navigation node ids
- key the sticky id map by a per-document token minted in the walker, so a
  navigated child frame gets fresh ids instead of recycling old ones
- track successfully-pressed modifier keys and release them in a finally
  covering the down loop, so an invalid key never leaves modifiers held on
  the persistent page
- pin clip screenshot semantics as viewport-relative by scrolling first

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* style: format dom-cua files with prettier

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix: accept numeric-string nodeId in domCua actions

Agents regex node ids out of the snapshot text, so they arrive as
strings; coerce digit-only strings instead of erroring.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix: downscale screenshots to css pixels when scale:css is ignored

Playwright ignores scale:'css' on viewport:null pages (headed and
connected Chrome), returning device-pixel images that break the 1:1
cua coordinate contract on Retina displays. Detect the mismatch by
parsing the JPEG dimensions and rescale in-page via OffscreenCanvas.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
…, Chrome 147 CDP attach (SawyerHood#115)

* fix: cap daemon socket request frames at 10 MiB

The per-connection reader buffered incoming bytes with no bound until a
newline arrived, so a local client could OOM the daemon by streaming
data without a line terminator. Reject oversized frames with an error
response and drop the connection before any JSON parsing.

Fixes SawyerHood#112

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix: serialize browser-stop with the per-browser lock

execute requests hold withBrowserLock for the browser they target, but
browser-stop tore the browser down directly, so a second client could
kill a browser while another client's script was mid-flight. Acquire
the same keyed lock before stopping.

Fixes SawyerHood#111

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix: prevent duplicate daemons on concurrent cold start

Two CLI invocations racing on a cold start could both probe the socket,
find no daemon, and both spawn one. The second daemon then unlinked the
first daemon's live socket path (unlinking a bound Unix socket does not
stop the server), splitting clients between two daemons and orphaning
the first.

- CLI: hold an exclusive file lock around the probe-and-spawn section so
  concurrent invocations serialize; the loser re-probes and reuses the
  winner's daemon.
- Daemon: before unlinking an existing socket path, probe it and exit if
  a live daemon answers; only claim the pid file after binding succeeds.
- Daemon: only unlink the socket/pid files on shutdown if this process
  owns them, so a losing daemon cannot delete the winner's endpoint.

Fixes SawyerHood#110

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix: default PW_CHROMIUM_ATTACH_TO_OTHER=1 for Chrome 147 CDP attach

Chrome 147's built-in remote debugging does not emit
Target.attachedToTarget for some target types, which hangs Playwright's
connectOverCDP auto-attach walk indefinitely. Default the documented
Playwright escape hatch in the daemon process (where the Playwright
server runs) while respecting an explicit user override.

Fixes SawyerHood#103

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix: address review findings in daemon hardening

Follow-up to the four hardening fixes, from an adversarial review pass:

- Frame cap (SawyerHood#112): pause the socket synchronously on an oversized frame so
  the unparsed remainder cannot be smuggled in as fresh requests while the
  error response drains under write backpressure. Rename the limit to
  MAX_FRAME_CHARS and report "characters", since it bounds the retained JS
  string (UTF-16 code units), not wire bytes. Drop the dead destroyed-guard.
- Cold-start race (SawyerHood#110): claim the socket by binding first and only unlink
  on EADDRINUSE after confirming no live daemon answers, so a losing daemon
  can never unlink a live socket. Attach the runtime error handler only after
  a successful bind.
- CLI spawn lock (SawyerHood#110): use flock(2) via libc (already a dependency) instead
  of std::fs::File::lock, which would have silently raised the MSRV to 1.89.
- Runtime extraction: write daemon files via temp-file + atomic rename so a
  concurrent spawn never reads a truncated daemon.mjs.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Replace the long-lived NPM_TOKEN secret with npm trusted publishing
(OIDC): add id-token write permission, upgrade npm to a version that
supports it, and drop NODE_AUTH_TOKEN. This also attaches build
provenance to the published package.
@ecochran76
ecochran76 marked this pull request as ready for review September 22, 2026 14:31

@ecochran76 ecochran76 left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed the fork-specific configuration, discovery/protocol plumbing, permissions, and validation evidence. The original CI exposed six Windows fixture failures; d26ad5c fixes native path expectations and exercises the existing Windows TCP transport without skipping the test. Local TypeScript checking and 41/41 discovery tests pass. Native CI is the final acceptance gate.

No further blocking findings identified in this bounded review. Native Windows live-browser attachment remains outside fixture coverage. The operator explicitly requested review/merge; this comment records the agent's review and does not impersonate an independent maintainer approval. No admin bypass or auto-merge is requested.

@ecochran76
ecochran76 merged commit c5ec6a0 into main Sep 22, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Integrate v0.2.9 maintenance and WSL Chromium selection

2 participants