@computesdk/opencomputer 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +98 -0
- package/dist/index.d.mts +139 -0
- package/dist/index.d.ts +139 -0
- package/dist/index.js +343 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +308 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +64 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 computesdk
|
|
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
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# @computesdk/opencomputer
|
|
2
|
+
|
|
3
|
+
OpenComputer provider for ComputeSDK - create persistent cloud VMs, run commands, read/write files, expose preview URLs, and manage checkpoints through the ComputeSDK interface.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install computesdk @computesdk/opencomputer
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Setup
|
|
12
|
+
|
|
13
|
+
Create an OpenComputer API key and set:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
export OPENCOMPUTER_API_KEY=your_api_key_here
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Optionally override the API URL:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
export OPENCOMPUTER_API_URL=https://app.opencomputer.dev
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Quick Start
|
|
26
|
+
|
|
27
|
+
```typescript
|
|
28
|
+
import { compute } from 'computesdk';
|
|
29
|
+
import { opencomputer } from '@computesdk/opencomputer';
|
|
30
|
+
|
|
31
|
+
compute.setConfig({
|
|
32
|
+
provider: opencomputer({ apiKey: process.env.OPENCOMPUTER_API_KEY }),
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
const sandbox = await compute.sandbox.create({ templateId: 'base' });
|
|
36
|
+
|
|
37
|
+
const result = await sandbox.runCommand('echo "Hello from OpenComputer"');
|
|
38
|
+
console.log(result.stdout);
|
|
39
|
+
|
|
40
|
+
await sandbox.filesystem.writeFile('/tmp/hello.txt', 'Hello ComputeSDK');
|
|
41
|
+
console.log(await sandbox.filesystem.readFile('/tmp/hello.txt'));
|
|
42
|
+
|
|
43
|
+
const url = await sandbox.getUrl({ port: 3000 });
|
|
44
|
+
console.log(url);
|
|
45
|
+
|
|
46
|
+
await sandbox.destroy();
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Configuration
|
|
50
|
+
|
|
51
|
+
```typescript
|
|
52
|
+
interface OpenComputerConfig {
|
|
53
|
+
apiKey?: string;
|
|
54
|
+
apiUrl?: string;
|
|
55
|
+
template?: string;
|
|
56
|
+
timeout?: number;
|
|
57
|
+
envs?: Record<string, string>;
|
|
58
|
+
metadata?: Record<string, string>;
|
|
59
|
+
cpuCount?: number;
|
|
60
|
+
memoryMB?: number;
|
|
61
|
+
diskMB?: number;
|
|
62
|
+
secretStore?: string;
|
|
63
|
+
burst?: boolean;
|
|
64
|
+
previewAuth?: { scheme?: 'bearer'; token?: 'auto' | string };
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
`timeout` uses ComputeSDK's millisecond convention and is converted to OpenComputer's seconds-based API.
|
|
69
|
+
|
|
70
|
+
## Features
|
|
71
|
+
|
|
72
|
+
- Command execution via OpenComputer exec
|
|
73
|
+
- Filesystem read, write, mkdir, list, exists, and remove
|
|
74
|
+
- Sandbox create, reconnect by ID, and destroy
|
|
75
|
+
- Preview URLs for sandbox ports
|
|
76
|
+
- Checkpoints through ComputeSDK snapshots
|
|
77
|
+
|
|
78
|
+
## Snapshots
|
|
79
|
+
|
|
80
|
+
OpenComputer checkpoints are scoped to a source sandbox. This provider returns snapshot IDs in the form `sandboxId:checkpointId` so ComputeSDK can later delete the checkpoint.
|
|
81
|
+
|
|
82
|
+
```typescript
|
|
83
|
+
const sandbox = await compute.sandbox.create();
|
|
84
|
+
|
|
85
|
+
const snapshot = await compute.snapshot.create(sandbox.sandboxId, {
|
|
86
|
+
name: 'ready-state',
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
const clone = await compute.sandbox.create({ snapshotId: snapshot.id });
|
|
90
|
+
|
|
91
|
+
await compute.snapshot.delete(snapshot.id);
|
|
92
|
+
await clone.destroy();
|
|
93
|
+
await sandbox.destroy();
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
You can also pass a raw OpenComputer checkpoint ID to `compute.sandbox.create({ snapshotId })` when you only need to fork from it.
|
|
97
|
+
|
|
98
|
+
Snapshots default to OpenComputer `disk_only` checkpoints with `promoteToFull: true`. Override with `metadata: { kind: 'full' }` or `metadata: { promoteToFull: false }` when needed.
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import * as _computesdk_provider from '@computesdk/provider';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* OpenComputer Provider - Factory-based Implementation
|
|
5
|
+
*
|
|
6
|
+
* Wraps the official `@opencomputer/sdk` so OpenComputer sandboxes can be used
|
|
7
|
+
* through the ComputeSDK provider interface.
|
|
8
|
+
*/
|
|
9
|
+
interface OpenComputerProcessResult {
|
|
10
|
+
stdout?: string;
|
|
11
|
+
stderr?: string;
|
|
12
|
+
exitCode?: number;
|
|
13
|
+
}
|
|
14
|
+
interface OpenComputerExecSession {
|
|
15
|
+
sessionId: string;
|
|
16
|
+
}
|
|
17
|
+
interface OpenComputerEntryInfo {
|
|
18
|
+
name: string;
|
|
19
|
+
isDir: boolean;
|
|
20
|
+
path: string;
|
|
21
|
+
size: number;
|
|
22
|
+
}
|
|
23
|
+
interface OpenComputerCheckpointInfo {
|
|
24
|
+
id: string;
|
|
25
|
+
sandboxId?: string;
|
|
26
|
+
orgId?: string;
|
|
27
|
+
name?: string;
|
|
28
|
+
status?: string;
|
|
29
|
+
sizeBytes?: number;
|
|
30
|
+
createdAt?: string;
|
|
31
|
+
sandboxConfig?: Record<string, unknown>;
|
|
32
|
+
}
|
|
33
|
+
interface OpenComputerPreviewURLResult {
|
|
34
|
+
hostname?: string;
|
|
35
|
+
customHostname?: string;
|
|
36
|
+
port: number;
|
|
37
|
+
}
|
|
38
|
+
interface OpenComputerNativeSandbox {
|
|
39
|
+
readonly sandboxId: string;
|
|
40
|
+
readonly id: string;
|
|
41
|
+
readonly status: string;
|
|
42
|
+
readonly previewAuthToken?: string;
|
|
43
|
+
readonly webhooks?: Array<{
|
|
44
|
+
id: string;
|
|
45
|
+
url: string;
|
|
46
|
+
secret?: string;
|
|
47
|
+
}>;
|
|
48
|
+
readonly commands: {
|
|
49
|
+
run(command: string, opts?: {
|
|
50
|
+
cwd?: string;
|
|
51
|
+
env?: Record<string, string>;
|
|
52
|
+
timeout?: number;
|
|
53
|
+
timeoutMs?: number;
|
|
54
|
+
}): Promise<OpenComputerProcessResult>;
|
|
55
|
+
};
|
|
56
|
+
readonly exec?: {
|
|
57
|
+
run(command: string, opts?: {
|
|
58
|
+
cwd?: string;
|
|
59
|
+
env?: Record<string, string>;
|
|
60
|
+
timeout?: number;
|
|
61
|
+
timeoutMs?: number;
|
|
62
|
+
}): Promise<OpenComputerProcessResult>;
|
|
63
|
+
background?(command: string, opts?: {
|
|
64
|
+
cwd?: string;
|
|
65
|
+
env?: Record<string, string>;
|
|
66
|
+
timeout?: number;
|
|
67
|
+
timeoutMs?: number;
|
|
68
|
+
}): Promise<OpenComputerExecSession>;
|
|
69
|
+
};
|
|
70
|
+
readonly files: {
|
|
71
|
+
read(path: string): Promise<string>;
|
|
72
|
+
write(path: string, content: string): Promise<void>;
|
|
73
|
+
makeDir(path: string): Promise<void>;
|
|
74
|
+
list(path?: string): Promise<OpenComputerEntryInfo[]>;
|
|
75
|
+
exists(path: string): Promise<boolean>;
|
|
76
|
+
remove(path: string): Promise<void>;
|
|
77
|
+
};
|
|
78
|
+
getPreviewDomain(port: number): string;
|
|
79
|
+
createPreviewURL(opts: {
|
|
80
|
+
port: number;
|
|
81
|
+
domain?: string;
|
|
82
|
+
authConfig?: Record<string, unknown>;
|
|
83
|
+
}): Promise<OpenComputerPreviewURLResult>;
|
|
84
|
+
listPreviewURLs(): Promise<OpenComputerPreviewURLResult[]>;
|
|
85
|
+
kill(): Promise<void>;
|
|
86
|
+
isRunning(): Promise<boolean>;
|
|
87
|
+
createCheckpoint(name: string, opts?: {
|
|
88
|
+
kind?: 'full' | 'disk_only';
|
|
89
|
+
promoteToFull?: boolean;
|
|
90
|
+
retentionPolicy?: unknown;
|
|
91
|
+
}): Promise<OpenComputerCheckpointInfo>;
|
|
92
|
+
listCheckpoints(): Promise<OpenComputerCheckpointInfo[]>;
|
|
93
|
+
deleteCheckpoint(checkpointId: string): Promise<void>;
|
|
94
|
+
}
|
|
95
|
+
interface OpenComputerConfig {
|
|
96
|
+
/** OpenComputer API key - falls back to OPENCOMPUTER_API_KEY. */
|
|
97
|
+
apiKey?: string;
|
|
98
|
+
/** OpenComputer API URL - falls back to OPENCOMPUTER_API_URL, then production. */
|
|
99
|
+
apiUrl?: string;
|
|
100
|
+
/** Default template for new sandboxes. Defaults to OpenComputer's `base` template. */
|
|
101
|
+
template?: string;
|
|
102
|
+
/** Default idle timeout in milliseconds. OpenComputer receives this as seconds. */
|
|
103
|
+
timeout?: number;
|
|
104
|
+
/** Default environment variables for new sandboxes. */
|
|
105
|
+
envs?: Record<string, string>;
|
|
106
|
+
/** Default metadata for new sandboxes. */
|
|
107
|
+
metadata?: Record<string, string>;
|
|
108
|
+
/** OpenComputer CPU count for new sandboxes. */
|
|
109
|
+
cpuCount?: number;
|
|
110
|
+
/** OpenComputer memory size in MB for new sandboxes. */
|
|
111
|
+
memoryMB?: number;
|
|
112
|
+
/** OpenComputer workspace disk size in MB for new sandboxes. */
|
|
113
|
+
diskMB?: number;
|
|
114
|
+
/** Secret store to attach to new sandboxes. */
|
|
115
|
+
secretStore?: string;
|
|
116
|
+
/** Create Burst sandboxes by default. */
|
|
117
|
+
burst?: boolean;
|
|
118
|
+
/** Require bearer auth on preview URLs. */
|
|
119
|
+
previewAuth?: {
|
|
120
|
+
scheme?: 'bearer';
|
|
121
|
+
token?: 'auto' | string;
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
interface OpenComputerSnapshot {
|
|
125
|
+
id: string;
|
|
126
|
+
provider: 'opencomputer';
|
|
127
|
+
createdAt: Date;
|
|
128
|
+
metadata: {
|
|
129
|
+
sandboxId?: string;
|
|
130
|
+
orgId?: string;
|
|
131
|
+
name?: string;
|
|
132
|
+
status?: string;
|
|
133
|
+
sizeBytes?: number;
|
|
134
|
+
sandboxConfig?: Record<string, unknown>;
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
declare const opencomputer: (config?: OpenComputerConfig) => _computesdk_provider.Provider<OpenComputerNativeSandbox, any, OpenComputerSnapshot>;
|
|
138
|
+
|
|
139
|
+
export { type OpenComputerConfig, type OpenComputerNativeSandbox, type OpenComputerSnapshot, opencomputer };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import * as _computesdk_provider from '@computesdk/provider';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* OpenComputer Provider - Factory-based Implementation
|
|
5
|
+
*
|
|
6
|
+
* Wraps the official `@opencomputer/sdk` so OpenComputer sandboxes can be used
|
|
7
|
+
* through the ComputeSDK provider interface.
|
|
8
|
+
*/
|
|
9
|
+
interface OpenComputerProcessResult {
|
|
10
|
+
stdout?: string;
|
|
11
|
+
stderr?: string;
|
|
12
|
+
exitCode?: number;
|
|
13
|
+
}
|
|
14
|
+
interface OpenComputerExecSession {
|
|
15
|
+
sessionId: string;
|
|
16
|
+
}
|
|
17
|
+
interface OpenComputerEntryInfo {
|
|
18
|
+
name: string;
|
|
19
|
+
isDir: boolean;
|
|
20
|
+
path: string;
|
|
21
|
+
size: number;
|
|
22
|
+
}
|
|
23
|
+
interface OpenComputerCheckpointInfo {
|
|
24
|
+
id: string;
|
|
25
|
+
sandboxId?: string;
|
|
26
|
+
orgId?: string;
|
|
27
|
+
name?: string;
|
|
28
|
+
status?: string;
|
|
29
|
+
sizeBytes?: number;
|
|
30
|
+
createdAt?: string;
|
|
31
|
+
sandboxConfig?: Record<string, unknown>;
|
|
32
|
+
}
|
|
33
|
+
interface OpenComputerPreviewURLResult {
|
|
34
|
+
hostname?: string;
|
|
35
|
+
customHostname?: string;
|
|
36
|
+
port: number;
|
|
37
|
+
}
|
|
38
|
+
interface OpenComputerNativeSandbox {
|
|
39
|
+
readonly sandboxId: string;
|
|
40
|
+
readonly id: string;
|
|
41
|
+
readonly status: string;
|
|
42
|
+
readonly previewAuthToken?: string;
|
|
43
|
+
readonly webhooks?: Array<{
|
|
44
|
+
id: string;
|
|
45
|
+
url: string;
|
|
46
|
+
secret?: string;
|
|
47
|
+
}>;
|
|
48
|
+
readonly commands: {
|
|
49
|
+
run(command: string, opts?: {
|
|
50
|
+
cwd?: string;
|
|
51
|
+
env?: Record<string, string>;
|
|
52
|
+
timeout?: number;
|
|
53
|
+
timeoutMs?: number;
|
|
54
|
+
}): Promise<OpenComputerProcessResult>;
|
|
55
|
+
};
|
|
56
|
+
readonly exec?: {
|
|
57
|
+
run(command: string, opts?: {
|
|
58
|
+
cwd?: string;
|
|
59
|
+
env?: Record<string, string>;
|
|
60
|
+
timeout?: number;
|
|
61
|
+
timeoutMs?: number;
|
|
62
|
+
}): Promise<OpenComputerProcessResult>;
|
|
63
|
+
background?(command: string, opts?: {
|
|
64
|
+
cwd?: string;
|
|
65
|
+
env?: Record<string, string>;
|
|
66
|
+
timeout?: number;
|
|
67
|
+
timeoutMs?: number;
|
|
68
|
+
}): Promise<OpenComputerExecSession>;
|
|
69
|
+
};
|
|
70
|
+
readonly files: {
|
|
71
|
+
read(path: string): Promise<string>;
|
|
72
|
+
write(path: string, content: string): Promise<void>;
|
|
73
|
+
makeDir(path: string): Promise<void>;
|
|
74
|
+
list(path?: string): Promise<OpenComputerEntryInfo[]>;
|
|
75
|
+
exists(path: string): Promise<boolean>;
|
|
76
|
+
remove(path: string): Promise<void>;
|
|
77
|
+
};
|
|
78
|
+
getPreviewDomain(port: number): string;
|
|
79
|
+
createPreviewURL(opts: {
|
|
80
|
+
port: number;
|
|
81
|
+
domain?: string;
|
|
82
|
+
authConfig?: Record<string, unknown>;
|
|
83
|
+
}): Promise<OpenComputerPreviewURLResult>;
|
|
84
|
+
listPreviewURLs(): Promise<OpenComputerPreviewURLResult[]>;
|
|
85
|
+
kill(): Promise<void>;
|
|
86
|
+
isRunning(): Promise<boolean>;
|
|
87
|
+
createCheckpoint(name: string, opts?: {
|
|
88
|
+
kind?: 'full' | 'disk_only';
|
|
89
|
+
promoteToFull?: boolean;
|
|
90
|
+
retentionPolicy?: unknown;
|
|
91
|
+
}): Promise<OpenComputerCheckpointInfo>;
|
|
92
|
+
listCheckpoints(): Promise<OpenComputerCheckpointInfo[]>;
|
|
93
|
+
deleteCheckpoint(checkpointId: string): Promise<void>;
|
|
94
|
+
}
|
|
95
|
+
interface OpenComputerConfig {
|
|
96
|
+
/** OpenComputer API key - falls back to OPENCOMPUTER_API_KEY. */
|
|
97
|
+
apiKey?: string;
|
|
98
|
+
/** OpenComputer API URL - falls back to OPENCOMPUTER_API_URL, then production. */
|
|
99
|
+
apiUrl?: string;
|
|
100
|
+
/** Default template for new sandboxes. Defaults to OpenComputer's `base` template. */
|
|
101
|
+
template?: string;
|
|
102
|
+
/** Default idle timeout in milliseconds. OpenComputer receives this as seconds. */
|
|
103
|
+
timeout?: number;
|
|
104
|
+
/** Default environment variables for new sandboxes. */
|
|
105
|
+
envs?: Record<string, string>;
|
|
106
|
+
/** Default metadata for new sandboxes. */
|
|
107
|
+
metadata?: Record<string, string>;
|
|
108
|
+
/** OpenComputer CPU count for new sandboxes. */
|
|
109
|
+
cpuCount?: number;
|
|
110
|
+
/** OpenComputer memory size in MB for new sandboxes. */
|
|
111
|
+
memoryMB?: number;
|
|
112
|
+
/** OpenComputer workspace disk size in MB for new sandboxes. */
|
|
113
|
+
diskMB?: number;
|
|
114
|
+
/** Secret store to attach to new sandboxes. */
|
|
115
|
+
secretStore?: string;
|
|
116
|
+
/** Create Burst sandboxes by default. */
|
|
117
|
+
burst?: boolean;
|
|
118
|
+
/** Require bearer auth on preview URLs. */
|
|
119
|
+
previewAuth?: {
|
|
120
|
+
scheme?: 'bearer';
|
|
121
|
+
token?: 'auto' | string;
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
interface OpenComputerSnapshot {
|
|
125
|
+
id: string;
|
|
126
|
+
provider: 'opencomputer';
|
|
127
|
+
createdAt: Date;
|
|
128
|
+
metadata: {
|
|
129
|
+
sandboxId?: string;
|
|
130
|
+
orgId?: string;
|
|
131
|
+
name?: string;
|
|
132
|
+
status?: string;
|
|
133
|
+
sizeBytes?: number;
|
|
134
|
+
sandboxConfig?: Record<string, unknown>;
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
declare const opencomputer: (config?: OpenComputerConfig) => _computesdk_provider.Provider<OpenComputerNativeSandbox, any, OpenComputerSnapshot>;
|
|
138
|
+
|
|
139
|
+
export { type OpenComputerConfig, type OpenComputerNativeSandbox, type OpenComputerSnapshot, opencomputer };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,343 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/index.ts
|
|
31
|
+
var index_exports = {};
|
|
32
|
+
__export(index_exports, {
|
|
33
|
+
opencomputer: () => opencomputer
|
|
34
|
+
});
|
|
35
|
+
module.exports = __toCommonJS(index_exports);
|
|
36
|
+
var import_provider = require("@computesdk/provider");
|
|
37
|
+
var _SandboxClass = null;
|
|
38
|
+
async function loadSandbox() {
|
|
39
|
+
if (!_SandboxClass) {
|
|
40
|
+
const mod = await import("@opencomputer/sdk");
|
|
41
|
+
_SandboxClass = mod.Sandbox;
|
|
42
|
+
}
|
|
43
|
+
return _SandboxClass;
|
|
44
|
+
}
|
|
45
|
+
function env(name) {
|
|
46
|
+
return typeof process !== "undefined" ? process.env?.[name] : void 0;
|
|
47
|
+
}
|
|
48
|
+
function baseOpts(config) {
|
|
49
|
+
return {
|
|
50
|
+
apiKey: config.apiKey || env("OPENCOMPUTER_API_KEY"),
|
|
51
|
+
apiUrl: config.apiUrl || env("OPENCOMPUTER_API_URL")
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
function toSeconds(milliseconds) {
|
|
55
|
+
return milliseconds == null ? void 0 : Math.ceil(milliseconds / 1e3);
|
|
56
|
+
}
|
|
57
|
+
function stringifyMetadata(metadata) {
|
|
58
|
+
if (!metadata) return void 0;
|
|
59
|
+
const out = {};
|
|
60
|
+
for (const [key, value] of Object.entries(metadata)) {
|
|
61
|
+
if (value == null || typeof value === "function" || typeof value === "symbol") {
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
if (typeof value === "string") {
|
|
65
|
+
out[key] = value;
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
if (typeof value === "number" || typeof value === "boolean" || typeof value === "bigint") {
|
|
69
|
+
out[key] = String(value);
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
try {
|
|
73
|
+
const serialized = JSON.stringify(value);
|
|
74
|
+
if (serialized !== void 0) {
|
|
75
|
+
out[key] = serialized;
|
|
76
|
+
}
|
|
77
|
+
} catch {
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return out;
|
|
81
|
+
}
|
|
82
|
+
function redactWebhooks(webhooks) {
|
|
83
|
+
return webhooks?.map((webhook) => ({
|
|
84
|
+
id: webhook.id,
|
|
85
|
+
url: webhook.url,
|
|
86
|
+
hasSecret: typeof webhook.secret === "string" && webhook.secret.length > 0
|
|
87
|
+
}));
|
|
88
|
+
}
|
|
89
|
+
function createOpts(config, options) {
|
|
90
|
+
return {
|
|
91
|
+
...baseOpts(config),
|
|
92
|
+
template: options?.templateId || config.template,
|
|
93
|
+
timeout: toSeconds(options?.timeout ?? config.timeout),
|
|
94
|
+
envs: { ...config.envs, ...options?.envs },
|
|
95
|
+
metadata: { ...config.metadata, ...stringifyMetadata(options?.metadata) },
|
|
96
|
+
cpuCount: options?.cpuCount ?? config.cpuCount,
|
|
97
|
+
memoryMB: options?.memoryMB ?? options?.memory ?? config.memoryMB,
|
|
98
|
+
diskMB: options?.diskMB ?? config.diskMB,
|
|
99
|
+
secretStore: options?.secretStore ?? config.secretStore,
|
|
100
|
+
burst: options?.burst ?? config.burst,
|
|
101
|
+
sandboxFamily: options?.sandboxFamily,
|
|
102
|
+
previewAuth: options?.previewAuth ?? config.previewAuth,
|
|
103
|
+
webhooks: options?.webhooks
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
function snapshotToCompute(snapshot) {
|
|
107
|
+
const id = snapshot.sandboxId ? `${snapshot.sandboxId}:${snapshot.id}` : snapshot.id;
|
|
108
|
+
return {
|
|
109
|
+
id,
|
|
110
|
+
provider: "opencomputer",
|
|
111
|
+
createdAt: snapshot.createdAt ? new Date(snapshot.createdAt) : /* @__PURE__ */ new Date(),
|
|
112
|
+
metadata: {
|
|
113
|
+
sandboxId: snapshot.sandboxId,
|
|
114
|
+
orgId: snapshot.orgId,
|
|
115
|
+
name: snapshot.name,
|
|
116
|
+
status: snapshot.status,
|
|
117
|
+
sizeBytes: snapshot.sizeBytes,
|
|
118
|
+
sandboxConfig: snapshot.sandboxConfig
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
function sleep(ms) {
|
|
123
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
124
|
+
}
|
|
125
|
+
async function waitForCheckpointReady(sandbox, checkpoint, timeoutMs = 3e5) {
|
|
126
|
+
if (checkpoint.status === "ready") return checkpoint;
|
|
127
|
+
if (checkpoint.status === "failed") {
|
|
128
|
+
throw new Error(`OpenComputer checkpoint ${checkpoint.id} failed.`);
|
|
129
|
+
}
|
|
130
|
+
const deadline = Date.now() + timeoutMs;
|
|
131
|
+
let delay = 1e3;
|
|
132
|
+
for (; ; ) {
|
|
133
|
+
if (Date.now() >= deadline) {
|
|
134
|
+
throw new Error(`OpenComputer checkpoint ${checkpoint.id} was not ready after ${timeoutMs}ms.`);
|
|
135
|
+
}
|
|
136
|
+
const checkpoints = await sandbox.listCheckpoints();
|
|
137
|
+
const current = checkpoints.find((candidate) => candidate.id === checkpoint.id);
|
|
138
|
+
if (!current) {
|
|
139
|
+
throw new Error(`OpenComputer checkpoint ${checkpoint.id} disappeared while waiting for readiness.`);
|
|
140
|
+
}
|
|
141
|
+
if (current.status === "ready") return current;
|
|
142
|
+
if (current.status === "failed") {
|
|
143
|
+
throw new Error(`OpenComputer checkpoint ${checkpoint.id} failed.`);
|
|
144
|
+
}
|
|
145
|
+
await sleep(delay);
|
|
146
|
+
delay = Math.min(delay * 1.5, 5e3);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
function isCheckpointIndexMiss(error) {
|
|
150
|
+
if (!(error instanceof Error)) return false;
|
|
151
|
+
const message = error.message.toLowerCase();
|
|
152
|
+
return message.includes("404") && message.includes("checkpoint") && message.includes("not found");
|
|
153
|
+
}
|
|
154
|
+
async function createFromCheckpointWithRetry(Sandbox, checkpointId, opts, timeoutMs = 6e4) {
|
|
155
|
+
const deadline = Date.now() + timeoutMs;
|
|
156
|
+
let delay = 1e3;
|
|
157
|
+
for (; ; ) {
|
|
158
|
+
try {
|
|
159
|
+
return await Sandbox.createFromCheckpoint(checkpointId, opts);
|
|
160
|
+
} catch (error) {
|
|
161
|
+
if (!isCheckpointIndexMiss(error) || Date.now() >= deadline) {
|
|
162
|
+
throw error;
|
|
163
|
+
}
|
|
164
|
+
await sleep(delay);
|
|
165
|
+
delay = Math.min(delay * 1.5, 5e3);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
async function createSandbox(config, options) {
|
|
170
|
+
const Sandbox = await loadSandbox();
|
|
171
|
+
const opts = createOpts(config, options);
|
|
172
|
+
if (options?.snapshotId) {
|
|
173
|
+
const checkpointId = options.snapshotId.includes(":") ? options.snapshotId.slice(options.snapshotId.indexOf(":") + 1) : options.snapshotId;
|
|
174
|
+
const sandbox2 = await createFromCheckpointWithRetry(Sandbox, checkpointId, {
|
|
175
|
+
...baseOpts(config),
|
|
176
|
+
timeout: opts.timeout,
|
|
177
|
+
envs: opts.envs,
|
|
178
|
+
secretStore: opts.secretStore
|
|
179
|
+
});
|
|
180
|
+
return { sandbox: sandbox2, sandboxId: sandbox2.sandboxId || sandbox2.id };
|
|
181
|
+
}
|
|
182
|
+
const sandbox = await Sandbox.create(opts);
|
|
183
|
+
return { sandbox, sandboxId: sandbox.sandboxId || sandbox.id };
|
|
184
|
+
}
|
|
185
|
+
var _provider = (0, import_provider.defineProvider)({
|
|
186
|
+
name: "opencomputer",
|
|
187
|
+
methods: {
|
|
188
|
+
sandbox: {
|
|
189
|
+
create: createSandbox,
|
|
190
|
+
getById: async (config, sandboxId) => {
|
|
191
|
+
const Sandbox = await loadSandbox();
|
|
192
|
+
try {
|
|
193
|
+
const sandbox = await Sandbox.connect(sandboxId, baseOpts(config));
|
|
194
|
+
return { sandbox, sandboxId: sandbox.sandboxId || sandbox.id || sandboxId };
|
|
195
|
+
} catch (error) {
|
|
196
|
+
if (error instanceof Error && (error.message.includes("404") || error.message.includes("not found"))) {
|
|
197
|
+
return null;
|
|
198
|
+
}
|
|
199
|
+
throw new Error(`Failed to get OpenComputer sandbox ${sandboxId}: ${error instanceof Error ? error.message : String(error)}`);
|
|
200
|
+
}
|
|
201
|
+
},
|
|
202
|
+
list: async () => {
|
|
203
|
+
throw new Error("OpenComputer provider does not support listing sandboxes via the TypeScript SDK.");
|
|
204
|
+
},
|
|
205
|
+
destroy: async (config, sandboxId) => {
|
|
206
|
+
const Sandbox = await loadSandbox();
|
|
207
|
+
try {
|
|
208
|
+
const sandbox = await Sandbox.connect(sandboxId, baseOpts(config));
|
|
209
|
+
await sandbox.kill();
|
|
210
|
+
} catch (error) {
|
|
211
|
+
if (error instanceof Error && (error.message.includes("404") || error.message.includes("not found"))) {
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
throw new Error(`Failed to destroy OpenComputer sandbox ${sandboxId}: ${error instanceof Error ? error.message : String(error)}`);
|
|
215
|
+
}
|
|
216
|
+
},
|
|
217
|
+
runCommand: async (sandbox, command, options) => {
|
|
218
|
+
const startTime = Date.now();
|
|
219
|
+
try {
|
|
220
|
+
const runOptions = {
|
|
221
|
+
cwd: options?.cwd,
|
|
222
|
+
env: options?.env,
|
|
223
|
+
timeout: toSeconds(options?.timeout),
|
|
224
|
+
timeoutMs: options?.timeout
|
|
225
|
+
};
|
|
226
|
+
if (options?.background && sandbox.exec?.background) {
|
|
227
|
+
const session = await sandbox.exec.background(command, runOptions);
|
|
228
|
+
return {
|
|
229
|
+
stdout: session.sessionId,
|
|
230
|
+
stderr: "",
|
|
231
|
+
exitCode: 0,
|
|
232
|
+
durationMs: Date.now() - startTime
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
const result = await (sandbox.exec ?? sandbox.commands).run(command, runOptions);
|
|
236
|
+
return {
|
|
237
|
+
stdout: result.stdout || "",
|
|
238
|
+
stderr: result.stderr || "",
|
|
239
|
+
exitCode: result.exitCode ?? 0,
|
|
240
|
+
durationMs: Date.now() - startTime
|
|
241
|
+
};
|
|
242
|
+
} catch (error) {
|
|
243
|
+
throw new Error(`OpenComputer command execution failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
244
|
+
}
|
|
245
|
+
},
|
|
246
|
+
getInfo: async (sandbox) => {
|
|
247
|
+
let status = sandbox.status;
|
|
248
|
+
try {
|
|
249
|
+
status = await sandbox.isRunning() ? "running" : sandbox.status;
|
|
250
|
+
} catch {
|
|
251
|
+
status = sandbox.status;
|
|
252
|
+
}
|
|
253
|
+
return {
|
|
254
|
+
id: sandbox.sandboxId || sandbox.id,
|
|
255
|
+
provider: "opencomputer",
|
|
256
|
+
status: status === "running" ? "running" : status === "error" ? "error" : "stopped",
|
|
257
|
+
createdAt: /* @__PURE__ */ new Date(),
|
|
258
|
+
timeout: 0,
|
|
259
|
+
metadata: {
|
|
260
|
+
opencomputerSandboxId: sandbox.sandboxId || sandbox.id,
|
|
261
|
+
previewAuthEnabled: Boolean(sandbox.previewAuthToken),
|
|
262
|
+
webhooks: redactWebhooks(sandbox.webhooks)
|
|
263
|
+
}
|
|
264
|
+
};
|
|
265
|
+
},
|
|
266
|
+
getUrl: async (sandbox, options) => {
|
|
267
|
+
const protocol = options.protocol || "https";
|
|
268
|
+
const domain = sandbox.getPreviewDomain(options.port);
|
|
269
|
+
if (domain) {
|
|
270
|
+
return `${protocol}://${domain}`;
|
|
271
|
+
}
|
|
272
|
+
const preview = await sandbox.createPreviewURL({ port: options.port });
|
|
273
|
+
const hostname = preview.customHostname || preview.hostname;
|
|
274
|
+
if (!hostname) {
|
|
275
|
+
throw new Error(`OpenComputer did not return a preview hostname for port ${options.port}.`);
|
|
276
|
+
}
|
|
277
|
+
return `${protocol}://${hostname}`;
|
|
278
|
+
},
|
|
279
|
+
filesystem: {
|
|
280
|
+
readFile: async (sandbox, path) => sandbox.files.read(path),
|
|
281
|
+
writeFile: async (sandbox, path, content) => {
|
|
282
|
+
await sandbox.files.write(path, content);
|
|
283
|
+
},
|
|
284
|
+
mkdir: async (sandbox, path) => {
|
|
285
|
+
await sandbox.files.makeDir(path);
|
|
286
|
+
},
|
|
287
|
+
readdir: async (sandbox, path) => {
|
|
288
|
+
const entries = await sandbox.files.list(path);
|
|
289
|
+
return entries.map((entry) => ({
|
|
290
|
+
name: entry.name,
|
|
291
|
+
type: entry.isDir ? "directory" : "file",
|
|
292
|
+
size: entry.size,
|
|
293
|
+
modified: /* @__PURE__ */ new Date()
|
|
294
|
+
}));
|
|
295
|
+
},
|
|
296
|
+
exists: async (sandbox, path) => sandbox.files.exists(path),
|
|
297
|
+
remove: async (sandbox, path) => {
|
|
298
|
+
await sandbox.files.remove(path);
|
|
299
|
+
}
|
|
300
|
+
},
|
|
301
|
+
getInstance: (sandbox) => sandbox
|
|
302
|
+
},
|
|
303
|
+
snapshot: {
|
|
304
|
+
create: async (config, sandboxId, options) => {
|
|
305
|
+
const Sandbox = await loadSandbox();
|
|
306
|
+
const sandbox = await Sandbox.connect(sandboxId, baseOpts(config));
|
|
307
|
+
const metadata = options?.metadata;
|
|
308
|
+
const kind = metadata?.kind ?? "disk_only";
|
|
309
|
+
const snapshot = await sandbox.createCheckpoint(options?.name || `snapshot-${Date.now()}`, {
|
|
310
|
+
kind,
|
|
311
|
+
promoteToFull: metadata?.promoteToFull ?? (kind === "disk_only" ? true : void 0),
|
|
312
|
+
retentionPolicy: metadata?.retentionPolicy
|
|
313
|
+
});
|
|
314
|
+
return snapshotToCompute(await waitForCheckpointReady(sandbox, snapshot));
|
|
315
|
+
},
|
|
316
|
+
list: async (config, options) => {
|
|
317
|
+
if (!options?.sandboxId) {
|
|
318
|
+
throw new Error("OpenComputer snapshots are scoped to a sandbox. Pass `sandboxId` to list snapshots.");
|
|
319
|
+
}
|
|
320
|
+
const Sandbox = await loadSandbox();
|
|
321
|
+
const sandbox = await Sandbox.connect(options.sandboxId, baseOpts(config));
|
|
322
|
+
const snapshots = await sandbox.listCheckpoints();
|
|
323
|
+
return snapshots.map(snapshotToCompute);
|
|
324
|
+
},
|
|
325
|
+
delete: async (config, snapshotId) => {
|
|
326
|
+
const sandboxId = snapshotId.split(":", 1)[0];
|
|
327
|
+
if (!sandboxId || sandboxId === snapshotId) {
|
|
328
|
+
throw new Error("OpenComputer snapshot deletion requires a sandbox-scoped id in the form `sandboxId:checkpointId`.");
|
|
329
|
+
}
|
|
330
|
+
const checkpointId = snapshotId.slice(sandboxId.length + 1);
|
|
331
|
+
const Sandbox = await loadSandbox();
|
|
332
|
+
const sandbox = await Sandbox.connect(sandboxId, baseOpts(config));
|
|
333
|
+
await sandbox.deleteCheckpoint(checkpointId);
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
});
|
|
338
|
+
var opencomputer = (config = {}) => _provider(config);
|
|
339
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
340
|
+
0 && (module.exports = {
|
|
341
|
+
opencomputer
|
|
342
|
+
});
|
|
343
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * OpenComputer Provider - Factory-based Implementation\n *\n * Wraps the official `@opencomputer/sdk` so OpenComputer sandboxes can be used\n * through the ComputeSDK provider interface.\n */\n\nimport { defineProvider } from '@computesdk/provider';\n\nimport type {\n CommandResult,\n CreateSandboxOptions,\n CreateSnapshotOptions,\n FileEntry,\n ListSnapshotsOptions,\n RunCommandOptions,\n SandboxInfo,\n} from '@computesdk/provider';\n\ninterface OpenComputerSandboxOpts {\n template?: string;\n timeout?: number;\n apiKey?: string;\n apiUrl?: string;\n envs?: Record<string, string>;\n metadata?: Record<string, string>;\n cpuCount?: number;\n memoryMB?: number;\n diskMB?: number;\n secretStore?: string;\n snapshot?: string;\n burst?: boolean;\n sandboxFamily?: 'spot';\n previewAuth?: { scheme?: 'bearer'; token?: 'auto' | string };\n webhooks?: Array<{ url: string; secret?: string; eventTypes?: string[] }>;\n}\n\ninterface OpenComputerProcessResult {\n stdout?: string;\n stderr?: string;\n exitCode?: number;\n}\n\ninterface OpenComputerExecSession {\n sessionId: string;\n}\n\ninterface OpenComputerEntryInfo {\n name: string;\n isDir: boolean;\n path: string;\n size: number;\n}\n\ninterface OpenComputerCheckpointInfo {\n id: string;\n sandboxId?: string;\n orgId?: string;\n name?: string;\n status?: string;\n sizeBytes?: number;\n createdAt?: string;\n sandboxConfig?: Record<string, unknown>;\n}\n\ninterface OpenComputerPreviewURLResult {\n hostname?: string;\n customHostname?: string;\n port: number;\n}\n\ninterface OpenComputerNativeSandbox {\n readonly sandboxId: string;\n readonly id: string;\n readonly status: string;\n readonly previewAuthToken?: string;\n readonly webhooks?: Array<{ id: string; url: string; secret?: string }>;\n readonly commands: {\n run(command: string, opts?: { cwd?: string; env?: Record<string, string>; timeout?: number; timeoutMs?: number }): Promise<OpenComputerProcessResult>;\n };\n readonly exec?: {\n run(command: string, opts?: { cwd?: string; env?: Record<string, string>; timeout?: number; timeoutMs?: number }): Promise<OpenComputerProcessResult>;\n background?(command: string, opts?: { cwd?: string; env?: Record<string, string>; timeout?: number; timeoutMs?: number }): Promise<OpenComputerExecSession>;\n };\n readonly files: {\n read(path: string): Promise<string>;\n write(path: string, content: string): Promise<void>;\n makeDir(path: string): Promise<void>;\n list(path?: string): Promise<OpenComputerEntryInfo[]>;\n exists(path: string): Promise<boolean>;\n remove(path: string): Promise<void>;\n };\n getPreviewDomain(port: number): string;\n createPreviewURL(opts: { port: number; domain?: string; authConfig?: Record<string, unknown> }): Promise<OpenComputerPreviewURLResult>;\n listPreviewURLs(): Promise<OpenComputerPreviewURLResult[]>;\n kill(): Promise<void>;\n isRunning(): Promise<boolean>;\n createCheckpoint(name: string, opts?: { kind?: 'full' | 'disk_only'; promoteToFull?: boolean; retentionPolicy?: unknown }): Promise<OpenComputerCheckpointInfo>;\n listCheckpoints(): Promise<OpenComputerCheckpointInfo[]>;\n deleteCheckpoint(checkpointId: string): Promise<void>;\n}\n\ninterface OpenComputerSandboxStatic {\n create(opts?: OpenComputerSandboxOpts): Promise<OpenComputerNativeSandbox>;\n connect(sandboxId: string, opts?: Pick<OpenComputerSandboxOpts, 'apiKey' | 'apiUrl'>): Promise<OpenComputerNativeSandbox>;\n createFromCheckpoint(checkpointId: string, opts?: Pick<OpenComputerSandboxOpts, 'apiKey' | 'apiUrl' | 'timeout' | 'envs' | 'secretStore'>): Promise<OpenComputerNativeSandbox>;\n}\n\nlet _SandboxClass: OpenComputerSandboxStatic | null = null;\n\nasync function loadSandbox(): Promise<OpenComputerSandboxStatic> {\n if (!_SandboxClass) {\n const mod = await import('@opencomputer/sdk');\n _SandboxClass = (mod as { Sandbox: OpenComputerSandboxStatic }).Sandbox;\n }\n return _SandboxClass;\n}\n\nexport interface OpenComputerConfig {\n /** OpenComputer API key - falls back to OPENCOMPUTER_API_KEY. */\n apiKey?: string;\n /** OpenComputer API URL - falls back to OPENCOMPUTER_API_URL, then production. */\n apiUrl?: string;\n /** Default template for new sandboxes. Defaults to OpenComputer's `base` template. */\n template?: string;\n /** Default idle timeout in milliseconds. OpenComputer receives this as seconds. */\n timeout?: number;\n /** Default environment variables for new sandboxes. */\n envs?: Record<string, string>;\n /** Default metadata for new sandboxes. */\n metadata?: Record<string, string>;\n /** OpenComputer CPU count for new sandboxes. */\n cpuCount?: number;\n /** OpenComputer memory size in MB for new sandboxes. */\n memoryMB?: number;\n /** OpenComputer workspace disk size in MB for new sandboxes. */\n diskMB?: number;\n /** Secret store to attach to new sandboxes. */\n secretStore?: string;\n /** Create Burst sandboxes by default. */\n burst?: boolean;\n /** Require bearer auth on preview URLs. */\n previewAuth?: { scheme?: 'bearer'; token?: 'auto' | string };\n}\n\nexport interface OpenComputerSnapshot {\n id: string;\n provider: 'opencomputer';\n createdAt: Date;\n metadata: {\n sandboxId?: string;\n orgId?: string;\n name?: string;\n status?: string;\n sizeBytes?: number;\n sandboxConfig?: Record<string, unknown>;\n };\n}\n\nfunction env(name: string): string | undefined {\n return typeof process !== 'undefined' ? process.env?.[name] : undefined;\n}\n\nfunction baseOpts(config: OpenComputerConfig): Pick<OpenComputerSandboxOpts, 'apiKey' | 'apiUrl'> {\n return {\n apiKey: config.apiKey || env('OPENCOMPUTER_API_KEY'),\n apiUrl: config.apiUrl || env('OPENCOMPUTER_API_URL'),\n };\n}\n\nfunction toSeconds(milliseconds: number | undefined): number | undefined {\n return milliseconds == null ? undefined : Math.ceil(milliseconds / 1000);\n}\n\nfunction stringifyMetadata(metadata: Record<string, unknown> | undefined): Record<string, string> | undefined {\n if (!metadata) return undefined;\n const out: Record<string, string> = {};\n for (const [key, value] of Object.entries(metadata)) {\n if (value == null || typeof value === 'function' || typeof value === 'symbol') {\n continue;\n }\n if (typeof value === 'string') {\n out[key] = value;\n continue;\n }\n if (typeof value === 'number' || typeof value === 'boolean' || typeof value === 'bigint') {\n out[key] = String(value);\n continue;\n }\n try {\n const serialized = JSON.stringify(value);\n if (serialized !== undefined) {\n out[key] = serialized;\n }\n } catch {\n // Skip metadata values that cannot be represented as JSON strings.\n }\n }\n return out;\n}\n\nfunction redactWebhooks(webhooks: OpenComputerNativeSandbox['webhooks']): Array<{ id: string; url: string; hasSecret: boolean }> | undefined {\n return webhooks?.map((webhook) => ({\n id: webhook.id,\n url: webhook.url,\n hasSecret: typeof webhook.secret === 'string' && webhook.secret.length > 0,\n }));\n}\n\nfunction createOpts(config: OpenComputerConfig, options?: CreateSandboxOptions): OpenComputerSandboxOpts {\n return {\n ...baseOpts(config),\n template: options?.templateId || config.template,\n timeout: toSeconds(options?.timeout ?? config.timeout),\n envs: { ...config.envs, ...options?.envs },\n metadata: { ...config.metadata, ...stringifyMetadata(options?.metadata) },\n cpuCount: (options as any)?.cpuCount ?? config.cpuCount,\n memoryMB: (options as any)?.memoryMB ?? (options as any)?.memory ?? config.memoryMB,\n diskMB: (options as any)?.diskMB ?? config.diskMB,\n secretStore: (options as any)?.secretStore ?? config.secretStore,\n burst: (options as any)?.burst ?? config.burst,\n sandboxFamily: (options as any)?.sandboxFamily,\n previewAuth: (options as any)?.previewAuth ?? config.previewAuth,\n webhooks: (options as any)?.webhooks,\n };\n}\n\nfunction snapshotToCompute(snapshot: OpenComputerCheckpointInfo): OpenComputerSnapshot {\n const id = snapshot.sandboxId ? `${snapshot.sandboxId}:${snapshot.id}` : snapshot.id;\n return {\n id,\n provider: 'opencomputer',\n createdAt: snapshot.createdAt ? new Date(snapshot.createdAt) : new Date(),\n metadata: {\n sandboxId: snapshot.sandboxId,\n orgId: snapshot.orgId,\n name: snapshot.name,\n status: snapshot.status,\n sizeBytes: snapshot.sizeBytes,\n sandboxConfig: snapshot.sandboxConfig,\n },\n };\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nasync function waitForCheckpointReady(\n sandbox: OpenComputerNativeSandbox,\n checkpoint: OpenComputerCheckpointInfo,\n timeoutMs = 300_000,\n): Promise<OpenComputerCheckpointInfo> {\n if (checkpoint.status === 'ready') return checkpoint;\n if (checkpoint.status === 'failed') {\n throw new Error(`OpenComputer checkpoint ${checkpoint.id} failed.`);\n }\n\n const deadline = Date.now() + timeoutMs;\n let delay = 1_000;\n\n for (;;) {\n if (Date.now() >= deadline) {\n throw new Error(`OpenComputer checkpoint ${checkpoint.id} was not ready after ${timeoutMs}ms.`);\n }\n\n const checkpoints = await sandbox.listCheckpoints();\n const current = checkpoints.find((candidate) => candidate.id === checkpoint.id);\n if (!current) {\n throw new Error(`OpenComputer checkpoint ${checkpoint.id} disappeared while waiting for readiness.`);\n }\n if (current.status === 'ready') return current;\n if (current.status === 'failed') {\n throw new Error(`OpenComputer checkpoint ${checkpoint.id} failed.`);\n }\n\n await sleep(delay);\n delay = Math.min(delay * 1.5, 5_000);\n }\n}\n\nfunction isCheckpointIndexMiss(error: unknown): boolean {\n if (!(error instanceof Error)) return false;\n const message = error.message.toLowerCase();\n return message.includes('404') && message.includes('checkpoint') && message.includes('not found');\n}\n\nasync function createFromCheckpointWithRetry(\n Sandbox: OpenComputerSandboxStatic,\n checkpointId: string,\n opts: Pick<OpenComputerSandboxOpts, 'apiKey' | 'apiUrl' | 'timeout' | 'envs' | 'secretStore'>,\n timeoutMs = 60_000,\n): Promise<OpenComputerNativeSandbox> {\n const deadline = Date.now() + timeoutMs;\n let delay = 1_000;\n\n for (;;) {\n try {\n return await Sandbox.createFromCheckpoint(checkpointId, opts);\n } catch (error) {\n if (!isCheckpointIndexMiss(error) || Date.now() >= deadline) {\n throw error;\n }\n await sleep(delay);\n delay = Math.min(delay * 1.5, 5_000);\n }\n }\n}\n\nasync function createSandbox(config: OpenComputerConfig, options?: CreateSandboxOptions) {\n const Sandbox = await loadSandbox();\n const opts = createOpts(config, options);\n\n if (options?.snapshotId) {\n const checkpointId = options.snapshotId.includes(':')\n ? options.snapshotId.slice(options.snapshotId.indexOf(':') + 1)\n : options.snapshotId;\n const sandbox = await createFromCheckpointWithRetry(Sandbox, checkpointId, {\n ...baseOpts(config),\n timeout: opts.timeout,\n envs: opts.envs,\n secretStore: opts.secretStore,\n });\n return { sandbox, sandboxId: sandbox.sandboxId || sandbox.id };\n }\n\n const sandbox = await Sandbox.create(opts);\n return { sandbox, sandboxId: sandbox.sandboxId || sandbox.id };\n}\n\nconst _provider = defineProvider<OpenComputerNativeSandbox, OpenComputerConfig, any, OpenComputerSnapshot>({\n name: 'opencomputer',\n methods: {\n sandbox: {\n create: createSandbox,\n\n getById: async (config: OpenComputerConfig, sandboxId: string) => {\n const Sandbox = await loadSandbox();\n try {\n const sandbox = await Sandbox.connect(sandboxId, baseOpts(config));\n return { sandbox, sandboxId: sandbox.sandboxId || sandbox.id || sandboxId };\n } catch (error) {\n if (error instanceof Error && (error.message.includes('404') || error.message.includes('not found'))) {\n return null;\n }\n throw new Error(`Failed to get OpenComputer sandbox ${sandboxId}: ${error instanceof Error ? error.message : String(error)}`);\n }\n },\n\n list: async () => {\n throw new Error('OpenComputer provider does not support listing sandboxes via the TypeScript SDK.');\n },\n\n destroy: async (config: OpenComputerConfig, sandboxId: string) => {\n const Sandbox = await loadSandbox();\n try {\n const sandbox = await Sandbox.connect(sandboxId, baseOpts(config));\n await sandbox.kill();\n } catch (error) {\n if (error instanceof Error && (error.message.includes('404') || error.message.includes('not found'))) {\n return;\n }\n throw new Error(`Failed to destroy OpenComputer sandbox ${sandboxId}: ${error instanceof Error ? error.message : String(error)}`);\n }\n },\n\n runCommand: async (sandbox: OpenComputerNativeSandbox, command: string, options?: RunCommandOptions): Promise<CommandResult> => {\n const startTime = Date.now();\n try {\n const runOptions = {\n cwd: options?.cwd,\n env: options?.env,\n timeout: toSeconds(options?.timeout),\n timeoutMs: options?.timeout,\n };\n if (options?.background && sandbox.exec?.background) {\n const session = await sandbox.exec.background(command, runOptions);\n return {\n stdout: session.sessionId,\n stderr: '',\n exitCode: 0,\n durationMs: Date.now() - startTime,\n };\n }\n\n const result = await (sandbox.exec ?? sandbox.commands).run(command, runOptions);\n return {\n stdout: result.stdout || '',\n stderr: result.stderr || '',\n exitCode: result.exitCode ?? 0,\n durationMs: Date.now() - startTime,\n };\n } catch (error) {\n throw new Error(`OpenComputer command execution failed: ${error instanceof Error ? error.message : String(error)}`);\n }\n },\n\n getInfo: async (sandbox: OpenComputerNativeSandbox): Promise<SandboxInfo> => {\n let status = sandbox.status;\n try {\n status = (await sandbox.isRunning()) ? 'running' : sandbox.status;\n } catch {\n status = sandbox.status;\n }\n\n return {\n id: sandbox.sandboxId || sandbox.id,\n provider: 'opencomputer',\n status: status === 'running' ? 'running' : status === 'error' ? 'error' : 'stopped',\n createdAt: new Date(),\n timeout: 0,\n metadata: {\n opencomputerSandboxId: sandbox.sandboxId || sandbox.id,\n previewAuthEnabled: Boolean(sandbox.previewAuthToken),\n webhooks: redactWebhooks(sandbox.webhooks),\n },\n };\n },\n\n getUrl: async (sandbox: OpenComputerNativeSandbox, options: { port: number; protocol?: string }): Promise<string> => {\n const protocol = options.protocol || 'https';\n const domain = sandbox.getPreviewDomain(options.port);\n if (domain) {\n return `${protocol}://${domain}`;\n }\n\n const preview = await sandbox.createPreviewURL({ port: options.port });\n const hostname = preview.customHostname || preview.hostname;\n if (!hostname) {\n throw new Error(`OpenComputer did not return a preview hostname for port ${options.port}.`);\n }\n return `${protocol}://${hostname}`;\n },\n\n filesystem: {\n readFile: async (sandbox: OpenComputerNativeSandbox, path: string): Promise<string> =>\n sandbox.files.read(path),\n writeFile: async (sandbox: OpenComputerNativeSandbox, path: string, content: string): Promise<void> => {\n await sandbox.files.write(path, content);\n },\n mkdir: async (sandbox: OpenComputerNativeSandbox, path: string): Promise<void> => {\n await sandbox.files.makeDir(path);\n },\n readdir: async (sandbox: OpenComputerNativeSandbox, path: string): Promise<FileEntry[]> => {\n const entries = await sandbox.files.list(path);\n return entries.map((entry) => ({\n name: entry.name,\n type: entry.isDir ? 'directory' as const : 'file' as const,\n size: entry.size,\n modified: new Date(),\n }));\n },\n exists: async (sandbox: OpenComputerNativeSandbox, path: string): Promise<boolean> =>\n sandbox.files.exists(path),\n remove: async (sandbox: OpenComputerNativeSandbox, path: string): Promise<void> => {\n await sandbox.files.remove(path);\n },\n },\n\n getInstance: (sandbox: OpenComputerNativeSandbox): OpenComputerNativeSandbox => sandbox,\n },\n\n snapshot: {\n create: async (config: OpenComputerConfig, sandboxId: string, options?: CreateSnapshotOptions) => {\n const Sandbox = await loadSandbox();\n const sandbox = await Sandbox.connect(sandboxId, baseOpts(config));\n const metadata = options?.metadata as\n | { kind?: 'full' | 'disk_only'; promoteToFull?: boolean; retentionPolicy?: unknown }\n | undefined;\n const kind = metadata?.kind ?? 'disk_only';\n const snapshot = await sandbox.createCheckpoint(options?.name || `snapshot-${Date.now()}`, {\n kind,\n promoteToFull: metadata?.promoteToFull ?? (kind === 'disk_only' ? true : undefined),\n retentionPolicy: metadata?.retentionPolicy,\n });\n return snapshotToCompute(await waitForCheckpointReady(sandbox, snapshot));\n },\n list: async (config: OpenComputerConfig, options?: ListSnapshotsOptions) => {\n if (!options?.sandboxId) {\n throw new Error('OpenComputer snapshots are scoped to a sandbox. Pass `sandboxId` to list snapshots.');\n }\n const Sandbox = await loadSandbox();\n const sandbox = await Sandbox.connect(options.sandboxId, baseOpts(config));\n const snapshots = await sandbox.listCheckpoints();\n return snapshots.map(snapshotToCompute);\n },\n delete: async (config: OpenComputerConfig, snapshotId: string) => {\n const sandboxId = snapshotId.split(':', 1)[0];\n if (!sandboxId || sandboxId === snapshotId) {\n throw new Error('OpenComputer snapshot deletion requires a sandbox-scoped id in the form `sandboxId:checkpointId`.');\n }\n const checkpointId = snapshotId.slice(sandboxId.length + 1);\n const Sandbox = await loadSandbox();\n const sandbox = await Sandbox.connect(sandboxId, baseOpts(config));\n await sandbox.deleteCheckpoint(checkpointId);\n },\n },\n },\n});\n\nexport const opencomputer = (config: OpenComputerConfig = {}) => _provider(config);\nexport type { OpenComputerNativeSandbox };\n"],"mappings":"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","names":["sandbox"]}
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,308 @@
|
|
|
1
|
+
// src/index.ts
|
|
2
|
+
import { defineProvider } from "@computesdk/provider";
|
|
3
|
+
var _SandboxClass = null;
|
|
4
|
+
async function loadSandbox() {
|
|
5
|
+
if (!_SandboxClass) {
|
|
6
|
+
const mod = await import("@opencomputer/sdk");
|
|
7
|
+
_SandboxClass = mod.Sandbox;
|
|
8
|
+
}
|
|
9
|
+
return _SandboxClass;
|
|
10
|
+
}
|
|
11
|
+
function env(name) {
|
|
12
|
+
return typeof process !== "undefined" ? process.env?.[name] : void 0;
|
|
13
|
+
}
|
|
14
|
+
function baseOpts(config) {
|
|
15
|
+
return {
|
|
16
|
+
apiKey: config.apiKey || env("OPENCOMPUTER_API_KEY"),
|
|
17
|
+
apiUrl: config.apiUrl || env("OPENCOMPUTER_API_URL")
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
function toSeconds(milliseconds) {
|
|
21
|
+
return milliseconds == null ? void 0 : Math.ceil(milliseconds / 1e3);
|
|
22
|
+
}
|
|
23
|
+
function stringifyMetadata(metadata) {
|
|
24
|
+
if (!metadata) return void 0;
|
|
25
|
+
const out = {};
|
|
26
|
+
for (const [key, value] of Object.entries(metadata)) {
|
|
27
|
+
if (value == null || typeof value === "function" || typeof value === "symbol") {
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
30
|
+
if (typeof value === "string") {
|
|
31
|
+
out[key] = value;
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
if (typeof value === "number" || typeof value === "boolean" || typeof value === "bigint") {
|
|
35
|
+
out[key] = String(value);
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
try {
|
|
39
|
+
const serialized = JSON.stringify(value);
|
|
40
|
+
if (serialized !== void 0) {
|
|
41
|
+
out[key] = serialized;
|
|
42
|
+
}
|
|
43
|
+
} catch {
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return out;
|
|
47
|
+
}
|
|
48
|
+
function redactWebhooks(webhooks) {
|
|
49
|
+
return webhooks?.map((webhook) => ({
|
|
50
|
+
id: webhook.id,
|
|
51
|
+
url: webhook.url,
|
|
52
|
+
hasSecret: typeof webhook.secret === "string" && webhook.secret.length > 0
|
|
53
|
+
}));
|
|
54
|
+
}
|
|
55
|
+
function createOpts(config, options) {
|
|
56
|
+
return {
|
|
57
|
+
...baseOpts(config),
|
|
58
|
+
template: options?.templateId || config.template,
|
|
59
|
+
timeout: toSeconds(options?.timeout ?? config.timeout),
|
|
60
|
+
envs: { ...config.envs, ...options?.envs },
|
|
61
|
+
metadata: { ...config.metadata, ...stringifyMetadata(options?.metadata) },
|
|
62
|
+
cpuCount: options?.cpuCount ?? config.cpuCount,
|
|
63
|
+
memoryMB: options?.memoryMB ?? options?.memory ?? config.memoryMB,
|
|
64
|
+
diskMB: options?.diskMB ?? config.diskMB,
|
|
65
|
+
secretStore: options?.secretStore ?? config.secretStore,
|
|
66
|
+
burst: options?.burst ?? config.burst,
|
|
67
|
+
sandboxFamily: options?.sandboxFamily,
|
|
68
|
+
previewAuth: options?.previewAuth ?? config.previewAuth,
|
|
69
|
+
webhooks: options?.webhooks
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
function snapshotToCompute(snapshot) {
|
|
73
|
+
const id = snapshot.sandboxId ? `${snapshot.sandboxId}:${snapshot.id}` : snapshot.id;
|
|
74
|
+
return {
|
|
75
|
+
id,
|
|
76
|
+
provider: "opencomputer",
|
|
77
|
+
createdAt: snapshot.createdAt ? new Date(snapshot.createdAt) : /* @__PURE__ */ new Date(),
|
|
78
|
+
metadata: {
|
|
79
|
+
sandboxId: snapshot.sandboxId,
|
|
80
|
+
orgId: snapshot.orgId,
|
|
81
|
+
name: snapshot.name,
|
|
82
|
+
status: snapshot.status,
|
|
83
|
+
sizeBytes: snapshot.sizeBytes,
|
|
84
|
+
sandboxConfig: snapshot.sandboxConfig
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
function sleep(ms) {
|
|
89
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
90
|
+
}
|
|
91
|
+
async function waitForCheckpointReady(sandbox, checkpoint, timeoutMs = 3e5) {
|
|
92
|
+
if (checkpoint.status === "ready") return checkpoint;
|
|
93
|
+
if (checkpoint.status === "failed") {
|
|
94
|
+
throw new Error(`OpenComputer checkpoint ${checkpoint.id} failed.`);
|
|
95
|
+
}
|
|
96
|
+
const deadline = Date.now() + timeoutMs;
|
|
97
|
+
let delay = 1e3;
|
|
98
|
+
for (; ; ) {
|
|
99
|
+
if (Date.now() >= deadline) {
|
|
100
|
+
throw new Error(`OpenComputer checkpoint ${checkpoint.id} was not ready after ${timeoutMs}ms.`);
|
|
101
|
+
}
|
|
102
|
+
const checkpoints = await sandbox.listCheckpoints();
|
|
103
|
+
const current = checkpoints.find((candidate) => candidate.id === checkpoint.id);
|
|
104
|
+
if (!current) {
|
|
105
|
+
throw new Error(`OpenComputer checkpoint ${checkpoint.id} disappeared while waiting for readiness.`);
|
|
106
|
+
}
|
|
107
|
+
if (current.status === "ready") return current;
|
|
108
|
+
if (current.status === "failed") {
|
|
109
|
+
throw new Error(`OpenComputer checkpoint ${checkpoint.id} failed.`);
|
|
110
|
+
}
|
|
111
|
+
await sleep(delay);
|
|
112
|
+
delay = Math.min(delay * 1.5, 5e3);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
function isCheckpointIndexMiss(error) {
|
|
116
|
+
if (!(error instanceof Error)) return false;
|
|
117
|
+
const message = error.message.toLowerCase();
|
|
118
|
+
return message.includes("404") && message.includes("checkpoint") && message.includes("not found");
|
|
119
|
+
}
|
|
120
|
+
async function createFromCheckpointWithRetry(Sandbox, checkpointId, opts, timeoutMs = 6e4) {
|
|
121
|
+
const deadline = Date.now() + timeoutMs;
|
|
122
|
+
let delay = 1e3;
|
|
123
|
+
for (; ; ) {
|
|
124
|
+
try {
|
|
125
|
+
return await Sandbox.createFromCheckpoint(checkpointId, opts);
|
|
126
|
+
} catch (error) {
|
|
127
|
+
if (!isCheckpointIndexMiss(error) || Date.now() >= deadline) {
|
|
128
|
+
throw error;
|
|
129
|
+
}
|
|
130
|
+
await sleep(delay);
|
|
131
|
+
delay = Math.min(delay * 1.5, 5e3);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
async function createSandbox(config, options) {
|
|
136
|
+
const Sandbox = await loadSandbox();
|
|
137
|
+
const opts = createOpts(config, options);
|
|
138
|
+
if (options?.snapshotId) {
|
|
139
|
+
const checkpointId = options.snapshotId.includes(":") ? options.snapshotId.slice(options.snapshotId.indexOf(":") + 1) : options.snapshotId;
|
|
140
|
+
const sandbox2 = await createFromCheckpointWithRetry(Sandbox, checkpointId, {
|
|
141
|
+
...baseOpts(config),
|
|
142
|
+
timeout: opts.timeout,
|
|
143
|
+
envs: opts.envs,
|
|
144
|
+
secretStore: opts.secretStore
|
|
145
|
+
});
|
|
146
|
+
return { sandbox: sandbox2, sandboxId: sandbox2.sandboxId || sandbox2.id };
|
|
147
|
+
}
|
|
148
|
+
const sandbox = await Sandbox.create(opts);
|
|
149
|
+
return { sandbox, sandboxId: sandbox.sandboxId || sandbox.id };
|
|
150
|
+
}
|
|
151
|
+
var _provider = defineProvider({
|
|
152
|
+
name: "opencomputer",
|
|
153
|
+
methods: {
|
|
154
|
+
sandbox: {
|
|
155
|
+
create: createSandbox,
|
|
156
|
+
getById: async (config, sandboxId) => {
|
|
157
|
+
const Sandbox = await loadSandbox();
|
|
158
|
+
try {
|
|
159
|
+
const sandbox = await Sandbox.connect(sandboxId, baseOpts(config));
|
|
160
|
+
return { sandbox, sandboxId: sandbox.sandboxId || sandbox.id || sandboxId };
|
|
161
|
+
} catch (error) {
|
|
162
|
+
if (error instanceof Error && (error.message.includes("404") || error.message.includes("not found"))) {
|
|
163
|
+
return null;
|
|
164
|
+
}
|
|
165
|
+
throw new Error(`Failed to get OpenComputer sandbox ${sandboxId}: ${error instanceof Error ? error.message : String(error)}`);
|
|
166
|
+
}
|
|
167
|
+
},
|
|
168
|
+
list: async () => {
|
|
169
|
+
throw new Error("OpenComputer provider does not support listing sandboxes via the TypeScript SDK.");
|
|
170
|
+
},
|
|
171
|
+
destroy: async (config, sandboxId) => {
|
|
172
|
+
const Sandbox = await loadSandbox();
|
|
173
|
+
try {
|
|
174
|
+
const sandbox = await Sandbox.connect(sandboxId, baseOpts(config));
|
|
175
|
+
await sandbox.kill();
|
|
176
|
+
} catch (error) {
|
|
177
|
+
if (error instanceof Error && (error.message.includes("404") || error.message.includes("not found"))) {
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
throw new Error(`Failed to destroy OpenComputer sandbox ${sandboxId}: ${error instanceof Error ? error.message : String(error)}`);
|
|
181
|
+
}
|
|
182
|
+
},
|
|
183
|
+
runCommand: async (sandbox, command, options) => {
|
|
184
|
+
const startTime = Date.now();
|
|
185
|
+
try {
|
|
186
|
+
const runOptions = {
|
|
187
|
+
cwd: options?.cwd,
|
|
188
|
+
env: options?.env,
|
|
189
|
+
timeout: toSeconds(options?.timeout),
|
|
190
|
+
timeoutMs: options?.timeout
|
|
191
|
+
};
|
|
192
|
+
if (options?.background && sandbox.exec?.background) {
|
|
193
|
+
const session = await sandbox.exec.background(command, runOptions);
|
|
194
|
+
return {
|
|
195
|
+
stdout: session.sessionId,
|
|
196
|
+
stderr: "",
|
|
197
|
+
exitCode: 0,
|
|
198
|
+
durationMs: Date.now() - startTime
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
const result = await (sandbox.exec ?? sandbox.commands).run(command, runOptions);
|
|
202
|
+
return {
|
|
203
|
+
stdout: result.stdout || "",
|
|
204
|
+
stderr: result.stderr || "",
|
|
205
|
+
exitCode: result.exitCode ?? 0,
|
|
206
|
+
durationMs: Date.now() - startTime
|
|
207
|
+
};
|
|
208
|
+
} catch (error) {
|
|
209
|
+
throw new Error(`OpenComputer command execution failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
210
|
+
}
|
|
211
|
+
},
|
|
212
|
+
getInfo: async (sandbox) => {
|
|
213
|
+
let status = sandbox.status;
|
|
214
|
+
try {
|
|
215
|
+
status = await sandbox.isRunning() ? "running" : sandbox.status;
|
|
216
|
+
} catch {
|
|
217
|
+
status = sandbox.status;
|
|
218
|
+
}
|
|
219
|
+
return {
|
|
220
|
+
id: sandbox.sandboxId || sandbox.id,
|
|
221
|
+
provider: "opencomputer",
|
|
222
|
+
status: status === "running" ? "running" : status === "error" ? "error" : "stopped",
|
|
223
|
+
createdAt: /* @__PURE__ */ new Date(),
|
|
224
|
+
timeout: 0,
|
|
225
|
+
metadata: {
|
|
226
|
+
opencomputerSandboxId: sandbox.sandboxId || sandbox.id,
|
|
227
|
+
previewAuthEnabled: Boolean(sandbox.previewAuthToken),
|
|
228
|
+
webhooks: redactWebhooks(sandbox.webhooks)
|
|
229
|
+
}
|
|
230
|
+
};
|
|
231
|
+
},
|
|
232
|
+
getUrl: async (sandbox, options) => {
|
|
233
|
+
const protocol = options.protocol || "https";
|
|
234
|
+
const domain = sandbox.getPreviewDomain(options.port);
|
|
235
|
+
if (domain) {
|
|
236
|
+
return `${protocol}://${domain}`;
|
|
237
|
+
}
|
|
238
|
+
const preview = await sandbox.createPreviewURL({ port: options.port });
|
|
239
|
+
const hostname = preview.customHostname || preview.hostname;
|
|
240
|
+
if (!hostname) {
|
|
241
|
+
throw new Error(`OpenComputer did not return a preview hostname for port ${options.port}.`);
|
|
242
|
+
}
|
|
243
|
+
return `${protocol}://${hostname}`;
|
|
244
|
+
},
|
|
245
|
+
filesystem: {
|
|
246
|
+
readFile: async (sandbox, path) => sandbox.files.read(path),
|
|
247
|
+
writeFile: async (sandbox, path, content) => {
|
|
248
|
+
await sandbox.files.write(path, content);
|
|
249
|
+
},
|
|
250
|
+
mkdir: async (sandbox, path) => {
|
|
251
|
+
await sandbox.files.makeDir(path);
|
|
252
|
+
},
|
|
253
|
+
readdir: async (sandbox, path) => {
|
|
254
|
+
const entries = await sandbox.files.list(path);
|
|
255
|
+
return entries.map((entry) => ({
|
|
256
|
+
name: entry.name,
|
|
257
|
+
type: entry.isDir ? "directory" : "file",
|
|
258
|
+
size: entry.size,
|
|
259
|
+
modified: /* @__PURE__ */ new Date()
|
|
260
|
+
}));
|
|
261
|
+
},
|
|
262
|
+
exists: async (sandbox, path) => sandbox.files.exists(path),
|
|
263
|
+
remove: async (sandbox, path) => {
|
|
264
|
+
await sandbox.files.remove(path);
|
|
265
|
+
}
|
|
266
|
+
},
|
|
267
|
+
getInstance: (sandbox) => sandbox
|
|
268
|
+
},
|
|
269
|
+
snapshot: {
|
|
270
|
+
create: async (config, sandboxId, options) => {
|
|
271
|
+
const Sandbox = await loadSandbox();
|
|
272
|
+
const sandbox = await Sandbox.connect(sandboxId, baseOpts(config));
|
|
273
|
+
const metadata = options?.metadata;
|
|
274
|
+
const kind = metadata?.kind ?? "disk_only";
|
|
275
|
+
const snapshot = await sandbox.createCheckpoint(options?.name || `snapshot-${Date.now()}`, {
|
|
276
|
+
kind,
|
|
277
|
+
promoteToFull: metadata?.promoteToFull ?? (kind === "disk_only" ? true : void 0),
|
|
278
|
+
retentionPolicy: metadata?.retentionPolicy
|
|
279
|
+
});
|
|
280
|
+
return snapshotToCompute(await waitForCheckpointReady(sandbox, snapshot));
|
|
281
|
+
},
|
|
282
|
+
list: async (config, options) => {
|
|
283
|
+
if (!options?.sandboxId) {
|
|
284
|
+
throw new Error("OpenComputer snapshots are scoped to a sandbox. Pass `sandboxId` to list snapshots.");
|
|
285
|
+
}
|
|
286
|
+
const Sandbox = await loadSandbox();
|
|
287
|
+
const sandbox = await Sandbox.connect(options.sandboxId, baseOpts(config));
|
|
288
|
+
const snapshots = await sandbox.listCheckpoints();
|
|
289
|
+
return snapshots.map(snapshotToCompute);
|
|
290
|
+
},
|
|
291
|
+
delete: async (config, snapshotId) => {
|
|
292
|
+
const sandboxId = snapshotId.split(":", 1)[0];
|
|
293
|
+
if (!sandboxId || sandboxId === snapshotId) {
|
|
294
|
+
throw new Error("OpenComputer snapshot deletion requires a sandbox-scoped id in the form `sandboxId:checkpointId`.");
|
|
295
|
+
}
|
|
296
|
+
const checkpointId = snapshotId.slice(sandboxId.length + 1);
|
|
297
|
+
const Sandbox = await loadSandbox();
|
|
298
|
+
const sandbox = await Sandbox.connect(sandboxId, baseOpts(config));
|
|
299
|
+
await sandbox.deleteCheckpoint(checkpointId);
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
});
|
|
304
|
+
var opencomputer = (config = {}) => _provider(config);
|
|
305
|
+
export {
|
|
306
|
+
opencomputer
|
|
307
|
+
};
|
|
308
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * OpenComputer Provider - Factory-based Implementation\n *\n * Wraps the official `@opencomputer/sdk` so OpenComputer sandboxes can be used\n * through the ComputeSDK provider interface.\n */\n\nimport { defineProvider } from '@computesdk/provider';\n\nimport type {\n CommandResult,\n CreateSandboxOptions,\n CreateSnapshotOptions,\n FileEntry,\n ListSnapshotsOptions,\n RunCommandOptions,\n SandboxInfo,\n} from '@computesdk/provider';\n\ninterface OpenComputerSandboxOpts {\n template?: string;\n timeout?: number;\n apiKey?: string;\n apiUrl?: string;\n envs?: Record<string, string>;\n metadata?: Record<string, string>;\n cpuCount?: number;\n memoryMB?: number;\n diskMB?: number;\n secretStore?: string;\n snapshot?: string;\n burst?: boolean;\n sandboxFamily?: 'spot';\n previewAuth?: { scheme?: 'bearer'; token?: 'auto' | string };\n webhooks?: Array<{ url: string; secret?: string; eventTypes?: string[] }>;\n}\n\ninterface OpenComputerProcessResult {\n stdout?: string;\n stderr?: string;\n exitCode?: number;\n}\n\ninterface OpenComputerExecSession {\n sessionId: string;\n}\n\ninterface OpenComputerEntryInfo {\n name: string;\n isDir: boolean;\n path: string;\n size: number;\n}\n\ninterface OpenComputerCheckpointInfo {\n id: string;\n sandboxId?: string;\n orgId?: string;\n name?: string;\n status?: string;\n sizeBytes?: number;\n createdAt?: string;\n sandboxConfig?: Record<string, unknown>;\n}\n\ninterface OpenComputerPreviewURLResult {\n hostname?: string;\n customHostname?: string;\n port: number;\n}\n\ninterface OpenComputerNativeSandbox {\n readonly sandboxId: string;\n readonly id: string;\n readonly status: string;\n readonly previewAuthToken?: string;\n readonly webhooks?: Array<{ id: string; url: string; secret?: string }>;\n readonly commands: {\n run(command: string, opts?: { cwd?: string; env?: Record<string, string>; timeout?: number; timeoutMs?: number }): Promise<OpenComputerProcessResult>;\n };\n readonly exec?: {\n run(command: string, opts?: { cwd?: string; env?: Record<string, string>; timeout?: number; timeoutMs?: number }): Promise<OpenComputerProcessResult>;\n background?(command: string, opts?: { cwd?: string; env?: Record<string, string>; timeout?: number; timeoutMs?: number }): Promise<OpenComputerExecSession>;\n };\n readonly files: {\n read(path: string): Promise<string>;\n write(path: string, content: string): Promise<void>;\n makeDir(path: string): Promise<void>;\n list(path?: string): Promise<OpenComputerEntryInfo[]>;\n exists(path: string): Promise<boolean>;\n remove(path: string): Promise<void>;\n };\n getPreviewDomain(port: number): string;\n createPreviewURL(opts: { port: number; domain?: string; authConfig?: Record<string, unknown> }): Promise<OpenComputerPreviewURLResult>;\n listPreviewURLs(): Promise<OpenComputerPreviewURLResult[]>;\n kill(): Promise<void>;\n isRunning(): Promise<boolean>;\n createCheckpoint(name: string, opts?: { kind?: 'full' | 'disk_only'; promoteToFull?: boolean; retentionPolicy?: unknown }): Promise<OpenComputerCheckpointInfo>;\n listCheckpoints(): Promise<OpenComputerCheckpointInfo[]>;\n deleteCheckpoint(checkpointId: string): Promise<void>;\n}\n\ninterface OpenComputerSandboxStatic {\n create(opts?: OpenComputerSandboxOpts): Promise<OpenComputerNativeSandbox>;\n connect(sandboxId: string, opts?: Pick<OpenComputerSandboxOpts, 'apiKey' | 'apiUrl'>): Promise<OpenComputerNativeSandbox>;\n createFromCheckpoint(checkpointId: string, opts?: Pick<OpenComputerSandboxOpts, 'apiKey' | 'apiUrl' | 'timeout' | 'envs' | 'secretStore'>): Promise<OpenComputerNativeSandbox>;\n}\n\nlet _SandboxClass: OpenComputerSandboxStatic | null = null;\n\nasync function loadSandbox(): Promise<OpenComputerSandboxStatic> {\n if (!_SandboxClass) {\n const mod = await import('@opencomputer/sdk');\n _SandboxClass = (mod as { Sandbox: OpenComputerSandboxStatic }).Sandbox;\n }\n return _SandboxClass;\n}\n\nexport interface OpenComputerConfig {\n /** OpenComputer API key - falls back to OPENCOMPUTER_API_KEY. */\n apiKey?: string;\n /** OpenComputer API URL - falls back to OPENCOMPUTER_API_URL, then production. */\n apiUrl?: string;\n /** Default template for new sandboxes. Defaults to OpenComputer's `base` template. */\n template?: string;\n /** Default idle timeout in milliseconds. OpenComputer receives this as seconds. */\n timeout?: number;\n /** Default environment variables for new sandboxes. */\n envs?: Record<string, string>;\n /** Default metadata for new sandboxes. */\n metadata?: Record<string, string>;\n /** OpenComputer CPU count for new sandboxes. */\n cpuCount?: number;\n /** OpenComputer memory size in MB for new sandboxes. */\n memoryMB?: number;\n /** OpenComputer workspace disk size in MB for new sandboxes. */\n diskMB?: number;\n /** Secret store to attach to new sandboxes. */\n secretStore?: string;\n /** Create Burst sandboxes by default. */\n burst?: boolean;\n /** Require bearer auth on preview URLs. */\n previewAuth?: { scheme?: 'bearer'; token?: 'auto' | string };\n}\n\nexport interface OpenComputerSnapshot {\n id: string;\n provider: 'opencomputer';\n createdAt: Date;\n metadata: {\n sandboxId?: string;\n orgId?: string;\n name?: string;\n status?: string;\n sizeBytes?: number;\n sandboxConfig?: Record<string, unknown>;\n };\n}\n\nfunction env(name: string): string | undefined {\n return typeof process !== 'undefined' ? process.env?.[name] : undefined;\n}\n\nfunction baseOpts(config: OpenComputerConfig): Pick<OpenComputerSandboxOpts, 'apiKey' | 'apiUrl'> {\n return {\n apiKey: config.apiKey || env('OPENCOMPUTER_API_KEY'),\n apiUrl: config.apiUrl || env('OPENCOMPUTER_API_URL'),\n };\n}\n\nfunction toSeconds(milliseconds: number | undefined): number | undefined {\n return milliseconds == null ? undefined : Math.ceil(milliseconds / 1000);\n}\n\nfunction stringifyMetadata(metadata: Record<string, unknown> | undefined): Record<string, string> | undefined {\n if (!metadata) return undefined;\n const out: Record<string, string> = {};\n for (const [key, value] of Object.entries(metadata)) {\n if (value == null || typeof value === 'function' || typeof value === 'symbol') {\n continue;\n }\n if (typeof value === 'string') {\n out[key] = value;\n continue;\n }\n if (typeof value === 'number' || typeof value === 'boolean' || typeof value === 'bigint') {\n out[key] = String(value);\n continue;\n }\n try {\n const serialized = JSON.stringify(value);\n if (serialized !== undefined) {\n out[key] = serialized;\n }\n } catch {\n // Skip metadata values that cannot be represented as JSON strings.\n }\n }\n return out;\n}\n\nfunction redactWebhooks(webhooks: OpenComputerNativeSandbox['webhooks']): Array<{ id: string; url: string; hasSecret: boolean }> | undefined {\n return webhooks?.map((webhook) => ({\n id: webhook.id,\n url: webhook.url,\n hasSecret: typeof webhook.secret === 'string' && webhook.secret.length > 0,\n }));\n}\n\nfunction createOpts(config: OpenComputerConfig, options?: CreateSandboxOptions): OpenComputerSandboxOpts {\n return {\n ...baseOpts(config),\n template: options?.templateId || config.template,\n timeout: toSeconds(options?.timeout ?? config.timeout),\n envs: { ...config.envs, ...options?.envs },\n metadata: { ...config.metadata, ...stringifyMetadata(options?.metadata) },\n cpuCount: (options as any)?.cpuCount ?? config.cpuCount,\n memoryMB: (options as any)?.memoryMB ?? (options as any)?.memory ?? config.memoryMB,\n diskMB: (options as any)?.diskMB ?? config.diskMB,\n secretStore: (options as any)?.secretStore ?? config.secretStore,\n burst: (options as any)?.burst ?? config.burst,\n sandboxFamily: (options as any)?.sandboxFamily,\n previewAuth: (options as any)?.previewAuth ?? config.previewAuth,\n webhooks: (options as any)?.webhooks,\n };\n}\n\nfunction snapshotToCompute(snapshot: OpenComputerCheckpointInfo): OpenComputerSnapshot {\n const id = snapshot.sandboxId ? `${snapshot.sandboxId}:${snapshot.id}` : snapshot.id;\n return {\n id,\n provider: 'opencomputer',\n createdAt: snapshot.createdAt ? new Date(snapshot.createdAt) : new Date(),\n metadata: {\n sandboxId: snapshot.sandboxId,\n orgId: snapshot.orgId,\n name: snapshot.name,\n status: snapshot.status,\n sizeBytes: snapshot.sizeBytes,\n sandboxConfig: snapshot.sandboxConfig,\n },\n };\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nasync function waitForCheckpointReady(\n sandbox: OpenComputerNativeSandbox,\n checkpoint: OpenComputerCheckpointInfo,\n timeoutMs = 300_000,\n): Promise<OpenComputerCheckpointInfo> {\n if (checkpoint.status === 'ready') return checkpoint;\n if (checkpoint.status === 'failed') {\n throw new Error(`OpenComputer checkpoint ${checkpoint.id} failed.`);\n }\n\n const deadline = Date.now() + timeoutMs;\n let delay = 1_000;\n\n for (;;) {\n if (Date.now() >= deadline) {\n throw new Error(`OpenComputer checkpoint ${checkpoint.id} was not ready after ${timeoutMs}ms.`);\n }\n\n const checkpoints = await sandbox.listCheckpoints();\n const current = checkpoints.find((candidate) => candidate.id === checkpoint.id);\n if (!current) {\n throw new Error(`OpenComputer checkpoint ${checkpoint.id} disappeared while waiting for readiness.`);\n }\n if (current.status === 'ready') return current;\n if (current.status === 'failed') {\n throw new Error(`OpenComputer checkpoint ${checkpoint.id} failed.`);\n }\n\n await sleep(delay);\n delay = Math.min(delay * 1.5, 5_000);\n }\n}\n\nfunction isCheckpointIndexMiss(error: unknown): boolean {\n if (!(error instanceof Error)) return false;\n const message = error.message.toLowerCase();\n return message.includes('404') && message.includes('checkpoint') && message.includes('not found');\n}\n\nasync function createFromCheckpointWithRetry(\n Sandbox: OpenComputerSandboxStatic,\n checkpointId: string,\n opts: Pick<OpenComputerSandboxOpts, 'apiKey' | 'apiUrl' | 'timeout' | 'envs' | 'secretStore'>,\n timeoutMs = 60_000,\n): Promise<OpenComputerNativeSandbox> {\n const deadline = Date.now() + timeoutMs;\n let delay = 1_000;\n\n for (;;) {\n try {\n return await Sandbox.createFromCheckpoint(checkpointId, opts);\n } catch (error) {\n if (!isCheckpointIndexMiss(error) || Date.now() >= deadline) {\n throw error;\n }\n await sleep(delay);\n delay = Math.min(delay * 1.5, 5_000);\n }\n }\n}\n\nasync function createSandbox(config: OpenComputerConfig, options?: CreateSandboxOptions) {\n const Sandbox = await loadSandbox();\n const opts = createOpts(config, options);\n\n if (options?.snapshotId) {\n const checkpointId = options.snapshotId.includes(':')\n ? options.snapshotId.slice(options.snapshotId.indexOf(':') + 1)\n : options.snapshotId;\n const sandbox = await createFromCheckpointWithRetry(Sandbox, checkpointId, {\n ...baseOpts(config),\n timeout: opts.timeout,\n envs: opts.envs,\n secretStore: opts.secretStore,\n });\n return { sandbox, sandboxId: sandbox.sandboxId || sandbox.id };\n }\n\n const sandbox = await Sandbox.create(opts);\n return { sandbox, sandboxId: sandbox.sandboxId || sandbox.id };\n}\n\nconst _provider = defineProvider<OpenComputerNativeSandbox, OpenComputerConfig, any, OpenComputerSnapshot>({\n name: 'opencomputer',\n methods: {\n sandbox: {\n create: createSandbox,\n\n getById: async (config: OpenComputerConfig, sandboxId: string) => {\n const Sandbox = await loadSandbox();\n try {\n const sandbox = await Sandbox.connect(sandboxId, baseOpts(config));\n return { sandbox, sandboxId: sandbox.sandboxId || sandbox.id || sandboxId };\n } catch (error) {\n if (error instanceof Error && (error.message.includes('404') || error.message.includes('not found'))) {\n return null;\n }\n throw new Error(`Failed to get OpenComputer sandbox ${sandboxId}: ${error instanceof Error ? error.message : String(error)}`);\n }\n },\n\n list: async () => {\n throw new Error('OpenComputer provider does not support listing sandboxes via the TypeScript SDK.');\n },\n\n destroy: async (config: OpenComputerConfig, sandboxId: string) => {\n const Sandbox = await loadSandbox();\n try {\n const sandbox = await Sandbox.connect(sandboxId, baseOpts(config));\n await sandbox.kill();\n } catch (error) {\n if (error instanceof Error && (error.message.includes('404') || error.message.includes('not found'))) {\n return;\n }\n throw new Error(`Failed to destroy OpenComputer sandbox ${sandboxId}: ${error instanceof Error ? error.message : String(error)}`);\n }\n },\n\n runCommand: async (sandbox: OpenComputerNativeSandbox, command: string, options?: RunCommandOptions): Promise<CommandResult> => {\n const startTime = Date.now();\n try {\n const runOptions = {\n cwd: options?.cwd,\n env: options?.env,\n timeout: toSeconds(options?.timeout),\n timeoutMs: options?.timeout,\n };\n if (options?.background && sandbox.exec?.background) {\n const session = await sandbox.exec.background(command, runOptions);\n return {\n stdout: session.sessionId,\n stderr: '',\n exitCode: 0,\n durationMs: Date.now() - startTime,\n };\n }\n\n const result = await (sandbox.exec ?? sandbox.commands).run(command, runOptions);\n return {\n stdout: result.stdout || '',\n stderr: result.stderr || '',\n exitCode: result.exitCode ?? 0,\n durationMs: Date.now() - startTime,\n };\n } catch (error) {\n throw new Error(`OpenComputer command execution failed: ${error instanceof Error ? error.message : String(error)}`);\n }\n },\n\n getInfo: async (sandbox: OpenComputerNativeSandbox): Promise<SandboxInfo> => {\n let status = sandbox.status;\n try {\n status = (await sandbox.isRunning()) ? 'running' : sandbox.status;\n } catch {\n status = sandbox.status;\n }\n\n return {\n id: sandbox.sandboxId || sandbox.id,\n provider: 'opencomputer',\n status: status === 'running' ? 'running' : status === 'error' ? 'error' : 'stopped',\n createdAt: new Date(),\n timeout: 0,\n metadata: {\n opencomputerSandboxId: sandbox.sandboxId || sandbox.id,\n previewAuthEnabled: Boolean(sandbox.previewAuthToken),\n webhooks: redactWebhooks(sandbox.webhooks),\n },\n };\n },\n\n getUrl: async (sandbox: OpenComputerNativeSandbox, options: { port: number; protocol?: string }): Promise<string> => {\n const protocol = options.protocol || 'https';\n const domain = sandbox.getPreviewDomain(options.port);\n if (domain) {\n return `${protocol}://${domain}`;\n }\n\n const preview = await sandbox.createPreviewURL({ port: options.port });\n const hostname = preview.customHostname || preview.hostname;\n if (!hostname) {\n throw new Error(`OpenComputer did not return a preview hostname for port ${options.port}.`);\n }\n return `${protocol}://${hostname}`;\n },\n\n filesystem: {\n readFile: async (sandbox: OpenComputerNativeSandbox, path: string): Promise<string> =>\n sandbox.files.read(path),\n writeFile: async (sandbox: OpenComputerNativeSandbox, path: string, content: string): Promise<void> => {\n await sandbox.files.write(path, content);\n },\n mkdir: async (sandbox: OpenComputerNativeSandbox, path: string): Promise<void> => {\n await sandbox.files.makeDir(path);\n },\n readdir: async (sandbox: OpenComputerNativeSandbox, path: string): Promise<FileEntry[]> => {\n const entries = await sandbox.files.list(path);\n return entries.map((entry) => ({\n name: entry.name,\n type: entry.isDir ? 'directory' as const : 'file' as const,\n size: entry.size,\n modified: new Date(),\n }));\n },\n exists: async (sandbox: OpenComputerNativeSandbox, path: string): Promise<boolean> =>\n sandbox.files.exists(path),\n remove: async (sandbox: OpenComputerNativeSandbox, path: string): Promise<void> => {\n await sandbox.files.remove(path);\n },\n },\n\n getInstance: (sandbox: OpenComputerNativeSandbox): OpenComputerNativeSandbox => sandbox,\n },\n\n snapshot: {\n create: async (config: OpenComputerConfig, sandboxId: string, options?: CreateSnapshotOptions) => {\n const Sandbox = await loadSandbox();\n const sandbox = await Sandbox.connect(sandboxId, baseOpts(config));\n const metadata = options?.metadata as\n | { kind?: 'full' | 'disk_only'; promoteToFull?: boolean; retentionPolicy?: unknown }\n | undefined;\n const kind = metadata?.kind ?? 'disk_only';\n const snapshot = await sandbox.createCheckpoint(options?.name || `snapshot-${Date.now()}`, {\n kind,\n promoteToFull: metadata?.promoteToFull ?? (kind === 'disk_only' ? true : undefined),\n retentionPolicy: metadata?.retentionPolicy,\n });\n return snapshotToCompute(await waitForCheckpointReady(sandbox, snapshot));\n },\n list: async (config: OpenComputerConfig, options?: ListSnapshotsOptions) => {\n if (!options?.sandboxId) {\n throw new Error('OpenComputer snapshots are scoped to a sandbox. Pass `sandboxId` to list snapshots.');\n }\n const Sandbox = await loadSandbox();\n const sandbox = await Sandbox.connect(options.sandboxId, baseOpts(config));\n const snapshots = await sandbox.listCheckpoints();\n return snapshots.map(snapshotToCompute);\n },\n delete: async (config: OpenComputerConfig, snapshotId: string) => {\n const sandboxId = snapshotId.split(':', 1)[0];\n if (!sandboxId || sandboxId === snapshotId) {\n throw new Error('OpenComputer snapshot deletion requires a sandbox-scoped id in the form `sandboxId:checkpointId`.');\n }\n const checkpointId = snapshotId.slice(sandboxId.length + 1);\n const Sandbox = await loadSandbox();\n const sandbox = await Sandbox.connect(sandboxId, baseOpts(config));\n await sandbox.deleteCheckpoint(checkpointId);\n },\n },\n },\n});\n\nexport const opencomputer = (config: OpenComputerConfig = {}) => _provider(config);\nexport type { OpenComputerNativeSandbox };\n"],"mappings":"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","names":["sandbox"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@computesdk/opencomputer",
|
|
3
|
+
"version": "1.0.1",
|
|
4
|
+
"description": "OpenComputer provider for ComputeSDK - persistent cloud VMs with checkpoints, preview URLs, command execution, and filesystem access",
|
|
5
|
+
"author": "ComputeSDK",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"main": "./dist/index.js",
|
|
8
|
+
"module": "./dist/index.mjs",
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"import": "./dist/index.mjs",
|
|
14
|
+
"require": "./dist/index.js"
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
"files": [
|
|
18
|
+
"dist"
|
|
19
|
+
],
|
|
20
|
+
"keywords": [
|
|
21
|
+
"computesdk",
|
|
22
|
+
"opencomputer",
|
|
23
|
+
"sandbox",
|
|
24
|
+
"checkpoint",
|
|
25
|
+
"code-execution",
|
|
26
|
+
"cloud",
|
|
27
|
+
"compute",
|
|
28
|
+
"provider"
|
|
29
|
+
],
|
|
30
|
+
"dependencies": {
|
|
31
|
+
"@opencomputer/sdk": "^0.12.4",
|
|
32
|
+
"@computesdk/provider": "2.1.4",
|
|
33
|
+
"computesdk": "4.1.4"
|
|
34
|
+
},
|
|
35
|
+
"devDependencies": {
|
|
36
|
+
"@types/node": "^20.0.0",
|
|
37
|
+
"@vitest/coverage-v8": "^1.0.0",
|
|
38
|
+
"eslint": "^8.37.0",
|
|
39
|
+
"rimraf": "^5.0.0",
|
|
40
|
+
"tsup": "^8.0.0",
|
|
41
|
+
"typescript": "^5.0.0",
|
|
42
|
+
"vitest": "^1.0.0",
|
|
43
|
+
"@computesdk/test-utils": "2.0.0"
|
|
44
|
+
},
|
|
45
|
+
"repository": {
|
|
46
|
+
"type": "git",
|
|
47
|
+
"url": "https://github.com/computesdk/computesdk.git",
|
|
48
|
+
"directory": "packages/opencomputer"
|
|
49
|
+
},
|
|
50
|
+
"homepage": "https://www.computesdk.com",
|
|
51
|
+
"bugs": {
|
|
52
|
+
"url": "https://github.com/computesdk/computesdk/issues"
|
|
53
|
+
},
|
|
54
|
+
"scripts": {
|
|
55
|
+
"build": "tsup",
|
|
56
|
+
"clean": "rimraf dist",
|
|
57
|
+
"dev": "tsup --watch",
|
|
58
|
+
"test": "vitest run",
|
|
59
|
+
"test:watch": "vitest watch",
|
|
60
|
+
"test:coverage": "vitest run --coverage",
|
|
61
|
+
"typecheck": "tsc --noEmit",
|
|
62
|
+
"lint": "eslint"
|
|
63
|
+
}
|
|
64
|
+
}
|