@limrun/cli 0.2.0 → 0.2.2
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 +335 -299
- package/dist/base-command.d.ts +5 -0
- package/dist/base-command.d.ts.map +1 -1
- package/dist/base-command.js +11 -0
- package/dist/base-command.js.map +1 -1
- package/dist/commands/android/connect.d.ts +1 -1
- package/dist/commands/android/connect.d.ts.map +1 -1
- package/dist/commands/android/connect.js +4 -3
- package/dist/commands/android/connect.js.map +1 -1
- package/dist/commands/android/create.d.ts.map +1 -1
- package/dist/commands/android/create.js +2 -0
- package/dist/commands/android/create.js.map +1 -1
- package/dist/commands/build.d.ts +1 -1
- package/dist/commands/build.d.ts.map +1 -1
- package/dist/commands/build.js +3 -2
- package/dist/commands/build.js.map +1 -1
- package/dist/commands/delete/index.d.ts.map +1 -1
- package/dist/commands/delete/index.js +2 -1
- package/dist/commands/delete/index.js.map +1 -1
- package/dist/commands/exec/element-tree.d.ts +1 -1
- package/dist/commands/exec/element-tree.d.ts.map +1 -1
- package/dist/commands/exec/element-tree.js +5 -4
- package/dist/commands/exec/element-tree.js.map +1 -1
- package/dist/commands/exec/install-app.d.ts +1 -1
- package/dist/commands/exec/install-app.d.ts.map +1 -1
- package/dist/commands/exec/install-app.js +5 -4
- package/dist/commands/exec/install-app.js.map +1 -1
- package/dist/commands/exec/open-url.d.ts +1 -1
- package/dist/commands/exec/open-url.d.ts.map +1 -1
- package/dist/commands/exec/open-url.js +5 -4
- package/dist/commands/exec/open-url.js.map +1 -1
- package/dist/commands/exec/press-key.d.ts +1 -1
- package/dist/commands/exec/press-key.d.ts.map +1 -1
- package/dist/commands/exec/press-key.js +5 -4
- package/dist/commands/exec/press-key.js.map +1 -1
- package/dist/commands/exec/record.d.ts +1 -1
- package/dist/commands/exec/record.d.ts.map +1 -1
- package/dist/commands/exec/record.js +8 -7
- package/dist/commands/exec/record.js.map +1 -1
- package/dist/commands/exec/screenshot.d.ts +1 -1
- package/dist/commands/exec/screenshot.d.ts.map +1 -1
- package/dist/commands/exec/screenshot.js +6 -5
- package/dist/commands/exec/screenshot.js.map +1 -1
- package/dist/commands/exec/scroll.d.ts +1 -1
- package/dist/commands/exec/scroll.d.ts.map +1 -1
- package/dist/commands/exec/scroll.js +5 -4
- package/dist/commands/exec/scroll.js.map +1 -1
- package/dist/commands/exec/tap-element.d.ts +1 -1
- package/dist/commands/exec/tap-element.d.ts.map +1 -1
- package/dist/commands/exec/tap-element.js +6 -5
- package/dist/commands/exec/tap-element.js.map +1 -1
- package/dist/commands/exec/tap.d.ts +1 -1
- package/dist/commands/exec/tap.d.ts.map +1 -1
- package/dist/commands/exec/tap.js +5 -4
- package/dist/commands/exec/tap.js.map +1 -1
- package/dist/commands/exec/type.d.ts +1 -1
- package/dist/commands/exec/type.d.ts.map +1 -1
- package/dist/commands/exec/type.js +5 -4
- package/dist/commands/exec/type.js.map +1 -1
- package/dist/commands/ios/create.d.ts.map +1 -1
- package/dist/commands/ios/create.js +1 -0
- package/dist/commands/ios/create.js.map +1 -1
- package/dist/commands/ios/launch-app.d.ts +1 -1
- package/dist/commands/ios/launch-app.d.ts.map +1 -1
- package/dist/commands/ios/launch-app.js +5 -4
- package/dist/commands/ios/launch-app.js.map +1 -1
- package/dist/commands/ios/list-apps.d.ts +1 -1
- package/dist/commands/ios/list-apps.d.ts.map +1 -1
- package/dist/commands/ios/list-apps.js +5 -4
- package/dist/commands/ios/list-apps.js.map +1 -1
- package/dist/commands/ios/log.d.ts +1 -1
- package/dist/commands/ios/log.d.ts.map +1 -1
- package/dist/commands/ios/log.js +6 -5
- package/dist/commands/ios/log.js.map +1 -1
- package/dist/commands/ios/terminate-app.d.ts +1 -1
- package/dist/commands/ios/terminate-app.d.ts.map +1 -1
- package/dist/commands/ios/terminate-app.js +5 -4
- package/dist/commands/ios/terminate-app.js.map +1 -1
- package/dist/commands/session/start.d.ts +1 -1
- package/dist/commands/session/start.d.ts.map +1 -1
- package/dist/commands/session/start.js +13 -12
- package/dist/commands/session/start.js.map +1 -1
- package/dist/commands/sync.d.ts +1 -1
- package/dist/commands/sync.d.ts.map +1 -1
- package/dist/commands/sync.js +7 -6
- package/dist/commands/sync.js.map +1 -1
- package/dist/commands/xcode/create.d.ts.map +1 -1
- package/dist/commands/xcode/create.js +2 -0
- package/dist/commands/xcode/create.js.map +1 -1
- package/dist/lib/config.d.ts +7 -0
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +47 -0
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/instance-client-factory.js +2 -2
- package/dist/lib/instance-client-factory.js.map +1 -1
- package/package.json +28 -10
package/README.md
CHANGED
|
@@ -19,11 +19,11 @@ npx @limrun/cli <command>
|
|
|
19
19
|
lim login
|
|
20
20
|
|
|
21
21
|
# Or provide an API key directly
|
|
22
|
-
lim --api-key <YOUR_KEY>
|
|
22
|
+
lim --api-key <YOUR_KEY> android list
|
|
23
23
|
|
|
24
24
|
# Or use an environment variable
|
|
25
25
|
export LIM_API_KEY=<YOUR_KEY>
|
|
26
|
-
lim
|
|
26
|
+
lim android list
|
|
27
27
|
|
|
28
28
|
# Log out (removes stored API key)
|
|
29
29
|
lim logout
|
|
@@ -41,49 +41,86 @@ Every command supports these flags:
|
|
|
41
41
|
| `--json` | Output as JSON instead of human-readable tables |
|
|
42
42
|
| `--help` | Show help for any command |
|
|
43
43
|
|
|
44
|
+
## Command Structure
|
|
45
|
+
|
|
46
|
+
Commands are organized by resource (noun-first), so you can discover everything available for a platform with `--help`:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
lim ios --help # All iOS commands
|
|
50
|
+
lim android --help # All Android commands
|
|
51
|
+
lim xcode --help # All Xcode commands
|
|
52
|
+
lim asset --help # All asset commands
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
**Instance ID is optional** on interaction commands. When omitted, the CLI uses the last created instance of the matching type:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
lim ios create # Creates ios_abc123, remembers it
|
|
59
|
+
lim ios screenshot -o test.png # Uses ios_abc123 automatically
|
|
60
|
+
lim ios tap 100 200 # Still uses ios_abc123
|
|
61
|
+
lim session start # Starts session for ios_abc123
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
You can always provide an ID explicitly to target a specific instance:
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
lim ios screenshot ios_def456 -o test.png
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
**Top-level shortcuts** are available for common actions — the platform is auto-detected from the instance ID prefix:
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
lim screenshot ios_abc123 # Works for both iOS and Android
|
|
74
|
+
lim tap 100 200 ios_abc123 # Auto-detects platform from ID prefix
|
|
75
|
+
lim delete ios_abc123 # Auto-detects resource type from ID prefix
|
|
76
|
+
```
|
|
77
|
+
|
|
44
78
|
## Commands
|
|
45
79
|
|
|
46
|
-
- [
|
|
47
|
-
- [
|
|
80
|
+
- [iOS](#ios) — Create, manage, and interact with iOS instances
|
|
81
|
+
- [Android](#android) — Create, manage, and interact with Android instances
|
|
82
|
+
- [Xcode](#xcode) — Create and manage Xcode sandbox instances
|
|
83
|
+
- [Assets](#assets) — Upload and download files (APKs, IPAs, etc.)
|
|
48
84
|
- [Sessions](#sessions) — Persistent connections for fast, interactive device control
|
|
49
|
-
- [Device Interaction](#device-interaction) — Screenshots, tapping, typing, scrolling, and more
|
|
50
85
|
- [Xcode Build Pipeline](#xcode-build-pipeline) — Sync code and run xcodebuild remotely
|
|
51
|
-
- [Connectivity](#connectivity) — ADB tunnel for Android debugging
|
|
52
86
|
|
|
53
87
|
---
|
|
54
88
|
|
|
55
|
-
###
|
|
56
|
-
|
|
57
|
-
#### Create Instances
|
|
89
|
+
### iOS
|
|
58
90
|
|
|
59
91
|
```bash
|
|
60
|
-
|
|
61
|
-
lim
|
|
92
|
+
lim ios create # Create a new iOS instance
|
|
93
|
+
lim ios list # List all ready iOS instances
|
|
94
|
+
lim ios list <ID> # Get details of a specific instance
|
|
95
|
+
lim ios delete <ID> # Delete an instance
|
|
96
|
+
```
|
|
62
97
|
|
|
63
|
-
|
|
64
|
-
lim run android --install ./my-app.apk --install ./another.apk
|
|
98
|
+
#### Create Options
|
|
65
99
|
|
|
66
|
-
|
|
67
|
-
|
|
100
|
+
```bash
|
|
101
|
+
# Basic
|
|
102
|
+
lim ios create
|
|
68
103
|
|
|
69
|
-
#
|
|
70
|
-
lim
|
|
104
|
+
# With specific device model
|
|
105
|
+
lim ios create --model ipad --rm
|
|
71
106
|
|
|
72
|
-
#
|
|
73
|
-
lim
|
|
107
|
+
# With pre-installed app from asset storage
|
|
108
|
+
lim ios create --install-asset my-app.ipa
|
|
74
109
|
|
|
75
|
-
#
|
|
76
|
-
lim
|
|
110
|
+
# With Xcode sandbox enabled
|
|
111
|
+
lim ios create --xcode
|
|
77
112
|
|
|
78
|
-
#
|
|
79
|
-
lim
|
|
113
|
+
# Full options
|
|
114
|
+
lim ios create --region us-west --display-name "CI Test" --label env=ci --rm
|
|
80
115
|
```
|
|
81
116
|
|
|
82
|
-
**
|
|
117
|
+
**Flags for `ios create`:**
|
|
83
118
|
|
|
84
119
|
| Flag | Description |
|
|
85
120
|
|------|-------------|
|
|
86
121
|
| `--rm` | Auto-delete the instance on exit (Ctrl+C) |
|
|
122
|
+
| `--model <iphone\|ipad\|watch>` | Simulator device model |
|
|
123
|
+
| `--xcode` | Attach a Xcode build sandbox to the iOS instance |
|
|
87
124
|
| `--region <value>` | Region for the instance (e.g. `us-west`) |
|
|
88
125
|
| `--display-name <value>` | Human-readable name |
|
|
89
126
|
| `--label <key=value>` | Labels (repeatable). Used for filtering and reuse |
|
|
@@ -93,6 +130,118 @@ lim run xcode --rm --hard-timeout 1h
|
|
|
93
130
|
| `--install <file>` | Local file to install (auto-uploads, repeatable) |
|
|
94
131
|
| `--install-asset <name>` | Asset name to install (repeatable) |
|
|
95
132
|
|
|
133
|
+
#### List and Filter
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
lim ios list # Ready instances
|
|
137
|
+
lim ios list --all # All states
|
|
138
|
+
lim ios list --state creating # Filter by state
|
|
139
|
+
lim ios list --region us-west # Filter by region
|
|
140
|
+
lim ios list --label-selector env=prod # Filter by labels
|
|
141
|
+
lim ios list --json # JSON output
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
#### Device Interaction
|
|
145
|
+
|
|
146
|
+
All interaction commands accept an optional `[ID]` as the last argument. When omitted, the last created iOS instance is used.
|
|
147
|
+
|
|
148
|
+
```bash
|
|
149
|
+
# Screenshots
|
|
150
|
+
lim ios screenshot -o screenshot.png
|
|
151
|
+
lim ios screenshot # Output base64 to stdout
|
|
152
|
+
|
|
153
|
+
# Tapping
|
|
154
|
+
lim ios tap 100 200
|
|
155
|
+
lim ios tap-element --label "Submit"
|
|
156
|
+
lim ios tap-element --accessibility-id btn_ok
|
|
157
|
+
|
|
158
|
+
# Text input
|
|
159
|
+
lim ios type "Hello World"
|
|
160
|
+
lim ios type "search query" --press-enter
|
|
161
|
+
lim ios press-key enter
|
|
162
|
+
lim ios press-key a --modifier shift
|
|
163
|
+
|
|
164
|
+
# Scrolling
|
|
165
|
+
lim ios scroll down --amount 500
|
|
166
|
+
|
|
167
|
+
# UI inspection
|
|
168
|
+
lim ios element-tree
|
|
169
|
+
lim ios element-tree | jq '.'
|
|
170
|
+
|
|
171
|
+
# Open URLs / deep links
|
|
172
|
+
lim ios open-url https://example.com
|
|
173
|
+
lim ios open-url myapp://settings
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
#### App Management (iOS only)
|
|
177
|
+
|
|
178
|
+
```bash
|
|
179
|
+
# Install an app (local file auto-uploads, or use URL)
|
|
180
|
+
lim ios install-app ./MyApp.ipa
|
|
181
|
+
lim ios install-app https://example.com/app.ipa
|
|
182
|
+
|
|
183
|
+
# Launch / terminate
|
|
184
|
+
lim ios launch-app com.example.myapp
|
|
185
|
+
lim ios launch-app com.example.myapp --mode RelaunchIfRunning
|
|
186
|
+
lim ios terminate-app com.example.myapp
|
|
187
|
+
|
|
188
|
+
# List installed apps
|
|
189
|
+
lim ios list-apps
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
#### Log Streaming (iOS only)
|
|
193
|
+
|
|
194
|
+
```bash
|
|
195
|
+
# Tail recent logs
|
|
196
|
+
lim ios log com.example.myapp --lines 50
|
|
197
|
+
|
|
198
|
+
# Stream logs continuously (Ctrl+C to stop)
|
|
199
|
+
lim ios log com.example.myapp -f
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
#### Video Recording
|
|
203
|
+
|
|
204
|
+
```bash
|
|
205
|
+
lim ios record start
|
|
206
|
+
lim ios record start --quality 8
|
|
207
|
+
lim ios record stop -o recording.mp4
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
#### Xcode Integration
|
|
211
|
+
|
|
212
|
+
```bash
|
|
213
|
+
# Sync and build (requires --xcode on create)
|
|
214
|
+
lim ios sync ./MyProject
|
|
215
|
+
lim ios build --scheme MyApp --workspace MyApp.xcworkspace
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
---
|
|
219
|
+
|
|
220
|
+
### Android
|
|
221
|
+
|
|
222
|
+
```bash
|
|
223
|
+
lim android create # Create a new Android instance
|
|
224
|
+
lim android list # List all ready Android instances
|
|
225
|
+
lim android list <ID> # Get details of a specific instance
|
|
226
|
+
lim android delete <ID> # Delete an instance
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
#### Create Options
|
|
230
|
+
|
|
231
|
+
```bash
|
|
232
|
+
# Basic (with ADB tunnel and scrcpy streaming)
|
|
233
|
+
lim android create
|
|
234
|
+
|
|
235
|
+
# With apps pre-installed
|
|
236
|
+
lim android create --install ./my-app.apk --install ./another.apk
|
|
237
|
+
|
|
238
|
+
# Without streaming
|
|
239
|
+
lim android create --no-stream
|
|
240
|
+
|
|
241
|
+
# Full options
|
|
242
|
+
lim android create --region us-west --display-name "CI Test" --label env=ci --rm
|
|
243
|
+
```
|
|
244
|
+
|
|
96
245
|
**Android-specific flags:**
|
|
97
246
|
|
|
98
247
|
| Flag | Description |
|
|
@@ -101,123 +250,146 @@ lim run xcode --rm --hard-timeout 1h
|
|
|
101
250
|
| `--[no-]stream` | Launch scrcpy for visual control (default: true) |
|
|
102
251
|
| `--adb-path <path>` | Path to `adb` binary (default: `adb`) |
|
|
103
252
|
|
|
104
|
-
|
|
253
|
+
#### Device Interaction
|
|
105
254
|
|
|
106
|
-
|
|
107
|
-
|------|-------------|
|
|
108
|
-
| `--model <iphone\|ipad\|watch>` | Simulator device model |
|
|
109
|
-
| `--xcode` | Attach a Xcode build sandbox to the iOS instance |
|
|
110
|
-
|
|
111
|
-
#### List Instances
|
|
255
|
+
All interaction commands accept an optional `[ID]` as the last argument. When omitted, the last created Android instance is used.
|
|
112
256
|
|
|
113
257
|
```bash
|
|
114
|
-
#
|
|
115
|
-
lim
|
|
116
|
-
|
|
117
|
-
|
|
258
|
+
# Screenshots
|
|
259
|
+
lim android screenshot -o screenshot.png
|
|
260
|
+
|
|
261
|
+
# Tapping
|
|
262
|
+
lim android tap 100 200
|
|
263
|
+
lim android tap-element --resource-id com.example:id/button
|
|
264
|
+
lim android tap-element --text "Sign In"
|
|
265
|
+
|
|
266
|
+
# Text input
|
|
267
|
+
lim android type "Hello World"
|
|
268
|
+
lim android press-key enter
|
|
118
269
|
|
|
119
|
-
#
|
|
120
|
-
lim
|
|
270
|
+
# Scrolling
|
|
271
|
+
lim android scroll down --amount 500
|
|
121
272
|
|
|
122
|
-
#
|
|
123
|
-
lim
|
|
273
|
+
# UI inspection
|
|
274
|
+
lim android element-tree
|
|
124
275
|
|
|
125
|
-
#
|
|
126
|
-
lim
|
|
127
|
-
lim get ios --region us-west
|
|
128
|
-
lim get android --label-selector env=prod,team=mobile
|
|
276
|
+
# Install app
|
|
277
|
+
lim android install-app ./app.apk
|
|
129
278
|
|
|
130
|
-
#
|
|
131
|
-
lim
|
|
279
|
+
# Open URL
|
|
280
|
+
lim android open-url https://example.com
|
|
281
|
+
|
|
282
|
+
# Video recording
|
|
283
|
+
lim android record start
|
|
284
|
+
lim android record stop -o recording.mp4
|
|
132
285
|
```
|
|
133
286
|
|
|
134
|
-
|
|
287
|
+
#### ADB Tunnel
|
|
135
288
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
289
|
+
Connect to a running Android instance for direct `adb` access:
|
|
290
|
+
|
|
291
|
+
```bash
|
|
292
|
+
lim android connect
|
|
293
|
+
lim android connect android_abc123 --adb-path /usr/local/bin/adb
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
The tunnel stays open until you press Ctrl+C. While connected, you can use `adb` commands in another terminal.
|
|
297
|
+
|
|
298
|
+
---
|
|
299
|
+
|
|
300
|
+
### Xcode
|
|
142
301
|
|
|
143
|
-
|
|
302
|
+
Standalone Xcode build sandboxes for remote compilation.
|
|
144
303
|
|
|
145
304
|
```bash
|
|
146
|
-
#
|
|
147
|
-
lim
|
|
148
|
-
lim
|
|
149
|
-
lim delete
|
|
305
|
+
lim xcode create # Create a new Xcode sandbox
|
|
306
|
+
lim xcode list # List all ready Xcode instances
|
|
307
|
+
lim xcode list <ID> # Get details of a specific instance
|
|
308
|
+
lim xcode delete <ID> # Delete an instance
|
|
309
|
+
```
|
|
150
310
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
lim
|
|
311
|
+
```bash
|
|
312
|
+
# Create with options
|
|
313
|
+
lim xcode create --rm --region us-west --hard-timeout 1h
|
|
314
|
+
|
|
315
|
+
# Sync and build
|
|
316
|
+
lim xcode sync ./MyProject
|
|
317
|
+
lim xcode build --scheme MyApp --workspace MyApp.xcworkspace
|
|
318
|
+
|
|
319
|
+
# Build and upload artifact
|
|
320
|
+
lim xcode build --scheme MyApp --upload my-app-build
|
|
154
321
|
```
|
|
155
322
|
|
|
156
323
|
---
|
|
157
324
|
|
|
158
|
-
###
|
|
325
|
+
### Assets
|
|
159
326
|
|
|
160
327
|
Assets are files (APKs, IPAs, configs, etc.) stored in Limrun's cloud storage for use with instances.
|
|
161
328
|
|
|
162
329
|
```bash
|
|
163
330
|
# Upload a file
|
|
164
|
-
lim push ./my-app.apk
|
|
165
|
-
lim push ./my-app.ipa -n custom-name
|
|
331
|
+
lim asset push ./my-app.apk
|
|
332
|
+
lim asset push ./my-app.ipa -n custom-name
|
|
166
333
|
|
|
167
334
|
# Download a file
|
|
168
|
-
lim pull asset_abc123
|
|
169
|
-
lim pull my-app.apk
|
|
170
|
-
lim pull asset_abc123 -o ./downloads
|
|
335
|
+
lim asset pull asset_abc123
|
|
336
|
+
lim asset pull my-app.apk
|
|
337
|
+
lim asset pull asset_abc123 -o ./downloads
|
|
171
338
|
|
|
172
339
|
# List assets
|
|
173
|
-
lim
|
|
174
|
-
lim
|
|
175
|
-
lim
|
|
340
|
+
lim asset list
|
|
341
|
+
lim asset list --name my-app
|
|
342
|
+
lim asset list --download-url
|
|
176
343
|
|
|
177
344
|
# Get a specific asset
|
|
178
|
-
lim
|
|
345
|
+
lim asset list asset_abc123
|
|
179
346
|
|
|
180
347
|
# Delete an asset
|
|
181
|
-
lim delete
|
|
348
|
+
lim asset delete asset_abc123
|
|
182
349
|
```
|
|
183
350
|
|
|
184
351
|
---
|
|
185
352
|
|
|
186
353
|
### Sessions
|
|
187
354
|
|
|
188
|
-
Sessions keep a persistent WebSocket connection to an instance in the background, making all
|
|
355
|
+
Sessions keep a persistent WebSocket connection to an instance in the background, making all interaction commands near-instant (~50ms instead of ~2s per command).
|
|
189
356
|
|
|
190
357
|
#### Why Sessions?
|
|
191
358
|
|
|
192
|
-
Without a session, every
|
|
359
|
+
Without a session, every command creates a new connection:
|
|
193
360
|
|
|
194
361
|
```
|
|
195
|
-
lim
|
|
196
|
-
lim
|
|
197
|
-
lim
|
|
362
|
+
lim ios screenshot # ~2s (connect + auth + screenshot + disconnect)
|
|
363
|
+
lim ios tap 100 200 # ~2s (connect + auth + tap + disconnect)
|
|
364
|
+
lim ios element-tree # ~2s (connect + auth + fetch + disconnect)
|
|
198
365
|
# Total: ~6s for 3 commands
|
|
199
366
|
```
|
|
200
367
|
|
|
201
368
|
With a session, the connection is created once and reused:
|
|
202
369
|
|
|
203
370
|
```
|
|
204
|
-
lim session start
|
|
205
|
-
lim
|
|
206
|
-
lim
|
|
207
|
-
lim
|
|
208
|
-
lim session stop
|
|
371
|
+
lim session start # ~2s (one-time connection setup)
|
|
372
|
+
lim ios screenshot # ~50ms (reuses connection)
|
|
373
|
+
lim ios tap 100 200 # ~50ms (reuses connection)
|
|
374
|
+
lim ios element-tree # ~50ms (reuses connection)
|
|
375
|
+
lim session stop # instant cleanup
|
|
209
376
|
# Total: ~2.15s for 3 commands
|
|
210
377
|
```
|
|
211
378
|
|
|
212
|
-
This makes sessions essential for interactive workflows, AI agent loops, and any scenario where you run multiple
|
|
379
|
+
This makes sessions essential for interactive workflows, AI agent loops, and any scenario where you run multiple commands against the same instance.
|
|
213
380
|
|
|
214
381
|
#### Session Commands
|
|
215
382
|
|
|
216
383
|
```bash
|
|
217
|
-
# Start
|
|
384
|
+
# Start a session (defaults to last created instance)
|
|
385
|
+
lim session start
|
|
386
|
+
|
|
387
|
+
# Or specify an instance explicitly
|
|
218
388
|
lim session start ios_abc123
|
|
219
|
-
|
|
220
|
-
|
|
389
|
+
|
|
390
|
+
# Multiple sessions can run simultaneously
|
|
391
|
+
lim session start ios_abc123
|
|
392
|
+
lim session start android_def456
|
|
221
393
|
|
|
222
394
|
# Check all active sessions
|
|
223
395
|
lim session status
|
|
@@ -234,53 +406,53 @@ If only one session is active, `lim session stop` (no ID) stops it automatically
|
|
|
234
406
|
|
|
235
407
|
#### How It Works
|
|
236
408
|
|
|
237
|
-
Each `lim session start
|
|
409
|
+
Each `lim session start` spawns an independent background daemon that:
|
|
238
410
|
- Holds a persistent WebSocket connection to that specific instance
|
|
239
411
|
- Listens on its own Unix socket at `/tmp/lim-sessions/<instance-id>/`
|
|
240
|
-
- All
|
|
412
|
+
- All interaction commands automatically detect the matching session and route through it
|
|
241
413
|
- Multiple sessions run in parallel with no shared state
|
|
242
414
|
|
|
243
415
|
#### Example: Interactive Testing
|
|
244
416
|
|
|
245
417
|
```bash
|
|
246
|
-
lim
|
|
247
|
-
lim session start
|
|
418
|
+
lim ios create --model iphone
|
|
419
|
+
lim session start
|
|
248
420
|
|
|
249
421
|
# Fast interaction loop — each command takes ~50ms
|
|
250
|
-
lim
|
|
251
|
-
lim
|
|
252
|
-
lim
|
|
253
|
-
lim
|
|
254
|
-
lim
|
|
255
|
-
lim
|
|
422
|
+
lim ios launch-app com.example.myapp
|
|
423
|
+
lim ios element-tree | jq '.tree'
|
|
424
|
+
lim ios tap-element --label "Login"
|
|
425
|
+
lim ios type "user@example.com"
|
|
426
|
+
lim ios tap-element --label "Submit"
|
|
427
|
+
lim ios screenshot -o after-login.png
|
|
256
428
|
|
|
257
|
-
lim session stop
|
|
258
|
-
lim delete ios_abc123
|
|
429
|
+
lim session stop
|
|
430
|
+
lim ios delete ios_abc123
|
|
259
431
|
```
|
|
260
432
|
|
|
261
433
|
#### Example: Multi-Device AI Agent
|
|
262
434
|
|
|
263
435
|
```bash
|
|
264
436
|
# Create two instances and start sessions for both
|
|
265
|
-
lim
|
|
266
|
-
lim
|
|
437
|
+
lim ios create --model iphone
|
|
438
|
+
lim ios create --model ipad
|
|
267
439
|
lim session start ios_phone_123
|
|
268
440
|
lim session start ios_tablet_456
|
|
269
441
|
|
|
270
442
|
# Agent controls both devices in parallel — ~50ms per command
|
|
271
|
-
lim
|
|
272
|
-
lim
|
|
443
|
+
lim ios launch-app com.example.myapp ios_phone_123
|
|
444
|
+
lim ios launch-app com.example.myapp ios_tablet_456
|
|
273
445
|
|
|
274
|
-
lim
|
|
275
|
-
lim
|
|
446
|
+
lim ios screenshot ios_phone_123 -o phone.png
|
|
447
|
+
lim ios screenshot ios_tablet_456 -o tablet.png
|
|
276
448
|
|
|
277
|
-
lim
|
|
278
|
-
lim
|
|
449
|
+
lim ios tap 200 400 ios_phone_123
|
|
450
|
+
lim ios element-tree ios_tablet_456 --json > tablet-tree.json
|
|
279
451
|
|
|
280
452
|
# Clean up all sessions
|
|
281
453
|
lim session stop --all
|
|
282
|
-
lim delete ios_phone_123
|
|
283
|
-
lim delete ios_tablet_456
|
|
454
|
+
lim ios delete ios_phone_123
|
|
455
|
+
lim ios delete ios_tablet_456
|
|
284
456
|
```
|
|
285
457
|
|
|
286
458
|
#### Example: Automated Test Matrix
|
|
@@ -291,15 +463,15 @@ DEVICES=("iphone" "ipad")
|
|
|
291
463
|
IDS=()
|
|
292
464
|
|
|
293
465
|
for model in "${DEVICES[@]}"; do
|
|
294
|
-
ID=$(lim
|
|
466
|
+
ID=$(lim ios create --model $model --json | jq -r '.metadata.id')
|
|
295
467
|
lim session start $ID
|
|
296
468
|
IDS+=($ID)
|
|
297
469
|
done
|
|
298
470
|
|
|
299
471
|
# Run tests against all devices
|
|
300
472
|
for ID in "${IDS[@]}"; do
|
|
301
|
-
lim
|
|
302
|
-
lim
|
|
473
|
+
lim ios launch-app com.example.myapp $ID
|
|
474
|
+
lim ios screenshot $ID -o "test_${ID}.png"
|
|
303
475
|
done
|
|
304
476
|
|
|
305
477
|
# Tear down
|
|
@@ -311,121 +483,6 @@ done
|
|
|
311
483
|
|
|
312
484
|
---
|
|
313
485
|
|
|
314
|
-
### Device Interaction
|
|
315
|
-
|
|
316
|
-
The `exec` commands let you interact with running Android and iOS instances directly from the command line. These commands auto-detect the platform from the instance ID prefix. When a [session](#sessions) is active, commands route through it automatically for near-instant execution.
|
|
317
|
-
|
|
318
|
-
#### Screenshots
|
|
319
|
-
|
|
320
|
-
```bash
|
|
321
|
-
# Save to file
|
|
322
|
-
lim exec screenshot ios_abc123 -o screenshot.png
|
|
323
|
-
|
|
324
|
-
# Output base64 to stdout (for piping)
|
|
325
|
-
lim exec screenshot ios_abc123
|
|
326
|
-
|
|
327
|
-
# JSON output with metadata
|
|
328
|
-
lim exec screenshot ios_abc123 --json
|
|
329
|
-
```
|
|
330
|
-
|
|
331
|
-
#### Tapping
|
|
332
|
-
|
|
333
|
-
```bash
|
|
334
|
-
# Tap at coordinates
|
|
335
|
-
lim exec tap ios_abc123 100 200
|
|
336
|
-
|
|
337
|
-
# Tap an element by accessibility selector
|
|
338
|
-
lim exec tap-element ios_abc123 --label "Submit"
|
|
339
|
-
lim exec tap-element ios_abc123 --accessibility-id btn_ok
|
|
340
|
-
|
|
341
|
-
# Android: tap by resource ID or text
|
|
342
|
-
lim exec tap-element android_abc123 --resource-id com.example:id/button
|
|
343
|
-
lim exec tap-element android_abc123 --text "Sign In"
|
|
344
|
-
```
|
|
345
|
-
|
|
346
|
-
#### Text Input
|
|
347
|
-
|
|
348
|
-
```bash
|
|
349
|
-
# Type text into the focused field
|
|
350
|
-
lim exec type ios_abc123 "Hello World"
|
|
351
|
-
|
|
352
|
-
# Type and press Enter (iOS)
|
|
353
|
-
lim exec type ios_abc123 "search query" --press-enter
|
|
354
|
-
|
|
355
|
-
# Press a key
|
|
356
|
-
lim exec press-key ios_abc123 enter
|
|
357
|
-
lim exec press-key ios_abc123 a --modifier shift
|
|
358
|
-
```
|
|
359
|
-
|
|
360
|
-
#### Scrolling
|
|
361
|
-
|
|
362
|
-
```bash
|
|
363
|
-
lim exec scroll ios_abc123 down --amount 500
|
|
364
|
-
lim exec scroll android_abc123 up --amount 300
|
|
365
|
-
```
|
|
366
|
-
|
|
367
|
-
#### UI Inspection
|
|
368
|
-
|
|
369
|
-
```bash
|
|
370
|
-
# Get the element/accessibility tree
|
|
371
|
-
lim exec element-tree ios_abc123
|
|
372
|
-
lim exec element-tree android_abc123
|
|
373
|
-
|
|
374
|
-
# Pipe to jq for filtering
|
|
375
|
-
lim exec element-tree ios_abc123 | jq '.'
|
|
376
|
-
```
|
|
377
|
-
|
|
378
|
-
#### App Management (iOS)
|
|
379
|
-
|
|
380
|
-
```bash
|
|
381
|
-
# Install an app from local file (auto-uploads)
|
|
382
|
-
lim exec install-app ios_abc123 ./MyApp.ipa
|
|
383
|
-
|
|
384
|
-
# Install from URL
|
|
385
|
-
lim exec install-app ios_abc123 https://example.com/app.ipa
|
|
386
|
-
|
|
387
|
-
# Launch / terminate
|
|
388
|
-
lim exec launch-app ios_abc123 com.example.myapp
|
|
389
|
-
lim exec launch-app ios_abc123 com.example.myapp --mode RelaunchIfRunning
|
|
390
|
-
lim exec terminate-app ios_abc123 com.example.myapp
|
|
391
|
-
|
|
392
|
-
# List installed apps
|
|
393
|
-
lim exec list-apps ios_abc123
|
|
394
|
-
```
|
|
395
|
-
|
|
396
|
-
#### Open URLs
|
|
397
|
-
|
|
398
|
-
```bash
|
|
399
|
-
# Open web URL (opens in browser on the device)
|
|
400
|
-
lim exec open-url ios_abc123 https://example.com
|
|
401
|
-
|
|
402
|
-
# Open deep link
|
|
403
|
-
lim exec open-url ios_abc123 myapp://settings
|
|
404
|
-
```
|
|
405
|
-
|
|
406
|
-
#### Log Streaming (iOS)
|
|
407
|
-
|
|
408
|
-
```bash
|
|
409
|
-
# Tail recent logs
|
|
410
|
-
lim exec log ios_abc123 com.example.myapp --lines 50
|
|
411
|
-
|
|
412
|
-
# Stream logs continuously (Ctrl+C to stop)
|
|
413
|
-
lim exec log ios_abc123 com.example.myapp -f
|
|
414
|
-
```
|
|
415
|
-
|
|
416
|
-
#### Video Recording
|
|
417
|
-
|
|
418
|
-
```bash
|
|
419
|
-
# Start recording
|
|
420
|
-
lim exec record ios_abc123 start
|
|
421
|
-
lim exec record ios_abc123 start --quality 8
|
|
422
|
-
|
|
423
|
-
# Stop and save
|
|
424
|
-
lim exec record ios_abc123 stop -o recording.mp4
|
|
425
|
-
```
|
|
426
|
-
|
|
427
|
-
---
|
|
428
|
-
|
|
429
486
|
### Xcode Build Pipeline
|
|
430
487
|
|
|
431
488
|
Build and test iOS apps remotely using cloud Xcode sandboxes. The `sync` and `build` commands work with both standalone Xcode instances and iOS instances that have Xcode sandbox enabled.
|
|
@@ -436,32 +493,32 @@ This gives you a simulator **and** a build environment in one instance — the b
|
|
|
436
493
|
|
|
437
494
|
```bash
|
|
438
495
|
# 1. Create iOS instance with Xcode sandbox
|
|
439
|
-
lim
|
|
496
|
+
lim ios create --xcode
|
|
440
497
|
# Output:
|
|
441
498
|
# Instance ID: ios_abc123
|
|
442
499
|
# Xcode Sandbox: https://...limrun.net/v1/sandbox_.../xcode
|
|
443
500
|
# (sandbox URL is cached locally for sync/build to use)
|
|
444
501
|
|
|
445
502
|
# 2. Sync your project code to the Xcode sandbox
|
|
446
|
-
lim sync
|
|
503
|
+
lim ios sync ./MyProject
|
|
447
504
|
|
|
448
505
|
# 3. Build — the app is auto-installed on the simulator
|
|
449
|
-
lim build
|
|
506
|
+
lim ios build --scheme MyApp --workspace MyApp.xcworkspace
|
|
450
507
|
|
|
451
508
|
# 4. Start a session for fast device interaction
|
|
452
|
-
lim session start
|
|
509
|
+
lim session start
|
|
453
510
|
|
|
454
511
|
# 5. Test the built app on the simulator (~50ms per command)
|
|
455
|
-
lim
|
|
456
|
-
lim
|
|
457
|
-
lim
|
|
512
|
+
lim ios launch-app com.example.myapp
|
|
513
|
+
lim ios element-tree | jq '.'
|
|
514
|
+
lim ios screenshot -o built-app.png
|
|
458
515
|
|
|
459
516
|
# 6. Clean up
|
|
460
|
-
lim session stop
|
|
461
|
-
lim delete ios_abc123
|
|
517
|
+
lim session stop
|
|
518
|
+
lim ios delete ios_abc123
|
|
462
519
|
```
|
|
463
520
|
|
|
464
|
-
> **Note:** The Xcode sandbox URL is only returned when the instance is created — not on subsequent `
|
|
521
|
+
> **Note:** The Xcode sandbox URL is only returned when the instance is created — not on subsequent `list` calls. The CLI caches it locally at `~/.lim/instances/` so that `sync` and `build` can find it. This means `sync`/`build` must run on the same machine where `ios create --xcode` was executed.
|
|
465
522
|
|
|
466
523
|
#### Option B: Standalone Xcode Instance
|
|
467
524
|
|
|
@@ -469,54 +526,36 @@ Use this when you only need to build (no simulator needed), or when you want to
|
|
|
469
526
|
|
|
470
527
|
```bash
|
|
471
528
|
# 1. Create a standalone Xcode instance
|
|
472
|
-
lim
|
|
529
|
+
lim xcode create --rm
|
|
473
530
|
|
|
474
531
|
# 2. Sync and build
|
|
475
|
-
lim sync
|
|
476
|
-
lim build
|
|
532
|
+
lim xcode sync ./MyProject
|
|
533
|
+
lim xcode build --scheme MyApp --workspace MyApp.xcworkspace
|
|
477
534
|
|
|
478
535
|
# 3. Upload build artifact
|
|
479
|
-
lim build
|
|
536
|
+
lim xcode build --scheme MyApp --upload my-app-build
|
|
480
537
|
|
|
481
538
|
# 4. Download the artifact
|
|
482
|
-
lim pull my-app-build -o ./build-output
|
|
539
|
+
lim asset pull my-app-build -o ./build-output
|
|
483
540
|
```
|
|
484
541
|
|
|
485
542
|
#### Sync Options
|
|
486
543
|
|
|
487
544
|
```bash
|
|
488
545
|
# Watch mode (re-syncs on file changes, default)
|
|
489
|
-
lim sync
|
|
546
|
+
lim ios sync ./MyProject --watch
|
|
490
547
|
|
|
491
548
|
# One-shot sync (no watch)
|
|
492
|
-
lim sync
|
|
549
|
+
lim ios sync ./MyProject --no-watch
|
|
493
550
|
|
|
494
551
|
# Sync without installing
|
|
495
|
-
lim sync
|
|
552
|
+
lim ios sync ./MyProject --no-install
|
|
496
553
|
```
|
|
497
554
|
|
|
498
555
|
The sync automatically ignores build artifacts (`build/`, `DerivedData/`, `.build/`), dependency folders (`Pods/`, `Carthage/Build/`, `.swiftpm/`), and user-specific files (`xcuserdata/`, `.dSYM/`).
|
|
499
556
|
|
|
500
557
|
---
|
|
501
558
|
|
|
502
|
-
### Connectivity
|
|
503
|
-
|
|
504
|
-
#### Android ADB Tunnel
|
|
505
|
-
|
|
506
|
-
Connect to a running Android instance for `adb` access:
|
|
507
|
-
|
|
508
|
-
```bash
|
|
509
|
-
# Connect to an existing instance
|
|
510
|
-
lim connect android android_abc123
|
|
511
|
-
|
|
512
|
-
# With custom adb path
|
|
513
|
-
lim connect android android_abc123 --adb-path /usr/local/bin/adb
|
|
514
|
-
```
|
|
515
|
-
|
|
516
|
-
The tunnel stays open until you press Ctrl+C. While connected, you can use `adb` commands in another terminal.
|
|
517
|
-
|
|
518
|
-
---
|
|
519
|
-
|
|
520
559
|
## Configuration
|
|
521
560
|
|
|
522
561
|
The CLI reads configuration from multiple sources (in order of precedence):
|
|
@@ -541,14 +580,14 @@ All commands support `--json` for machine-readable output, making the CLI suitab
|
|
|
541
580
|
|
|
542
581
|
```bash
|
|
543
582
|
# Get instance details as JSON
|
|
544
|
-
lim
|
|
583
|
+
lim ios list ios_abc123 --json
|
|
545
584
|
|
|
546
585
|
# Parse with jq
|
|
547
|
-
lim
|
|
586
|
+
lim android list --json | jq '.[].metadata.id'
|
|
548
587
|
|
|
549
588
|
# Use in scripts
|
|
550
|
-
INSTANCE_ID=$(lim
|
|
551
|
-
lim
|
|
589
|
+
INSTANCE_ID=$(lim ios create --json | jq -r '.metadata.id')
|
|
590
|
+
lim ios screenshot -o test.png
|
|
552
591
|
lim delete $INSTANCE_ID
|
|
553
592
|
```
|
|
554
593
|
|
|
@@ -559,45 +598,43 @@ lim delete $INSTANCE_ID
|
|
|
559
598
|
### CI Testing: Install and Verify an App
|
|
560
599
|
|
|
561
600
|
```bash
|
|
562
|
-
INSTANCE_ID="ios_..."
|
|
563
|
-
|
|
564
601
|
# Create instance and start session for fast commands
|
|
565
|
-
lim
|
|
566
|
-
lim session start
|
|
602
|
+
lim ios create --install ./build/MyApp.ipa
|
|
603
|
+
lim session start
|
|
567
604
|
|
|
568
605
|
# Verify — each command takes ~50ms with session
|
|
569
|
-
lim
|
|
606
|
+
lim ios launch-app com.example.myapp
|
|
570
607
|
sleep 2
|
|
571
|
-
lim
|
|
572
|
-
lim
|
|
608
|
+
lim ios element-tree | grep "Welcome"
|
|
609
|
+
lim ios screenshot -o test-result.png
|
|
573
610
|
|
|
574
611
|
# Clean up
|
|
575
|
-
lim session stop
|
|
576
|
-
lim delete
|
|
612
|
+
lim session stop
|
|
613
|
+
lim delete ios_abc123
|
|
577
614
|
```
|
|
578
615
|
|
|
579
616
|
### AI Agent Automation
|
|
580
617
|
|
|
581
618
|
```bash
|
|
582
619
|
# Create instance
|
|
583
|
-
INSTANCE=$(lim
|
|
620
|
+
INSTANCE=$(lim ios create --model iphone --json)
|
|
584
621
|
ID=$(echo $INSTANCE | jq -r '.metadata.id')
|
|
585
622
|
|
|
586
|
-
# Start session — all
|
|
587
|
-
lim session start
|
|
623
|
+
# Start session — all commands now run in ~50ms
|
|
624
|
+
lim session start
|
|
588
625
|
|
|
589
626
|
# Agent can interact at high speed
|
|
590
|
-
lim
|
|
591
|
-
lim
|
|
592
|
-
lim
|
|
593
|
-
lim
|
|
594
|
-
lim
|
|
627
|
+
lim ios tap 200 400
|
|
628
|
+
lim ios type "test@example.com"
|
|
629
|
+
lim ios tap-element --label "Sign In"
|
|
630
|
+
lim ios screenshot -o result.png
|
|
631
|
+
lim ios element-tree --json > ui-state.json
|
|
595
632
|
|
|
596
633
|
# Tail logs (non-streaming works through session too)
|
|
597
|
-
lim
|
|
634
|
+
lim ios log com.example.myapp --lines 20
|
|
598
635
|
|
|
599
636
|
# Clean up
|
|
600
|
-
lim session stop
|
|
637
|
+
lim session stop
|
|
601
638
|
lim delete $ID
|
|
602
639
|
```
|
|
603
640
|
|
|
@@ -605,18 +642,18 @@ lim delete $ID
|
|
|
605
642
|
|
|
606
643
|
```bash
|
|
607
644
|
# Single instance: Xcode sandbox + iOS simulator
|
|
608
|
-
ID=$(lim
|
|
645
|
+
ID=$(lim ios create --xcode --json | jq -r '.metadata.id')
|
|
609
646
|
|
|
610
647
|
# Sync, build, and test
|
|
611
|
-
lim sync
|
|
612
|
-
lim build
|
|
648
|
+
lim ios sync ./MyiOSProject --no-watch
|
|
649
|
+
lim ios build --scheme MyApp --workspace MyApp.xcworkspace
|
|
613
650
|
|
|
614
651
|
# Verify the built app on the simulator
|
|
615
|
-
lim session start
|
|
616
|
-
lim
|
|
652
|
+
lim session start
|
|
653
|
+
lim ios launch-app com.example.myapp
|
|
617
654
|
sleep 2
|
|
618
|
-
lim
|
|
619
|
-
lim
|
|
655
|
+
lim ios element-tree | grep "Welcome"
|
|
656
|
+
lim ios screenshot -o test-result.png
|
|
620
657
|
lim session stop
|
|
621
658
|
|
|
622
659
|
lim delete $ID
|
|
@@ -625,12 +662,11 @@ lim delete $ID
|
|
|
625
662
|
### Build-Only with Artifact Upload
|
|
626
663
|
|
|
627
664
|
```bash
|
|
628
|
-
lim
|
|
629
|
-
XCODE_ID="xcode_..."
|
|
665
|
+
lim xcode create --rm --reuse-if-exists --label project=myapp
|
|
630
666
|
|
|
631
|
-
lim sync
|
|
632
|
-
lim build
|
|
633
|
-
lim pull myapp-latest -o ./build-output
|
|
667
|
+
lim xcode sync ./MyiOSProject --no-watch
|
|
668
|
+
lim xcode build --scheme MyApp --workspace MyApp.xcworkspace --upload myapp-latest
|
|
669
|
+
lim asset pull myapp-latest -o ./build-output
|
|
634
670
|
```
|
|
635
671
|
|
|
636
672
|
---
|
|
@@ -652,8 +688,8 @@ npm run build
|
|
|
652
688
|
npm run build && node bin/run.js <command>
|
|
653
689
|
|
|
654
690
|
# Or use watch mode in one terminal, run in another
|
|
655
|
-
npx tsc --watch
|
|
656
|
-
node bin/run.js
|
|
691
|
+
npx tsc --watch # Terminal 1
|
|
692
|
+
node bin/run.js ios list # Terminal 2
|
|
657
693
|
```
|
|
658
694
|
|
|
659
695
|
### Link globally
|
|
@@ -663,7 +699,7 @@ npm link
|
|
|
663
699
|
|
|
664
700
|
# Now `lim` works anywhere on your machine
|
|
665
701
|
lim --help
|
|
666
|
-
lim
|
|
702
|
+
lim android list
|
|
667
703
|
|
|
668
704
|
# Unlink when done
|
|
669
705
|
npm unlink -g @limrun/cli
|