Skip to content

fix(agent): use CDP mouse events for React-compatible clicks - #165

Open
justrach wants to merge 6 commits into
mainfrom
fix/react-click-164
Open

fix(agent): use CDP mouse events for React-compatible clicks#165
justrach wants to merge 6 commits into
mainfrom
fix/react-click-164

Conversation

@justrach

Copy link
Copy Markdown
Owner

Summary

Fixes #164kuri-agent click / server /action?action=click now triggers React onClick handlers.

  • Root cause: this.click() fires an untrusted DOM event (isTrusted: false) that React 18/19's event delegation on the root container ignores.
  • Fix: Replace with CDP Input.dispatchMouseEvent — sends a mousePressedmouseReleased triplet at the element's bounding-rect center. These are trusted browser-level events that React's synthetic event system recognizes.
  • Scope: click, check, and uncheck actions in both the CLI path (agent_main.zig) and HTTP server path (server/router.zig).

Test plan

  • kuri-agent click @<ref> on a React button with onClick handler — handler fires, state updates
  • kuri-agent check @<ref> / uncheck on a React checkbox — toggles correctly
  • Server API: POST /action?action=click&ref=e0 on React app — same behavior
  • Non-React pages (vanilla JS, static HTML) — click still works as before
  • zig build compiles clean
  • Existing tests pass (pre-existing HAR test failure unrelated)

🤖 Generated with Claude Code

justrach and others added 6 commits May 21, 2026 02:01
Windows users were hitting a generic "Unsupported OS" error with no
context. Add a Platform-support table to readme.md (macOS + Linux only,
WSL2 as fallback), and route win32 / MINGW / MSYS / CYGWIN through
explicit messages in both install.sh and npm/bin/install.js that link
issue #153. The npm self-test still passes — the existing
`/unsupported platform: win32/` assertion still matches the new message.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
`std.c.clock_gettime` and `std.c.isatty` are POSIX-only — they're the
easiest sites blocking a `-Dtarget=x86_64-windows` build. Route the
three time wrappers in src/compat.zig through a single `realtimeNanos()`
that picks `GetSystemTimeAsFileTime` on Windows and `clock_gettime` on
POSIX. Add `compat.isTtyStderr()` using `GetConsoleMode` on Windows and
`isatty(2)` on POSIX, and switch the three call sites in browse_main,
fetch_main, and server/api_token to it. macOS build + tests unchanged
(the Windows branch is comptime-unreachable on non-Windows targets).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…s-gnu` is green (#153)

Adds enough cross-platform and stub code to make all five binaries
(`kuri`, `kuri-agent`, `kuri-browse`, `kuri-fetch`, `merjs-e2e`) build
clean for `x86_64-windows-gnu`. macOS + Linux builds are unchanged.

What works on Windows:
- Realtime clock, monotonic sleep, TTY detection (compat.zig).
- Mutex / RwLock via Win32 SRWLOCK instead of pthread.
- Stdout/stderr writes via `WriteFile(GetStdHandle(...))`.
- `--version` / `--help` paths through `main` for each binary.

What is stubbed with `error.UnsupportedOnWindows` on Windows (returns
the error at runtime; does not silently no-op):
- `compat.cwd*` file ops, `compat.runCommand`, `compat.tcp*` /
  `TcpStream` / `TcpServer` (raw BSD-socket code).
- `chrome/launcher.zig` Chrome spawn + reaper (uses `fork`+`SIG.KILL`).
- `cdp/websocket.zig` connect + raw socket read; `cdp/client.zig`
  `drainWsEvents`.
- `server/router.zig` `discoverTabs` (uses `std.posix.setsockopt` and
  `std.posix.read` on the raw CDP socket); gets an explicit
  `DiscoverTabsError` so the handler's switch stays exhaustive on both
  platforms.
- `storage/auth_profiles.zig` `deleteProfile` / `listProfiles` (uses
  POSIX `opendir`/`readdir`).
- `server/api_token.zig` `writeMode0600` (uses POSIX `open` + `fchmod`).
- `agent_main.zig` `cmdOpen` (fork+exec Chrome) and `fetchChromeTabs`
  (raw socket).
- `browse_main.zig` `repl` (POSIX stdin fd) and `readLine`
  (`std.posix.read`).
- `lifecycle.zig` `install` (POSIX `sigaction`).

Real Chrome automation, signal-based shutdown, daemonization, the
agent's HAR recorder, and the file-backed auth store are all
follow-up work — none of them are wired up on Windows yet, but the
build succeeds and a Windows binary will load and respond to
`--version`/`--help` / static commands.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Add a `windows-cross-compile` CI job that runs `zig build
-Dtarget=x86_64-windows-gnu -Doptimize=ReleaseSafe` and asserts that
all four user-facing binaries land as PE32+ executables. This pins the
compile-level Windows baseline introduced in the previous commit so a
future patch can't quietly re-introduce an ungated POSIX call (`fork`,
`std.c.open`, raw `setsockopt`/`read` on a socket) without breaking
CI.

Also widen the readme Platform-support table: Windows is no longer
"Not supported yet" but "Experimental — cross-compile only", with the
runtime caveats (Chrome / daemonize / sockets stubbed) spelled out.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…andlers (#164)

React 18/19 uses event delegation on the root container and ignores
untrusted DOM `.click()` calls. Replace with CDP Input.dispatchMouseEvent
mousePressed/mouseReleased triplet at the element's bounding-rect center,
which produces trusted isTrusted:true events that React's synthetic event
system recognizes. Applies to click, check, and uncheck actions in both
the CLI (agent_main) and HTTP server (router) paths.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ng (#164)

- type/fill now uses per-character CDP Input.dispatchKeyEvent instead of
  setting target.value directly, so React controlled inputs fire onChange
- Server router defaults realistic=true for type/fill (was opt-in)
- Fix JS operator precedence bug in click coordinate calculation:
  r.y+r.height/2 was string-concatenated instead of added
- Add React 18 test fixture (test/react-form.html) for e2e validation

E2E verified: fill name → fill email → click submit → React state
updates correctly, submit handler fires, result div renders.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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.

kuri-agent click / eval click() does not trigger React onClick handlers

1 participant