Skip to content

Commit fcede52

Browse files
committed
feat: add project default simulator selection
1 parent cd2cfdf commit fcede52

11 files changed

Lines changed: 778 additions & 380 deletions

File tree

README.md

Lines changed: 68 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -93,10 +93,11 @@ CLI commands automatically use the same warm daemon:
9393

9494
```sh
9595
simdeck list
96-
simdeck tap <udid> 0.5 0.5 --normalized
97-
simdeck describe <udid> --format agent --max-depth 2
98-
SIMDECK_DEVICE=<udid> simdeck tap "Continue"
99-
simdeck --device <udid> describe --format agent --max-depth 2 --interactive
96+
simdeck use <udid>
97+
simdeck tap 0.5 0.5 --normalized
98+
simdeck tap "Continue"
99+
simdeck describe --format agent --max-depth 2 --interactive
100+
simdeck --device <other-udid> describe --format agent --max-depth 2
100101
```
101102

102103
## Daemon
@@ -139,65 +140,72 @@ simdeck core-simulator shutdown
139140

140141
```sh
141142
simdeck list
143+
simdeck use <udid>
142144
simdeck boot <udid>
143-
simdeck shutdown <udid>
144-
simdeck erase <udid>
145-
simdeck install <udid> /path/to/App.app
146-
simdeck install <udid> /path/to/App.ipa
145+
simdeck shutdown
146+
simdeck erase
147+
simdeck install /path/to/App.app
148+
simdeck install /path/to/App.ipa
147149
simdeck install android:<avd-name> /path/to/app.apk
148-
simdeck uninstall <udid> com.example.App
149-
simdeck open-url <udid> https://example.com
150-
simdeck launch <udid> com.apple.Preferences
151-
simdeck toggle-appearance <udid>
152-
simdeck pasteboard set <udid> "hello"
153-
simdeck pasteboard get <udid>
154-
simdeck screenshot <udid> --output screen.png
155-
simdeck screenshot <udid> --with-bezel --output screen-bezel.png
156-
simdeck record <udid> --seconds 5 --output screen-recording.mp4
157-
simdeck stream <udid> --frames 120 > stream.h264
158-
simdeck describe <udid>
159-
simdeck describe <udid> --format agent --max-depth 4
160-
simdeck describe <udid> --format agent --max-depth 4 --interactive
161-
simdeck describe <udid> --point 120,240
162-
simdeck wait-for <udid> --label "Welcome" --timeout-ms 5000
163-
simdeck assert <udid> --id login.button --source auto --max-depth 8
164-
simdeck tap <udid> 120 240
165-
simdeck tap <udid> --label "Continue" --wait-timeout-ms 5000
150+
simdeck uninstall com.example.App
151+
simdeck open-url https://example.com
152+
simdeck launch com.apple.Preferences
153+
simdeck toggle-appearance
154+
simdeck pasteboard set "hello"
155+
simdeck pasteboard get
156+
simdeck screenshot --output screen.png
157+
simdeck screenshot --with-bezel --output screen-bezel.png
158+
simdeck record --seconds 5 --output screen-recording.mp4
159+
simdeck stream --frames 120 > stream.h264
160+
simdeck describe
161+
simdeck describe --format agent --max-depth 4
162+
simdeck describe --format agent --max-depth 4 --interactive
163+
simdeck describe --point 120,240
164+
simdeck wait-for --label "Welcome" --timeout-ms 5000
165+
simdeck assert --id login.button --source auto --max-depth 8
166+
simdeck tap 120 240
167+
simdeck tap --label "Continue" --wait-timeout-ms 5000
166168
simdeck tap "Continue"
167-
simdeck swipe <udid> 200 700 200 200
168-
simdeck gesture <udid> scroll-down
169-
simdeck pinch <udid> --start-distance 160 --end-distance 80
170-
simdeck rotate-gesture <udid> --radius 100 --degrees 90
171-
simdeck touch <udid> 0.5 0.5 --phase began --normalized
172-
simdeck touch <udid> 120 240 --down --up --delay-ms 800
173-
simdeck key <udid> enter
174-
simdeck key-sequence <udid> --keycodes h,e,l,l,o
175-
simdeck key-combo <udid> --modifiers cmd --key a
176-
simdeck type <udid> "hello"
177-
simdeck type <udid> --file message.txt
178-
simdeck button <udid> lock --duration-ms 1000
179-
simdeck button <udid> volume-up
180-
simdeck button <udid> action --duration-ms 1000
181-
simdeck button <udid> digital-crown
182-
simdeck crown <udid> --delta 50
183-
simdeck button <udid> left-side-button
184-
simdeck batch <udid> --step "tap --label Continue" --step "type 'hello'" --step "wait-for --label hello"
185-
simdeck dismiss-keyboard <udid>
186-
simdeck home <udid>
187-
simdeck app-switcher <udid>
188-
simdeck rotate-left <udid>
189-
simdeck rotate-right <udid>
190-
simdeck chrome-profile <udid>
191-
simdeck logs <udid> --seconds 30 --limit 200
192-
simdeck processes <udid>
193-
simdeck stats <udid> --watch
194-
simdeck sample <udid> --seconds 3
169+
simdeck swipe 200 700 200 200
170+
simdeck gesture scroll-down
171+
simdeck pinch --start-distance 160 --end-distance 80
172+
simdeck rotate-gesture --radius 100 --degrees 90
173+
simdeck touch 0.5 0.5 --phase began --normalized
174+
simdeck touch 120 240 --down --up --delay-ms 800
175+
simdeck key enter
176+
simdeck key-sequence --keycodes h,e,l,l,o
177+
simdeck key-combo --modifiers cmd --key a
178+
simdeck type "hello"
179+
simdeck type --file message.txt
180+
simdeck button lock --duration-ms 1000
181+
simdeck button volume-up
182+
simdeck button action --duration-ms 1000
183+
simdeck button digital-crown
184+
simdeck crown --delta 50
185+
simdeck button left-side-button
186+
simdeck batch --step "tap --label Continue" --step "type 'hello'" --step "wait-for --label hello"
187+
simdeck dismiss-keyboard
188+
simdeck home
189+
simdeck app-switcher
190+
simdeck rotate-left
191+
simdeck rotate-right
192+
simdeck chrome-profile
193+
simdeck logs --seconds 30 --limit 200
194+
simdeck processes
195+
simdeck stats --watch
196+
simdeck sample --seconds 3
195197
```
196198

197199
`simdeck list` defaults to compact JSON for agent-friendly device selection.
198200
Use `simdeck list --format json` for the full inventory with paths and display
199201
metadata.
200202

203+
`simdeck use <udid>` stores a default simulator for the current project
204+
directory. Most device commands accept `[<udid>]`; when it is omitted, SimDeck
205+
uses `--device`, `SIMDECK_DEVICE`, `SIMDECK_UDID`, the saved project default,
206+
or the only booted simulator, in that order. The old explicit-UDID form still
207+
works for every command.
208+
201209
`boot` uses SimDeck's private CoreSimulator boot path so it can start devices
202210
without launching Simulator.app. If that private path is unavailable, the
203211
command returns the CoreSimulator error instead of falling back to
@@ -219,10 +227,11 @@ Flutter, or UIKit in-app inspectors, then falls back to the built-in private
219227
CoreSimulator accessibility bridge. Use `--format agent` or
220228
`--format compact-json` for
221229
lower-token hierarchy dumps, and add `--interactive`/`-i` when an agent only
222-
needs actionable elements plus their ancestors. `describe` and `tap` can infer a
223-
target from `--device`, `SIMDECK_DEVICE`, `SIMDECK_UDID`, or the only booted
224-
simulator. Coordinate commands accept screen coordinates from the accessibility
225-
tree by default; pass `--normalized` to send `0.0..1.0` coordinates directly.
230+
needs actionable elements plus their ancestors. Set a project default with
231+
`simdeck use <udid>` so agent commands can use short forms like
232+
`simdeck tap "Continue"` and `simdeck describe --format agent --max-depth 2`.
233+
Coordinate commands accept screen coordinates from the accessibility tree by
234+
default; pass `--normalized` to send `0.0..1.0` coordinates directly.
226235

227236
## JS/TS Tests
228237

@@ -249,7 +258,7 @@ explicit UDID as the first argument when needed.
249258
Run common Maestro YAML flows against the same daemon-backed simulator API:
250259

251260
```sh
252-
simdeck maestro test <udid> flow.yaml --artifacts-dir artifacts/maestro
261+
simdeck maestro test flow.yaml --artifacts-dir artifacts/maestro
253262
```
254263

255264
## NativeScript Inspector

docs/cli/commands.md

Lines changed: 67 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -43,98 +43,103 @@ rotate the token and pairing code, then restart the LaunchAgent.
4343
```sh
4444
simdeck list
4545
simdeck list --format json
46+
simdeck use <udid>
4647
simdeck boot <udid>
47-
simdeck shutdown <udid>
48-
simdeck erase <udid>
48+
simdeck shutdown
49+
simdeck erase
4950
```
5051

5152
Android emulators appear as IDs such as `android:Pixel_8_API_36`.
5253
`list` defaults to compact JSON. Use `--format json` for the full simulator
5354
inventory, including paths and display metadata.
5455

56+
`simdeck use <udid>` saves a default simulator for the current project
57+
directory. After that, most device commands can omit `<udid>`; explicit UDIDs
58+
still override the default.
59+
5560
## Apps And URLs
5661

5762
```sh
58-
simdeck install <udid> /path/to/App.app
59-
simdeck install <udid> /path/to/App.ipa
63+
simdeck install /path/to/App.app
64+
simdeck install /path/to/App.ipa
6065
simdeck install android:<avd-name> /path/to/app.apk
61-
simdeck uninstall <udid> com.example.App
62-
simdeck launch <udid> com.example.App
63-
simdeck open-url <udid> https://example.com
64-
simdeck toggle-appearance <udid>
66+
simdeck uninstall com.example.App
67+
simdeck launch com.example.App
68+
simdeck open-url https://example.com
69+
simdeck toggle-appearance
6570
```
6671

6772
## Inspect UI
6873

6974
```sh
70-
simdeck describe <udid>
71-
simdeck describe <udid> --format agent --max-depth 4
72-
simdeck describe <udid> --format agent --max-depth 4 --interactive
73-
simdeck describe <udid> --format compact-json
74-
simdeck describe <udid> --source nativescript
75-
simdeck describe <udid> --source react-native
76-
simdeck describe <udid> --source flutter
77-
simdeck describe <udid> --source uikit
78-
simdeck describe <udid> --source native-ax
79-
simdeck describe <udid> --point 120,240
80-
simdeck wait-for <udid> --label "Welcome" --timeout-ms 5000
81-
simdeck assert <udid> --id login.button --source auto --max-depth 8
75+
simdeck describe
76+
simdeck describe --format agent --max-depth 4
77+
simdeck describe --format agent --max-depth 4 --interactive
78+
simdeck describe --format compact-json
79+
simdeck describe --source nativescript
80+
simdeck describe --source react-native
81+
simdeck describe --source flutter
82+
simdeck describe --source uikit
83+
simdeck describe --source native-ax
84+
simdeck describe --point 120,240
85+
simdeck wait-for --label "Welcome" --timeout-ms 5000
86+
simdeck assert --id login.button --source auto --max-depth 8
8287
```
8388

84-
Default source selection prefers a connected framework inspector, then the Swift in-app agent, then native accessibility. Use `--interactive` or `-i` to keep actionable elements and the ancestor context needed to find them. For quick agent loops, `describe` can infer the device from `--device`, `SIMDECK_DEVICE`, `SIMDECK_UDID`, or the only booted simulator.
89+
Default source selection prefers a connected framework inspector, then the Swift in-app agent, then native accessibility. Use `--interactive` or `-i` to keep actionable elements and the ancestor context needed to find them. For quick agent loops, set the project default once and keep `describe` shallow.
8590

8691
## Performance
8792

8893
```sh
89-
simdeck processes <udid>
90-
simdeck stats <udid>
91-
simdeck stats <udid> --pid 12345
92-
simdeck stats <udid> --watch
93-
simdeck sample <udid>
94-
simdeck sample <udid> --pid 12345 --seconds 3
94+
simdeck processes
95+
simdeck stats
96+
simdeck stats --pid 12345
97+
simdeck stats --watch
98+
simdeck sample
99+
simdeck sample --pid 12345 --seconds 3
95100
```
96101

97102
Performance data is simulator-only and uses host-process telemetry for matching app, extension, helper, and web-content PIDs. `stats` reports CPU, memory, disk write rate, network receive/send rates, connection count, hang state, and recent crash or termination signals. `sample` captures a short macOS `sample` report for the selected or foreground app process.
98103

99104
## Input
100105

101-
Coordinates are screen points unless `--normalized` is present. `tap "Continue"` is shorthand for a label tap on the inferred device. Use `--device <udid>` or `SIMDECK_DEVICE=<udid>` when more than one simulator is booted.
106+
Coordinates are screen points unless `--normalized` is present. `tap "Continue"` is shorthand for a label tap on the selected device. Use `--device <udid>` or `SIMDECK_DEVICE=<udid>` for one-off overrides.
102107

103108
```sh
104-
simdeck tap <udid> 120 240
105-
simdeck tap <udid> 0.5 0.5 --normalized
106-
simdeck tap <udid> --label "Continue" --wait-timeout-ms 5000
109+
simdeck tap 120 240
110+
simdeck tap 0.5 0.5 --normalized
111+
simdeck tap --label "Continue" --wait-timeout-ms 5000
107112
simdeck tap "Continue"
108-
simdeck swipe <udid> 200 700 200 200
109-
simdeck gesture <udid> scroll-down
110-
simdeck pinch <udid> --start-distance 160 --end-distance 80
111-
simdeck rotate-gesture <udid> --radius 100 --degrees 90
112-
simdeck type <udid> "hello"
113-
simdeck type <udid> --file message.txt
114-
simdeck key <udid> enter
115-
simdeck key-sequence <udid> --keycodes h,e,l,l,o
116-
simdeck key-combo <udid> --modifiers cmd --key a
113+
simdeck swipe 200 700 200 200
114+
simdeck gesture scroll-down
115+
simdeck pinch --start-distance 160 --end-distance 80
116+
simdeck rotate-gesture --radius 100 --degrees 90
117+
simdeck type "hello"
118+
simdeck type --file message.txt
119+
simdeck key enter
120+
simdeck key-sequence --keycodes h,e,l,l,o
121+
simdeck key-combo --modifiers cmd --key a
117122
```
118123

119124
System controls:
120125

121126
```sh
122-
simdeck button <udid> lock --duration-ms 1000
123-
simdeck button <udid> volume-up
124-
simdeck button <udid> action
125-
simdeck button <udid> digital-crown
126-
simdeck crown <udid> --delta 50
127-
simdeck dismiss-keyboard <udid>
128-
simdeck home <udid>
129-
simdeck app-switcher <udid>
130-
simdeck rotate-left <udid>
131-
simdeck rotate-right <udid>
127+
simdeck button lock --duration-ms 1000
128+
simdeck button volume-up
129+
simdeck button action
130+
simdeck button digital-crown
131+
simdeck crown --delta 50
132+
simdeck dismiss-keyboard
133+
simdeck home
134+
simdeck app-switcher
135+
simdeck rotate-left
136+
simdeck rotate-right
132137
```
133138

134139
## Batch
135140

136141
```sh
137-
simdeck batch <udid> \
142+
simdeck batch \
138143
--step "tap --label Continue --wait-timeout-ms 5000" \
139144
--step "type 'hello world'" \
140145
--step "wait-for --label 'hello world' --timeout-ms 5000"
@@ -147,29 +152,29 @@ Use `wait-for` or `assert` steps instead of fixed sleeps when possible.
147152
Run common Maestro flows through SimDeck's daemon-backed iOS Simulator API:
148153

149154
```sh
150-
simdeck maestro test <udid> flow.yaml --artifacts-dir artifacts/maestro
155+
simdeck maestro test flow.yaml --artifacts-dir artifacts/maestro
151156
```
152157

153158
The compatibility runner supports the core local commands: `launchApp`, `openLink`, `tapOn`, `inputText`, `eraseText`, `pressKey`, `assertVisible`, `assertNotVisible`, `scrollUntilVisible`, `swipe`, `takeScreenshot`, and `waitForAnimationToEnd`.
154159

155160
## Evidence
156161

157162
```sh
158-
simdeck screenshot <udid> --output screen.png
159-
simdeck screenshot <udid> --with-bezel --output screen-bezel.png
160-
simdeck screenshot <udid> --stdout > screen.png
161-
simdeck record <udid> --seconds 5 --output screen-recording.mp4
162-
simdeck record <udid> --seconds 5 --stdout > screen-recording.mp4
163-
simdeck pasteboard set <udid> "hello"
164-
simdeck pasteboard get <udid>
165-
simdeck logs <udid> --seconds 30 --limit 200
166-
simdeck chrome-profile <udid>
163+
simdeck screenshot --output screen.png
164+
simdeck screenshot --with-bezel --output screen-bezel.png
165+
simdeck screenshot --stdout > screen.png
166+
simdeck record --seconds 5 --output screen-recording.mp4
167+
simdeck record --seconds 5 --stdout > screen-recording.mp4
168+
simdeck pasteboard set "hello"
169+
simdeck pasteboard get
170+
simdeck logs --seconds 30 --limit 200
171+
simdeck chrome-profile
167172
```
168173

169174
Diagnostic iOS H.264 stream:
170175

171176
```sh
172-
simdeck stream <udid> --frames 120 > stream.h264
177+
simdeck stream --frames 120 > stream.h264
173178
```
174179

175180
## Studio And Providers

docs/cli/flags.md

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,14 @@ simdeck daemon start --help
1010

1111
## Global
1212

13-
| Flag | Env | Purpose |
14-
| --------------------- | -------------------- | ---------------------------------------------- |
15-
| `--server-url <url>` | `SIMDECK_SERVER_URL` | Target a specific running daemon |
16-
| `--device <selector>` | `SIMDECK_DEVICE` | Default simulator for inferred-device commands |
13+
| Flag | Env | Purpose |
14+
| --------------------- | -------------------- | -------------------------------- |
15+
| `--server-url <url>` | `SIMDECK_SERVER_URL` | Target a specific running daemon |
16+
| `--device <selector>` | `SIMDECK_DEVICE` | One-off simulator override |
17+
18+
`SIMDECK_UDID` is also accepted for compatibility. Device commands resolve in
19+
this order: positional UDID, `--device`, `SIMDECK_DEVICE`, `SIMDECK_UDID`, the
20+
project default from `simdeck use <udid>`, then auto-inference from the daemon.
1721

1822
## Server Options
1923

0 commit comments

Comments
 (0)