@agent-sh/computer-use-linux 0.7.25 → 0.7.27
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -2
- package/npm/README.md +23 -0
- package/package.json +1 -1
- package/pi/extension/generated-tools.ts +30 -5
- package/pi/extension/index.ts +2 -0
- package/skills/computer-use-linux/SKILL.md +15 -1
package/README.md
CHANGED
|
@@ -63,6 +63,7 @@ The crate was extracted from [`codex-desktop-linux`](https://github.com/avifenes
|
|
|
63
63
|
| | `setup_accessibility` | Enables and verifies GNOME's `org.gnome.desktop.interface toolkit-accessibility` setting so toolkit apps expose AT-SPI trees. |
|
|
64
64
|
| | `setup_window_targeting` | Installs and enables the bundled GNOME Shell extension when `org.gnome.Shell.Introspect` is locked down. |
|
|
65
65
|
| **Discovery & observation** | `get_app_state` | Combined screenshot + compacted AT-SPI accessibility tree with stable `element_index` handles. Scope with `app_name_or_bundle_identifier` or a window target (`window_id`, `pid`, `app_id`, `wm_class`, `title`). |
|
|
66
|
+
| | `get_tree_page` | Page through the latest cached tree by node offset, for trees too large to return inline when the host cannot read the spill file. |
|
|
66
67
|
| | `screenshot` | Bounded PNG or JPEG capture of the full desktop (`full_screen: true` or no target) or a raised and cropped target window (`window_id`, `pid`, `app_id`, `wm_class`, `title`, `raise_window`). |
|
|
67
68
|
| | `list_windows` | Compositor windows with `window_id`, title, `app_id`, `wm_class`, PID, focus state, client type (`wayland`/`x11`), bounds, and terminal TTY/process metadata. |
|
|
68
69
|
| | `focused_window` | The window currently holding keyboard focus. |
|
|
@@ -118,7 +119,7 @@ the origin. A missing window target is rejected.
|
|
|
118
119
|
|
|
119
120
|
**X11 text fidelity:** `xdotool`/XTEST can silently substitute symbols under non-US XKB layouts (reported with Brazilian `br`/ABNT2) or changing keymap state, even when `type_text` returns `ok: true`. Every successful xdotool text dispatch includes a layout warning. XKB layout replacement events, persistent mapping/group changes, and keyboard focus/grab transitions detected across a call return an error after dispatch, without replaying the text. Keyboard grabs can divert characters without changing the polled focused-window ID. If monitoring cannot start, xdotool still dispatches and the response explicitly warns that layout-change and keyboard interception detection were unavailable. PointerRoot focus is unsupported because pointer motion can redirect input without a detectable focus event. This also detects a `setxkbmap` layout changed and restored during one call. Temporary raw remaps or group switches restored within a call and dropped text with a stable map remain unverified. Re-observe the actual text before pressing Enter, submitting it, or treating it as delivered. Use `include_tree: true` for AT-SPI readback when the application exposes the text, or `screenshot_after: true` to inspect it. These observations do not automatically compare the field to the requested text. Do not retry blindly.
|
|
120
121
|
|
|
121
|
-
Targeted `press_key`/`type_text` results append focused-element feedback from AT-SPI (role, name, editable) and warn when a concrete non-terminal focus is not editable. Terminals accept keyboard input without an EditableText interface; re-observe the contents to confirm input. Click/screenshot/input results warn when the target window or coordinate is partially or fully off-screen. `get_app_state` returns a compact readiness block by default; pass `verbose: true` for the full diagnostics report. It also reports `tree_scoped` (false when no app target narrowed the AT-SPI tree, with a warning in `message`) and `accessibility_tree_truncated` (true when the node, depth, or
|
|
122
|
+
Targeted `press_key`/`type_text` results append focused-element feedback from AT-SPI (role, name, editable) and warn when a concrete non-terminal focus is not editable. Terminals accept keyboard input without an EditableText interface; re-observe the contents to confirm input. Click/screenshot/input results warn when the target window or coordinate is partially or fully off-screen. `get_app_state` returns a compact readiness block by default; pass `verbose: true` for the full diagnostics report. It also reports `tree_scoped` (false when no app target narrowed the AT-SPI tree, with a warning in `message`) and `accessibility_tree_truncated` (true when the node, depth, read, or time budget stopped traversal with unread elements left). When a result would pass 32,000 bytes, the tree comes back as its leading nodes plus `accessibility_tree_spill` (`path`, `node_count`, `bytes`, `inline_node_count`). `path` is a private JSON file holding the whole tree with the same `element_index` values, in `$XDG_RUNTIME_DIR/computer-use-linux/trees` when that runtime directory is private, otherwise under `~/.cache` (directories 0700, file 0600). Search the file instead of requesting the tree again; hosts that cannot read files page through the same tree with `get_tree_page`. The file lasts until the next snapshot or until the server exits; after a crash it is swept at the next start or after an hour.
|
|
122
123
|
|
|
123
124
|
An `app_id` may be a full desktop ID or its final dot-separated segment; matching is case-insensitive, ambiguous aliases are rejected, and an unresolved explicit `app_id` returns an empty scoped tree rather than the desktop.
|
|
124
125
|
|
|
@@ -144,7 +145,7 @@ Captures require the shared capture lock and, when an overlay is running, its ac
|
|
|
144
145
|
|
|
145
146
|
| Class | Tools | Contract |
|
|
146
147
|
| --- | --- | --- |
|
|
147
|
-
| Read-only observation | `doctor`, `list_apps`, `list_windows`, `focused_window`, `get_app_state` | `readOnlyHint=true`; may reveal app, window, accessibility, and screenshot contents. `get_app_state` may trigger the desktop screenshot portal prompt. |
|
|
148
|
+
| Read-only observation | `doctor`, `list_apps`, `list_windows`, `focused_window`, `get_app_state`, `get_tree_page` | `readOnlyHint=true`; may reveal app, window, accessibility, and screenshot contents. `get_app_state` may trigger the desktop screenshot portal prompt. |
|
|
148
149
|
| Local setup mutators | `setup_accessibility`, `setup_window_targeting` | `readOnlyHint=false`, `destructiveHint=false`, `idempotentHint=true`; modifies user desktop configuration by enabling accessibility or installing/enabling the GNOME window-targeting extension. |
|
|
149
150
|
| UI state mutators | `activate_window`, `move_window`, `resize_window`, `scroll`, `screenshot` | `readOnlyHint=false`, `destructiveHint=false`; changes focus, geometry, or scroll position in the live desktop, or raises a window to capture it. |
|
|
150
151
|
| Desktop action mutators | `click`, `drag`, `press_key`, `type_text`, `perform_action`, `set_value` | `readOnlyHint=false`, `destructiveHint=true`, `openWorldHint=true`; can trigger arbitrary actions in whatever local application is targeted. |
|
|
@@ -503,6 +504,8 @@ files.
|
|
|
503
504
|
- **Input fallback** — on X11, keyboard input prefers `xdotool`/XTEST and falls back only when xdotool cannot launch. On Wayland, literal text uses `wtype` when installed and the remote-desktop portal is unavailable; `wtype` supports Unicode through the virtual-keyboard protocol on compatible compositors such as Hyprland/wlroots. If wtype is unavailable, the binary falls back to a compatible ydotool 1.0.3+ CLI and `ydotoold` socket. A launched wtype failure is returned without replaying the text. `install.sh` can configure `ydotoold`; the `setup` command only enables the GNOME AT-SPI bridge.
|
|
504
505
|
- **Hyprland/Electron text** — for classified nonsecret fields on Hyprland, wtype passes one literal argument after `--` to avoid stdin keymap-refresh corruption. Argument text is visible in process listings; confirmed password fields are rejected. Terminals and ambiguous fields (with or without AT-SPI) use private stdin for at most 100 Unicode characters per call; split larger input into smaller calls or expose accessibility. The input probe has its own 1.5-second budget; the 250 ms indicator probe only masks text. Other compatible compositors retain their existing stdin path. NUL and text over 131,071 UTF-8 bytes are rejected before focus or indicators. Success confirms dispatch only; re-observe the field before retrying.
|
|
505
506
|
- **Limited accessibility feedback** — when exact window focus was verified before input but AT-SPI reports no focused element, the result describes the missing feedback without claiming the input was lost. It still does not verify the field contents. A complete scoped tree containing only application/window containers adds an Electron/Chromium `--force-renderer-accessibility` hint; a truncated tree instead retains its traversal-limit guidance.
|
|
507
|
+
- **Focused containers**: Chromium can mark a `document web` focused alongside its contenteditable editor. The focus probe keeps searching that document and reports the editor; a document that holds focus itself still gets a warning, which no longer claims the text was lost. An editor can carry the `editable` state without the EditableText interface (`supports_editable_text: false`): `type_text` can reach it, `set_value` cannot. Verify its text or a screenshot before submitting or retrying.
|
|
508
|
+
- **Large embedded browser trees**: an app-scoped snapshot includes embedded browser documents, which can use up the node budget before the app's own controls. When `accessibility_tree_truncated` is true, a missing editor proves nothing: raise `max_nodes` (default 1000, hard cap 10000) and, if needed, `max_depth` (hard cap 64). A busy renderer may give only a few thousand nodes before the deadline. A snapshot stops reading at 10 seconds and returns what it read, marked truncated; if the editor is still missing, hide the embedded browser pane for the snapshot.
|
|
506
509
|
- **Wayland coordinate input** — coordinate clicks, drags, and targeted scrolls require the absolute uinput pointer or an approved RemoteDesktop portal session. Targeted scroll positions through uinput before sending only wheel events through ydotool. If accurate positioning is unavailable, the call returns `ok: false` before sending coordinate input. The absolute pointer still requires a successful full-desktop capture when first created; an existing device does not need another capture. Scrolling without a point or window/element target keeps using the current pointer position.
|
|
507
510
|
- **Native X11 coordinate clicks** — eligible native X11 sessions use one supervised `xdotool mousemove -- X Y click --repeat N BUTTON` command for left, middle, and right clicks; ydotool is used only when xdotool cannot launch, while a launched nonzero xdotool command is reported as an error without replay. `COMPUTER_USE_LINUX_FORCE_YDOTOOL_POINTER=1` skips this xdotool path.
|
|
508
511
|
- **Native X11 scroll.** The same sessions send one `xdotool` command, `mousemove -- X Y click --delay 12 --repeat N BUTTON` when a point is set, or `click` alone when it is not. Buttons are 4 up, 5 down, 6 left, and 7 right, and `N` is the same notch count ydotool would pass to `mousemove --wheel` (five per page). ydotool's absolute move warps through (0, 0); GTK 3 then drops the single following wheel event because re-entry resets its XI2 scroll valuators. XTEST has no scroll valuators, so GTK takes the button path. A missing xdotool falls back to ydotool; a launched nonzero xdotool command does not. `COMPUTER_USE_LINUX_FORCE_YDOTOOL_POINTER=1` skips this path.
|
package/npm/README.md
CHANGED
|
@@ -184,3 +184,26 @@ does not yet forward the flag or include the tool in its catalog.
|
|
|
184
184
|
content makes the feedback informational. Such trees get a conditional
|
|
185
185
|
Electron/Chromium hint computed before compaction; this is not positive Electron
|
|
186
186
|
detection.
|
|
187
|
+
|
|
188
|
+
Chromium can mark a `document web` focused alongside its contenteditable
|
|
189
|
+
editor. The focus probe keeps searching that document and reports the editor;
|
|
190
|
+
a document that holds focus itself still gets a warning, which no longer
|
|
191
|
+
claims the text was lost. An editor can carry the `editable` state without the
|
|
192
|
+
EditableText interface (`supports_editable_text: false`): `type_text` can
|
|
193
|
+
reach it, `set_value` cannot. Verify its text or a screenshot before
|
|
194
|
+
submitting or retrying. Embedded browser documents can use up an app-scoped
|
|
195
|
+
snapshot's node budget before the app's own controls; when
|
|
196
|
+
`accessibility_tree_truncated` is true, a missing editor proves nothing. Raise
|
|
197
|
+
`max_nodes` (default 1000, hard cap 10000) and, if needed, `max_depth` (hard
|
|
198
|
+
cap 64); a busy renderer may give only a few thousand nodes before the
|
|
199
|
+
deadline. A snapshot stops reading at 10 seconds
|
|
200
|
+
and returns what it read, marked truncated; if the editor is still missing,
|
|
201
|
+
hide the embedded browser pane for the snapshot.
|
|
202
|
+
|
|
203
|
+
When a result would pass 32,000 bytes, the tree comes back as its leading
|
|
204
|
+
nodes plus `accessibility_tree_spill` (`path`, `node_count`, `bytes`,
|
|
205
|
+
`inline_node_count`). `path` is a private JSON file holding the whole tree
|
|
206
|
+
with the same `element_index` values (under `$XDG_RUNTIME_DIR` when it is
|
|
207
|
+
private, otherwise `~/.cache`). Search it instead of requesting the tree
|
|
208
|
+
again; hosts that cannot read files page through it with `get_tree_page`. The
|
|
209
|
+
file lasts until the next snapshot or until the server exits.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agent-sh/computer-use-linux",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.27",
|
|
4
4
|
"description": "Native Linux desktop control for AI agents (MCP server, Pi tools, and CLI): semantic AT-SPI accessibility trees, screenshots, compositor window targeting, Wayland/X11 input, and an on-screen activity indicator.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "commonjs",
|
|
@@ -7,9 +7,9 @@ export interface GeneratedMcpToolDefinition {
|
|
|
7
7
|
annotations: Record<string, unknown>;
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
-
export const GENERATED_SERVER_VERSION = "0.7.
|
|
11
|
-
export const GENERATED_TOOL_CATALOG_HASH = "
|
|
12
|
-
export const GENERATED_SHELL_TOOL_CATALOG_HASH = "
|
|
10
|
+
export const GENERATED_SERVER_VERSION = "0.7.27";
|
|
11
|
+
export const GENERATED_TOOL_CATALOG_HASH = "711deb97eb5c8a6cbe0a2fadbb64fdffc7592e304479dbbf277d3fcc4d58210f";
|
|
12
|
+
export const GENERATED_SHELL_TOOL_CATALOG_HASH = "1a927deb2579d314a975afc586bd31010862141779cbe7af50cd76f0387a607c";
|
|
13
13
|
export const GENERATED_MCP_TOOLS =
|
|
14
14
|
[
|
|
15
15
|
{
|
|
@@ -565,7 +565,7 @@ export const GENERATED_MCP_TOOLS =
|
|
|
565
565
|
"openWorldHint": true,
|
|
566
566
|
"readOnlyHint": true
|
|
567
567
|
},
|
|
568
|
-
"description": "Start an app use session if needed, then get a size-bounded screenshot and accessibility state for a Linux app. Scope the accessibility tree with app_name_or_bundle_identifier or a window_id/pid/app_id/wm_class/title target; omitting a target returns the whole desktop tree and can flood context. Screenshot results include coordinate_width, coordinate_height, scale, format, and quality when the returned image is downscaled or compressed; callers can request jpeg/quality for compression before resizing.",
|
|
568
|
+
"description": "Start an app use session if needed, then get a size-bounded screenshot and accessibility state for a Linux app. Scope the accessibility tree with app_name_or_bundle_identifier or a window_id/pid/app_id/wm_class/title target; omitting a target returns the whole desktop tree and can flood context. A tree too large to return inline is written whole to the private file in accessibility_tree_spill. Screenshot results include coordinate_width, coordinate_height, scale, format, and quality when the returned image is downscaled or compressed; callers can request jpeg/quality for compression before resizing.",
|
|
569
569
|
"inputSchema": {
|
|
570
570
|
"$defs": {
|
|
571
571
|
"ScreenshotOutputFormat": {
|
|
@@ -643,7 +643,7 @@ export const GENERATED_MCP_TOOLS =
|
|
|
643
643
|
},
|
|
644
644
|
"max_nodes": {
|
|
645
645
|
"default": null,
|
|
646
|
-
"description": "Maximum raw AT-SPI nodes to inspect before compaction (default 1000, hard max
|
|
646
|
+
"description": "Maximum raw AT-SPI nodes to inspect before compaction (default 1000, hard max 10000).",
|
|
647
647
|
"minimum": 0,
|
|
648
648
|
"type": [
|
|
649
649
|
"integer",
|
|
@@ -758,6 +758,31 @@ export const GENERATED_MCP_TOOLS =
|
|
|
758
758
|
},
|
|
759
759
|
"name": "get_app_state"
|
|
760
760
|
},
|
|
761
|
+
{
|
|
762
|
+
"annotations": {
|
|
763
|
+
"destructiveHint": false,
|
|
764
|
+
"idempotentHint": true,
|
|
765
|
+
"openWorldHint": true,
|
|
766
|
+
"readOnlyHint": true
|
|
767
|
+
},
|
|
768
|
+
"description": "Return a page of the accessibility tree from the latest get_app_state or include_tree snapshot, starting at node offset (default 0). Use it when a tree was too large to return inline (accessibility_tree_spill is set) and the host cannot read the spill file; page with next_offset until it is null. Element indices match the snapshot, so element_index actions work on these nodes. It does not read the desktop again.",
|
|
769
|
+
"inputSchema": {
|
|
770
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
771
|
+
"properties": {
|
|
772
|
+
"offset": {
|
|
773
|
+
"default": null,
|
|
774
|
+
"description": "First node to return, counted from the start of the cached tree (default 0).",
|
|
775
|
+
"minimum": 0,
|
|
776
|
+
"type": [
|
|
777
|
+
"integer",
|
|
778
|
+
"null"
|
|
779
|
+
]
|
|
780
|
+
}
|
|
781
|
+
},
|
|
782
|
+
"type": "object"
|
|
783
|
+
},
|
|
784
|
+
"name": "get_tree_page"
|
|
785
|
+
},
|
|
761
786
|
{
|
|
762
787
|
"annotations": {
|
|
763
788
|
"destructiveHint": false,
|
package/pi/extension/index.ts
CHANGED
|
@@ -43,6 +43,7 @@ const DEFAULT_TOOLS = [
|
|
|
43
43
|
"list_windows",
|
|
44
44
|
"focused_window",
|
|
45
45
|
"get_app_state",
|
|
46
|
+
"get_tree_page",
|
|
46
47
|
] as const;
|
|
47
48
|
const MAX_RESULT_TEXT_CHARS = 200_000;
|
|
48
49
|
const MAX_RESULT_IMAGE_BYTES = 2 * 1024 * 1024;
|
|
@@ -113,6 +114,7 @@ const TOOL_ALIASES: Record<string, string[]> = {
|
|
|
113
114
|
drag: ["mouse drag"],
|
|
114
115
|
focused_window: ["active window", "focus"],
|
|
115
116
|
get_app_state: ["accessibility", "observe", "snapshot", "screen state"],
|
|
117
|
+
get_tree_page: ["tree page", "more nodes", "spilled tree"],
|
|
116
118
|
list_apps: ["applications", "processes"],
|
|
117
119
|
list_windows: ["windows", "titles"],
|
|
118
120
|
move_window: ["position window"],
|
|
@@ -134,7 +134,7 @@ Pi native tools skip this MCP `command` config; see [Pi setup](references/pi-set
|
|
|
134
134
|
## Procedure
|
|
135
135
|
|
|
136
136
|
1. In Pi, call `computer_use_linux_tools` with the exact tools or capability you need. Enabled tools use the `computer_use_linux_<name>` prefix, appear starting on the next model turn, and remain active for the session.
|
|
137
|
-
2. Begin every desktop-control turn with `get_app_state`, scoped to the app you are working in: pass `app_name_or_bundle_identifier` or a window target (`window_id`, `pid`, `app_id`, `wm_class`, `title`). An `app_id` may be a full desktop ID or its final dot-separated segment; matching is case-insensitive, ambiguous aliases are rejected, and an unresolved explicit `app_id` returns an empty scoped tree rather than the desktop. Without a target the result is the whole desktop AT-SPI tree, `tree_scoped` is `false`, and `message` warns; that can flood context. Use `include_screenshot: false` when the accessibility tree is sufficient. If `accessibility_tree_truncated` is `true`, the tree is incomplete: scope to a narrower target and raise `max_nodes` or `max_depth` (hard caps
|
|
137
|
+
2. Begin every desktop-control turn with `get_app_state`, scoped to the app you are working in: pass `app_name_or_bundle_identifier` or a window target (`window_id`, `pid`, `app_id`, `wm_class`, `title`). An `app_id` may be a full desktop ID or its final dot-separated segment; matching is case-insensitive, ambiguous aliases are rejected, and an unresolved explicit `app_id` returns an empty scoped tree rather than the desktop. Without a target the result is the whole desktop AT-SPI tree, `tree_scoped` is `false`, and `message` warns; that can flood context. Use `include_screenshot: false` when the accessibility tree is sufficient. If `accessibility_tree_truncated` is `true`, the tree is incomplete: scope to a narrower target and raise `max_nodes` or `max_depth` (hard caps 10000 and 64) rather than lowering them. A tree too large to return inline comes back as its leading nodes plus `accessibility_tree_spill.path`, a private JSON file with the whole tree and the same `element_index` values: search it (for a role, name or text) instead of requesting the tree again, or page through it with `get_tree_page` when you cannot read files. The compact readiness block identifies missing setup.
|
|
138
138
|
3. Use `doctor` only when you need the full diagnostic report.
|
|
139
139
|
4. If `can_build_accessibility_tree` is false, run `setup_accessibility` and restart the target app.
|
|
140
140
|
5. If `can_query_windows` is false on GNOME Wayland, run `setup_window_targeting` and ask the user to log out and back in if setup says the shell extension needs a reload.
|
|
@@ -164,6 +164,20 @@ content makes the feedback informational. Such trees get a conditional
|
|
|
164
164
|
Electron/Chromium hint computed before compaction; this is not positive Electron
|
|
165
165
|
detection.
|
|
166
166
|
|
|
167
|
+
Chromium can mark a `document web` focused alongside its contenteditable editor.
|
|
168
|
+
The focus probe keeps searching that document and reports the editor; a document
|
|
169
|
+
that holds focus itself still gets a warning, which no longer claims the text
|
|
170
|
+
was lost. An editor can carry the `editable` state without the EditableText
|
|
171
|
+
interface (`supports_editable_text: false`): `type_text` can reach it,
|
|
172
|
+
`set_value` cannot. Verify its text or a screenshot before submitting or
|
|
173
|
+
retrying. Embedded browser documents can use up an app-scoped snapshot's node
|
|
174
|
+
budget before the app's own controls; when `accessibility_tree_truncated` is
|
|
175
|
+
true, a missing editor proves nothing. Raise `max_nodes` (default 1000, hard cap
|
|
176
|
+
10000) and, if needed, `max_depth` (hard cap 64); a busy renderer may give
|
|
177
|
+
only a few thousand nodes before the deadline. A snapshot stops reading at 10 seconds and returns what it read,
|
|
178
|
+
marked truncated; if the editor is still missing, hide the embedded browser pane
|
|
179
|
+
for the snapshot.
|
|
180
|
+
|
|
167
181
|
Plain left element/index/selector `click` prefers native AT-SPI `click`,
|
|
168
182
|
`press`, or `toggle` over toolkit bounds, avoiding coordinate
|
|
169
183
|
conversion when available. This preference does not replace a coordinate click
|