pctr 0.3.4__tar.gz → 0.4.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2026 Space-lab515
3
+ Copyright (c) 2026 NTUserDev
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
@@ -1,12 +1,12 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pctr
3
- Version: 0.3.4
4
- Summary: Element-based Windows UI Automation CLI for AI agents. Find controls by name/type/id and click, type, hold, drag, and screenshot - no pixel coordinates.
5
- Author: Space-lab515
3
+ Version: 0.4.0
4
+ Summary: PCTR - Personal Computer Tactile Response. Element-based Windows UI Automation CLI for AI agents. Find controls by name/type/id and click, type, hold, drag, and screenshot - no pixel coordinates.
5
+ Author: NTUserDev
6
6
  License-Expression: MIT
7
- Project-URL: Homepage, https://github.com/Space-lab515/pctr
8
- Project-URL: Repository, https://github.com/Space-lab515/pctr
9
- Project-URL: Issues, https://github.com/Space-lab515/pctr/issues
7
+ Project-URL: Homepage, https://github.com/NTUserDev/pctr
8
+ Project-URL: Repository, https://github.com/NTUserDev/pctr
9
+ Project-URL: Issues, https://github.com/NTUserDev/pctr/issues
10
10
  Keywords: automation,windows,uia,pywinauto,desktop,agent,computer-use,rpa
11
11
  Classifier: Development Status :: 4 - Beta
12
12
  Classifier: Environment :: Win32 (MS Windows)
@@ -31,10 +31,18 @@ Provides-Extra: vision
31
31
  Requires-Dist: ultralytics>=8.2; extra == "vision"
32
32
  Provides-Extra: mcp
33
33
  Requires-Dist: mcp>=2; extra == "mcp"
34
+ Provides-Extra: pad
35
+ Requires-Dist: vgamepad>=0.1.0; extra == "pad"
36
+ Provides-Extra: serial
37
+ Requires-Dist: pyserial>=3.5; extra == "serial"
38
+ Provides-Extra: all
39
+ Requires-Dist: pctr[mcp,pad,serial,vision]; extra == "all"
34
40
  Dynamic: license-file
35
41
 
36
42
  # pctr
37
43
 
44
+ **PCTR — Personal Computer Tactile Response**
45
+
38
46
  Element-based Windows UI Automation CLI for AI agents.
39
47
 
40
48
  Instead of screenshotting and guessing pixel coordinates, `pctr` finds controls
@@ -46,11 +54,21 @@ mouse and keyboard input. On top of UIA it also offers **OCR**
46
54
  (`Windows.Media.Ocr`) and **YOLO-World** open-vocabulary detection for text and
47
55
  objects that aren't exposed as controls.
48
56
 
57
+ ![pctr driving by element name: enumerating windows, mapping virtual desktops, dumping the control tree, filling a field, then reading it back with OCR](docs/demo.gif)
58
+
59
+ *Driven entirely by pctr itself - list windows, map virtual desktops, dump a
60
+ control tree, `set` a field, read it back with OCR, screenshot it, and YOLO-World
61
+ detect. Recorded with OBS, which pctr also piloted.*
62
+
49
63
  ## Install
50
64
 
51
65
  ```bash
52
- pip install pctr
53
- pip install "pctr[vision]" # adds ultralytics for `pctr look`
66
+ pip install pctr # core (UIA + OCR)
67
+ pip install "pctr[vision]" # + ultralytics, for `pctr look`
68
+ pip install "pctr[mcp]" # + MCP SDK, for the MCP server
69
+ pip install "pctr[pad]" # + vgamepad, for `pctr pad` (needs ViGEmBus)
70
+ pip install "pctr[serial]" # + pyserial, for `pctr hid` / the serial-hid backend
71
+ pip install "pctr[all]" # everything
54
72
  ```
55
73
 
56
74
  Windows only.
@@ -77,6 +95,18 @@ Tools exposed: `pctr_windows`, `pctr_tree`, `pctr_find`, `pctr_click`,
77
95
  `pctr_shot`, `pctr_ocr`, `pctr_ocrfind`, `pctr_ocrclick`, `pctr_look`,
78
96
  `pctr_desktop`.
79
97
 
98
+ Or run/manage it from the CLI:
99
+
100
+ ```bash
101
+ pctr mcp status # SDK + server state
102
+ pctr mcp start --transport streamable-http --port 8765 # background HTTP server
103
+ pctr mcp restart | pctr mcp stop
104
+ pctr mcp help
105
+ ```
106
+
107
+ `stdio` runs in the foreground (what a client spawns); `sse` / `streamable-http`
108
+ run in the background, reachable at `http://127.0.0.1:8765/mcp` (or `…/sse`).
109
+
80
110
  ## Commands
81
111
 
82
112
  | Command | What it does |
@@ -97,13 +127,19 @@ Tools exposed: `pctr_windows`, `pctr_tree`, `pctr_find`, `pctr_click`,
97
127
  | `pctr move --x N --y N` / `down` / `up` / `hold --ms N` | Raw mouse control (`--direct` for games). |
98
128
  | `pctr drag --start x,y --end x,y [--duration S]` | Drag between two points. |
99
129
  | `pctr keydown / keyup --key a` / `keyhold --key w --ms 1500` | Hold keyboard keys (`--direct` for games). |
100
- | `pctr ocr [--title RE]` | OCR the screen/window; list words with boxes. |
101
- | `pctr ocrfind --text RE` | OCR then list matches with click centers (single words). |
102
- | `pctr ocrclick --text RE [--nth N]` | OCR then click a word. |
130
+ | `pctr ocr [--title RE] [--lang TAG]` | OCR the screen/window; list words with boxes. |
131
+ | `pctr ocrfind --text RE [--lang TAG]` | OCR then list matches with click centers (single words). |
132
+ | `pctr ocrclick --text RE [--nth N] [--lang TAG]` | OCR then click a word. |
103
133
  | `pctr look --for "a dog" [--title RE] [--conf X]` | YOLO-World detect objects by text prompt. |
104
134
  | `pctr lookclick --for "a dog" [--nth N]` | Detect then click the top match. |
135
+ | `pctr pad <button\|stick\|trigger\|status>` | Virtual Xbox 360 gamepad via ViGEmBus. |
136
+ | `pctr hid <action> --port COMx` | Serial-HID bridge to a real USB-HID microcontroller. |
137
+ | `pctr mcp <start\|stop\|restart\|status\|help>` | Manage the MCP server (stdio or background http/sse). |
105
138
  | `pctr skill [--install]` / `pctr setup` | Print/install the agent skill + an AGENTS.md section. |
106
139
 
140
+ Global flags: `--json` (machine-readable output) and `--file FILE` (run a batch
141
+ of commands from a file).
142
+
107
143
  Common filters: `--title` (regex), `--name` (regex), `--control-type`
108
144
  (`Button`, `Edit`, `Pane`, `MenuItem`, …), `--auto-id`, `--nth`, `--process`.
109
145
 
@@ -118,6 +154,33 @@ pctr click --title "Notepad" --name "^File$"
118
154
  pctr set --title "Notepad" --name "Text Editor" --text "hello"
119
155
  ```
120
156
 
157
+ ## JSON output
158
+
159
+ Add `--json` (global, or per-command) for machine-readable output from
160
+ `windows`, `tree`, `find`, `ocr`, `ocrfind`, `look`, and `desktop`:
161
+
162
+ ```bash
163
+ pctr windows --json
164
+ # [{"hwnd":1234,"pid":5678,"title":"Untitled - Notepad"}, ...]
165
+
166
+ pctr desktop list --json
167
+ # [{"index":0,"guid":"ae37…","current":true,"windows":11}, ...]
168
+
169
+ pctr look --for "a car" --json
170
+ # [{"label":"a car","conf":0.86,"x":512,"y":300,"box":[400,220,620,380]}, ...]
171
+ ```
172
+
173
+ Progress and warnings go to stderr, so stdout stays valid JSON.
174
+
175
+ ## Batch files
176
+
177
+ ```bash
178
+ pctr --file script.txt # one command per line; # comments and blanks skipped
179
+ pctr --json --file script.txt # --json applies to every line
180
+ ```
181
+
182
+ Stops on the first failing line and reports its line number.
183
+
121
184
  ## Virtual desktops
122
185
 
123
186
  ```bash
@@ -137,6 +200,49 @@ pctr desktop move-window --title RE --to N
137
200
  - **`move-window` is blocked on Windows 11** (third-party `MoveWindowToDesktop`
138
201
  returns `Access denied`); it works on Windows 10.
139
202
 
203
+ ## Raw input backends
204
+
205
+ The OS flags `SendInput` events as injected, so anything built on user32 is
206
+ detectable in principle. `pctr` can route raw mouse/keyboard through a different
207
+ backend with `--backend`:
208
+
209
+ | Backend | How | Detectable? |
210
+ |---|---|---|
211
+ | `pyautogui` (default / `sendinput`) | user32 `SendInput`, virtual keys | yes (`injected` flag) |
212
+ | `pydirectinput` (or `--direct`) | `SendInput` with **scancodes** — better for DirectInput games | yes |
213
+ | `serial-hid` | a **microcontroller presenting real USB HID** over serial | no — it *is* real hardware |
214
+
215
+ ```bash
216
+ pctr move --backend pydirectinput --x 800 --y 400
217
+ pctr keyhold --key w --ms 400 --backend pydirectinput
218
+ pctr type --text "hi" --backend serial-hid --port COM5 # needs a board
219
+ ```
220
+
221
+ Applies to `move` / `down` / `up` / `hold` / `keydown` / `keyup` / `keyhold` /
222
+ `hotkey` / `drag` / `type` / `desktop`.
223
+
224
+ ### Gamepad
225
+
226
+ ```bash
227
+ pip install "pctr[pad]" # + the ViGEmBus driver
228
+ pctr pad button --name A --ms 150
229
+ pctr pad button --name DPAD_UP --ms 100
230
+ pctr pad stick --x 1.0 --y -0.5 --ms 400
231
+ pctr pad trigger --right 1.0 --ms 300
232
+ ```
233
+
234
+ ### Serial-HID bridge
235
+
236
+ Firmware protocol, newline-terminated ASCII:
237
+ `MOVE x y` · `CLICK b` · `DOWN b` · `UP b` · `KEY k DOWN|UP` · `WRITE text` · `HOTKEY a+b`
238
+
239
+ ```bash
240
+ pip install "pctr[serial]"
241
+ pctr hid ports # list COM ports
242
+ pctr hid move --x 500 --y 300 --port COM5
243
+ pctr hid type --text "hello" --port COM5
244
+ ```
245
+
140
246
  ## Exit codes
141
247
 
142
248
  - `0` success, `1` no match / window not found, `2` usage/validation error.
@@ -1,5 +1,7 @@
1
1
  # pctr
2
2
 
3
+ **PCTR — Personal Computer Tactile Response**
4
+
3
5
  Element-based Windows UI Automation CLI for AI agents.
4
6
 
5
7
  Instead of screenshotting and guessing pixel coordinates, `pctr` finds controls
@@ -11,11 +13,21 @@ mouse and keyboard input. On top of UIA it also offers **OCR**
11
13
  (`Windows.Media.Ocr`) and **YOLO-World** open-vocabulary detection for text and
12
14
  objects that aren't exposed as controls.
13
15
 
16
+ ![pctr driving by element name: enumerating windows, mapping virtual desktops, dumping the control tree, filling a field, then reading it back with OCR](docs/demo.gif)
17
+
18
+ *Driven entirely by pctr itself - list windows, map virtual desktops, dump a
19
+ control tree, `set` a field, read it back with OCR, screenshot it, and YOLO-World
20
+ detect. Recorded with OBS, which pctr also piloted.*
21
+
14
22
  ## Install
15
23
 
16
24
  ```bash
17
- pip install pctr
18
- pip install "pctr[vision]" # adds ultralytics for `pctr look`
25
+ pip install pctr # core (UIA + OCR)
26
+ pip install "pctr[vision]" # + ultralytics, for `pctr look`
27
+ pip install "pctr[mcp]" # + MCP SDK, for the MCP server
28
+ pip install "pctr[pad]" # + vgamepad, for `pctr pad` (needs ViGEmBus)
29
+ pip install "pctr[serial]" # + pyserial, for `pctr hid` / the serial-hid backend
30
+ pip install "pctr[all]" # everything
19
31
  ```
20
32
 
21
33
  Windows only.
@@ -42,6 +54,18 @@ Tools exposed: `pctr_windows`, `pctr_tree`, `pctr_find`, `pctr_click`,
42
54
  `pctr_shot`, `pctr_ocr`, `pctr_ocrfind`, `pctr_ocrclick`, `pctr_look`,
43
55
  `pctr_desktop`.
44
56
 
57
+ Or run/manage it from the CLI:
58
+
59
+ ```bash
60
+ pctr mcp status # SDK + server state
61
+ pctr mcp start --transport streamable-http --port 8765 # background HTTP server
62
+ pctr mcp restart | pctr mcp stop
63
+ pctr mcp help
64
+ ```
65
+
66
+ `stdio` runs in the foreground (what a client spawns); `sse` / `streamable-http`
67
+ run in the background, reachable at `http://127.0.0.1:8765/mcp` (or `…/sse`).
68
+
45
69
  ## Commands
46
70
 
47
71
  | Command | What it does |
@@ -62,13 +86,19 @@ Tools exposed: `pctr_windows`, `pctr_tree`, `pctr_find`, `pctr_click`,
62
86
  | `pctr move --x N --y N` / `down` / `up` / `hold --ms N` | Raw mouse control (`--direct` for games). |
63
87
  | `pctr drag --start x,y --end x,y [--duration S]` | Drag between two points. |
64
88
  | `pctr keydown / keyup --key a` / `keyhold --key w --ms 1500` | Hold keyboard keys (`--direct` for games). |
65
- | `pctr ocr [--title RE]` | OCR the screen/window; list words with boxes. |
66
- | `pctr ocrfind --text RE` | OCR then list matches with click centers (single words). |
67
- | `pctr ocrclick --text RE [--nth N]` | OCR then click a word. |
89
+ | `pctr ocr [--title RE] [--lang TAG]` | OCR the screen/window; list words with boxes. |
90
+ | `pctr ocrfind --text RE [--lang TAG]` | OCR then list matches with click centers (single words). |
91
+ | `pctr ocrclick --text RE [--nth N] [--lang TAG]` | OCR then click a word. |
68
92
  | `pctr look --for "a dog" [--title RE] [--conf X]` | YOLO-World detect objects by text prompt. |
69
93
  | `pctr lookclick --for "a dog" [--nth N]` | Detect then click the top match. |
94
+ | `pctr pad <button\|stick\|trigger\|status>` | Virtual Xbox 360 gamepad via ViGEmBus. |
95
+ | `pctr hid <action> --port COMx` | Serial-HID bridge to a real USB-HID microcontroller. |
96
+ | `pctr mcp <start\|stop\|restart\|status\|help>` | Manage the MCP server (stdio or background http/sse). |
70
97
  | `pctr skill [--install]` / `pctr setup` | Print/install the agent skill + an AGENTS.md section. |
71
98
 
99
+ Global flags: `--json` (machine-readable output) and `--file FILE` (run a batch
100
+ of commands from a file).
101
+
72
102
  Common filters: `--title` (regex), `--name` (regex), `--control-type`
73
103
  (`Button`, `Edit`, `Pane`, `MenuItem`, …), `--auto-id`, `--nth`, `--process`.
74
104
 
@@ -83,6 +113,33 @@ pctr click --title "Notepad" --name "^File$"
83
113
  pctr set --title "Notepad" --name "Text Editor" --text "hello"
84
114
  ```
85
115
 
116
+ ## JSON output
117
+
118
+ Add `--json` (global, or per-command) for machine-readable output from
119
+ `windows`, `tree`, `find`, `ocr`, `ocrfind`, `look`, and `desktop`:
120
+
121
+ ```bash
122
+ pctr windows --json
123
+ # [{"hwnd":1234,"pid":5678,"title":"Untitled - Notepad"}, ...]
124
+
125
+ pctr desktop list --json
126
+ # [{"index":0,"guid":"ae37…","current":true,"windows":11}, ...]
127
+
128
+ pctr look --for "a car" --json
129
+ # [{"label":"a car","conf":0.86,"x":512,"y":300,"box":[400,220,620,380]}, ...]
130
+ ```
131
+
132
+ Progress and warnings go to stderr, so stdout stays valid JSON.
133
+
134
+ ## Batch files
135
+
136
+ ```bash
137
+ pctr --file script.txt # one command per line; # comments and blanks skipped
138
+ pctr --json --file script.txt # --json applies to every line
139
+ ```
140
+
141
+ Stops on the first failing line and reports its line number.
142
+
86
143
  ## Virtual desktops
87
144
 
88
145
  ```bash
@@ -102,6 +159,49 @@ pctr desktop move-window --title RE --to N
102
159
  - **`move-window` is blocked on Windows 11** (third-party `MoveWindowToDesktop`
103
160
  returns `Access denied`); it works on Windows 10.
104
161
 
162
+ ## Raw input backends
163
+
164
+ The OS flags `SendInput` events as injected, so anything built on user32 is
165
+ detectable in principle. `pctr` can route raw mouse/keyboard through a different
166
+ backend with `--backend`:
167
+
168
+ | Backend | How | Detectable? |
169
+ |---|---|---|
170
+ | `pyautogui` (default / `sendinput`) | user32 `SendInput`, virtual keys | yes (`injected` flag) |
171
+ | `pydirectinput` (or `--direct`) | `SendInput` with **scancodes** — better for DirectInput games | yes |
172
+ | `serial-hid` | a **microcontroller presenting real USB HID** over serial | no — it *is* real hardware |
173
+
174
+ ```bash
175
+ pctr move --backend pydirectinput --x 800 --y 400
176
+ pctr keyhold --key w --ms 400 --backend pydirectinput
177
+ pctr type --text "hi" --backend serial-hid --port COM5 # needs a board
178
+ ```
179
+
180
+ Applies to `move` / `down` / `up` / `hold` / `keydown` / `keyup` / `keyhold` /
181
+ `hotkey` / `drag` / `type` / `desktop`.
182
+
183
+ ### Gamepad
184
+
185
+ ```bash
186
+ pip install "pctr[pad]" # + the ViGEmBus driver
187
+ pctr pad button --name A --ms 150
188
+ pctr pad button --name DPAD_UP --ms 100
189
+ pctr pad stick --x 1.0 --y -0.5 --ms 400
190
+ pctr pad trigger --right 1.0 --ms 300
191
+ ```
192
+
193
+ ### Serial-HID bridge
194
+
195
+ Firmware protocol, newline-terminated ASCII:
196
+ `MOVE x y` · `CLICK b` · `DOWN b` · `UP b` · `KEY k DOWN|UP` · `WRITE text` · `HOTKEY a+b`
197
+
198
+ ```bash
199
+ pip install "pctr[serial]"
200
+ pctr hid ports # list COM ports
201
+ pctr hid move --x 500 --y 300 --port COM5
202
+ pctr hid type --text "hello" --port COM5
203
+ ```
204
+
105
205
  ## Exit codes
106
206
 
107
207
  - `0` success, `1` no match / window not found, `2` usage/validation error.
@@ -4,12 +4,12 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "pctr"
7
- version = "0.3.4"
8
- description = "Element-based Windows UI Automation CLI for AI agents. Find controls by name/type/id and click, type, hold, drag, and screenshot - no pixel coordinates."
7
+ version = "0.4.0"
8
+ description = "PCTR - Personal Computer Tactile Response. Element-based Windows UI Automation CLI for AI agents. Find controls by name/type/id and click, type, hold, drag, and screenshot - no pixel coordinates."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
11
11
  license = "MIT"
12
- authors = [{ name = "Space-lab515" }]
12
+ authors = [{ name = "NTUserDev" }]
13
13
  keywords = ["automation", "windows", "uia", "pywinauto", "desktop", "agent", "computer-use", "rpa"]
14
14
  classifiers = [
15
15
  "Development Status :: 4 - Beta",
@@ -35,18 +35,21 @@ dependencies = [
35
35
  [project.optional-dependencies]
36
36
  vision = ["ultralytics>=8.2"]
37
37
  mcp = ["mcp>=2"]
38
+ pad = ["vgamepad>=0.1.0"]
39
+ serial = ["pyserial>=3.5"]
40
+ all = ["pctr[vision,mcp,pad,serial]"]
38
41
 
39
42
  [project.scripts]
40
43
  pctr = "pctr.cli:main"
41
44
  pctr-mcp = "pctr.mcp_server:main"
42
45
 
43
46
  [project.urls]
44
- Homepage = "https://github.com/Space-lab515/pctr"
45
- Repository = "https://github.com/Space-lab515/pctr"
46
- Issues = "https://github.com/Space-lab515/pctr/issues"
47
+ Homepage = "https://github.com/NTUserDev/pctr"
48
+ Repository = "https://github.com/NTUserDev/pctr"
49
+ Issues = "https://github.com/NTUserDev/pctr/issues"
47
50
 
48
51
  [tool.setuptools.packages.find]
49
52
  where = ["src"]
50
53
 
51
54
  [tool.setuptools.package-data]
52
- pctr = ["data/*.md"]
55
+ pctr = ["data/*.md", "py.typed"]
@@ -0,0 +1 @@
1
+ __version__ = "0.4.0"