Add Cua to Install > AI - #11342
Add Cua to Install > AI#11342spencerbull wants to merge 14 commits into
Conversation
|
Second pass now that the plugin recipe has landed in omarchy-pkgs (#346, builds enabled by #432). Three commits since the PR opened, and the body above now describes the final state. What the package side looks like today. What changed here.
How it was proven. On an omabot worker on stable (Hyprland 0.56.2-2) I built the plugin from the merged recipe with makepkg (all CTests pass) and served it from a local pacman repo so the flow saw it exactly as a channel would. Install > AI > Cua then installed driver 0.27.0-1, both skill sets, and the plugin. Before the toggle, Worth a product call. The plugin's background input route only admits the exact app versions Cua qualified, which on stable today is Inkscape 1.4.4-6 (the qualified Calc is 26.2.5-3; stable has 26.8.0-2). The toggle is explicit and off by default because of the keymap cost, but if that scope is too narrow to ship a switch for yet, the last commit lifts out cleanly and the install flow still installs the package and points at the README. |
U+E90F is the koala mark from cua.ai, taken from the monochrome logo_black.svg in the trycua/cua repository. Upstream draws it as seven paths and omarchy dev font takes exactly one, so cua.svg beside the font keeps the merged single-path version the glyph was built from, and the README records both. The charset range menu-test pins moves with it. Co-Authored-By: Fable 5.1 <noreply@anthropic.com>
omarchy-provision-user links every skill under default/agents/skills into the agent skill directories for everyone. A skill that only makes sense once an optional tool is on the machine needs the same directories without the unconditional provisioning, so this command links one skill directory into them on demand and takes those links back with --remove. It never replaces something the user put there: a real directory of the same name is left alone, and so is a live symlink pointing somewhere else, the rule cua-driver's own skill installer follows. --remove only deletes links that resolve to the given skill, so a foreign link of the same name survives. Co-Authored-By: Fable 5.1 <noreply@anthropic.com>
The Install > AI entry runs omarchy-install-ai-cua in a floating terminal. It installs cua-driver-bin, the Cua computer-use driver packaged in omarchy-pkgs, then offers the Cua agent skills: the upstream pack through `cua-driver skills install`, which links it into every agent skills directory that exists, and an Omarchy companion under default/agents/optional-skills/cua-omarchy covering package identity, Hyprland geometry and focus, and the plugin, linked with omarchy-agent-skill-link. The skills are opt-in because a skill is read into every session of every agent on the machine. When the package channel carries cua-hyprland-plugin it is installed as well, and its absence is reported otherwise; the package never loads the module itself and pins the exact Hyprland release, so the terminal says both. Remove > AI lets the driver take back its own skill links before the package goes, unlinks the companion, drops the plugin when present and then the driver, and deletes the driver's identity, update-check, socket and log state under ~/.cua-driver, ~/.config/cua and ~/.cache/cua-driver. Co-Authored-By: Fable 5.1 <noreply@anthropic.com>
cua-hyprland-plugin depends on one exact Hyprland release, and edge moves past it before the plugin is requalified: today the plugin pins 0.56.2-2 while the edge mirror carries 0.56.2-3. A channel can therefore offer the package while pacman cannot install it, which used to surface as a failed sudo pacman transaction followed by a generic message. pacman -Sp resolves the same transaction without root, so the install now says which Hyprland the plugin wants and which one is installed, and skips it. Co-Authored-By: Fable 5.1 <noreply@anthropic.com>
The driver only takes its native Wayland backend when CUA_DRIVER_RS_ENABLE_WAYLAND=1 reaches whichever process serves the calls, and an agent following the skill pack starts that process from its own session without knowing the flag. Omarchy is Wayland-only, so default/hypr/envs.lua exports it for every session, and the Cua install hands it to the running one through the user manager and the activation environment so the first agent session after installing has it too. The companion skill says where it comes from. Co-Authored-By: Fable 5.1 <noreply@anthropic.com>
cua-hyprland-plugin ships no hook, autoload, or config edit on purpose: its README makes activation an explicit step after the package's compatibility check passes in a fresh session, and its input route only admits one exact keymap (rules evdev, model pc105, layout us, nothing else), which drops Omarchy's Compose-on-Caps-Lock while it is on. Left as a hand ritual, the plugin the install flow adds stays inert. omarchy-toggle-cua-input is that step made reversible. on refuses without the package, on any layout other than a plain US one, and when the package's own profile_verify.py says the module does not match the running Hyprland; otherwise it loads the module and lands default/hypr/toggles/cua-input.lua through omarchy-hyprland-toggle, which sets the admitted keymap and plugin:cua:enabled. off removes the flag and reloads; the module stays mapped for the session, as the package requires. The flag runs --load at each session start, since a loaded module does not outlive the session: the check runs again and a failure turns the flag off rather than leaving the keymap changed for nothing. The kit digest the verifier wants is read from the installed KIT-PROVENANCE.json that pacman already verified, not pinned here where it would go stale with every requalified profile. Trigger > Toggle > Cua Input appears once the plugin package is installed. The Cua install flow points there instead of at the package README, and the remover switches the toggle off before dropping the plugin. Verified on an omabot worker on stable (Hyprland 0.56.2-2) with the plugin built from the merged recipe: on sets the keymap and cua:status reports configured with a ready transport, off restores both, and a reboot with the flag on loads the module again. Co-Authored-By: Fable 5.1 <noreply@anthropic.com>
Require the plugin's independent agent keymaps and remove the toggle's human keyboard overrides. Refresh existing flags without recreating one removed by a concurrent off, and leave older mapped modules disabled until a new session. Co-Authored-By: Codex XHigh <noreply@openai.com>
34a88d0 to
94e9705
Compare
With Cua input on, fcitx5 requests an input method on each agent seat, and when it exits (omarchy-restart-xcompose restarts it) Hyprland 0.56.2 can dereference a destroyed input-method popup surface and crash into safe mode. cua-hyprland-plugin 0.32.0-3 hooks the two methods that reach that surface and reports ime_popup_guard: true; earlier packages report the keyboard capabilities this toggle checked but carry no guard, so it would enable input on exactly the build that crashes. Require 0.32.0-3 and an active guard, treating a module without one like any other stale mapped module.
A loaded module with no ime_popup_guard key was mapped before the update, and logging out loads the new one. A current module reporting false means its hooks did not install; logging out would load the same build and fail the same way, so say that the guard is missing and point at cua:status instead. Co-Authored-By: Codex XHigh <noreply@openai.com>
Hyprland reloads its configuration as soon as a plugin loads, and the flag already says plugin.cua.enabled = true at login, so the module resumed input before --load had checked it, including a module whose input-method guard failed to install. Rewrite the existing flag to enabled = false before loading and restore it only after the module passes; both writes use conv=nocreat, so a concurrent off still wins. Co-Authored-By: Codex XHigh <noreply@openai.com>
A failed reload around the held flag ended --load under set -e, and a failed restore only notified, so each left a flag reporting Cua Input on while Hyprland's live configuration still held input off. Turn the toggle off on all three paths, as every other startup failure does. Co-Authored-By: Codex XHigh <noreply@openai.com>
on with the flag already set and the module not yet loaded hit the same load-triggered reload as session start, so it now holds the flag the same way. A failed reload while landing the flag left it reporting on, and refuse could die on its own failed reload before telling the user; both now remove the flag and notify. Co-Authored-By: Codex XHigh <noreply@openai.com>
|
Tested at head
Still open before this leaves draft: omarchy-pkgs#772 has to publish 🤖 Generated by Opus 5.5 in Claude Code. Reviewed by Codex XHigh. |
|
| refuse "Log out and back in to use the updated Cua plugin, then turn Cua Input on again." | ||
| fi | ||
| ime_guard_active || refuse "The Cua plugin could not install its input-method crash guard; hyprctl -j cua:status has the details." | ||
| omarchy-hyprland-toggle "$FLAG" on >/dev/null || refuse "Hyprland could not reload its configuration; Cua Input stays off." |
There was a problem hiding this comment.
If an on command is still verifying or loading the plugin when the user turns Cua Input off, the off command removes the flag and reloads Hyprland. This final on call then recreates the flag and enables input again. Unlike the startup restore, it does not preserve the user's off request.
Knowledge Base Used: Hyprland configuration and display control
| turn_off() { | ||
| omarchy-hyprland-toggle "$FLAG" off >/dev/null | ||
| notify "Cua input off" "The plugin stays loaded until you log out." |
There was a problem hiding this comment.
Failed reload leaves input active
If hyprctl reload fails while turning Cua Input off, the flag has already been deleted, but the running compositor can retain the enabled setting. This command exits before notifying the user. The refusal path also ignores a failed off reload, so it can say input is off while it remains active.
Knowledge Base Used: Hyprland configuration and display control
| if omarchy-pkg-present cua-hyprland-plugin; then | ||
| # The keymap override and the session-start reload go now; the module | ||
| # itself stays mapped for the rest of the session, as the package requires. | ||
| if omarchy-hyprland-toggle-enabled cua-input; then | ||
| omarchy-toggle-cua-input off |
There was a problem hiding this comment.
If the plugin package was removed separately while its module and input remain enabled in the running session, removing Cua skips the off command because the package is absent. The mapped module can remain active until logout, and the enabled flag survives removal.
Knowledge Base Used: Hyprland configuration and display control
The flag ran hl.config({ plugin = { cua = { enabled = true } } }) whenever Hyprland read its configuration, but at login the module is loaded afterwards, by the hyprland.start hook, so every login with Cua Input on showed "unknown config key 'plugin.cua.enabled'". On an Omabot worker, drawing that error at startup deadlocked Hyprland 0.56.2. hl.get_config returns nil for a key no plugin has registered and a value once the module is loaded, so the flag now checks it first; the reload that follows the load applies the setting, and --load's hold still keeps it off until the module passes.
|
End-to-end run at head What the run found. With Cua Input on, every login showed "Your config has errors: … unknown config key 'plugin.cua.enabled'", because the flag set the option when Hyprland read its configuration and the start hook only loads the module after that. On the worker, drawing that error at startup deadlocked Hyprland 0.56.2 (main thread waiting in Install and remove. Computer use, driven by an agent through the installed packages, on both machines:
Limits seen, none of them introduced here: the driver's trusted CDP clicks are refused on Hyprland even with the browser focused (its page-route typing and DOM-event clicks work); a GTK popover that holds a grab, such as Nautilus's rename, refuses all plugin input, by design; foreground typing aimed at an unfocused window stops after two or three keys while fcitx5 is running, so the target needs focus first; and background input refuses a window under the user's pointer ( This stays a draft until a maintainer reviews it. 🤖 Generated by Opus 5.5 in Claude Code. Reviewed by Codex XHigh. |


Cua Driver lets coding agents inspect and operate desktop applications, but installing the package alone does not surface its agent skills or the optional Hyprland input route. This adds Cua to Install > AI and Remove > AI, and adds Trigger > Toggle > Cua Input when the plugin package is installed.
The installer adds
cua-driver-bin, offers the upstream agent skills and an Omarchy companion skill, and installscua-hyprland-pluginwhen the channel offers a resolvable package. The companion documents package ownership, the native Wayland environment, targeting and verification, and the plugin's limits. Existing skill directories and foreign symlinks are preserved. Omarchy exportsCUA_DRIVER_RS_ENABLE_WAYLAND=1for the native backend; installation also passes it to the running session's activation environment.Cua Input checks the installed plugin against the running Hyprland before loading it. It requires
cua-hyprland-plugin0.32.0-3 or newer, supplied by omacom/omarchy-pkgs#772: background agent keyboards own their US keymaps, plain pointer operations do not require a US layout, foreground key operations validate the live mapping and modifier state while preserving compatible Num Lock state, and the module guards Hyprland 0.56.2 against an input-method crash. With input on, fcitx5 requests an input method on every agent seat, and when it exits, whichomarchy-restart-xcomposemakes it do, Hyprland can dereference an input-method popup whose surface is already gone and restart in safe mode. Earlier packages report the keyboard capabilities but carry no guard, so the toggle requires the package version and an activeime_popup_guardboth. The toggle leaves the user's layout, variants, Compose key, Num Lock, and remaps unchanged. Caps Lock, held/latched modifiers, nonzero groups, and keys whose meaning changes remain guarded. Full foreground support for arbitrary layouts and Unicode/IME input remains outside this change. The plugin's application/version qualification restrictions still apply.A loaded plugin without
keyboard_layout_independent,foreground_numlock_compatibleand anime_popup_guardkey is left mapped and input is turned off with a logout/login instruction. This detects an older module still running after package installation; it does not claim to identify every future package upgrade. A module reportingime_popup_guard: falsedid not install its hooks, so it is refused with its own message instead: logging in again would load the same build. The flag setsplugin.cua.enabledonly oncehl.get_configsees that option: at login Hyprland reads the configuration before the start hook loads the module, and naming a plugin option earlier is an unknown-key config error. Hyprland reloads its configuration as soon as a plugin loads, so whenever the flag is already on while a module loads, at session start or when turning Cua Input on, the flag is held atenabled = falseuntil the module passes and restored afterwards; both writes useconv=nocreat, so turning Cua Input off during session-start verification still wins. A failed hold, restore or reload removes the flag rather than leaving it reporting on. Log out and back in after updating a loaded plugin. Existing copied toggle flags that contain keyboard overrides are replaced on activation or session startup, and a failed startup check or load removes the flag. Turning Cua Input off removes its flag and reloads configuration without unloading the module.The plugin remains an explicit opt-in after installation and pins its qualified Hyprland release. An unavailable package or unresolved pin does not undo the driver installation. Removal takes back the driver's own skills, unlinks only the Omarchy companion links it owns, turns off Cua Input before removing the plugin, and removes the driver's own state. The driver retains its upstream content-free telemetry default;
cua-driver telemetry disablechanges it.This stays a draft until omarchy-pkgs#772 publishes 0.32.0-3: until then the channel's plugin pins the previous Hyprland, so on edge the installer skips it and the toggle refuses it.
🤖 Generated by Codex in T3 Code and Opus 5.5 in Claude Code. Reviewed by Codex XHigh.