shhivv/arc-cua

★ 89⑂ 7

Superfast action layer for computer-use agents

About shhivv/arc-cua

shhivv/arc-cua is an open-source project on GitHub, mainly written in Python. Superfast action layer for computer-use agents It currently holds 89 stars and 7 forks with 0 open issues, and was last pushed on an unknown date (repository created unknown).

Project Overview

AI Homed tracks it on the Today's Trending board, currently at rank #94 with 0 new stars today.

GitHub Repository Details

Repository shhivv/arc-cua · default branch - · size 0 KB · watchers 0 · source: GitHub REST API and repository README

README

arc-cua

Low-latency execution runtime for desktop computer-use agents.

arc-cua lets a planner or CUA agent reason at a high level, hand off a small bounded desktop subtask, and let a fast decision model execute the UI loop without calling the planner again after every click.

JEV is the first supported decision backend.

any planner / CUA
        |
        | Subtask(
        |   goal,
        |   inputs,
        |   verification,
        |   constraints
        | )
        v
+-----------------------+
|       arc-cua         |
|                       |
| observe desktop       |
| AX + local OCR        |
|         v             |
| build legal           |
| action space          |
|         v             |
| JEV decision          |<------+
|         v             |       |
| freshness guard       |       |
|         v             |       |
| execute UI            |       |
|         v             |       |
| wait for UI settle    |-------+
+-----------+-----------+
            |
            v
SUBTASK_COMPLETE / BLOCKED / NEEDS_AGENT
            |
            v
         planner

Why

Computer-use agents should not need a frontier model to reason about every individual click.

A typical CUA loop looks roughly like:

observe
  ↓
large model
  ↓
click
  ↓
observe
  ↓
large model
  ↓
type
  ↓
observe
  ↓
large model
  ↓
click

arc-cua instead separates high-level reasoning from low-level execution:

planner / LLM
     ↓
bounded subtask
     ↓
arc-cua
     ↓
JEV → action
JEV → action
JEV → action
JEV → action
     ↓
return to planner

The optimization target is fewer expensive reasoning calls per completed task, not fewer UI actions.

The agent owns intent

The upstream agent decides:

For example:

Subtask(
    goal="Play Get Lucky by Daft Punk in Spotify",
    inputs={
        "search_query": "Get Lucky Daft Punk",
    },
    verification=(
        "Spotify shows Get Lucky by Daft Punk as the current track",
    ),
    constraints=(
        "Do not modify the user's library",
    ),
)

JEV can then choose:

TYPE_TEXT
target = Spotify search field
input_key = search_query

But JEV does not generate:

"Get Lucky Daft Punk"

That literal was supplied by the agent.

arc-cua resolves:

input_key = search_query
        ↓
Subtask.inputs["search_query"]
        ↓
"Get Lucky Daft Punk"

and executes it.

Agent-facing contract

The boundary is plain Python / JSON.

{
  "goal": "Open Effects and search for Gaussian Blur",
  "verification": [
    "The Effects search field contains Gaussian Blur"
  ],
  "inputs": {
    "effect_name": "Gaussian Blur"
  },
  "constraints": [
    "Do not modify another clip"
  ],
  "max_actions": 15
}

Any GPT, Claude, Gemini, local model, deterministic planner, or other CUA can generate that payload.

from arc_cua import execute_payload

result = execute_payload(executor, payload)

A result may look like:

{
  "status": "SUBTASK_COMPLETE",
  "actions_taken": 4,
  "reason": null
}

The planner deliberately lives outside the package.

---

Hybrid macOS perception

arc-cua currently combines two local perception sources:

              macOS application
                    |
          +---------+---------+
          |                   |
      AXUIElement         Apple Vision
    accessibility             OCR
          |                   |
 buttons / fields        visible text
 menus / values          bounding boxes
          |                   |
          +---------+---------+
                    |
                    v
             DesktopElement[]
                    |
                    v
                   JEV

This lets arc-cua use strong semantic information when the application exposes it, while falling back to screen text when Accessibility is incomplete.

Accessibility

macOS Accessibility provides semantic controls such as:

DesktopElement(
    id="ax_91da...",
    role="TextField",
    name="Search",
    value="",
    actions=(
        ActionKind.CLICK,
        ActionKind.TYPE_TEXT,
    ),
    source="macos_ax",
)

The AX backend can currently:

Local Apple Vision OCR

Some desktop applications expose little useful accessibility information.

For those interfaces, arc-cua captures the target window locally and uses Apple Vision OCR to turn visible screen text into indexed elements.

DesktopElement(
    id="ocr_91ab...",
    role="visible_text",
    name="Get Lucky",
    bounds=Bounds(...),
    actions=(
        ActionKind.CLICK,
        ActionKind.DOUBLE_CLICK,
    ),
    source="macos_ocr",
)

The screenshot is processed locally.

JEV receives structured text elements and IDs, not the screenshot itself.

Visual text-entry targets

OCR does not automatically mean a region is editable.

A region such as:

What do you want to play

may be classified as a plausible visual input and expose:

CLICK
DOUBLE_CLICK
RIGHT_CLICK
TYPE_TEXT

while ordinary visible labels such as:

Daft Punk
Home
••• < >

remain click-only.

This prevents every OCR string on the screen from becoming an arbitrary typing target.

---

Text entry

Literal text always originates from the upstream agent.

For OCR-backed inputs, arc-cua currently uses the same basic macOS text-delivery strategy that worked in Third Hand:

focus visual input
      ↓
Cmd+A
      ↓
brief settle
      ↓
emit Unicode CGEvent key-down/up
one character at a time

Modifier flags are explicitly cleared for each Unicode event so the preceding Cmd+A cannot leak into the typed text.

The decision model chooses:

input_key = search_query

The runtime supplies:

Subtask.inputs["search_query"]

The decision model never invents arbitrary text.

---

Desktop snapshot

Every backend normalizes UI state into DesktopElements.

DesktopElement(
    id="ax_91da...",
    role="TextField",
    name="Search Effects",
    value="",
    actions=(
        ActionKind.CLICK,
        ActionKind.TYPE_TEXT,
    ),
    source="macos_ax",
)

A DesktopSnapshot contains:

The decision policy can only select operations and IDs exposed by the current snapshot.

It cannot invent arbitrary selectors or coordinates.

Coordinates remain a backend implementation detail.

---

Dynamic JEV action space

The JEV policy builds its choices dynamically from the current desktop state.

A request may contain questions like:

operation:
  CLICK
  DOUBLE_CLICK
  RIGHT_CLICK
  TYPE_TEXT
  SET_VALUE
  PRESS_KEY
  HOTKEY
  SCROLL
  SUBTASK_COMPLETE
  BLOCKED
  NEEDS_AGENT

click_target: element_4 element_7 element_12

double_click_target: element_19 element_22

type_text_target: element_7

type_text_input: effect_name filename

One JEV request can ask for the operation and speculative operation-specific choices in parallel.

Only the head corresponding to the selected operation is consumed.

For example:

operation = TYPE_TEXT
type_text_target = element_7
type_text_input = effect_name

The other speculative answers are ignored.

---

Runtime-owned UI settling

Timing is not delegated to JEV.

After a mutating action, arc-cua re-observes the UI until the desktop becomes structurally stable or a timeout is reached.

TYPE_TEXT
    ↓
application begins updating
    ↓
observe
    ↓
state still changing
    ↓
observe
    ↓
state stable
    ↓
ask JEV for next action

This matters for asynchronous interfaces such as:

The decision model decides what to do.

The runtime decides when the resulting UI is ready to reason over again.

---

OCR stability

OCR output is inherently noisy.

The same Spotify search field may be recognized across frames as:

What do you want to play
What doyou want to plafP
Q Whatdoyouwantto play

arc-cua therefore avoids using exact OCR text as visual identity.

OCR regions use coarse spatial identity, and overlapping detections are deduplicated before they are exposed to JEV.

This keeps small OCR fluctuations from looking like entirely new UI state.

---

Freshness protection

Every actionable target has a semantic or visual guard.

Before executing a chosen mutation, the backend checks that the target still corresponds to the UI state JEV observed.

observe
  ↓
JEV decides
  ↓
target changes before execution
  ↓
discard decision
  ↓
observe again

A stale action is never blindly replayed.

The runtime also consumes each decision before mutation so a successful action cannot accidentally execute twice during a retry.

---

Terminal states

arc-cua can return:

SUBTASK_COMPLETE

The agent-supplied verification criteria appear satisfied from the available structured state.

This does not mean the user's entire request is complete.

BLOCKED

The executor cannot make progress using the currently supported UI operations.

NEEDS_AGENT

Higher-level reasoning or perception is required, the action budget has been reached, or the executor cannot establish the supplied verification criteria.

The caller owns overall task completion.

---

Install

Currently macOS-first.

python3.12 -m venv .venv
source .venv/bin/activate

python -m pip install --upgrade pip pip install -e '.[macos]'

Set your TypeSafe key:

export TYPESAFE_API_KEY=...

The live integration uses JEV through TypeSafe.

macOS permissions

The terminal/editor running Python needs:

Accessibility

System Settings
→ Privacy & Security
→ Accessibility

Screen Recording

System Settings
→ Privacy & Security
→ Screen Recording

Screen Recording is required for the Apple Vision OCR path.

Restart the terminal/editor after granting permissions if necessary.

---

Examples

Deterministic architecture demo

No JEV API key required:

python examples/effects_demo.py

Simulated trajectory:

CLICK Effects
TYPE_TEXT Search Effects <- effect_name
DOUBLE_CLICK Gaussian Blur
SUBTASK_COMPLETE

macOS Accessibility probe

Inspect the frontmost application's AX tree:

python examples/macos_ax_probe.py

OCR probe

Inspect visible text detected by Apple Vision:

python examples/ocr_probe.py

Spotify

Example task:

Play Get Lucky by Daft Punk
python examples/test_spotify.py

This exercises an OCR-heavy workflow:

detect Spotify search input
        ↓
TYPE_TEXT agent-supplied search_query
        ↓
wait for results
        ↓
OCR search results
        ↓
select matching track

System Settings

Example task:

Open Appearance and change macOS to Dark mode
python examples/test_settings.py

This exercises a more Accessibility-heavy workflow.

Calendar

Example task:

Create an event called "Meet with Sam" at 3 PM

This demonstrates native app interaction with agent-supplied literal content.

---

Current scope

arc-cua is currently macOS-first.

AX + OCR already covers a useful set of native and Electron desktop workflows.

The next major perception problem is custom graphical interfaces where text alone is insufficient:

These can be added as additional perception providers while keeping the same DesktopElement and execution interfaces.

GitHub Stars & Activity

89Stars
7Forks
0Open issues
PythonLanguage

GitHub Popularity

GitHub stars89
Forks7
Open issues0
Primary languagePython
License-
Stars gained today0
Created-
Last pushed-

Trending History

Daily boardrank #94 · ▲ 0 stars

Related AI Projects

1

Significant-Gravitas / AutoGPT

Python★ 187,469⑂ 46,006▲ 27 stars
2

docling-project / docling

Python★ 67,466⑂ 4,869▲ 585 stars
3

openai / openai-python

Python★ 31,666⑂ 5,904▲ 6 stars
4

harvard-edge / cs249r_book

Python★ 28,390⑂ 3,591▲ 28 stars
5

browser-use / browser-harness

Python★ 17,893⑂ 1,750▲ 87 stars
6

FareedKhan-dev / train-llm-from-scratch

Python★ 10,474⑂ 1,450▲ 265 stars
7

zhouxiaoka / autoclip

Python★ 7,934⑂ 1,551▲ 395 stars
8

More AI Rankings