@limrun/cli 0.2.9 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (270) hide show
  1. package/README.md +90 -89
  2. package/bin/run.js +60 -5
  3. package/dist/base-command.d.ts.map +1 -1
  4. package/dist/base-command.js +2 -2
  5. package/dist/base-command.js.map +1 -1
  6. package/dist/commands/android/connect.d.ts +1 -1
  7. package/dist/commands/android/connect.d.ts.map +1 -1
  8. package/dist/commands/android/connect.js +13 -4
  9. package/dist/commands/android/connect.js.map +1 -1
  10. package/dist/commands/android/create.d.ts +0 -2
  11. package/dist/commands/android/create.d.ts.map +1 -1
  12. package/dist/commands/android/create.js +26 -23
  13. package/dist/commands/android/create.js.map +1 -1
  14. package/dist/commands/android/delete.d.ts +1 -1
  15. package/dist/commands/android/delete.d.ts.map +1 -1
  16. package/dist/commands/android/delete.js +6 -3
  17. package/dist/commands/android/delete.js.map +1 -1
  18. package/dist/commands/android/element-tree.d.ts +2 -0
  19. package/dist/commands/android/element-tree.d.ts.map +1 -0
  20. package/dist/commands/android/element-tree.js +9 -0
  21. package/dist/commands/android/element-tree.js.map +1 -0
  22. package/dist/commands/android/get.d.ts +1 -1
  23. package/dist/commands/android/get.d.ts.map +1 -1
  24. package/dist/commands/android/get.js +3 -3
  25. package/dist/commands/android/get.js.map +1 -1
  26. package/dist/commands/android/install-app.d.ts +2 -0
  27. package/dist/commands/android/install-app.d.ts.map +1 -0
  28. package/dist/commands/android/install-app.js +9 -0
  29. package/dist/commands/android/install-app.js.map +1 -0
  30. package/dist/commands/android/list.d.ts +1 -0
  31. package/dist/commands/android/list.d.ts.map +1 -1
  32. package/dist/commands/android/list.js +17 -5
  33. package/dist/commands/android/list.js.map +1 -1
  34. package/dist/commands/android/open-url.d.ts +2 -0
  35. package/dist/commands/android/open-url.d.ts.map +1 -0
  36. package/dist/commands/android/open-url.js +9 -0
  37. package/dist/commands/android/open-url.js.map +1 -0
  38. package/dist/commands/android/press-key.d.ts +2 -0
  39. package/dist/commands/android/press-key.d.ts.map +1 -0
  40. package/dist/commands/android/press-key.js +9 -0
  41. package/dist/commands/android/press-key.js.map +1 -0
  42. package/dist/commands/android/record.d.ts +2 -0
  43. package/dist/commands/android/record.d.ts.map +1 -0
  44. package/dist/commands/android/record.js +9 -0
  45. package/dist/commands/android/record.js.map +1 -0
  46. package/dist/commands/android/screenshot.d.ts +2 -0
  47. package/dist/commands/android/screenshot.d.ts.map +1 -0
  48. package/dist/commands/android/screenshot.js +9 -0
  49. package/dist/commands/android/screenshot.js.map +1 -0
  50. package/dist/commands/android/scroll.d.ts +2 -0
  51. package/dist/commands/android/scroll.d.ts.map +1 -0
  52. package/dist/commands/android/scroll.js +9 -0
  53. package/dist/commands/android/scroll.js.map +1 -0
  54. package/dist/commands/android/tap-element.d.ts +2 -0
  55. package/dist/commands/android/tap-element.d.ts.map +1 -0
  56. package/dist/commands/android/tap-element.js +9 -0
  57. package/dist/commands/android/tap-element.js.map +1 -0
  58. package/dist/commands/android/tap.d.ts +2 -0
  59. package/dist/commands/android/tap.d.ts.map +1 -0
  60. package/dist/commands/android/tap.js +9 -0
  61. package/dist/commands/android/tap.js.map +1 -0
  62. package/dist/commands/android/type.d.ts +2 -0
  63. package/dist/commands/android/type.d.ts.map +1 -0
  64. package/dist/commands/android/type.js +9 -0
  65. package/dist/commands/android/type.js.map +1 -0
  66. package/dist/commands/asset/delete.d.ts +1 -1
  67. package/dist/commands/asset/delete.d.ts.map +1 -1
  68. package/dist/commands/asset/delete.js +2 -2
  69. package/dist/commands/asset/delete.js.map +1 -1
  70. package/dist/commands/asset/list.d.ts +1 -1
  71. package/dist/commands/asset/list.d.ts.map +1 -1
  72. package/dist/commands/asset/list.js +16 -6
  73. package/dist/commands/asset/list.js.map +1 -1
  74. package/dist/commands/asset/pull.d.ts +1 -1
  75. package/dist/commands/asset/pull.d.ts.map +1 -1
  76. package/dist/commands/asset/pull.js +16 -4
  77. package/dist/commands/asset/pull.js.map +1 -1
  78. package/dist/commands/asset/push.d.ts +1 -1
  79. package/dist/commands/asset/push.d.ts.map +1 -1
  80. package/dist/commands/asset/push.js +3 -3
  81. package/dist/commands/asset/push.js.map +1 -1
  82. package/dist/commands/exec/element-tree.d.ts +1 -1
  83. package/dist/commands/exec/element-tree.d.ts.map +1 -1
  84. package/dist/commands/exec/element-tree.js +6 -2
  85. package/dist/commands/exec/element-tree.js.map +1 -1
  86. package/dist/commands/exec/install-app.d.ts +0 -1
  87. package/dist/commands/exec/install-app.d.ts.map +1 -1
  88. package/dist/commands/exec/install-app.js +9 -4
  89. package/dist/commands/exec/install-app.js.map +1 -1
  90. package/dist/commands/exec/open-url.d.ts +1 -1
  91. package/dist/commands/exec/open-url.d.ts.map +1 -1
  92. package/dist/commands/exec/open-url.js +9 -3
  93. package/dist/commands/exec/open-url.js.map +1 -1
  94. package/dist/commands/exec/perform.d.ts +16 -0
  95. package/dist/commands/exec/perform.d.ts.map +1 -0
  96. package/dist/commands/exec/perform.js +232 -0
  97. package/dist/commands/exec/perform.js.map +1 -0
  98. package/dist/commands/exec/press-key.d.ts +1 -1
  99. package/dist/commands/exec/press-key.d.ts.map +1 -1
  100. package/dist/commands/exec/press-key.js +9 -3
  101. package/dist/commands/exec/press-key.js.map +1 -1
  102. package/dist/commands/exec/record.d.ts +1 -1
  103. package/dist/commands/exec/record.d.ts.map +1 -1
  104. package/dist/commands/exec/record.js +20 -6
  105. package/dist/commands/exec/record.js.map +1 -1
  106. package/dist/commands/exec/screenshot.d.ts +1 -1
  107. package/dist/commands/exec/screenshot.d.ts.map +1 -1
  108. package/dist/commands/exec/screenshot.js +9 -3
  109. package/dist/commands/exec/screenshot.js.map +1 -1
  110. package/dist/commands/exec/scroll.d.ts +1 -1
  111. package/dist/commands/exec/scroll.d.ts.map +1 -1
  112. package/dist/commands/exec/scroll.js +7 -4
  113. package/dist/commands/exec/scroll.js.map +1 -1
  114. package/dist/commands/exec/tap-element.d.ts +1 -1
  115. package/dist/commands/exec/tap-element.d.ts.map +1 -1
  116. package/dist/commands/exec/tap-element.js +16 -6
  117. package/dist/commands/exec/tap-element.js.map +1 -1
  118. package/dist/commands/exec/tap.d.ts +1 -1
  119. package/dist/commands/exec/tap.d.ts.map +1 -1
  120. package/dist/commands/exec/tap.js +13 -4
  121. package/dist/commands/exec/tap.js.map +1 -1
  122. package/dist/commands/exec/type.d.ts +2 -2
  123. package/dist/commands/exec/type.d.ts.map +1 -1
  124. package/dist/commands/exec/type.js +12 -6
  125. package/dist/commands/exec/type.js.map +1 -1
  126. package/dist/commands/ios/create.d.ts +0 -1
  127. package/dist/commands/ios/create.d.ts.map +1 -1
  128. package/dist/commands/ios/create.js +28 -11
  129. package/dist/commands/ios/create.js.map +1 -1
  130. package/dist/commands/ios/delete.d.ts +1 -1
  131. package/dist/commands/ios/delete.d.ts.map +1 -1
  132. package/dist/commands/ios/delete.js +3 -3
  133. package/dist/commands/ios/delete.js.map +1 -1
  134. package/dist/commands/ios/element-tree.d.ts +2 -0
  135. package/dist/commands/ios/element-tree.d.ts.map +1 -0
  136. package/dist/commands/ios/element-tree.js +9 -0
  137. package/dist/commands/ios/element-tree.js.map +1 -0
  138. package/dist/commands/ios/get.d.ts +1 -1
  139. package/dist/commands/ios/get.d.ts.map +1 -1
  140. package/dist/commands/ios/get.js +3 -3
  141. package/dist/commands/ios/get.js.map +1 -1
  142. package/dist/commands/{delete/index.d.ts → ios/info.d.ts} +5 -5
  143. package/dist/commands/ios/info.d.ts.map +1 -0
  144. package/dist/commands/ios/info.js +60 -0
  145. package/dist/commands/ios/info.js.map +1 -0
  146. package/dist/commands/ios/install-app.d.ts +2 -0
  147. package/dist/commands/ios/install-app.d.ts.map +1 -0
  148. package/dist/commands/ios/install-app.js +9 -0
  149. package/dist/commands/ios/install-app.js.map +1 -0
  150. package/dist/commands/ios/launch-app.d.ts +1 -1
  151. package/dist/commands/ios/launch-app.d.ts.map +1 -1
  152. package/dist/commands/ios/launch-app.js +5 -3
  153. package/dist/commands/ios/launch-app.js.map +1 -1
  154. package/dist/commands/ios/list-apps.d.ts +1 -1
  155. package/dist/commands/ios/list-apps.d.ts.map +1 -1
  156. package/dist/commands/ios/list-apps.js +9 -3
  157. package/dist/commands/ios/list-apps.js.map +1 -1
  158. package/dist/commands/ios/list.d.ts +1 -0
  159. package/dist/commands/ios/list.d.ts.map +1 -1
  160. package/dist/commands/ios/list.js +17 -5
  161. package/dist/commands/ios/list.js.map +1 -1
  162. package/dist/commands/ios/log.d.ts +1 -1
  163. package/dist/commands/ios/log.d.ts.map +1 -1
  164. package/dist/commands/ios/log.js +17 -5
  165. package/dist/commands/ios/log.js.map +1 -1
  166. package/dist/commands/ios/open-url.d.ts +2 -0
  167. package/dist/commands/ios/open-url.d.ts.map +1 -0
  168. package/dist/commands/ios/open-url.js +9 -0
  169. package/dist/commands/ios/open-url.js.map +1 -0
  170. package/dist/commands/ios/perform.d.ts +2 -0
  171. package/dist/commands/ios/perform.d.ts.map +1 -0
  172. package/dist/commands/ios/perform.js +9 -0
  173. package/dist/commands/ios/perform.js.map +1 -0
  174. package/dist/commands/ios/press-key.d.ts +2 -0
  175. package/dist/commands/ios/press-key.d.ts.map +1 -0
  176. package/dist/commands/ios/press-key.js +9 -0
  177. package/dist/commands/ios/press-key.js.map +1 -0
  178. package/dist/commands/ios/record.d.ts +2 -0
  179. package/dist/commands/ios/record.d.ts.map +1 -0
  180. package/dist/commands/ios/record.js +9 -0
  181. package/dist/commands/ios/record.js.map +1 -0
  182. package/dist/commands/ios/screenshot.d.ts +2 -0
  183. package/dist/commands/ios/screenshot.d.ts.map +1 -0
  184. package/dist/commands/ios/screenshot.js +9 -0
  185. package/dist/commands/ios/screenshot.js.map +1 -0
  186. package/dist/commands/ios/scroll.d.ts +2 -0
  187. package/dist/commands/ios/scroll.d.ts.map +1 -0
  188. package/dist/commands/ios/scroll.js +9 -0
  189. package/dist/commands/ios/scroll.js.map +1 -0
  190. package/dist/commands/ios/sync.d.ts +19 -0
  191. package/dist/commands/ios/sync.d.ts.map +1 -0
  192. package/dist/commands/ios/sync.js +91 -0
  193. package/dist/commands/ios/sync.js.map +1 -0
  194. package/dist/commands/ios/tap-element.d.ts +2 -0
  195. package/dist/commands/ios/tap-element.d.ts.map +1 -0
  196. package/dist/commands/ios/tap-element.js +9 -0
  197. package/dist/commands/ios/tap-element.js.map +1 -0
  198. package/dist/commands/ios/tap.d.ts +2 -0
  199. package/dist/commands/ios/tap.d.ts.map +1 -0
  200. package/dist/commands/ios/tap.js +9 -0
  201. package/dist/commands/ios/tap.js.map +1 -0
  202. package/dist/commands/ios/terminate-app.d.ts +1 -1
  203. package/dist/commands/ios/terminate-app.d.ts.map +1 -1
  204. package/dist/commands/ios/terminate-app.js +9 -3
  205. package/dist/commands/ios/terminate-app.js.map +1 -1
  206. package/dist/commands/ios/type.d.ts +2 -0
  207. package/dist/commands/ios/type.d.ts.map +1 -0
  208. package/dist/commands/ios/type.js +9 -0
  209. package/dist/commands/ios/type.js.map +1 -0
  210. package/dist/commands/login.d.ts +1 -0
  211. package/dist/commands/login.d.ts.map +1 -1
  212. package/dist/commands/login.js +2 -1
  213. package/dist/commands/login.js.map +1 -1
  214. package/dist/commands/logout.d.ts +1 -0
  215. package/dist/commands/logout.d.ts.map +1 -1
  216. package/dist/commands/logout.js +2 -1
  217. package/dist/commands/logout.js.map +1 -1
  218. package/dist/commands/session/start.d.ts.map +1 -1
  219. package/dist/commands/session/start.js +4 -2
  220. package/dist/commands/session/start.js.map +1 -1
  221. package/dist/commands/session/status.d.ts +1 -0
  222. package/dist/commands/session/status.d.ts.map +1 -1
  223. package/dist/commands/session/status.js +2 -1
  224. package/dist/commands/session/status.js.map +1 -1
  225. package/dist/commands/session/stop.d.ts.map +1 -1
  226. package/dist/commands/session/stop.js +8 -3
  227. package/dist/commands/session/stop.js.map +1 -1
  228. package/dist/commands/{build.d.ts → xcode/build.d.ts} +2 -3
  229. package/dist/commands/xcode/build.d.ts.map +1 -0
  230. package/dist/commands/{build.js → xcode/build.js} +31 -26
  231. package/dist/commands/xcode/build.js.map +1 -0
  232. package/dist/commands/xcode/create.d.ts +0 -1
  233. package/dist/commands/xcode/create.d.ts.map +1 -1
  234. package/dist/commands/xcode/create.js +15 -7
  235. package/dist/commands/xcode/create.js.map +1 -1
  236. package/dist/commands/xcode/delete.d.ts +1 -1
  237. package/dist/commands/xcode/delete.d.ts.map +1 -1
  238. package/dist/commands/xcode/delete.js +4 -4
  239. package/dist/commands/xcode/delete.js.map +1 -1
  240. package/dist/commands/xcode/get.d.ts +1 -1
  241. package/dist/commands/xcode/get.d.ts.map +1 -1
  242. package/dist/commands/xcode/get.js +3 -3
  243. package/dist/commands/xcode/get.js.map +1 -1
  244. package/dist/commands/xcode/list.d.ts +1 -0
  245. package/dist/commands/xcode/list.d.ts.map +1 -1
  246. package/dist/commands/xcode/list.js +16 -4
  247. package/dist/commands/xcode/list.js.map +1 -1
  248. package/dist/commands/{sync.d.ts → xcode/sync.d.ts} +2 -3
  249. package/dist/commands/xcode/sync.d.ts.map +1 -0
  250. package/dist/commands/{sync.js → xcode/sync.js} +32 -26
  251. package/dist/commands/xcode/sync.js.map +1 -0
  252. package/dist/lib/daemon-client.d.ts +1 -1
  253. package/dist/lib/daemon-client.d.ts.map +1 -1
  254. package/dist/lib/daemon-client.js +2 -2
  255. package/dist/lib/daemon-client.js.map +1 -1
  256. package/dist/lib/daemon.d.ts.map +1 -1
  257. package/dist/lib/daemon.js +12 -0
  258. package/dist/lib/daemon.js.map +1 -1
  259. package/dist/lib/instance-client-factory.d.ts +1 -1
  260. package/dist/lib/instance-client-factory.d.ts.map +1 -1
  261. package/dist/lib/instance-client-factory.js +2 -2
  262. package/dist/lib/instance-client-factory.js.map +1 -1
  263. package/package.json +8 -17
  264. package/dist/commands/build.d.ts.map +0 -1
  265. package/dist/commands/build.js.map +0 -1
  266. package/dist/commands/delete/index.d.ts.map +0 -1
  267. package/dist/commands/delete/index.js +0 -48
  268. package/dist/commands/delete/index.js.map +0 -1
  269. package/dist/commands/sync.d.ts.map +0 -1
  270. package/dist/commands/sync.js.map +0 -1
package/README.md CHANGED
@@ -35,11 +35,11 @@ The CLI stores configuration in `~/.lim/config.yaml`. This file is compatible wi
35
35
 
36
36
  Every command supports these flags:
37
37
 
38
- | Flag | Description |
39
- |------|-------------|
40
- | `--api-key <value>` | API key (also reads `LIM_API_KEY` env var) |
41
- | `--json` | Output as JSON instead of human-readable tables |
42
- | `--help` | Show help for any command |
38
+ | Flag | Description |
39
+ | ------------------- | ----------------------------------------------- |
40
+ | `--api-key <value>` | API key (also reads `LIM_API_KEY` env var) |
41
+ | `--json` | Output as JSON instead of human-readable tables |
42
+ | `--help` | Show help for any command |
43
43
 
44
44
  ## Command Structure
45
45
 
@@ -67,14 +67,16 @@ You can always provide an ID explicitly to target a specific instance:
67
67
  lim ios screenshot -o test.png --id ios_def456
68
68
  ```
69
69
 
70
- **Top-level shortcuts** are available for common actions the platform is auto-detected from the instance ID prefix:
70
+ For repeatable scripts and LLM agents, prefer explicit platform commands plus an explicit `--id` once you have it:
71
71
 
72
72
  ```bash
73
- lim screenshot --id ios_abc123 # Works for both iOS and Android
74
- lim tap 100 200 --id ios_abc123 # Auto-detects platform from ID prefix
75
- lim delete ios_abc123 # Auto-detects resource type from ID prefix
73
+ lim ios get ios_abc123 --json
74
+ lim ios screenshot --id ios_abc123 -o screenshot.png
75
+ lim android tap --id android_abc123 100 200
76
76
  ```
77
77
 
78
+ This avoids relying on locally cached "last created" state and keeps the target platform explicit.
79
+
78
80
  ## Commands
79
81
 
80
82
  - [iOS](#ios) — Create, manage, and interact with iOS instances
@@ -93,6 +95,7 @@ lim ios create # Create a new iOS instance
93
95
  lim ios list # List all ready iOS instances
94
96
  lim ios get <ID> # Get details of a specific instance
95
97
  lim ios delete <ID> # Delete an instance
98
+ lim ios info # Get device info from a running instance
96
99
  ```
97
100
 
98
101
  #### Create Options
@@ -116,19 +119,19 @@ lim ios create --region us-west --display-name "CI Test" --label env=ci --rm
116
119
 
117
120
  **Flags for `ios create`:**
118
121
 
119
- | Flag | Description |
120
- |------|-------------|
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 |
124
- | `--region <value>` | Region for the instance (e.g. `us-west`) |
125
- | `--display-name <value>` | Human-readable name |
126
- | `--label <key=value>` | Labels (repeatable). Used for filtering and reuse |
127
- | `--hard-timeout <duration>` | Max lifetime (e.g. `1m`, `10m`, `3h`). Default: none |
128
- | `--inactivity-timeout <duration>` | Idle timeout. Default: `3m` |
129
- | `--reuse-if-exists` | Reuse an existing instance with matching labels/region |
130
- | `--install <file>` | Local file to install (auto-uploads, repeatable) |
131
- | `--install-asset <name>` | Asset name to install (repeatable) |
122
+ | Flag | Description |
123
+ | --------------------------------- | ------------------------------------------------------ |
124
+ | `--rm` | Auto-delete the instance on exit (Ctrl+C) |
125
+ | `--model <iphone\|ipad\|watch>` | Simulator device model |
126
+ | `--xcode` | Attach a Xcode build sandbox to the iOS instance |
127
+ | `--region <value>` | Region for the instance (e.g. `us-west`) |
128
+ | `--display-name <value>` | Human-readable name |
129
+ | `--label <key=value>` | Labels (repeatable). Used for filtering and reuse |
130
+ | `--hard-timeout <duration>` | Max lifetime (e.g. `1m`, `10m`, `3h`). Default: none |
131
+ | `--inactivity-timeout <duration>` | Idle timeout. Default: `3m` |
132
+ | `--reuse-if-exists` | Reuse an existing instance with matching labels/region |
133
+ | `--install <file>` | Local file to install (auto-uploads, repeatable) |
134
+ | `--install-asset <name>` | Asset name to install (repeatable) |
132
135
 
133
136
  #### List and Filter
134
137
 
@@ -147,6 +150,10 @@ lim ios get <ID> # Single instance details
147
150
  All interaction commands accept an optional `--id`. When omitted, the last created iOS instance is used.
148
151
 
149
152
  ```bash
153
+ # Device info
154
+ lim ios info
155
+ lim ios info --json
156
+
150
157
  # Screenshots
151
158
  lim ios screenshot -o screenshot.png
152
159
  lim ios screenshot # Output base64 to stdout
@@ -158,13 +165,25 @@ lim ios tap-element --accessibility-id btn_ok
158
165
 
159
166
  # Text input
160
167
  lim ios type "Hello World"
161
- lim ios type "search query" --press-enter
168
+ lim ios type "search query" --enter
162
169
  lim ios press-key enter
163
170
  lim ios press-key a --modifier shift
164
171
 
165
172
  # Scrolling
166
173
  lim ios scroll down --amount 500
167
174
 
175
+ # Batch multiple actions in one call
176
+ lim ios perform --action type=tap,x=100,y=200 --action 'type=typeText,text=Hello World'
177
+ lim ios perform --action type=wait,durationMs=500 --action type=pressKey,key=enter
178
+ lim ios perform --file ./actions.yaml
179
+
180
+ # actions.yaml
181
+ - type: tap
182
+ x: 100
183
+ y: 200
184
+ - type: typeText
185
+ text: "Hello World"
186
+
168
187
  # UI inspection
169
188
  lim ios element-tree
170
189
  lim ios element-tree | jq '.'
@@ -210,12 +229,14 @@ lim ios record stop -o recording.mp4
210
229
  lim ios record stop --presigned-url https://example.com/upload
211
230
  ```
212
231
 
213
- #### Xcode Integration
232
+ #### Built App Sync (iOS only)
214
233
 
215
234
  ```bash
216
- # Sync/build use the current directory if no path is provided; pass instance IDs with --id (requires --xcode on create)
217
- lim ios sync ./MyProject
218
- lim ios build --scheme MyApp --workspace MyApp.xcworkspace
235
+ # Sync a built .app bundle to the current iOS instance
236
+ lim ios sync ./Build/Products/Debug-iphonesimulator/MyApp.app
237
+
238
+ # Re-sync on changes and relaunch if the app is already running
239
+ lim ios sync ./MyApp.app --watch --launch-mode RelaunchIfRunning
219
240
  ```
220
241
 
221
242
  ---
@@ -232,14 +253,14 @@ lim android delete <ID> # Delete an instance
232
253
  #### Create Options
233
254
 
234
255
  ```bash
235
- # Basic (with ADB tunnel and scrcpy streaming)
256
+ # Basic (prints a Console URL you can open in the browser)
236
257
  lim android create
237
258
 
238
259
  # With apps pre-installed
239
260
  lim android create --install ./my-app.apk --install ./another.apk
240
261
 
241
- # Without streaming
242
- lim android create --no-stream
262
+ # Create without opening an ADB tunnel
263
+ lim android create --no-connect
243
264
 
244
265
  # Full options
245
266
  lim android create --region us-west --display-name "CI Test" --label env=ci --rm
@@ -247,11 +268,12 @@ lim android create --region us-west --display-name "CI Test" --label env=ci --rm
247
268
 
248
269
  **Android-specific flags:**
249
270
 
250
- | Flag | Description |
251
- |------|-------------|
252
- | `--[no-]connect` | Start ADB tunnel (default: true) |
253
- | `--[no-]stream` | Launch scrcpy for visual control (default: true) |
254
- | `--adb-path <path>` | Path to `adb` binary (default: `adb`) |
271
+ | Flag | Description |
272
+ | ------------------- | ------------------------------------------------ |
273
+ | `--[no-]connect` | Start an ADB tunnel immediately (default: true) |
274
+ | `--adb-path <path>` | Path to `adb` binary (default: `adb`) |
275
+
276
+ `lim android create` always prints a Console URL such as `https://console.limrun.com/stream/android_...` that you can open in the browser for live viewing. For automation, `--no-connect` is usually the safest default.
255
277
 
256
278
  #### Device Interaction
257
279
 
@@ -317,12 +339,11 @@ lim xcode delete <ID> # Delete an instance
317
339
  # Create with options
318
340
  lim xcode create --rm --region us-west --hard-timeout 1h
319
341
 
320
- # Sync and build
321
- lim xcode sync ./MyProject
322
- lim xcode build --scheme MyApp --workspace MyApp.xcworkspace
342
+ # Build (automatically syncs the project path first)
343
+ lim xcode build ./MyProject --scheme MyApp --workspace MyApp.xcworkspace
323
344
 
324
345
  # Build and upload artifact
325
- lim xcode build --scheme MyApp --upload my-app-build
346
+ lim xcode build ./MyProject --scheme MyApp --upload my-app-build
326
347
  ```
327
348
 
328
349
  ---
@@ -338,8 +359,9 @@ lim asset push ./my-app.ipa -n custom-name
338
359
 
339
360
  # Download a file
340
361
  lim asset pull asset_abc123
341
- lim asset pull my-app.apk
342
362
  lim asset pull asset_abc123 -o ./downloads
363
+ lim asset list --name my-app.apk --json
364
+ lim asset pull asset_abc123
343
365
 
344
366
  # List assets
345
367
  lim asset list
@@ -407,11 +429,12 @@ lim session stop --id ios_abc123
407
429
  lim session stop --all
408
430
  ```
409
431
 
410
- If only one session is active, `lim session stop` (no ID) stops it automatically.
432
+ If only one session is active, `lim session stop` (no ID) stops it automatically. For scripts and agents, prefer `--id` explicitly so the target instance is unambiguous.
411
433
 
412
434
  #### How It Works
413
435
 
414
436
  Each `lim session start` spawns an independent background daemon that:
437
+
415
438
  - Holds a persistent WebSocket connection to that specific instance
416
439
  - Listens on its own Unix socket at `/tmp/lim-sessions/<instance-id>/`
417
440
  - All interaction commands automatically detect the matching session and route through it
@@ -482,7 +505,7 @@ done
482
505
  # Tear down
483
506
  lim session stop --all
484
507
  for ID in "${IDS[@]}"; do
485
- lim delete $ID
508
+ lim ios delete $ID
486
509
  done
487
510
  ```
488
511
 
@@ -504,26 +527,23 @@ lim ios create --xcode
504
527
  # Xcode Sandbox: https://...limrun.net/v1/sandbox_.../xcode
505
528
  # (sandbox URL is cached locally for sync/build to use)
506
529
 
507
- # 2. Sync your project code to the Xcode sandbox
508
- lim ios sync ./MyProject
530
+ # 2. Build — automatically syncs your project code first, then auto-installs on the simulator
531
+ lim xcode build ./MyProject --id ios_abc123 --scheme MyApp --workspace MyApp.xcworkspace
509
532
 
510
- # 3. Build the app is auto-installed on the simulator
511
- lim ios build --scheme MyApp --workspace MyApp.xcworkspace
512
-
513
- # 4. Start a session for fast device interaction
533
+ # 3. Start a session for fast device interaction
514
534
  lim session start
515
535
 
516
- # 5. Test the built app on the simulator (~50ms per command)
536
+ # 4. Test the built app on the simulator (~50ms per command)
517
537
  lim ios launch-app com.example.myapp
518
538
  lim ios element-tree | jq '.'
519
539
  lim ios screenshot -o built-app.png
520
540
 
521
- # 6. Clean up
541
+ # 5. Clean up
522
542
  lim session stop
523
543
  lim ios delete ios_abc123
524
544
  ```
525
545
 
526
- > **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.
546
+ > **Note:** `lim xcode build` already syncs the project path you pass before invoking `xcodebuild`, so you do not need to call `lim xcode sync` first. 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 build workflows can find it. This means `build` must run on the same machine where `ios create --xcode` was executed.
527
547
 
528
548
  #### Option B: Standalone Xcode Instance
529
549
 
@@ -533,37 +553,19 @@ Use this when you only need to build (no simulator needed), or when you want to
533
553
  # 1. Create a standalone Xcode instance
534
554
  lim xcode create --rm
535
555
 
536
- # 2. Sync and build
537
- lim xcode sync ./MyProject
538
- lim xcode build --scheme MyApp --workspace MyApp.xcworkspace
556
+ # 2. Build (automatically syncs the project path first)
557
+ lim xcode build ./MyProject --scheme MyApp --workspace MyApp.xcworkspace
539
558
 
540
559
  # 3. Upload build artifact
541
- lim xcode build --scheme MyApp --upload my-app-build
560
+ lim xcode build ./MyProject --scheme MyApp --upload my-app-build
542
561
 
543
562
  # 4. Download the artifact
544
563
  lim asset pull my-app-build -o ./build-output
545
564
  ```
546
565
 
547
- #### Sync Options
548
-
549
- ```bash
550
- # Sync the current directory
551
- lim ios sync
552
-
553
- # Watch mode (re-syncs on file changes)
554
- lim ios sync ./MyProject --watch
555
-
556
- # One-shot sync (default)
557
- lim ios sync ./MyProject
566
+ #### Build Behavior
558
567
 
559
- # Explicitly disable watch mode
560
- lim ios sync ./MyProject --no-watch
561
-
562
- # Sync without installing
563
- lim ios sync ./MyProject --no-install
564
- ```
565
-
566
- The sync automatically ignores build artifacts (`build/`, `DerivedData/`, `.build/`), dependency folders (`Pods/`, `Carthage/Build/`, `.swiftpm/`), and user-specific files (`xcuserdata/`, `.dSYM/`).
568
+ `lim xcode build [PATH]` automatically performs a one-shot code sync for the given project path before invoking `xcodebuild`. The sync step automatically ignores build artifacts (`build/`, `DerivedData/`, `.build/`), dependency folders (`Pods/`, `Carthage/Build/`, `.swiftpm/`), and user-specific files (`xcuserdata/`, `.dSYM/`).
567
569
 
568
570
  ---
569
571
 
@@ -577,10 +579,10 @@ The CLI reads configuration from multiple sources (in order of precedence):
577
579
 
578
580
  **Config file keys:**
579
581
 
580
- | Key | Default | Description |
581
- |-----|---------|-------------|
582
- | `api-key` | — | Your Limrun API key |
583
- | `api-endpoint` | `https://api.limrun.com` | API base URL |
582
+ | Key | Default | Description |
583
+ | ------------------ | ---------------------------- | ----------------------- |
584
+ | `api-key` | — | Your Limrun API key |
585
+ | `api-endpoint` | `https://api.limrun.com` | API base URL |
584
586
  | `console-endpoint` | `https://console.limrun.com` | Console URL (for login) |
585
587
 
586
588
  ---
@@ -598,8 +600,8 @@ lim android list --json | jq '.[].metadata.id'
598
600
 
599
601
  # Use in scripts
600
602
  INSTANCE_ID=$(lim ios create --json | jq -r '.metadata.id')
601
- lim ios screenshot -o test.png
602
- lim delete $INSTANCE_ID
603
+ lim ios screenshot --id $INSTANCE_ID -o test.png
604
+ lim ios delete $INSTANCE_ID
603
605
  ```
604
606
 
605
607
  ---
@@ -621,7 +623,7 @@ lim ios screenshot -o test-result.png
621
623
 
622
624
  # Clean up
623
625
  lim session stop
624
- lim delete ios_abc123
626
+ lim ios delete ios_abc123
625
627
  ```
626
628
 
627
629
  ### AI Agent Automation
@@ -646,7 +648,7 @@ lim ios log com.example.myapp --lines 20
646
648
 
647
649
  # Clean up
648
650
  lim session stop
649
- lim delete $ID
651
+ lim ios delete $ID
650
652
  ```
651
653
 
652
654
  ### Remote Build + Test on iOS Simulator
@@ -655,9 +657,8 @@ lim delete $ID
655
657
  # Single instance: Xcode sandbox + iOS simulator
656
658
  ID=$(lim ios create --xcode --json | jq -r '.metadata.id')
657
659
 
658
- # Sync, build, and test
659
- lim ios sync ./MyiOSProject
660
- lim ios build --scheme MyApp --workspace MyApp.xcworkspace
660
+ # Build and test (build automatically syncs the project path first)
661
+ lim xcode build ./MyiOSProject --id $ID --scheme MyApp --workspace MyApp.xcworkspace
661
662
 
662
663
  # Verify the built app on the simulator
663
664
  lim session start
@@ -667,7 +668,7 @@ lim ios element-tree | grep "Welcome"
667
668
  lim ios screenshot -o test-result.png
668
669
  lim session stop
669
670
 
670
- lim delete $ID
671
+ lim ios delete $ID
671
672
  ```
672
673
 
673
674
  ### Build-Only with Artifact Upload
@@ -675,9 +676,9 @@ lim delete $ID
675
676
  ```bash
676
677
  lim xcode create --rm --reuse-if-exists --label project=myapp
677
678
 
678
- lim xcode sync ./MyiOSProject
679
- lim xcode build --scheme MyApp --workspace MyApp.xcworkspace --upload myapp-latest
680
- lim asset pull myapp-latest -o ./build-output
679
+ lim xcode build ./MyiOSProject --scheme MyApp --workspace MyApp.xcworkspace --upload myapp-latest
680
+ lim asset list --name myapp-latest --json
681
+ lim asset pull asset_abc123 -o ./build-output
681
682
  ```
682
683
 
683
684
  ---
package/bin/run.js CHANGED
@@ -1,8 +1,63 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- const oclif = require('@oclif/core');
3
+ const { flush } = require('@oclif/core');
4
+ const { Config } = require('@oclif/core/config');
5
+ const { handle } = require('@oclif/core/errors');
6
+ const { Help, standardizeIDFromArgv } = require('@oclif/core/help');
7
+ const { run } = require('@oclif/core/run');
4
8
 
5
- oclif
6
- .execute({ dir: __dirname, args: process.argv.slice(2) })
7
- .then(oclif.flush)
8
- .catch(oclif.Errors.handle);
9
+ function isUsageError(error) {
10
+ return typeof error?.message === 'string' && error.message.includes('\nSee more help with --help');
11
+ }
12
+
13
+ async function inferCommandArgv(argv) {
14
+ const config = await Config.load(__dirname);
15
+ const normalizedArgv = standardizeIDFromArgv([...argv], config);
16
+ const normalizedCommandId = normalizedArgv[0];
17
+
18
+ if (normalizedCommandId && config.findCommand(normalizedCommandId)) {
19
+ return { commandArgv: normalizedCommandId.split(':'), config };
20
+ }
21
+
22
+ const positionalPrefix = [];
23
+ for (const token of argv) {
24
+ if (token === '--' || token.startsWith('-')) break;
25
+ positionalPrefix.push(token);
26
+ }
27
+
28
+ for (let i = positionalPrefix.length; i > 0; i -= 1) {
29
+ const commandId = positionalPrefix.slice(0, i).join(':');
30
+ if (config.findCommand(commandId)) {
31
+ return { commandArgv: commandId.split(':'), config };
32
+ }
33
+ }
34
+
35
+ return { commandArgv: undefined, config };
36
+ }
37
+
38
+ async function handleError(error) {
39
+ if (!isUsageError(error)) {
40
+ await handle(error);
41
+ return;
42
+ }
43
+
44
+ error.message = error.message.replace(/\nSee more help with --help$/, '');
45
+
46
+ const { commandArgv, config } = await inferCommandArgv(process.argv.slice(2));
47
+ if (!commandArgv) {
48
+ await handle(error);
49
+ return;
50
+ }
51
+
52
+ console.error(typeof error.render === 'function' ? error.render() : error.message);
53
+ console.error();
54
+
55
+ const help = new Help(config, {
56
+ ...(config.pjson.oclif.helpOptions ?? config.pjson.helpOptions),
57
+ sendToStderr: true,
58
+ });
59
+ await help.showHelp(commandArgv);
60
+ process.exitCode = error.oclif?.exit ?? 1;
61
+ }
62
+
63
+ run(process.argv.slice(2), __dirname).catch(handleError).finally(flush);
@@ -1 +1 @@
1
- {"version":3,"file":"base-command.d.ts","sourceRoot":"","sources":["../src/base-command.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAS,MAAM,aAAa,CAAC;AAC7C,OAAO,MAA+B,MAAM,aAAa,CAAC;AAO1D,8BAAsB,WAAY,SAAQ,OAAO;IAC/C,MAAM,CAAC,SAAS;;;MASd;IAEF,OAAO,CAAC,OAAO,CAAC,CAAS;IAEzB,SAAS,KAAK,MAAM,IAAI,MAAM,CAc7B;IAED,OAAO,CAAC,YAAY,CAAC,CAA0B;IAE/C,SAAS,KAAK,WAAW,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAE/D;IAED,SAAS,CAAC,cAAc,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;cAI9C,QAAQ,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAiB7D,SAAS,CAAC,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,IAAI;IAgBhE,SAAS,CAAC,UAAU,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI;IAIzC,SAAS,CAAC,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM;IAKtD;;;OAGG;IACH,SAAS,CAAC,SAAS,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM;CAO5D"}
1
+ {"version":3,"file":"base-command.d.ts","sourceRoot":"","sources":["../src/base-command.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAS,MAAM,aAAa,CAAC;AAC7C,OAAO,MAA+B,MAAM,aAAa,CAAC;AAO1D,8BAAsB,WAAY,SAAQ,OAAO;IAC/C,MAAM,CAAC,SAAS;;;MAWd;IAEF,OAAO,CAAC,OAAO,CAAC,CAAS;IAEzB,SAAS,KAAK,MAAM,IAAI,MAAM,CAc7B;IAED,OAAO,CAAC,YAAY,CAAC,CAA0B;IAE/C,SAAS,KAAK,WAAW,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAE/D;IAED,SAAS,CAAC,cAAc,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;cAI9C,QAAQ,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAiB7D,SAAS,CAAC,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,IAAI;IAgBhE,SAAS,CAAC,UAAU,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI;IAIzC,SAAS,CAAC,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM;IAKtD;;;OAGG;IACH,SAAS,CAAC,SAAS,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM;CAO5D"}
@@ -115,11 +115,11 @@ class BaseCommand extends core_1.Command {
115
115
  exports.BaseCommand = BaseCommand;
116
116
  BaseCommand.baseFlags = {
117
117
  'api-key': core_1.Flags.string({
118
- description: 'API key for authentication',
118
+ description: 'API key to use for this command. Overrides the saved login and can also be provided via LIM_API_KEY.',
119
119
  env: 'LIM_API_KEY',
120
120
  }),
121
121
  json: core_1.Flags.boolean({
122
- description: 'Output as JSON',
122
+ description: 'Output structured JSON instead of human-readable tables or plain text when the command supports it.',
123
123
  default: false,
124
124
  }),
125
125
  };
@@ -1 +1 @@
1
- {"version":3,"file":"base-command.js","sourceRoot":"","sources":["../src/base-command.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"base-command.js","sourceRoot":"","sources":["../src/base-command.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  import { BaseCommand } from '../../base-command';
2
2
  export default class AndroidConnect extends BaseCommand {
3
3
  static summary: string;
4
- static aliases: string[];
4
+ static description: string;
5
5
  static examples: string[];
6
6
  static args: {};
7
7
  static flags: {
@@ -1 +1 @@
1
- {"version":3,"file":"connect.d.ts","sourceRoot":"","sources":["../../../src/commands/android/connect.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEjD,MAAM,CAAC,OAAO,OAAO,cAAe,SAAQ,WAAW;IACrD,MAAM,CAAC,OAAO,SAA4D;IAC1E,MAAM,CAAC,OAAO,WAAuB;IACrC,MAAM,CAAC,QAAQ,WAAwF;IAEvG,MAAM,CAAC,IAAI,KAAM;IAEjB,MAAM,CAAC,KAAK;;;;;MAIV;IAEI,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAoC3B"}
1
+ {"version":3,"file":"connect.d.ts","sourceRoot":"","sources":["../../../src/commands/android/connect.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEjD,MAAM,CAAC,OAAO,OAAO,cAAe,SAAQ,WAAW;IACrD,MAAM,CAAC,OAAO,SAA4D;IAC1E,MAAM,CAAC,WAAW,SACmN;IACrO,MAAM,CAAC,QAAQ,WAIb;IAEF,MAAM,CAAC,IAAI,KAAM;IAEjB,MAAM,CAAC,KAAK;;;;;MAUV;IAEI,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAoC3B"}
@@ -69,13 +69,22 @@ class AndroidConnect extends base_command_1.BaseCommand {
69
69
  }
70
70
  }
71
71
  AndroidConnect.summary = 'Connect to an existing Android instance via ADB tunnel';
72
- AndroidConnect.aliases = ['connect android'];
73
- AndroidConnect.examples = ['<%= config.bin %> android connect', '<%= config.bin %> android connect --id <ID>'];
72
+ AndroidConnect.description = 'Open a long-lived ADB tunnel to a running Android instance so local tools can talk to it as if it were attached over USB. The command stays running until you stop it. For scripts and agents, prefer passing `--id` explicitly.';
73
+ AndroidConnect.examples = [
74
+ '<%= config.bin %> android connect',
75
+ '<%= config.bin %> android connect --id <ID>',
76
+ '<%= config.bin %> android connect --id android_abc123 --adb-path /opt/homebrew/bin/adb',
77
+ ];
74
78
  AndroidConnect.args = {};
75
79
  AndroidConnect.flags = {
76
80
  ...base_command_1.BaseCommand.baseFlags,
77
- id: core_1.Flags.string({ description: 'Android instance ID (defaults to last created)' }),
78
- 'adb-path': core_1.Flags.string({ description: 'Path to adb binary', default: 'adb' }),
81
+ id: core_1.Flags.string({
82
+ description: 'Android instance ID to connect to. Defaults to the last created Android instance, but `--id` is recommended for scripts and agents.',
83
+ }),
84
+ 'adb-path': core_1.Flags.string({
85
+ description: 'Path to the adb binary available on your machine',
86
+ default: 'adb',
87
+ }),
79
88
  };
80
89
  exports.default = AndroidConnect;
81
90
  //# sourceMappingURL=connect.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"connect.js","sourceRoot":"","sources":["../../../src/commands/android/connect.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,sCAAoC;AACpC,qDAAiD;AAEjD,MAAqB,cAAe,SAAQ,0BAAW;IAarD,KAAK,CAAC,GAAG;QACP,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;QACzD,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;QAE3B,MAAM,IAAI,CAAC,QAAQ,CAAC,KAAK,IAAI,EAAE;YAC7B,MAAM,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YACpC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAC5D,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;gBAC5B,IAAI,CAAC,KAAK,CAAC,YAAY,EAAE,wCAAwC,CAAC,CAAC;YACrE,CAAC;YAED,MAAM,EAAE,oBAAoB,EAAE,GAAG,wDAAa,aAAa,GAAC,CAAC;YAC7D,MAAM,cAAc,GAAG,MAAM,oBAAoB,CAAC;gBAChD,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM;gBAC9B,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,eAAe;gBACvC,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,KAAK;aAC7B,CAAC,CAAC;YAEH,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,cAAc,EAAE,CAAC;YACrD,IAAI,CAAC,GAAG,CAAC,uCAAuC,CAAC,CAAC;YAElD,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;gBAClC,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE,GAAE,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC;gBACjD,MAAM,QAAQ,GAAG,GAAG,EAAE;oBACpB,aAAa,CAAC,SAAS,CAAC,CAAC;oBACzB,IAAI,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;oBAC/B,OAAO,EAAE,CAAC;gBACZ,CAAC,CAAC;gBACF,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;gBAC/B,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;YAClC,CAAC,CAAC,CAAC;YAEH,MAAM,CAAC,KAAK,EAAE,CAAC;YACf,cAAc,CAAC,UAAU,EAAE,CAAC;QAC9B,CAAC,CAAC,CAAC;IACL,CAAC;;AA/CM,sBAAO,GAAG,wDAAwD,CAAC;AACnE,sBAAO,GAAG,CAAC,iBAAiB,CAAC,CAAC;AAC9B,uBAAQ,GAAG,CAAC,mCAAmC,EAAE,6CAA6C,CAAC,CAAC;AAEhG,mBAAI,GAAG,EAAE,CAAC;AAEV,oBAAK,GAAG;IACb,GAAG,0BAAW,CAAC,SAAS;IACxB,EAAE,EAAE,YAAK,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,gDAAgD,EAAE,CAAC;IACnF,UAAU,EAAE,YAAK,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,oBAAoB,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;CAChF,CAAC;kBAXiB,cAAc"}
1
+ {"version":3,"file":"connect.js","sourceRoot":"","sources":["../../../src/commands/android/connect.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,sCAAoC;AACpC,qDAAiD;AAEjD,MAAqB,cAAe,SAAQ,0BAAW;IAwBrD,KAAK,CAAC,GAAG;QACP,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;QACzD,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;QAE3B,MAAM,IAAI,CAAC,QAAQ,CAAC,KAAK,IAAI,EAAE;YAC7B,MAAM,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YACpC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAC5D,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;gBAC5B,IAAI,CAAC,KAAK,CAAC,YAAY,EAAE,wCAAwC,CAAC,CAAC;YACrE,CAAC;YAED,MAAM,EAAE,oBAAoB,EAAE,GAAG,wDAAa,aAAa,GAAC,CAAC;YAC7D,MAAM,cAAc,GAAG,MAAM,oBAAoB,CAAC;gBAChD,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM;gBAC9B,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,eAAe;gBACvC,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,KAAK;aAC7B,CAAC,CAAC;YAEH,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,cAAc,EAAE,CAAC;YACrD,IAAI,CAAC,GAAG,CAAC,uCAAuC,CAAC,CAAC;YAElD,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;gBAClC,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE,GAAE,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC;gBACjD,MAAM,QAAQ,GAAG,GAAG,EAAE;oBACpB,aAAa,CAAC,SAAS,CAAC,CAAC;oBACzB,IAAI,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;oBAC/B,OAAO,EAAE,CAAC;gBACZ,CAAC,CAAC;gBACF,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;gBAC/B,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;YAClC,CAAC,CAAC,CAAC;YAEH,MAAM,CAAC,KAAK,EAAE,CAAC;YACf,cAAc,CAAC,UAAU,EAAE,CAAC;QAC9B,CAAC,CAAC,CAAC;IACL,CAAC;;AA1DM,sBAAO,GAAG,wDAAwD,CAAC;AACnE,0BAAW,GAChB,kOAAkO,CAAC;AAC9N,uBAAQ,GAAG;IAChB,mCAAmC;IACnC,6CAA6C;IAC7C,wFAAwF;CACzF,CAAC;AAEK,mBAAI,GAAG,EAAE,CAAC;AAEV,oBAAK,GAAG;IACb,GAAG,0BAAW,CAAC,SAAS;IACxB,EAAE,EAAE,YAAK,CAAC,MAAM,CAAC;QACf,WAAW,EACT,qIAAqI;KACxI,CAAC;IACF,UAAU,EAAE,YAAK,CAAC,MAAM,CAAC;QACvB,WAAW,EAAE,kDAAkD;QAC/D,OAAO,EAAE,KAAK;KACf,CAAC;CACH,CAAC;kBAtBiB,cAAc"}
@@ -2,11 +2,9 @@ import { BaseCommand } from '../../base-command';
2
2
  export default class AndroidCreate extends BaseCommand {
3
3
  static summary: string;
4
4
  static description: string;
5
- static aliases: string[];
6
5
  static examples: string[];
7
6
  static flags: {
8
7
  connect: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
9
- stream: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
10
8
  rm: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
11
9
  'adb-path': import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
12
10
  'display-name': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
@@ -1 +1 @@
1
- {"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../../src/commands/android/create.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAKjD,MAAM,CAAC,OAAO,OAAO,aAAc,SAAQ,WAAW;IACpD,MAAM,CAAC,OAAO,SAAmC;IACjD,MAAM,CAAC,WAAW,SACkF;IACpG,MAAM,CAAC,OAAO,WAAmB;IAEjC,MAAM,CAAC,QAAQ,WAIb;IAEF,MAAM,CAAC,KAAK;;;;;;;;;;;;;;;MAwBV;IAEI,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAgH3B"}
1
+ {"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../../src/commands/android/create.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAKjD,MAAM,CAAC,OAAO,OAAO,aAAc,SAAQ,WAAW;IACpD,MAAM,CAAC,OAAO,SAAmC;IACjD,MAAM,CAAC,WAAW,SAC+J;IAEjL,MAAM,CAAC,QAAQ,WAKb;IAEF,MAAM,CAAC,KAAK;;;;;;;;;;;;;;MAsCV;IAEI,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAyG3B"}
@@ -37,7 +37,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
37
37
  };
38
38
  Object.defineProperty(exports, "__esModule", { value: true });
39
39
  const path_1 = __importDefault(require("path"));
40
- const child_process_1 = require("child_process");
41
40
  const core_1 = require("@oclif/core");
42
41
  const base_command_1 = require("../../base-command");
43
42
  const formatting_1 = require("../../lib/formatting");
@@ -119,16 +118,7 @@ class AndroidCreate extends base_command_1.BaseCommand {
119
118
  token: instance.status.token,
120
119
  });
121
120
  const tunnel = await instanceClient.startAdbTunnel();
122
- if (flags.stream) {
123
- const addr = `${tunnel.address.address}:${tunnel.address.port}`;
124
- const scrcpy = (0, child_process_1.spawn)('scrcpy', ['-s', addr], { stdio: 'inherit' });
125
- scrcpy.on('error', (err) => {
126
- this.warn(`Failed to start scrcpy: ${err.message}`);
127
- });
128
- scrcpy.on('close', () => {
129
- process.kill(process.pid, 'SIGTERM');
130
- });
131
- }
121
+ this.log(`Open the Console URL in your browser to stream the device: ${this.consoleStreamUrl(instance.metadata.id)}`);
132
122
  this.log('Tunnel started. Press Ctrl+C to stop.');
133
123
  await new Promise((resolve) => {
134
124
  const keepAlive = setInterval(() => { }, 1 << 30);
@@ -152,35 +142,48 @@ class AndroidCreate extends base_command_1.BaseCommand {
152
142
  }
153
143
  }
154
144
  AndroidCreate.summary = 'Create a new Android instance';
155
- AndroidCreate.description = 'Creates and optionally connects to a new Android instance with ADB tunnel and scrcpy streaming.';
156
- AndroidCreate.aliases = ['run android'];
145
+ AndroidCreate.description = 'Create a new cloud Android instance and optionally connect to it immediately with an ADB tunnel. Use the printed Console URL to open the live device stream in your browser.';
157
146
  AndroidCreate.examples = [
158
147
  '<%= config.bin %> android create',
159
148
  '<%= config.bin %> android create --rm --install ./app.apk',
160
149
  '<%= config.bin %> android create --region us-west --label env=dev',
150
+ '<%= config.bin %> android create --no-connect',
161
151
  ];
162
152
  AndroidCreate.flags = {
163
153
  ...base_command_1.BaseCommand.baseFlags,
164
154
  connect: core_1.Flags.boolean({
165
- description: 'Connect to the instance (start ADB tunnel)',
155
+ description: 'Connect to the new instance immediately by starting an ADB tunnel',
166
156
  default: true,
167
157
  allowNo: true,
168
158
  }),
169
- stream: core_1.Flags.boolean({ description: 'Stream the instance with scrcpy', default: true, allowNo: true }),
170
- rm: core_1.Flags.boolean({ description: 'Delete instance on exit', default: false }),
171
- 'adb-path': core_1.Flags.string({ description: 'Path to adb binary', default: 'adb' }),
172
- 'display-name': core_1.Flags.string({ description: 'Display name for the instance' }),
173
- region: core_1.Flags.string({ description: 'Region where the instance will be created' }),
159
+ rm: core_1.Flags.boolean({
160
+ description: 'Delete the instance automatically when this CLI process exits',
161
+ default: false,
162
+ }),
163
+ 'adb-path': core_1.Flags.string({
164
+ description: 'Path to the adb binary used for tunnel-driven workflows',
165
+ default: 'adb',
166
+ }),
167
+ 'display-name': core_1.Flags.string({
168
+ description: 'Human-friendly display name shown in listings and the console',
169
+ }),
170
+ region: core_1.Flags.string({ description: 'Region where the instance should be created, such as us-west' }),
174
171
  'hard-timeout': core_1.Flags.string({ description: 'Hard timeout (e.g. 1m, 10m, 3h). Default: no timeout' }),
175
172
  'inactivity-timeout': core_1.Flags.string({ description: 'Inactivity timeout (e.g. 1m, 10m, 3h). Default: 3m' }),
176
- label: core_1.Flags.string({ description: 'Labels in key=value format', multiple: true }),
173
+ label: core_1.Flags.string({
174
+ description: 'Metadata label in key=value format. Repeat to attach multiple labels.',
175
+ multiple: true,
176
+ }),
177
177
  'reuse-if-exists': core_1.Flags.boolean({
178
- description: 'Reuse existing instance with same labels/region',
178
+ description: 'Reuse an existing matching instance instead of creating a new one',
179
179
  default: false,
180
180
  }),
181
- 'install-asset': core_1.Flags.string({ description: 'Asset name to install (can be repeated)', multiple: true }),
181
+ 'install-asset': core_1.Flags.string({
182
+ description: 'Existing asset name to install after creation. Repeat for multiple assets.',
183
+ multiple: true,
184
+ }),
182
185
  install: core_1.Flags.string({
183
- description: 'Local file to install (auto-uploads if needed, can be repeated)',
186
+ description: 'Local app file to upload and install automatically after creation. Repeat for multiple files.',
184
187
  multiple: true,
185
188
  }),
186
189
  };