usecomputer 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Kimaki
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/bin.js ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ import './dist/cli.js'
package/dist/cli.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
package/dist/cli.js ADDED
@@ -0,0 +1,339 @@
1
+ // usecomputer CLI — computer automation for AI agents.
2
+ // Outline only. Commands print "not implemented" placeholders.
3
+ import { goke } from 'goke';
4
+ import { z } from 'zod';
5
+ import dedent from 'string-dedent';
6
+ import pkg from '../package.json' with { type: 'json' };
7
+ const cli = goke('usecomputer');
8
+ // ─── Core Commands ──────────────────────────────────────────────────────
9
+ cli
10
+ .command('snapshot', dedent `
11
+ Capture the accessibility tree of the desktop or a window.
12
+
13
+ Uses native accessibility APIs (macOS AX, AT-SPI on Linux, UIA on Windows)
14
+ to produce a structured tree of UI elements with roles, names, and ref IDs.
15
+ Refs like @e1, @e2 can be used in click, type, and other commands.
16
+ `)
17
+ .option('-w, --window [window]', z.string().describe('Target a specific window by title or ID'))
18
+ .option('-a, --app [app]', z.string().describe('Target a specific application by name or bundle ID'))
19
+ .option('-i, --interactive', 'Only show interactive elements (buttons, inputs, links)')
20
+ .option('-c, --compact', 'Remove empty structural elements')
21
+ .option('-d, --depth [depth]', z.number().describe('Limit tree depth'))
22
+ .example('# Full desktop accessibility snapshot')
23
+ .example('usecomputer snapshot')
24
+ .example('# Interactive elements in a specific app')
25
+ .example('usecomputer snapshot --app "Visual Studio Code" -i')
26
+ .action((options) => {
27
+ console.log('not implemented');
28
+ });
29
+ cli
30
+ .command('screenshot [path]', dedent `
31
+ Take a screenshot of the entire screen, a window, or a region.
32
+
33
+ Saves as PNG. If no path is given, prints the file path of a temp file.
34
+ Use --window or --app to capture a specific window.
35
+ Use --region to capture a rectangular area (x,y,width,height).
36
+ `)
37
+ .option('-w, --window [window]', z.string().describe('Capture a specific window by title or ID'))
38
+ .option('-a, --app [app]', z.string().describe('Capture a specific application by name or bundle ID'))
39
+ .option('-r, --region [region]', z.string().describe('Capture region as x,y,width,height'))
40
+ .option('--display [display]', z.number().describe('Display/monitor index for multi-monitor setups'))
41
+ .option('--annotate', 'Annotate screenshot with numbered labels on interactive elements')
42
+ .example('# Screenshot entire screen')
43
+ .example('usecomputer screenshot')
44
+ .example('# Screenshot a specific app window')
45
+ .example('usecomputer screenshot --app Finder ~/Desktop/finder.png')
46
+ .example('# Screenshot a region')
47
+ .example('usecomputer screenshot --region 100,200,800,600')
48
+ .action((path, options) => {
49
+ console.log('not implemented');
50
+ });
51
+ cli
52
+ .command('click <target>', dedent `
53
+ Click at a target. Target can be:
54
+ - Coordinates: "500,300" (x,y pixels)
55
+ - Accessibility ref: "@e2" (from a snapshot)
56
+ - Text match: "Submit" (finds element by accessible name)
57
+ `)
58
+ .option('--button [button]', z.enum(['left', 'right', 'middle']).default('left').describe('Mouse button'))
59
+ .option('--count [count]', z.number().default(1).describe('Number of clicks (2 for double-click)'))
60
+ .option('--modifiers [modifiers]', z.string().describe('Modifier keys held during click (ctrl,shift,alt,meta)'))
61
+ .example('# Click at coordinates')
62
+ .example('usecomputer click 500,300')
63
+ .example('# Click an element from snapshot')
64
+ .example('usecomputer click @e2')
65
+ .example('# Right-click')
66
+ .example('usecomputer click 500,300 --button right')
67
+ .example('# Double-click')
68
+ .example('usecomputer click @e5 --count 2')
69
+ .action((target, options) => {
70
+ console.log('not implemented');
71
+ });
72
+ cli
73
+ .command('type <text>', dedent `
74
+ Type text using keyboard input, as if the user is typing.
75
+
76
+ Types each character sequentially with realistic key events.
77
+ Works with the currently focused element. Use "click" first to focus.
78
+ `)
79
+ .option('--delay [delay]', z.number().describe('Delay between keystrokes in milliseconds'))
80
+ .example('# Type into the currently focused field')
81
+ .example('usecomputer type "Hello, world!"')
82
+ .action((text, options) => {
83
+ console.log('not implemented');
84
+ });
85
+ cli
86
+ .command('press <key>', dedent `
87
+ Press a key or key combination.
88
+
89
+ Supports modifier combos like "ctrl+c", "cmd+shift+s", "alt+tab".
90
+ Key names: enter, tab, escape, space, backspace, delete, up, down,
91
+ left, right, home, end, pageup, pagedown, f1-f12.
92
+ `)
93
+ .option('--count [count]', z.number().default(1).describe('Number of times to press'))
94
+ .option('--delay [delay]', z.number().describe('Delay between repeated presses in milliseconds'))
95
+ .example('# Press Enter')
96
+ .example('usecomputer press enter')
97
+ .example('# Copy to clipboard')
98
+ .example('usecomputer press cmd+c')
99
+ .example('# Switch apps on macOS')
100
+ .example('usecomputer press cmd+tab')
101
+ .example('# Press Escape 3 times')
102
+ .example('usecomputer press escape --count 3')
103
+ .action((key, options) => {
104
+ console.log('not implemented');
105
+ });
106
+ cli
107
+ .command('scroll <direction> [amount]', dedent `
108
+ Scroll in a direction. Amount is in pixels (default: 300).
109
+
110
+ Directions: up, down, left, right.
111
+ Scrolls at the current mouse position unless --at is specified.
112
+ `)
113
+ .option('--at [at]', z.string().describe('Scroll at specific coordinates (x,y)'))
114
+ .example('# Scroll down')
115
+ .example('usecomputer scroll down')
116
+ .example('# Scroll up 500px at a specific position')
117
+ .example('usecomputer scroll up 500 --at 400,300')
118
+ .action((direction, amount, options) => {
119
+ console.log('not implemented');
120
+ });
121
+ cli
122
+ .command('drag <from> <to>', dedent `
123
+ Drag from one position to another.
124
+
125
+ Positions are x,y coordinates or accessibility refs (@e1).
126
+ Performs mouse-down at "from", moves to "to", then mouse-up.
127
+ `)
128
+ .option('--duration [duration]', z.number().describe('Duration of the drag in milliseconds'))
129
+ .example('# Drag from one position to another')
130
+ .example('usecomputer drag 100,200 500,200')
131
+ .example('# Drag an accessibility element')
132
+ .example('usecomputer drag @e3 400,600')
133
+ .action((from, to, options) => {
134
+ console.log('not implemented');
135
+ });
136
+ cli
137
+ .command('hover <target>', dedent `
138
+ Move the mouse to a target without clicking.
139
+
140
+ Target can be coordinates (x,y) or an accessibility ref (@e1).
141
+ `)
142
+ .example('usecomputer hover 500,300')
143
+ .example('usecomputer hover @e4')
144
+ .action((target) => {
145
+ console.log('not implemented');
146
+ });
147
+ // ─── Mouse Commands ─────────────────────────────────────────────────────
148
+ cli
149
+ .command('mouse move <x> <y>', 'Move mouse cursor to absolute screen coordinates.')
150
+ .action((x, y) => {
151
+ console.log('not implemented');
152
+ });
153
+ cli
154
+ .command('mouse down', 'Press and hold mouse button.')
155
+ .option('--button [button]', z.enum(['left', 'right', 'middle']).default('left').describe('Mouse button'))
156
+ .action((options) => {
157
+ console.log('not implemented');
158
+ });
159
+ cli
160
+ .command('mouse up', 'Release mouse button.')
161
+ .option('--button [button]', z.enum(['left', 'right', 'middle']).default('left').describe('Mouse button'))
162
+ .action((options) => {
163
+ console.log('not implemented');
164
+ });
165
+ cli
166
+ .command('mouse position', 'Print the current mouse cursor position as x,y.')
167
+ .action(() => {
168
+ console.log('not implemented');
169
+ });
170
+ // ─── Get Info Commands ──────────────────────────────────────────────────
171
+ cli
172
+ .command('get text <target>', 'Get the accessible text content of an element. Target is an accessibility ref (@e1) or coordinates.')
173
+ .action((target) => {
174
+ console.log('not implemented');
175
+ });
176
+ cli
177
+ .command('get title <target>', 'Get the title/name of a window or element. Target is a ref, coordinates, or window ID.')
178
+ .action((target) => {
179
+ console.log('not implemented');
180
+ });
181
+ cli
182
+ .command('get value <target>', 'Get the current value of an input element (text fields, sliders, checkboxes).')
183
+ .action((target) => {
184
+ console.log('not implemented');
185
+ });
186
+ cli
187
+ .command('get bounds <target>', 'Get the bounding rectangle (x, y, width, height) of an element or window.')
188
+ .action((target) => {
189
+ console.log('not implemented');
190
+ });
191
+ cli
192
+ .command('get focused', 'Get the currently focused element and its accessibility info.')
193
+ .action(() => {
194
+ console.log('not implemented');
195
+ });
196
+ // ─── Window Management ─────────────────────────────────────────────────
197
+ cli
198
+ .command('window list', 'List all open windows with their titles, apps, positions, and sizes.')
199
+ .option('--app [app]', z.string().describe('Filter by application name'))
200
+ .option('--json', 'Output as JSON')
201
+ .action((options) => {
202
+ console.log('not implemented');
203
+ });
204
+ cli
205
+ .command('window focus <target>', 'Bring a window to the foreground. Target is a window title, ID, or app name.')
206
+ .action((target) => {
207
+ console.log('not implemented');
208
+ });
209
+ cli
210
+ .command('window resize <target> <width> <height>', 'Resize a window. Target is a window title, ID, or app name.')
211
+ .action((target, width, height) => {
212
+ console.log('not implemented');
213
+ });
214
+ cli
215
+ .command('window move <target> <x> <y>', 'Move a window to absolute screen coordinates.')
216
+ .action((target, x, y) => {
217
+ console.log('not implemented');
218
+ });
219
+ cli
220
+ .command('window minimize <target>', 'Minimize a window.')
221
+ .action((target) => {
222
+ console.log('not implemented');
223
+ });
224
+ cli
225
+ .command('window maximize <target>', 'Maximize/fullscreen a window.')
226
+ .action((target) => {
227
+ console.log('not implemented');
228
+ });
229
+ cli
230
+ .command('window close <target>', 'Close a window.')
231
+ .action((target) => {
232
+ console.log('not implemented');
233
+ });
234
+ // ─── App Management ────────────────────────────────────────────────────
235
+ cli
236
+ .command('app list', 'List all running applications with their process IDs and window counts.')
237
+ .option('--json', 'Output as JSON')
238
+ .action((options) => {
239
+ console.log('not implemented');
240
+ });
241
+ cli
242
+ .command('app launch <name>', dedent `
243
+ Launch an application by name or path.
244
+
245
+ On macOS: app name ("Safari"), bundle ID ("com.apple.Safari"), or path.
246
+ On Linux: executable name or .desktop file.
247
+ On Windows: executable name or Start Menu shortcut.
248
+ `)
249
+ .option('--wait', 'Wait for the application window to appear before returning')
250
+ .action((name, options) => {
251
+ console.log('not implemented');
252
+ });
253
+ cli
254
+ .command('app quit <name>', 'Quit an application gracefully by name or process ID.')
255
+ .option('--force', 'Force-kill the application if it does not quit gracefully')
256
+ .action((name, options) => {
257
+ console.log('not implemented');
258
+ });
259
+ // ─── Clipboard ──────────────────────────────────────────────────────────
260
+ cli
261
+ .command('clipboard get', 'Print the current clipboard text content.')
262
+ .action(() => {
263
+ console.log('not implemented');
264
+ });
265
+ cli
266
+ .command('clipboard set <text>', 'Set the clipboard content to the given text.')
267
+ .action((text) => {
268
+ console.log('not implemented');
269
+ });
270
+ // ─── Wait ───────────────────────────────────────────────────────────────
271
+ cli
272
+ .command('wait <target>', dedent `
273
+ Wait for a condition before continuing.
274
+
275
+ Target can be:
276
+ - Milliseconds: "2000" (wait 2 seconds)
277
+ - Accessibility ref: "@e5" (wait for element to appear)
278
+ - Window title: "--window Untitled" (wait for window to appear)
279
+ `)
280
+ .option('-w, --window [window]', z.string().describe('Wait for a window with this title to appear'))
281
+ .option('--timeout [timeout]', z.number().default(30000).describe('Maximum wait time in milliseconds'))
282
+ .example('# Wait 2 seconds')
283
+ .example('usecomputer wait 2000')
284
+ .example('# Wait for an element to appear')
285
+ .example('usecomputer wait @e5')
286
+ .example('# Wait for a window to appear')
287
+ .example('usecomputer wait --window "Save As"')
288
+ .action((target, options) => {
289
+ console.log('not implemented');
290
+ });
291
+ // ─── Display ────────────────────────────────────────────────────────────
292
+ cli
293
+ .command('display list', 'List connected displays with their resolutions, positions, and scale factors.')
294
+ .option('--json', 'Output as JSON')
295
+ .action((options) => {
296
+ console.log('not implemented');
297
+ });
298
+ // ─── Find Elements ──────────────────────────────────────────────────────
299
+ cli
300
+ .command('find <query>', dedent `
301
+ Search for UI elements matching a text query across the accessibility tree.
302
+
303
+ Returns matching elements with their refs, roles, and positions.
304
+ Useful for locating elements before clicking or typing.
305
+ `)
306
+ .option('-w, --window [window]', z.string().describe('Scope search to a specific window'))
307
+ .option('-a, --app [app]', z.string().describe('Scope search to a specific application'))
308
+ .option('--role [role]', z.string().describe('Filter by accessibility role (button, textField, link, etc.)'))
309
+ .option('--limit [limit]', z.number().default(20).describe('Maximum number of results'))
310
+ .example('# Find all buttons with "Save" in the name')
311
+ .example('usecomputer find "Save" --role button')
312
+ .example('# Find elements in a specific app')
313
+ .example('usecomputer find "File" --app "Visual Studio Code"')
314
+ .action((query, options) => {
315
+ console.log('not implemented');
316
+ });
317
+ // ─── Diff ───────────────────────────────────────────────────────────────
318
+ cli
319
+ .command('diff snapshot', 'Compare the current accessibility snapshot against the previous one. Shows added, removed, and changed elements.')
320
+ .option('-w, --window [window]', z.string().describe('Scope to a specific window'))
321
+ .option('-a, --app [app]', z.string().describe('Scope to a specific application'))
322
+ .action((options) => {
323
+ console.log('not implemented');
324
+ });
325
+ cli
326
+ .command('diff screenshot', 'Compare the current screenshot against a baseline image. Highlights visual differences.')
327
+ .option('--baseline <baseline>', z.string().describe('Path to the baseline screenshot'))
328
+ .option('--threshold [threshold]', z.number().default(0.1).describe('Pixel difference threshold (0-1)'))
329
+ .action((options) => {
330
+ console.log('not implemented');
331
+ });
332
+ // ─── Global Options ─────────────────────────────────────────────────────
333
+ cli.option('--json', 'Output as JSON');
334
+ cli.option('--display [display]', z.number().describe('Target display/monitor index for multi-monitor setups'));
335
+ cli.option('--timeout [timeout]', z.number().default(25000).describe('Default timeout for operations in milliseconds'));
336
+ cli.option('--debug', 'Enable debug output');
337
+ cli.help();
338
+ cli.version(pkg.version);
339
+ cli.parse();
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,4 @@
1
+ // usecomputer — fast computer automation CLI for AI agents.
2
+ // Controls any desktop via accessibility APIs, mouse, keyboard, and screen capture.
3
+ // Cross-platform: macOS, Linux, Windows.
4
+ export {};
package/package.json ADDED
@@ -0,0 +1,68 @@
1
+ {
2
+ "name": "usecomputer",
3
+ "version": "0.0.1",
4
+ "type": "module",
5
+ "description": "Fast computer automation CLI for AI agents. Control any desktop with accessibility snapshots, clicks, typing, scrolling, and more.",
6
+ "bin": {
7
+ "usecomputer": "./bin.js"
8
+ },
9
+ "main": "./dist/index.js",
10
+ "types": "./dist/index.d.ts",
11
+ "exports": {
12
+ "./package.json": "./package.json",
13
+ ".": {
14
+ "types": "./dist/index.d.ts",
15
+ "default": "./dist/index.js"
16
+ },
17
+ "./src": {
18
+ "types": "./src/index.ts",
19
+ "default": "./src/index.ts"
20
+ },
21
+ "./src/*": {
22
+ "types": "./src/*.ts",
23
+ "default": "./src/*.ts"
24
+ }
25
+ },
26
+ "files": [
27
+ "src",
28
+ "dist",
29
+ "bin.js",
30
+ "README.md"
31
+ ],
32
+ "keywords": [
33
+ "computer-use",
34
+ "automation",
35
+ "accessibility",
36
+ "cli",
37
+ "ai-agent",
38
+ "desktop-automation",
39
+ "screen-control",
40
+ "macos",
41
+ "linux",
42
+ "windows",
43
+ "cross-platform"
44
+ ],
45
+ "license": "MIT",
46
+ "repository": {
47
+ "type": "git",
48
+ "url": "https://github.com/remorses/usecomputer",
49
+ "directory": "."
50
+ },
51
+ "homepage": "https://github.com/remorses/usecomputer",
52
+ "bugs": {
53
+ "url": "https://github.com/remorses/usecomputer/issues"
54
+ },
55
+ "dependencies": {
56
+ "goke": "^6.2.3",
57
+ "string-dedent": "^3.0.1",
58
+ "zod": "^4.3.6"
59
+ },
60
+ "devDependencies": {
61
+ "@types/node": "^22.15.3",
62
+ "typescript": "^5.8.3"
63
+ },
64
+ "scripts": {
65
+ "build": "tsc",
66
+ "typecheck": "tsc --noEmit"
67
+ }
68
+ }
package/src/cli.ts ADDED
@@ -0,0 +1,478 @@
1
+ // usecomputer CLI — computer automation for AI agents.
2
+ // Outline only. Commands print "not implemented" placeholders.
3
+
4
+ import { goke } from 'goke'
5
+ import { z } from 'zod'
6
+ import dedent from 'string-dedent'
7
+ import pkg from '../package.json' with { type: 'json' }
8
+
9
+ const cli = goke('usecomputer')
10
+
11
+ // ─── Core Commands ──────────────────────────────────────────────────────
12
+
13
+ cli
14
+ .command(
15
+ 'snapshot',
16
+ dedent`
17
+ Capture the accessibility tree of the desktop or a window.
18
+
19
+ Uses native accessibility APIs (macOS AX, AT-SPI on Linux, UIA on Windows)
20
+ to produce a structured tree of UI elements with roles, names, and ref IDs.
21
+ Refs like @e1, @e2 can be used in click, type, and other commands.
22
+ `,
23
+ )
24
+ .option('-w, --window [window]', z.string().describe('Target a specific window by title or ID'))
25
+ .option('-a, --app [app]', z.string().describe('Target a specific application by name or bundle ID'))
26
+ .option('-i, --interactive', 'Only show interactive elements (buttons, inputs, links)')
27
+ .option('-c, --compact', 'Remove empty structural elements')
28
+ .option('-d, --depth [depth]', z.number().describe('Limit tree depth'))
29
+ .example('# Full desktop accessibility snapshot')
30
+ .example('usecomputer snapshot')
31
+ .example('# Interactive elements in a specific app')
32
+ .example('usecomputer snapshot --app "Visual Studio Code" -i')
33
+ .action((options) => {
34
+ console.log('not implemented')
35
+ })
36
+
37
+ cli
38
+ .command(
39
+ 'screenshot [path]',
40
+ dedent`
41
+ Take a screenshot of the entire screen, a window, or a region.
42
+
43
+ Saves as PNG. If no path is given, prints the file path of a temp file.
44
+ Use --window or --app to capture a specific window.
45
+ Use --region to capture a rectangular area (x,y,width,height).
46
+ `,
47
+ )
48
+ .option('-w, --window [window]', z.string().describe('Capture a specific window by title or ID'))
49
+ .option('-a, --app [app]', z.string().describe('Capture a specific application by name or bundle ID'))
50
+ .option('-r, --region [region]', z.string().describe('Capture region as x,y,width,height'))
51
+ .option('--display [display]', z.number().describe('Display/monitor index for multi-monitor setups'))
52
+ .option('--annotate', 'Annotate screenshot with numbered labels on interactive elements')
53
+ .example('# Screenshot entire screen')
54
+ .example('usecomputer screenshot')
55
+ .example('# Screenshot a specific app window')
56
+ .example('usecomputer screenshot --app Finder ~/Desktop/finder.png')
57
+ .example('# Screenshot a region')
58
+ .example('usecomputer screenshot --region 100,200,800,600')
59
+ .action((path, options) => {
60
+ console.log('not implemented')
61
+ })
62
+
63
+ cli
64
+ .command(
65
+ 'click <target>',
66
+ dedent`
67
+ Click at a target. Target can be:
68
+ - Coordinates: "500,300" (x,y pixels)
69
+ - Accessibility ref: "@e2" (from a snapshot)
70
+ - Text match: "Submit" (finds element by accessible name)
71
+ `,
72
+ )
73
+ .option('--button [button]', z.enum(['left', 'right', 'middle']).default('left').describe('Mouse button'))
74
+ .option('--count [count]', z.number().default(1).describe('Number of clicks (2 for double-click)'))
75
+ .option('--modifiers [modifiers]', z.string().describe('Modifier keys held during click (ctrl,shift,alt,meta)'))
76
+ .example('# Click at coordinates')
77
+ .example('usecomputer click 500,300')
78
+ .example('# Click an element from snapshot')
79
+ .example('usecomputer click @e2')
80
+ .example('# Right-click')
81
+ .example('usecomputer click 500,300 --button right')
82
+ .example('# Double-click')
83
+ .example('usecomputer click @e5 --count 2')
84
+ .action((target, options) => {
85
+ console.log('not implemented')
86
+ })
87
+
88
+ cli
89
+ .command(
90
+ 'type <text>',
91
+ dedent`
92
+ Type text using keyboard input, as if the user is typing.
93
+
94
+ Types each character sequentially with realistic key events.
95
+ Works with the currently focused element. Use "click" first to focus.
96
+ `,
97
+ )
98
+ .option('--delay [delay]', z.number().describe('Delay between keystrokes in milliseconds'))
99
+ .example('# Type into the currently focused field')
100
+ .example('usecomputer type "Hello, world!"')
101
+ .action((text, options) => {
102
+ console.log('not implemented')
103
+ })
104
+
105
+ cli
106
+ .command(
107
+ 'press <key>',
108
+ dedent`
109
+ Press a key or key combination.
110
+
111
+ Supports modifier combos like "ctrl+c", "cmd+shift+s", "alt+tab".
112
+ Key names: enter, tab, escape, space, backspace, delete, up, down,
113
+ left, right, home, end, pageup, pagedown, f1-f12.
114
+ `,
115
+ )
116
+ .option('--count [count]', z.number().default(1).describe('Number of times to press'))
117
+ .option('--delay [delay]', z.number().describe('Delay between repeated presses in milliseconds'))
118
+ .example('# Press Enter')
119
+ .example('usecomputer press enter')
120
+ .example('# Copy to clipboard')
121
+ .example('usecomputer press cmd+c')
122
+ .example('# Switch apps on macOS')
123
+ .example('usecomputer press cmd+tab')
124
+ .example('# Press Escape 3 times')
125
+ .example('usecomputer press escape --count 3')
126
+ .action((key, options) => {
127
+ console.log('not implemented')
128
+ })
129
+
130
+ cli
131
+ .command(
132
+ 'scroll <direction> [amount]',
133
+ dedent`
134
+ Scroll in a direction. Amount is in pixels (default: 300).
135
+
136
+ Directions: up, down, left, right.
137
+ Scrolls at the current mouse position unless --at is specified.
138
+ `,
139
+ )
140
+ .option('--at [at]', z.string().describe('Scroll at specific coordinates (x,y)'))
141
+ .example('# Scroll down')
142
+ .example('usecomputer scroll down')
143
+ .example('# Scroll up 500px at a specific position')
144
+ .example('usecomputer scroll up 500 --at 400,300')
145
+ .action((direction, amount, options) => {
146
+ console.log('not implemented')
147
+ })
148
+
149
+ cli
150
+ .command(
151
+ 'drag <from> <to>',
152
+ dedent`
153
+ Drag from one position to another.
154
+
155
+ Positions are x,y coordinates or accessibility refs (@e1).
156
+ Performs mouse-down at "from", moves to "to", then mouse-up.
157
+ `,
158
+ )
159
+ .option('--duration [duration]', z.number().describe('Duration of the drag in milliseconds'))
160
+ .example('# Drag from one position to another')
161
+ .example('usecomputer drag 100,200 500,200')
162
+ .example('# Drag an accessibility element')
163
+ .example('usecomputer drag @e3 400,600')
164
+ .action((from, to, options) => {
165
+ console.log('not implemented')
166
+ })
167
+
168
+ cli
169
+ .command(
170
+ 'hover <target>',
171
+ dedent`
172
+ Move the mouse to a target without clicking.
173
+
174
+ Target can be coordinates (x,y) or an accessibility ref (@e1).
175
+ `,
176
+ )
177
+ .example('usecomputer hover 500,300')
178
+ .example('usecomputer hover @e4')
179
+ .action((target) => {
180
+ console.log('not implemented')
181
+ })
182
+
183
+ // ─── Mouse Commands ─────────────────────────────────────────────────────
184
+
185
+ cli
186
+ .command('mouse move <x> <y>', 'Move mouse cursor to absolute screen coordinates.')
187
+ .action((x, y) => {
188
+ console.log('not implemented')
189
+ })
190
+
191
+ cli
192
+ .command('mouse down', 'Press and hold mouse button.')
193
+ .option('--button [button]', z.enum(['left', 'right', 'middle']).default('left').describe('Mouse button'))
194
+ .action((options) => {
195
+ console.log('not implemented')
196
+ })
197
+
198
+ cli
199
+ .command('mouse up', 'Release mouse button.')
200
+ .option('--button [button]', z.enum(['left', 'right', 'middle']).default('left').describe('Mouse button'))
201
+ .action((options) => {
202
+ console.log('not implemented')
203
+ })
204
+
205
+ cli
206
+ .command('mouse position', 'Print the current mouse cursor position as x,y.')
207
+ .action(() => {
208
+ console.log('not implemented')
209
+ })
210
+
211
+ // ─── Get Info Commands ──────────────────────────────────────────────────
212
+
213
+ cli
214
+ .command(
215
+ 'get text <target>',
216
+ 'Get the accessible text content of an element. Target is an accessibility ref (@e1) or coordinates.',
217
+ )
218
+ .action((target) => {
219
+ console.log('not implemented')
220
+ })
221
+
222
+ cli
223
+ .command(
224
+ 'get title <target>',
225
+ 'Get the title/name of a window or element. Target is a ref, coordinates, or window ID.',
226
+ )
227
+ .action((target) => {
228
+ console.log('not implemented')
229
+ })
230
+
231
+ cli
232
+ .command(
233
+ 'get value <target>',
234
+ 'Get the current value of an input element (text fields, sliders, checkboxes).',
235
+ )
236
+ .action((target) => {
237
+ console.log('not implemented')
238
+ })
239
+
240
+ cli
241
+ .command(
242
+ 'get bounds <target>',
243
+ 'Get the bounding rectangle (x, y, width, height) of an element or window.',
244
+ )
245
+ .action((target) => {
246
+ console.log('not implemented')
247
+ })
248
+
249
+ cli
250
+ .command(
251
+ 'get focused',
252
+ 'Get the currently focused element and its accessibility info.',
253
+ )
254
+ .action(() => {
255
+ console.log('not implemented')
256
+ })
257
+
258
+ // ─── Window Management ─────────────────────────────────────────────────
259
+
260
+ cli
261
+ .command(
262
+ 'window list',
263
+ 'List all open windows with their titles, apps, positions, and sizes.',
264
+ )
265
+ .option('--app [app]', z.string().describe('Filter by application name'))
266
+ .option('--json', 'Output as JSON')
267
+ .action((options) => {
268
+ console.log('not implemented')
269
+ })
270
+
271
+ cli
272
+ .command(
273
+ 'window focus <target>',
274
+ 'Bring a window to the foreground. Target is a window title, ID, or app name.',
275
+ )
276
+ .action((target) => {
277
+ console.log('not implemented')
278
+ })
279
+
280
+ cli
281
+ .command(
282
+ 'window resize <target> <width> <height>',
283
+ 'Resize a window. Target is a window title, ID, or app name.',
284
+ )
285
+ .action((target, width, height) => {
286
+ console.log('not implemented')
287
+ })
288
+
289
+ cli
290
+ .command(
291
+ 'window move <target> <x> <y>',
292
+ 'Move a window to absolute screen coordinates.',
293
+ )
294
+ .action((target, x, y) => {
295
+ console.log('not implemented')
296
+ })
297
+
298
+ cli
299
+ .command(
300
+ 'window minimize <target>',
301
+ 'Minimize a window.',
302
+ )
303
+ .action((target) => {
304
+ console.log('not implemented')
305
+ })
306
+
307
+ cli
308
+ .command(
309
+ 'window maximize <target>',
310
+ 'Maximize/fullscreen a window.',
311
+ )
312
+ .action((target) => {
313
+ console.log('not implemented')
314
+ })
315
+
316
+ cli
317
+ .command(
318
+ 'window close <target>',
319
+ 'Close a window.',
320
+ )
321
+ .action((target) => {
322
+ console.log('not implemented')
323
+ })
324
+
325
+ // ─── App Management ────────────────────────────────────────────────────
326
+
327
+ cli
328
+ .command(
329
+ 'app list',
330
+ 'List all running applications with their process IDs and window counts.',
331
+ )
332
+ .option('--json', 'Output as JSON')
333
+ .action((options) => {
334
+ console.log('not implemented')
335
+ })
336
+
337
+ cli
338
+ .command(
339
+ 'app launch <name>',
340
+ dedent`
341
+ Launch an application by name or path.
342
+
343
+ On macOS: app name ("Safari"), bundle ID ("com.apple.Safari"), or path.
344
+ On Linux: executable name or .desktop file.
345
+ On Windows: executable name or Start Menu shortcut.
346
+ `,
347
+ )
348
+ .option('--wait', 'Wait for the application window to appear before returning')
349
+ .action((name, options) => {
350
+ console.log('not implemented')
351
+ })
352
+
353
+ cli
354
+ .command(
355
+ 'app quit <name>',
356
+ 'Quit an application gracefully by name or process ID.',
357
+ )
358
+ .option('--force', 'Force-kill the application if it does not quit gracefully')
359
+ .action((name, options) => {
360
+ console.log('not implemented')
361
+ })
362
+
363
+ // ─── Clipboard ──────────────────────────────────────────────────────────
364
+
365
+ cli
366
+ .command(
367
+ 'clipboard get',
368
+ 'Print the current clipboard text content.',
369
+ )
370
+ .action(() => {
371
+ console.log('not implemented')
372
+ })
373
+
374
+ cli
375
+ .command(
376
+ 'clipboard set <text>',
377
+ 'Set the clipboard content to the given text.',
378
+ )
379
+ .action((text) => {
380
+ console.log('not implemented')
381
+ })
382
+
383
+ // ─── Wait ───────────────────────────────────────────────────────────────
384
+
385
+ cli
386
+ .command(
387
+ 'wait <target>',
388
+ dedent`
389
+ Wait for a condition before continuing.
390
+
391
+ Target can be:
392
+ - Milliseconds: "2000" (wait 2 seconds)
393
+ - Accessibility ref: "@e5" (wait for element to appear)
394
+ - Window title: "--window Untitled" (wait for window to appear)
395
+ `,
396
+ )
397
+ .option('-w, --window [window]', z.string().describe('Wait for a window with this title to appear'))
398
+ .option('--timeout [timeout]', z.number().default(30000).describe('Maximum wait time in milliseconds'))
399
+ .example('# Wait 2 seconds')
400
+ .example('usecomputer wait 2000')
401
+ .example('# Wait for an element to appear')
402
+ .example('usecomputer wait @e5')
403
+ .example('# Wait for a window to appear')
404
+ .example('usecomputer wait --window "Save As"')
405
+ .action((target, options) => {
406
+ console.log('not implemented')
407
+ })
408
+
409
+ // ─── Display ────────────────────────────────────────────────────────────
410
+
411
+ cli
412
+ .command(
413
+ 'display list',
414
+ 'List connected displays with their resolutions, positions, and scale factors.',
415
+ )
416
+ .option('--json', 'Output as JSON')
417
+ .action((options) => {
418
+ console.log('not implemented')
419
+ })
420
+
421
+ // ─── Find Elements ──────────────────────────────────────────────────────
422
+
423
+ cli
424
+ .command(
425
+ 'find <query>',
426
+ dedent`
427
+ Search for UI elements matching a text query across the accessibility tree.
428
+
429
+ Returns matching elements with their refs, roles, and positions.
430
+ Useful for locating elements before clicking or typing.
431
+ `,
432
+ )
433
+ .option('-w, --window [window]', z.string().describe('Scope search to a specific window'))
434
+ .option('-a, --app [app]', z.string().describe('Scope search to a specific application'))
435
+ .option('--role [role]', z.string().describe('Filter by accessibility role (button, textField, link, etc.)'))
436
+ .option('--limit [limit]', z.number().default(20).describe('Maximum number of results'))
437
+ .example('# Find all buttons with "Save" in the name')
438
+ .example('usecomputer find "Save" --role button')
439
+ .example('# Find elements in a specific app')
440
+ .example('usecomputer find "File" --app "Visual Studio Code"')
441
+ .action((query, options) => {
442
+ console.log('not implemented')
443
+ })
444
+
445
+ // ─── Diff ───────────────────────────────────────────────────────────────
446
+
447
+ cli
448
+ .command(
449
+ 'diff snapshot',
450
+ 'Compare the current accessibility snapshot against the previous one. Shows added, removed, and changed elements.',
451
+ )
452
+ .option('-w, --window [window]', z.string().describe('Scope to a specific window'))
453
+ .option('-a, --app [app]', z.string().describe('Scope to a specific application'))
454
+ .action((options) => {
455
+ console.log('not implemented')
456
+ })
457
+
458
+ cli
459
+ .command(
460
+ 'diff screenshot',
461
+ 'Compare the current screenshot against a baseline image. Highlights visual differences.',
462
+ )
463
+ .option('--baseline <baseline>', z.string().describe('Path to the baseline screenshot'))
464
+ .option('--threshold [threshold]', z.number().default(0.1).describe('Pixel difference threshold (0-1)'))
465
+ .action((options) => {
466
+ console.log('not implemented')
467
+ })
468
+
469
+ // ─── Global Options ─────────────────────────────────────────────────────
470
+
471
+ cli.option('--json', 'Output as JSON')
472
+ cli.option('--display [display]', z.number().describe('Target display/monitor index for multi-monitor setups'))
473
+ cli.option('--timeout [timeout]', z.number().default(25000).describe('Default timeout for operations in milliseconds'))
474
+ cli.option('--debug', 'Enable debug output')
475
+
476
+ cli.help()
477
+ cli.version(pkg.version)
478
+ cli.parse()
package/src/index.ts ADDED
@@ -0,0 +1,5 @@
1
+ // usecomputer — fast computer automation CLI for AI agents.
2
+ // Controls any desktop via accessibility APIs, mouse, keyboard, and screen capture.
3
+ // Cross-platform: macOS, Linux, Windows.
4
+
5
+ export {}