@exedev/sdk 0.1.0 → 0.2.0

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.
@@ -1,10 +1,15 @@
1
1
  // Code generated by "go run ./cmd/gensdkjs" in the exe.dev repository. DO NOT EDIT.
2
- //
3
- // Every public exe.dev command that runs over the HTTPS API (POST /exec), as a
4
- // method of Commands, documented with the command's own help text. Positional
5
- // arguments are parameters; flags are keys of the options object, spelled as
6
- // on the command line.
7
- export class Commands {
2
+ import { Transport, ExeAPIError, ExeProtocolError, abortable, delay } from "./client.js";
3
+ export class ExedevClient {
4
+ #transport;
5
+ constructor(options) { this.#transport = new Transport(options); }
6
+ /** Reference an existing VM without a request. Use refresh() to fetch its metadata. */
7
+ vm(name) {
8
+ if (typeof name !== "string" || !/^[a-zA-Z0-9][a-zA-Z0-9-]*$/.test(name)) {
9
+ throw new TypeError("exedev: expected a VM name, not a command or SSH destination");
10
+ }
11
+ return new VM(this.#transport, { name, tags: [] });
12
+ }
8
13
  /**
9
14
  * Browse documentation
10
15
  *
@@ -12,8 +17,9 @@ export class Commands {
12
17
  *
13
18
  * Tag-scoped API keys may run this command.
14
19
  */
15
- doc(slugOrQueries, options) {
16
- return this.run("doc", [slugOrQueries], options, {});
20
+ async doc(slugOrQueries, options) {
21
+ const result = await this.#transport.call("doc", [slugOrQueries], options, {}, false);
22
+ return result;
17
23
  }
18
24
  /**
19
25
  * List your VMs
@@ -22,11 +28,12 @@ export class Commands {
22
28
  *
23
29
  * Tag-scoped API keys may run this command.
24
30
  */
25
- ls(nameOrPattern, options) {
26
- return this.run("ls", [nameOrPattern], options, {
31
+ async ls(nameOrPattern, options) {
32
+ const result = await this.#transport.call("ls", [nameOrPattern], options, {
27
33
  group: "string",
28
34
  l: "bool",
29
- });
35
+ }, true);
36
+ return listVMs(this.#transport, result);
30
37
  }
31
38
  /**
32
39
  * Create a new VM
@@ -45,8 +52,10 @@ export class Commands {
45
52
  *
46
53
  * Tag-scoped API keys may run this command.
47
54
  */
48
- new(options) {
49
- return this.run("new", [], options, {
55
+ async new(options) {
56
+ const ready = readiness(options ?? {});
57
+ const { waitUntil, timeoutMs, ...flags } = options ?? {};
58
+ const result = await this.#transport.call("new", [], flags, {
50
59
  comment: "string",
51
60
  cpu: "number",
52
61
  disk: "string",
@@ -64,297 +73,22 @@ export class Commands {
64
73
  "setup-script": "string",
65
74
  standalone: "bool",
66
75
  tag: "repeated",
67
- });
68
- }
69
- /**
70
- * Delete a VM
71
- *
72
- * Usage: `rm <vmname>...`
73
- *
74
- * Tag-scoped API keys may run this command.
75
- */
76
- rm(vmnames, options) {
77
- return this.run("rm", [vmnames], options, {});
78
- }
79
- /**
80
- * Restart a VM
81
- *
82
- * Usage: `restart <vmname>`
83
- *
84
- * Tag-scoped API keys may run this command.
85
- */
86
- restart(vmname, options) {
87
- return this.run("restart", [vmname], options, {});
88
- }
89
- /**
90
- * Pause a VM (snapshot RAM to disk, free its CPU and memory)
91
- *
92
- * Usage: `pause <vmname>`
93
- *
94
- * CLI examples:
95
- * ```
96
- * pause my-vm # snapshot RAM to disk; resume later with 'resume my-vm'
97
- * ```
98
- *
99
- * Tag-scoped API keys may run this command.
100
- */
101
- pause(vmname, options) {
102
- return this.run("pause", [vmname], options, {});
103
- }
104
- /**
105
- * Resume a paused VM (restore RAM from disk)
106
- *
107
- * Usage: `resume <vmname>`
108
- *
109
- * Tag-scoped API keys may run this command.
110
- */
111
- resume(vmname, options) {
112
- return this.run("resume", [vmname], options, {});
113
- }
114
- /**
115
- * rename a vm
116
- *
117
- * Usage: `rename <oldname> <newname>`
118
- *
119
- * Tag-scoped API keys may run this command.
120
- */
121
- rename(oldname, newname, options) {
122
- return this.run("rename", [oldname, newname], options, {});
123
- }
124
- /**
125
- * Add or remove tags on a VM
126
- *
127
- * Usage: `tag [-d] <vm> <tag-name> [tag-name...]`
128
- *
129
- * CLI examples:
130
- * ```
131
- * tag my-vm prod web # add tags
132
- * tag -d my-vm prod web # remove tags
133
- * ```
134
- *
135
- * Tag-scoped API keys may run this command.
136
- */
137
- tag(vm, tagNames, options) {
138
- return this.run("tag", [vm, tagNames], options, {
139
- d: "bool",
140
- });
141
- }
142
- /**
143
- * Copy an existing VM
144
- *
145
- * Usage: `cp <source-vm> [new-name] [--pool=<name>] [--memory=<size>] [--cpu=<count>] [--disk=<size>]`
146
- *
147
- * CLI examples:
148
- * ```
149
- * cp my-vm # copy with auto-generated name
150
- * cp my-vm my-vm-copy # copy with specific name
151
- * cp my-vm --cpu=4 --memory=16GB # copy with different resources
152
- * cp my-vm my-pool-copy --pool=build # copy into a team pool
153
- * cp my-vm --copy-tags=false # copy without tags
154
- * ```
155
- *
156
- * Tag-scoped API keys may run this command.
157
- */
158
- cp(sourceVm, newName, options) {
159
- return this.run("cp", [sourceVm, newName], options, {
160
- "copy-tags": "bool",
161
- cpu: "number",
162
- disk: "string",
163
- memory: "string",
164
- pool: "string",
165
- sandbox: "bool",
166
- standalone: "bool",
167
- });
168
- }
169
- /**
170
- * Resize a VM's resources (memory, CPU, disk)
171
- *
172
- * Usage: `resize <vmname> [--memory=<size>] [--cpu=<count>] [--disk=<size>]`
173
- *
174
- * Tag-scoped API keys may run this command.
175
- */
176
- resize(vmname, options) {
177
- return this.run("resize", [vmname], options, {
178
- cpu: "number",
179
- disk: "string",
180
- memory: "string",
181
- });
182
- }
183
- /**
184
- * Set or clear a short comment on a VM
185
- *
186
- * Usage: `comment <hostname> <text>`
187
- *
188
- * CLI examples:
189
- * ```
190
- * comment my-vm staging copy
191
- * comment my-vm "" # clear the comment
192
- * ```
193
- *
194
- * Tag-scoped API keys may run this command.
195
- */
196
- comment(hostname, text, options) {
197
- return this.run("comment", [hostname, text], options, {});
198
- }
199
- /**
200
- * Link a custom domain to a VM
201
- *
202
- * Usage: `domain add [--wildcard] <vm> <domain>`
203
- */
204
- domainAdd(vm, domain, options) {
205
- return this.run("domain add", [vm, domain], options, {
206
- wildcard: "bool",
207
- });
208
- }
209
- /**
210
- * Remove a custom domain from a VM
211
- *
212
- * Usage: `domain rm <vm> <domain>`
213
- */
214
- domainRm(vm, domain, options) {
215
- return this.run("domain rm", [vm, domain], options, {});
76
+ }, true);
77
+ const vm = new VM(this.#transport, vmInfo(result, "new"));
78
+ if (ready)
79
+ await vm.waitUntilReady(ready);
80
+ return vm;
216
81
  }
217
82
  /**
218
83
  * List custom domains for a VM (or -a for all your VMs)
219
84
  *
220
85
  * Usage: `domain ls <vm> | domain ls -a`
221
86
  */
222
- domainLs(args, options) {
223
- return this.run("domain ls", [args], options, {
87
+ async domainLs(args, options) {
88
+ const result = await this.#transport.call("domain ls", [args], options, {
224
89
  a: "bool",
225
- });
226
- }
227
- /**
228
- * Show current shares for a VM
229
- *
230
- * Usage: `share show <vm>`
231
- *
232
- * Tag-scoped API keys may run this command.
233
- */
234
- shareShow(vm, options) {
235
- return this.run("share show", [vm], options, {
236
- qr: "bool",
237
- });
238
- }
239
- /**
240
- * Set the HTTP proxy port for a VM
241
- *
242
- * Usage: `share port <vm> [port]`
243
- *
244
- * CLI examples:
245
- * ```
246
- * share port mybox 8080
247
- * ```
248
- *
249
- * Tag-scoped API keys may run this command.
250
- */
251
- sharePort(vm, port, options) {
252
- return this.run("share port", [vm, port], options, {});
253
- }
254
- /**
255
- * Make the HTTP proxy publicly accessible
256
- *
257
- * Usage: `share set-public <vm>`
258
- *
259
- * Tag-scoped API keys may run this command.
260
- */
261
- shareSetPublic(vm, options) {
262
- return this.run("share set-public", [vm], options, {});
263
- }
264
- /**
265
- * Restrict the HTTP proxy to authenticated users
266
- *
267
- * Usage: `share set-private <vm>`
268
- *
269
- * Tag-scoped API keys may run this command.
270
- */
271
- shareSetPrivate(vm, options) {
272
- return this.run("share set-private", [vm], options, {});
273
- }
274
- /**
275
- * Share VM with a user via email, or grant shell access with --root
276
- *
277
- * Usage: `share add <vm> <email|team> [--root] [--message='...']`
278
- *
279
- * CLI examples:
280
- * ```
281
- * share add mybox user@example.com
282
- * share add mybox user@example.com --message='Check this out'
283
- * share add mybox team
284
- * share add mybox teammate@example.com --root
285
- * share add mybox team --root
286
- * ```
287
- *
288
- * Tag-scoped API keys may run this command.
289
- */
290
- shareAdd(vm, emailOrTeam, options) {
291
- return this.run("share add", [vm, emailOrTeam], options, {
292
- message: "string",
293
- qr: "bool",
294
- root: "bool",
295
- });
296
- }
297
- /**
298
- * Revoke a user's access to a VM, or downgrade shell access to web with --root
299
- *
300
- * Usage: `share remove <vm> <email|team> [--root]`
301
- *
302
- * CLI examples:
303
- * ```
304
- * share remove mybox user@example.com
305
- * share remove mybox team
306
- * share remove mybox teammate@example.com --root
307
- * share remove mybox team --root
308
- * ```
309
- *
310
- * Tag-scoped API keys may run this command.
311
- */
312
- shareRemove(vm, emailOrTeam, options) {
313
- return this.run("share remove", [vm, emailOrTeam], options, {
314
- root: "bool",
315
- });
316
- }
317
- /**
318
- * Create a shareable link for a VM
319
- *
320
- * Usage: `share add-link <vm>`
321
- *
322
- * Tag-scoped API keys may run this command.
323
- */
324
- shareAddLink(vm, options) {
325
- return this.run("share add-link", [vm], options, {
326
- qr: "bool",
327
- });
328
- }
329
- /**
330
- * Revoke a shareable link
331
- *
332
- * Usage: `share remove-link <vm> <token>`
333
- *
334
- * Tag-scoped API keys may run this command.
335
- */
336
- shareRemoveLink(vm, token, options) {
337
- return this.run("share remove-link", [vm, token], options, {});
338
- }
339
- /**
340
- * Enable or disable inbound email for a VM
341
- *
342
- * Usage: `share receive-email <vm> [on|off] [--reply-policy=all|known|owner|none]`
343
- *
344
- * CLI examples:
345
- * ```
346
- * share receive-email mybox on
347
- * share receive-email mybox off
348
- * share receive-email mybox --reply-policy=known
349
- * share receive-email mybox
350
- * ```
351
- *
352
- * Tag-scoped API keys may run this command.
353
- */
354
- shareReceiveEmail(vm, onOrOff, options) {
355
- return this.run("share receive-email", [vm, onOrOff], options, {
356
- "reply-policy": "string",
357
- });
90
+ }, false);
91
+ return result;
358
92
  }
359
93
  /**
360
94
  * Show user information (email, keys, etc)
@@ -363,8 +97,9 @@ export class Commands {
363
97
  *
364
98
  * Tag-scoped API keys may run this command.
365
99
  */
366
- whoami(options) {
367
- return this.run("whoami", [], options, {});
100
+ async whoami(options) {
101
+ const result = await this.#transport.call("whoami", [], options, {}, true);
102
+ return result;
368
103
  }
369
104
  /**
370
105
  * List all SSH keys associated with your account
@@ -373,8 +108,9 @@ export class Commands {
373
108
  *
374
109
  * Tag-scoped API keys may run this command.
375
110
  */
376
- sshKeyList(options) {
377
- return this.run("ssh-key list", [], options, {});
111
+ async sshKeyList(options) {
112
+ const result = await this.#transport.call("ssh-key list", [], options, {}, false);
113
+ return result;
378
114
  }
379
115
  /**
380
116
  * Add a new SSH key to your account
@@ -399,10 +135,11 @@ export class Commands {
399
135
  *
400
136
  * Tag-scoped API keys may run this command.
401
137
  */
402
- sshKeyAdd(publicKey, options) {
403
- return this.run("ssh-key add", [publicKey], options, {
138
+ async sshKeyAdd(publicKey, options) {
139
+ const result = await this.#transport.call("ssh-key add", [publicKey], options, {
404
140
  tag: "string",
405
- });
141
+ }, false);
142
+ return result;
406
143
  }
407
144
  /**
408
145
  * Remove an SSH key from your account
@@ -411,8 +148,9 @@ export class Commands {
411
148
  *
412
149
  * Tag-scoped API keys may run this command.
413
150
  */
414
- sshKeyRemove(nameOrFingerprintOrPublicKey, options) {
415
- return this.run("ssh-key remove", [nameOrFingerprintOrPublicKey], options, {});
151
+ async sshKeyRemove(nameOrFingerprintOrPublicKey, options) {
152
+ const result = await this.#transport.call("ssh-key remove", [nameOrFingerprintOrPublicKey], options, {}, false);
153
+ return result;
416
154
  }
417
155
  /**
418
156
  * Rename an SSH key
@@ -421,8 +159,9 @@ export class Commands {
421
159
  *
422
160
  * Tag-scoped API keys may run this command.
423
161
  */
424
- sshKeyRename(oldName, newName, options) {
425
- return this.run("ssh-key rename", [oldName, newName], options, {});
162
+ async sshKeyRename(oldName, newName, options) {
163
+ const result = await this.#transport.call("ssh-key rename", [oldName, newName], options, {}, false);
164
+ return result;
426
165
  }
427
166
  /**
428
167
  * Generate an API key for the exe.dev HTTPS API or for a specific VM
@@ -440,21 +179,23 @@ export class Commands {
440
179
  *
441
180
  * Tag-scoped API keys may run this command.
442
181
  */
443
- sshKeyGenerateApiKey(options) {
444
- return this.run("ssh-key generate-api-key", [], options, {
182
+ async sshKeyGenerateApiKey(options) {
183
+ const result = await this.#transport.call("ssh-key generate-api-key", [], options, {
445
184
  cmds: "string",
446
185
  exp: "string",
447
186
  label: "string",
448
187
  vm: "string",
449
- });
188
+ }, false);
189
+ return result;
450
190
  }
451
191
  /**
452
192
  * Set your preferred region for new VMs.
453
193
  *
454
194
  * Usage: `set-region <region-code>`
455
195
  */
456
- setRegion(regionCode, options) {
457
- return this.run("set-region", [regionCode], options, {});
196
+ async setRegion(regionCode, options) {
197
+ const result = await this.#transport.call("set-region", [regionCode], options, {}, false);
198
+ return result;
458
199
  }
459
200
  /**
460
201
  * List your integrations
@@ -463,37 +204,40 @@ export class Commands {
463
204
  *
464
205
  * Tag-scoped API keys may run this command.
465
206
  */
466
- integrationsList(options) {
467
- return this.run("integrations list", [], options, {
207
+ async integrationsList(options) {
208
+ const result = await this.#transport.call("integrations list", [], options, {
468
209
  usage: "bool",
469
- });
210
+ }, false);
211
+ return result;
470
212
  }
471
213
  /**
472
214
  * Set up GitHub integration
473
215
  *
474
216
  * Usage: `integrations setup github [--list|--verify|-d]`
475
217
  */
476
- integrationsSetupGithub(options) {
477
- return this.run("integrations setup github", [], options, {
218
+ async integrationsSetupGithub(options) {
219
+ const result = await this.#transport.call("integrations setup github", [], options, {
478
220
  d: "bool",
479
221
  delete: "bool",
480
222
  list: "bool",
481
223
  verify: "bool",
482
- });
224
+ }, false);
225
+ return result;
483
226
  }
484
227
  /**
485
228
  * Set up ChatGPT account access for LLM integrations
486
229
  *
487
230
  * Usage: `integrations setup chatgpt [--name=<account-name>|--list|--verify|-d]`
488
231
  */
489
- integrationsSetupChatgpt(options) {
490
- return this.run("integrations setup chatgpt", [], options, {
232
+ async integrationsSetupChatgpt(options) {
233
+ const result = await this.#transport.call("integrations setup chatgpt", [], options, {
491
234
  d: "bool",
492
235
  delete: "bool",
493
236
  list: "bool",
494
237
  name: "string",
495
238
  verify: "bool",
496
- });
239
+ }, false);
240
+ return result;
497
241
  }
498
242
  /**
499
243
  * Add a new integration
@@ -502,8 +246,8 @@ export class Commands {
502
246
  *
503
247
  * Usage: `integrations add <type> [--default | --name=<name> [--team] [args...]]`
504
248
  */
505
- integrationsAdd(type, options) {
506
- return this.run("integrations add", [type], options, {
249
+ async integrationsAdd(type, options) {
250
+ const result = await this.#transport.call("integrations add", [type], options, {
507
251
  "act-as-user": "bool",
508
252
  attach: "repeated",
509
253
  bearer: "string",
@@ -521,27 +265,30 @@ export class Commands {
521
265
  "strip-prefix": "string",
522
266
  target: "string",
523
267
  team: "bool",
524
- });
268
+ }, false);
269
+ return result;
525
270
  }
526
271
  /**
527
272
  * Remove an integration
528
273
  *
529
274
  * Usage: `integrations remove <name> [--team]`
530
275
  */
531
- integrationsRemove(name, options) {
532
- return this.run("integrations remove", [name], options, {
276
+ async integrationsRemove(name, options) {
277
+ const result = await this.#transport.call("integrations remove", [name], options, {
533
278
  team: "bool",
534
- });
279
+ }, false);
280
+ return result;
535
281
  }
536
282
  /**
537
283
  * Test an integration's credential (connection check)
538
284
  *
539
285
  * Usage: `integrations test <name> [--team]`
540
286
  */
541
- integrationsTest(name, options) {
542
- return this.run("integrations test", [name], options, {
287
+ async integrationsTest(name, options) {
288
+ const result = await this.#transport.call("integrations test", [name], options, {
543
289
  team: "bool",
544
- });
290
+ }, false);
291
+ return result;
545
292
  }
546
293
  /**
547
294
  * Edit an integration
@@ -550,8 +297,8 @@ export class Commands {
550
297
  *
551
298
  * Usage: `integrations edit <name> [--team] [args...]`
552
299
  */
553
- integrationsEdit(name, args, options) {
554
- return this.run("integrations edit", [name, args], options, {
300
+ async integrationsEdit(name, args, options) {
301
+ const result = await this.#transport.call("integrations edit", [name, args], options, {
555
302
  "act-as-user": "bool",
556
303
  bearer: "string",
557
304
  "clear-header": "bool",
@@ -566,7 +313,8 @@ export class Commands {
566
313
  target: "string",
567
314
  team: "bool",
568
315
  "webhook-url": "string",
569
- });
316
+ }, false);
317
+ return result;
570
318
  }
571
319
  /**
572
320
  * Attach an integration to a VM, tag, or all VMs
@@ -594,32 +342,35 @@ export class Commands {
594
342
  * int attach gmail vm:dev1 --for 2h
595
343
  * ```
596
344
  */
597
- integrationsAttach(name, spec, options) {
598
- return this.run("integrations attach", [name, spec], options, {
345
+ async integrationsAttach(name, spec, options) {
346
+ const result = await this.#transport.call("integrations attach", [name, spec], options, {
599
347
  for: "string",
600
348
  team: "bool",
601
349
  until: "string",
602
- });
350
+ }, false);
351
+ return result;
603
352
  }
604
353
  /**
605
354
  * Detach an integration from a VM, tag, or all VMs
606
355
  *
607
356
  * Usage: `integrations detach <name> <spec> [--team]`
608
357
  */
609
- integrationsDetach(name, spec, options) {
610
- return this.run("integrations detach", [name, spec], options, {
358
+ async integrationsDetach(name, spec, options) {
359
+ const result = await this.#transport.call("integrations detach", [name, spec], options, {
611
360
  team: "bool",
612
- });
361
+ }, false);
362
+ return result;
613
363
  }
614
364
  /**
615
365
  * Rename an integration
616
366
  *
617
367
  * Usage: `integrations rename <name> <new-name> [--team]`
618
368
  */
619
- integrationsRename(name, newName, options) {
620
- return this.run("integrations rename", [name, newName], options, {
369
+ async integrationsRename(name, newName, options) {
370
+ const result = await this.#transport.call("integrations rename", [name, newName], options, {
621
371
  team: "bool",
622
- });
372
+ }, false);
373
+ return result;
623
374
  }
624
375
  /**
625
376
  * Browse the catalog of ready-made service integrations
@@ -632,74 +383,83 @@ export class Commands {
632
383
  * int catalog stripe
633
384
  * ```
634
385
  */
635
- integrationsCatalog(serviceOrSearchTerm, options) {
636
- return this.run("integrations catalog", [serviceOrSearchTerm], options, {});
386
+ async integrationsCatalog(serviceOrSearchTerm, options) {
387
+ const result = await this.#transport.call("integrations catalog", [serviceOrSearchTerm], options, {}, false);
388
+ return result;
637
389
  }
638
390
  /**
639
391
  * View and manage your team
640
392
  */
641
- team(options) {
642
- return this.run("team", [], options, {});
393
+ async team(options) {
394
+ const result = await this.#transport.call("team", [], options, {}, false);
395
+ return result;
643
396
  }
644
397
  /**
645
398
  * Disband your team
646
399
  *
647
400
  * Usage: `team disable`
648
401
  */
649
- teamDisable(options) {
650
- return this.run("team disable", [], options, {
402
+ async teamDisable(options) {
403
+ const result = await this.#transport.call("team disable", [], options, {
651
404
  yes: "bool",
652
- });
405
+ }, false);
406
+ return result;
653
407
  }
654
408
  /**
655
409
  * List team members
656
410
  *
657
411
  * Usage: `team members`
658
412
  */
659
- teamMembers(options) {
660
- return this.run("team members", [], options, {});
413
+ async teamMembers(options) {
414
+ const result = await this.#transport.call("team members", [], options, {}, false);
415
+ return result;
661
416
  }
662
417
  /**
663
418
  * Show team pool, disk, and bandwidth usage for the billing period
664
419
  *
665
420
  * Usage: `team usage`
666
421
  */
667
- teamUsage(options) {
668
- return this.run("team usage", [], options, {});
422
+ async teamUsage(options) {
423
+ const result = await this.#transport.call("team usage", [], options, {}, false);
424
+ return result;
669
425
  }
670
426
  /**
671
427
  * Add a user to the team
672
428
  *
673
429
  * Usage: `team add <email> [<user|admin|billing_owner>]`
674
430
  */
675
- teamAdd(email, userOrAdminOrBillingOwner, options) {
676
- return this.run("team add", [email, userOrAdminOrBillingOwner], options, {});
431
+ async teamAdd(email, userOrAdminOrBillingOwner, options) {
432
+ const result = await this.#transport.call("team add", [email, userOrAdminOrBillingOwner], options, {}, false);
433
+ return result;
677
434
  }
678
435
  /**
679
436
  * Remove a user from the team
680
437
  *
681
438
  * Usage: `team remove <email> [--transfer-vms-to <email>]`
682
439
  */
683
- teamRemove(email, options) {
684
- return this.run("team remove", [email], options, {
440
+ async teamRemove(email, options) {
441
+ const result = await this.#transport.call("team remove", [email], options, {
685
442
  "transfer-vms-to": "string",
686
- });
443
+ }, false);
444
+ return result;
687
445
  }
688
446
  /**
689
447
  * Change a team member's role
690
448
  *
691
449
  * Usage: `team role <email> <user|admin|billing_owner>`
692
450
  */
693
- teamRole(email, userOrAdminOrBillingOwner, options) {
694
- return this.run("team role", [email, userOrAdminOrBillingOwner], options, {});
451
+ async teamRole(email, userOrAdminOrBillingOwner, options) {
452
+ const result = await this.#transport.call("team role", [email, userOrAdminOrBillingOwner], options, {}, false);
453
+ return result;
695
454
  }
696
455
  /**
697
456
  * Rename your team
698
457
  *
699
458
  * Usage: `team rename <name>`
700
459
  */
701
- teamRename(name, options) {
702
- return this.run("team rename", [name], options, {});
460
+ async teamRename(name, options) {
461
+ const result = await this.#transport.call("team rename", [name], options, {}, false);
462
+ return result;
703
463
  }
704
464
  /**
705
465
  * Show your team's plan
@@ -712,18 +472,19 @@ export class Commands {
712
472
  * team billing plan --all # plans your team can switch to
713
473
  * ```
714
474
  */
715
- teamBillingPlan(options) {
716
- return this.run("team billing plan", [], options, {
475
+ async teamBillingPlan(options) {
476
+ const result = await this.#transport.call("team billing plan", [], options, {
717
477
  all: "bool",
718
- });
478
+ }, false);
479
+ return result;
719
480
  }
720
481
  /**
721
482
  * Update team billing information
722
483
  *
723
484
  * Usage: `team billing update [--email=<email>] [--name=<name>] [--business-name=<name>] [--phone=<phone>] [--address-line1=<line>] [--address-line2=<line>] [--address-city=<city>] [--address-state=<state>] [--address-postal-code=<code>] [--address-country=<country>] [--tax-id-type=<type>] [--tax-id-value=<value>]`
724
485
  */
725
- teamBillingUpdate(options) {
726
- return this.run("team billing update", [], options, {
486
+ async teamBillingUpdate(options) {
487
+ const result = await this.#transport.call("team billing update", [], options, {
727
488
  "address-city": "string",
728
489
  "address-country": "string",
729
490
  "address-line1": "string",
@@ -736,127 +497,142 @@ export class Commands {
736
497
  phone: "string",
737
498
  "tax-id-type": "string",
738
499
  "tax-id-value": "string",
739
- });
500
+ }, false);
501
+ return result;
740
502
  }
741
503
  /**
742
504
  * Transfer a VM to another team member
743
505
  *
744
506
  * Usage: `team transfer <vm_name> <target_email>`
745
507
  */
746
- teamTransfer(vmName, targetEmail, options) {
747
- return this.run("team transfer", [vmName, targetEmail], options, {});
508
+ async teamTransfer(vmName, targetEmail, options) {
509
+ const result = await this.#transport.call("team transfer", [vmName, targetEmail], options, {}, false);
510
+ return result;
748
511
  }
749
512
  /**
750
513
  * View and manage team auth settings
751
514
  *
752
515
  * Usage: `team auth`
753
516
  */
754
- teamAuth(options) {
755
- return this.run("team auth", [], options, {});
517
+ async teamAuth(options) {
518
+ const result = await this.#transport.call("team auth", [], options, {}, false);
519
+ return result;
756
520
  }
757
521
  /**
758
522
  * Require OIDC for web login (web|off)
759
523
  *
760
524
  * Usage: `team auth require-oidc <web|off>`
761
525
  */
762
- teamAuthRequireOidc(webOrOff, options) {
763
- return this.run("team auth require-oidc", [webOrOff], options, {});
526
+ async teamAuthRequireOidc(webOrOff, options) {
527
+ const result = await this.#transport.call("team auth require-oidc", [webOrOff], options, {}, false);
528
+ return result;
764
529
  }
765
530
  /**
766
531
  * Set the team auth provider (default, google, oidc)
767
532
  *
768
533
  * Usage: `team auth set <default|google|oidc> [--issuer-url=<url> --client-id=<id> --client-secret=<secret>]`
769
534
  */
770
- teamAuthSet(defaultOrGoogleOrOidc, options) {
771
- return this.run("team auth set", [defaultOrGoogleOrOidc], options, {
535
+ async teamAuthSet(defaultOrGoogleOrOidc, options) {
536
+ const result = await this.#transport.call("team auth set", [defaultOrGoogleOrOidc], options, {
772
537
  "client-id": "string",
773
538
  "client-secret": "string",
774
539
  "display-name": "string",
775
540
  "issuer-url": "string",
776
- });
541
+ }, false);
542
+ return result;
777
543
  }
778
544
  /**
779
545
  * View and manage team settings
780
546
  *
781
547
  * Usage: `team settings`
782
548
  */
783
- teamSettings(options) {
784
- return this.run("team settings", [], options, {});
549
+ async teamSettings(options) {
550
+ const result = await this.#transport.call("team settings", [], options, {}, false);
551
+ return result;
785
552
  }
786
553
  /**
787
554
  * View and manage automatic VM placement
788
555
  *
789
556
  * Usage: `team settings vm-placement`
790
557
  */
791
- teamSettingsVmPlacement(options) {
792
- return this.run("team settings vm-placement", [], options, {});
558
+ async teamSettingsVmPlacement(options) {
559
+ const result = await this.#transport.call("team settings vm-placement", [], options, {}, false);
560
+ return result;
793
561
  }
794
562
  /**
795
563
  * Use ordinary VM placement
796
564
  *
797
565
  * Usage: `team settings vm-placement default`
798
566
  */
799
- teamSettingsVmPlacementDefault(options) {
800
- return this.run("team settings vm-placement default", [], options, {});
567
+ async teamSettingsVmPlacementDefault(options) {
568
+ const result = await this.#transport.call("team settings vm-placement default", [], options, {}, false);
569
+ return result;
801
570
  }
802
571
  /**
803
572
  * Send bare new commands to a shared team pool
804
573
  *
805
574
  * Usage: `team settings vm-placement pool <name>`
806
575
  */
807
- teamSettingsVmPlacementPool(name, options) {
808
- return this.run("team settings vm-placement pool", [name], options, {});
576
+ async teamSettingsVmPlacementPool(name, options) {
577
+ const result = await this.#transport.call("team settings vm-placement pool", [name], options, {}, false);
578
+ return result;
809
579
  }
810
580
  /**
811
581
  * Create or reuse one team pool per member for bare new commands
812
582
  *
813
583
  * Usage: `team settings vm-placement member-pool --cpus=N [--max-vms=N]`
814
584
  */
815
- teamSettingsVmPlacementMemberPool(options) {
816
- return this.run("team settings vm-placement member-pool", [], options, {
585
+ async teamSettingsVmPlacementMemberPool(options) {
586
+ const result = await this.#transport.call("team settings vm-placement member-pool", [], options, {
817
587
  cpus: "number",
818
588
  "max-vms": "number",
819
- });
589
+ }, false);
590
+ return result;
820
591
  }
821
592
  /**
822
593
  * Keep bare new commands outside pools while migrating (legacy)
823
594
  *
824
595
  * Usage: `team settings vm-placement poolless`
825
596
  */
826
- teamSettingsVmPlacementPoolless(options) {
827
- return this.run("team settings vm-placement poolless", [], options, {});
597
+ async teamSettingsVmPlacementPoolless(options) {
598
+ const result = await this.#transport.call("team settings vm-placement poolless", [], options, {}, false);
599
+ return result;
828
600
  }
829
601
  /**
830
602
  * Set who can create standalone VMs
831
603
  *
832
604
  * Usage: `team settings standalone <off|admins-only|all-users>`
833
605
  */
834
- teamSettingsStandalone(offOrAdminsOnlyOrAllUsers, options) {
835
- return this.run("team settings standalone", [offOrAdminsOnlyOrAllUsers], options, {});
606
+ async teamSettingsStandalone(offOrAdminsOnlyOrAllUsers, options) {
607
+ const result = await this.#transport.call("team settings standalone", [offOrAdminsOnlyOrAllUsers], options, {}, false);
608
+ return result;
836
609
  }
837
610
  /**
838
611
  * Allow or block the exe.dev LLM gateway (your own API keys are unaffected)
839
612
  *
840
613
  * Usage: `team settings llm-gateway <on|off>`
841
614
  */
842
- teamSettingsLlmGateway(onOrOff, options) {
843
- return this.run("team settings llm-gateway", [onOrOff], options, {});
615
+ async teamSettingsLlmGateway(onOrOff, options) {
616
+ const result = await this.#transport.call("team settings llm-gateway", [onOrOff], options, {}, false);
617
+ return result;
844
618
  }
845
619
  /**
846
620
  * Allow team VMs to share CPU cores with each other
847
621
  *
848
622
  * Usage: `team settings core-sharing <on|off>`
849
623
  */
850
- teamSettingsCoreSharing(onOrOff, options) {
851
- return this.run("team settings core-sharing", [onOrOff], options, {});
624
+ async teamSettingsCoreSharing(onOrOff, options) {
625
+ const result = await this.#transport.call("team settings core-sharing", [onOrOff], options, {}, false);
626
+ return result;
852
627
  }
853
628
  /**
854
629
  * Set who can share team VMs
855
630
  *
856
631
  * Usage: `team settings vm-sharing <admins-only|all-members>`
857
632
  */
858
- teamSettingsVmSharing(adminsOnlyOrAllMembers, options) {
859
- return this.run("team settings vm-sharing", [adminsOnlyOrAllMembers], options, {});
633
+ async teamSettingsVmSharing(adminsOnlyOrAllMembers, options) {
634
+ const result = await this.#transport.call("team settings vm-sharing", [adminsOnlyOrAllMembers], options, {}, false);
635
+ return result;
860
636
  }
861
637
  /**
862
638
  * Set how long members stay signed in on the web and mobile apps
@@ -869,16 +645,18 @@ export class Commands {
869
645
  * team settings session-length default
870
646
  * ```
871
647
  */
872
- teamSettingsSessionLength(length, options) {
873
- return this.run("team settings session-length", [length], options, {});
648
+ async teamSettingsSessionLength(length, options) {
649
+ const result = await this.#transport.call("team settings session-length", [length], options, {}, false);
650
+ return result;
874
651
  }
875
652
  /**
876
653
  * Allow users from your email domain to join this team on signup
877
654
  *
878
655
  * Usage: `team settings auto-join <on|off>`
879
656
  */
880
- teamSettingsAutoJoin(onOrOff, options) {
881
- return this.run("team settings auto-join", [onOrOff], options, {});
657
+ async teamSettingsAutoJoin(onOrOff, options) {
658
+ const result = await this.#transport.call("team settings auto-join", [onOrOff], options, {}, false);
659
+ return result;
882
660
  }
883
661
  /**
884
662
  * List all VMs across your team
@@ -887,42 +665,46 @@ export class Commands {
887
665
  *
888
666
  * Tag-scoped API keys may run this command.
889
667
  */
890
- teamVmLs(nameOrPattern, options) {
891
- return this.run("team vm ls", [nameOrPattern], options, {
668
+ async teamVmLs(nameOrPattern, options) {
669
+ const result = await this.#transport.call("team vm ls", [nameOrPattern], options, {
892
670
  group: "string",
893
671
  l: "bool",
894
- });
672
+ }, false);
673
+ return result;
895
674
  }
896
675
  /**
897
676
  * Create a pool: reserved capacity for your team's VMs
898
677
  *
899
678
  * Usage: `pool new <name> --cpus=N [--region=<region>] [--max-vms=M]`
900
679
  */
901
- poolNew(name, options) {
902
- return this.run("pool new", [name], options, {
680
+ async poolNew(name, options) {
681
+ const result = await this.#transport.call("pool new", [name], options, {
903
682
  cpus: "number",
904
683
  "max-vms": "number",
905
684
  region: "string",
906
- });
685
+ }, false);
686
+ return result;
907
687
  }
908
688
  /**
909
689
  * Show your team's dedicated hosts, where its new pools are placed
910
690
  *
911
691
  * Usage: `pool hosts`
912
692
  */
913
- poolHosts(options) {
914
- return this.run("pool hosts", [], options, {});
693
+ async poolHosts(options) {
694
+ const result = await this.#transport.call("pool hosts", [], options, {}, false);
695
+ return result;
915
696
  }
916
697
  /**
917
698
  * List your team's pools, or show live or historical usage with --usage
918
699
  *
919
700
  * Usage: `pool list [pool-name] [--usage [--range=live|24h|7d|30d]]`
920
701
  */
921
- poolList(poolName, options) {
922
- return this.run("pool list", [poolName], options, {
702
+ async poolList(poolName, options) {
703
+ const result = await this.#transport.call("pool list", [poolName], options, {
923
704
  range: "string",
924
705
  usage: "bool",
925
- });
706
+ }, false);
707
+ return result;
926
708
  }
927
709
  /**
928
710
  * Adopt a VM into a pool; this can take several minutes
@@ -934,11 +716,12 @@ export class Commands {
934
716
  * pool adopt --vm=builder --pool=compile
935
717
  * ```
936
718
  */
937
- poolAdopt(options) {
938
- return this.run("pool adopt", [], options, {
719
+ async poolAdopt(options) {
720
+ const result = await this.#transport.call("pool adopt", [], options, {
939
721
  pool: "string",
940
722
  vm: "string",
941
- });
723
+ }, false);
724
+ return result;
942
725
  }
943
726
  /**
944
727
  * Detach a VM from its pool into its own standalone capacity (--poolless leaves it outside any pool)
@@ -951,39 +734,43 @@ export class Commands {
951
734
  * pool detach --vm=builder --poolless
952
735
  * ```
953
736
  */
954
- poolDetach(options) {
955
- return this.run("pool detach", [], options, {
737
+ async poolDetach(options) {
738
+ const result = await this.#transport.call("pool detach", [], options, {
956
739
  poolless: "bool",
957
740
  vm: "string",
958
- });
741
+ }, false);
742
+ return result;
959
743
  }
960
744
  /**
961
745
  * Change a pool's CPU capacity or VM cap
962
746
  *
963
747
  * Usage: `pool resize <name> --cpus=N | pool resize <name> --max-vms=N [--force]`
964
748
  */
965
- poolResize(args, options) {
966
- return this.run("pool resize", [args], options, {
749
+ async poolResize(args, options) {
750
+ const result = await this.#transport.call("pool resize", [args], options, {
967
751
  cpus: "number",
968
752
  force: "bool",
969
753
  "max-vms": "string",
970
- });
754
+ }, false);
755
+ return result;
971
756
  }
972
757
  /**
973
758
  * Rename a pool without changing its capacity or VMs
974
759
  *
975
760
  * Usage: `pool rename <old-name> <new-name>`
976
761
  */
977
- poolRename(oldName, newName, options) {
978
- return this.run("pool rename", [oldName, newName], options, {});
762
+ async poolRename(oldName, newName, options) {
763
+ const result = await this.#transport.call("pool rename", [oldName, newName], options, {}, false);
764
+ return result;
979
765
  }
980
766
  /**
981
767
  * Delete a pool (refused while it has VMs; --force detaches them)
982
768
  *
983
769
  * Usage: `pool delete <name> [--force]`
984
770
  */
985
- poolDelete(name, options) {
986
- return this.run("pool delete", [name], options, {});
771
+ async poolDelete(name, options) {
772
+ const result = await this.#transport.call("pool delete", [name], options, {}, false);
773
+ return result;
987
774
  }
988
775
  /**
989
776
  * Show your current plan and resource limits
@@ -996,10 +783,11 @@ export class Commands {
996
783
  * billing plan --all # plans you can switch to
997
784
  * ```
998
785
  */
999
- billingPlan(options) {
1000
- return this.run("billing plan", [], options, {
786
+ async billingPlan(options) {
787
+ const result = await this.#transport.call("billing plan", [], options, {
1001
788
  all: "bool",
1002
- });
789
+ }, false);
790
+ return result;
1003
791
  }
1004
792
  /**
1005
793
  * Show VM resource usage against your plan quotas
@@ -1012,19 +800,21 @@ export class Commands {
1012
800
  * billing credits usage # Shelley/LLM credit spend instead
1013
801
  * ```
1014
802
  */
1015
- billingUsage(options) {
1016
- return this.run("billing usage", [], options, {
803
+ async billingUsage(options) {
804
+ const result = await this.#transport.call("billing usage", [], options, {
1017
805
  group: "string",
1018
806
  range: "string",
1019
- });
807
+ }, false);
808
+ return result;
1020
809
  }
1021
810
  /**
1022
811
  * Show Shelley credit balances
1023
812
  *
1024
813
  * Usage: `billing credits [usage|transactions|buy]`
1025
814
  */
1026
- billingCredits(options) {
1027
- return this.run("billing credits", [], options, {});
815
+ async billingCredits(options) {
816
+ const result = await this.#transport.call("billing credits", [], options, {}, false);
817
+ return result;
1028
818
  }
1029
819
  /**
1030
820
  * Show Shelley (LLM) credit spend by model, day, or VM
@@ -1038,22 +828,24 @@ export class Commands {
1038
828
  * billing credits usage --month=2026-05 --group=box
1039
829
  * ```
1040
830
  */
1041
- billingCreditsUsage(options) {
1042
- return this.run("billing credits usage", [], options, {
831
+ async billingCreditsUsage(options) {
832
+ const result = await this.#transport.call("billing credits usage", [], options, {
1043
833
  detail: "bool",
1044
834
  group: "string",
1045
835
  month: "string",
1046
- });
836
+ }, false);
837
+ return result;
1047
838
  }
1048
839
  /**
1049
840
  * Show your credit purchases and gifts
1050
841
  *
1051
842
  * Usage: `billing credits transactions [--limit=N]`
1052
843
  */
1053
- billingCreditsTransactions(options) {
1054
- return this.run("billing credits transactions", [], options, {
844
+ async billingCreditsTransactions(options) {
845
+ const result = await this.#transport.call("billing credits transactions", [], options, {
1055
846
  limit: "string",
1056
- });
847
+ }, false);
848
+ return result;
1057
849
  }
1058
850
  /**
1059
851
  * Buy Shelley credits with your personal payment method
@@ -1066,19 +858,21 @@ export class Commands {
1066
858
  * billing credits buy 100 --yes
1067
859
  * ```
1068
860
  */
1069
- billingCreditsBuy(dollars, options) {
1070
- return this.run("billing credits buy", [dollars], options, {
861
+ async billingCreditsBuy(dollars, options) {
862
+ const result = await this.#transport.call("billing credits buy", [dollars], options, {
1071
863
  "idempotency-key": "string",
1072
864
  yes: "bool",
1073
- });
865
+ }, false);
866
+ return result;
1074
867
  }
1075
868
  /**
1076
869
  * Show invite rewards you've earned
1077
870
  *
1078
871
  * Usage: `billing rewards`
1079
872
  */
1080
- billingRewards(options) {
1081
- return this.run("billing rewards", [], options, {});
873
+ async billingRewards(options) {
874
+ const result = await this.#transport.call("billing rewards", [], options, {}, false);
875
+ return result;
1082
876
  }
1083
877
  /**
1084
878
  * Change your subscription capacity
@@ -1091,27 +885,30 @@ export class Commands {
1091
885
  * billing capacity --cpu=4 --yes
1092
886
  * ```
1093
887
  */
1094
- billingCapacity(options) {
1095
- return this.run("billing capacity", [], options, {
888
+ async billingCapacity(options) {
889
+ const result = await this.#transport.call("billing capacity", [], options, {
1096
890
  cpu: "number",
1097
891
  yes: "bool",
1098
- });
892
+ }, false);
893
+ return result;
1099
894
  }
1100
895
  /**
1101
896
  * Show your payment methods
1102
897
  *
1103
898
  * Usage: `billing payment [list]`
1104
899
  */
1105
- billingPayment(options) {
1106
- return this.run("billing payment", [], options, {});
900
+ async billingPayment(options) {
901
+ const result = await this.#transport.call("billing payment", [], options, {}, false);
902
+ return result;
1107
903
  }
1108
904
  /**
1109
905
  * List all payment methods on file
1110
906
  *
1111
907
  * Usage: `billing payment list`
1112
908
  */
1113
- billingPaymentList(options) {
1114
- return this.run("billing payment list", [], options, {});
909
+ async billingPaymentList(options) {
910
+ const result = await this.#transport.call("billing payment list", [], options, {}, false);
911
+ return result;
1115
912
  }
1116
913
  /**
1117
914
  * Remove a saved payment method
@@ -1123,8 +920,9 @@ export class Commands {
1123
920
  * billing payment remove 4f1c2a9b8d3e
1124
921
  * ```
1125
922
  */
1126
- billingPaymentRemove(ref, options) {
1127
- return this.run("billing payment remove", [ref], options, {});
923
+ async billingPaymentRemove(ref, options) {
924
+ const result = await this.#transport.call("billing payment remove", [ref], options, {}, false);
925
+ return result;
1128
926
  }
1129
927
  /**
1130
928
  * Make a saved payment method the default
@@ -1136,32 +934,35 @@ export class Commands {
1136
934
  * billing payment default 4f1c2a9b8d3e
1137
935
  * ```
1138
936
  */
1139
- billingPaymentDefault(ref, options) {
1140
- return this.run("billing payment default", [ref], options, {});
937
+ async billingPaymentDefault(ref, options) {
938
+ const result = await this.#transport.call("billing payment default", [ref], options, {}, false);
939
+ return result;
1141
940
  }
1142
941
  /**
1143
942
  * Open the billing management page
1144
943
  *
1145
944
  * Usage: `billing manage`
1146
945
  */
1147
- billingManage(options) {
1148
- return this.run("billing manage", [], options, {});
946
+ async billingManage(options) {
947
+ const result = await this.#transport.call("billing manage", [], options, {}, false);
948
+ return result;
1149
949
  }
1150
950
  /**
1151
951
  * Open the personal plan activation page
1152
952
  *
1153
953
  * Usage: `billing activate`
1154
954
  */
1155
- billingActivate(options) {
1156
- return this.run("billing activate", [], options, {});
955
+ async billingActivate(options) {
956
+ const result = await this.#transport.call("billing activate", [], options, {}, false);
957
+ return result;
1157
958
  }
1158
959
  /**
1159
960
  * Update your billing contact information
1160
961
  *
1161
962
  * Usage: `billing update [--email=<email>] [--name=<name>] [--business-name=<name>] [--phone=<phone>] [--address-line1=<line>] [--address-line2=<line>] [--address-city=<city>] [--address-state=<state>] [--address-postal-code=<code>] [--address-country=<country>] [--tax-id-type=<type>] [--tax-id-value=<value>]`
1162
963
  */
1163
- billingUpdate(options) {
1164
- return this.run("billing update", [], options, {
964
+ async billingUpdate(options) {
965
+ const result = await this.#transport.call("billing update", [], options, {
1165
966
  "address-city": "string",
1166
967
  "address-country": "string",
1167
968
  "address-line1": "string",
@@ -1174,15 +975,17 @@ export class Commands {
1174
975
  phone: "string",
1175
976
  "tax-id-type": "string",
1176
977
  "tax-id-value": "string",
1177
- });
978
+ }, false);
979
+ return result;
1178
980
  }
1179
981
  /**
1180
982
  * Show recent invoices
1181
983
  *
1182
984
  * Usage: `billing invoices`
1183
985
  */
1184
- billingInvoices(options) {
1185
- return this.run("billing invoices", [], options, {});
986
+ async billingInvoices(options) {
987
+ const result = await this.#transport.call("billing invoices", [], options, {}, false);
988
+ return result;
1186
989
  }
1187
990
  /**
1188
991
  * List invoices for your personal or team account
@@ -1194,10 +997,11 @@ export class Commands {
1194
997
  * billing invoices list --account=team
1195
998
  * ```
1196
999
  */
1197
- billingInvoicesList(options) {
1198
- return this.run("billing invoices list", [], options, {
1000
+ async billingInvoicesList(options) {
1001
+ const result = await this.#transport.call("billing invoices list", [], options, {
1199
1002
  account: "string",
1200
- });
1003
+ }, false);
1004
+ return result;
1201
1005
  }
1202
1006
  /**
1203
1007
  * Show one invoice with its usage breakdown
@@ -1209,10 +1013,11 @@ export class Commands {
1209
1013
  * billing invoices show in_1Abc --vms
1210
1014
  * ```
1211
1015
  */
1212
- billingInvoicesShow(id, options) {
1213
- return this.run("billing invoices show", [id], options, {
1016
+ async billingInvoicesShow(id, options) {
1017
+ const result = await this.#transport.call("billing invoices show", [id], options, {
1214
1018
  vms: "bool",
1215
- });
1019
+ }, false);
1020
+ return result;
1216
1021
  }
1217
1022
  /**
1218
1023
  * Show credit purchase receipts and purchases (this billing account only)
@@ -1224,11 +1029,12 @@ export class Commands {
1224
1029
  * billing receipts --from=2026-01-01 --to=2026-06-30
1225
1030
  * ```
1226
1031
  */
1227
- billingReceipts(options) {
1228
- return this.run("billing receipts", [], options, {
1032
+ async billingReceipts(options) {
1033
+ const result = await this.#transport.call("billing receipts", [], options, {
1229
1034
  from: "string",
1230
1035
  to: "string",
1231
- });
1036
+ }, false);
1037
+ return result;
1232
1038
  }
1233
1039
  /**
1234
1040
  * Open a consolidated credit purchase statement
@@ -1240,105 +1046,507 @@ export class Commands {
1240
1046
  * billing statement --from=2026-01-01 --to=2026-06-30
1241
1047
  * ```
1242
1048
  */
1243
- billingStatement(options) {
1244
- return this.run("billing statement", [], options, {
1049
+ async billingStatement(options) {
1050
+ const result = await this.#transport.call("billing statement", [], options, {
1245
1051
  from: "string",
1246
1052
  to: "string",
1247
- });
1053
+ }, false);
1054
+ return result;
1248
1055
  }
1249
1056
  /**
1250
1057
  * Connect a marketplace subscription to your team
1251
1058
  *
1252
1059
  * Usage: `billing provider link <aws|azure> --token=<link-token> [--size=<team-size>] [--team-name=<name>]`
1253
1060
  */
1254
- billingProviderLink(awsOrAzure, options) {
1255
- return this.run("billing provider link", [awsOrAzure], options, {
1061
+ async billingProviderLink(awsOrAzure, options) {
1062
+ const result = await this.#transport.call("billing provider link", [awsOrAzure], options, {
1256
1063
  size: "string",
1257
1064
  "team-name": "string",
1258
1065
  token: "string",
1259
- });
1066
+ }, false);
1067
+ return result;
1260
1068
  }
1261
1069
  /**
1262
1070
  * Manage your invite link and rewards
1263
1071
  */
1264
- invite(options) {
1265
- return this.run("invite", [], options, {});
1072
+ async invite(options) {
1073
+ const result = await this.#transport.call("invite", [], options, {}, false);
1074
+ return result;
1266
1075
  }
1267
1076
  /**
1268
1077
  * Show your active invite link and reward
1269
1078
  *
1270
1079
  * Usage: `invite show`
1271
1080
  */
1272
- inviteShow(options) {
1273
- return this.run("invite show", [], options, {});
1081
+ async inviteShow(options) {
1082
+ const result = await this.#transport.call("invite show", [], options, {}, false);
1083
+ return result;
1274
1084
  }
1275
1085
  /**
1276
1086
  * Print only your active invite link
1277
1087
  *
1278
1088
  * Usage: `invite link`
1279
1089
  */
1280
- inviteLink(options) {
1281
- return this.run("invite link", [], options, {});
1090
+ async inviteLink(options) {
1091
+ const result = await this.#transport.call("invite link", [], options, {}, false);
1092
+ return result;
1282
1093
  }
1283
1094
  /**
1284
1095
  * List invite rewards you can use
1285
1096
  *
1286
1097
  * Usage: `invite rewards`
1287
1098
  */
1288
- inviteRewards(options) {
1289
- return this.run("invite rewards", [], options, {});
1099
+ async inviteRewards(options) {
1100
+ const result = await this.#transport.call("invite rewards", [], options, {}, false);
1101
+ return result;
1290
1102
  }
1291
1103
  /**
1292
1104
  * Choose the reward for your invite link
1293
1105
  *
1294
1106
  * Usage: `invite set-reward standard|bonus-credits|extra-memory|extra-disk`
1295
1107
  */
1296
- inviteSetReward(standardOrBonusCreditsOrExtraMemoryOrExtraDisk, options) {
1297
- return this.run("invite set-reward", [standardOrBonusCreditsOrExtraMemoryOrExtraDisk], options, {});
1108
+ async inviteSetReward(standardOrBonusCreditsOrExtraMemoryOrExtraDisk, options) {
1109
+ const result = await this.#transport.call("invite set-reward", [standardOrBonusCreditsOrExtraMemoryOrExtraDisk], options, {}, false);
1110
+ return result;
1298
1111
  }
1299
1112
  /**
1300
1113
  * Show signups, upgrades, and reward status
1301
1114
  *
1302
1115
  * Usage: `invite activity`
1303
1116
  */
1304
- inviteActivity(options) {
1305
- return this.run("invite activity", [], options, {});
1117
+ async inviteActivity(options) {
1118
+ const result = await this.#transport.call("invite activity", [], options, {}, false);
1119
+ return result;
1306
1120
  }
1307
1121
  /**
1308
1122
  * Request more trial invites
1309
1123
  *
1310
1124
  * Usage: `invite request`
1311
1125
  */
1312
- inviteRequest(options) {
1313
- return this.run("invite request", [], options, {});
1126
+ async inviteRequest(options) {
1127
+ const result = await this.#transport.call("invite request", [], options, {}, false);
1128
+ return result;
1314
1129
  }
1315
1130
  /**
1316
1131
  * Open the invites page
1317
1132
  *
1318
1133
  * Usage: `invite manage`
1319
1134
  */
1320
- inviteManage(options) {
1321
- return this.run("invite manage", [], options, {});
1135
+ async inviteManage(options) {
1136
+ const result = await this.#transport.call("invite manage", [], options, {}, false);
1137
+ return result;
1322
1138
  }
1323
1139
  /**
1324
- * Install or upgrade Shelley to the current version
1140
+ * Generate a magic link to log in to the website
1325
1141
  *
1326
- * Usage: `shelley install <vm>`
1142
+ * Usage: `browser`
1143
+ */
1144
+ async browser(options) {
1145
+ const result = await this.#transport.call("browser", [], options, {
1146
+ qr: "bool",
1147
+ }, false);
1148
+ return result;
1149
+ }
1150
+ }
1151
+ /** A VM reference. info is a snapshot; refresh() fetches current metadata. */
1152
+ export class VM {
1153
+ #transport;
1154
+ #info;
1155
+ /** @internal Obtain VMs through exe.new(), exe.ls(), exe.vm(), or vm.cp(). */
1156
+ constructor(transport, info) {
1157
+ this.#transport = transport;
1158
+ this.#info = Object.freeze({ ...info, tags: Object.freeze([...info.tags]) });
1159
+ }
1160
+ get info() { return this.#info; }
1161
+ get name() { return this.#info.name; }
1162
+ get httpsUrl() { return this.#info.httpsUrl; }
1163
+ get sshDest() { return this.#info.sshDest; }
1164
+ get tags() { return this.#info.tags; }
1165
+ /** Run a shell command once. Nonzero exit codes are results, not exceptions. */
1166
+ ssh(command, options) {
1167
+ return this.#transport.ssh(this.name, command, options);
1168
+ }
1169
+ /** Refresh metadata without changing this reference's identity. Requires ls permission. */
1170
+ async refresh(options) {
1171
+ const result = await this.#transport.call("ls", [this.name], options, {}, true);
1172
+ const vm = listVMs(this.#transport, result).find((vm) => vm.name === this.name);
1173
+ if (!vm)
1174
+ throw new ExeAPIError("ls", 404, "VM not found");
1175
+ this.#info = vm.info;
1176
+ return this;
1177
+ }
1178
+ /**
1179
+ * Probe SSH with `true` until it exits successfully. Never reruns a user command.
1180
+ * The default deadline is 60 seconds, including requests and backoff. This does
1181
+ * not wait for application servers or setup scripts. Requires ssh permission.
1182
+ */
1183
+ async waitUntilReady(options = {}) {
1184
+ const timeoutMs = readyTimeout(options.timeoutMs);
1185
+ options.signal?.throwIfAborted();
1186
+ const controller = new AbortController();
1187
+ const abort = () => controller.abort(options.signal.reason);
1188
+ options.signal?.addEventListener("abort", abort, { once: true });
1189
+ const timer = setTimeout(() => controller.abort(new DOMException("SSH readiness timed out", "TimeoutError")), timeoutMs);
1190
+ let backoff = 100;
1191
+ try {
1192
+ while (true) {
1193
+ try {
1194
+ const result = await abortable(this.ssh("true", { signal: controller.signal, capture: false }), controller.signal);
1195
+ controller.signal.throwIfAborted();
1196
+ if (result.exitCode !== 0)
1197
+ throw new ExeProtocolError("ssh readiness probe");
1198
+ return this;
1199
+ }
1200
+ catch (err) {
1201
+ controller.signal.throwIfAborted();
1202
+ // /exec reports these failures before a remote command starts. Other
1203
+ // rejections (not found, permissions, no SSH configured) fail fast.
1204
+ if (!(err instanceof ExeAPIError) || err.status !== 422 ||
1205
+ !/failed to (?:connect|dial|create session|run command on VM)/i.test(err.details().body))
1206
+ throw err;
1207
+ }
1208
+ await delay(backoff, controller.signal);
1209
+ backoff = Math.min(backoff * 2, 1000);
1210
+ }
1211
+ }
1212
+ catch (err) {
1213
+ options.signal?.throwIfAborted();
1214
+ throw new VMReadyError(this, err);
1215
+ }
1216
+ finally {
1217
+ clearTimeout(timer);
1218
+ options.signal?.removeEventListener("abort", abort);
1219
+ }
1220
+ }
1221
+ /**
1222
+ * Delete a VM
1223
+ *
1224
+ * Usage: `rm <vmname>...`
1327
1225
  *
1328
1226
  * Tag-scoped API keys may run this command.
1329
1227
  */
1330
- shelleyInstall(vm, options) {
1331
- return this.run("shelley install", [vm], options, {});
1228
+ async rm(options) {
1229
+ const result = await this.#transport.call("rm", [this.name], options, {}, true);
1230
+ return result;
1332
1231
  }
1333
1232
  /**
1334
- * Generate a magic link to log in to the website
1233
+ * Restart a VM
1335
1234
  *
1336
- * Usage: `browser`
1235
+ * Usage: `restart <vmname>`
1236
+ *
1237
+ * Tag-scoped API keys may run this command.
1238
+ */
1239
+ async restart(options) {
1240
+ const ready = readiness(options ?? {});
1241
+ const { waitUntil, timeoutMs, ...flags } = options ?? {};
1242
+ const result = await this.#transport.call("restart", [this.name], flags, {}, true);
1243
+ if (ready)
1244
+ await this.waitUntilReady(ready);
1245
+ return this;
1246
+ }
1247
+ /**
1248
+ * Pause a VM (snapshot RAM to disk, free its CPU and memory)
1249
+ *
1250
+ * Usage: `pause <vmname>`
1251
+ *
1252
+ * CLI examples:
1253
+ * ```
1254
+ * pause my-vm # snapshot RAM to disk; resume later with 'resume my-vm'
1255
+ * ```
1256
+ *
1257
+ * Tag-scoped API keys may run this command.
1258
+ */
1259
+ async pause(options) {
1260
+ const result = await this.#transport.call("pause", [this.name], options, {}, false);
1261
+ return result;
1262
+ }
1263
+ /**
1264
+ * Resume a paused VM (restore RAM from disk)
1265
+ *
1266
+ * Usage: `resume <vmname>`
1267
+ *
1268
+ * Tag-scoped API keys may run this command.
1269
+ */
1270
+ async resume(options) {
1271
+ const ready = readiness(options ?? {});
1272
+ const { waitUntil, timeoutMs, ...flags } = options ?? {};
1273
+ const result = await this.#transport.call("resume", [this.name], flags, {}, false);
1274
+ if (ready)
1275
+ await this.waitUntilReady(ready);
1276
+ return this;
1277
+ }
1278
+ /**
1279
+ * rename a vm
1280
+ *
1281
+ * Usage: `rename <oldname> <newname>`
1282
+ *
1283
+ * Tag-scoped API keys may run this command.
1284
+ */
1285
+ async rename(newname, options) {
1286
+ if (newname === this.name)
1287
+ return this;
1288
+ const result = await this.#transport.call("rename", [this.name, newname], options, {}, true);
1289
+ if (result?.new_name !== newname || result?.old_name !== this.name)
1290
+ throw new ExeProtocolError("rename");
1291
+ // Destinations and other metadata may have changed. Do not invent URLs.
1292
+ this.#info = Object.freeze({ name: newname, tags: this.tags });
1293
+ return this;
1294
+ }
1295
+ /**
1296
+ * Add or remove tags on a VM
1297
+ *
1298
+ * Usage: `tag [-d] <vm> <tag-name> [tag-name...]`
1299
+ *
1300
+ * CLI examples:
1301
+ * ```
1302
+ * tag my-vm prod web # add tags
1303
+ * tag -d my-vm prod web # remove tags
1304
+ * ```
1305
+ *
1306
+ * Tag-scoped API keys may run this command.
1307
+ */
1308
+ async tag(tagNames, options) {
1309
+ const result = await this.#transport.call("tag", [this.name, tagNames], options, {
1310
+ d: "bool",
1311
+ }, false);
1312
+ return result;
1313
+ }
1314
+ /**
1315
+ * Copy an existing VM
1316
+ *
1317
+ * Usage: `cp <source-vm> [new-name] [--pool=<name>] [--memory=<size>] [--cpu=<count>] [--disk=<size>]`
1318
+ *
1319
+ * CLI examples:
1320
+ * ```
1321
+ * cp my-vm # copy with auto-generated name
1322
+ * cp my-vm my-vm-copy # copy with specific name
1323
+ * cp my-vm --cpu=4 --memory=16GB # copy with different resources
1324
+ * cp my-vm my-pool-copy --pool=build # copy into a team pool
1325
+ * cp my-vm --copy-tags=false # copy without tags
1326
+ * ```
1327
+ *
1328
+ * Tag-scoped API keys may run this command.
1329
+ */
1330
+ async cp(options) {
1331
+ const ready = readiness(options ?? {});
1332
+ const { waitUntil, timeoutMs, name, ...flags } = options ?? {};
1333
+ const result = await this.#transport.call("cp", [this.name, name], flags, {
1334
+ "copy-tags": "bool",
1335
+ cpu: "number",
1336
+ disk: "string",
1337
+ memory: "string",
1338
+ pool: "string",
1339
+ sandbox: "bool",
1340
+ standalone: "bool",
1341
+ }, true);
1342
+ const vm = new VM(this.#transport, vmInfo(result, "cp"));
1343
+ if (ready)
1344
+ await vm.waitUntilReady(ready);
1345
+ return vm;
1346
+ }
1347
+ /**
1348
+ * Resize a VM's resources (memory, CPU, disk)
1349
+ *
1350
+ * Usage: `resize <vmname> [--memory=<size>] [--cpu=<count>] [--disk=<size>]`
1351
+ *
1352
+ * Tag-scoped API keys may run this command.
1353
+ */
1354
+ async resize(options) {
1355
+ const result = await this.#transport.call("resize", [this.name], options, {
1356
+ cpu: "number",
1357
+ disk: "string",
1358
+ memory: "string",
1359
+ }, false);
1360
+ return result;
1361
+ }
1362
+ /**
1363
+ * Set or clear a short comment on a VM
1364
+ *
1365
+ * Usage: `comment <hostname> <text>`
1366
+ *
1367
+ * CLI examples:
1368
+ * ```
1369
+ * comment my-vm staging copy
1370
+ * comment my-vm "" # clear the comment
1371
+ * ```
1372
+ *
1373
+ * Tag-scoped API keys may run this command.
1374
+ */
1375
+ async comment(text, options) {
1376
+ const result = await this.#transport.call("comment", [this.name, text], options, {}, false);
1377
+ return result;
1378
+ }
1379
+ /**
1380
+ * Link a custom domain to a VM
1381
+ *
1382
+ * Usage: `domain add [--wildcard] <vm> <domain>`
1383
+ */
1384
+ async domainAdd(domain, options) {
1385
+ const result = await this.#transport.call("domain add", [this.name, domain], options, {
1386
+ wildcard: "bool",
1387
+ }, false);
1388
+ return result;
1389
+ }
1390
+ /**
1391
+ * Remove a custom domain from a VM
1392
+ *
1393
+ * Usage: `domain rm <vm> <domain>`
1394
+ */
1395
+ async domainRm(domain, options) {
1396
+ const result = await this.#transport.call("domain rm", [this.name, domain], options, {}, false);
1397
+ return result;
1398
+ }
1399
+ /**
1400
+ * Show current shares for a VM
1401
+ *
1402
+ * Usage: `share show <vm>`
1403
+ *
1404
+ * Tag-scoped API keys may run this command.
1405
+ */
1406
+ async shareShow(options) {
1407
+ const result = await this.#transport.call("share show", [this.name], options, {
1408
+ qr: "bool",
1409
+ }, false);
1410
+ return result;
1411
+ }
1412
+ /**
1413
+ * Set the HTTP proxy port for a VM
1414
+ *
1415
+ * Usage: `share port <vm> [port]`
1416
+ *
1417
+ * CLI examples:
1418
+ * ```
1419
+ * share port mybox 8080
1420
+ * ```
1421
+ *
1422
+ * Tag-scoped API keys may run this command.
1423
+ */
1424
+ async sharePort(port, options) {
1425
+ const result = await this.#transport.call("share port", [this.name, port], options, {}, false);
1426
+ return result;
1427
+ }
1428
+ /**
1429
+ * Make the HTTP proxy publicly accessible
1430
+ *
1431
+ * Usage: `share set-public <vm>`
1432
+ *
1433
+ * Tag-scoped API keys may run this command.
1434
+ */
1435
+ async shareSetPublic(options) {
1436
+ const result = await this.#transport.call("share set-public", [this.name], options, {}, false);
1437
+ return result;
1438
+ }
1439
+ /**
1440
+ * Restrict the HTTP proxy to authenticated users
1441
+ *
1442
+ * Usage: `share set-private <vm>`
1443
+ *
1444
+ * Tag-scoped API keys may run this command.
1445
+ */
1446
+ async shareSetPrivate(options) {
1447
+ const result = await this.#transport.call("share set-private", [this.name], options, {}, false);
1448
+ return result;
1449
+ }
1450
+ /**
1451
+ * Share VM with a user via email, or grant shell access with --root
1452
+ *
1453
+ * Usage: `share add <vm> <email|team> [--root] [--message='...']`
1454
+ *
1455
+ * CLI examples:
1456
+ * ```
1457
+ * share add mybox user@example.com
1458
+ * share add mybox user@example.com --message='Check this out'
1459
+ * share add mybox team
1460
+ * share add mybox teammate@example.com --root
1461
+ * share add mybox team --root
1462
+ * ```
1463
+ *
1464
+ * Tag-scoped API keys may run this command.
1465
+ */
1466
+ async shareAdd(emailOrTeam, options) {
1467
+ const result = await this.#transport.call("share add", [this.name, emailOrTeam], options, {
1468
+ message: "string",
1469
+ qr: "bool",
1470
+ root: "bool",
1471
+ }, false);
1472
+ return result;
1473
+ }
1474
+ /**
1475
+ * Revoke a user's access to a VM, or downgrade shell access to web with --root
1476
+ *
1477
+ * Usage: `share remove <vm> <email|team> [--root]`
1478
+ *
1479
+ * CLI examples:
1480
+ * ```
1481
+ * share remove mybox user@example.com
1482
+ * share remove mybox team
1483
+ * share remove mybox teammate@example.com --root
1484
+ * share remove mybox team --root
1485
+ * ```
1486
+ *
1487
+ * Tag-scoped API keys may run this command.
1488
+ */
1489
+ async shareRemove(emailOrTeam, options) {
1490
+ const result = await this.#transport.call("share remove", [this.name, emailOrTeam], options, {
1491
+ root: "bool",
1492
+ }, false);
1493
+ return result;
1494
+ }
1495
+ /**
1496
+ * Create a shareable link for a VM
1497
+ *
1498
+ * Usage: `share add-link <vm>`
1499
+ *
1500
+ * Tag-scoped API keys may run this command.
1337
1501
  */
1338
- browser(options) {
1339
- return this.run("browser", [], options, {
1502
+ async shareAddLink(options) {
1503
+ const result = await this.#transport.call("share add-link", [this.name], options, {
1340
1504
  qr: "bool",
1341
- });
1505
+ }, false);
1506
+ return result;
1507
+ }
1508
+ /**
1509
+ * Revoke a shareable link
1510
+ *
1511
+ * Usage: `share remove-link <vm> <token>`
1512
+ *
1513
+ * Tag-scoped API keys may run this command.
1514
+ */
1515
+ async shareRemoveLink(token, options) {
1516
+ const result = await this.#transport.call("share remove-link", [this.name, token], options, {}, false);
1517
+ return result;
1518
+ }
1519
+ /**
1520
+ * Enable or disable inbound email for a VM
1521
+ *
1522
+ * Usage: `share receive-email <vm> [on|off] [--reply-policy=all|known|owner|none]`
1523
+ *
1524
+ * CLI examples:
1525
+ * ```
1526
+ * share receive-email mybox on
1527
+ * share receive-email mybox off
1528
+ * share receive-email mybox --reply-policy=known
1529
+ * share receive-email mybox
1530
+ * ```
1531
+ *
1532
+ * Tag-scoped API keys may run this command.
1533
+ */
1534
+ async shareReceiveEmail(onOrOff, options) {
1535
+ const result = await this.#transport.call("share receive-email", [this.name, onOrOff], options, {
1536
+ "reply-policy": "string",
1537
+ }, false);
1538
+ return result;
1539
+ }
1540
+ /**
1541
+ * Install or upgrade Shelley to the current version
1542
+ *
1543
+ * Usage: `shelley install <vm>`
1544
+ *
1545
+ * Tag-scoped API keys may run this command.
1546
+ */
1547
+ async shelleyInstall(options) {
1548
+ const result = await this.#transport.call("shelley install", [this.name], options, {}, false);
1549
+ return result;
1342
1550
  }
1343
1551
  /**
1344
1552
  * Allow exe.dev support to log in to a VM
@@ -1347,8 +1555,9 @@ export class Commands {
1347
1555
  *
1348
1556
  * Tag-scoped API keys may run this command.
1349
1557
  */
1350
- grantSupportRoot(vmname, onOrOff, options) {
1351
- return this.run("grant-support-root", [vmname, onOrOff], options, {});
1558
+ async grantSupportRoot(onOrOff, options) {
1559
+ const result = await this.#transport.call("grant-support-root", [this.name, onOrOff], options, {}, false);
1560
+ return result;
1352
1561
  }
1353
1562
  /**
1354
1563
  * Show vCPU, disk, IO, and network (RX/TX) metrics for a VM
@@ -1364,10 +1573,68 @@ export class Commands {
1364
1573
  *
1365
1574
  * Tag-scoped API keys may run this command.
1366
1575
  */
1367
- stat(vmName, options) {
1368
- return this.run("stat", [vmName], options, {
1576
+ async stat(options) {
1577
+ const result = await this.#transport.call("stat", [this.name], options, {
1369
1578
  range: "string",
1370
- });
1579
+ }, true);
1580
+ return result;
1581
+ }
1582
+ }
1583
+ /** Readiness failed after a VM was obtained/created. The VM is not deleted. */
1584
+ export class VMReadyError extends Error {
1585
+ vm;
1586
+ constructor(vm, cause) {
1587
+ super(`exedev: VM ${vm.name} is not SSH-ready`, { cause });
1588
+ this.vm = vm;
1589
+ this.name = "VMReadyError";
1590
+ }
1591
+ }
1592
+ function readyTimeout(value = 60_000) {
1593
+ if (!Number.isSafeInteger(value) || value <= 0 || value > 2_147_483_647) {
1594
+ throw new TypeError("exedev: timeoutMs must be a positive integer no greater than 2147483647");
1595
+ }
1596
+ return value;
1597
+ }
1598
+ function readiness(options) {
1599
+ const { waitUntil = "ssh", timeoutMs, signal } = options;
1600
+ readyTimeout(timeoutMs); // Validate before creating/copying/restarting a VM.
1601
+ if (waitUntil !== "ssh" && waitUntil !== "created")
1602
+ throw new TypeError("exedev: waitUntil must be ssh or created");
1603
+ return waitUntil === "ssh" ? { timeoutMs, signal } : undefined;
1604
+ }
1605
+ function vmInfo(value, operation) {
1606
+ if (!value || typeof value !== "object" || Array.isArray(value))
1607
+ throw new ExeProtocolError(operation);
1608
+ const obj = value;
1609
+ const string = (key, required = false) => {
1610
+ const value = obj[key];
1611
+ if (value === undefined && !required)
1612
+ return undefined;
1613
+ if (typeof value !== "string" || required && !value)
1614
+ throw new ExeProtocolError(operation);
1615
+ return value;
1616
+ };
1617
+ const name = string(operation === "cp" ? "name" : "vm_name", true);
1618
+ if (!/^[a-zA-Z0-9][a-zA-Z0-9-]*$/.test(name))
1619
+ throw new ExeProtocolError(operation);
1620
+ const tags = obj.tags ?? [];
1621
+ if (!Array.isArray(tags) || !tags.every((tag) => typeof tag === "string"))
1622
+ throw new ExeProtocolError(operation);
1623
+ return {
1624
+ name, tags,
1625
+ sshDest: string(operation === "cp" ? "ssh" : "ssh_dest", true),
1626
+ httpsUrl: string("https_url", operation !== "cp"),
1627
+ status: string(operation === "cp" ? "state" : "status"),
1628
+ region: string("region"),
1629
+ comment: string("comment"),
1630
+ createdAt: string("created_at"),
1631
+ setupError: string("error"),
1632
+ };
1633
+ }
1634
+ function listVMs(transport, value) {
1635
+ if (!value || typeof value !== "object" || !("vms" in value) || !Array.isArray(value.vms)) {
1636
+ throw new ExeProtocolError("ls");
1371
1637
  }
1638
+ return value.vms.map((row) => new VM(transport, vmInfo(row, "ls")));
1372
1639
  }
1373
1640
  //# sourceMappingURL=commands.gen.js.map