Skip to content

feat(cua-driver): consolidate type_text; remove get_accessibility_tree - #1415

Closed
f-trycua wants to merge 4 commits into
mainfrom
feat/cua-driver-consolidate-tools
Closed

feat(cua-driver): consolidate type_text; remove get_accessibility_tree#1415
f-trycua wants to merge 4 commits into
mainfrom
feat/cua-driver-consolidate-tools

Conversation

@f-trycua

@f-trycua f-trycua commented May 1, 2026

Copy link
Copy Markdown
Collaborator

Summary

type_text consolidation

  • type_text_chars is deleted. type_text now auto-falls back to CGEvent character synthesis (CGEvent.postToPid) when the AX attribute write is rejected — covers Chromium/Electron inputs transparently.
  • New delay_ms param (0–200, default 30ms) controls inter-character delay in the CGEvent fallback path; ignored when the AX path succeeds.
  • Response summary notes which path was taken (via AX or via CGEvent (AX fallback)).
  • All references in docs, skills (SKILL.md, RECORDING.md, TESTS.md, WEB_APPS.md), mcp-tools.mdx, cli-reference.mdx updated.

get_accessibility_tree removal

  • Tool deleted — its functionality (running apps + visible windows list) is fully covered by list_apps and list_windows.
  • Removed from ToolRegistry; stale references in ScreenshotTool, WindowCapture, and all docs updated to point at list_windows.

Test plan

  • swift build clean ✅
  • cua-driver type_text '{"pid":N,"text":"hello"}' — succeeds on a Cocoa text field (AX path, summary says via AX)
  • Same call against a Chrome input — falls back to CGEvent, summary says via CGEvent (AX fallback)
  • cua-driver type_text '{"pid":N,"text":"hello","delay_ms":50}' — delay_ms respected in fallback path
  • cua-driver get_accessibility_treeUnknown tool error (removed)
  • cua-driver list_apps and cua-driver list_windows still work as the canonical discovery tools

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • get_window_state now supports file-based screenshot output via screenshot_out_file parameter
    • type_text tool now includes keystroke fallback with optional delay_ms parameter (0–200ms)
  • Removed Tools

    • Removed get_accessibility_tree tool
    • Removed type_text_chars tool; functionality consolidated into type_text
  • CLI Changes

    • Renamed --image-out option to --screenshot-out-file
  • Documentation

    • Updated tool references, integration guides, and screenshot handling documentation

f-trycua and others added 4 commits April 30, 2026 21:32
…base64 by default

get_window_state now accepts screenshot_out_file (optional absolute path).
When set, screenshot bytes are written to that file, the MCP image content
block is omitted, and screenshot_file_path is returned in structuredContent
instead — callers get the AX tree without paying the ~31 KB base64-in-context
token cost.

CLI change: removed mergeImageContentIntoJSON — stdout no longer splices
screenshot_png_b64 into the JSON by default. Use --image-out <path> or the
new screenshot_out_file param to get the image on disk. This fixes context
saturation in agents that call get_window_state via CLI subprocess (OpenCode
with local Ollama models being the motivating case).

Docs: integrations.mdx OpenCode section now warns about the CLI fallback
problem and shows the modalities config fix for local vision models. SKILL.md
updated to remove the legacy jq .screenshot_png_b64 path and document
screenshot_out_file.

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

Aligns the CLI flag name with the tool param name (screenshot_out_file)
so both interfaces use the same terminology.

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

- GetWindowStateTool: only set resolvedScreenshotFilePath when write
  actually succeeds; fall through to inline image block on I/O error
- AppState: fix doc comment — saved file is JPEG not PNG
- SKILL.md: remove stale has_screenshot entry; add bash fence language
- integrations.mdx: update callout to reflect actual CLI behavior after
  mergeImageContentIntoJSON removal

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
type_text now auto-falls back to CGEvent character synthesis when the AX
write is rejected — covers Chromium/Electron inputs without requiring the
caller to choose between two tools. Adds delay_ms param (default 30ms,
used only in the CGEvent path). TypeTextCharsTool deleted; all references
updated to type_text throughout docs, skills, and tests.

get_accessibility_tree removed — its functionality (running apps + window
list) is fully covered by list_apps and list_windows. Tool file deleted,
removed from ToolRegistry, stale doc references updated to list_windows.

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

vercel Bot commented May 1, 2026

Copy link
Copy Markdown
Contributor

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

Project Deployment Actions Updated (UTC)
docs Ready Ready Preview, Comment May 1, 2026 4:51am

Request Review

@coderabbitai

coderabbitai Bot commented May 1, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

The PR consolidates text input tooling by removing type_text_chars and get_accessibility_tree tools, adding fallback logic to type_text for CGEvent synthesis, and shifting from inline base64 image embedding to file-based screenshot handling via a new screenshot_out_file parameter.

Changes

Cohort / File(s) Summary
Documentation Updates
docs/content/docs/cua-driver/guide/getting-started/integrations.mdx, docs/content/docs/cua-driver/reference/cli-reference.mdx, docs/content/docs/cua-driver/reference/mcp-tools.mdx
Removed get_accessibility_tree from documented tools; updated type_text documentation to reflect automatic CGEvent fallback behavior and new delay_ms parameter; removed type_text_chars documentation.
Skill & Recording Docs
libs/cua-driver/Skills/cua-driver/SKILL.md, libs/cua-driver/Skills/cua-driver/RECORDING.md, libs/cua-driver/Skills/cua-driver/WEB_APPS.md, libs/cua-driver/Skills/cua-driver/TESTS.md
Updated keyboard input guidance to standardize on type_text instead of type_text_chars; revised get_window_state screenshot workflow to use file-based --screenshot-out-file instead of inline base64; removed type_text_chars from recorded action tools and replay examples.
Tool Removal
libs/cua-driver/Sources/CuaDriverServer/Tools/GetAccessibilityTreeTool.swift, libs/cua-driver/Sources/CuaDriverServer/Tools/TypeTextCharsTool.swift
Deleted GetAccessibilityTreeTool (48 lines) and TypeTextCharsTool (111 lines) entirely; both tools no longer available for MCP invocation.
TypeTextTool Enhancement
libs/cua-driver/Sources/CuaDriverServer/Tools/TypeTextTool.swift
Added fallback logic: attempts AXSelectedText write, then falls back to CGEvent.postToPid character synthesis on AXInputError; new optional delay_ms parameter (default 30, range 0–200) controls fallback pacing; success responses indicate insertion method (AX vs. CGEvent).
GetWindowStateTool Enhancement
libs/cua-driver/Sources/CuaDriverServer/Tools/GetWindowStateTool.swift
Added optional screenshot_out_file parameter; when set, writes screenshot bytes to disk and suppresses inline .image content block; new screenshotFilePath field included in structured output.
CLI Refactoring
libs/cua-driver/Sources/CuaDriverCLI/CallCommand.swift
Renamed --image-out to --screenshot-out-file; removed mergeImageContentIntoJSON logic; JSON output no longer augmented with screenshot_png_b64; structured content emitted directly.
AppState & Registry Updates
libs/cua-driver/Sources/CuaDriverCore/AppState/AppState.swift, libs/cua-driver/Sources/CuaDriverServer/ToolRegistry.swift
Added optional screenshotFilePath: String? property to AppStateSnapshot; removed type_text_chars from actionToolNames and removed handler registrations for GetAccessibilityTreeTool and TypeTextCharsTool.
Documentation References
libs/cua-driver/Sources/CuaDriverCore/Capture/WindowCapture.swift, libs/cua-driver/Sources/CuaDriverServer/Tools/ScreenshotTool.swift
Updated documentation comments to reference list_windows instead of get_accessibility_tree for obtaining window IDs; no functional logic changes.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • PR #1414: Implements identical code-level changes across tool handlers, CLI option renaming, and screenshot file path integration.
  • PR #1359: Introduced the original GetAccessibilityTreeTool, TypeTextCharsTool, and --image-out option that this PR removes/refactors.
  • PR #1407: Updates the same OpenCode/MCP integration documentation with related config guidance.

Poem

🐰 With burrows deep and tools refined,
We consolidated types, left chars behind,
Fallbacks now flow like garden streams,
From AX to CGEvent, fulfilling dreams—
Screenshots saved, no base64 in sight,
Our tunnels run cleaner, our code feels right! 🥕

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 70.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the two main changes: consolidating type_text and removing get_accessibility_tree, matching the core objectives.
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/cua-driver-consolidate-tools
⚔️ Resolve merge conflicts
  • Resolve merge conflict in branch feat/cua-driver-consolidate-tools

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
Review rate limit: 7/8 reviews remaining, refill in 7 minutes and 30 seconds.

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
docs/content/docs/cua-driver/reference/mcp-tools.mdx (1)

8-10: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Correct the tool count in the intro.

This page now enumerates 29 tools, so 28 is stale after the type_text consolidation and get_accessibility_tree removal.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/content/docs/cua-driver/reference/mcp-tools.mdx` around lines 8 - 10,
Update the introductory count from "28 MCP tools" to "29 MCP tools" in the
`cua-driver` docs and ensure the same numeric reference is updated anywhere else
on the page; specifically edit the sentence that currently reads "`cua-driver`
exposes 28 MCP tools through a single stdio server (`cua-driver mcp`)" to use
29, and double-check references to the tool list (e.g., mentions of `type_text`
consolidation and `get_accessibility_tree` removal) to ensure the count matches
the enumerated tools.
🧹 Nitpick comments (1)
docs/content/docs/cua-driver/reference/cli-reference.mdx (1)

370-371: ⚡ Quick win

Mention delay_ms in the type_text inventory entry for discoverability.

The new fallback pacing control is a key part of the tool contract and worth surfacing in this summary line too.

Suggested doc tweak
-- `type_text` — insert text via `AXSelectedText` with automatic CGEvent fallback for Chromium/Electron inputs. Pid-scoped.
+- `type_text` — insert text via `AXSelectedText` with automatic CGEvent fallback for Chromium/Electron inputs; supports `delay_ms` (0–200, default 30) for fallback pacing. Pid-scoped.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/content/docs/cua-driver/reference/cli-reference.mdx` around lines 370 -
371, Update the inventory summary line for the type_text entry to mention the
new delay_ms parameter for discoverability: locate the `type_text` entry in the
CLI reference summary (the line that currently reads "`type_text` — insert text
via `AXSelectedText` with automatic CGEvent fallback for Chromium/Electron
inputs. Pid-scoped.") and append or integrate "supports delay_ms for
pacing/fallback control" (or equivalent short phrasing) so the summary includes
the `delay_ms` symbol.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@libs/cua-driver/Skills/cua-driver/SKILL.md`:
- Around line 444-446: Update the SKILL.md example so it only claims
--screenshot-out-file works for screenshot-bearing capture modes: change or
annotate the `cua-driver get_window_state '{"pid":N,"window_id":W}'
--screenshot-out-file /tmp/shot.jpg` example to explicitly state it applies to
`som`/`vision` capture modes (or add a short note that `ax` snapshots are
tree-only and the flag is a no-op or emits a warning when no screenshot exists);
reference the CLI flag `--screenshot-out-file`, the command `cua-driver
get_window_state`, and the capture modes `ax`, `som`, `vision` in the updated
text so readers know the limitation.

In `@libs/cua-driver/Sources/CuaDriverServer/Tools/TypeTextTool.swift`:
- Around line 90-91: The code currently reads delay_ms into delayMs and relies
on KeyboardInput.typeCharacters to clamp it, causing the response summary to
show the raw value; update TypeTextTool to clamp delay_ms once right after
reading it (e.g., compute clampedDelay = max(minDelay, min(maxDelay, delayMs)))
and pass clampedDelay into KeyboardInput.typeCharacters and into any
response/summary text so reported and actual behavior match; apply the same
change where delay_ms is read in the other block referenced (around the 154-160
area) so both uses use the clampedDelay variable.

---

Outside diff comments:
In `@docs/content/docs/cua-driver/reference/mcp-tools.mdx`:
- Around line 8-10: Update the introductory count from "28 MCP tools" to "29 MCP
tools" in the `cua-driver` docs and ensure the same numeric reference is updated
anywhere else on the page; specifically edit the sentence that currently reads
"`cua-driver` exposes 28 MCP tools through a single stdio server (`cua-driver
mcp`)" to use 29, and double-check references to the tool list (e.g., mentions
of `type_text` consolidation and `get_accessibility_tree` removal) to ensure the
count matches the enumerated tools.

---

Nitpick comments:
In `@docs/content/docs/cua-driver/reference/cli-reference.mdx`:
- Around line 370-371: Update the inventory summary line for the type_text entry
to mention the new delay_ms parameter for discoverability: locate the
`type_text` entry in the CLI reference summary (the line that currently reads
"`type_text` — insert text via `AXSelectedText` with automatic CGEvent fallback
for Chromium/Electron inputs. Pid-scoped.") and append or integrate "supports
delay_ms for pacing/fallback control" (or equivalent short phrasing) so the
summary includes the `delay_ms` symbol.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 928e64b4-0c1b-4b5a-9dbd-65f7766a10e0

📥 Commits

Reviewing files that changed from the base of the PR and between 9d623c0 and f2896b9.

📒 Files selected for processing (16)
  • docs/content/docs/cua-driver/guide/getting-started/integrations.mdx
  • docs/content/docs/cua-driver/reference/cli-reference.mdx
  • docs/content/docs/cua-driver/reference/mcp-tools.mdx
  • libs/cua-driver/Skills/cua-driver/RECORDING.md
  • libs/cua-driver/Skills/cua-driver/SKILL.md
  • libs/cua-driver/Skills/cua-driver/TESTS.md
  • libs/cua-driver/Skills/cua-driver/WEB_APPS.md
  • libs/cua-driver/Sources/CuaDriverCLI/CallCommand.swift
  • libs/cua-driver/Sources/CuaDriverCore/AppState/AppState.swift
  • libs/cua-driver/Sources/CuaDriverCore/Capture/WindowCapture.swift
  • libs/cua-driver/Sources/CuaDriverServer/ToolRegistry.swift
  • libs/cua-driver/Sources/CuaDriverServer/Tools/GetAccessibilityTreeTool.swift
  • libs/cua-driver/Sources/CuaDriverServer/Tools/GetWindowStateTool.swift
  • libs/cua-driver/Sources/CuaDriverServer/Tools/ScreenshotTool.swift
  • libs/cua-driver/Sources/CuaDriverServer/Tools/TypeTextCharsTool.swift
  • libs/cua-driver/Sources/CuaDriverServer/Tools/TypeTextTool.swift
💤 Files with no reviewable changes (2)
  • libs/cua-driver/Sources/CuaDriverServer/Tools/TypeTextCharsTool.swift
  • libs/cua-driver/Sources/CuaDriverServer/Tools/GetAccessibilityTreeTool.swift

Comment on lines +444 to 446
# CLI --screenshot-out-file flag is equivalent and works for all capture modes
cua-driver get_window_state '{"pid":N,"window_id":W}' --screenshot-out-file /tmp/shot.jpg
```

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Scope the --screenshot-out-file example to screenshot-bearing modes.

ax snapshots are tree-only, so this flag cannot produce a file there. As written, the example reads as if --screenshot-out-file works for every capture mode; please limit it to som / vision, or note the no-op warning when no screenshot exists.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@libs/cua-driver/Skills/cua-driver/SKILL.md` around lines 444 - 446, Update
the SKILL.md example so it only claims --screenshot-out-file works for
screenshot-bearing capture modes: change or annotate the `cua-driver
get_window_state '{"pid":N,"window_id":W}' --screenshot-out-file /tmp/shot.jpg`
example to explicitly state it applies to `som`/`vision` capture modes (or add a
short note that `ax` snapshots are tree-only and the flag is a no-op or emits a
warning when no screenshot exists); reference the CLI flag
`--screenshot-out-file`, the command `cua-driver get_window_state`, and the
capture modes `ax`, `som`, `vision` in the updated text so readers know the
limitation.

Comment on lines +90 to 91
let delayMs = arguments?["delay_ms"]?.intValue ?? 30
guard let pid = Int32(exactly: rawPid) else {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Clamp delay_ms once before use so behavior and summary stay consistent.

KeyboardInput.typeCharacters clamps internally, but the response text reports the raw value. That can misreport the effective delay.

Suggested patch
-            let delayMs = arguments?["delay_ms"]?.intValue ?? 30
+            let requestedDelayMs = arguments?["delay_ms"]?.intValue ?? 30
+            let delayMs = max(0, min(200, requestedDelayMs))

Also applies to: 154-160

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@libs/cua-driver/Sources/CuaDriverServer/Tools/TypeTextTool.swift` around
lines 90 - 91, The code currently reads delay_ms into delayMs and relies on
KeyboardInput.typeCharacters to clamp it, causing the response summary to show
the raw value; update TypeTextTool to clamp delay_ms once right after reading it
(e.g., compute clampedDelay = max(minDelay, min(maxDelay, delayMs))) and pass
clampedDelay into KeyboardInput.typeCharacters and into any response/summary
text so reported and actual behavior match; apply the same change where delay_ms
is read in the other block referenced (around the 154-160 area) so both uses use
the clampedDelay variable.

@f-trycua

f-trycua commented May 1, 2026

Copy link
Copy Markdown
Collaborator Author

Superseded by #1416 (clean rebase off main).

@f-trycua f-trycua closed this May 1, 2026
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