@@ -15,6 +15,38 @@ it shipped into a `## [x.y.z] - date` section of their own; the tag's
1515
1616### Added
1717
18+ - Action files can be signed with an Ed25519 key pair, so an endpoint that
19+ verifies does not hold what signs: `create_signing_keypair(private_path,
20+ public_path)` / ` AC_create_signing_keypair` , ` private_key_path=` on
21+ ` sign_action_file ` , ` public_key_path= ` on ` verify_action_file ` , and the
22+ environment variables ` JE_AUTOCONTROL_ACTION_SIGNING_PRIVATE_KEY ` ,
23+ ` JE_AUTOCONTROL_ACTION_SIGNING_PUBLIC_KEY ` and
24+ ` JE_AUTOCONTROL_ACCEPT_LEGACY_ACTION_SIGNATURES ` . Nothing changes while none
25+ of them is set. ` CryptographyUnavailableError ` (an ` AutoControlException ` and
26+ a ` RuntimeError ` ) replaces the bare ` RuntimeError ` raised without the
27+ ` cryptography ` package.
28+ - Opt-in roles for the REST API and the MCP HTTP transport:
29+ ` JE_AUTOCONTROL_RBAC_USERS=<user store file> ` (or ` user_store= ` , or ` --users `
30+ on the REST entry points). A bearer token then names a user, each route,
31+ tool and privileged ` AC_* ` command needs a capability of that user's role,
32+ and audit entries carry the user id. ` UserStore ` , ` UserRecord ` ,
33+ ` AuthorizationContext ` , ` AuthorizationError ` , ` UserAuthError ` and
34+ ` authorization_scope ` are exported; ` Capability.SIGN_ACTIONS ` is new.
35+ - Opt-in confinement of MCP file arguments: ` JE_AUTOCONTROL_MCP_PATH_ROOTS ` ,
36+ ` JE_AUTOCONTROL_MCP_PATH_ROOTS_FROM_CLIENT ` and, for ` env:// ` references,
37+ ` JE_AUTOCONTROL_MCP_ENV_REF_ALLOW ` . Tool schemas mark file-path arguments
38+ with ` "format": "path" ` . ` PathPolicy ` and ` PathNotAllowedError ` are exported.
39+ - ` execution_scope(variables=None) ` : a fresh variable scope for a block of
40+ runs.
41+ - ` JE_AUTOCONTROL_ALLOWED_PACKAGES ` and `je_auto_control run --allow-package
42+ NAME` allow packages at the package gate without Python glue.
43+ - USB passthrough requests carry an optional ` request_id ` that a current host
44+ echoes; ` UsbClientDesynchronized ` , ` ClientHandle.reusable ` ,
45+ ` UsbPassthroughClient.reusable ` .
46+ - ` remote_desktop_registry ` records who opened each host and viewer
47+ (` adopt ` , ` evict ` , ` release ` , ` owner_of ` , ` owned ` ; ` owner= ` on the stop and
48+ disconnect methods), and every ` *_status ` result gains an ` "owner" ` key.
49+ - ` mark_screen ` returns ` image_origin ` ; ` render_marks(..., origin=) ` .
1850- GUI: a navigation panel on the left of the main window lists every tab by
1951 category, with a search box (` Ctrl+K ` ; ` Ctrl+B ` hides the panel).
2052 ` AutoControlGUIWidget.activate_tab(key) ` opens a tab or brings it to the
@@ -93,8 +125,8 @@ it shipped into a `## [x.y.z] - date` section of their own; the tag's
93125 in one call: the clicks land on one point, ` interval ` seconds apart.
94126 Defaults keep the single click, and a single click records the same
95127 action as before. ` AC_click_mouse ` , the ` ac_click_mouse ` MCP tool and the
96- Script Builder take both parameters. On macOS the clicks still arrive as
97- separate single clicks ( ` Progress.md ` ).
128+ Script Builder take both parameters. On macOS the n-th click sets the
129+ click-state field (unverified on hardware, ` Progress.md ` ).
98130- ** Drag pacing: ` tween_drag ` / ` drag_path ` take ` step_delay_s ` and
99131 ` settle_s ` ** (seconds, default 0). ` step_delay_s ` rests after each move;
100132 ` settle_s ` rests on the start before the press, after the press and before
@@ -161,6 +193,84 @@ it shipped into a `## [x.y.z] - date` section of their own; the tag's
161193
162194### Changed
163195
196+ - ** Breaking: the package gate refuses by default.**
197+ ` AC_add_package_to_executor ` / ` AC_add_package_to_callback_executor ` (and
198+ the ` package_manager ` methods) no longer import a package that has not been
199+ allowed; the ` DeprecationWarning ` release is over. Allow with
200+ ` executor.allow_packages(...) ` , ` JE_AUTOCONTROL_ALLOWED_PACKAGES ` or
201+ ` --allow-package ` ; ` executor.set_allow_arbitrary_packages(True) ` restores
202+ the old behaviour. ` allow_packages ` now rejects a name that is not a dotted
203+ module name.
204+ - ** Breaking: a file a remote-desktop host pushes lands below the viewer's
205+ download directory.** ` host.send_file_to_viewers(src, dest_path) ` :
206+ ` dest_path ` is now relative to ` ~/Downloads/AutoControl `
207+ (` JE_AUTOCONTROL_REMOTE_DOWNLOAD_DIR ` ); an absolute path, a drive or UNC
208+ path, ` .. ` or a link leading outside fails the transfer. Viewer → host is
209+ unchanged, and ` FileReceiver() ` without ` base_dir ` is unconfined as before.
210+ - ** Variables no longer survive a run.** ` execute_action_with_vars ` , REST
211+ ` /execute ` and ` /execute_file ` , every MCP tool call, each socket command,
212+ scheduler jobs, trigger / hotkey / webhook / e-mail firings, ChatOps ` /run `
213+ and voice commands each get a fresh variable scope; a later ` ${name} ` fails
214+ with ` Unknown variable ` instead of reading the previous caller's value.
215+ Direct ` executor.execute_action(...) ` from Python keeps the process scope.
216+ An ` AC_parallel ` branch starts with a copy of the caller's variables, and
217+ ` AC_run_dag ` local nodes run on the calling list's executor and scope.
218+ - ** Windows is per-monitor DPI aware.** Importing the package asks for
219+ per-monitor v2 (falling back to system awareness). On a monitor whose scale
220+ differs from the primary's, coordinates and capture sizes are now physical
221+ pixels: a point at an offset from that monitor's corner moves by
222+ ` its scale / primary scale ` , and its screenshots are no longer downscaled.
223+ Coordinates, regions, window layouts and templates recorded on such a
224+ monitor have to be recorded again; the primary monitor is unaffected.
225+ - ** Keyboard input on Windows and X11.** ` write("Hi") ` types ` Hi ` (it typed
226+ ` hi ` ); ` is_shift=True ` is honoured by ` type_keyboard ` , ` hotkey ` , ` write ` and
227+ ` press_keyboard_key ` ; CR LF is one Enter; ` write_secret ` and the Unicode
228+ typing helpers press Return / Tab / Backspace as keys instead of sending
229+ them as code points.
230+ - ** ` mouse_scroll ` defaults to ` scroll_direction="scroll_up" ` ** , so a positive
231+ amount scrolls up on every platform; on X11 / Wayland it used to scroll
232+ down. NaN, infinite and non-numeric coordinates raise before anything moves,
233+ and fractional coordinates are rounded rather than truncated.
234+ - ** Window management on Windows.** ` focus_window ` raises
235+ ` AutoControlActionException ` when the window did not become the foreground
236+ one; ` show_window_by_title ` and the z-order calls return the real result;
237+ ` list_windows ` / ` find_window ` skip DWM-cloaked and zero-area windows;
238+ ` post_key ` sends one ` WM_CHAR ` for a printable character (pass the integer
239+ virtual-key code to get key messages) and ` post_key_to_window ` accepts
240+ ` "enter" ` / ` "esc" ` ; ` save_window_layout ` stores the rectangle ` MoveWindow `
241+ positions (re-save older layout files); snap / grid / cascade use the work
242+ area; ` wait_for_window ` never sleeps past its timeout.
243+ - Screenshots of a region on Windows (` pil_screenshot ` , ` screenshot ` ,
244+ ` AC_screenshot ` , ` keyword_screenshot ` , ` capture_window ` ) capture any
245+ monitor instead of returning black outside the primary one; a region
246+ entirely off every monitor raises ` AutoControlScreenException ` .
247+ ` grab_logical ` clips a region to the desktop and returns the clipped
248+ origin, and set-of-marks renders the whole virtual desktop.
249+ - macOS: ` click_mouse(clicks=n) ` sets the click-state field on the n-th
250+ click's events, ` list_windows ` includes minimised windows and ` restore `
251+ finds them, and ` grab_logical ` works in points across every display. None
252+ of this has been run on a Mac yet (` Progress.md ` ).
253+ - With an Ed25519 key configured, a legacy HMAC signature is refused unless
254+ ` JE_AUTOCONTROL_ACCEPT_LEGACY_ACTION_SIGNATURES ` is set, and an endpoint
255+ holding only the public key refuses ` AC_sign_action_file ` .
256+ - A remote-desktop panel reads, drives and disconnects only the session it
257+ opened; a panel whose session is replaced closes its window. Starting a
258+ host no longer disconnects a viewer.
259+ - The Anthropic agent backends no longer rewrite turns they have sent: past
260+ three screenshots the conversation restarts from a summary of the goal and
261+ the actions so far plus the latest screenshot.
262+ - The ` pytest11 ` entry point is the top-level module ` je_auto_control_pytest ` ,
263+ which imports only pytest; ` je_auto_control.utils.pytest_plugin ` re-exports
264+ it. Reinstall for the new entry point to take effect.
265+ - ` cryptography>=50.0.0 ` (was ` >=48.0.1 ` ). There is no ` macosx_10_9_x86_64 `
266+ wheel at that floor, so an Intel Mac builds it from source.
267+ - Image and OCR: templates load from non-ASCII paths and may be grayscale; an
268+ unreadable or unsupported template raises ` ImageNotFoundException ` ;
269+ ` find_spans ` finds a phrase that starts inside a long box; the centre of a
270+ box with negative coordinates is floored.
271+ - ` keyboard_layout ` reports ` None ` for a Shift half that prints no single
272+ character and labels ISO / UK / ABNT keys; a clipboard format named ` None `
273+ normalises to ` "" ` .
164274- GUI tabs are built the first time they are opened. ` AutoControlGUIWidget `
165275 registers all 48 tabs from ` gui/tab_registry.py ` but constructs only the
166276 three it opens on and its own forms; ` list_registered_tabs() ` builds
0 commit comments