Skip to content

feat(cua-driver): cursor overhaul + Hermes-decoupling MCP surface - #1961

Merged
f-trycua merged 4 commits into
mainfrom
feat/docs-prompts-and-agent-cursor
Jun 21, 2026
Merged

feat(cua-driver): cursor overhaul + Hermes-decoupling MCP surface#1961
f-trycua merged 4 commits into
mainfrom
feat/docs-prompts-and-agent-cursor

Conversation

@f-trycua

@f-trycua f-trycua commented Jun 21, 2026

Copy link
Copy Markdown
Collaborator

Summary

Four logical groups in this branch:

  1. docs(driver): Fix the mcp-config --client claude command shape in tutorials + recipes; add a new personalize-cursor how-to.
  2. feat(cursor-overlay): Retina-aware rendering + --cursor-shape arrow|teardrop selection. arrow (the procedural gradient diamond — the cursor shape before this PR) stays the default until the embedded teardrop SVG's retina rasterisation is fully sorted; users can opt into the SVG with --cursor-shape teardrop. --cursor-icon <path> (custom file) still wins over --cursor-shape. Backing-scale plumbed end-to-end so macOS renders at physical pixels via CALayer.contentsScale.
  3. feat(cua-driver): MCP surface needed by Hermes' computer_use wrapper to decouple from cua-driver internals (hermes#47072 Surfaces 4, 6, 7, 8) — mcp-config --client claude emits --scope user, machine-readable CLI manifest via --help --machine-readable, per-tool capabilities[] on tools/list, capability_version on initialize, explicit mimeType on image-part responses, click.button enum (left/right/middle), get_window_state.structuredContent.elements[] with bounded walk, opaque element_token alongside element_index on 7 token-accepting tools (click, double_click, right_click, scroll, type_text, press_key, set_value), accessibility.element_tokens capability claim.
  4. feat(cua-driver): type_text falls back to direct key-event synthesis when the target is a terminal emulator (Ghostty / iTerm2 / Terminal.app / Windows Terminal / mintty / GVim, etc.) — bypasses the silent-drop affecting AX-text injection on those consoles. New capability input.keyboard.type.terminal_safe; type_text_chars deliberately doesn't claim it.

The integer element_index surface is preserved — element_token is purely additive. No CAPABILITY_VERSION bump (additive only).

Test plan

  • macOS host: cargo test --workspace --lib --exclude platform-macos — all lib tests green (cua-driver-core, cursor-overlay, platform-linux, platform-windows). cargo test -p cua-driver --tests — only the pre-existing mcp_protocol_test failures present on the base commit (verified on base by checking out and rerunning).
  • Ubuntu 24.04 (real Linux build): full cargo build --workspace + cargo test --workspace --lib --exclude platform-macos --exclude platform-windows + cargo test -p cua-driver --tests — green.
  • Windows 11 Enterprise (real Windows build): cargo test -p cua-driver-core -p platform-windows --lib — 56 platform-windows lib tests + cua-driver-core green. cargo test -p cua-driver --tests — 5 pre-existing fails on base, 0 new.
  • Visual confirmation on both Linux (Xvfb + xfce4 + ffmpeg x11grab) and Windows (RDP Session 2) for both --cursor-shape arrow (default) and --cursor-shape teardrop. Cross-platform cursor parity confirmed.
  • Manual smoke for reviewer: register MCP via cua-driver mcp-config --client claude and confirm tools/list carries the new fields (capabilities[], element_token, mimeType, button enum).

Notes for reviewers

  • Branch is squashed to 4 logical commits — one per concern. Recommended merge style is rebase merge to preserve the 4-commit narrative on main.
  • element_token format: s{snapshot_hex}:{index} (8–12 chars), per-pid LRU cap 8. Stale tokens return an explicit stale error rather than silently mis-resolving.
  • --cursor-shape default is intentionally arrow and not teardrop — the SVG path still has retina-rasterisation work pending. See the personalize-cursor.mdx page for the rationale.
  • Runtime switching between arrow and teardrop via set_agent_cursor_style is NOT in this PR — CLI-only today. Can be added in a follow-up.

Summary by CodeRabbit

  • New Features

    • Added cursor shape customization with built-in options (arrow and teardrop).
    • Introduced element tokens for stable, snapshot-aware UI element addressing across tools.
    • Added terminal detection to improve text input reliability in terminal emulators.
    • Added support for bounded tree traversal with configurable depth and element limits.
    • Added middle-click gesture support on macOS.
    • Added CLI manifest command for machine-readable interface description.
  • Documentation

    • New guide for cursor personalization options and runtime customization.
    • Updated multi-step task guides with clarifications.
  • Tests

    • Added integration tests for element token contracts and tool capability validation.

f-trycua added 4 commits June 21, 2026 14:16
- Fix `mcp-config --client claude` command shape across tutorials and
  recipes so it matches what the CLI actually emits
- Add `Using cua-driver,` preamble to example prompts (export-contacts,
  build-a-report, calculator)
- New how-to: personalize the agent cursor — runtime style override,
  bringing your own SVG/PNG/ICO via `--cursor-icon`, the default render
  details (gradient body, white outline, 2× rasterize for retina), plus
  what's intentionally not personalizable today (multi-palette, motion
  curve shape, the dot-style `cursor_size` field)
Two built-in cursor silhouettes, selectable via `--cursor-shape`:

- `arrow` (default): the procedural gradient diamond drawn from vector
  primitives each frame. Sharp at any backing scale because nothing
  rasterises. This is the same silhouette as before this PR.
- `teardrop`: the embedded `cursor-up` SVG (upward teardrop with notched
  bottom, gradient body, white outline). Rasterised once into a 52 px
  RGBA buffer at startup and blitted with a runtime transform.

`arrow` stays the default until the teardrop's retina rasterisation is
fully sorted; users can opt into the SVG with `--cursor-shape teardrop`.
`--cursor-icon <path>` (custom asset) always wins over `--cursor-shape`.

Plumbing in this commit:

- New `BuiltinShape` enum in `cursor-overlay::shape` with parse + default
  Arrow; re-exported alongside `CursorShape`.
- `CursorConfig` gains `builtin_shape: BuiltinShape`; `--cursor-shape`
  parsed in `CursorConfig::parse`; unknown names warn and fall back.
- `paint_cursor` branches on `(custom shape, builtin)`: custom file →
  blit it; else `Arrow` → call `draw_default_arrow`; else `Teardrop` →
  blit `CursorShape::teardrop()` (renamed from `cua_brand()`).
- Backing-scale plumbed end-to-end so the teardrop renders at physical
  pixels on retina: `paint_cursor` takes `backing_scale: f32`,
  platform-macos sources it from `NSScreen.backingScaleFactor` and sets
  `CALayer.contentsScale`, platform-{linux,windows} pass `1.0`.
- CLI surface: `--cursor-shape` added to `VALUE_FLAGS` and to the
  cursor-overlay help block.
- Docs: `personalize-cursor.mdx` describes both built-ins, the
  default-arrow choice, and the runtime knobs.

Runtime switching between `arrow` and `teardrop` via
`set_agent_cursor_style` is intentionally deferred — restart with a
different `--cursor-shape` to swap today.
Lands the MCP-layer changes Hermes' `computer_use` wrapper needs to
decouple from cua-driver internals (Surfaces 4, 6, 7, 8 from
hermes#47072). The integer `element_index` surface is preserved —
`element_token` is purely additive.

- `mcp-config --client claude` emits `--scope user` and drops the dead
  `--claude-code-computer-use-compat` flag — fixes the per-project-scope
  footgun where tools registered into one repo didn't surface elsewhere
- Machine-readable CLI manifest via `--help --machine-readable`:
  subcommand list + arg shapes so consumers don't parse free-form text
- Per-tool `capabilities[]` array on `tools/list` + top-level
  `capability_version` on `initialize` — consumers detect support
  before calling instead of trying tool names blindly (Surface 4)
- Image-part responses gain explicit `mimeType` so consumers don't
  sniff base64 magic bytes (Surface 7)
- `click`: `button` arg accepts `left` / `right` / `middle`; unknown
  buttons rejected instead of silently falling through to left
- `get_window_state` emits `structuredContent.elements[]` and a
  top-level `snapshot_id` — single canonical shape with a bounded walk
- Opaque `element_token` alongside `element_index` on 7 token-accepting
  tools (`click`, `double_click`, `right_click`, `scroll`, `type_text`,
  `press_key`, `set_value`): format `s{snapshot_hex}:{index}`,
  per-pid LRU cap 8, stale tokens return an explicit "stale" error
  (Surface 6)
- `accessibility.element_tokens` capability claimed by all 7
  token-accepting tools + `get_window_state` (which emits the tokens)

Includes Linux fixups for cfg-gated paths Agent D couldn't reach from
a macOS host build: `pid: u32 → i32` cast at `register_snapshot` and
`element_index` + `element_token` added to the Linux `press_key`
schema + invoke (resolves the token's `window_id` before XSendEvent).
`type_text` now detects when the focused window is a terminal emulator
(bundle id on macOS, WM_CLASS + process name on Linux, window class on
Windows) and routes past the accessibility-text channel to direct
key-event synthesis. Fixes the silent-drop that otherwise affects
Ghostty / iTerm2 / Terminal.app / Windows Terminal / mintty / GVim and
other consoles where AX-text injection is broken or no-op.

- macOS: `TERMINAL_BUNDLE_IDS` list (10 entries) → CGEvent
  `type_text_with_delay`
- Linux: `TERMINAL_WM_CLASS_SUBSTRINGS` + existing process-name list →
  tty master injection (`crate::tty::inject_via_master`) or
  `send_type_text_xtest` on X11 / virtual-keyboard on Wayland
- Windows: `TERMINAL_CLASS_PREFIXES` (Cascadia hosting class,
  `ConsoleWindowClass`, `mintty`, `nvim`, `Vim`) → SendInput +
  `KEYEVENTF_UNICODE` via `inject_text_cloaked`
- Structured response: `path: "ax" | "key_events"` + `characters: <n>`
- New capability `input.keyboard.type.terminal_safe`; claimed by
  `type_text` only — `type_text_chars` does NOT claim it (Linux
  per-char XSendEvent path has no terminal short-circuit; contract is
  intentionally narrower)
- Per-platform terminal constants live in
  `platform-{macos,linux,windows}/src/terminal.rs` for easy extension
@vercel

vercel Bot commented Jun 21, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
docs Ignored Ignored Jun 21, 2026 10:23pm

Request Review

@coderabbitai

coderabbitai Bot commented Jun 21, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Caution

Review failed

Pull request was closed or merged during review

📝 Walkthrough

Walkthrough

Introduces "Surface 6" opaque per-snapshot element tokens for stable MCP tool addressing, adds configurable bounded tree walking with depth/parent_element_index/frame metadata across macOS AX, Linux AT-SPI, and Windows UIA/MSAA walkers, propagates element tokens through all action tools, adds MCP capability token arrays to tools/list, adds a manifest CLI subcommand, adds a teardrop built-in cursor silhouette with retina backing-scale rendering, adds cross-platform terminal emulator detection modules, and adds a new cursor personalization documentation page.

Changes

cua-driver Surface 6 feature set

Layer / File(s) Summary
Element token registry and resolve_element_args
libs/cua-driver/rust/crates/cua-driver-core/src/element_token.rs, libs/cua-driver/rust/crates/cua-driver-core/src/lib.rs, libs/cua-driver/rust/crates/cua-driver-core/src/protocol.rs
New TokenRegistry (per-pid LRU, register_snapshot/resolve), token format s{hex}:{index}, global singleton, ResolvedElement enum, and resolve_element_args precedence logic with token-takes-precedence and stale-token-errors-no-fallback guarantees; comprehensive unit tests; element_token module exposed from crate root; Content serialization contract tests added.
Bounded AX/UIA/AT-SPI tree walking with depth and parent metadata
libs/cua-driver/rust/crates/platform-macos/src/ax/tree.rs, libs/cua-driver/rust/crates/platform-macos/src/ax/mod.rs, libs/cua-driver/rust/crates/platform-macos/src/ax/cache.rs, libs/cua-driver/rust/crates/platform-linux/src/atspi/mod.rs, libs/cua-driver/rust/crates/platform-linux/src/atspi/native.rs, libs/cua-driver/rust/crates/platform-windows/src/uia/mod.rs, libs/cua-driver/rust/crates/platform-windows/src/msaa.rs
Adds walk_tree_bounded APIs and exported default caps on all platforms; extends AXNode/AtspiNode/UiaNode with depth, parent_element_index, frame; propagates parent ancestry tracking through all recursive walkers; walk_tree becomes a shim.
get_window_state: snapshot registration, element_tokens, bounded walk
libs/cua-driver/rust/crates/platform-macos/src/tools/get_window_state.rs, libs/cua-driver/rust/crates/platform-macos/src/tools/mod.rs, libs/cua-driver/rust/crates/platform-macos/src/tools/get_screen_size.rs, libs/cua-driver/rust/crates/platform-macos/src/apps/mod.rs, libs/cua-driver/rust/crates/platform-linux/src/tools/impl_.rs (get_window_state sections), libs/cua-driver/rust/crates/platform-windows/src/tools/impl_.rs (get_window_state sections)
Parses max_elements/max_depth, routes through bounded walker, registers snapshot in global token registry, emits element_token per element plus snapshot_id, _note, screenshot_mime_type in structured output; adds build_elements_array_with_token and back-compat shim; exposes bundle_id_for_pid on macOS.
Action tools: element_token schema + resolve_element_args (macOS, Linux, Windows)
libs/cua-driver/rust/crates/platform-macos/src/tools/click.rs, ...double_click.rs, ...right_click.rs, ...type_text_chars.rs, ...press_key.rs, ...scroll.rs, ...set_value.rs, ...zoom.rs, ...input/mouse.rs, libs/cua-driver/rust/crates/platform-linux/src/tools/impl_.rs (action tools), libs/cua-driver/rust/crates/platform-windows/src/tools/impl_.rs (action tools)
Adds element_token to schemas and resolve_element_args precedence for click, double_click, right_click, type_text, type_text_chars, press_key, scroll, set_value on all platforms; adds explicit button validation and middle-click CGEvent support to click; adds mime_type to zoom structured output; adds macOS middle_click_at_xy helpers.
Terminal emulator detection + type_text terminal short-circuit
libs/cua-driver/rust/crates/platform-macos/src/terminal.rs, libs/cua-driver/rust/crates/platform-macos/src/lib.rs, libs/cua-driver/rust/crates/platform-linux/src/terminal.rs, libs/cua-driver/rust/crates/platform-linux/src/lib.rs, libs/cua-driver/rust/crates/platform-linux/src/x11/mod.rs, libs/cua-driver/rust/crates/platform-windows/src/terminal.rs, libs/cua-driver/rust/crates/platform-windows/src/lib.rs, libs/cua-driver/rust/crates/platform-macos/src/tools/type_text.rs, libs/cua-driver/rust/crates/platform-windows/src/tools/impl_.rs (type_text section)
Adds terminal detection modules on macOS (bundle IDs), Linux (WM_CLASS substrings + process names via new wm_class_for_window), and Windows (class-name prefixes); type_text on macOS/Windows short-circuits the AX write path for terminal targets and routes to CGEvent/SendInput; structured responses include {path, characters} tokens.
MCP tools/list capability tokens and envelope versioning
libs/cua-driver/rust/crates/cua-driver-core/src/tool.rs, libs/cua-driver/rust/crates/cua-driver/src/proxy.rs, libs/cua-driver/rust/crates/cua-driver/src/serve.rs, libs/cua-driver/rust/crates/cua-driver/tests/element_token_test.rs, libs/cua-driver/rust/crates/cua-driver/tests/mcp_protocol_test.rs
Adds CAPABILITY_VERSION, default_capabilities_for mapping, capabilities array per tool in to_list_entry; tools_list envelope gains capability_version and schema_version; daemon serve (Unix/Windows) and proxy reshaping propagate these; integration tests verify per-tool claims and envelope keys.
CLI manifest subcommand and updated mcp-config Claude output
libs/cua-driver/rust/crates/cua-driver/src/cli.rs, libs/cua-driver/rust/crates/cua-driver/src/main.rs
Adds Command::Manifest{pretty}, run_manifest/build_manifest producing stable JSON; wires dispatch arm on macOS and non-macOS; updates --help, VALUE_FLAGS; updates Claude mcp-config to emit claude mcp add-json registration; adds telemetry event and manifest contract tests.
Cursor overlay: BuiltinShape (teardrop), backing-scale rendering
libs/cua-driver/rust/crates/cursor-overlay/src/shape.rs, libs/cua-driver/rust/crates/cursor-overlay/src/lib.rs, libs/cua-driver/rust/crates/cursor-overlay/src/render_state.rs, libs/cua-driver/rust/crates/platform-macos/src/cursor/overlay.rs, libs/cua-driver/rust/crates/platform-linux/src/overlay.rs, libs/cua-driver/rust/crates/platform-windows/src/overlay.rs
Adds BuiltinShape{Arrow, Teardrop} with --cursor-shape CLI flag; reduces CURSOR_SIZE 64→52; adds lazy SVG rasterizer for teardrop; render_frame/paint_cursor gain backing_scale parameter scaling all geometry; macOS overlay derives backing scale from NSScreen; Linux/Windows stubs pass 1.0; adds retina pixel-count regression test.
Documentation updates
docs/content/docs/how-to-guides/driver/personalize-cursor.mdx, docs/content/docs/how-to-guides/driver/meta.json, docs/content/docs/tutorials/drive-your-first-app.mdx, docs/content/docs/how-to-guides/recipes/build-a-report-in-a-native-app.mdx, docs/content/docs/how-to-guides/recipes/export-contacts-overnight.mdx
Adds new personalize-cursor.mdx page covering --cursor-shape, --cursor-icon, set_agent_cursor_style MCP tool, silhouette render details, and limitations; updates tutorial with claude mcp add-json step and Using cua-driver, prompt prefix; minor recipe prompt text tweaks.

Sequence Diagram(s)

sequenceDiagram
  participant Agent as MCP Agent
  participant driver as cua-driver MCP server
  participant gws as get_window_state
  participant reg as TokenRegistry
  participant tool as click / type_text / etc.

  Agent->>driver: tools/call get_window_state {pid, max_elements, max_depth}
  driver->>gws: invoke
  gws->>gws: walk_tree_bounded(pid, window_id, max_elements, max_depth)
  gws->>reg: register_snapshot(pid, window_id, element_count)
  reg-->>gws: snapshot_id
  gws-->>Agent: structuredContent{elements[{element_token, element_index, ...}], snapshot_id}

  Agent->>driver: tools/call click {pid, element_token: "s001a:3", button: "right"}
  driver->>tool: invoke
  tool->>reg: resolve_element_args(pid, None, "s001a:3", None)
  reg-->>tool: ResolvedElement::Element{window_id, element_index:3, via_token:true}
  tool->>tool: AX element path → effective_action = show_menu
  tool-->>Agent: success "right-click element 3"
Loading

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120 minutes

Possibly related PRs

  • trycua/cua#1779: Modifies cursor-overlay rendering and per-session cursor command plumbing, which directly overlaps with the backing-scale and teardrop silhouette changes to the same crate.
  • trycua/cua#1606: Modifies platform-windows/src/uia/mod.rs around the UIA tree walk and walk_root_by_pid fallback, the same code paths extended here with bounded caps and parent tracking.
  • trycua/cua#1789: Modifies platform-linux/src/tools/impl_.rs for terminal-specific type_text/press_key behavior, directly intersecting with the new terminal detection module and type_text short-circuit added here.

Poem

🐇 Hop, hop, the tokens are here,
Each snapshot a key, each element clear!
Teardrop or arrow — just pass --cursor-shape,
Bounded tree walks keep the context in shape.
Capability lists, a manifest too —
This bunny ships features, all shiny and new! ✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The pull request title accurately summarizes the primary changes: cursor overlay improvements with built-in silhouettes and MCP surface enhancements for Hermes decoupling, matching the four logical groups of work described in the objectives.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/docs-prompts-and-agent-cursor

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@f-trycua
f-trycua merged commit 687d908 into main Jun 21, 2026
63 of 64 checks passed
@f-trycua
f-trycua deleted the feat/docs-prompts-and-agent-cursor branch June 21, 2026 22:31
@github-actions

Copy link
Copy Markdown
Contributor

Linux visual regression artifacts

Matrix jobs now run independently. Download visual artifacts from this workflow run.
Each background-GUI job uploads a .gif of the interaction plus two annotated PNGs (<app>.png raw, <app>-atspi.png with AT-SPI element boxes); the cua-driver-linux-som-overlays artifact adds <app>-som.png cua Set-of-Marks overlays:

  • cua-driver-linux-cursor-click-gif
  • cua-driver-linux-background-terminal-gif
  • cua-driver-linux-parallel-drag-xserver
  • cua-driver-linux-background-gui-chromium
  • cua-driver-linux-background-gui-tk
  • cua-driver-linux-background-gui-gtk3-gedit
  • cua-driver-linux-background-gui-gtk3-mousepad
  • cua-driver-linux-background-gui-gtk3-scite
  • cua-driver-linux-background-gui-gtk4-characters
  • cua-driver-linux-background-gui-qt5-manuskript
  • cua-driver-linux-background-gui-qt5-klog
  • cua-driver-linux-background-gui-qt5-openambit
  • cua-driver-linux-background-gui-qt6-kate
  • cua-driver-linux-background-gui-qt6-kcalc
  • cua-driver-linux-background-gui-qt6-okular
  • cua-driver-linux-background-gui-qt6-qownnotes
  • cua-driver-linux-background-gui-electron-zettlr
  • cua-driver-linux-background-gui-electron-joplin
  • cua-driver-linux-background-gui-electron-logseq
  • cua-driver-linux-som-overlays

Open workflow run and download artifacts

dominofeng-maker added a commit to dominofeng-maker/hermes-agent that referenced this pull request Jul 30, 2026
…token availability (P0-1, P0-2)

P0-1: cua-driver's drag tool is coordinates-only — verified against the local v0.8.3 schema (drag is additionalProperties:false with no element/token parameters) and against upstream trycua/cua, where from_element has zero source references in any version. The element-drag path used to send from_element/to_element straight into the driver and die on an obscure schema rejection. It is now schema-gated before dispatch (CuaDriverBackend._session_supports_drag_elements, cached from tools/list at startup): element drags return ok=False with code='drag_elements_unsupported' and an actionable message (re-capture, read bounds, use from_coordinate/to_coordinate, or upgrade cua-driver). from/to_element token attachment stays capability-gated for future drivers that add element-drag support.

P0-2: capture now reports tokens_available — on the CaptureResult, as a summary note for tokenless snapshots, and in every response payload (multimodal meta, vision_unavailable and AX text paths) — so the model can tell whether element actions carry stale-element protection. An action carrying element_index without a matching snapshot token is now marked degraded with meta.bare_element_index and a re-capture hint (trycua/cua#1961), but only on token-capable drivers; on older tokenless drivers the capture-level notice covers it without per-action noise.

Verified: all computer_use tests green (289/289 incl. 5 new regression tests) plus a live cua-driver 0.8.3 capture (tokens_available=True over a 491-element window) and a blocked element-drag (code=drag_elements_unsupported, zero input events).
x7peeps added a commit to x7peeps/hermes-agent that referenced this pull request Aug 9, 2026
…t frames

cua-driver builds older than 0.10.0 lack the structuredContent.elements
frame (trycua/cua#1961) that Hermes' _parse_elements_from_structured
reads (NousResearch#47072 Surface 2). Those builds still 'work' — element-index
AXPress clicks resolve through the driver — but bounds are always
(0,0,0,0), so pixel-coordinate clicks (UIElement.center()) silently
degrade. Users see no error and no path forward.

Add a version_gate check to the doctor composite report:

* _parse_version_tuple — X.Y.Z / X.Y into a comparable tuple.
* _version_gate_check — fail when the parsed version < 0.10.0 with an
  upgrade hint; pass at/above; skip on unparseable strings (don't
  mislead on exotic version output).
* Wired into _compose_fallback_report after binary_version, so the
  silent bounds=0 degradation becomes a diagnosable failure.

Minimum pinned to 0.10.0 — the contract Hermes' computer-use backend
aligns to (0.9/0.10 permission-mode alignment); 0.19.x verified working.

9 new tests: pass/fail at threshold, below, unparseable skip,
prerelease parse, version tuple parsing. 31 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.

1 participant