Skip to content

fix(cua): stabilize native window previews and Windows app identity - #16975

Draft
juliusmarminge wants to merge 8 commits into
t3code/cua/6-browser-tabsfrom
t3code/cua/linux-pip
Draft

juliusmarminge wants to merge 8 commits into
t3code/cua/6-browser-tabsfrom
t3code/cua/linux-pip

Conversation

@juliusmarminge

@juliusmarminge juliusmarminge commented Oct 7, 2026 •

Copy link
Copy Markdown
Member

Computer-use PiP could show unrelated desktop pixels after a failed window capture, flash while replacing images, and remain open after a turn ended. Capture now stays bound to the selected window, retries transient failures, decodes replacement frames before painting them to a persistent canvas, and dismisses the computer preview when the turn settles. Windows packaged apps now retain their own names and native icons instead of appearing as ApplicationFrameHost.exe.

The subscriber-driven loop caps active capture at 4 FPS, leaves idle time after slow captures, suppresses identical frames, and drops static-window polling to 1 FPS after three unchanged captures. A changed frame restores the normal rate; renewed motion can take up to one second to detect. Drivers advertising display_only use an observation-only capture that skips action-registry PNG decoding and snapshot replacement. Older drivers keep the typed screenshot path. No SDK ABI change is required.

Stacked on #16532.

Windows integration

Window identities are keyed by PID and window handle, so Calculator and Settings remain distinct when Windows hosts them in one process. PiP captions and icons travel with the captured frame, display-only inspections do not redirect the preview, and native icons resolve packaged-app AUMIDs through their manifests. Duplicate detection includes app identity as well as image bytes and window metadata.

The temporary Cua Driver 0.34.1 CREATE_NO_WINDOW source patch and regression test are included in patches/cua-driver-0.34.1-windows-console.patch. T3CODE_CUA_DRIVER_SDK_LIBRARY optionally stages a locally rebuilt Windows SDK DLL into both the desktop host and server sidecar. This override is opt-in; normal release builds still use the published SDK.

Windows test build 9007 was exercised interactively: Calculator operations stayed in the background, its name/icon matched the preview, closing it showed an unavailable state, and Theo confirmed no flashing. After integration with the newer stack head: 133 focused tests pass, one is skipped, and two packaging tests fail identically on the parent commit (Linux cargo executable lookup on Windows and the cross-architecture native probe). Server/web typechecks and targeted lint pass. The combined stack has not received another packaged interactive pass.

Windows integration by GPT-6.1-Sol through the Codex harness.

Cua Driver 0.34.1

The native Linux fixes this PR used to carry as a source patch shipped upstream in Cua Driver 0.34.1 (trycua/cua#4895): the Wayland opt-in reaches embedded hosts, GNOME windows are captured from their own actor with compositor downscaling (WinRects API 10), the GNOME helper reuses one session-bus connection, GNOME's changing PNG Creation Time chunk is stripped, and get_window_state accepts display_only on Linux, macOS, and Windows with the same schema, refusal, and response fields.

The stack now pins 0.34.1 from #16527 (SDK, platform packages, and the release checksum table), and this PR packages Linux like macOS and Windows: the published driver archive is bundled, and the SDK's native library comes from npm. The source patch, scripts/build-cua-linux.sh, SDK library replacement, the Linux CLI's bundled-driver lookup, and the extra Rust toolchain and X11/Wayland dev packages in CI are removed.

One piece of the old patch is not upstream: it hid GNOME's stage-wide agent cursor during window-targeted actions and after each action ended. With 0.34.1 that cursor follows upstream behavior.

Evidence from the patched build

Measured on the patched 0.34.0 build, whose native changes 0.34.1 now ships. 0.34.1 itself has not been reprofiled.

A covered Helium window benchmark measured median native capture at 61.1 ms normally versus 38.5 ms display-only (19 measured calls per mode after warmup). For static content, normal 4 FPS capture used 14.3% driver CPU / 13.3% GNOME CPU / 4.8% device GPU busy; display-only adaptive polling used 1.8% / 6.9% / 3.8%, with 23 captures and one changed frame over 20.8 seconds. For animated content, capture stayed at 4 FPS while driver CPU fell from 14.8% to 6.1%. The persistent D-Bus transport reduced median native capture from 381 ms to 58 ms and raised capture rate from 1.29 to 4 FPS.

Installed build 2757: the covered Helium window appears correctly in the actual PiP. A 30-second static run captured 33 frames and averaged 2.65% device GPU busy and 41.7% tracked CPU (down from 7.3%/62.2% on 2755); an animated run captured 119 frames (3.96/sec) at 9.48% GPU and 62.4% CPU (down from 13.0%/72.9%). Closing PiP stopped capture completely: zero calls for 20 seconds. Tracked CPU includes T3 processes, GNOME, Cua, and Helium; one core = 100%.

Validation

  • Focused tests: apps/server/src/cua, apps/desktop/src/cua, packages/shared/src/cuaDriverHostOptions.test.ts, scripts/build-desktop-artifact.test.ts, scripts/lib/cli-external-packages.test.ts: 166 pass. The one failure, "skips the primary native probe for cross-architecture Windows payloads", also fails on main.
  • Typecheck clean for scripts, server, shared, and desktop; targeted lint clean.
  • The upstream 0.34.1 linux-x86_64-binary archive matches the pinned SHA-256 on Linux x64, reports cua-driver 0.34.1, and its get_window_state schema advertises display_only with the description our capability probe matches.

Still draft: before/after video evidence is outstanding, and an installed 0.34.1 build has not been exercised on GNOME.

Implemented with GPT-6 Astra through the Codex harness; the 0.34.1 bump and removal of the source patch by Claude Opus 5.5 through Claude Code.

🤖 Generated with Claude Code

Application mentions

The composer can now find installed applications from the selected environment when typing @, including Helium on Windows. Selections retain the environment and launch identity, render as native app chips, and tell providers to resolve the current window before interacting. The inventory uses Cua Driver's cross-platform listApps API and stays disabled when Computer Use is off. Native icons retain a fallback until the image loads and when loading fails.

Validation: 184 focused tests pass across app inventory, reference projection, composer editing, icon loading, and authorization. Server/web typechecks passed. Windows build 9009 was exercised with an @helium mention: the provider received the correct executable and environment, launched Helium, navigated releases and discussions, and closed its test window. macOS/Linux inventory behavior has fixture coverage but has not been exercised interactively.

Application mentions implemented with GPT-6.1-Sol through the Codex harness.

@github-actions github-actions Bot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Oct 7, 2026
@juliusmarminge juliusmarminge added the macroscope-review Opt PRs made by unvouched contributors in for Macroscope review. Vouched contributors auto-reviews label Oct 7, 2026
@juliusmarminge
juliusmarminge added this pull request to stack #16533 October 7, 2026 22:05
@github-actions

github-actions Bot commented Oct 7, 2026 •

Copy link
Copy Markdown
Contributor

Thread transfer impact

✅ Thread transfer remains within every enforced ceiling.

ℹ️ No successful main baseline artifact is available yet. This run establishes the initial measurement.

Provider Metric Main baseline This PR Impact PR ceiling
Codex Total thread wire — 5.0 KiB — 6.8 KiB ✅
Codex Thread snapshot wire — 3.8 KiB — 4.9 KiB ✅
Codex Live turn WebSocket wire — 1.2 KiB — 2.0 KiB ✅
Codex Live turn WebSocket decoded — 20.9 KiB — 29.3 KiB ✅
Codex Live turn messages — 2 — 8 ✅
Claude Total thread wire — 5.0 KiB — 6.8 KiB ✅
Claude Thread snapshot wire — 3.8 KiB — 4.9 KiB ✅
Claude Live turn WebSocket wire — 1.2 KiB — 2.0 KiB ✅
Claude Live turn WebSocket decoded — 21.2 KiB — 29.3 KiB ✅
Claude Live turn messages — 2 — 8 ✅

Baseline: unavailable · PR result: 5261335 · Source CI: success

Scenario and decoded snapshot size

10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.

  • Codex decoded thread snapshot: 108.5 KiB
  • Claude decoded thread snapshot: 108.8 KiB

Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed.

@github-actions github-actions Bot added size:XXL 1,000+ changed lines (additions + deletions). and removed size:L 100-499 changed lines (additions + deletions). labels Oct 7, 2026
f-trycua added a commit to trycua/cua that referenced this pull request Oct 8, 2026
…d hosts (#4877)

The embedded host builds the daemon environment from an allowlist, and
CUA_DRIVER_RS_ENABLE_WAYLAND was not on it. A host such as an Electron
app could never turn on the native Wayland backend: the opt-in was
dropped silently. Allow it, and test inheritance, an explicit host
opt-in, and an explicit opt-out winning over an inherited opt-in.

Ported from T3 Code's Linux patch to Cua Driver 0.34.0
(pingdotgg/t3code#16975, MIT, Copyright (c) 2026 T3 Tools Inc.);
credited in THIRD_PARTY_NOTICES.md.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
f-trycua added a commit to trycua/cua that referenced this pull request Oct 8, 2026
…ing (#4880)

The libei worker replied as soon as input requests were flushed to the
socket. A flush is not delivery: the caller's focus guard could restore
the user's window while the compositor still had the input queued, and
the input then landed in the wrong app.

After each input command, send ei_connection.sync and reply only when
EIS answers its callback, which it does after processing every earlier
request. If no answer comes within 5 s, fail with "delivery is unknown"
instead of reporting success. WaitReady and failed commands reply
immediately as before.

Ported from T3 Code's Linux patch to Cua Driver 0.34.0
(pingdotgg/t3code#16975, MIT, Copyright (c) 2026 T3 Tools Inc.).

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
f-trycua added a commit to trycua/cua that referenced this pull request Oct 8, 2026
…s v10)

On GNOME Wayland, window screenshots were crops of the Shell stage.
GetRects proves a window's geometry, not that nothing covers it, so a
covered window's screenshot showed the app on top.

The WinRects helper gains two additive methods:

- CaptureWindow(id, pid), API 9: snapshot the window's own actor with
  paint_to_content. Covered windows keep their content, nothing is
  activated, and a 1x1 transparent clone keeps Mutter painting a fully
  covered window for 4 s after the last capture. Refused while locked,
  for minimized windows, and above 32 MiB.
- CaptureWindowPreview(id, pid, max), API 10: the same capture,
  downscaled on the GPU, returning the full-size dimensions too.

The driver uses CaptureWindow whenever the attested helper reports
API 9 or newer, and then never falls back to a stage crop. Older
helpers keep the stage crop, so users who have not reinstalled the
helper keep window screenshots. A screenshot-only get_window_state
with a size cap uses CaptureWindowPreview (falling back to the full
capture on older helpers), and GNOME's per-capture Creation Time PNG
chunk is removed so unchanged preview frames compare equal.
list_windows asks a verified GNOME helper first instead of probing
other compositor protocols.

Versioning: the UUID stays winrects@cua. One UUID means one installed
copy per user; two UUIDs would race for org.cua.WinRects. API numbers
9 and 10 match T3 Code's bundled helper exactly, so either copy serves
both drivers. install.sh and both cua-driver installers no longer
downgrade a newer installed helper (install.sh --force still does).
The helper README documents the rules and the version table.

Ported from T3 Code's Linux patch to Cua Driver 0.34.0
(pingdotgg/t3code#16975, MIT, Copyright (c) 2026 T3 Tools Inc.). The
stage-crop fallback for older helpers and the no-downgrade installers
are new here.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
f-trycua added a commit to trycua/cua that referenced this pull request Oct 8, 2026
…er (#4879)

* perf(cua-driver): reuse one session-bus connection for the GNOME helper

Every WinRects call spawned a gdbus subprocess, and owner attestation
alone makes three D-Bus calls before the real one. A live preview pays
that on every frame. Replace the subprocess with one zbus connection on
a dedicated single-thread Tokio runtime, so callers inside or outside
Tokio can block on it without nesting runtimes.

Bodies are typed on the wire, and replies keep the textual shape the
existing parsers read (GetRects now arrives as raw JSON, which also
avoids gdbus quoting). A timeout or transport error drops the
connection and the next call reconnects; a mutation is never replayed.
An error reply, such as no helper on the bus, keeps the connection.

T3 Code measured window capture going from 381 ms to 58 ms with this
transport. Ported from their Linux patch to Cua Driver 0.34.0
(pingdotgg/t3code#16975, MIT, Copyright (c) 2026 T3 Tools Inc.); the
reply-versus-transport split is new here.

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

* test(cua-driver): cover GetRects titles gdbus would have escaped

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

* fix(cua-driver): strict GetRects parsing and run the bus test in Nix

Parse the typed GetRects reply as raw JSON instead of slicing a bracket
span, and reuse that parser for focus. Salvaged from #4809, including
the malformed-snapshot fixtures and the Nix dbus check input.

Co-authored-by: injaneity <44902825+injaneity@users.noreply.github.com>

* test(cua-driver): start the private test bus from its own config

dbus-daemon --session needs the system session.conf, which the Nix
build sandbox lacks; the daemon then exits without an address. Write a
minimal session config listening in a temp dir instead.

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Louis Grenard <1731544+louistiti@users.noreply.github.com>
f-trycua added a commit to trycua/cua that referenced this pull request Oct 8, 2026
…s v10)

On GNOME Wayland, window screenshots were crops of the Shell stage.
GetRects proves a window's geometry, not that nothing covers it, so a
covered window's screenshot showed the app on top.

The WinRects helper gains two additive methods:

- CaptureWindow(id, pid), API 9: snapshot the window's own actor with
  paint_to_content. Covered windows keep their content, nothing is
  activated, and a 1x1 transparent clone keeps Mutter painting a fully
  covered window for 4 s after the last capture. Refused while locked,
  for minimized windows, and above 32 MiB.
- CaptureWindowPreview(id, pid, max), API 10: the same capture,
  downscaled on the GPU, returning the full-size dimensions too.

The driver uses CaptureWindow whenever the attested helper reports
API 9 or newer, and then never falls back to a stage crop. Older
helpers keep the stage crop, so users who have not reinstalled the
helper keep window screenshots. A screenshot-only get_window_state
with a size cap uses CaptureWindowPreview (falling back to the full
capture on older helpers), and GNOME's per-capture Creation Time PNG
chunk is removed so unchanged preview frames compare equal.
list_windows asks a verified GNOME helper first instead of probing
other compositor protocols.

Versioning: the UUID stays winrects@cua. One UUID means one installed
copy per user; two UUIDs would race for org.cua.WinRects. API numbers
9 and 10 match T3 Code's bundled helper exactly, so either copy serves
both drivers. install.sh and both cua-driver installers no longer
downgrade a newer installed helper (install.sh --force still does).
The helper README documents the rules and the version table.

Ported from T3 Code's Linux patch to Cua Driver 0.34.0
(pingdotgg/t3code#16975, MIT, Copyright (c) 2026 T3 Tools Inc.). The
stage-crop fallback for older helpers and the no-downgrade installers
are new here.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
f-trycua added a commit to trycua/cua that referenced this pull request Oct 8, 2026
…s v10) (#4882)

* feat(cua-driver): capture GNOME windows from their own actor (WinRects v10)

On GNOME Wayland, window screenshots were crops of the Shell stage.
GetRects proves a window's geometry, not that nothing covers it, so a
covered window's screenshot showed the app on top.

The WinRects helper gains two additive methods:

- CaptureWindow(id, pid), API 9: snapshot the window's own actor with
  paint_to_content. Covered windows keep their content, nothing is
  activated, and a 1x1 transparent clone keeps Mutter painting a fully
  covered window for 4 s after the last capture. Refused while locked,
  for minimized windows, and above 32 MiB.
- CaptureWindowPreview(id, pid, max), API 10: the same capture,
  downscaled on the GPU, returning the full-size dimensions too.

The driver uses CaptureWindow whenever the attested helper reports
API 9 or newer, and then never falls back to a stage crop. Older
helpers keep the stage crop, so users who have not reinstalled the
helper keep window screenshots. A screenshot-only get_window_state
with a size cap uses CaptureWindowPreview (falling back to the full
capture on older helpers), and GNOME's per-capture Creation Time PNG
chunk is removed so unchanged preview frames compare equal.
list_windows asks a verified GNOME helper first instead of probing
other compositor protocols.

Versioning: the UUID stays winrects@cua. One UUID means one installed
copy per user; two UUIDs would race for org.cua.WinRects. API numbers
9 and 10 match T3 Code's bundled helper exactly, so either copy serves
both drivers. install.sh and both cua-driver installers no longer
downgrade a newer installed helper (install.sh --force still does).
The helper README documents the rules and the version table.

Ported from T3 Code's Linux patch to Cua Driver 0.34.0
(pingdotgg/t3code#16975, MIT, Copyright (c) 2026 T3 Tools Inc.). The
stage-crop fallback for older helpers and the no-downgrade installers
are new here.

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

* docs(cua-driver): credit every T3 Code Linux port in THIRD_PARTY_NOTICES

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions github-actions Bot added size:L 100-499 changed lines (additions + deletions). and removed size:XXL 1,000+ changed lines (additions + deletions). labels Oct 9, 2026
tanishqkancharla pushed a commit to tanishqkancharla/cua that referenced this pull request Oct 10, 2026
…d hosts (trycua#4877)

The embedded host builds the daemon environment from an allowlist, and
CUA_DRIVER_RS_ENABLE_WAYLAND was not on it. A host such as an Electron
app could never turn on the native Wayland backend: the opt-in was
dropped silently. Allow it, and test inheritance, an explicit host
opt-in, and an explicit opt-out winning over an inherited opt-in.

Ported from T3 Code's Linux patch to Cua Driver 0.34.0
(pingdotgg/t3code#16975, MIT, Copyright (c) 2026 T3 Tools Inc.);
credited in THIRD_PARTY_NOTICES.md.

Backported to the 0.34 release line from main (cherry picked from commit 07cbc6c).

Conflict: THIRD_PARTY_NOTICES.md keeps the 0.34.0 table and adds only the T3 Code row (the QuickJS/rquickjs rows and trope-cua wording belong to 0.35 changes not in this line).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
tanishqkancharla pushed a commit to tanishqkancharla/cua that referenced this pull request Oct 10, 2026
…ing (trycua#4880)

The libei worker replied as soon as input requests were flushed to the
socket. A flush is not delivery: the caller's focus guard could restore
the user's window while the compositor still had the input queued, and
the input then landed in the wrong app.

After each input command, send ei_connection.sync and reply only when
EIS answers its callback, which it does after processing every earlier
request. If no answer comes within 5 s, fail with "delivery is unknown"
instead of reporting success. WaitReady and failed commands reply
immediately as before.

Ported from T3 Code's Linux patch to Cua Driver 0.34.0
(pingdotgg/t3code#16975, MIT, Copyright (c) 2026 T3 Tools Inc.).

Backported to the 0.34 release line from main (cherry picked from commit 9487b0f).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
tanishqkancharla pushed a commit to tanishqkancharla/cua that referenced this pull request Oct 10, 2026
…er (trycua#4879)

* perf(cua-driver): reuse one session-bus connection for the GNOME helper

Every WinRects call spawned a gdbus subprocess, and owner attestation
alone makes three D-Bus calls before the real one. A live preview pays
that on every frame. Replace the subprocess with one zbus connection on
a dedicated single-thread Tokio runtime, so callers inside or outside
Tokio can block on it without nesting runtimes.

Bodies are typed on the wire, and replies keep the textual shape the
existing parsers read (GetRects now arrives as raw JSON, which also
avoids gdbus quoting). A timeout or transport error drops the
connection and the next call reconnects; a mutation is never replayed.
An error reply, such as no helper on the bus, keeps the connection.

T3 Code measured window capture going from 381 ms to 58 ms with this
transport. Ported from their Linux patch to Cua Driver 0.34.0
(pingdotgg/t3code#16975, MIT, Copyright (c) 2026 T3 Tools Inc.); the
reply-versus-transport split is new here.

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

* test(cua-driver): cover GetRects titles gdbus would have escaped

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

* fix(cua-driver): strict GetRects parsing and run the bus test in Nix

Parse the typed GetRects reply as raw JSON instead of slicing a bracket
span, and reuse that parser for focus. Salvaged from trycua#4809, including
the malformed-snapshot fixtures and the Nix dbus check input.

Co-authored-by: injaneity <44902825+injaneity@users.noreply.github.com>

* test(cua-driver): start the private test bus from its own config

dbus-daemon --session needs the system session.conf, which the Nix
build sandbox lacks; the daemon then exits without an address. Write a
minimal session config listening in a temp dir instead.

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

---------

Backported to the 0.34 release line from main (cherry picked from commit 48cc491).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
tanishqkancharla pushed a commit to tanishqkancharla/cua that referenced this pull request Oct 10, 2026
…s v10) (trycua#4882)

* feat(cua-driver): capture GNOME windows from their own actor (WinRects v10)

On GNOME Wayland, window screenshots were crops of the Shell stage.
GetRects proves a window's geometry, not that nothing covers it, so a
covered window's screenshot showed the app on top.

The WinRects helper gains two additive methods:

- CaptureWindow(id, pid), API 9: snapshot the window's own actor with
  paint_to_content. Covered windows keep their content, nothing is
  activated, and a 1x1 transparent clone keeps Mutter painting a fully
  covered window for 4 s after the last capture. Refused while locked,
  for minimized windows, and above 32 MiB.
- CaptureWindowPreview(id, pid, max), API 10: the same capture,
  downscaled on the GPU, returning the full-size dimensions too.

The driver uses CaptureWindow whenever the attested helper reports
API 9 or newer, and then never falls back to a stage crop. Older
helpers keep the stage crop, so users who have not reinstalled the
helper keep window screenshots. A screenshot-only get_window_state
with a size cap uses CaptureWindowPreview (falling back to the full
capture on older helpers), and GNOME's per-capture Creation Time PNG
chunk is removed so unchanged preview frames compare equal.
list_windows asks a verified GNOME helper first instead of probing
other compositor protocols.

Versioning: the UUID stays winrects@cua. One UUID means one installed
copy per user; two UUIDs would race for org.cua.WinRects. API numbers
9 and 10 match T3 Code's bundled helper exactly, so either copy serves
both drivers. install.sh and both cua-driver installers no longer
downgrade a newer installed helper (install.sh --force still does).
The helper README documents the rules and the version table.

Ported from T3 Code's Linux patch to Cua Driver 0.34.0
(pingdotgg/t3code#16975, MIT, Copyright (c) 2026 T3 Tools Inc.). The
stage-crop fallback for older helpers and the no-downgrade installers
are new here.

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

* docs(cua-driver): credit every T3 Code Linux port in THIRD_PARTY_NOTICES

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

---------

Backported to the 0.34 release line from main (cherry picked from commit 78212ad).

Conflict: THIRD_PARTY_NOTICES.md keeps the 0.34.0 table; the T3 Code row now lists every ported file, as on main.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
tanishqkancharla pushed a commit to tanishqkancharla/cua that referenced this pull request Oct 10, 2026
…ews (trycua#4881)

Backport of trycua#4881 to the 0.34 release line, reworked for the 0.34.0 code.

`display_only:true` on get_window_state (with
include_accessibility_tree:false) returns the window's pixels and metadata
but publishes, refreshes and removes no snapshot and registers no action
capture, so a preview polling the window several times a second (T3 Code's
picture-in-picture) no longer stales the agent's element tokens or pixel
frame. It maps onto the existing internal observation-only read on macOS,
Windows and Linux; on macOS it also skips the background_input probe.

The contract matches T3 Code's Linux patch to Cua Driver 0.34.0
(pingdotgg/t3code#16975, MIT, Copyright (c) 2026 T3 Tools Inc.) word for
word: the schema property T3 feature-detects, the refusal
`display_only requires include_accessibility_tree:false`, and the
`display_only` / `frame_note` result fields. The typed contract
(cua-driver-contract) and the UniFFI surface are unchanged.

Differences from main's trycua#4881:
- main keeps the helper in cua_driver_core::window_state_view, which does
  not exist on 0.34; here it is cua_driver_core::display_only with the same
  strings and functions, and each backend adds the property to its own
  schema.
- Not backported: plain screenshot-only reads refreshing the current
  snapshot in place on Windows and Linux (refresh_screenshot_for_session is
  0.35 snapshot-store code). On 0.34.x a plain screenshot-only read behaves
  as in 0.34.0; display_only is the side-effect-free read.
- No tool-description or skill text changes; the property's description
  carries the contract. cli-specs and the generated reference page gain the
  property (macOS regenerated from the native dump).

(cherry picked from commit 4cbd096, with conflicts reworked)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
juliusmarminge and others added 6 commits October 16, 2026 09:46
Cua Driver 0.34.1 includes our Linux fixes: the Wayland opt-in reaches
embedded hosts, GNOME windows are captured from their own actor (WinRects
API 10), the GNOME helper reuses one session-bus connection, and
get_window_state accepts display_only. Linux packaging now bundles the
published release like macOS and Windows, so the source patch, the native
build script, SDK library replacement, the Linux CLI bundle lookup, and the
extra CI toolchain are gone.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@juliusmarminge juliusmarminge changed the title fix(cua): stabilize Linux window previews and turn cleanup fix(cua): stabilize native window previews and Windows app identity Oct 16, 2026
@github-actions github-actions Bot added size:XL 500-999 changed lines (additions + deletions). and removed size:L 100-499 changed lines (additions + deletions). labels Oct 16, 2026
@github-actions github-actions Bot added size:XXL 1,000+ changed lines (additions + deletions). and removed size:XL 500-999 changed lines (additions + deletions). labels Oct 16, 2026
@juliusmarminge

Copy link
Copy Markdown
Member Author

terminal-preview-24 feasibility: blocked on the native stack and final-driver verification; no changes pushed.

The actual head is t3code/cua/linux-pip, based on t3code/cua/6-browser-tabs. The Cua services are absent from current main, so this draft cannot be rebuilt as a standalone main-based fix without bringing in its parent stack, which is outside this batch.

The final native pass needs:

  • Installed 0.34.1 on GNOME Wayland: cover the selected target window; its preview must contain only that window. Confirm static content drops to 1 FPS, motion resumes 4 FPS, and closing the preview or settling the turn stops capture calls and closes lingering previews.
  • A normal packaged Windows build without T3CODE_CUA_DRIVER_SDK_LIBRARY: start the driver and check for console flashes. The source patch is applied through the override path, so the release artifact needs its own proof. Exercise Calculator and Settings identities/icons and the unavailable state after closing each app.
  • macOS: exercise the display-only capture path and app mentions/permission prompts. App enumeration currently acquires the driver from a read-scoped RPC; decide whether first-use downloads/permission prompts are intended when typing @.

Keep the app-mention feature separate from the preview lifecycle fix when the parent stack is ready. Capture the outstanding before/after recording against the final installed driver. No duplicate with #18217 or #8469 was found.

This branch was successfully deployed

1 active deployment
production — d388b798 Deployed Oct 16, 2026 by juliusmarminge via Resolve T3 Connect public config #3231
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

macroscope-review Opt PRs made by unvouched contributors in for Macroscope review. Vouched contributors auto-reviews size:XXL 1,000+ changed lines (additions + deletions). vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant