computer-use-linux 0.7.39

Native Linux desktop control over MCP and CLI — semantic AT-SPI accessibility trees, multi-compositor window targeting (GNOME, KDE/KWin, Hyprland, niri, COSMIC, i3, X11), bounded screenshots, Wayland/X11 input, and an on-screen agent activity indicator.
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

## [0.7.39] - 2026-11-04

### Changed

- The crates.io package carries only what the crate builds and tests from (src, tests, examples, the five Python scripts the tests run, the GNOME Shell extension, manifest, lockfile, README, CHANGELOG, LICENSE): 75 files instead of 135. The npm wrapper, Pi extension, plugins and CI config are no longer published to crates.io.

### Fixed

- The npm wrapper downloads the release binaries on first launch when npm skipped the package's install script, as npm 12 does for scripts it was not told to allow. A global install under npm 12 used to fail on every launch with `computer-use-linux binary not found`. The download's output goes to stderr, so an MCP client's stdout stays clean, each binary is written beside its destination and renamed into place, main binary last, so a server starting at the same time never runs a half-written file or misses a helper. A download that receives no data for 30 s fails, and a package directory that cannot be written is refused before anything is downloaded.
- The npm installer escapes CR, LF and the other C0 control characters in what it logs, so a path or URL from the environment (`COMPUTER_USE_LINUX_DOWNLOAD_BASE`, a local binary path) cannot add forged lines to the install output.

## [0.7.38] - 2026-11-04

### Fixed

- Window bounds from the i3 backend on Sway are scaled from Sway's layout coordinates to capture pixels when every active output has the same scale (never below 1, as grim captures), with edges rounded outward, and left out with mixed scales. Disabled and non-desktop outputs, which Sway lists without a scale, no longer make the output layout unreadable. On a scaled output, a window-cropped screenshot or a window-relative click used the layout rect as pixels and hit the wrong region ([#375](https://github.com/agent-sh/computer-use-linux/issues/375)).
- The i3 backend works on Sway without the i3 package: it runs `swaymsg` when `i3-msg` is missing, and takes the first live socket of `I3SOCK` and `SWAYSOCK`, then the newest i3 socket, then the newest `sway-ipc.*.sock` in `XDG_RUNTIME_DIR`. A failed `swaymsg` command reports the error it printed on stdout ([#376](https://github.com/agent-sh/computer-use-linux/issues/376)).

## [0.7.37] - 2026-11-04

### Fixed

- `activate_window` with the i3 backend on Sway focuses Xwayland windows. The backend sent the window id in hex, which Sway rejects with `The value for 'id' should be numeric`; it now sends the decimal id, which i3 also accepts ([#357](https://github.com/agent-sh/computer-use-linux/issues/357)).
- The i3 backend on Sway lists native Wayland windows, so `list_windows`, `focused_window`, `activate_window` and targeted input reach them. It used to skip every window without an X11 id. A native Wayland window's `window_id` is 2^32 plus its Sway container id, above every X11 id, and focus matches `con_id`; X11 windows keep their X11 id. Sway windows carry the pid from the tree; i3 windows still read it through `xprop` ([#357](https://github.com/agent-sh/computer-use-linux/issues/357)).
- The i3 backend marks a window hidden when it sits in the scratchpad (under `__i3_scratch`). It used to read the window's `scratchpad_state`, which Sway keeps `fresh` after the window is shown, so a shown scratchpad window was refused for window-cropped screenshots; i3 reports `none` there, so a hidden i3 scratchpad window was never marked hidden.
- An element action with an exact window target is refused when the app's cached tree was narrowed to one window but recorded none, or recorded one that another window backend listed. A tree records no window when it was narrowed through the cached scope from another pid or frame, or when `get_app_state` took a title the window list could not resolve. Before, the action passed on the shared pid, so an index from one Chromium window could act on another ([#370](https://github.com/agent-sh/computer-use-linux/issues/370)).

Thanks @RaphaelFakhri for the decimal window id fix on Sway ([#367](https://github.com/agent-sh/computer-use-linux/pull/367)), and @joshuadavidthomas for the Sway report ([#357](https://github.com/agent-sh/computer-use-linux/issues/357)).

## [0.7.36] - 2026-11-01

### Added

- List and focus windows through `zwlr_foreign_toplevel_manager_v1` on wlroots compositors without a dedicated backend, such as stock labwc, phoc and river-classic. Windows carry no pids or bounds, and focus requires a unique app id and title match.
- Selkies container guide: run the server inside a linuxserver.io Selkies desktop container, reached from the host's MCP client over `docker exec`, with a launcher that joins the desktop session (`skills/computer-use-linux/references/selkies-setup.md`).
- `press_key` sends chords through `wtype` on Wayland sessions without ydotool whose session bus answers that no RemoteDesktop portal exists, as on wlroots compositors with xdg-desktop-portal-wlr (Sway, labwc, river, phoc, cage). Chords used to fail there. The portal stays preferred when it exists, when a keyboard session is already active, or with `COMPUTER_USE_LINUX_FORCE_PORTAL_KEYBOARD=1`. A missing or unreachable bus, a timeout or any other error keeps the portal route, and a failed or denied portal request is never replayed through wtype.

### Fixed

- Hyprland background input releases a key left down when a `send_key_state` batch stops between its down and up events, or when the batch's outcome is unknown, so the target app does not start its own key repeat. The error says whether the release went through, and the release waits at most a second.
- An element action whose target window shares its pid with another window of the same app (Chromium) is refused when the cached tree was narrowed to the other window and the target names that one window (a `window_id`, or an `app_id`, `wm_class` or title that matches it alone). Before, a matching pid passed the check. An app-wide tree, or an `app_id` shared by several windows, still passes on the pid.
- A post-action tree keeps the window it was taken for, so a follow-up action on the same window with an index from that tree passes the ownership check instead of asking for a new `get_app_state`. A window with no pid (i3, sway, COSMIC) is recorded only when the tree was narrowed to its frame, and its tree no longer borrows the previous snapshot's app. A tree narrowed through the previous snapshot's window scope (a target with no `window_id` or title) is recorded as that snapshot's window only when it came from the same pid and matched the same frame; otherwise it records no window. The snapshot's window, encoding and window scope are now stored together, so a concurrent call can no longer stamp one snapshot's window scope onto another.
- `perform_action`, `set_value`, and `press_key` and `type_text` in Hyprland background mode refuse a `screenshot_after: "window"` crop when the target window is not focused, since they do not raise it and the crop could show whatever covers it. No backend reports whether a window is covered, so on tiling layouts (sway, i3, Hyprland, labwc) this also refuses a window that sits visible beside the focused one, as `get_app_state` already does for its targeted screenshot. Use `screenshot_after: "screen"`, or the `screenshot` tool, which raises the target first.
- A compositor title that decorates the accessibility frame name, such as `PlanetScale - Chromium (Profile 1)` for the frame `PlanetScale - Chromium`, now narrows the tree to that window: the longest frame name the title starts with, followed by ` (...)` or ` - ...`.
- Hyprland background mode checks that the target is a Hyprland window before it refuses input it cannot map, and takes the `press_key` grammar of every other backend, so modifiers with no key (`Ctrl+Shift`) are refused. Background window capture reads the window's `stableId` from the listing that resolved it instead of listing every client again.
- `perform_action` and `set_value` with a window-style target and a `pid` fall back to the pid for the ownership check when the window listing is unavailable, as on GNOME without the Shell extension. Without a pid they still refuse.

Thanks @joshuadavidthomas for the wlr foreign toplevel backend ([#359](https://github.com/agent-sh/computer-use-linux/pull/359)) and the wtype chord route ([#360](https://github.com/agent-sh/computer-use-linux/pull/360)), and @berney for the Selkies container guide ([#361](https://github.com/agent-sh/computer-use-linux/pull/361)).

## [0.7.35] - 2026-10-31

### Added

- Hyprland background mode: with `COMPUTER_USE_LINUX_HYPRLAND_BACKGROUND=1`, `type_text` and `press_key` calls that name a target window send keys through Hyprland's `send_key_state` dispatcher without focusing it, and `get_app_state` and `screenshot` capture an unfocused target alone with `grim -T` instead of raising it or using the portal. Targets on hidden workspaces are captured until two frames match, because Hyprland repaints them only when captured. The user's focus, cursor and workspace stay put, so an agent can work on a window on another workspace. Keys go over Hyprland's control socket, never in a process's arguments, and show on the action indicator (masked unless the target's field is known not to be secret). Text is mapped for a US layout and refused whole otherwise.

### Fixed

- `get_app_state` refuses a screenshot of a targeted window that is not focused before it captures anything. It used to capture the whole desktop first and then refuse, so on a portal session the call raised a consent prompt and grabbed every monitor only to discard the image.
- Keep the remote desktop restore grant when EIS setup fails after `Start` on a non-GNOME session such as COSMIC, so persistence does not drop the grant and prompt for consent again.
- Connect the pixelflux client to the configured loopback host instead of always dialing 127.0.0.1, so `[::1]:PORT` reaches an IPv6-only server. Read screenshot dimensions from the PNG header instead of fully decoding the image, cap the typing request timeout at two minutes, and refuse text past the timeout budget before anything is sent instead of timing out mid-typing.

## [0.7.34] - 2026-10-31

### Added

- `get_app_state` takes `interactive_only: true` to return only nodes with an action, editable text or a value, plus headings, status and live regions, windows and dialogs. Containers are collapsed and `element_index` values match the full tree ([#338](https://github.com/agent-sh/computer-use-linux/issues/338)).

### Changed

- Accessibility trees in `get_app_state`, `get_tree_page`, `include_tree` results and spill files use a compact node encoding: null, empty, zero and false fields are left out, containers drop the U+FFFC placeholder text, and `actions` lists action names. `get_app_state` with `verbose: true` returns the full encoding. Compaction also drops containers whose only text is that placeholder and whose only actions are the `doDefault`, `showContextMenu` and `clickAncestor` that Chromium lists on every element ([#338](https://github.com/agent-sh/computer-use-linux/issues/338)).
- A `title` or `window_id` target narrows the tree to that window when the app exposes several windows under one AT-SPI application root, as Chromium does. The app's popups, dialogs and unnamed windows stay, since Chromium lists them beside the window; `include_tree` results use the same scope ([#338](https://github.com/agent-sh/computer-use-linux/issues/338)).

### Fixed

- Give `perform_action` and `set_value` the optional app target `click` takes (`pid`, `window_id`, `app_id`, `wm_class`, `window_title`). With a target, an `element_index` or selector from another app's `get_app_state` snapshot is refused with the message `click` returns, instead of acting on that app. When the window backend reports no pid for the target window (i3, sway, COSMIC), all four tools compare the snapshot's window instead and refuse when they differ or when the snapshot was not taken for a window. An `element_identifier` whose bus owner is a different pid than the target is refused. The window is not focused. Calls without a target behave as before ([#337](https://github.com/agent-sh/computer-use-linux/issues/337)).
- Build the release binaries with cargo-zigbuild against glibc 2.28, so they run on RHEL 8, Debian 10, Ubuntu 20.04 and newer. v0.7.33 needed glibc 2.38 for the main binary and 2.43 for the indicator, so it failed on Ubuntu 22.04, and the indicator also failed on Ubuntu 24.04 and Debian 13. The release job now fails if a binary needs a newer glibc. Thanks @zqj2021 for the report and symbol analysis ([#339](https://github.com/agent-sh/computer-use-linux/issues/339)).
- Keep KWin window IDs within JavaScript's exact integer range (2^53-1), so JavaScript MCP clients can pass a `window_id` from `list_windows` back unchanged. KWin hashed the window UUID into all 64 bits, and clients that parse JSON numbers as doubles rounded the ID. KWin IDs change once with this release and stay stable per window after it. Every other backend already returned IDs in range. Tool schemas now advertise the maximum, and a `window_id` that is not an integer from 0 to 2^53-1, including a rounded ID above the u64 range, is rejected with a prompt to re-run `list_windows` instead of being matched by rounding. Thanks @Movoid for the report ([#341](https://github.com/agent-sh/computer-use-linux/issues/341)).

## [0.7.33] - 2026-10-30

### Added

- Drive Selkies desktops through the configured pixelflux computer-use API for screenshots, clicks, scrolling, drags and keyboard input. Map element targets from logical layout coordinates and keep uncertain input outcomes from being replayed.

### Fixed

- Keep pixelflux input serialized until its request completes, including after the caller cancels it.
- Use the portal's negotiated EIS pointer regions on GNOME so fractional scaling can reach the right and bottom screen edges. Keep the legacy D-Bus path when EIS is unsupported.
- Bound wlroots output discovery even when a Wayland peer stops responding, and include pixelflux in input readiness diagnostics.

Thanks @berney for the pixelflux backend ([#331](https://github.com/agent-sh/computer-use-linux/pull/331)) and @DenysFizer for the GNOME fractional-scaling report ([#330](https://github.com/agent-sh/computer-use-linux/issues/330)).

## [0.7.32] - 2026-10-29

### Added

- List and activate labwc windows through the Selkies IPC extension. Require matching compositor identities and unique window matches; omit bounds when output scaling cannot be verified.

### Fixed

- Keep native X11 clicks, scrolls and drags on the selected X display through XTEST. Repeated clicks land after another device moves the pointer, and missing xdotool returns an error without a system-wide fallback.
- Send paced intermediate motion for XTEST, uinput and portal drags. Preserve valid portal drags across monitor gaps and attempt button release after failed presses or motion.
- Keep the terminal paste chord when Konsole exposes focused container widgets, while retaining ordinary paste for editable fields.
- Read KDE logical output geometry from KWin for portal mapping and keep layout revalidation on the selected source.
- Avoid duplicate GNOME indicator hides during capture acknowledgement. Preserve compositor settling and tolerate short renderer stalls without replaying an action.
- Keep labwc window identities within JavaScript's exact integer range, reject ambiguous activation, and preserve listings containing byte-truncated UTF-8 titles.
- Snapshot forced GTK/Qt accessibility bridge state from the selected compositor so readiness and capabilities agree.

Thanks @berney for the KDE and labwc contributions ([#316](https://github.com/agent-sh/computer-use-linux/pull/316), [#317](https://github.com/agent-sh/computer-use-linux/pull/317), [#318](https://github.com/agent-sh/computer-use-linux/pull/318)), @qixuancao for the GNOME capture fix ([#319](https://github.com/agent-sh/computer-use-linux/issues/319), [#320](https://github.com/agent-sh/computer-use-linux/pull/320)), and @martin152 for the X11 pointer and drag reproductions ([#321](https://github.com/agent-sh/computer-use-linux/issues/321), [#322](https://github.com/agent-sh/computer-use-linux/issues/322), [#323](https://github.com/agent-sh/computer-use-linux/issues/323), [#326](https://github.com/agent-sh/computer-use-linux/pull/326)).

## [0.7.31] - 2026-10-28

### Fixed

- Use per-monitor RemoteDesktop portal streams for COSMIC pointer coordinates. Its uinput absolute pointer maps onto the active monitor, which could send clicks to the wrong window on mixed-size displays.
- Use COSMIC's EIS connection when available and wait for its input devices to resume before sending the first event, preventing text prefixes and clicks from being lost during portal startup.
- Preserve the receiving window or app target across portal consent and verify its focus again before typing, key chords, and targeted pointer input. Cancelled portal keyboard startup and failed focus verification send no input.
- Verify existing GNOME Introspect app focus without calling Shell FocusApp, which opens the overview. Window activation requires the GNOME Shell extension.
- Read COSMIC window geometry and logical output origins for targeted screenshots and relative input. Wait for both snapshots and keep window IDs within JavaScript's exact integer range. PID remains optional because the protocol does not expose it.

Thanks @madnix007 for the report ([#312](https://github.com/agent-sh/computer-use-linux/issues/312), [#313](https://github.com/agent-sh/computer-use-linux/pull/313)).

## [0.7.30] - 2026-10-28

### Changed

- Return from short commands as soon as they finish, instead of polling their output every 10 ms. On KDE Plasma, `doctor` takes about 43 ms instead of 221 ms, and a `get_app_state` call that reuses cached diagnostics takes about 50 ms less.

Thanks @ofek29 for the performance improvement and regression coverage ([#308](https://github.com/agent-sh/computer-use-linux/pull/308)).

## [0.7.29] - 2026-10-27

### Changed

- Reuse the desktop diagnostics behind the `get_app_state` readiness block for up to 30 seconds, so a repeat call on KDE Plasma takes about 140 ms less and starts 6 of the 26 diagnostic subprocesses. Those 6 recheck accessibility on every call, so switching it on or off takes effect at once. A call runs all the diagnostics before it answers when it passes `verbose: true`, when its screenshot, window lookup, or accessibility tree read fails, or when it finds a window that the cached diagnostics say no backend can list. The call after a failed observation, a failed action, or a setup tool runs them too, and `doctor` always runs them.

Thanks @ofek29 for the performance improvement and regression coverage ([#305](https://github.com/agent-sh/computer-use-linux/pull/305)).

## [0.7.28] - 2026-10-27

### Fixed

- Report `backend: "unavailable"` when `focused_window`, `activate_window`, or `list_windows` fails, instead of claiming `gnome-shell-introspect`. On niri, KDE, Hyprland, and other non-GNOME sessions the old label pointed troubleshooting at GNOME Shell. The `windows` CLI command already used this value. When no window has focus, `focused_window` now names the backend that answered.

Thanks @lihaoze123 for the fix and @luochen1990 for the report ([#301](https://github.com/agent-sh/computer-use-linux/pull/301), [downstream issue](https://github.com/lihaoze123/niri-computer-use/issues/2)).

## [0.7.27] - 2026-10-25

### Added

- `get_tree_page` pages through the latest cached tree by node offset, for hosts that cannot read the spill file.

### Changed

- Keep tool results under 32,000 bytes when they carry a large accessibility tree: the result holds the leading nodes, and the whole compacted tree goes to a private file named in `accessibility_tree_spill`, with the same `element_index` values. A 2,000-node tree was about 1.2 MB of JSON, far past what MCP hosts show a model. The file lasts until the next snapshot or until the server exits.

## [0.7.26] - 2026-10-25

### Fixed

- Keep searching a focused Chromium document for its focused contenteditable editor, and stop claiming that typed text went nowhere when focus is on a non-editable element. Thanks @pnll1991 for the report and the patch. (#290)
- Return the partial accessibility tree, marked truncated, when a snapshot reaches its 10-second deadline, instead of failing with an empty tree.
- Allow `max_nodes` up to 10000, so a snapshot can read past a large embedded browser document to the app's own controls. The default stays 1000. (#290)
- Isolate the text preflight test from an inherited KDE desktop session. Thanks @ArcticLampyrid. (#293)

## [0.7.25] - 2026-10-24

### Fixed

- Accept global AT-SPI logical pointer coordinates with `coordinate_space: "atspi"`, map them through verified KWin window and output geometry, and preserve raw screenshot pixels as the default. (#281)
- Reject ambiguous same-process window ownership before checking a caller-supplied point, including when an explicit window ID is supplied.
- Capture through an already-running desktop portal without requiring a D-Bus activation file, supporting supervised isolated desktops.

## [0.7.24] - 2026-10-24

### Fixed

- Keep semantic recovery trees local and invalidate cached indices before a recovered action, requiring fresh state instead of silently renumbering the caller's last tree.
- Pin recovery to the observed process and exact window/backend identity, and reject name-only or PID-unproved rebinding after the original AT-SPI owner disappears. Thanks @ilysenko for the review.

## [0.7.23] - 2026-10-24

### Fixed

- Report failed desktop actions and intentional refusals as MCP tool errors with `isError: true`, while preserving successful results when only post-action observation fails. Thanks @OnlyHa1bara. (#280)
- Read stable machine-readable AT-SPI action names so Qt buttons use native click/press/toggle activation instead of pointer fallback. Thanks @sinantux for the detailed reports. (#281)
- Map KWin element clicks using coherent frame, client, output and scale geometry. Reject ambiguous window ownership, unknown desktop visibility, mixed output scales and stale pointer dimensions before sending input. (#281)
- Keep KWin Save/Open dialogs, confirmation prompts and verified interactive transients targetable, including dialogs that skip the taskbar. (#286)
- Refresh stale semantic AT-SPI targets once before action dispatch, preserving the original app scope and never replaying numeric-index or already-dispatched actions. (#282)
- Scope `get_app_state` by short or reverse-DNS `app_id` values, reject ambiguous aliases, and avoid whole-desktop fallback for unresolved explicit app IDs. (#283)
- Verify editable-text `set_value` results with exact full-content readback, report mismatches or verification failures instead of false success, and mark password fields unverifiable. (#284)
- Reject unsupported X11 PointerRoot keyboard monitoring before typing, preserve one xdotool dispatch with an explicit monitoring warning, and never replay the text. (#272)

### Security

- Update Tokio to 1.53.3 and register the GNOME indicator socket with the I/O-safe `AsyncFd::register` API, addressing RUSTSEC-2026-0386. Thanks @OnlyHa1bara. (#280)
- Update Pi and schema-check dependencies, including patched Undici, Vitest, Zod, body-parser, fast-uri and ip-address. Regenerate the bundled MCP client. (#285)

## [0.7.22] - 2026-10-20

### Fixed

- Detect keyboard grabs and focus transitions during X11 text dispatch, including a brief grab that drops a contiguous block of characters while the keymap and polled focused-window ID stay unchanged. Return an error without replaying the text. The regression exercises real byte loss, restored focus, stable ASCII/Unicode, and restored layout changes. This addresses a reproduced loss mechanism from the investigation of #272; the trigger of the reporter's original spontaneous capture is not confirmed.

## [0.7.21] - 2026-10-20

### Fixed

- Read WebKitGTK accessibility content through well-known AT-SPI child references and indexed localized action methods. Bound action discovery and revalidation so unresponsive peers do not block later input. Thanks @OnlyHa1bara. (#273)
- Return an error after X11 typing if an XKB layout replacement or a persistent mapping/group change is detected. Detect the reported br-to-us-to-br replacement even when the original layout is restored. Do not replay dispatched input. Preserve xdotool dispatch with an explicit warning when monitoring cannot start. This detects the layout-change case in #272; it does not repair dispatched text, prove field contents, detect every transient remap/group change, or fix the separately reported loss with a stable keymap. Thanks @JADRT22 for the reproduction.

## [0.7.20] - 2026-10-18

### Fixed

- Warn after X11 xdotool text dispatch that non-US or changing XKB layouts can silently substitute symbols. Require inspecting the text before submitting it. Correct the post-action test subprocess selector so its assertions execute. (#267)

## [0.7.19] - 2026-10-17

### Fixed

- MCP hosts that probe with `server/discover` before `initialize` (MCP 2026-07-28) no longer fail with "expect initialized request". The server now uses rmcp 3.5.1, keeps the connection open after an empty probe so the host can initialize, and supports metadata-bearing discovery requests.

## [0.7.18] - 2026-10-17

### Added
- Support opt-in post-action observation (`screenshot_after: true | "screen" | "window"`, `format`, `quality`, `scale`, `max_width`, `max_height`, `max_bytes`, and `include_tree: true`) on mutating tools (`click`, `drag`, `scroll`, `press_key`, `type_text`, `perform_action`, `set_value`, `activate_window`, `move_window`, and `resize_window`) so an action and its verification can complete in one MCP round trip. (#259)

## [0.7.17] - 2026-10-16

### Fixed
- Stabilize Hyprland wtype input for long text in confirmed nonsecret fields. Keep terminal and unknown-field text on private stdin, limited to 100 Unicode characters per call, and reject confirmed password fields. (#256)
- Preserve missing-focus warnings for content trees, including renderer hints computed before tree compaction. Recognize Electron editable states and qualify successful text input as dispatch-only. (#256)

## [0.7.16] - 2026-10-13

### Fixed
- Replace the KWin backend atomic update with stable Rust primitives so source builds work on Rust 1.93.1. (#252)

## [0.7.15] - 2026-10-10

### Fixed
- Treat focused AT-SPI terminals as keyboard targets without requiring an EditableText interface. Keep warnings for other non-editable controls. (#246)
- Send X11 text newlines as Return instead of Linefeed, with one newline per CRLF pair. (#247)

## [0.7.14] - 2026-10-10

### Fixed
- Wait for COSMIC focus state and verify window activation. Report missing initial state as an error, discard closed windows, and wait for complete monitor layouts. (#245)
- Preserve screenshots in native Pi codemode calls with structured results and image blocks accepted by `image()`. Expose MCP tool errors in structured results. (#243)

## [0.7.13] - 2026-10-08

### Fixed
- Remove new portal screenshot files after reading them, including invalid images and cancelled queued reads. Snapshot Pictures filenames before requesting capture, preserve existing names, and hold the returned file open so a replacement cannot reuse its inode.
- Shorten ydotool test directory names so private scratch paths fit Unix socket limits.

## [0.7.12] - 2026-10-07

### Added
- Add a native GNOME Shell activity indicator with cursor motion, click pulses, keycaps, typed-text masking, agent colors and idle fading. The helper preserves shared capture exclusion and rejects captures when hiding is not acknowledged.
- On-screen indicator, on by default: `computer-use-linux-indicator` draws a
  software cursor that glides to coordinate pointer targets and ripples on
  click, keycaps and a typing line for keyboard input,
  an edge glow, and a status pill naming the agent from the MCP `clientInfo`.
  Pointer actions wait 350 ms for the cursor to land; AT-SPI actions report
  their status without moving it. Screen captures require the capture lock
  and a valid hide acknowledgement from a running overlay. `set_value`
  values are always masked; keycaps and typed text are masked for password
  or unknown focus. Uses `wlr-layer-shell` or the GNOME Shell extension; set
  `COMPUTER_USE_LINUX_INDICATOR=0` to turn it off. Installed by `./install.sh`,
  `cargo install`, npm, and published as a release asset.

### Fixed

- Reuse desktop session discovery until its environment changes. Process screenshot files and encode images on one blocking worker so large captures keep MCP responsive without multiplying decoded-image memory.
- Refresh already-enabled GNOME extension assets during installation and report the required session restart.
- Mask generic text-box roles, terminal focus and generic enum fallback roles in typed text and keycaps. GTK obscured entries can advertise the same text-box role as public entries.
- `setup-window-targeting` enables the system extension in `/usr/share/gnome-shell/extensions` if a distribution package installed it. It installs the user extension in `~/.local/share/gnome-shell/extensions` only if there is no system extension. If there is a system extension, setup removes the user extension from earlier setups and asks for a GNOME Shell reload. Before, setup always installed the user extension, and GNOME Shell used it instead of the system extension, so package updates had no effect.
- The GNOME Shell extension supports GNOME Shell 51.
- On at-spi2-core 2.62 and later, the doctor check `screen_reader_enabled` failed with "No such property ScreenReaderEnabled", because 2.62 removed that D-Bus property. If the property does not exist, doctor now reads the `org.gnome.desktop.a11y.applications screen-reader-enabled` setting. With older at-spi2-core versions, doctor still reads the property.
- The doctor checks `at_spi_enabled` and `screen_reader_enabled` now show text such as "AT-SPI IsEnabled is false" and "Screen reader is off". Before, they showed raw D-Bus output such as `b false` or `(<false>,)`.

## [0.7.11] - 2026-10-04

### Fixed

- Doctor now separates detected screenshot routes from verified capture. A detected route reports `screenshot_capture_status: "unverified"` and `can_capture_screenshots: false`; use `get_app_state` with a screenshot to obtain `verified` or `failed`. Unverified capture is a setup warning, and callers should not treat the boolean alone as a missing backend.
- GNOME literal text prefers the portal and rejects strings its keymap cannot represent before typing. Wayland coordinate input refuses inaccurate relative-motion fallback. (#226)
- Portal wheel direction matches compositor axis signs on GNOME and KDE. (#226)
- Screenshot errors retain their backend causes, and diagnostic subprocesses have bounded execution and cleanup.

### Changed
- Local development builds keep line information with less debug data, and CI host builds share their cache. Release settings are unchanged. (#225)
- Pi and schema-check dependency lockfiles address audit findings. (#221)

## [0.7.10] - 2026-10-01

### Security
- COSMIC targeted input trusts compositor-reported focus rather than an
  activation cache, and no longer writes focus state into a shared temporary
  file. GNOME extension calls verify the unique owner of `org.gnome.Shell`. (#215)
- Portal responses are bound to the expected sender and request path.
  Screenshot files reject symlinks and non-regular files and enforce byte and
  decoded-pixel limits before processing. (#215)
- Automatic ydotool discovery accepts only private, same-user sockets and
  no longer falls back to shared `/tmp` sockets. The installer creates a
  mode-0600 daemon socket; `YDOTOOL_SOCKET` remains an explicit override. (#215)
- Scroll amounts must be finite and within -100 to 100 before input locks
  are taken. Pi executable and PATH overrides must use absolute paths. (#215)

### Fixed
- MCP safety checks recognize npm launcher error output without weakening
  the failure assertions. (#214)

## [0.7.9] - 2026-10-01

### Fixed
- Screenshot execution failures return MCP tool results with `isError: true`
  and the original error message. Window targeting, capture, crop, and resize
  failures no longer surface as JSON-RPC internal errors that some clients
  mistake for broken connections. (#210)
- KWin temporary plugin sequences use the current atomic update API so
  builds with warnings denied pass on Rust 1.99. (#211)

## [0.7.8] - 2026-10-01

### Added
- Official Claude Code and Codex plugin. The repo is a marketplace for both
  hosts: `claude plugin marketplace add agent-sh/computer-use-linux` or
  `codex plugin marketplace add agent-sh/computer-use-linux`. The plugin ships
  the skill and a launcher that downloads the release binaries pinned to the
  plugin version, verifies their sha256, and caches them per version. The
  Codex manifest forwards the desktop session variables that Codex strips
  from MCP server environments. `COMPUTER_USE_LINUX_BIN` runs a local build. (#202)

### Fixed
- Native X11 queries now enforce one deadline in the transport itself.
  Connect, handshake, and every reply share a 2-second bound, so a stalled
  X server closes the query connection instead of leaving a blocked worker
  running after a timeout. The `doctor` X11 check no longer spawns a
  detached thread. Unix sockets, literal IP addresses, and `localhost` need
  no resolver; a remote hostname in `DISPLAY` resolves through
  `getent ahosts` under the same bound, and a missing or failing lookup
  reports the X11 route as unavailable. Fix by Gary Lysenko (ilysenko),
  from ilysenko/codex-desktop-linux#1532. (#203)
- Accessibility snapshots stay stable during input. The cached nodes and
  the pid that owns them are now one snapshot, and `get_app_state`
  publishes a new one only after in-flight input finishes. An index that
  passed the owner check can no longer resolve to another app's node
  mid-action. `perform_action` and `set_value` now take the input lock that
  `click` and `scroll` already held. Fix by Gary Lysenko (ilysenko), from
  ilysenko/codex-desktop-linux#1532. (#203)
- PTY metadata alone no longer makes a window a paste-capable terminal. The
  paste chord comes only from a known terminal app id or WM_CLASS, so an
  IDE with an integrated terminal keeps the standard paste shortcut. PTY
  enrichment now also recognizes Ghostty, GNOME Terminal, and KGX by app
  id or WM_CLASS, not only by title, which keeps enrichment working for
  X11 windows with a custom class and a plain title. This replaces the
  earlier rule that defaulted an enriched window with no known identity to
  Ctrl+Shift+V. Fix by Gary Lysenko (ilysenko), from
  ilysenko/codex-desktop-linux#1532. (#203)
- The bounded process runner no longer sleeps after every chunk while a
  command is still producing output. Each drain stays capped and the
  deadline is still checked every pass, so continuous output cannot starve
  stderr or bypass the output limit. Fix by Gary Lysenko (ilysenko), from
  ilysenko/codex-desktop-linux#1532. (#203)
||||||| parent of 1954063 (feat: official Claude Code and Codex plugin)

## [0.7.7] - 2026-09-30

### Added
- Window listing and exact focus on niri through `niri msg`, with direct
  JSON IPC as a fallback when the CLI is unavailable. Socket discovery
  matches the current Wayland display and refuses ambiguous sessions.
  Focus is verified with a fresh window query before targeted input.
  Window bounds account for output scaling and window offsets. Missing
  positions stay null; unknown or mixed scaling omits bounds. (#192)

## [0.7.6] - 2026-09-29

### Fixed
- Wayland `press_key` on the remote-desktop portal now sends modifiers and
  named keys (Enter, arrows, F-keys and the rest) as keysyms, so the
  compositor resolves them against the active keymap. With Caps Lock and
  Control swapped, `Ctrl+A` used to press the physical Control position,
  which toggled Caps Lock and typed `A`. It now selects all. Letters and
  digits stay physical keycodes: mutter drops a keysym missing from the
  current layout group, so a keysym `a` would vanish under a Hebrew or
  Cyrillic layout, and GTK and Qt match shortcuts on those layouts by the
  US keycode. KDE Plasma keeps keycodes for now. (#191)

## [0.7.5] - 2026-09-28

### Added
- Opt-in persistence for the Wayland remote-desktop portal. Set
  `COMPUTER_USE_LINUX_PERSIST_REMOTE_DESKTOP=1` to send `persist_mode=2`
  on `RemoteDesktop.SelectDevices` and reuse the single-use `restore_token`
  returned by `Start`. Nothing persistence-related is sent on
  `ScreenCast.SelectSources` (that call rejects it for a remote-desktop
  session). Pointer and keyboard sessions store separate tokens, mode
  `0600`, under `$XDG_STATE_HOME/computer-use-linux/` or
  `~/.local/state/computer-use-linux/`. The first grant still shows the
  dialog. Later processes restore until the desktop revokes the grant, or
  until the token cannot be restored, which falls back to a prompt.
  Interface version 2 is required. Unset, behavior is unchanged. (#185)

### Fixed
- X11 `scroll` no longer follows ydotool's absolute move with a single wheel
  event. That move warps the pointer through (0, 0). GTK 3 resets its XI2
  scroll valuators when the pointer re-enters the window, so the one wheel
  event only re-baselines them and the window does not move, while the tool
  still returns success. Native X11 now sends the same notch count as XTEST
  wheel buttons through xdotool (4 up, 5 down, 6 left, 7 right), which have
  no scroll valuators. Wayland portal scroll is unchanged. (#184)

## [0.7.4] - 2026-09-27

### Fixed
- The #167 index check no longer trusts a pid the snapshot did not match.
  When `get_app_state` named a pid with no accessibility root plus an app
  name, the tree came from the app-name match but was recorded under the
  requested pid. An index from that tree then passed a click aimed at the
  requested pid and was refused for the app that owns it. The snapshot now
  records a pid only when its roots were selected by that pid; otherwise each
  node is checked against its owner on the accessibility bus.

## [0.7.3] - 2026-09-26

### Fixed
- `click` and `scroll` by `element_index` or selector now refuse an index from
  another app's snapshot. `get_app_state` records the pid it snapshotted;
  when the action's target resolves to a different pid, the call fails and
  asks for a `get_app_state` of the target, instead of acting on the other
  app's node and reporting `ok: true`. An untargeted snapshot mixes apps, so
  its node is checked against the pid that owns it on the accessibility bus.
  (#167)
- Portal pointer input on scaled GNOME Wayland (for example 125 %) now lands
  where it is aimed. mutter maps a stream point to `monitor.x + stream_x /
  scale` when its layout mode is logical, which is the GNOME 50 default, so
  logical coordinates arrived at 1/scale of the target and still reported
  success. The pointer path reads the layout mode from
  `org.gnome.Mutter.DisplayConfig` and sends each stream's point multiplied
  by its monitor scale. Click, scroll, and drag share the path. Unscaled
  monitors, physical layout mode, and other compositors are unchanged. (#169)
- The Pi extension falls back to `computer-use-linux` on `PATH` when neither
  `COMPUTER_USE_LINUX_BIN` nor the downloaded package binary is available.
  Temporary extensions (`pi -e npm:@agent-sh/computer-use-linux`) are staged
  without that binary and warned "binary not found" even with a global
  install. The PATH lookup was dropped in the native-tools rewrite. (#170)
- `type_text` and `press_key` no longer warn "no focused element" when the
  focus probe merely ran out of budget. The 400-node search now reports when a
  node, depth, or read limit stopped it, and the feedback says the input could
  not be verified instead. With a target pid, the probe searches only that
  app; when no AT-SPI app belongs to it (xterm, Electron without
  `--force-renderer-accessibility`), feedback says so instead of warning or
  reporting another app's focused widget. (#168)
- KDE Plasma clipboard paste into xterm, uxterm, rxvt, urxvt, and koi8rxterm
  now sends Shift+Insert. Those terminals have no Ctrl+Shift+V binding by
  default, so the paste was dropped; Klipper sets the selection as well as
  the clipboard, so Shift+Insert pastes the new text. When AT-SPI reports a
  focused element that is not a terminal (a search field in a terminal
  window), paste falls back to Ctrl+V. The check reads the AT-SPI role enum,
  not the localized role name. Behavior ported from
  ilysenko/codex-desktop-linux#1413.
- Helper spawns (ydotool, wtype, xdotool, gnome-screenshot, and every command
  run through the supervised runner) retry a transient `ETXTBSY` ("Text file
  busy") for up to 75 ms. The error appears when a helper binary is being
  replaced, and it made xdotool fall back to ydotool as if it were missing.
  It also made tests that write and exec fake helper scripts fail under the
  parallel suite, which failed the first v0.7.2 tag run.

## [0.7.2] - 2026-09-26

### Added
- Native X11 screenshot route: one `GetImage` on the root window over the
  X11 connection, used only on a native X11 session (never XWayland) and
  tried after GNOME Shell and the portal, before `gnome-screenshot`.
  Pixels are device pixels, the space xdotool input and X11 window origins
  use. MATE/X11 had no working route: xdg-desktop-portal-gtk has no
  Screenshot, and gnome-screenshot 41 blacks out 3/4 of the frame at
  window-scaling-factor 2. `doctor` reports the route as
  `platform.x11_display` and `capabilities.screenshot` entry `x11`;
  `COMPUTER_USE_LINUX_SCREENSHOT_BACKEND=x11` pins it. (#155)

### Fixed
- `doctor` no longer reports the XDG Screenshot, ScreenCast, or InputCapture
  portal as available when the portal does not export that interface.
  `busctl introspect` exits 0 with only a header line for a missing interface,
  so each entry now requires its methods (Screenshot: `Screenshot`). Readiness
  gains `can_capture_screenshots` and a blocker when no screenshot route is
  detected; this is detection, not a test capture. (#156)
- X11/EWMH window origins now come from the X server
  (`TranslateCoordinates` to the root window) instead of `wmctrl -lG`, which
  counts the client's offset inside its frame twice. Window-targeted
  screenshots cropped the wrong area, relative clicks were offset by the same
  amount, off-screen warnings misfired on maximized windows, and
  `move_window` reported a mismatch after a correct move. Bounds are the
  client area; `move_window` now verifies the frame origin it requested. When
  the X server cannot be asked, the origin is reported unknown instead of the
  shifted wmctrl value. (#157)

## [0.7.1] - 2026-09-19

### Changed
- `get_app_state` now returns its screenshot as a structured `image` content
  block (the same shape as the `screenshot` tool) followed by the JSON report
  as text and `structuredContent`. The JSON `screenshot` field keeps the
  metadata (dimensions, scale, format, bytes) but no longer embeds the base64
  `data_url`, which hosts were counting as ~30K text tokens per call. Callers
  that read `screenshot.data_url` from the JSON should read the image block
  instead. (#145)

### Fixed
- `type_text` on X11 no longer delivers characters out of order. The xdotool
  backend passed `--delay 0`, which lets XTEST key events race each other on
  some X servers (seen on Cinnamon / Mint 22). It now uses xdotool's 12ms
  per-character default and scales the command timeout with text length.
  `COMPUTER_USE_LINUX_XDOTOOL_TYPE_DELAY_MS` overrides the delay. (#147)
- The unscoped-tree warning from `get_app_state` no longer tells a caller that
  already passed a `pid` or window target to pass a target. When the target
  matched no AT-SPI application root, the warning now points at the app's
  missing accessibility support, `list_apps`, and a lower `max_nodes` instead.

## [0.7.0] - 2026-09-16

### Added
- `get_app_state` reports `tree_scoped` and `accessibility_tree_truncated`,
  warns in `message` when no app target narrowed the AT-SPI tree to one app,
  and documents every scoping parameter in its schema, the server
  instructions, the skill, and the Pi guide. Unscoped calls used to return the
  whole desktop tree silently and could exhaust a small context window.

### Fixed
- Skill Install section now separates Pi native install from PATH CLI/MCP
  install, so `pi install` is not described as sufficient for shell `doctor`
  and `setup`.

## [0.6.0] - 2026-09-15

### Added
- GTK4 delivered-event coordinate probe and an opt-in GTK3/MCP semantic-click
  regression that verifies actual button activation at scales 1 and 2.
- Explicit foreground `guard-accessibility` command with a passive AT-SPI
  listener and verified GNOME toolkit-accessibility reassertion. Ctrl-C or
  SIGTERM stops the guard without disabling other accessibility clients or
  restoring an old saved setting. Never started automatically by MCP or setup.
- Optional `complete_interaction` MCP notification, enabled by
  `COMPUTER_USE_LINUX_NOTIFY_ON_COMPLETE=1`, with bounded notification execution
  and graceful handling of unavailable desktop notification services.

### Fixed
- KDE Plasma terminal paste uses terminal shortcuts, including uxterm detection.
- Setup verifies saved GNOME accessibility settings instead of reporting an
  unverified write as success.
- Plain left element/selector clicks prefer recognized native AT-SPI activation
  actions over toolkit bounds, avoiding GTK3 HiDPI and GTK4 zero-origin pointer
  conversion when a matching action is available. Explicit coordinates, right
  clicks, and multi-clicks preserve pointer semantics.
- Clarified that relative click/scroll coordinates use the clipped window
  screenshot crop origin before preview resizing, not raw surface or widget
  coordinates, and require a window target.

## [0.5.0] - 2026-08-31

### Added
- The Pi package now exposes native `computer_use_linux_*` tools without a
  separate MCP adapter. One small loader stays active initially, then uses
  Pi's additive dynamic-tool loading to expose selected tools with their exact
  generated MCP schemas only when desktop control is needed.
- Pi keeps one lazily started, session-scoped computer-use-linux process,
  forwards cancellation, serializes desktop actions, preserves image results,
  bounds text output, and rejects binary/schema version drift.

### Changed
- Pi installation is now one command (`pi install
  npm:@agent-sh/computer-use-linux`) and no longer writes
  `~/.pi/agent/mcp.json`. Existing adapter-based entries are detected and
  reported for non-destructive manual cleanup.

## [0.4.10] - 2026-08-29

### Added
- An explicitly opt-in `run_shell` MCP tool supports bounded same-user shell
  execution for trusted remote MCP deployments. The tool is absent unless
  `COMPUTER_USE_LINUX_ENABLE_SHELL=1`, clears ambient credentials, requires
  visible environment additions, enforces timeout/output limits and process-
  group cleanup, and emits command-digest audit records.

### Fixed
- Wayland literal text now uses `wtype` on compatible compositors when portal
  keyboard input is unavailable, preserving Unicode before the ydotool
  fallback. Known-incompatible GNOME, KDE/Plasma, and COSMIC sessions do not
  advertise or select wtype, and a launched failure never replays the text.
- Absolute uinput pointer axes now end at the final logical desktop pixel, so
  edge coordinates are advertised and clamped consistently.
- Capability maps now advertise AT-SPI only when its bus is reachable and a
  toolkit accessibility status is actually enabled.
- Buttons outside the absolute uinput device's left, middle, and right set now
  fall through to a backend that can synthesize them instead of becoming left clicks.
- Temporary KWin script callbacks now accept one matching response from the
  current `org.kde.KWin` bus owner, reject spoofed or replayed responses, and
  time out the complete script transaction before cleaning up owned temporary
  state without disturbing a colliding callback registration.
- KWin window listings now classify Plasma 6 native Wayland and Xwayland
  clients when the legacy client flags are unavailable.
- GNOME extension setup now reports when changed files require an already-active
  Shell extension to reload before its newly installed DBus methods are served,
  and requires that reload when the previous extension state cannot be read.

## [0.4.9] - 2026-08-12

### Fixed
- Bounded AT-SPI traversals now use concurrent indexed child reads, count both
  queued references and failed child lookups against their work budgets, and
  enforce a snapshot deadline so wide, malformed, or stalled accessibility
  trees cannot allocate or retain unbounded work.

## [0.4.8] - 2026-08-12

### Fixed
- AT-SPI state capture now reaches deeply nested GTK4 controls such as Nautilus
  file cells by using a 1,000-node default budget and depth-32 traversal, with
  bounded 2,000-node and depth-64 limits shared by the MCP and CLI paths.
- `install.sh` now treats unavailable window-targeting or exact-focus support as
  a degraded platform capability when MCP registration, accessibility trees,
  and development input are ready, while missing core prerequisites remain hard
  failures. The same classification applies when `jq` is unavailable.

## [0.4.7] - 2026-08-09

### Fixed
- `install.sh` now recognizes Artix as pacman-based, chooses an explicitly
  requested or unambiguous package manager for unknown distros, treats
  ydotool as an optional fallback, installs the required xdotool keyboard
  backend on X11, distinguishes pointer-only direct uinput from keyboard-ready
  input in `doctor`, reports Wayland RemoteDesktop pointer availability
  separately from its required keyboard contract, and skips automatic ydotoold
  setup when a systemd user manager is unavailable.

## [0.4.6] - 2026-08-05

### Fixed
- Native X11 coordinate clicks now use one supervised
  `xdotool mousemove -- X Y click --repeat N BUTTON` command after the
  absolute pointer and eligible portal paths, with `ydotool` fallback only
  when `xdotool` cannot be spawned. Standard left, middle, and right buttons
  are supported; extended buttons retain the existing fallback path. Set
  `COMPUTER_USE_LINUX_FORCE_YDOTOOL_POINTER=1` to skip xdotool.

## [0.4.5] - 2026-08-01

### Fixed
- Stateful ydotool operations now complete while retaining the serialized input
  lock after caller cancellation, preventing paired button or key events from
  being interrupted. Drag also attempts button release after intermediate
  failures.
- Scaled KWin sessions now map logical window geometry through the compositor's
  virtual screen geometry while preserving logical portal input coordinates.
- Hyprland window bounds now map against grim's complete global output union,
  including negative origins and mixed or fractional scales, and are omitted
  when monitor metadata is unavailable or invalid.
- Mirrored KScreen outputs are excluded from the portal monitor layout.

## [0.4.4] - 2026-07-31

### Fixed
- KWin window listing and activation now support both Plasma 6
  (`windowList`/`activeWindow`) and Plasma 5 (`clientList`/`activeClient`).
- ydotool is now used only when its CLI, daemon, and socket support the raw
  event semantics Computer Use emits. Compatibility probing works without
  `XDG_RUNTIME_DIR`, uses an isolated private socket, and rejects CLI errors
  that are returned with a successful exit status.
- X11 `xdotool type` now disables per-character delay, and a command that
  starts but fails is no longer replayed through ydotool. The ydotool fallback
  is limited to failures to launch xdotool, avoiding duplicate partial input.

## [0.4.3] - 2026-07-31

### Fixed
- Hyprland window activation now checks `hyprctl dispatch` stdout instead of
  trusting its exit status, so an exit-zero `Invalid dispatcher` response falls
  through to the compatible focus dispatcher. (#62)
- Modifier chords sent through the ydotool fallback now include a 100 ms
  inter-event delay so applications such as Firefox do not drop simultaneous
  modifier and key events. (#63)

## [0.4.2] - 2026-07-25

### Fixed
- X11 keyboard input now goes through `xdotool` (XTEST) instead of ydotool.
  ydotool injects raw evdev scancodes into a virtual uinput device, which X11
  re-interprets through the active XKB layout — so `press_key "Return"` and
  chords like `ctrl+a` landed as stray characters, and `type_text` mangled
  symbols and digits (`_` → `%`, `1` → `+`) even on a plain US layout. XTEST
  resolves keysyms against the live layout. Wayland behaviour is unchanged, and
  the ydotool path remains the fallback when `xdotool` is missing or fails.
  `doctor` now reports an `xdotool` input backend on X11. Override with
  `COMPUTER_USE_LINUX_FORCE_YDOTOOL_KEYBOARD=1` (opt out) or
  `COMPUTER_USE_LINUX_FORCE_XDOTOOL_KEYBOARD=1` (force on). (#58)
- Portal `scroll` direction on KDE Plasma Wayland: vertical discrete axis steps
  are inverted for the xdg-desktop-portal-kde discrete path so `direction:
  "up"|"down"` matches viewport motion. ydotool / REL_WHEEL polarity is
  unchanged. Override with `COMPUTER_USE_LINUX_PORTAL_SCROLL_INVERT=0|1`. (#56)

## [0.4.1] - 2026-07-15

### Fixed
- Targeted `get_app_state` screenshots now crop to the resolved target window,
  and refuse the full-desktop fallback when a target was requested but window
  bounds cannot be resolved or the window is entirely off-screen. (#48)
- Hyprland window bounds are normalized against each window's monitor origin
  and fractional scale so portal screenshot coordinates align on
  multi-monitor and scaled (e.g. 1.8x/2.0x) setups. (#48)
- Wayland sessions are recognized via `WAYLAND_DISPLAY` when
  `XDG_SESSION_TYPE` is unavailable, so the portal input fallback engages in
  environments that don't export the session type. (#48)
- Window focus verification now allows up to one second for compositor
  workspace/focus transitions before reporting activation failure. (#48)

## [0.4.0] - 2026-07-15

### Added
- Generic X11/EWMH window backend so `list_windows`, `focused_window`,
  `activate_window`, `move_window`, and `resize_window` work on X11 window
  managers without a dedicated backend (Cinnamon/Muffin, MATE/Marco,
  Xfce/xfwm4, Openbox, and others). (#41)
- Pi coding agent extension package: `pi install npm:@agent-sh/computer-use-linux`
  now provides Linux desktop control tools through `pi-mcp-adapter`'s MCP
  proxy without a separate pi-specific skill. (#42)

### Fixed
- Hyprland 0.55 exact window focus: `activate_window` now tries the 0.55 Lua
  focus dispatcher (`hl.dsp.focus`) first and falls back to the legacy
  `focuswindow` dispatcher on older releases. (#45)
- Exported MCP tool schemas no longer carry the non-standard `uint`/`uint8`/
  `uint16`/`uint32`/`uint64`/`usize` `format` annotations emitted by
  `schemars`, which produced repeated warnings in MCP clients; integer types
  and numeric constraints are preserved. (#45)
- GNOME extension package bootstrap on Ubuntu no longer tries to install the
  nonexistent `gnome-shell-extension-tool` apt package; `gnome-shell` is
  installed only when `gnome-extensions` is missing and apt can provide it. (#40)

## [0.3.1] - 2026-07-03

### Fixed
- A scroll with a window target but no x/y/element_index focused the window and
  then scrolled whatever sat under the cursor while reporting success.
  Window-targeted scroll now defaults its point to the centre of the resolved
  window (and errors with a pass-x/y hint when bounds are unavailable). Scroll
  results also gain the same off-screen coordinate warning click already had.

## [0.3.0] - 2026-07-03

### Added
- Exposed a focused Rust library surface for downstream diagnostics,
  accessibility snapshots, screenshots, and server integration while preserving
  the existing CLI binaries and standalone naming. (#35)
- Input-landing feedback: targeted keyboard input results append
  focused-element feedback from AT-SPI and warn when no editable element holds
  focus.
- Off-screen detection: screenshot, click, and input results warn when the
  target window or coordinate is partially or fully off-screen.
- Window geometry tools: `move_window` and `resize_window` via the GNOME Shell
  extension backend.

## [0.2.9] - 2026-06-22

### Fixed
- GTK4 applications (Nautilus, Text Editor, baobab, and others) now return their
  full accessibility tree instead of a single `role: "unknown"` root with
  `child_count: 0`. Reads were routed through the `atspi` `P2P` trait's
  `object_as_accessible`, whose no-peer fallback builds a proxy with a path but
  no destination; on the shared a11y bus that fails with `ServiceUnknown` for
  any app that does not advertise a peer-to-peer bus address. Modern GTK4 apps
  do not implement the legacy `GetApplicationBusAddress`, so they hit the broken
  fallback while GTK3/Chromium/Electron apps kept working. Reads now use
  `ObjectRefExt::as_accessible_proxy`, which always pins the destination to the
  object's bus name. (#31)

## [0.2.8] - 2026-06-17

### Changed
- Published a metadata-only patch release so local and downstream consumers can
  pin the already-validated `computer-use-linux` package state.

## [0.2.7] - 2026-06-16

### Fixed
- Window-relative clicks now require a verified target window and resolved
  bounds before coordinates are translated, preventing clicks from silently
  landing against stale or originless window data.
- Long `ydotool type --file -` input now gets a bounded timeout with both a
  fixed process budget and a text-length budget while stdout/stderr are drained
  asynchronously.
- KDE clipboard text input now uses the session DBus API directly and waits
  long enough for large paste payloads before restoring the previous clipboard;
  Klipper proxy creation and method calls share the same bounded DBus timeout.
- Failed accessibility tree extraction clears cached nodes so later
  element-targeted actions cannot use stale coordinates.

### Changed
- The COSMIC helper source path and runtime override surface now use standalone
  `computer-use-linux` naming only.

## [0.2.6] - 2026-06-06

### Fixed
- Screenshots now work from background processes (systemd user services,
  non-interactive parent shells) on GNOME Wayland. The GNOME Shell DBus method
  rejects callers that do not own an allowlisted bus name, and the XDG portal
  cancels non-interactive requests when there is no foreground window, so both
  prior backends failed in that context. `gnome-screenshot` is now a third
  capture fallback that works regardless of session context, bounded by a 20s
  timeout so a hung capture degrades to a clear error instead of blocking.

### Added
- `COMPUTER_USE_LINUX_SCREENSHOT_BACKEND` to force a single screenshot backend
  (`gnome-shell`, `portal`, or `gnome-screenshot`), skipping the fallback chain
  for pinned/background deployments and debugging.
- `doctor` now probes `gnome-screenshot` and lists it under
  `capabilities.screenshot` when present.

## [0.2.5] - 2026-06-05

### Added
- Added build-time GNOME extension / DBus identity overrides (`CUL_*`) so the
  `codex-desktop-linux` embedded copy can share this source while keeping its
  Codex extension identity, plus runtime `CODEX_COMPUTER_USE_*` aliases for the
  embedded input/backend knobs.

### Documentation
- Cross-referenced the sibling `agent-workspace-linux` project in the README.

### Fixed
- Bounded screenshot payloads by default before returning them to MCP hosts,
  while exposing opt-in screenshot sizing controls and coordinate metadata for
  downscaled captures.
- Added opt-in JPEG screenshot output with a caller-selected quality so agents
  can choose compression before the byte cap forces additional resizing.
- Ported downstream Linux readiness fixes: `doctor` now treats direct
  `/dev/uinput` and the XDG RemoteDesktop portal as valid development-input
  backends instead of requiring `ydotoold` in every ready setup.
- Ported downstream session hydration fixes for X11 launches by carrying
  `XAUTHORITY` through environment hydration and checking the same-user namespace
  init process when it owns the graphical session environment.

### Security
- Pinned the release upload GitHub Action to a commit SHA in CI.

## [0.2.4] - 2026-05-25

Primarily a documentation release that refreshes the crates.io and npm README
pages; also bumps the MCP server's advertised version string to match.

### Added
- Documented the `screenshot` MCP tool and the `doctor` capability map, which
  were missing from the README tool list and the MCP safety-contract table.
- A new "Environment variables" section covering runtime overrides
  (`CU_DISABLE_ABS_POINTER`, the `COMPUTER_USE_LINUX_FORCE_PORTAL` /
  `FORCE_YDOTOOL` pointer and keyboard knobs) and the npm wrapper install knobs
  (`COMPUTER_USE_LINUX_BIN`, `DOWNLOAD_BASE`, `SKIP_DOWNLOAD`, `LOCAL_*`).

### Changed
- Stopped pinning explicit versions throughout the docs (README, npm README,
  Hermes skill). Install commands are now bare and download links use GitHub's
  `/releases/latest` redirect, so the docs no longer drift on every release.
- Dropped the `version` field from the Hermes skill frontmatter (optional per
  the agentskills.io standard) so it no longer mirrors the tool version.
- Friendlier README opening: warmer tagline and a verb-driven summary, with no
  sections removed.

### Fixed
- `install.sh` now reads the current `doctor` readiness schema
  (`.readiness.blockers`, empty array means ready) instead of the removed
  `.ready` / `.checks` fields, so a fully provisioned system reports ready
  instead of always failing the doctor step. Restored the `install.sh`
  executable bit. (#9)

## [0.2.3] - 2026-05-22

### Added
- A `sync reminder` CI workflow (`.github/workflows/sync-reminder.yml`) that
  opens (or updates) a `codex-sync`-labeled issue when a merge to `main` touches
  the crate sources (`src/**`, `Cargo.toml`, `gnome-shell-extension/**`), so the
  change can be propagated into the `codex-desktop-linux` embedded copy with its
  codex naming re-applied.

### Changed
- Bumped to establish version-enumeration parity with the `codex-desktop-linux`
  embedded copy (`0.2.3-linux-alpha1`). The two crates are kept on the same
  enumeration on purpose: a mismatch signals that a sync between them is pending.

## [0.2.2] - 2026-05-21

### Added
- Added a uinput absolute pointer (`abs_pointer.rs`) that creates a private
  `ABS_X`/`ABS_Y` device mapped to the portal screenshot coordinate space, so
  clicks land at the requested pixel on multi-monitor / HiDPI setups instead of
  being distorted by pointer acceleration and fractional scaling. Wired into
  `click()` with `ydotool` fallback; opt out via `CU_DISABLE_ABS_POINTER`.
- Added a Hermes-compatible skill tap at `skills/computer-use-linux/SKILL.md`
  and an `agnix` CI gate for agent-sh skill/config hygiene.
- Added agent-sh project-health files: `CONTRIBUTING.md`, `SECURITY.md`,
  `CODE_OF_CONDUCT.md`, and `CODEOWNERS`.
- Synced upstream Linux Computer Use text-input improvements: Wayland remote
  desktop portal keyboard sessions, KDE/Plasma clipboard paste fallback for
  layout-safe `type_text`, and literal keysym typing on non-KDE Wayland
  sessions before falling back to `ydotool`.
- Synced upstream Hyprland/session hydration fixes, including systemd user
  environment discovery, common command path hydration, `HYPRLAND_INSTANCE_SIGNATURE`
  inference, and rounded window-id disambiguation.

### Fixed
- Omitted the debug-only `received` echo field from the generated MCP
  `outputSchema` for `ActionOutput` and `ActivateWindowOutput`. `schemars`
  serialized `Option<serde_json::Value>` as the boolean schema `true`, which
  strict MCP clients (mcphub, Claude Desktop, `@modelcontextprotocol/sdk`'s
  `AssertObjectSchema`) reject, failing the whole `tools/list` response.
  Affected `click`, `drag`, `perform_action`, `press_key`, `scroll`,
  `set_value`, `type_text`, and `activate_window`. (#1)

### Changed
- Updated repository, release, package, and CI links from `avifenesh` to the
  `agent-sh/computer-use-linux` org repo.
- `setup_accessibility` and `doctor` now understand the AT-SPI
  `org.a11y.Status IsEnabled` path in addition to GNOME toolkit accessibility.

## [0.2.1] - 2026-05-14

### Added
- npm wrapper package (`@agent-sh/computer-use-linux`) for Node.js users. It
  downloads and verifies the matching GitHub release binaries at install time.
- Tag-driven GitHub Actions publishing for crates.io and npm using repository
  secrets.
- CI release gates for locked Rust checks, clippy, tests, private rustdoc,
  cargo publish dry-run, cargo audit, npm wrapper smoke tests, and an MCP
  protocol/safety contract check.
- MCP `ToolAnnotations` that mark read-only observation tools separately from
  mutating desktop-control tools.

### Changed
- Switch the COSMIC protocol dependency from a pinned Git revision to the
  published `cosmic-protocols` `0.2.0` crate so `computer-use-linux` can be
  published on crates.io.
- Ship the `computer-use-linux-cosmic` helper alongside prebuilt release
  binaries and install it from `install.sh` so COSMIC window targeting works
  outside `cargo install`.
- Keep the MCP `serverInfo.version` aligned with the Cargo package version.
- Remove unused direct `libc` and `png` dependencies from the crate manifest.

### Documentation
- Add Hermes Agent CLI setup commands and clarify the registered MCP tool
  names / toolset.
- Add npm install instructions and fix the prebuilt binary install example to
  match the release assets, which are raw binaries with `.sha256` files rather
  than tar archives.
- Document the mutating-tool safety contract for MCP hosts and npm users.
- Pin README and npm README install examples to the released `0.2.1` packages
  and `v0.2.1` GitHub release assets.

## [0.2.0] - 2026-05-14

### Added
- **Multi-compositor window targeting**: native backends for **KWin**
  (KDE Plasma), **Hyprland**, **i3**, and **COSMIC** Wayland alongside
  the existing GNOME Shell backend. Window listing, focus tracking, and
  activation now work across all five compositors with automatic backend
  selection at runtime.
- **COSMIC Wayland helper** (`computer-use-linux-cosmic` binary) that
  speaks the `zcosmic_toplevel_info_v1` and `zcosmic_toplevel_manager_v1`
  protocols, used by the main server when running under COSMIC.
- **`windowing/` crate-internal module** consolidating all backends behind
  a uniform `WindowBackend` trait, with a registry that picks the right
  backend per session.
- **Datagram ydotool socket support** in addition to the existing stream
  sockets. Aligns with `ydotoold`'s newer default and avoids a
  reconnection penalty per input event.
- **Raw-keycode keyboard input** path for ydotool, fixing keystroke
  delivery on layouts where the symbolic keysym path was unreliable.
- **Compact Linux accessibility trees** in `get_app_state` — deduplicated
  redundant container nodes for smaller, more focused snapshots.
- **Enriched AT-SPI state readback** — element states (`focused`,
  `selected`, `expanded`, `checked`, …) now flow through to the response
  schema for `get_app_state`.

### Changed
- Server-side rejection of empty window-backend results (returns a
  structured "no backend available" error instead of an empty list).
- Stale-client eviction in the chrome-extension host path on backend
  side (host binary itself not shipped here — see Removed).

### Removed
- **`codex-chrome-extension-host` binary** is intentionally not shipped
  in this fork — it is a Chrome native messaging host scoped to Codex
  browser automation (`com.openai.codexextension`), unrelated to the
  computer-use MCP. The cosmic helper binary is renamed to
  `computer-use-linux-cosmic` to match the project naming.

### Synced from upstream
- This release tracks
  [`ilysenko/codex-desktop-linux`](https://github.com/ilysenko/codex-desktop-linux)
  through commit `4d6fd96` (May 2026), then re-applies the rebrand
  (DBus names, env vars, GNOME extension UUID, cache-file prefixes).
  Upstream credit goes to ilysenko, mosesmrima, PinguuSS, and the
  original Codex contributors.

## [0.1.0] - 2026-05-13

### Added
- Initial public release as a standalone repository, extracted from
  [`codex-desktop-linux-local-stack`](https://github.com/avifenesh/codex-desktop-linux).
- Linux Computer Use MCP server (`computer-use-linux` binary) speaking
  [rmcp](https://docs.rs/rmcp) over stdio.
- 15 MCP tools: `doctor`, `setup_accessibility`, `setup_window_targeting`,
  `list_apps`, `get_app_state`, `list_windows`, `focused_window`,
  `activate_window`, `click`, `drag`, `scroll`, `press_key`, `type_text`,
  `perform_action`, `set_value`.
- AT-SPI accessibility tree with semantic element selectors (role / name /
  text / states) for `click`, `perform_action`, and `set_value`.
- GNOME Shell window targeting via the bundled
  `computer-use-linux@avifenesh.dev` Shell extension (DBus service
  `dev.avifenesh.ComputerUseLinux.WindowControl`), with automatic fallback to
  `org.gnome.Shell.Introspect` when the extension is not installed.
- Screenshot capture through GNOME Shell DBus (preferred) and
  `org.freedesktop.portal.Screenshot` (fallback). Supports full-screen,
  per-app, per-window, region, and per-element scopes.
- Input synthesis through the Wayland remote-desktop portal when available,
  falling back to `ydotool` / `ydotoold` for keystrokes and pointer events.
- Best-effort terminal-window enrichment: maps each terminal window to its
  active TTY and foreground process for targeted `type_text` / `press_key`.
- `doctor` subcommand reporting AT-SPI bus health, GNOME Shell introspection
  status, extension status, ydotool socket readiness, and portal coverage in
  a single JSON document.

### Architecture
- Wayland-first; X11 best-effort through AT-SPI + ydotool.
- Validated against GNOME 50.1 on Wayland (Ubuntu 25.10).
- KDE / Sway / Hyprland untested — see README support matrix.

[Unreleased]: https://github.com/agent-sh/computer-use-linux/compare/v0.7.39...HEAD
[0.7.39]: https://github.com/agent-sh/computer-use-linux/compare/v0.7.38...v0.7.39
[0.7.38]: https://github.com/agent-sh/computer-use-linux/compare/v0.7.37...v0.7.38
[0.7.37]: https://github.com/agent-sh/computer-use-linux/compare/v0.7.36...v0.7.37
[0.7.36]: https://github.com/agent-sh/computer-use-linux/compare/v0.7.35...v0.7.36
[0.7.35]: https://github.com/agent-sh/computer-use-linux/compare/v0.7.34...v0.7.35
[0.7.34]: https://github.com/agent-sh/computer-use-linux/compare/v0.7.33...v0.7.34
[0.7.33]: https://github.com/agent-sh/computer-use-linux/compare/v0.7.32...v0.7.33
[0.7.32]: https://github.com/agent-sh/computer-use-linux/compare/v0.7.31...v0.7.32
[0.7.31]: https://github.com/agent-sh/computer-use-linux/compare/v0.7.30...v0.7.31
[0.7.30]: https://github.com/agent-sh/computer-use-linux/compare/v0.7.29...v0.7.30
[0.7.29]: https://github.com/agent-sh/computer-use-linux/compare/v0.7.28...v0.7.29
[0.7.28]: https://github.com/agent-sh/computer-use-linux/compare/v0.7.27...v0.7.28
[0.7.27]: https://github.com/agent-sh/computer-use-linux/compare/v0.7.26...v0.7.27
[0.7.26]: https://github.com/agent-sh/computer-use-linux/compare/v0.7.25...v0.7.26
[0.7.25]: https://github.com/agent-sh/computer-use-linux/compare/v0.7.24...v0.7.25
[0.7.24]: https://github.com/agent-sh/computer-use-linux/compare/v0.7.23...v0.7.24
[0.7.23]: https://github.com/agent-sh/computer-use-linux/compare/v0.7.22...v0.7.23
[0.7.22]: https://github.com/agent-sh/computer-use-linux/compare/v0.7.21...v0.7.22
[0.7.21]: https://github.com/agent-sh/computer-use-linux/compare/v0.7.20...v0.7.21
[0.7.20]: https://github.com/agent-sh/computer-use-linux/compare/v0.7.19...v0.7.20
[0.7.19]: https://github.com/agent-sh/computer-use-linux/compare/v0.7.18...v0.7.19
[0.7.18]: https://github.com/agent-sh/computer-use-linux/compare/v0.7.17...v0.7.18
[0.7.17]: https://github.com/agent-sh/computer-use-linux/compare/v0.7.16...v0.7.17
[0.7.16]: https://github.com/agent-sh/computer-use-linux/compare/v0.7.15...v0.7.16
[0.7.15]: https://github.com/agent-sh/computer-use-linux/compare/v0.7.14...v0.7.15
[0.7.14]: https://github.com/agent-sh/computer-use-linux/compare/v0.7.13...v0.7.14
[0.7.13]: https://github.com/agent-sh/computer-use-linux/compare/v0.7.12...v0.7.13
[0.7.12]: https://github.com/agent-sh/computer-use-linux/compare/v0.7.11...v0.7.12
[0.7.11]: https://github.com/agent-sh/computer-use-linux/compare/v0.7.10...v0.7.11
[0.7.10]: https://github.com/agent-sh/computer-use-linux/compare/v0.7.9...v0.7.10
[0.7.9]: https://github.com/agent-sh/computer-use-linux/compare/v0.7.8...v0.7.9
[0.7.8]: https://github.com/agent-sh/computer-use-linux/compare/v0.7.7...v0.7.8
[0.7.7]: https://github.com/agent-sh/computer-use-linux/compare/v0.7.6...v0.7.7
[0.7.6]: https://github.com/agent-sh/computer-use-linux/compare/v0.7.5...v0.7.6
[0.7.5]: https://github.com/agent-sh/computer-use-linux/compare/v0.7.4...v0.7.5
[0.7.4]: https://github.com/agent-sh/computer-use-linux/compare/v0.7.3...v0.7.4
[0.7.3]: https://github.com/agent-sh/computer-use-linux/compare/v0.7.2...v0.7.3
[0.7.2]: https://github.com/agent-sh/computer-use-linux/compare/v0.7.1...v0.7.2
[0.7.1]: https://github.com/agent-sh/computer-use-linux/compare/v0.7.0...v0.7.1
[0.7.0]: https://github.com/agent-sh/computer-use-linux/compare/v0.6.0...v0.7.0
[0.6.0]: https://github.com/agent-sh/computer-use-linux/compare/v0.5.0...v0.6.0
[0.5.0]: https://github.com/agent-sh/computer-use-linux/compare/v0.4.10...v0.5.0
[0.4.10]: https://github.com/agent-sh/computer-use-linux/compare/v0.4.9...v0.4.10
[0.4.9]: https://github.com/agent-sh/computer-use-linux/compare/v0.4.8...v0.4.9
[0.4.8]: https://github.com/agent-sh/computer-use-linux/compare/v0.4.7...v0.4.8
[0.4.7]: https://github.com/agent-sh/computer-use-linux/compare/v0.4.6...v0.4.7
[0.4.6]: https://github.com/agent-sh/computer-use-linux/compare/v0.4.5...v0.4.6
[0.4.5]: https://github.com/agent-sh/computer-use-linux/compare/v0.4.4...v0.4.5
[0.4.4]: https://github.com/agent-sh/computer-use-linux/compare/v0.4.3...v0.4.4
[0.4.3]: https://github.com/agent-sh/computer-use-linux/compare/v0.4.2...v0.4.3
[0.4.2]: https://github.com/agent-sh/computer-use-linux/compare/v0.4.1...v0.4.2
[0.4.1]: https://github.com/agent-sh/computer-use-linux/compare/v0.4.0...v0.4.1
[0.4.0]: https://github.com/agent-sh/computer-use-linux/compare/v0.3.1...v0.4.0
[0.3.1]: https://github.com/agent-sh/computer-use-linux/compare/v0.3.0...v0.3.1
[0.3.0]: https://github.com/agent-sh/computer-use-linux/compare/v0.2.9...v0.3.0
[0.2.9]: https://github.com/agent-sh/computer-use-linux/compare/v0.2.8...v0.2.9
[0.2.8]: https://github.com/agent-sh/computer-use-linux/compare/v0.2.7...v0.2.8
[0.2.7]: https://github.com/agent-sh/computer-use-linux/compare/v0.2.6...v0.2.7
[0.2.6]: https://github.com/agent-sh/computer-use-linux/compare/v0.2.5...v0.2.6
[0.2.5]: https://github.com/agent-sh/computer-use-linux/compare/v0.2.4...v0.2.5
[0.2.4]: https://github.com/agent-sh/computer-use-linux/compare/v0.2.3...v0.2.4
[0.2.3]: https://github.com/agent-sh/computer-use-linux/compare/v0.2.2...v0.2.3
[0.2.2]: https://github.com/agent-sh/computer-use-linux/compare/v0.2.1...v0.2.2
[0.2.1]: https://github.com/agent-sh/computer-use-linux/compare/v0.2.0...v0.2.1
[0.2.0]: https://github.com/agent-sh/computer-use-linux/releases/tag/v0.2.0
[0.1.0]: https://github.com/agent-sh/computer-use-linux/releases/tag/v0.1.0