agent-desktop-linux
Skill4.8k starsChanged 2 days agoApache-2.0View on GitHub
Linux platform guide for the agent-desktop CLI. Lists per command group what works on X11 and on Wayland, how to check the AT-SPI accessibility bus, the first-contact gotchas (app names, Chromium and Electron flags, headed focus, blocked key combos), and where to find lifecycle, screenshot, clipboard, tray, notification and troubleshooting details. Triggers on: "linux desktop automation", "AT-SPI tree", "automate GNOME app", "agent-desktop on Linux", "accessibility bus not available", "empty supported_surfaces", "wayland screenshot consent", or any Linux GUI interaction task.
We split this skill into the rules it gives an agent
7 rules. About 0 are common, 4 are distinctive, and 3 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈4
Distinctive · estimate
This author's own choices. Worth a look.
3
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 73
An empty file view does not prove an empty folder: If an icon view exposes no file items, try an available list or detailed view, then take …
- Very specific: line 76
A window appears before its content: Run wait --window "Text Editor" --app gnome-text-editor first, then wait --text, which matches a …
- Distinctive: line 99
A GTK4 secret field can show its text: Only a password role is withheld.
- Distinctive: line 100
Treat a GTK4 entry with hidden characters as readable by every observation command.
- Very specific: line 120
Wait for an app window to appear (--window requires a title or title substring):
- Distinctive: line 139
Start a session and pass its returned ID to every overlay command:
- Very specific: line 228
Read any file from the binary: agent-desktop skills get agent-desktop-linux references/troubleshooting.md.
≈ “Common” is an estimate: at least 1 in 5 of the 308,232 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
agent-desktop-linux
The observe-act loop, refs, JSON envelope, sessions and tracing match every platform. This file covers only what differs on Linux.
Needs Ubuntu 24.04+ (x86_64 or aarch64), a graphical session of the signed-in
user and a running AT-SPI bus. Other distributions need the at-spi2-core bridge
fix dc0dc33; Ubuntu 22.04's bridge aborts on Action.GetActions. The archive
loader floor is glibc 2.35. Run the CLI inside the target apps' desktop session:
the session bus, display and runtime directory come from its environment. A TTY
login, an SSH shell without session variables, a container without a bus or
another user's session sees no apps. GNOME is the measured desktop; X11 and
Wayland sessions both work and differ in input, capture and window control.
Observation and semantic actions need no helper tool.
Capability Table
| Group | Commands | Status on Linux |
| Observation | snapshot, find, get, is | Works on X11 and Wayland through AT-SPI. Supports window, sheet, alert and menu; GNOME adds shell surfaces. Virtual tray getters have limits; see the shell reference and check status |
| Surfaces | list-surfaces | Lists an app's windows, sheets and open menus; shell reads use snapshot --surface |
| Ref interaction | click, right-click, type, set-value, clear, select, toggle, check, uncheck, expand, collapse, scroll-to | Need a readable live identity and the required AT-SPI capability. See the shell reference for menu-ref resolution limits; X11 headed fallback also needs usable geometry and does not bypass identity checks |
| Wheel scrolling | scroll, mouse-wheel | Physical wheel input; X11 and --headed only |
| Pointer gestures | double-click, triple-click, hover, drag | --headed, X11 only. On Wayland the pointer cannot be aimed and these refuse with ACTION_NOT_SUPPORTED |
| Focus | focus | Needs --headed for the focus permission. Calls AT-SPI Component.GrabFocus on a focusable node that is not yet focused, not the pointer, and verifies the state; a GTK4 app rejects the call, so focus ends ACTION_FAILED grab_focus_rejected there and focus-window is the way to focus its window |
| Keyboard and mouse | press, mouse-click, mouse-move, mouse-wheel | press and text keys work on X11 and capability-detected Mutter Wayland sessions; pointer commands are X11 and --headed. See references/display-servers-and-input.md |
| Held input | key-down, key-up, mouse-down, mouse-up | Fail closed on every platform: on Linux, key-down and key-up with ACTION_NOT_SUPPORTED; mouse-down and mouse-up with POLICY_DENIED headless and ACTION_NOT_SUPPORTED with --headed |
| App and window | launch, close-app, list-windows, list-apps, focus-window, move-window, resize-window, minimize, maximize, restore | Launch and listing work on X11 and Wayland; focus-window requires X11. Other window control and graceful close need an X11 client. See references/windows-and-lifecycle.md |
| Displays | list-displays | Works |
| Capture | screenshot | X11: a window without permission; a display only under a non-compositing manager. Wayland: portal consent, with display cropping. No selector returns the primary display. See references/capture-and-clipboard.md |
| Clipboard | clipboard-get, clipboard-set, clipboard-clear | Works; text, images and file lists. Wayland needs wl-clipboard |
| Wait | wait | Works for ms, --element, --window, --text, --menu, --menu-closed, --event. Menu waits share the menu-surface detector; --notification waits for a new notification on GNOME |
| Notifications | list-notifications, dismiss-notification, dismiss-all-notifications, notification-action | GNOME Shell only; list headless, mutations --headed on X11, and dismiss-notification and notification-action also need --expected-app or --expected-title. Fields are read from the shell's widget layout, verified on GNOME Shell 46.0 only, and each mutation is proven by its effect. Wayland refuses the shell pointer before input. A notification owner that is not the shell or its own helper returns PLATFORM_NOT_SUPPORTED. See the shell reference |
| Shell surfaces | open-system-surface | Only system-tray and action-center can work. system-tray needs a StatusNotifierWatcher (else it refuses with watcher: absent); action-center needs proven role ancestry. quick-settings refuses with shell_container_unproven, taskbar always refuses, and start-menu and system-tray-overflow are not supported, though --help lists them. See the shell reference |
| Cursor overlay | cursor-overlay | Requires an active session; see Cursor overlay below. X11 enable returns data.rendered: true; Wayland saves the setting with data.rendered: false |
| System | status, permissions, version, batch, skills, session, trace | Works |
First Contact
- Run
agent-desktop statusfirst. An emptysupported_surfacesmeans the accessibility bus did not answer, not an empty desktop. Readreferences/bus-and-permissions.md; do not restart a bus you did not start. --apptakes the namelist-appsprints (gnome-calculator,nautilus) or a desktop-entry name or id backed by verified executable and argument identity, never a window title or an arbitrary registry label. A desktop-entry name such asFilesis accepted once the entry exists.list-windows --appis exact (aliases included);list-apps --appcombines a substring of the listed name with exact adapter aliases, ignoring case.- Window ids are opaque addresses of 34 to 70 characters, valid for the
life of the window's process; run
list-windowsagain after a restart.list-appsrows carrybundle_id(desktop id when known) andprocess_instance. - GTK4 apps nest deeply.
--max-depthand--skeletoncount semantic levels, so empty layout wrappers add output levels.-i --compactstill shows nested namelessgroupnodes: read past them. - An empty file view does not prove an empty folder. If an icon view exposes no file items, try an available list or detailed view, then take a fresh snapshot and verify which items the application exposes.
- A window appears before its content. Run
wait --window "Text Editor" --app gnome-text-editorfirst, thenwait --text, which matches a node's own name, value or description. For a web-engine app (detected from its AT-SPI toolkit metadata), a window observation waits for three equal full reads and a web-document role, or a requested depth cut. A shell with no document yet stays incomplete when the budget ends. A--timeoutshorter than the first read returnsTIMEOUT, never a partial tree. - Geometry-only refs require unchanged geometry. Position and size must
both match, in the ref's recorded coordinate frame; a one-pixel change breaks
identity. After a layout change or a window move, take a fresh snapshot
instead of retrying the old ref. Indistinguishable siblings stay
AMBIGUOUS_TARGET: in a Text Editor window with three tabs, the text views share one rectangle and one state, so a ref to any of them answersAMBIGUOUS_TARGETwithcandidate_count3 until the extra tabs close. A ref belongs to the window it was taken in, so two windows with the same title each resolve their own refs. - Chromium and Qt apps need a launch flag or variable to appear on the bus;
Electron apps need none, only
--no-sandboxwherechrome-sandboxis not setuid. Seereferences/troubleshooting.md. - Headed ref actions need a window that can take focus. A window the
window manager never activated ends
activation_not_granted. Seereferences/windows-and-lifecycle.md. - A GTK4 secret field can show its text. Only a password role is withheld. Treat a GTK4 entry with hidden characters as readable by every observation command.
- Blocked key combos refuse without
--force. Seereferences/display-servers-and-input.md. - After opening a menu-role popup, inspect
data.surfaces. Amenuentry leads tosnapshot --surface menu --app <name> -i. If absent, usewait --menuandlist-surfacesbefore assuming the opener failed. A list-backed dropdown is part of the window, not a menu surface; see the shell reference. - Shell pointer input requires receiver proof. On X11 a headed shell click is proven from the shell's own tree: the receiver must be the target and stand still, or the click refuses before any pointer event. Wayland shell clicks refuse. Notifications need the GNOME notification service; tray snapshots also need a StatusNotifierWatcher.
- The state root must be private. A group-writable or world-accessible
AGENT_DESKTOP_HOMEor~/.agent-desktopmakessnapshotfail withINTERNAL; runchmod 700on it or let the tool create it.
Wait for a window
Wait for an app window to appear (--window requires a title or title substring):
agent-desktop wait --window "Text Editor" --app gnome-text-editor --timeout 10000To wait for a close that you cause, batch it so the baseline is taken before the close (Calculator has no unsaved-document prompt to interrupt it):
agent-desktop batch '[{"command":"close-app","args":{"app":"gnome-calculator"}},{"command":"wait","args":{"event":"window-closed","app":"gnome-calculator","timeout":10000}}]' --stop-on-errorTo watch someone else close a window, start
agent-desktop wait --event window-closed --app gnome-text-editor --timeout 10000
before they close the window. There is no --window-closed flag.
Cursor overlay
Start a session and pass its returned ID to every overlay command:
session_id=$(agent-desktop session start --name docs-example | jq -r '.data.session_id')
agent-desktop cursor-overlay enable --session "$session_id"
agent-desktop cursor-overlay disable --session "$session_id"
agent-desktop session end "$session_id"Without a session, cursor-overlay enable and disable return INVALID_ARGS.
On X11, enable returns data.rendered: true; on Wayland it saves the setting
and returns data.rendered: false without drawing an overlay.
session start --cursor --multi-agent returns data.rendered: false, because
nothing is drawn until an agent acts. On X11 each agent id then gets its own
cursor; on Wayland none is drawn.
What differs on Linux
- Firefox/Gecko
selectcan change the selected value without firingchangeorinputevents, so dependent page handlers do not run. The result staysdelivered_unverifiedeven when value readback matches. Check the dependent application effect before continuing: value readback alone is no commit proof. - Two
clickcalls on one GTK4 button less than about 250 ms apart act once. Both answerok: truewithdelivered_unverified. To click one button several times, wait for the effect between the clicks: usewait --element <ref> --predicate value --value <expected>on the element that shows the result, orwait 300. - Ref actions are semantic AT-SPI calls that never move the pointer or change
the active window. Under
--headed, refclick,right-clickandtypetry physical input first and fall back to the semantic action only after anot_deliveredrefusal (Windows works the other way round). On Wayland, headed pointer commands and a headedselectrefuse at once withACTION_NOT_SUPPORTED, causewayland_session; a headedtypeneeds the Mutter RemoteDesktop capability.references/display-servers-and-input.mdhas the full rules. selecttries the semantic route first and the pointer second; the pointer route needs an explicit--headedrequest on X11. A Qt combo's semantic selection only highlights its popup row, so headless selection refuses withPOLICY_DENIED, kindpointer_required, before changing that highlight. Headed, on a list whose toolkit index cannot be mapped to the row (a GTK4 list) it clicks the row and checks itsselectedstate; on a combo with no semantic opener (a libadwaita combo row) it clicks the combo open, selects the choice through the popup's own list and checks the value the combo shows. Headless, a list refuses withselection_index_unproven, and a combo with no semantic opener withPOLICY_DENIED, kindpointer_required, unless the combo already shows the choice. A GTK4 drop-down that opens through its own toggle takesselectwithout--headedand checks the value it shows.- A ref can expose no safe semantic mutation route. Headless requests then
return an unsupported-action error without inventing
hiddenordisabledstate and without switching to physical input. GTK4 entry and passwordActivateactions are one such case: usetypeto edit the field, or request--headedexplicitly when a pointer click is intended. - Opening a native Wayland Qt combo returns
ACTION_NOT_SUPPORTED, kindnative_popup_requires_input, before invoking its action. Qt needs a user input serial to show that popup. An already open combo may be collapsed; Qt windows proven to use Xwayland retain their semantic opener. - Headless
typewrites throughEditableText. A terminal's text node is atextfieldnamedTerminalwhose only action isRightClick; headlesstypeon it isPOLICY_DENIEDwith checksupported_action, and its value is null. It receives keys only under--headed. - In key combos
cmdandmetaare the Super key. Key names are the macOS and Windows names plus X keysym names.presstakes mapped keys only;typehandles characters the layout cannot produce. - Window ops act on X11 clients;
focus-windowand headed scopedpressrequire an X11 session. Headless scopedpressrequires live target focus on either display server. Focusing a window on another workspace can switch the user's current desktop. - Linux exact FFI refs carrying bounds or a bounds hash require window-relative geometry, even when the ref also carries a name or identifier. Geometry-free identity refs are supported.
References
references/bus-and-permissions.md: bus bootstrap, the three bus states,statusandpermissionsoutput, state-root rules.references/display-servers-and-input.md: X11 versus Wayland table,press,type, pointer, wheel, drag, blocked combos, key names.references/windows-and-lifecycle.md:launch,close-app, window ops, focus, workspaces, stopped apps, backgroundpress.references/capture-and-clipboard.md:screenshoton X11 and Wayland, the Wayland consent dialog, clipboard owner and helper.references/shell-tray-and-notifications.md: menus and GTK4 popovers, GNOME Overview/top bar, shell reads and input, notification identity guards, SNI and AppIndicator requirements and refusals, sandbox guidance.references/troubleshooting.md: symptom-to-cause map, Chromium, Electron and Qt flags, toolkit limits, error codes withplatform_detail.
Read any file from the binary:
agent-desktop skills get agent-desktop-linux references/troubleshooting.md.
Other versions1 project uses a version of this.
Word for word · 0
None found.
Edited · 1
- lahfir/agent-desktop★ 1.8k100% same
Wrote their own version · 0
None found.
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository9 other files it gives its agents.
- AGENTS.mdAGENTS.md
- apps/docs/AGENTS.mdAGENTS.md
- architecture-diagramSkill
- technical-writerSkill
- agent-desktop-ffiSkill
- agent-desktop-macosSkill
- agent-desktopSkill
- agent-desktop-windowsSkill
- jev-desktopSkill
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

