instavm 0.11.0 → 0.15.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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 InstaVM
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,8 +1,8 @@
1
- # InstaVM JavaScript SDK
1
+ # InstaVM JavaScript SDK + CLI
2
2
 
3
3
  ![Build Status](https://github.com/instavm/js/actions/workflows/ci.yml/badge.svg)
4
4
 
5
- Official JavaScript/TypeScript client for InstaVM code execution, VM lifecycle, snapshots, networking controls, browser automation, and platform APIs.
5
+ Official JavaScript/TypeScript SDK and installed CLI for [InstaVM](https://instavm.io). Use it to manage VMs, snapshots, shares, volumes, desktops, account settings, and code execution from Node.js or your shell.
6
6
 
7
7
  ## Installation
8
8
 
@@ -10,64 +10,120 @@ Official JavaScript/TypeScript client for InstaVM code execution, VM lifecycle,
10
10
  npm install instavm
11
11
  ```
12
12
 
13
- ## Quick Start
13
+ **Requirements:** Node.js 18+, TypeScript 4.7+ (optional)
14
14
 
15
- ### Cloud Quick Start
15
+ ## CLI
16
16
 
17
- ```typescript
18
- import { InstaVM } from 'instavm';
17
+ The published package includes an `instavm` binary.
19
18
 
20
- const client = new InstaVM(process.env.INSTAVM_API_KEY || 'your_api_key');
19
+ ```bash
20
+ npx instavm --help
21
+ pnpm exec instavm --help
22
+ yarn exec instavm --help
23
+ bunx instavm --help
24
+ ```
21
25
 
22
- try {
23
- const result = await client.execute("print('hello from instavm')");
24
- console.log(result.stdout);
26
+ If you want `instavm` directly on your PATH, install it globally:
25
27
 
26
- const usage = await client.getUsage();
27
- console.log(usage);
28
- } finally {
29
- await client.dispose();
30
- }
28
+ ```bash
29
+ npm install -g instavm
30
+ instavm --help
31
+ ```
32
+
33
+ The CLI stores defaults in `~/.instavm/config.json`, checks `INSTAVM_API_KEY` when no key is stored, and also respects `INSTAVM_BASE_URL` and `INSTAVM_SSH_HOST`.
34
+
35
+ ### Auth & Config
36
+
37
+ ```bash
38
+ instavm auth set-key
39
+ instavm auth status
40
+ printf '%s' "$INSTAVM_API_KEY" | instavm auth set-key
41
+ ```
42
+
43
+ ### Common Commands
44
+
45
+ ```bash
46
+ instavm whoami
47
+ instavm ls
48
+ instavm create --type computer-use --memory 4096
49
+ instavm connect vm_123
50
+ instavm snapshot ls
51
+ instavm volume ls
52
+ instavm volume files upload <volume_id> ./README.md --path docs/README.md
53
+ instavm share create vm_123 3000 --public
54
+ instavm share set-private <share_id>
55
+ instavm ssh-key list
56
+ instavm desktop viewer <session_id>
57
+ instavm doc
58
+ instavm billing
31
59
  ```
32
60
 
33
- ### Local Mode Quick Start
61
+ ### Command Reference
62
+
63
+ - `auth`: `set-key`, `status`, `logout`
64
+ - `whoami`: show account details and SSH keys
65
+ - `create`/`new`, `ls`/`list`, `rm`/`delete`, `clone`, `connect`: core VM workflows
66
+ - `snapshot`: `ls`, `create`, `build`, `get`, `rm`
67
+ - `desktop`: `status`, `start`, `stop`, `viewer`
68
+ - `volume`: `ls`, `get`, `create`, `update`, `rm`, `checkpoint`, `files`
69
+ - `share`: `create`, `set-public`, `set-private`, `revoke`
70
+ - `ssh-key`: `list`, `add`, `remove`
71
+ - `doc`/`docs`, `billing`: docs and billing links
72
+
73
+ All leaf commands support `--json`. Share visibility updates use `share_id`, which matches the public API.
74
+
75
+ ## Library Quick Start
34
76
 
35
77
  ```typescript
36
78
  import { InstaVM } from 'instavm';
37
79
 
38
- const client = new InstaVM('', {
39
- local: true,
40
- localURL: 'http://coderunner.local:8222',
41
- });
80
+ const client = new InstaVM(process.env.INSTAVM_API_KEY || 'your_api_key');
42
81
 
43
- const result = await client.execute("print('hello from local mode')");
44
- console.log(result.stdout);
82
+ const [me, vms] = await Promise.all([
83
+ client.getCurrentUser(),
84
+ client.vms.list(),
85
+ ]);
45
86
 
46
- const content = await client.browser.extractContent({
47
- url: 'https://example.com',
48
- includeInteractive: true,
49
- includeAnchors: true,
50
- });
51
-
52
- console.log(content.readableContent.title);
87
+ console.log(me.email);
88
+ console.log(vms.length);
53
89
  ```
54
90
 
55
91
  ## Table of Contents
56
92
 
57
- - [Core Workflows](#core-workflows)
58
- - [Infrastructure & Platform APIs](#infrastructure-platform-apis)
59
- - [Browser & Computer Use](#browser-computer-use)
93
+ - [CLI](#cli)
94
+ - [Auth & Config](#auth--config)
95
+ - [Common Commands](#common-commands)
96
+ - [Command Reference](#command-reference)
97
+ - [Library Quick Start](#library-quick-start)
98
+ - [Code Execution](#code-execution)
99
+ - [Cloud Mode](#cloud-mode)
100
+ - [Local Mode](#local-mode)
101
+ - [File Operations](#file-operations)
102
+ - [Async Execution](#async-execution)
103
+ - [Sessions & Sandboxes](#sessions--sandboxes)
104
+ - [VMs & Snapshots](#vms--snapshots)
105
+ - [Volumes](#volumes)
106
+ - [Volume CRUD & Files](#volume-crud--files)
107
+ - [VM Volume Attachments](#vm-volume-attachments)
108
+ - [Networking](#networking)
109
+ - [Egress, Shares, SSH](#egress-shares-ssh)
110
+ - [Browser Automation](#browser-automation)
111
+ - [Basic Browser Flow](#basic-browser-flow)
112
+ - [Content Extraction](#content-extraction)
113
+ - [Computer Use](#computer-use)
114
+ - [Platform APIs](#platform-apis)
60
115
  - [Error Handling](#error-handling)
61
- - [Development & Testing](#development-testing)
62
- - [Docs Map (Further Reading)](#docs-map-further-reading)
63
- - [Version / Changelog](#version-changelog)
116
+ - [Development & Testing](#development--testing)
117
+ - [Further Reading](#further-reading)
118
+ - [Changelog](#changelog)
119
+
120
+ ---
64
121
 
65
- <a id="core-workflows"></a>
66
- ## Core Workflows
122
+ ## Code Execution
67
123
 
68
- ### Cloud Quick Start
124
+ ### Cloud Mode
69
125
 
70
- Cloud mode supports sessions, VM/network controls, platform APIs, and browser sessions.
126
+ Cloud mode gives you sessions, VM/network controls, platform APIs, and browser sessions.
71
127
 
72
128
  ```typescript
73
129
  import { InstaVM } from 'instavm';
@@ -83,34 +139,38 @@ const sessionId = await client.createSession();
83
139
  console.log('session:', sessionId);
84
140
  ```
85
141
 
86
- ### Local Mode Quick Start
142
+ ### Local Mode
87
143
 
88
- Local mode is optimized for direct execution and lightweight browser helpers.
144
+ Local mode connects to a self-hosted runner for direct execution and browser helpers.
89
145
 
90
146
  ```typescript
91
147
  import { InstaVM } from 'instavm';
92
148
 
93
- const client = new InstaVM('', { local: true });
149
+ const client = new InstaVM('', {
150
+ local: true,
151
+ localURL: 'http://coderunner.local:8222',
152
+ });
94
153
 
95
- await client.execute("print('local execution works')");
96
- await client.browser.navigate('https://example.com');
154
+ const result = await client.execute("print('hello from local mode')");
155
+ console.log(result.stdout);
97
156
  ```
98
157
 
99
158
  ### File Operations
100
159
 
101
160
  ```typescript
102
- import { InstaVM } from 'instavm';
103
-
104
161
  const client = new InstaVM('your_api_key');
105
162
  const sessionId = await client.createSession();
106
163
 
164
+ // Upload
107
165
  await client.upload(
108
166
  [{ name: 'script.py', content: "print('uploaded')", path: '/app/script.py' }],
109
167
  { sessionId }
110
168
  );
111
169
 
170
+ // Execute
112
171
  await client.execute('python /app/script.py', { language: 'bash', sessionId });
113
172
 
173
+ // Download
114
174
  const download = await client.download('output.json', { sessionId });
115
175
  console.log(download.filename, download.size);
116
176
  ```
@@ -118,8 +178,6 @@ console.log(download.filename, download.size);
118
178
  ### Async Execution
119
179
 
120
180
  ```typescript
121
- import { InstaVM } from 'instavm';
122
-
123
181
  const client = new InstaVM('your_api_key');
124
182
 
125
183
  const task = await client.executeAsync("sleep 5 && echo 'done'", { language: 'bash' });
@@ -128,21 +186,53 @@ const result = await client.getTaskResult(task.taskId, 2, 60);
128
186
  console.log(result.stdout);
129
187
  ```
130
188
 
131
- ### VMs + Snapshots
189
+ ---
190
+
191
+ ## Sessions & Sandboxes
132
192
 
133
193
  ```typescript
134
- import { InstaVM } from 'instavm';
194
+ const client = new InstaVM('your_api_key');
195
+ const sessionId = await client.createSession();
135
196
 
197
+ // Get the publicly-reachable app URL (optionally for a specific port)
198
+ const appUrl = await client.getSessionAppUrl(sessionId, 8080);
199
+ console.log(appUrl.app_url);
200
+
201
+ // List sandbox records with optional metadata filter and limit
202
+ const sandboxes = await client.listSandboxes({
203
+ metadata: { env: 'production' },
204
+ limit: 50,
205
+ });
206
+ console.log(sandboxes.length);
207
+ ```
208
+
209
+ ---
210
+
211
+ ## VMs & Snapshots
212
+
213
+ ```typescript
136
214
  const client = new InstaVM('your_api_key');
137
215
 
216
+ // Create a basic VM
138
217
  const vm = await client.vms.create({ metadata: { purpose: 'dev' } }, true);
139
218
  const vmId = String(vm.vm_id);
140
219
 
141
- const vmList = await client.vms.list(); // GET /v1/vms
142
- const vmAllRecords = await client.vms.listAllRecords(); // GET /v1/vms/
220
+ // Create a VM with pre-attached volumes
221
+ const vmWithVols = await client.vms.create({
222
+ metadata: { purpose: 'data-processing' },
223
+ volumes: [
224
+ { volume_id: 'vol_abc', mount_path: '/data', mode: 'rw' },
225
+ ],
226
+ }, true);
143
227
 
228
+ // List VMs
229
+ const vmList = await client.vms.list(); // GET /v1/vms (running)
230
+ const vmAllRecords = await client.vms.listAllRecords(); // GET /v1/vms/ (all records)
231
+
232
+ // Snapshot a running VM
144
233
  await client.vms.snapshot(vmId, { name: 'dev-base' }, true);
145
234
 
235
+ // Build a snapshot from an OCI image
146
236
  await client.snapshots.create({
147
237
  oci_image: 'docker.io/library/python:3.11-slim',
148
238
  name: 'python-3-11-dev',
@@ -157,17 +247,84 @@ await client.snapshots.create({
157
247
  });
158
248
 
159
249
  const userSnapshots = await client.snapshots.list({ type: 'user' });
160
- console.log(vmList.length, vmAllRecords.length, userSnapshots.length);
161
250
  ```
162
251
 
163
- ### Networking (Egress, Shares, SSH)
252
+ ---
253
+
254
+ ## Volumes
255
+
256
+ ### Volume CRUD & Files
164
257
 
165
258
  ```typescript
166
- import { InstaVM } from 'instavm';
259
+ const client = new InstaVM('your_api_key');
260
+
261
+ // Create
262
+ const volume = await client.volumes.create({
263
+ name: 'project-data',
264
+ quota_bytes: 10 * 1024 * 1024 * 1024,
265
+ });
266
+ const volumeId = String(volume.id);
267
+
268
+ // Read / Update
269
+ await client.volumes.list(true); // refresh_usage=true
270
+ await client.volumes.get(volumeId, true);
271
+ await client.volumes.update(volumeId, {
272
+ name: 'project-data-v2',
273
+ quota_bytes: 20 * 1024 * 1024 * 1024,
274
+ });
275
+
276
+ // File operations
277
+ await client.volumes.uploadFile(volumeId, {
278
+ filePath: './README.md',
279
+ path: 'docs/README.md',
280
+ overwrite: true,
281
+ });
282
+
283
+ const files = await client.volumes.listFiles(volumeId, {
284
+ prefix: 'docs/',
285
+ recursive: true,
286
+ limit: 1000,
287
+ });
288
+
289
+ const file = await client.volumes.downloadFile(volumeId, 'docs/README.md');
290
+ await client.volumes.deleteFile(volumeId, 'docs/README.md');
291
+
292
+ // Checkpoints
293
+ const checkpoint = await client.volumes.createCheckpoint(volumeId, { name: 'pre-release' });
294
+ await client.volumes.listCheckpoints(volumeId);
295
+ await client.volumes.deleteCheckpoint(volumeId, String(checkpoint.id));
296
+
297
+ // Cleanup
298
+ await client.volumes.delete(volumeId);
299
+ ```
300
+
301
+ ### VM Volume Attachments
302
+
303
+ ```typescript
304
+ const vm = await client.vms.create({}, true);
305
+ const vmId = String(vm.vm_id);
306
+
307
+ await client.vms.mountVolume(vmId, {
308
+ volume_id: volumeId,
309
+ mount_path: '/data',
310
+ mode: 'rw',
311
+ }, true);
312
+
313
+ await client.vms.listVolumes(vmId);
314
+ await client.vms.unmountVolume(vmId, volumeId, '/data', true);
315
+ ```
167
316
 
317
+ ---
318
+
319
+ ## Networking
320
+
321
+ ### Egress, Shares, SSH
322
+
323
+ ```typescript
168
324
  const client = new InstaVM('your_api_key');
169
325
  const sessionId = await client.createSession();
170
326
 
327
+ // Egress policy
171
328
  await client.setSessionEgress(
172
329
  {
173
330
  allowPackageManagers: true,
@@ -178,81 +335,36 @@ await client.setSessionEgress(
178
335
  sessionId
179
336
  );
180
337
 
338
+ // Public/private share links
181
339
  const share = await client.shares.create({ session_id: sessionId, port: 3000, is_public: false });
182
340
  await client.shares.update(String(share.share_id), { is_public: true });
183
341
 
342
+ // SSH key registration
184
343
  const key = await client.addSshKey('ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAA... user@host');
185
- console.log(key);
186
- ```
187
-
188
- <a id="infrastructure-platform-apis"></a>
189
- ## Infrastructure & Platform APIs
190
-
191
- ### Platform APIs (API Keys, Audit, Webhooks)
192
-
193
- ```typescript
194
- import { InstaVM } from 'instavm';
195
-
196
- const client = new InstaVM('your_api_key');
197
-
198
- const apiKey = await client.apiKeys.create({ description: 'ci key' });
199
- const events = await client.audit.events({ status: 'success', limit: 25 });
200
-
201
- const endpoint = await client.webhooks.createEndpoint({
202
- url: 'https://example.com/instavm/webhook',
203
- event_patterns: ['vm.*', 'snapshot.*'],
204
- });
205
-
206
- const deliveries = await client.webhooks.listDeliveries({ limit: 10 });
207
- console.log(apiKey, events, endpoint, deliveries);
208
344
  ```
209
345
 
210
- <a id="browser-computer-use"></a>
211
- ## Browser & Computer Use
346
+ ---
212
347
 
213
- ### Browser Automation
348
+ ## Browser Automation
214
349
 
215
- Basic browser session flow:
350
+ ### Basic Browser Flow
216
351
 
217
352
  ```typescript
218
- import { InstaVM } from 'instavm';
219
-
220
353
  const client = new InstaVM('your_api_key');
221
354
 
222
355
  const browser = await client.browser.createSession({ viewportWidth: 1366, viewportHeight: 768 });
223
356
  await browser.navigate('https://example.com');
224
357
  await browser.click('a');
225
358
  const screenshot = await browser.screenshot({ fullPage: true });
226
-
227
- console.log(screenshot.length);
228
359
  await browser.close();
229
360
  ```
230
361
 
231
- Advanced flow with waits and extraction:
362
+ ### Content Extraction
232
363
 
233
- ```typescript
234
- import { InstaVM } from 'instavm';
235
-
236
- const client = new InstaVM('your_api_key');
237
- const browser = await client.browser.createSession();
238
-
239
- await browser.navigate('https://news.ycombinator.com');
240
- await browser.wait({ type: 'visible', selector: 'a.storylink' }, 10000);
241
-
242
- const links = await browser.extractElements('a.storylink', ['text', 'href']);
243
- console.log(links.slice(0, 5));
244
-
245
- await browser.close();
246
- ```
247
-
248
- ### LLM-Friendly Content Extraction (concise pattern only)
364
+ LLM-friendly extraction with optional interactive-element and anchor discovery:
249
365
 
250
366
  ```typescript
251
- import { InstaVM } from 'instavm';
252
-
253
- const client = new InstaVM('your_api_key');
254
367
  const browser = await client.browser.createSession();
255
-
256
368
  await browser.navigate('https://example.com/docs');
257
369
 
258
370
  const content = await browser.extractContent({
@@ -269,23 +381,57 @@ for (const anchor of (content.contentAnchors || []).slice(0, 5)) {
269
381
  await browser.close();
270
382
  ```
271
383
 
272
- ### Computer Use
384
+ ---
273
385
 
274
- ```typescript
275
- import { InstaVM } from 'instavm';
386
+ ## Computer Use
387
+
388
+ Control a full desktop environment inside a VM session:
276
389
 
390
+ ```typescript
277
391
  const client = new InstaVM('your_api_key');
278
392
  const sessionId = await client.createSession();
279
393
 
394
+ // Viewer URL and state
280
395
  const viewer = await client.computerUse.viewerUrl(sessionId);
281
396
  const state = await client.computerUse.get(sessionId, '/state');
282
397
 
283
- console.log(viewer, state);
398
+ // Proxy methods (GET, POST, HEAD)
399
+ const headResp = await client.computerUse.head(sessionId, '/state');
400
+
401
+ // VNC websockify URL for remote desktop streaming
402
+ const vnc = await client.computerUse.vncWebsockify(sessionId);
403
+ ```
404
+
405
+ ---
406
+
407
+ ## Platform APIs
408
+
409
+ API keys, audit logs, and webhooks:
410
+
411
+ ```typescript
412
+ const client = new InstaVM('your_api_key');
413
+
414
+ // API Keys
415
+ const apiKey = await client.apiKeys.create({ description: 'ci key' });
416
+
417
+ // Audit log
418
+ const events = await client.audit.events({ status: 'success', limit: 25 });
419
+
420
+ // Webhooks
421
+ const endpoint = await client.webhooks.createEndpoint({
422
+ url: 'https://example.com/instavm/webhook',
423
+ event_patterns: ['vm.*', 'snapshot.*'],
424
+ });
425
+
426
+ const deliveries = await client.webhooks.listDeliveries({ limit: 10 });
284
427
  ```
285
428
 
286
- <a id="error-handling"></a>
429
+ ---
430
+
287
431
  ## Error Handling
288
432
 
433
+ All SDK errors extend a typed hierarchy for precise `catch` handling:
434
+
289
435
  ```typescript
290
436
  import {
291
437
  InstaVM,
@@ -317,40 +463,52 @@ try {
317
463
  }
318
464
  ```
319
465
 
320
- <a id="development-testing"></a>
466
+ ---
467
+
321
468
  ## Development & Testing
322
469
 
323
470
  ```bash
324
- # Install dependencies
325
- npm install
326
-
327
- # Run unit tests
328
- npm run test:unit
329
-
330
- # Optional: full test run
331
- npm test
332
-
333
- # Build package
334
- npm run build
471
+ npm install # Install dependencies
472
+ npm run test:unit # Unit tests
473
+ npm test # Full test suite
474
+ npm run build # Build package
335
475
  ```
336
476
 
337
- <a id="docs-map-further-reading"></a>
338
- ## Docs Map (Further Reading)
477
+ ---
478
+
479
+ ## Further Reading
339
480
 
340
481
  - [JavaScript SDK Docs](https://instavm.io/docs/sdks/javascript)
341
482
  - [VMs API](https://instavm.io/docs/api/vms/)
342
483
  - [Snapshots API](https://instavm.io/docs/api/snapshots/)
343
484
  - [Shares API](https://instavm.io/docs/api/shares/)
344
- - [Computer Use API (REST API Reference)](https://instavm.io/docs/api#endpoint-categories)
345
- - [Webhooks API (REST API Reference)](https://instavm.io/docs/api#endpoint-categories)
485
+ - [Computer Use API](https://instavm.io/docs/api#endpoint-categories)
486
+ - [Webhooks API](https://instavm.io/docs/api#endpoint-categories)
487
+
488
+ ---
489
+
490
+ ## Changelog
491
+
492
+ Current package version: **0.15.0**
493
+
494
+ ### 0.15.0
495
+
496
+ - Installed `instavm` CLI for `npm`, `pnpm`, `yarn`, `bun`, and global package installs
497
+ - Stored CLI auth/config in `~/.instavm/config.json` with `INSTAVM_API_KEY` fallback
498
+ - Added [`getCurrentUser()`](#library-quick-start) and `getSessionStatus(sessionId?)` helpers for identity and desktop workflows
499
+
500
+ ### 0.13.0
346
501
 
347
- <a id="version-changelog"></a>
348
- ## Version / Changelog
502
+ - [`getSessionAppUrl(sessionId?, port?)`](#sessions--sandboxes) — session app URL with optional port
503
+ - [`listSandboxes({ metadata?, limit? })`](#sessions--sandboxes) — list sandbox records with metadata filtering
504
+ - [`computerUse.head(sessionId, path)`](#computer-use) — HEAD proxy method for computer-use sessions
505
+ - [`computerUse.vncWebsockify(sessionId)`](#computer-use) — VNC websockify URL for remote desktop streaming
506
+ - VM creation now accepts [`volumes`](#vms--snapshots) for pre-attached volume mounts
507
+ - `APIKey` type includes `key_prefix` and `full_key` fields
349
508
 
350
- Current package version: `0.11.0`.
509
+ ### 0.12.0
351
510
 
352
- Highlights in this line:
353
- - Manager-based infrastructure APIs (VMs, snapshots, shares, custom domains, computer use, API keys, audit, webhooks)
511
+ - Manager-based infrastructure APIs (VMs, volumes, snapshots, shares, custom domains, computer use, API keys, audit, webhooks)
354
512
  - Snapshot build args support for env vars and Git clone inputs
355
513
  - Distinct VM list helpers for `/v1/vms` and `/v1/vms/`
356
514