instavm 0.11.0 → 0.13.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
@@ -2,7 +2,7 @@
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 client for [InstaVM](https://instavm.io) — secure code execution in ephemeral microVMs with browser automation, networking controls, and platform APIs.
6
6
 
7
7
  ## Installation
8
8
 
@@ -10,9 +10,9 @@ 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
+ ## Quick Start
16
16
 
17
17
  ```typescript
18
18
  import { InstaVM } from 'instavm';
@@ -22,52 +22,43 @@ const client = new InstaVM(process.env.INSTAVM_API_KEY || 'your_api_key');
22
22
  try {
23
23
  const result = await client.execute("print('hello from instavm')");
24
24
  console.log(result.stdout);
25
-
26
- const usage = await client.getUsage();
27
- console.log(usage);
28
25
  } finally {
29
26
  await client.dispose();
30
27
  }
31
28
  ```
32
29
 
33
- ### Local Mode Quick Start
34
-
35
- ```typescript
36
- import { InstaVM } from 'instavm';
37
-
38
- const client = new InstaVM('', {
39
- local: true,
40
- localURL: 'http://coderunner.local:8222',
41
- });
42
-
43
- const result = await client.execute("print('hello from local mode')");
44
- console.log(result.stdout);
45
-
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);
53
- ```
54
-
55
30
  ## Table of Contents
56
31
 
57
- - [Core Workflows](#core-workflows)
58
- - [Infrastructure & Platform APIs](#infrastructure-platform-apis)
59
- - [Browser & Computer Use](#browser-computer-use)
32
+ - [Quick Start](#quick-start)
33
+ - [Code Execution](#code-execution)
34
+ - [Cloud Mode](#cloud-mode)
35
+ - [Local Mode](#local-mode)
36
+ - [File Operations](#file-operations)
37
+ - [Async Execution](#async-execution)
38
+ - [Sessions & Sandboxes](#sessions--sandboxes)
39
+ - [VMs & Snapshots](#vms--snapshots)
40
+ - [Volumes](#volumes)
41
+ - [Volume CRUD & Files](#volume-crud--files)
42
+ - [VM Volume Attachments](#vm-volume-attachments)
43
+ - [Networking](#networking)
44
+ - [Egress, Shares, SSH](#egress-shares-ssh)
45
+ - [Browser Automation](#browser-automation)
46
+ - [Basic Browser Flow](#basic-browser-flow)
47
+ - [Content Extraction](#content-extraction)
48
+ - [Computer Use](#computer-use)
49
+ - [Platform APIs](#platform-apis)
60
50
  - [Error Handling](#error-handling)
61
- - [Development & Testing](#development-testing)
62
- - [Docs Map (Further Reading)](#docs-map-further-reading)
63
- - [Version / Changelog](#version-changelog)
51
+ - [Development & Testing](#development--testing)
52
+ - [Further Reading](#further-reading)
53
+ - [Changelog](#changelog)
54
+
55
+ ---
64
56
 
65
- <a id="core-workflows"></a>
66
- ## Core Workflows
57
+ ## Code Execution
67
58
 
68
- ### Cloud Quick Start
59
+ ### Cloud Mode
69
60
 
70
- Cloud mode supports sessions, VM/network controls, platform APIs, and browser sessions.
61
+ Cloud mode gives you sessions, VM/network controls, platform APIs, and browser sessions.
71
62
 
72
63
  ```typescript
73
64
  import { InstaVM } from 'instavm';
@@ -83,34 +74,38 @@ const sessionId = await client.createSession();
83
74
  console.log('session:', sessionId);
84
75
  ```
85
76
 
86
- ### Local Mode Quick Start
77
+ ### Local Mode
87
78
 
88
- Local mode is optimized for direct execution and lightweight browser helpers.
79
+ Local mode connects to a self-hosted runner for direct execution and browser helpers.
89
80
 
90
81
  ```typescript
91
82
  import { InstaVM } from 'instavm';
92
83
 
93
- const client = new InstaVM('', { local: true });
84
+ const client = new InstaVM('', {
85
+ local: true,
86
+ localURL: 'http://coderunner.local:8222',
87
+ });
94
88
 
95
- await client.execute("print('local execution works')");
96
- await client.browser.navigate('https://example.com');
89
+ const result = await client.execute("print('hello from local mode')");
90
+ console.log(result.stdout);
97
91
  ```
98
92
 
99
93
  ### File Operations
100
94
 
101
95
  ```typescript
102
- import { InstaVM } from 'instavm';
103
-
104
96
  const client = new InstaVM('your_api_key');
105
97
  const sessionId = await client.createSession();
106
98
 
99
+ // Upload
107
100
  await client.upload(
108
101
  [{ name: 'script.py', content: "print('uploaded')", path: '/app/script.py' }],
109
102
  { sessionId }
110
103
  );
111
104
 
105
+ // Execute
112
106
  await client.execute('python /app/script.py', { language: 'bash', sessionId });
113
107
 
108
+ // Download
114
109
  const download = await client.download('output.json', { sessionId });
115
110
  console.log(download.filename, download.size);
116
111
  ```
@@ -118,8 +113,6 @@ console.log(download.filename, download.size);
118
113
  ### Async Execution
119
114
 
120
115
  ```typescript
121
- import { InstaVM } from 'instavm';
122
-
123
116
  const client = new InstaVM('your_api_key');
124
117
 
125
118
  const task = await client.executeAsync("sleep 5 && echo 'done'", { language: 'bash' });
@@ -128,21 +121,53 @@ const result = await client.getTaskResult(task.taskId, 2, 60);
128
121
  console.log(result.stdout);
129
122
  ```
130
123
 
131
- ### VMs + Snapshots
124
+ ---
125
+
126
+ ## Sessions & Sandboxes
132
127
 
133
128
  ```typescript
134
- import { InstaVM } from 'instavm';
129
+ const client = new InstaVM('your_api_key');
130
+ const sessionId = await client.createSession();
131
+
132
+ // Get the publicly-reachable app URL (optionally for a specific port)
133
+ const appUrl = await client.getSessionAppUrl(sessionId, 8080);
134
+ console.log(appUrl.app_url);
135
+
136
+ // List sandbox records with optional metadata filter and limit
137
+ const sandboxes = await client.listSandboxes({
138
+ metadata: { env: 'production' },
139
+ limit: 50,
140
+ });
141
+ console.log(sandboxes.length);
142
+ ```
135
143
 
144
+ ---
145
+
146
+ ## VMs & Snapshots
147
+
148
+ ```typescript
136
149
  const client = new InstaVM('your_api_key');
137
150
 
151
+ // Create a basic VM
138
152
  const vm = await client.vms.create({ metadata: { purpose: 'dev' } }, true);
139
153
  const vmId = String(vm.vm_id);
140
154
 
141
- const vmList = await client.vms.list(); // GET /v1/vms
142
- const vmAllRecords = await client.vms.listAllRecords(); // GET /v1/vms/
155
+ // Create a VM with pre-attached volumes
156
+ const vmWithVols = await client.vms.create({
157
+ metadata: { purpose: 'data-processing' },
158
+ volumes: [
159
+ { volume_id: 'vol_abc', mount_path: '/data', mode: 'rw' },
160
+ ],
161
+ }, true);
162
+
163
+ // List VMs
164
+ const vmList = await client.vms.list(); // GET /v1/vms (running)
165
+ const vmAllRecords = await client.vms.listAllRecords(); // GET /v1/vms/ (all records)
143
166
 
167
+ // Snapshot a running VM
144
168
  await client.vms.snapshot(vmId, { name: 'dev-base' }, true);
145
169
 
170
+ // Build a snapshot from an OCI image
146
171
  await client.snapshots.create({
147
172
  oci_image: 'docker.io/library/python:3.11-slim',
148
173
  name: 'python-3-11-dev',
@@ -157,17 +182,84 @@ await client.snapshots.create({
157
182
  });
158
183
 
159
184
  const userSnapshots = await client.snapshots.list({ type: 'user' });
160
- console.log(vmList.length, vmAllRecords.length, userSnapshots.length);
161
185
  ```
162
186
 
163
- ### Networking (Egress, Shares, SSH)
187
+ ---
188
+
189
+ ## Volumes
190
+
191
+ ### Volume CRUD & Files
164
192
 
165
193
  ```typescript
166
- import { InstaVM } from 'instavm';
194
+ const client = new InstaVM('your_api_key');
195
+
196
+ // Create
197
+ const volume = await client.volumes.create({
198
+ name: 'project-data',
199
+ quota_bytes: 10 * 1024 * 1024 * 1024,
200
+ });
201
+ const volumeId = String(volume.id);
202
+
203
+ // Read / Update
204
+ await client.volumes.list(true); // refresh_usage=true
205
+ await client.volumes.get(volumeId, true);
206
+ await client.volumes.update(volumeId, {
207
+ name: 'project-data-v2',
208
+ quota_bytes: 20 * 1024 * 1024 * 1024,
209
+ });
210
+
211
+ // File operations
212
+ await client.volumes.uploadFile(volumeId, {
213
+ filePath: './README.md',
214
+ path: 'docs/README.md',
215
+ overwrite: true,
216
+ });
167
217
 
218
+ const files = await client.volumes.listFiles(volumeId, {
219
+ prefix: 'docs/',
220
+ recursive: true,
221
+ limit: 1000,
222
+ });
223
+
224
+ const file = await client.volumes.downloadFile(volumeId, 'docs/README.md');
225
+ await client.volumes.deleteFile(volumeId, 'docs/README.md');
226
+
227
+ // Checkpoints
228
+ const checkpoint = await client.volumes.createCheckpoint(volumeId, { name: 'pre-release' });
229
+ await client.volumes.listCheckpoints(volumeId);
230
+ await client.volumes.deleteCheckpoint(volumeId, String(checkpoint.id));
231
+
232
+ // Cleanup
233
+ await client.volumes.delete(volumeId);
234
+ ```
235
+
236
+ ### VM Volume Attachments
237
+
238
+ ```typescript
239
+ const vm = await client.vms.create({}, true);
240
+ const vmId = String(vm.vm_id);
241
+
242
+ await client.vms.mountVolume(vmId, {
243
+ volume_id: volumeId,
244
+ mount_path: '/data',
245
+ mode: 'rw',
246
+ }, true);
247
+
248
+ await client.vms.listVolumes(vmId);
249
+ await client.vms.unmountVolume(vmId, volumeId, '/data', true);
250
+ ```
251
+
252
+ ---
253
+
254
+ ## Networking
255
+
256
+ ### Egress, Shares, SSH
257
+
258
+ ```typescript
168
259
  const client = new InstaVM('your_api_key');
169
260
  const sessionId = await client.createSession();
170
261
 
262
+ // Egress policy
171
263
  await client.setSessionEgress(
172
264
  {
173
265
  allowPackageManagers: true,
@@ -178,81 +270,36 @@ await client.setSessionEgress(
178
270
  sessionId
179
271
  );
180
272
 
273
+ // Public/private share links
181
274
  const share = await client.shares.create({ session_id: sessionId, port: 3000, is_public: false });
182
275
  await client.shares.update(String(share.share_id), { is_public: true });
183
276
 
277
+ // SSH key registration
184
278
  const key = await client.addSshKey('ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAA... user@host');
185
- console.log(key);
186
279
  ```
187
280
 
188
- <a id="infrastructure-platform-apis"></a>
189
- ## Infrastructure & Platform APIs
281
+ ---
190
282
 
191
- ### Platform APIs (API Keys, Audit, Webhooks)
283
+ ## Browser Automation
192
284
 
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
- ```
209
-
210
- <a id="browser-computer-use"></a>
211
- ## Browser & Computer Use
212
-
213
- ### Browser Automation
214
-
215
- Basic browser session flow:
285
+ ### Basic Browser Flow
216
286
 
217
287
  ```typescript
218
- import { InstaVM } from 'instavm';
219
-
220
288
  const client = new InstaVM('your_api_key');
221
289
 
222
290
  const browser = await client.browser.createSession({ viewportWidth: 1366, viewportHeight: 768 });
223
291
  await browser.navigate('https://example.com');
224
292
  await browser.click('a');
225
293
  const screenshot = await browser.screenshot({ fullPage: true });
226
-
227
- console.log(screenshot.length);
228
294
  await browser.close();
229
295
  ```
230
296
 
231
- Advanced flow with waits and extraction:
232
-
233
- ```typescript
234
- import { InstaVM } from 'instavm';
235
-
236
- const client = new InstaVM('your_api_key');
237
- const browser = await client.browser.createSession();
297
+ ### Content Extraction
238
298
 
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)
299
+ LLM-friendly extraction with optional interactive-element and anchor discovery:
249
300
 
250
301
  ```typescript
251
- import { InstaVM } from 'instavm';
252
-
253
- const client = new InstaVM('your_api_key');
254
302
  const browser = await client.browser.createSession();
255
-
256
303
  await browser.navigate('https://example.com/docs');
257
304
 
258
305
  const content = await browser.extractContent({
@@ -269,23 +316,57 @@ for (const anchor of (content.contentAnchors || []).slice(0, 5)) {
269
316
  await browser.close();
270
317
  ```
271
318
 
272
- ### Computer Use
319
+ ---
273
320
 
274
- ```typescript
275
- import { InstaVM } from 'instavm';
321
+ ## Computer Use
276
322
 
323
+ Control a full desktop environment inside a VM session:
324
+
325
+ ```typescript
277
326
  const client = new InstaVM('your_api_key');
278
327
  const sessionId = await client.createSession();
279
328
 
329
+ // Viewer URL and state
280
330
  const viewer = await client.computerUse.viewerUrl(sessionId);
281
331
  const state = await client.computerUse.get(sessionId, '/state');
282
332
 
283
- console.log(viewer, state);
333
+ // Proxy methods (GET, POST, HEAD)
334
+ const headResp = await client.computerUse.head(sessionId, '/state');
335
+
336
+ // VNC websockify URL for remote desktop streaming
337
+ const vnc = await client.computerUse.vncWebsockify(sessionId);
284
338
  ```
285
339
 
286
- <a id="error-handling"></a>
340
+ ---
341
+
342
+ ## Platform APIs
343
+
344
+ API keys, audit logs, and webhooks:
345
+
346
+ ```typescript
347
+ const client = new InstaVM('your_api_key');
348
+
349
+ // API Keys
350
+ const apiKey = await client.apiKeys.create({ description: 'ci key' });
351
+
352
+ // Audit log
353
+ const events = await client.audit.events({ status: 'success', limit: 25 });
354
+
355
+ // Webhooks
356
+ const endpoint = await client.webhooks.createEndpoint({
357
+ url: 'https://example.com/instavm/webhook',
358
+ event_patterns: ['vm.*', 'snapshot.*'],
359
+ });
360
+
361
+ const deliveries = await client.webhooks.listDeliveries({ limit: 10 });
362
+ ```
363
+
364
+ ---
365
+
287
366
  ## Error Handling
288
367
 
368
+ All SDK errors extend a typed hierarchy for precise `catch` handling:
369
+
289
370
  ```typescript
290
371
  import {
291
372
  InstaVM,
@@ -317,40 +398,46 @@ try {
317
398
  }
318
399
  ```
319
400
 
320
- <a id="development-testing"></a>
401
+ ---
402
+
321
403
  ## Development & Testing
322
404
 
323
405
  ```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
406
+ npm install # Install dependencies
407
+ npm run test:unit # Unit tests
408
+ npm test # Full test suite
409
+ npm run build # Build package
335
410
  ```
336
411
 
337
- <a id="docs-map-further-reading"></a>
338
- ## Docs Map (Further Reading)
412
+ ---
413
+
414
+ ## Further Reading
339
415
 
340
416
  - [JavaScript SDK Docs](https://instavm.io/docs/sdks/javascript)
341
417
  - [VMs API](https://instavm.io/docs/api/vms/)
342
418
  - [Snapshots API](https://instavm.io/docs/api/snapshots/)
343
419
  - [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)
420
+ - [Computer Use API](https://instavm.io/docs/api#endpoint-categories)
421
+ - [Webhooks API](https://instavm.io/docs/api#endpoint-categories)
422
+
423
+ ---
424
+
425
+ ## Changelog
426
+
427
+ Current package version: **0.13.0**
428
+
429
+ ### 0.13.0
346
430
 
347
- <a id="version-changelog"></a>
348
- ## Version / Changelog
431
+ - [`getSessionAppUrl(sessionId?, port?)`](#sessions--sandboxes) — session app URL with optional port
432
+ - [`listSandboxes({ metadata?, limit? })`](#sessions--sandboxes) — list sandbox records with metadata filtering
433
+ - [`computerUse.head(sessionId, path)`](#computer-use) — HEAD proxy method for computer-use sessions
434
+ - [`computerUse.vncWebsockify(sessionId)`](#computer-use) — VNC websockify URL for remote desktop streaming
435
+ - VM creation now accepts [`volumes`](#vms--snapshots) for pre-attached volume mounts
436
+ - `APIKey` type includes `key_prefix` and `full_key` fields
349
437
 
350
- Current package version: `0.11.0`.
438
+ ### 0.12.0
351
439
 
352
- Highlights in this line:
353
- - Manager-based infrastructure APIs (VMs, snapshots, shares, custom domains, computer use, API keys, audit, webhooks)
440
+ - Manager-based infrastructure APIs (VMs, volumes, snapshots, shares, custom domains, computer use, API keys, audit, webhooks)
354
441
  - Snapshot build args support for env vars and Git clone inputs
355
442
  - Distinct VM list helpers for `/v1/vms` and `/v1/vms/`
356
443