@skillful-agents/agent-computer 0.0.3
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/README.md +458 -0
- package/bin/ac-core-darwin-arm64 +0 -0
- package/bin/ac-core-darwin-x64 +0 -0
- package/bin/ac-core-win32-arm64.exe +0 -0
- package/bin/ac-core-win32-x64.exe +0 -0
- package/dist/bin/ac.d.ts +3 -0
- package/dist/bin/ac.d.ts.map +1 -0
- package/dist/bin/ac.js +126 -0
- package/dist/bin/ac.js.map +1 -0
- package/dist/src/bridge.d.ts +69 -0
- package/dist/src/bridge.d.ts.map +1 -0
- package/dist/src/bridge.js +687 -0
- package/dist/src/bridge.js.map +1 -0
- package/dist/src/cdp/ax-tree.d.ts +19 -0
- package/dist/src/cdp/ax-tree.d.ts.map +1 -0
- package/dist/src/cdp/ax-tree.js +159 -0
- package/dist/src/cdp/ax-tree.js.map +1 -0
- package/dist/src/cdp/bounds.d.ts +25 -0
- package/dist/src/cdp/bounds.d.ts.map +1 -0
- package/dist/src/cdp/bounds.js +62 -0
- package/dist/src/cdp/bounds.js.map +1 -0
- package/dist/src/cdp/client.d.ts +115 -0
- package/dist/src/cdp/client.d.ts.map +1 -0
- package/dist/src/cdp/client.js +269 -0
- package/dist/src/cdp/client.js.map +1 -0
- package/dist/src/cdp/connection.d.ts +25 -0
- package/dist/src/cdp/connection.d.ts.map +1 -0
- package/dist/src/cdp/connection.js +249 -0
- package/dist/src/cdp/connection.js.map +1 -0
- package/dist/src/cdp/diff.d.ts +17 -0
- package/dist/src/cdp/diff.d.ts.map +1 -0
- package/dist/src/cdp/diff.js +52 -0
- package/dist/src/cdp/diff.js.map +1 -0
- package/dist/src/cdp/discovery.d.ts +8 -0
- package/dist/src/cdp/discovery.d.ts.map +1 -0
- package/dist/src/cdp/discovery.js +54 -0
- package/dist/src/cdp/discovery.js.map +1 -0
- package/dist/src/cdp/index.d.ts +12 -0
- package/dist/src/cdp/index.d.ts.map +1 -0
- package/dist/src/cdp/index.js +10 -0
- package/dist/src/cdp/index.js.map +1 -0
- package/dist/src/cdp/interactions.d.ts +47 -0
- package/dist/src/cdp/interactions.d.ts.map +1 -0
- package/dist/src/cdp/interactions.js +298 -0
- package/dist/src/cdp/interactions.js.map +1 -0
- package/dist/src/cdp/port-manager.d.ts +3 -0
- package/dist/src/cdp/port-manager.d.ts.map +1 -0
- package/dist/src/cdp/port-manager.js +33 -0
- package/dist/src/cdp/port-manager.js.map +1 -0
- package/dist/src/cdp/role-map.d.ts +8 -0
- package/dist/src/cdp/role-map.d.ts.map +1 -0
- package/dist/src/cdp/role-map.js +99 -0
- package/dist/src/cdp/role-map.js.map +1 -0
- package/dist/src/cdp/types.d.ts +53 -0
- package/dist/src/cdp/types.d.ts.map +1 -0
- package/dist/src/cdp/types.js +2 -0
- package/dist/src/cdp/types.js.map +1 -0
- package/dist/src/cli/commands/apps.d.ts +2 -0
- package/dist/src/cli/commands/apps.d.ts.map +1 -0
- package/dist/src/cli/commands/apps.js +62 -0
- package/dist/src/cli/commands/apps.js.map +1 -0
- package/dist/src/cli/commands/batch.d.ts +2 -0
- package/dist/src/cli/commands/batch.d.ts.map +1 -0
- package/dist/src/cli/commands/batch.js +36 -0
- package/dist/src/cli/commands/batch.js.map +1 -0
- package/dist/src/cli/commands/click.d.ts +2 -0
- package/dist/src/cli/commands/click.d.ts.map +1 -0
- package/dist/src/cli/commands/click.js +60 -0
- package/dist/src/cli/commands/click.js.map +1 -0
- package/dist/src/cli/commands/clipboard.d.ts +2 -0
- package/dist/src/cli/commands/clipboard.d.ts.map +1 -0
- package/dist/src/cli/commands/clipboard.js +30 -0
- package/dist/src/cli/commands/clipboard.js.map +1 -0
- package/dist/src/cli/commands/dialog.d.ts +2 -0
- package/dist/src/cli/commands/dialog.d.ts.map +1 -0
- package/dist/src/cli/commands/dialog.js +44 -0
- package/dist/src/cli/commands/dialog.js.map +1 -0
- package/dist/src/cli/commands/drag.d.ts +2 -0
- package/dist/src/cli/commands/drag.d.ts.map +1 -0
- package/dist/src/cli/commands/drag.js +25 -0
- package/dist/src/cli/commands/drag.js.map +1 -0
- package/dist/src/cli/commands/find.d.ts +2 -0
- package/dist/src/cli/commands/find.d.ts.map +1 -0
- package/dist/src/cli/commands/find.js +98 -0
- package/dist/src/cli/commands/find.js.map +1 -0
- package/dist/src/cli/commands/menu.d.ts +2 -0
- package/dist/src/cli/commands/menu.d.ts.map +1 -0
- package/dist/src/cli/commands/menu.js +35 -0
- package/dist/src/cli/commands/menu.js.map +1 -0
- package/dist/src/cli/commands/screenshot.d.ts +2 -0
- package/dist/src/cli/commands/screenshot.d.ts.map +1 -0
- package/dist/src/cli/commands/screenshot.js +26 -0
- package/dist/src/cli/commands/screenshot.js.map +1 -0
- package/dist/src/cli/commands/scroll.d.ts +2 -0
- package/dist/src/cli/commands/scroll.d.ts.map +1 -0
- package/dist/src/cli/commands/scroll.js +76 -0
- package/dist/src/cli/commands/scroll.js.map +1 -0
- package/dist/src/cli/commands/session.d.ts +2 -0
- package/dist/src/cli/commands/session.d.ts.map +1 -0
- package/dist/src/cli/commands/session.js +26 -0
- package/dist/src/cli/commands/session.js.map +1 -0
- package/dist/src/cli/commands/snapshot.d.ts +2 -0
- package/dist/src/cli/commands/snapshot.d.ts.map +1 -0
- package/dist/src/cli/commands/snapshot.js +23 -0
- package/dist/src/cli/commands/snapshot.js.map +1 -0
- package/dist/src/cli/commands/type.d.ts +2 -0
- package/dist/src/cli/commands/type.d.ts.map +1 -0
- package/dist/src/cli/commands/type.js +68 -0
- package/dist/src/cli/commands/type.js.map +1 -0
- package/dist/src/cli/commands/windowmgmt.d.ts +2 -0
- package/dist/src/cli/commands/windowmgmt.d.ts.map +1 -0
- package/dist/src/cli/commands/windowmgmt.js +61 -0
- package/dist/src/cli/commands/windowmgmt.js.map +1 -0
- package/dist/src/cli/commands/windows.d.ts +2 -0
- package/dist/src/cli/commands/windows.d.ts.map +1 -0
- package/dist/src/cli/commands/windows.js +9 -0
- package/dist/src/cli/commands/windows.js.map +1 -0
- package/dist/src/cli/commands.d.ts +13 -0
- package/dist/src/cli/commands.d.ts.map +1 -0
- package/dist/src/cli/commands.js +177 -0
- package/dist/src/cli/commands.js.map +1 -0
- package/dist/src/cli/output.d.ts +4 -0
- package/dist/src/cli/output.d.ts.map +1 -0
- package/dist/src/cli/output.js +249 -0
- package/dist/src/cli/output.js.map +1 -0
- package/dist/src/cli/parser.d.ts +19 -0
- package/dist/src/cli/parser.d.ts.map +1 -0
- package/dist/src/cli/parser.js +125 -0
- package/dist/src/cli/parser.js.map +1 -0
- package/dist/src/config.d.ts +14 -0
- package/dist/src/config.d.ts.map +1 -0
- package/dist/src/config.js +73 -0
- package/dist/src/config.js.map +1 -0
- package/dist/src/daemon.d.ts +21 -0
- package/dist/src/daemon.d.ts.map +1 -0
- package/dist/src/daemon.js +180 -0
- package/dist/src/daemon.js.map +1 -0
- package/dist/src/errors.d.ts +39 -0
- package/dist/src/errors.d.ts.map +1 -0
- package/dist/src/errors.js +103 -0
- package/dist/src/errors.js.map +1 -0
- package/dist/src/index.d.ts +8 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +8 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/platform/index.d.ts +6 -0
- package/dist/src/platform/index.d.ts.map +1 -0
- package/dist/src/platform/index.js +14 -0
- package/dist/src/platform/index.js.map +1 -0
- package/dist/src/platform/resolve.d.ts +2 -0
- package/dist/src/platform/resolve.d.ts.map +1 -0
- package/dist/src/platform/resolve.js +54 -0
- package/dist/src/platform/resolve.js.map +1 -0
- package/dist/src/refs.d.ts +12 -0
- package/dist/src/refs.d.ts.map +1 -0
- package/dist/src/refs.js +85 -0
- package/dist/src/refs.js.map +1 -0
- package/dist/src/sdk.d.ts +258 -0
- package/dist/src/sdk.d.ts.map +1 -0
- package/dist/src/sdk.js +285 -0
- package/dist/src/sdk.js.map +1 -0
- package/dist/src/types.d.ts +93 -0
- package/dist/src/types.d.ts.map +1 -0
- package/dist/src/types.js +9 -0
- package/dist/src/types.js.map +1 -0
- package/package.json +67 -0
- package/schema/examples/click.response.example.json +9 -0
- package/schema/examples/error.response.example.json +12 -0
- package/schema/examples/ping.response.example.json +7 -0
- package/schema/examples/snapshot.response.example.json +50 -0
- package/schema/methods/click.request.json +26 -0
- package/schema/methods/click.response.json +24 -0
- package/schema/methods/error.response.json +19 -0
- package/schema/methods/ping.request.json +12 -0
- package/schema/methods/ping.response.json +17 -0
- package/schema/methods/snapshot.request.json +24 -0
- package/schema/methods/snapshot.response.json +23 -0
- package/schema/methods/status.request.json +12 -0
- package/schema/methods/status.response.json +20 -0
- package/schema/types/element.json +26 -0
- package/schema/types/normalized-role.json +13 -0
- package/schema/types/ref.json +7 -0
- package/schema/types/window-info.json +24 -0
- package/scripts/build-macos.sh +5 -0
- package/scripts/postinstall.js +35 -0
package/README.md
ADDED
|
@@ -0,0 +1,458 @@
|
|
|
1
|
+
# agent-computer — Agent Computer
|
|
2
|
+
|
|
3
|
+
Native macOS desktop automation CLI for AI agents. Control any app through the accessibility tree.
|
|
4
|
+
|
|
5
|
+
Built for the **snapshot → act** loop: take a snapshot of any app's UI, get typed refs (`@b1`, `@t2`), then click, type, and navigate — all from the command line or TypeScript SDK.
|
|
6
|
+
|
|
7
|
+
## Why agent-computer?
|
|
8
|
+
|
|
9
|
+
- **Works with any macOS app** — native apps (TextEdit, Safari, Finder) have rich accessibility trees; Electron apps work too with automatic detection and guidance
|
|
10
|
+
- **Typed refs** — snapshot returns prefixed refs: `@b3` (button), `@t5` (text field), `@c1` (checkbox) — easy for LLMs to reason about
|
|
11
|
+
- **Short commands** — agents generate these token-by-token; fewer tokens = cheaper + faster
|
|
12
|
+
- **Fast** — persistent daemon with ~5ms per command over Unix domain socket
|
|
13
|
+
- **Auto-focus** — keyboard commands auto-switch to the grabbed app and restore your previous window
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm install -g @skillful-agents/agent-computer
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Or as a project dependency:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npm install @skillful-agents/agent-computer
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### Requirements
|
|
28
|
+
|
|
29
|
+
- macOS 13+ (Ventura or later)
|
|
30
|
+
- Node.js 20+
|
|
31
|
+
- **Accessibility permission** must be granted to your terminal app
|
|
32
|
+
|
|
33
|
+
### Permissions
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
agent-computer permissions # check permission status
|
|
37
|
+
agent-computer permissions grant # opens System Settings
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Grant **Accessibility** access to your terminal (Terminal.app, iTerm2, Ghostty, etc.) in System Settings → Privacy & Security → Accessibility. Screen Recording permission is needed for screenshots.
|
|
41
|
+
|
|
42
|
+
## Quick Start
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
# 1. See what's running
|
|
46
|
+
agent-computer apps
|
|
47
|
+
|
|
48
|
+
# 2. Pick a window
|
|
49
|
+
agent-computer windows
|
|
50
|
+
agent-computer grab @w1
|
|
51
|
+
|
|
52
|
+
# 3. Snapshot the UI (interactive elements only)
|
|
53
|
+
agent-computer snapshot -i
|
|
54
|
+
|
|
55
|
+
# 4. Interact using refs from the snapshot
|
|
56
|
+
agent-computer click @b3
|
|
57
|
+
agent-computer fill @t1 "Hello, world!"
|
|
58
|
+
agent-computer key cmd+s
|
|
59
|
+
|
|
60
|
+
# 5. Take a screenshot to see the result
|
|
61
|
+
agent-computer screenshot
|
|
62
|
+
|
|
63
|
+
# 6. Release the window
|
|
64
|
+
agent-computer ungrab
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Core Workflow
|
|
68
|
+
|
|
69
|
+
The fundamental loop for AI agents:
|
|
70
|
+
|
|
71
|
+
```
|
|
72
|
+
agent-computer snapshot -i → read refs → agent-computer click @b1 → agent-computer snapshot -i → ...
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
1. **Observe** — `agent-computer snapshot -i` returns the accessibility tree with typed refs
|
|
76
|
+
2. **Act** — `agent-computer click @b1`, `agent-computer fill @t2 "text"`, `agent-computer key cmd+s`
|
|
77
|
+
3. **Verify** — `agent-computer snapshot -i` again, or `agent-computer screenshot` for visual confirmation
|
|
78
|
+
|
|
79
|
+
## Command Reference
|
|
80
|
+
|
|
81
|
+
### Snapshot & Observation
|
|
82
|
+
|
|
83
|
+
| Command | Description |
|
|
84
|
+
|---------|-------------|
|
|
85
|
+
| `agent-computer snapshot` | Full accessibility tree of the active window |
|
|
86
|
+
| `agent-computer snapshot -i` | Interactive elements only (buttons, fields, etc.) |
|
|
87
|
+
| `agent-computer snapshot -c` | Compact flat list |
|
|
88
|
+
| `agent-computer snapshot -d 3` | Limit tree depth |
|
|
89
|
+
| `agent-computer snapshot --app Safari` | Target a specific app |
|
|
90
|
+
| `agent-computer screenshot` | Take a screenshot (PNG) |
|
|
91
|
+
| `agent-computer screenshot /tmp/shot.png` | Save to specific path |
|
|
92
|
+
| `agent-computer find "Save"` | Find elements by text |
|
|
93
|
+
| `agent-computer find --role button` | Find elements by role |
|
|
94
|
+
| `agent-computer read @t1` | Read an element's value |
|
|
95
|
+
|
|
96
|
+
### Click & Mouse
|
|
97
|
+
|
|
98
|
+
| Command | Description |
|
|
99
|
+
|---------|-------------|
|
|
100
|
+
| `agent-computer click @b1` | Click an element by ref |
|
|
101
|
+
| `agent-computer click 500,300` | Click at screen coordinates |
|
|
102
|
+
| `agent-computer click @b1 --right` | Right-click |
|
|
103
|
+
| `agent-computer click @b1 --double` | Double-click |
|
|
104
|
+
| `agent-computer hover @b1` | Move mouse to element |
|
|
105
|
+
| `agent-computer drag @b1 @b2` | Drag from one element to another |
|
|
106
|
+
| `agent-computer drag --from-x 100 --from-y 200 --to-x 300 --to-y 400` | Drag by coordinates |
|
|
107
|
+
|
|
108
|
+
### Keyboard & Text
|
|
109
|
+
|
|
110
|
+
| Command | Description |
|
|
111
|
+
|---------|-------------|
|
|
112
|
+
| `agent-computer type "Hello"` | Type text into the focused element |
|
|
113
|
+
| `agent-computer fill @t1 "text"` | Focus, clear, and set text on an element |
|
|
114
|
+
| `agent-computer key cmd+a` | Press a key combination |
|
|
115
|
+
| `agent-computer key cmd+c` | Copy |
|
|
116
|
+
| `agent-computer key enter` | Press Enter |
|
|
117
|
+
| `agent-computer paste "text"` | Paste text via clipboard |
|
|
118
|
+
|
|
119
|
+
> **Auto-focus:** When a window is grabbed, `key`, `type`, `keydown`, `keyup`, and `paste` automatically switch to the grabbed app, perform the action, then switch back to your previous window.
|
|
120
|
+
|
|
121
|
+
### Apps & Windows
|
|
122
|
+
|
|
123
|
+
| Command | Description |
|
|
124
|
+
|---------|-------------|
|
|
125
|
+
| `agent-computer apps` | List running applications |
|
|
126
|
+
| `agent-computer launch TextEdit --wait` | Launch an app and wait for it to be ready |
|
|
127
|
+
| `agent-computer quit TextEdit` | Quit an app |
|
|
128
|
+
| `agent-computer switch Safari` | Bring an app to the foreground |
|
|
129
|
+
| `agent-computer windows` | List all windows with refs |
|
|
130
|
+
| `agent-computer grab @w1` | Lock onto a window for subsequent commands |
|
|
131
|
+
| `agent-computer grab --app TextEdit` | Grab the first window of an app |
|
|
132
|
+
| `agent-computer ungrab` | Release the grabbed window |
|
|
133
|
+
|
|
134
|
+
### Window Management
|
|
135
|
+
|
|
136
|
+
| Command | Description |
|
|
137
|
+
|---------|-------------|
|
|
138
|
+
| `agent-computer minimize` | Minimize the grabbed window |
|
|
139
|
+
| `agent-computer maximize` | Maximize (zoom) the grabbed window |
|
|
140
|
+
| `agent-computer fullscreen` | Toggle fullscreen |
|
|
141
|
+
| `agent-computer close` | Close the grabbed window |
|
|
142
|
+
| `agent-computer raise` | Bring window to front |
|
|
143
|
+
| `agent-computer move --x 100 --y 200` | Move window |
|
|
144
|
+
| `agent-computer resize --width 800 --height 600` | Resize window |
|
|
145
|
+
| `agent-computer bounds --preset left-half` | Snap to preset (left-half, right-half, fill, center) |
|
|
146
|
+
|
|
147
|
+
### Menus
|
|
148
|
+
|
|
149
|
+
| Command | Description |
|
|
150
|
+
|---------|-------------|
|
|
151
|
+
| `agent-computer menu list` | List top-level menus |
|
|
152
|
+
| `agent-computer menu list Edit` | List items in a menu |
|
|
153
|
+
| `agent-computer menu "Edit > Select All"` | Click a menu item by path |
|
|
154
|
+
| `agent-computer menu "Format > Font > Bold"` | Navigate nested menus |
|
|
155
|
+
|
|
156
|
+
### Scroll & Focus
|
|
157
|
+
|
|
158
|
+
| Command | Description |
|
|
159
|
+
|---------|-------------|
|
|
160
|
+
| `agent-computer scroll down` | Scroll down (3 ticks) |
|
|
161
|
+
| `agent-computer scroll up 10` | Scroll up 10 ticks |
|
|
162
|
+
| `agent-computer scroll down --on @sa1` | Scroll within a specific element |
|
|
163
|
+
| `agent-computer scroll down --smooth` | Smooth animated scroll |
|
|
164
|
+
| `agent-computer focus @t1` | Focus an element |
|
|
165
|
+
| `agent-computer check @c1` | Check a checkbox |
|
|
166
|
+
| `agent-computer uncheck @c1` | Uncheck a checkbox |
|
|
167
|
+
| `agent-computer select @d1 --value "Option"` | Select a dropdown value |
|
|
168
|
+
|
|
169
|
+
### Clipboard
|
|
170
|
+
|
|
171
|
+
| Command | Description |
|
|
172
|
+
|---------|-------------|
|
|
173
|
+
| `agent-computer clipboard` | Read clipboard contents |
|
|
174
|
+
| `agent-computer clipboard set "text"` | Set clipboard contents |
|
|
175
|
+
|
|
176
|
+
### Dialogs & Alerts
|
|
177
|
+
|
|
178
|
+
| Command | Description |
|
|
179
|
+
|---------|-------------|
|
|
180
|
+
| `agent-computer dialog` | Detect if a dialog/alert is visible |
|
|
181
|
+
| `agent-computer dialog accept` | Click OK/Save on the dialog |
|
|
182
|
+
| `agent-computer dialog cancel` | Dismiss the dialog |
|
|
183
|
+
| `agent-computer dialog file /tmp/doc.txt` | Set filename in a file save dialog |
|
|
184
|
+
|
|
185
|
+
### Wait
|
|
186
|
+
|
|
187
|
+
| Command | Description |
|
|
188
|
+
|---------|-------------|
|
|
189
|
+
| `agent-computer wait 2000` | Wait for 2 seconds |
|
|
190
|
+
| `agent-computer wait --app TextEdit` | Wait for an app to launch |
|
|
191
|
+
| `agent-computer wait --text "Loading complete"` | Wait for text to appear |
|
|
192
|
+
| `agent-computer wait --text "Loading" --gone` | Wait for text to disappear |
|
|
193
|
+
|
|
194
|
+
### Batch & Diff
|
|
195
|
+
|
|
196
|
+
| Command | Description |
|
|
197
|
+
|---------|-------------|
|
|
198
|
+
| `agent-computer batch '[["click","@b1"],["key","enter"]]'` | Execute commands sequentially |
|
|
199
|
+
| `agent-computer changed` | Check if UI changed since last snapshot |
|
|
200
|
+
| `agent-computer diff` | Get added/removed elements since last snapshot |
|
|
201
|
+
|
|
202
|
+
### System
|
|
203
|
+
|
|
204
|
+
| Command | Description |
|
|
205
|
+
|---------|-------------|
|
|
206
|
+
| `agent-computer status` | Show session state (grabbed window, daemon info) |
|
|
207
|
+
| `agent-computer daemon start\|stop\|restart\|status` | Manage the background daemon |
|
|
208
|
+
| `agent-computer permissions` | Check accessibility/screen recording permissions |
|
|
209
|
+
| `agent-computer doctor` | Run diagnostics |
|
|
210
|
+
| `agent-computer displays` | List connected displays |
|
|
211
|
+
| `agent-computer version` | Print version |
|
|
212
|
+
|
|
213
|
+
## Ref System
|
|
214
|
+
|
|
215
|
+
Snapshots assign typed refs based on element role:
|
|
216
|
+
|
|
217
|
+
| Prefix | Role | Example |
|
|
218
|
+
|--------|------|---------|
|
|
219
|
+
| `@b` | Button | `@b1`, `@b2` |
|
|
220
|
+
| `@t` | Text field | `@t1` |
|
|
221
|
+
| `@l` | Link | `@l1` |
|
|
222
|
+
| `@c` | Checkbox | `@c1` |
|
|
223
|
+
| `@r` | Radio button | `@r1` |
|
|
224
|
+
| `@s` | Slider | `@s1` |
|
|
225
|
+
| `@d` | Dropdown | `@d1` |
|
|
226
|
+
| `@i` | Image | `@i1` |
|
|
227
|
+
| `@g` | Group | `@g1` |
|
|
228
|
+
| `@w` | Window | `@w1` |
|
|
229
|
+
| `@m` | Menu item | `@m1` |
|
|
230
|
+
| `@sa` | Scroll area | `@sa1` |
|
|
231
|
+
| `@cb` | Combo box | `@cb1` |
|
|
232
|
+
| `@x` | Generic | `@x1` |
|
|
233
|
+
|
|
234
|
+
Refs are stable within a snapshot but re-assigned on each new snapshot.
|
|
235
|
+
|
|
236
|
+
## Global Options
|
|
237
|
+
|
|
238
|
+
| Flag | Description |
|
|
239
|
+
|------|-------------|
|
|
240
|
+
| `--json` | JSON output (default is human-readable text) |
|
|
241
|
+
| `--timeout <ms>` | Override default timeout (default: 10000) |
|
|
242
|
+
| `--verbose` | Debug logging to stderr |
|
|
243
|
+
| `--content-boundary` | Wrap output in delimiters for LLM safety |
|
|
244
|
+
| `--max-output <n>` | Truncate output to N characters |
|
|
245
|
+
| `--app <name>` | Target a specific app (for snapshot, find, menu, etc.) |
|
|
246
|
+
|
|
247
|
+
### Environment Variables
|
|
248
|
+
|
|
249
|
+
| Variable | Description |
|
|
250
|
+
|----------|-------------|
|
|
251
|
+
| `AC_JSON` | Set to `1` for JSON output |
|
|
252
|
+
| `AC_VERBOSE` | Set to `1` for debug logging |
|
|
253
|
+
|
|
254
|
+
## TypeScript SDK
|
|
255
|
+
|
|
256
|
+
Use `agent-computer` programmatically from Node.js:
|
|
257
|
+
|
|
258
|
+
```typescript
|
|
259
|
+
import { AC } from '@skillful-agents/agent-computer';
|
|
260
|
+
|
|
261
|
+
const ac = new AC();
|
|
262
|
+
|
|
263
|
+
// Launch and interact with TextEdit
|
|
264
|
+
await ac.launch('TextEdit', { wait: true });
|
|
265
|
+
await ac.grab('TextEdit');
|
|
266
|
+
|
|
267
|
+
const snap = await ac.snapshot({ interactive: true });
|
|
268
|
+
const textarea = snap.elements.find(e => e.role === 'textarea');
|
|
269
|
+
|
|
270
|
+
if (textarea) {
|
|
271
|
+
await ac.fill(textarea.ref, 'Hello from the SDK!');
|
|
272
|
+
await ac.key('cmd+a');
|
|
273
|
+
await ac.menuClick('Format > Font > Bold', 'TextEdit');
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
await ac.screenshot({ path: '/tmp/result.png' });
|
|
277
|
+
await ac.quit('TextEdit');
|
|
278
|
+
await ac.disconnect();
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
### SDK Methods
|
|
282
|
+
|
|
283
|
+
The `AC` class provides typed methods for every CLI command:
|
|
284
|
+
|
|
285
|
+
```typescript
|
|
286
|
+
// Observation
|
|
287
|
+
await ac.snapshot({ interactive: true, app: 'Safari' });
|
|
288
|
+
await ac.find('Submit', { role: 'button' });
|
|
289
|
+
await ac.read('@t1');
|
|
290
|
+
await ac.is('enabled', '@b1');
|
|
291
|
+
|
|
292
|
+
// Actions
|
|
293
|
+
await ac.click('@b1');
|
|
294
|
+
await ac.clickAt(500, 300);
|
|
295
|
+
await ac.fill('@t1', 'text');
|
|
296
|
+
await ac.key('cmd+s');
|
|
297
|
+
await ac.scroll('down', { amount: 5 });
|
|
298
|
+
await ac.drag('@b1', '@b2');
|
|
299
|
+
|
|
300
|
+
// Menus
|
|
301
|
+
await ac.menuClick('File > Save');
|
|
302
|
+
await ac.menuList('Edit');
|
|
303
|
+
|
|
304
|
+
// Apps & Windows
|
|
305
|
+
await ac.launch('Calculator', { wait: true });
|
|
306
|
+
await ac.grab('Calculator');
|
|
307
|
+
await ac.windows();
|
|
308
|
+
await ac.ungrab();
|
|
309
|
+
|
|
310
|
+
// Dialogs
|
|
311
|
+
const dialog = await ac.dialog();
|
|
312
|
+
if (dialog.found) await ac.dialogAccept();
|
|
313
|
+
|
|
314
|
+
// Wait
|
|
315
|
+
await ac.waitForText('Loading complete', { timeout: 10000 });
|
|
316
|
+
await ac.waitForApp('Safari');
|
|
317
|
+
|
|
318
|
+
// Batch
|
|
319
|
+
await ac.batch([['click', '@b1'], ['key', 'enter']]);
|
|
320
|
+
|
|
321
|
+
// Diff
|
|
322
|
+
const { changed } = await ac.changed();
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
## Architecture
|
|
326
|
+
|
|
327
|
+
```
|
|
328
|
+
┌─────────────────────────────────────────────┐
|
|
329
|
+
│ CLI (bin/ac.ts) or SDK (AC class) │
|
|
330
|
+
├─────────────────────────────────────────────┤
|
|
331
|
+
│ Bridge — JSON-RPC 2.0 over Unix socket │
|
|
332
|
+
├─────────────────────────────────────────────┤
|
|
333
|
+
│ Daemon (ac-core) — persistent Swift binary │
|
|
334
|
+
│ ┌─────────┬──────────┬──────────┐ │
|
|
335
|
+
│ │ AX Tree │ CGEvent │ Screen │ │
|
|
336
|
+
│ │ Walking │ Input │ Capture │ │
|
|
337
|
+
│ └─────────┴──────────┴──────────┘ │
|
|
338
|
+
├─────────────────────────────────────────────┤
|
|
339
|
+
│ macOS Accessibility + CoreGraphics APIs │
|
|
340
|
+
└─────────────────────────────────────────────┘
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
- **CLI/SDK** — TypeScript, parses commands, manages daemon lifecycle
|
|
344
|
+
- **Bridge** — JSON-RPC 2.0 over Unix domain socket, auto-starts daemon
|
|
345
|
+
- **Daemon** — Native Swift binary, stays running (~5ms per command vs ~80ms one-shot)
|
|
346
|
+
- **Native APIs** — AXUIElement for accessibility tree, CGEvent for input, screencapture for screenshots
|
|
347
|
+
|
|
348
|
+
## Chromium/Electron Apps
|
|
349
|
+
|
|
350
|
+
Electron apps (Spotify, Slack, VS Code, Discord) have limited accessibility trees. `agent-computer` automatically detects Chromium-based apps and shows a warning:
|
|
351
|
+
|
|
352
|
+
```
|
|
353
|
+
⚠️ This is a Chromium/Electron app. The accessibility tree may be limited.
|
|
354
|
+
Consider using keyboard shortcuts, coordinate-based clicks (agent-computer click x,y),
|
|
355
|
+
or screenshots for navigation.
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
For Electron apps, prefer:
|
|
359
|
+
- **Keyboard shortcuts** — `agent-computer key cmd+f`, `agent-computer key space`
|
|
360
|
+
- **Coordinate clicks** — `agent-computer screenshot` to find positions, then `agent-computer click 500,300`
|
|
361
|
+
- **Paste** — `agent-computer paste "text"` instead of `agent-computer fill`
|
|
362
|
+
|
|
363
|
+
## Human-Like Mode
|
|
364
|
+
|
|
365
|
+
For automation that needs to appear more natural:
|
|
366
|
+
|
|
367
|
+
```bash
|
|
368
|
+
# Curved mouse movement (Bezier path)
|
|
369
|
+
agent-computer human_move --x 500 --y 300
|
|
370
|
+
|
|
371
|
+
# Variable-cadence typing
|
|
372
|
+
agent-computer human_type --text "Hello there" --delay 50
|
|
373
|
+
|
|
374
|
+
# Click with slight positional jitter
|
|
375
|
+
agent-computer human_click --ref @b1
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
## Examples
|
|
379
|
+
|
|
380
|
+
### Fill a form in Safari
|
|
381
|
+
|
|
382
|
+
```bash
|
|
383
|
+
agent-computer launch Safari --wait
|
|
384
|
+
agent-computer grab --app Safari
|
|
385
|
+
agent-computer snapshot -i
|
|
386
|
+
agent-computer fill @t1 "https://example.com"
|
|
387
|
+
agent-computer key enter
|
|
388
|
+
agent-computer wait --text "Example Domain"
|
|
389
|
+
agent-computer snapshot -i
|
|
390
|
+
agent-computer screenshot /tmp/page.png
|
|
391
|
+
agent-computer ungrab
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+
### Calculator arithmetic
|
|
395
|
+
|
|
396
|
+
```bash
|
|
397
|
+
agent-computer launch Calculator --wait
|
|
398
|
+
agent-computer grab --app Calculator
|
|
399
|
+
agent-computer snapshot -i
|
|
400
|
+
agent-computer click @b7 # 7
|
|
401
|
+
agent-computer click @b12 # +
|
|
402
|
+
agent-computer click @b3 # 3
|
|
403
|
+
agent-computer click @b15 # =
|
|
404
|
+
agent-computer snapshot -i # read the display
|
|
405
|
+
agent-computer quit Calculator
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
### Cross-app copy/paste
|
|
409
|
+
|
|
410
|
+
```bash
|
|
411
|
+
agent-computer launch TextEdit --wait
|
|
412
|
+
agent-computer grab --app TextEdit
|
|
413
|
+
agent-computer snapshot -i
|
|
414
|
+
agent-computer fill @t1 "Transfer this text"
|
|
415
|
+
agent-computer key cmd+a
|
|
416
|
+
agent-computer key cmd+c
|
|
417
|
+
agent-computer launch Notes --wait
|
|
418
|
+
agent-computer grab --app Notes
|
|
419
|
+
agent-computer key cmd+v
|
|
420
|
+
agent-computer snapshot -i
|
|
421
|
+
```
|
|
422
|
+
|
|
423
|
+
### Batch operations
|
|
424
|
+
|
|
425
|
+
```bash
|
|
426
|
+
agent-computer batch '[["clipboard_set", {"text": "Hello"}], ["clipboard_read"]]'
|
|
427
|
+
```
|
|
428
|
+
|
|
429
|
+
## Troubleshooting
|
|
430
|
+
|
|
431
|
+
### "Accessibility permission not granted"
|
|
432
|
+
|
|
433
|
+
Open System Settings → Privacy & Security → Accessibility and add your terminal app.
|
|
434
|
+
|
|
435
|
+
### Daemon not starting
|
|
436
|
+
|
|
437
|
+
```bash
|
|
438
|
+
agent-computer daemon status # check if running
|
|
439
|
+
agent-computer daemon restart # restart
|
|
440
|
+
agent-computer doctor # full diagnostics
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
### Stale refs
|
|
444
|
+
|
|
445
|
+
Refs are re-assigned on each snapshot. If you get "Element not found", take a new snapshot:
|
|
446
|
+
|
|
447
|
+
```bash
|
|
448
|
+
agent-computer snapshot -i # get fresh refs
|
|
449
|
+
agent-computer click @b1 # now use the new refs
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
## License
|
|
453
|
+
|
|
454
|
+
MIT
|
|
455
|
+
|
|
456
|
+
## Credits
|
|
457
|
+
|
|
458
|
+
Inspired by [agent-browser](https://github.com/anthropics/agent-browser) and [Peekaboo](https://github.com/steipete/Peekaboo).
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/dist/bin/ac.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ac.d.ts","sourceRoot":"","sources":["../../bin/ac.ts"],"names":[],"mappings":""}
|
package/dist/bin/ac.js
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { parseArgs } from '../src/cli/parser.js';
|
|
3
|
+
import { getCommand, getCommandAsync } from '../src/cli/commands.js';
|
|
4
|
+
import { formatOutput, wrapBoundary, truncateOutput } from '../src/cli/output.js';
|
|
5
|
+
import { Bridge } from '../src/bridge.js';
|
|
6
|
+
import { ACError } from '../src/errors.js';
|
|
7
|
+
import { resolveConfig } from '../src/config.js';
|
|
8
|
+
async function main() {
|
|
9
|
+
const parsed = parseArgs(process.argv);
|
|
10
|
+
const config = resolveConfig();
|
|
11
|
+
// Resolve global options
|
|
12
|
+
const jsonMode = parsed.flags['json'] === true || process.env.AC_JSON === '1';
|
|
13
|
+
const textMode = !jsonMode;
|
|
14
|
+
const verbose = parsed.flags['verbose'] === true || process.env.AC_VERBOSE === '1';
|
|
15
|
+
const contentBoundary = parsed.flags['content-boundary'] === true || config['content-boundary'];
|
|
16
|
+
const maxOutput = typeof parsed.flags['max-output'] === 'string'
|
|
17
|
+
? parseInt(parsed.flags['max-output'], 10)
|
|
18
|
+
: undefined;
|
|
19
|
+
const timeout = typeof parsed.flags['timeout'] === 'string'
|
|
20
|
+
? parseInt(parsed.flags['timeout'], 10)
|
|
21
|
+
: config['default-timeout'];
|
|
22
|
+
if (verbose) {
|
|
23
|
+
process.env.AC_VERBOSE = '1';
|
|
24
|
+
}
|
|
25
|
+
// Special case: help outputs plain text
|
|
26
|
+
if (parsed.command === 'help') {
|
|
27
|
+
const handler = getCommand('help');
|
|
28
|
+
const result = await handler(parsed, null);
|
|
29
|
+
console.log(result.data);
|
|
30
|
+
process.exit(0);
|
|
31
|
+
}
|
|
32
|
+
// Find command handler
|
|
33
|
+
const handler = await getCommandAsync(parsed.command);
|
|
34
|
+
if (!handler) {
|
|
35
|
+
// Try sending as a raw method to the daemon
|
|
36
|
+
const bridge = new Bridge({ timeout });
|
|
37
|
+
try {
|
|
38
|
+
const result = await bridge.send(parsed.command, buildParamsFromArgs(parsed));
|
|
39
|
+
output(result, textMode, contentBoundary, maxOutput);
|
|
40
|
+
await bridge.disconnect();
|
|
41
|
+
process.exit(0);
|
|
42
|
+
}
|
|
43
|
+
catch (err) {
|
|
44
|
+
if (err instanceof ACError) {
|
|
45
|
+
outputError(err, textMode);
|
|
46
|
+
await bridge.disconnect();
|
|
47
|
+
process.exit(err.exitCode);
|
|
48
|
+
}
|
|
49
|
+
console.error(`Unknown command: ${parsed.command}. Run 'agent-computer --help' for usage.`);
|
|
50
|
+
await bridge.disconnect();
|
|
51
|
+
process.exit(126);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
// Execute command
|
|
55
|
+
const bridge = new Bridge({ timeout });
|
|
56
|
+
try {
|
|
57
|
+
const result = await handler(parsed, bridge);
|
|
58
|
+
// Show hint (e.g., Chromium app warning) on stderr
|
|
59
|
+
if (result.data && typeof result.data === 'object' && 'hint' in result.data) {
|
|
60
|
+
const hint = result.data.hint;
|
|
61
|
+
process.stderr.write(`\n⚠️ ${hint}\n\n`);
|
|
62
|
+
}
|
|
63
|
+
output(result.data, textMode, contentBoundary, maxOutput);
|
|
64
|
+
await bridge.disconnect();
|
|
65
|
+
process.exit(result.exitCode);
|
|
66
|
+
}
|
|
67
|
+
catch (err) {
|
|
68
|
+
if (err instanceof ACError) {
|
|
69
|
+
outputError(err, textMode);
|
|
70
|
+
await bridge.disconnect();
|
|
71
|
+
process.exit(err.exitCode);
|
|
72
|
+
}
|
|
73
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
74
|
+
console.error(textMode ? `Error: ${message}` : JSON.stringify({ error: message }));
|
|
75
|
+
await bridge.disconnect();
|
|
76
|
+
process.exit(126);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
function output(data, textMode, boundary, maxOutput) {
|
|
80
|
+
let out;
|
|
81
|
+
if (typeof data === 'string') {
|
|
82
|
+
out = data;
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
out = formatOutput(data, textMode);
|
|
86
|
+
}
|
|
87
|
+
if (maxOutput) {
|
|
88
|
+
out = truncateOutput(out, maxOutput);
|
|
89
|
+
}
|
|
90
|
+
if (boundary) {
|
|
91
|
+
out = wrapBoundary(out);
|
|
92
|
+
}
|
|
93
|
+
console.log(out);
|
|
94
|
+
}
|
|
95
|
+
function outputError(err, textMode) {
|
|
96
|
+
if (textMode) {
|
|
97
|
+
console.error(`Error [${err.name}]: ${err.message}`);
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
console.error(JSON.stringify({
|
|
101
|
+
error: {
|
|
102
|
+
code: err.code,
|
|
103
|
+
name: err.name,
|
|
104
|
+
message: err.message,
|
|
105
|
+
data: err.data,
|
|
106
|
+
},
|
|
107
|
+
}));
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
function buildParamsFromArgs(parsed) {
|
|
111
|
+
const params = { ...parsed.flags };
|
|
112
|
+
if (parsed.positional.length > 0) {
|
|
113
|
+
params._positional = parsed.positional;
|
|
114
|
+
// Common pattern: first positional is a ref or selector
|
|
115
|
+
params.ref = parsed.positional[0];
|
|
116
|
+
}
|
|
117
|
+
if (parsed.subcommand) {
|
|
118
|
+
params._subcommand = parsed.subcommand;
|
|
119
|
+
}
|
|
120
|
+
return params;
|
|
121
|
+
}
|
|
122
|
+
main().catch((err) => {
|
|
123
|
+
console.error(err);
|
|
124
|
+
process.exit(126);
|
|
125
|
+
});
|
|
126
|
+
//# sourceMappingURL=ac.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ac.js","sourceRoot":"","sources":["../../bin/ac.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
export interface RPCRequest {
|
|
2
|
+
jsonrpc: '2.0';
|
|
3
|
+
id: number;
|
|
4
|
+
method: string;
|
|
5
|
+
params: Record<string, unknown>;
|
|
6
|
+
}
|
|
7
|
+
export interface RPCResponse {
|
|
8
|
+
jsonrpc: '2.0';
|
|
9
|
+
id: number;
|
|
10
|
+
result?: unknown;
|
|
11
|
+
error?: {
|
|
12
|
+
code: number;
|
|
13
|
+
message: string;
|
|
14
|
+
data?: Record<string, unknown>;
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
export declare function buildRequest(method: string, params?: Record<string, unknown>): RPCRequest;
|
|
18
|
+
export declare function parseResponse(raw: unknown): unknown;
|
|
19
|
+
export declare function _resetIdCounter(): void;
|
|
20
|
+
export interface BridgeOptions {
|
|
21
|
+
timeout?: number;
|
|
22
|
+
binaryPath?: string;
|
|
23
|
+
}
|
|
24
|
+
export declare class Bridge {
|
|
25
|
+
private socket;
|
|
26
|
+
private daemonProcess;
|
|
27
|
+
private binaryPath;
|
|
28
|
+
private timeout;
|
|
29
|
+
private pendingRequests;
|
|
30
|
+
private buffer;
|
|
31
|
+
private bomChecked;
|
|
32
|
+
private cdpClients;
|
|
33
|
+
private grabbedAppInfo;
|
|
34
|
+
constructor(options?: BridgeOptions);
|
|
35
|
+
send(method: string, params?: Record<string, unknown>): Promise<unknown>;
|
|
36
|
+
sendToNative(method: string, params?: Record<string, unknown>): Promise<unknown>;
|
|
37
|
+
sendOneShot(method: string, params?: Record<string, unknown>): unknown;
|
|
38
|
+
/**
|
|
39
|
+
* Lazily detect if the currently grabbed app has CDP available.
|
|
40
|
+
* Checks live every time: asks daemon for grab state, checks if Chromium,
|
|
41
|
+
* scans port range for a live CDP endpoint.
|
|
42
|
+
*/
|
|
43
|
+
private ensureCDPIfNeeded;
|
|
44
|
+
private sendToCDP;
|
|
45
|
+
private handleLaunch;
|
|
46
|
+
private handleRelaunch;
|
|
47
|
+
private handleGrab;
|
|
48
|
+
private handleUngrab;
|
|
49
|
+
private handleBatch;
|
|
50
|
+
private handleWait;
|
|
51
|
+
private flattenElements;
|
|
52
|
+
private ensureDaemon;
|
|
53
|
+
private spawnDaemon;
|
|
54
|
+
private waitForSocket;
|
|
55
|
+
private probeConnection;
|
|
56
|
+
private connectToSocket;
|
|
57
|
+
private setupSocketHandlers;
|
|
58
|
+
private processBuffer;
|
|
59
|
+
private readDaemonInfo;
|
|
60
|
+
private isProcessAlive;
|
|
61
|
+
private cleanupStaleFiles;
|
|
62
|
+
isRunning(): boolean;
|
|
63
|
+
daemonPid(): number | null;
|
|
64
|
+
disconnect(): Promise<void>;
|
|
65
|
+
shutdown(): Promise<void>;
|
|
66
|
+
_killDaemonProcess(): void;
|
|
67
|
+
_sendRawToSocket(data: string): void;
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=bridge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bridge.d.ts","sourceRoot":"","sources":["../../src/bridge.ts"],"names":[],"mappings":"AAqBA,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,KAAK,CAAC;IACf,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACjC;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,KAAK,CAAC;IACf,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE;QACN,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KAChC,CAAC;CACH;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GAAG,UAAU,CAO7F;AAED,wBAAgB,aAAa,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAyBnD;AAED,wBAAgB,eAAe,IAAI,IAAI,CAEtC;AAID,MAAM,WAAW,aAAa;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAQD,qBAAa,MAAM;IACjB,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,aAAa,CAA6B;IAClD,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,eAAe,CAIlB;IACL,OAAO,CAAC,MAAM,CAAM;IACpB,OAAO,CAAC,UAAU,CAAS;IAG3B,OAAO,CAAC,UAAU,CAAgC;IAClD,OAAO,CAAC,cAAc,CAA6D;gBAEvE,OAAO,GAAE,aAAkB;IAMjC,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAkB5E,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IA4B1F,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GAAG,OAAO;IA8B1E;;;;OAIG;YACW,iBAAiB;YAoCjB,SAAS;YAyIT,YAAY;YAyBZ,cAAc;YAgBd,UAAU;YAcV,YAAY;YAKZ,WAAW;YAuBX,UAAU;IAiCxB,OAAO,CAAC,eAAe;YAYT,YAAY;YAkCZ,WAAW;YAwBX,aAAa;IA0B3B,OAAO,CAAC,eAAe;IASvB,OAAO,CAAC,eAAe;IAwBvB,OAAO,CAAC,mBAAmB;IA+B3B,OAAO,CAAC,aAAa;IA2BrB,OAAO,CAAC,cAAc;IAUtB,OAAO,CAAC,cAAc;IAStB,OAAO,CAAC,iBAAiB;IAQzB,SAAS,IAAI,OAAO;IAIpB,SAAS,IAAI,MAAM,GAAG,IAAI;IAKpB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAc3B,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAmB/B,kBAAkB,IAAI,IAAI;IAY1B,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;CAGrC"}
|