Skip to content

Commit fcc8f06

Browse files
authored
Merge pull request #184 from Integration-Automation/dev
Profiler, run-history timeline, secrets, webhook + email triggers, embedder fixes
2 parents 2580ea5 + 7b51269 commit fcc8f06

47 files changed

Lines changed: 5463 additions & 26 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@
6464
- **LLM Action Planner** — translate a plain-language description into a validated `AC_*` action list using Claude
6565
- **Runtime Variables & Control Flow**`${var}` substitution at execution time, plus `AC_set_var` / `AC_inc_var` / `AC_if_var` / `AC_for_each` / `AC_loop` / `AC_retry` for data-driven scripts
6666
- **Remote Desktop** — stream this machine's screen and accept remote input over a token-authenticated TCP protocol, *or* connect to another machine and view + control it (host + viewer GUIs included). Optional TLS (HTTPS-grade encryption), WebSocket transport (ws:// + wss:// for browser / firewall-friendly clients), persistent 9-digit Host ID, host→viewer audio streaming, bidirectional clipboard sync (text + image), and chunked file transfer (drag-drop + progress bar; arbitrary destination path; no size cap). Plus folder sync (additive mirror — local deletions never propagate) and a self-hosted coturn TURN config bundle generator (turnserver.conf + systemd unit + docker-compose + README). **AnyDesk-style popout**: when the viewer authenticates, the live remote desktop opens in its own resizable top-level window so the control panel stays uncluttered. The Remote Desktop tabs are wrapped in `QScrollArea` so the panel stays usable on small windows and stretches edge-to-edge on 4K displays. Driveable headlessly via `je_auto_control` and over MCP through the new `ac_remote_*` tools
67+
- **Driver-level input backends (opt-in)** — for games / apps that ignore SendInput (Win) or XTest (Linux): **Interception driver backend** for Windows (HID-layer keyboard / mouse injection via Oblita's WHQL-signed driver, opt-in via `JE_AUTOCONTROL_WIN32_BACKEND=interception`), **uinput backend** for Linux (kernel `/dev/uinput` synthetic HID device, opt-in via `JE_AUTOCONTROL_LINUX_BACKEND=uinput`), and **ViGEm virtual gamepad** for Windows games that read controllers (virtual Xbox 360 pad with friendly button / dpad / stick / trigger API, exposed as `AC_gamepad_*` executor commands and `ac_gamepad_*` MCP tools). All three fall back gracefully when the driver isn't installed, so existing deployments keep working unchanged
6768
- **Clipboard** — read/write system clipboard text on Windows, macOS, and Linux
6869
- **Screenshot & Screen Recording** — capture full screen or regions as images, record screen to video (AVI/MP4)
6970
- **Action Recording & Playback** — record mouse/keyboard events and replay them

README/README_zh-CN.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@
6363
- **LLM 动作规划器** — 用 Claude 把自然语言描述翻译成验证过的 `AC_*` 动作清单
6464
- **运行期变量与流程控制** — 执行时 `${var}` 替换,加上 `AC_set_var` / `AC_inc_var` / `AC_if_var` / `AC_for_each` / `AC_loop` / `AC_retry` 让脚本数据驱动
6565
- **远程桌面** — 用 token 认证的 TCP 协议串流本机画面并接收输入,**** 连接到他机观看与控制(host + viewer GUI 内置)。可选 TLS(HTTPS 级加密)、WebSocket 传输(``ws://`` + ``wss://``,穿墙/浏览器友好)、持久化 9 位数 Host ID、host→viewer 音频串流、双向剪贴板同步(文字 + 图片)、分块文件传输(拖放 + 进度条;任意目的路径;无大小上限)。另含文件夹同步(增量镜像 — 本地删除不会传出去)与自建 coturn TURN 配置包生成器(turnserver.conf + systemd unit + docker-compose + README)。**AnyDesk 风格弹出窗口**:viewer 认证成功后远程桌面会开在独立的可调整大小顶层窗口,控制面板保持简洁;Remote Desktop 子分页外层包了 `QScrollArea`,小窗口下可滚动、4K 屏幕下会铺满。同时支持 headless API 与 MCP 工具 (`ac_remote_*`) 直接驱动
66+
- **驱动级输入后端(可选)** — 针对忽略 SendInput(Win)或 XTest(Linux)的游戏/应用:**Interception driver 后端**(Windows,HID 层鍵鼠注入,使用 Oblita WHQL-signed driver,通过 `JE_AUTOCONTROL_WIN32_BACKEND=interception` 启用)、**uinput 后端**(Linux,kernel `/dev/uinput` 合成 HID 设备,通过 `JE_AUTOCONTROL_LINUX_BACKEND=uinput` 启用),以及 **ViGEm 虚拟手柄**(Windows,针对只认手柄的游戏,提供虚拟 Xbox 360 手柄 + 友善的 button / dpad / stick / trigger API,并暴露为 `AC_gamepad_*` 执行器命令与 `ac_gamepad_*` MCP 工具)。三者在 driver 没装时都会优雅 fallback,不影响既有部署
6667
- **剪贴板** — 于 Windows / macOS / Linux 读写系统剪贴板文本
6768
- **截图与屏幕录制** — 捕获全屏或指定区域为图片,录制屏幕为视频(AVI/MP4)
6869
- **动作录制与回放** — 录制鼠标/键盘事件并重新播放

README/README_zh-TW.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@
6363
- **LLM 動作規劃器** — 用 Claude 把自然語言描述翻譯成驗證過的 `AC_*` 動作清單
6464
- **執行期變數與流程控制** — 執行時 `${var}` 取代,加上 `AC_set_var` / `AC_inc_var` / `AC_if_var` / `AC_for_each` / `AC_loop` / `AC_retry` 讓腳本資料驅動
6565
- **遠端桌面** — 用 token 認證的 TCP 協定串流本機畫面並接收輸入,**** 連線到他機觀看與控制(host + viewer GUI 皆內建)。可選 TLS(HTTPS 級加密)、WebSocket 傳輸(``ws://`` + ``wss://``,穿牆/瀏覽器友善)、持久化 9 位數 Host ID、host→viewer 音訊串流、雙向剪貼簿同步(文字 + 圖片)、分塊檔案傳輸(拖放 + 進度條;任意目的路徑;無大小上限)。另含資料夾同步(增量鏡像 — 本地刪除不會傳出去)與自架 coturn TURN 設定包產生器(turnserver.conf + systemd unit + docker-compose + README)。**AnyDesk 風格彈出視窗**:viewer 認證成功後遠端桌面會開在獨立的可調整大小頂層視窗,控制面板維持簡潔;Remote Desktop 子分頁外層包了 `QScrollArea`,小視窗下可捲動、4K 螢幕下會延展到整寬。同時可由 headless API 與 MCP 工具(`ac_remote_*`)直接驅動
66+
- **驅動層輸入後端(可選)** — 針對忽略 SendInput(Win)或 XTest(Linux)的遊戲/應用:**Interception driver 後端**(Windows,HID 層鍵鼠注入,使用 Oblita WHQL-signed driver,以 `JE_AUTOCONTROL_WIN32_BACKEND=interception` 啟用)、**uinput 後端**(Linux,kernel `/dev/uinput` 合成 HID 裝置,以 `JE_AUTOCONTROL_LINUX_BACKEND=uinput` 啟用),以及 **ViGEm 虛擬手把**(Windows,針對只認手把的遊戲,提供虛擬 Xbox 360 手把 + 友善的 button / dpad / stick / trigger API,並暴露為 `AC_gamepad_*` 執行器指令與 `ac_gamepad_*` MCP 工具)。三者在 driver 沒裝時都會優雅 fallback,不影響既有部署
6667
- **剪貼簿** — 於 Windows / macOS / Linux 讀寫系統剪貼簿文字
6768
- **截圖與螢幕錄製** — 擷取全螢幕或指定區域為圖片,錄製螢幕為影片(AVI/MP4)
6869
- **動作錄製與回放** — 錄製滑鼠/鍵盤事件並重新播放

docs/source/Eng/doc/new_features/new_features_doc.rst

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -790,3 +790,123 @@ The status / observer tools (``ac_remote_host_status``,
790790
server's ``--readonly`` filter; everything that mutates state is
791791
correctly tagged ``destructiveHint: true`` so MCP clients can
792792
prompt for user confirmation.
793+
794+
795+
Driver-level input backends — drive games that ignore SendInput / XTest
796+
========================================================================
797+
798+
The default Windows (SendInput) and Linux (XTest) input paths sit at
799+
the user-mode / X-server layer. Modern games that read input via
800+
``GetRawInputData`` (Win) or ``evdev`` (Linux) skip those layers
801+
entirely and ignore synthetic events. Three optional backends bridge
802+
the gap.
803+
804+
Interception (Windows)
805+
----------------------
806+
807+
Oblita's WHQL-signed Interception driver
808+
(https://github.com/oblitum/Interception) injects keyboard / mouse
809+
events at the HID layer; the OS sees them as real-hardware events.
810+
811+
* New sub-package: ``je_auto_control/windows/interception/``
812+
(``_dll.py`` ctypes bindings + ``keyboard.py`` + ``mouse.py``).
813+
* Same public surface as ``win32_ctype_keyboard_control`` /
814+
``win32_ctype_mouse_control`` — the platform wrapper just swaps
815+
modules, no caller changes.
816+
* Opt-in via ``JE_AUTOCONTROL_WIN32_BACKEND=interception``; the
817+
wrapper falls back to SendInput with a warning when the driver is
818+
missing, so deployments can roll the driver out lazily.
819+
* Override device IDs with ``JE_AUTOCONTROL_INTERCEPTION_KEYBOARD``
820+
/ ``JE_AUTOCONTROL_INTERCEPTION_MOUSE`` (defaults: ``1`` / ``11``).
821+
822+
Operator setup::
823+
824+
# 1. Install the driver as Administrator (one-time, requires reboot)
825+
install-interception.exe /install
826+
827+
# 2. Tell AutoControl to route through it
828+
setx JE_AUTOCONTROL_WIN32_BACKEND interception
829+
830+
uinput (Linux)
831+
--------------
832+
833+
The kernel's synthetic-input gateway. Events emitted via
834+
``/dev/uinput`` show up as a brand-new HID device, so anything reading
835+
``evdev`` (most games + SDL2 apps) sees them as real input.
836+
837+
* New sub-package: ``je_auto_control/linux_with_x11/uinput/``
838+
(``_device.py`` ctypes wrapper around ``ioctl`` + ``keyboard.py`` +
839+
``mouse.py``).
840+
* No third-party dependency — direct ``ctypes`` + ``ioctl`` to
841+
``/dev/uinput``.
842+
* Opt-in via ``JE_AUTOCONTROL_LINUX_BACKEND=uinput``; falls back to
843+
XTest with a warning when ``/dev/uinput`` isn't writable.
844+
845+
Operator setup::
846+
847+
# Load the kernel module if it isn't already.
848+
sudo modprobe uinput
849+
850+
# Grant write access. For one-off testing:
851+
sudo chmod 666 /dev/uinput
852+
853+
# For persistent provisioning, drop a udev rule:
854+
echo 'KERNEL=="uinput", GROUP="input", MODE="0660"' \
855+
| sudo tee /etc/udev/rules.d/99-autocontrol-uinput.rules
856+
sudo udevadm control --reload && sudo udevadm trigger
857+
sudo usermod -aG input $USER # log out / back in to apply
858+
859+
# Then opt in:
860+
export JE_AUTOCONTROL_LINUX_BACKEND=uinput
861+
862+
ViGEm virtual gamepad (Windows)
863+
-------------------------------
864+
865+
For games that don't take keyboard input at all but read controllers,
866+
ViGEmBus exposes a virtual Xbox 360 / DualShock 4 controller that
867+
AutoControl drives through the third-party ``vgamepad`` Python
868+
package.
869+
870+
* New module: ``je_auto_control/utils/gamepad/`` with a friendly
871+
``VirtualGamepad`` API (string-keyed buttons / dpad / sticks /
872+
triggers, context manager).
873+
* Headless::
874+
875+
from je_auto_control import VirtualGamepad
876+
with VirtualGamepad() as pad:
877+
pad.click_button("a") # face button A
878+
pad.set_left_stick(16000, 0) # int16 stick offsets
879+
pad.set_right_trigger(255) # 0..255 pressure
880+
pad.set_dpad("up") # hold dpad up
881+
pad.update() # flush → driver
882+
883+
* Executor commands: ``AC_gamepad_press``, ``AC_gamepad_release``,
884+
``AC_gamepad_click``, ``AC_gamepad_dpad``,
885+
``AC_gamepad_left_stick`` / ``_right_stick``,
886+
``AC_gamepad_left_trigger`` / ``_right_trigger``, and
887+
``AC_gamepad_reset``.
888+
889+
* MCP tools: same names with the ``ac_`` prefix
890+
(``ac_gamepad_press``, ``ac_gamepad_left_stick``, …) — so a model
891+
can play a gamepad-only game over MCP.
892+
893+
Operator setup::
894+
895+
# 1. Install the ViGEmBus driver (one-time, requires reboot)
896+
# https://github.com/nefarius/ViGEmBus/releases
897+
# 2. Install the Python wrapper:
898+
pip install vgamepad
899+
900+
Anti-cheat caveat (all three)
901+
-----------------------------
902+
903+
Driver-level injection is harder to detect than SendInput / XTest,
904+
but anti-cheat systems with a kernel-mode driver of their own
905+
(Vanguard, Easy Anti-Cheat with kernel module, BattlEye) can still
906+
enumerate Interception / ViGEmBus / a freshly-created uinput device
907+
and refuse to launch.
908+
909+
These backends target legitimate use cases — accessibility software,
910+
GUI testing of games that lock out user-mode input, controlling a
911+
remote game-running machine from a headless setup — and aren't a
912+
generic anti-cheat bypass.

docs/source/Zh/doc/new_features/new_features_doc.rst

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -739,3 +739,118 @@ registry 包成工具,工廠函式為
739739
``ac_remote_viewer_status``)為唯讀,可以通過 MCP server 的
740740
``--readonly`` 過濾;會修改狀態的工具都正確帶上
741741
``destructiveHint: true``,MCP client 端可以據此跳出使用者確認。
742+
743+
744+
驅動層輸入後端 — 驅動不接受 SendInput / XTest 的遊戲
745+
=====================================================
746+
747+
預設的 Windows(SendInput)與 Linux(XTest)輸入路徑落在 user-mode
748+
/ X-server 那一層;會用 ``GetRawInputData``(Win)或 ``evdev``
749+
(Linux)直接讀 raw input 的遊戲會跳過這些層,完全忽略合成事件。
750+
新增三個可選的後端可以解決這個問題。
751+
752+
Interception(Windows)
753+
------------------------
754+
755+
Oblita 的 WHQL-signed Interception driver
756+
(https://github.com/oblitum/Interception)在 HID 層注入鍵鼠事件,
757+
OS 看到的就是「真實裝置」事件。
758+
759+
* 新增子套件:``je_auto_control/windows/interception/``
760+
(``_dll.py`` ctypes bindings + ``keyboard.py`` + ``mouse.py``)。
761+
* 與 ``win32_ctype_keyboard_control`` /
762+
``win32_ctype_mouse_control`` 公開介面完全一致 — wrapper 在啟動
763+
時直接換模組,呼叫端不需要任何修改。
764+
* 透過 ``JE_AUTOCONTROL_WIN32_BACKEND=interception`` 啟用;若
765+
driver 沒裝,wrapper 會打 warning 並回到 SendInput,所以可以分
766+
階段佈署。
767+
* 用 ``JE_AUTOCONTROL_INTERCEPTION_KEYBOARD`` /
768+
``JE_AUTOCONTROL_INTERCEPTION_MOUSE`` 覆寫 device id(預設
769+
``1`` / ``11``)。
770+
771+
操作步驟::
772+
773+
# 1. 以系統管理員身份安裝 driver(一次性,需要重開機)
774+
install-interception.exe /install
775+
776+
# 2. 告訴 AutoControl 走這條路
777+
setx JE_AUTOCONTROL_WIN32_BACKEND interception
778+
779+
uinput(Linux)
780+
----------------
781+
782+
kernel 自帶的合成輸入閘道。透過 ``/dev/uinput`` 送出的事件會被
783+
建立成一個全新的 HID 裝置,任何讀 ``evdev`` 的程式(包含大部分
784+
遊戲與 SDL2 app)都會視為真實輸入。
785+
786+
* 新增子套件:``je_auto_control/linux_with_x11/uinput/``
787+
(``_device.py`` 直接用 ctypes + ioctl 包 ``/dev/uinput`` +
788+
``keyboard.py`` + ``mouse.py``)。
789+
* 無第三方依賴 — 全程 ctypes + ioctl。
790+
* 透過 ``JE_AUTOCONTROL_LINUX_BACKEND=uinput`` 啟用;若
791+
``/dev/uinput`` 沒寫入權限,會 warning 後回退到 XTest。
792+
793+
操作步驟::
794+
795+
# 載入 kernel module
796+
sudo modprobe uinput
797+
798+
# 一次性測試:直接放寬權限
799+
sudo chmod 666 /dev/uinput
800+
801+
# 持續性權限,寫一個 udev rule:
802+
echo 'KERNEL=="uinput", GROUP="input", MODE="0660"' \
803+
| sudo tee /etc/udev/rules.d/99-autocontrol-uinput.rules
804+
sudo udevadm control --reload && sudo udevadm trigger
805+
sudo usermod -aG input $USER # 重新登入後生效
806+
807+
# 啟用後端
808+
export JE_AUTOCONTROL_LINUX_BACKEND=uinput
809+
810+
ViGEm 虛擬手把(Windows)
811+
-------------------------
812+
813+
針對「完全不吃鍵鼠、只認手把」的遊戲,可以用 ViGEmBus 建立一個虛
814+
擬 Xbox 360 / DualShock 4 控制器;AutoControl 透過第三方 ``vgamepad``
815+
套件來驅動它。
816+
817+
* 新增模組:``je_auto_control/utils/gamepad/`` 提供友善的
818+
``VirtualGamepad`` API(字串名稱的 button / dpad / stick /
819+
trigger,支援 context manager)。
820+
* Headless::
821+
822+
from je_auto_control import VirtualGamepad
823+
with VirtualGamepad() as pad:
824+
pad.click_button("a") # A 鍵
825+
pad.set_left_stick(16000, 0) # int16 stick 偏移
826+
pad.set_right_trigger(255) # 0..255 力度
827+
pad.set_dpad("up") # 按住方向鍵上
828+
pad.update() # 把狀態 flush 給 driver
829+
830+
* Executor 指令:``AC_gamepad_press``、``AC_gamepad_release``、
831+
``AC_gamepad_click``、``AC_gamepad_dpad``、
832+
``AC_gamepad_left_stick`` / ``_right_stick``、
833+
``AC_gamepad_left_trigger`` / ``_right_trigger``,以及
834+
``AC_gamepad_reset``。
835+
836+
* MCP 工具:同名加上 ``ac_`` 前綴(``ac_gamepad_press``、
837+
``ac_gamepad_left_stick`` …),所以模型可以透過 MCP 玩只支援
838+
手把的遊戲。
839+
840+
操作步驟::
841+
842+
# 1. 安裝 ViGEmBus driver(一次性,需要重開機)
843+
# https://github.com/nefarius/ViGEmBus/releases
844+
# 2. 安裝 Python wrapper:
845+
pip install vgamepad
846+
847+
反作弊注意事項
848+
---------------
849+
850+
驅動層注入比 SendInput / XTest 更難偵測,但帶 kernel-mode driver
851+
的反作弊(Vanguard、有 kernel module 的 Easy Anti-Cheat、
852+
BattlEye)依然可以列舉 Interception / ViGEmBus / 新建立的 uinput
853+
裝置然後拒絕啟動。
854+
855+
這三個後端針對的是合法用途 — 輔助科技、遊戲 GUI 測試、從 headless
856+
環境控制執行遊戲的遠端機器 — **不是** 通用反作弊繞過工具。

je_auto_control/__init__.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,11 @@
7878
from je_auto_control.utils.remote_desktop.registry import (
7979
registry as remote_desktop_registry,
8080
)
81+
from je_auto_control.utils.gamepad import (
82+
GamepadUnavailable, VirtualGamepad,
83+
default_gamepad as default_virtual_gamepad,
84+
is_available as is_virtual_gamepad_available,
85+
)
8186
# MCP server (headless stdio bridge for Claude / other MCP clients)
8287
from je_auto_control.utils.mcp_server import (
8388
AuditLogger, HttpMCPServer, MCPContent, MCPPrompt, MCPPromptArgument,
@@ -122,6 +127,15 @@
122127
ConfigBundleExporter, ConfigBundleImporter, ImportReport,
123128
export_config_bundle, import_config_bundle,
124129
)
130+
# Profiler (headless)
131+
from je_auto_control.utils.profiler import (
132+
ActionProfiler, ActionStats, default_profiler,
133+
)
134+
# Secrets (headless)
135+
from je_auto_control.utils.secrets import (
136+
SecretManager, SecretStoreError, SecretStoreLocked,
137+
default_secret_manager, default_secret_store_path,
138+
)
125139
# Run history (headless)
126140
from je_auto_control.utils.run_history.history_store import (
127141
HistoryStore, RunRecord, default_history_store,
@@ -131,6 +145,12 @@
131145
FilePathTrigger, ImageAppearsTrigger, PixelColorTrigger, TriggerEngine,
132146
WindowAppearsTrigger, default_trigger_engine,
133147
)
148+
from je_auto_control.utils.triggers.webhook_server import (
149+
WebhookTrigger, WebhookTriggerServer, default_webhook_server,
150+
)
151+
from je_auto_control.utils.triggers.email_trigger import (
152+
EmailTrigger, EmailTriggerWatcher, default_email_trigger_watcher,
153+
)
134154
# Recording editor (headless helpers)
135155
from je_auto_control.utils.recording_edit.editor import (
136156
adjust_delays, filter_actions, insert_action, remove_action,
@@ -297,6 +317,14 @@ def start_autocontrol_gui(*args, **kwargs):
297317
"TriggerEngine", "default_trigger_engine",
298318
"ImageAppearsTrigger", "WindowAppearsTrigger",
299319
"PixelColorTrigger", "FilePathTrigger",
320+
"WebhookTrigger", "WebhookTriggerServer", "default_webhook_server",
321+
"EmailTrigger", "EmailTriggerWatcher",
322+
"default_email_trigger_watcher",
323+
# Profiler
324+
"ActionProfiler", "ActionStats", "default_profiler",
325+
# Secret manager
326+
"SecretManager", "SecretStoreError", "SecretStoreLocked",
327+
"default_secret_manager", "default_secret_store_path",
300328
# Run history
301329
"HistoryStore", "RunRecord", "default_history_store",
302330
# Accessibility
@@ -312,6 +340,9 @@ def start_autocontrol_gui(*args, **kwargs):
312340
"RemoteDesktopHost", "RemoteDesktopViewer",
313341
"RemoteDesktopAuthError", "RemoteDesktopInputError",
314342
"RemoteDesktopProtocolError", "remote_desktop_registry",
343+
# Virtual gamepad (ViGEm)
344+
"VirtualGamepad", "GamepadUnavailable",
345+
"default_virtual_gamepad", "is_virtual_gamepad_available",
315346
"generate_html", "generate_html_report", "generate_json", "generate_json_report", "generate_xml",
316347
"generate_xml_report", "get_dir_files_as_list", "create_project_dir", "start_autocontrol_socket_server",
317348
"callback_executor", "package_manager", "ShellManager", "default_shell_manager",

0 commit comments

Comments
 (0)