computesdk 2.0.0 → 2.0.2
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/README.md +512 -546
- package/dist/index.d.mts +4031 -551
- package/dist/index.d.ts +4031 -551
- package/dist/index.js +4368 -598
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +4337 -580
- package/dist/index.mjs.map +1 -1
- package/package.json +5 -8
package/dist/index.d.mts
CHANGED
|
@@ -1,41 +1,61 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Universal Sandbox Interface
|
|
3
3
|
*
|
|
4
|
-
*
|
|
4
|
+
* The canonical interface for all ComputeSDK sandboxes.
|
|
5
|
+
*
|
|
6
|
+
* Core methods (required):
|
|
7
|
+
* - runCode, runCommand, getInfo, getUrl, destroy, filesystem
|
|
8
|
+
*
|
|
9
|
+
* Advanced features (optional):
|
|
10
|
+
* - terminal, server, watcher, auth, env, etc.
|
|
11
|
+
*
|
|
12
|
+
* Providers can implement as much or as little as makes sense for their platform.
|
|
13
|
+
* The gateway Sandbox class implements the full specification.
|
|
14
|
+
*
|
|
15
|
+
* **Note on naming:** This interface is named "Sandbox" in this file for clarity,
|
|
16
|
+
* but is exported as "SandboxInterface" from the main computesdk package to avoid
|
|
17
|
+
* collision with the gateway Sandbox class. The rename happens at export time in
|
|
18
|
+
* src/index.ts. Providers using @computesdk/provider will only see "SandboxInterface".
|
|
19
|
+
*
|
|
20
|
+
* @example Minimal implementation
|
|
21
|
+
* ```typescript
|
|
22
|
+
* class MinimalSandbox implements Pick<Sandbox, 'sandboxId' | 'provider' | 'runCode' | 'runCommand' | 'getInfo' | 'getUrl' | 'destroy' | 'filesystem'> {
|
|
23
|
+
* // Just implement core methods
|
|
24
|
+
* }
|
|
25
|
+
* ```
|
|
26
|
+
*
|
|
27
|
+
* @example Full implementation
|
|
28
|
+
* ```typescript
|
|
29
|
+
* class FullSandbox implements Sandbox {
|
|
30
|
+
* // Implement everything - core + advanced features
|
|
31
|
+
* }
|
|
32
|
+
* ```
|
|
5
33
|
*/
|
|
6
34
|
/**
|
|
7
35
|
* Supported runtime environments
|
|
8
36
|
*/
|
|
9
|
-
type Runtime = 'node' | 'python';
|
|
10
|
-
/**
|
|
11
|
-
* Supported provider types
|
|
12
|
-
*/
|
|
13
|
-
type ProviderType = 'e2b' | 'vercel' | 'daytona' | 'auto';
|
|
37
|
+
type Runtime = 'node' | 'python' | 'deno' | 'bun';
|
|
14
38
|
/**
|
|
15
|
-
*
|
|
39
|
+
* Code execution result
|
|
16
40
|
*/
|
|
17
|
-
|
|
41
|
+
interface CodeResult$1 {
|
|
42
|
+
output: string;
|
|
43
|
+
exitCode: number;
|
|
44
|
+
language: string;
|
|
45
|
+
}
|
|
18
46
|
/**
|
|
19
|
-
*
|
|
47
|
+
* Command execution result
|
|
20
48
|
*/
|
|
21
|
-
interface
|
|
22
|
-
/** Standard output from the execution */
|
|
49
|
+
interface CommandResult$1 {
|
|
23
50
|
stdout: string;
|
|
24
|
-
/** Standard error from the execution */
|
|
25
51
|
stderr: string;
|
|
26
|
-
/** Exit code from the execution */
|
|
27
52
|
exitCode: number;
|
|
28
|
-
|
|
29
|
-
executionTime: number;
|
|
30
|
-
/** ID of the sandbox where the code was executed */
|
|
31
|
-
sandboxId: string;
|
|
32
|
-
/** Provider that executed the code */
|
|
33
|
-
provider: string;
|
|
53
|
+
durationMs: number;
|
|
34
54
|
}
|
|
35
55
|
/**
|
|
36
|
-
*
|
|
56
|
+
* Sandbox information
|
|
37
57
|
*/
|
|
38
|
-
interface SandboxInfo {
|
|
58
|
+
interface SandboxInfo$1 {
|
|
39
59
|
/** Unique identifier for the sandbox */
|
|
40
60
|
id: string;
|
|
41
61
|
/** Provider hosting the sandbox */
|
|
@@ -43,7 +63,7 @@ interface SandboxInfo {
|
|
|
43
63
|
/** Runtime environment in the sandbox */
|
|
44
64
|
runtime: Runtime;
|
|
45
65
|
/** Current status of the sandbox */
|
|
46
|
-
status:
|
|
66
|
+
status: 'running' | 'stopped' | 'error';
|
|
47
67
|
/** When the sandbox was created */
|
|
48
68
|
createdAt: Date;
|
|
49
69
|
/** Execution timeout in milliseconds */
|
|
@@ -52,665 +72,4125 @@ interface SandboxInfo {
|
|
|
52
72
|
metadata?: Record<string, any>;
|
|
53
73
|
}
|
|
54
74
|
/**
|
|
55
|
-
*
|
|
56
|
-
*/
|
|
57
|
-
interface ContainerConfig {
|
|
58
|
-
/** Docker image to use */
|
|
59
|
-
image: string;
|
|
60
|
-
/** Command to run in the container */
|
|
61
|
-
command?: string[];
|
|
62
|
-
/** Environment variables for the container */
|
|
63
|
-
env?: Record<string, string>;
|
|
64
|
-
/** Ports to expose from the container */
|
|
65
|
-
ports?: number[];
|
|
66
|
-
/** Working directory in the container */
|
|
67
|
-
workdir?: string;
|
|
68
|
-
}
|
|
69
|
-
/**
|
|
70
|
-
* Configuration for creating a compute sandbox
|
|
71
|
-
*/
|
|
72
|
-
interface SandboxConfig {
|
|
73
|
-
/** Provider to use for execution */
|
|
74
|
-
provider?: ProviderType;
|
|
75
|
-
/** Runtime environment to use */
|
|
76
|
-
runtime?: Runtime;
|
|
77
|
-
/** Container configuration if using container-based provider */
|
|
78
|
-
container?: string | ContainerConfig;
|
|
79
|
-
/** Execution timeout in milliseconds */
|
|
80
|
-
timeout?: number;
|
|
81
|
-
}
|
|
82
|
-
/**
|
|
83
|
-
* File system entry information
|
|
75
|
+
* File entry from directory listing
|
|
84
76
|
*/
|
|
85
77
|
interface FileEntry {
|
|
86
|
-
/** File/directory name */
|
|
87
78
|
name: string;
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
isDirectory: boolean;
|
|
92
|
-
/** File size in bytes (0 for directories) */
|
|
93
|
-
size: number;
|
|
94
|
-
/** Last modified timestamp */
|
|
95
|
-
lastModified: Date;
|
|
79
|
+
type: 'file' | 'directory';
|
|
80
|
+
size?: number;
|
|
81
|
+
modified?: Date;
|
|
96
82
|
}
|
|
97
83
|
/**
|
|
98
|
-
*
|
|
84
|
+
* Options for running a command
|
|
99
85
|
*/
|
|
100
|
-
interface
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
/** Terminal status */
|
|
106
|
-
status: 'running' | 'exited';
|
|
107
|
-
/** Exit code (if exited) */
|
|
108
|
-
exitCode?: number;
|
|
86
|
+
interface RunCommandOptions {
|
|
87
|
+
cwd?: string;
|
|
88
|
+
env?: Record<string, string>;
|
|
89
|
+
timeout?: number;
|
|
90
|
+
background?: boolean;
|
|
109
91
|
}
|
|
110
92
|
/**
|
|
111
|
-
*
|
|
93
|
+
* Filesystem operations interface
|
|
112
94
|
*/
|
|
113
95
|
interface SandboxFileSystem {
|
|
114
|
-
/** Read file contents */
|
|
115
96
|
readFile(path: string): Promise<string>;
|
|
116
|
-
/** Write file contents */
|
|
117
97
|
writeFile(path: string, content: string): Promise<void>;
|
|
118
|
-
/** Create directory */
|
|
119
|
-
mkdir(path: string): Promise<void>;
|
|
120
|
-
/** List directory contents */
|
|
121
98
|
readdir(path: string): Promise<FileEntry[]>;
|
|
122
|
-
|
|
99
|
+
mkdir(path: string): Promise<void>;
|
|
123
100
|
exists(path: string): Promise<boolean>;
|
|
124
|
-
/** Remove file or directory */
|
|
125
101
|
remove(path: string): Promise<void>;
|
|
126
102
|
}
|
|
127
103
|
/**
|
|
128
|
-
*
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
/** Create a new interactive terminal session */
|
|
132
|
-
create(options?: TerminalCreateOptions): Promise<InteractiveTerminalSession>;
|
|
133
|
-
/** List active terminal sessions */
|
|
134
|
-
list(): Promise<InteractiveTerminalSession[]>;
|
|
135
|
-
}
|
|
136
|
-
/**
|
|
137
|
-
* Base provider specification that all providers must implement
|
|
104
|
+
* Options for creating a sandbox
|
|
105
|
+
*
|
|
106
|
+
* Providers can extend this with additional properties specific to their implementation
|
|
138
107
|
*/
|
|
139
|
-
interface
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
runCommand(command: string, args?: string[]): Promise<ExecutionResult>;
|
|
152
|
-
/** Kill the sandbox */
|
|
153
|
-
doKill(): Promise<void>;
|
|
154
|
-
/** Get information about the sandbox */
|
|
155
|
-
doGetInfo(): Promise<SandboxInfo>;
|
|
108
|
+
interface CreateSandboxOptions$1 {
|
|
109
|
+
runtime?: Runtime;
|
|
110
|
+
timeout?: number;
|
|
111
|
+
templateId?: string;
|
|
112
|
+
metadata?: Record<string, any>;
|
|
113
|
+
envs?: Record<string, string>;
|
|
114
|
+
name?: string;
|
|
115
|
+
namespace?: string;
|
|
116
|
+
directory?: string;
|
|
117
|
+
overlays?: SandboxOverlayConfig[];
|
|
118
|
+
servers?: SandboxServerConfig[];
|
|
119
|
+
[key: string]: any;
|
|
156
120
|
}
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
readonly filesystem: SandboxFileSystem;
|
|
121
|
+
interface SandboxOverlayConfig {
|
|
122
|
+
source: string;
|
|
123
|
+
target: string;
|
|
124
|
+
ignore?: string[];
|
|
125
|
+
strategy?: 'copy' | 'smart';
|
|
163
126
|
}
|
|
127
|
+
type SandboxRestartPolicy = 'never' | 'on-failure' | 'always';
|
|
164
128
|
/**
|
|
165
|
-
*
|
|
129
|
+
* Health check configuration for servers
|
|
166
130
|
*/
|
|
167
|
-
interface
|
|
168
|
-
/**
|
|
169
|
-
|
|
131
|
+
interface SandboxHealthCheckConfig {
|
|
132
|
+
/** Path to poll for health checks (default: "/") */
|
|
133
|
+
path?: string;
|
|
134
|
+
/** Interval between health checks in milliseconds (default: 2000) */
|
|
135
|
+
interval_ms?: number;
|
|
136
|
+
/** Timeout for each health check request in milliseconds (default: 1500) */
|
|
137
|
+
timeout_ms?: number;
|
|
138
|
+
/** Delay before starting health checks after port detection in milliseconds (default: 5000) */
|
|
139
|
+
delay_ms?: number;
|
|
170
140
|
}
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
141
|
+
interface SandboxServerConfig {
|
|
142
|
+
slug: string;
|
|
143
|
+
start: string;
|
|
144
|
+
install?: string;
|
|
145
|
+
path?: string;
|
|
146
|
+
port?: number;
|
|
147
|
+
strict_port?: boolean;
|
|
148
|
+
autostart?: boolean;
|
|
149
|
+
env_file?: string;
|
|
150
|
+
environment?: Record<string, string>;
|
|
151
|
+
restart_policy?: SandboxRestartPolicy;
|
|
152
|
+
max_restarts?: number;
|
|
153
|
+
restart_delay_ms?: number;
|
|
154
|
+
stop_timeout_ms?: number;
|
|
155
|
+
depends_on?: string[];
|
|
156
|
+
overlay?: SandboxOverlayConfig;
|
|
157
|
+
overlays?: SandboxOverlayConfig[];
|
|
158
|
+
health_check?: SandboxHealthCheckConfig;
|
|
175
159
|
}
|
|
176
160
|
/**
|
|
177
|
-
*
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
*
|
|
161
|
+
* Universal Sandbox Interface
|
|
162
|
+
*
|
|
163
|
+
* All ComputeSDK sandboxes implement this interface.
|
|
164
|
+
* Core methods are required, advanced features are optional.
|
|
165
|
+
*
|
|
166
|
+
* Note: Implementations may use slightly different types for return values
|
|
167
|
+
* as long as they are structurally compatible. For example, getInfo() might
|
|
168
|
+
* return additional fields beyond the base SandboxInfo.
|
|
182
169
|
*/
|
|
183
|
-
interface
|
|
184
|
-
/**
|
|
185
|
-
|
|
186
|
-
/**
|
|
187
|
-
|
|
170
|
+
interface Sandbox$1 {
|
|
171
|
+
/** Unique identifier for the sandbox */
|
|
172
|
+
readonly sandboxId: string;
|
|
173
|
+
/** Provider name (e2b, railway, modal, gateway, etc.) */
|
|
174
|
+
readonly provider: string;
|
|
188
175
|
/** Execute code in the sandbox */
|
|
189
|
-
|
|
190
|
-
/**
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
176
|
+
runCode(code: string, runtime?: Runtime): Promise<CodeResult$1>;
|
|
177
|
+
/**
|
|
178
|
+
* Execute shell command
|
|
179
|
+
*
|
|
180
|
+
* Send raw command string to the sandbox - no preprocessing.
|
|
181
|
+
* The provider/server handles shell invocation and execution details.
|
|
182
|
+
*/
|
|
183
|
+
runCommand(command: string, options?: RunCommandOptions): Promise<CommandResult$1>;
|
|
196
184
|
/** Get information about the sandbox */
|
|
197
|
-
getInfo(): Promise<SandboxInfo>;
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
185
|
+
getInfo(): Promise<SandboxInfo$1>;
|
|
186
|
+
/** Get URL for accessing the sandbox on a specific port */
|
|
187
|
+
getUrl(options: {
|
|
188
|
+
port: number;
|
|
189
|
+
protocol?: string;
|
|
190
|
+
}): Promise<string>;
|
|
191
|
+
/** Destroy the sandbox and clean up resources */
|
|
192
|
+
destroy(): Promise<void>;
|
|
203
193
|
/** File system operations */
|
|
204
194
|
readonly filesystem: SandboxFileSystem;
|
|
195
|
+
/**
|
|
196
|
+
* Terminal management (interactive PTY and exec modes)
|
|
197
|
+
* Available in: gateway, e2b (potentially)
|
|
198
|
+
*/
|
|
199
|
+
readonly terminal?: any;
|
|
200
|
+
/**
|
|
201
|
+
* Code and command execution namespace
|
|
202
|
+
* Available in: gateway
|
|
203
|
+
*/
|
|
204
|
+
readonly run?: any;
|
|
205
|
+
/**
|
|
206
|
+
* Managed server operations
|
|
207
|
+
* Available in: gateway
|
|
208
|
+
*/
|
|
209
|
+
readonly server?: any;
|
|
210
|
+
/**
|
|
211
|
+
* File watcher with real-time change events
|
|
212
|
+
* Available in: gateway
|
|
213
|
+
*/
|
|
214
|
+
readonly watcher?: any;
|
|
215
|
+
/**
|
|
216
|
+
* Session token management
|
|
217
|
+
* Available in: gateway
|
|
218
|
+
*/
|
|
219
|
+
readonly sessionToken?: any;
|
|
220
|
+
/**
|
|
221
|
+
* Magic link authentication
|
|
222
|
+
* Available in: gateway
|
|
223
|
+
*/
|
|
224
|
+
readonly magicLink?: any;
|
|
225
|
+
/**
|
|
226
|
+
* Signal service for port/error events
|
|
227
|
+
* Available in: gateway
|
|
228
|
+
*/
|
|
229
|
+
readonly signal?: any;
|
|
230
|
+
/**
|
|
231
|
+
* File operations namespace
|
|
232
|
+
* Available in: gateway
|
|
233
|
+
*/
|
|
234
|
+
readonly file?: any;
|
|
235
|
+
/**
|
|
236
|
+
* Environment variable management
|
|
237
|
+
* Available in: gateway
|
|
238
|
+
*/
|
|
239
|
+
readonly env?: any;
|
|
240
|
+
/**
|
|
241
|
+
* Authentication operations
|
|
242
|
+
* Available in: gateway
|
|
243
|
+
*/
|
|
244
|
+
readonly auth?: any;
|
|
245
|
+
/**
|
|
246
|
+
* Child sandbox management
|
|
247
|
+
* Available in: gateway
|
|
248
|
+
*/
|
|
249
|
+
readonly child?: any;
|
|
205
250
|
}
|
|
251
|
+
|
|
206
252
|
/**
|
|
207
|
-
*
|
|
253
|
+
* Terminal created notification
|
|
208
254
|
*/
|
|
209
|
-
interface
|
|
210
|
-
|
|
211
|
-
|
|
255
|
+
interface TerminalCreatedMessage {
|
|
256
|
+
type: 'terminal:created';
|
|
257
|
+
channel: string;
|
|
258
|
+
data: {
|
|
259
|
+
id: string;
|
|
260
|
+
status: 'running' | 'stopped';
|
|
261
|
+
};
|
|
212
262
|
}
|
|
213
263
|
/**
|
|
214
|
-
*
|
|
264
|
+
* Terminal output data
|
|
265
|
+
* Note: output field may be base64 encoded depending on encoding field
|
|
215
266
|
*/
|
|
216
|
-
interface
|
|
267
|
+
interface TerminalOutputMessage {
|
|
268
|
+
type: 'terminal:output';
|
|
269
|
+
channel: string;
|
|
270
|
+
data: {
|
|
271
|
+
output: string;
|
|
272
|
+
encoding?: 'raw' | 'base64';
|
|
273
|
+
};
|
|
217
274
|
}
|
|
218
275
|
/**
|
|
219
|
-
*
|
|
276
|
+
* Terminal destroyed notification
|
|
220
277
|
*/
|
|
221
|
-
|
|
278
|
+
interface TerminalDestroyedMessage {
|
|
279
|
+
type: 'terminal:destroyed';
|
|
280
|
+
channel: string;
|
|
281
|
+
data: {
|
|
282
|
+
id: string;
|
|
283
|
+
};
|
|
284
|
+
}
|
|
222
285
|
/**
|
|
223
|
-
*
|
|
286
|
+
* Terminal error notification
|
|
224
287
|
*/
|
|
225
|
-
interface
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
runtime?: Runtime;
|
|
288
|
+
interface TerminalErrorMessage {
|
|
289
|
+
type: 'terminal:error';
|
|
290
|
+
channel: string;
|
|
291
|
+
data: {
|
|
292
|
+
error: string;
|
|
293
|
+
};
|
|
232
294
|
}
|
|
233
295
|
/**
|
|
234
|
-
*
|
|
296
|
+
* Command stdout streaming message (exec mode with stream: true)
|
|
235
297
|
*/
|
|
236
|
-
interface
|
|
237
|
-
|
|
238
|
-
|
|
298
|
+
interface CommandStdoutMessage {
|
|
299
|
+
type: 'command:stdout';
|
|
300
|
+
channel: string;
|
|
301
|
+
data: {
|
|
302
|
+
terminal_id: string;
|
|
303
|
+
cmd_id: string;
|
|
304
|
+
output: string;
|
|
305
|
+
};
|
|
239
306
|
}
|
|
240
307
|
/**
|
|
241
|
-
*
|
|
308
|
+
* Command stderr streaming message (exec mode with stream: true)
|
|
242
309
|
*/
|
|
243
|
-
|
|
310
|
+
interface CommandStderrMessage {
|
|
311
|
+
type: 'command:stderr';
|
|
312
|
+
channel: string;
|
|
313
|
+
data: {
|
|
314
|
+
terminal_id: string;
|
|
315
|
+
cmd_id: string;
|
|
316
|
+
output: string;
|
|
317
|
+
};
|
|
318
|
+
}
|
|
244
319
|
/**
|
|
245
|
-
*
|
|
320
|
+
* Command exit message (exec mode with stream: true)
|
|
246
321
|
*/
|
|
247
|
-
|
|
322
|
+
interface CommandExitMessage {
|
|
323
|
+
type: 'command:exit';
|
|
324
|
+
channel: string;
|
|
325
|
+
data: {
|
|
326
|
+
terminal_id: string;
|
|
327
|
+
cmd_id: string;
|
|
328
|
+
exit_code: number;
|
|
329
|
+
};
|
|
330
|
+
}
|
|
248
331
|
/**
|
|
249
|
-
*
|
|
332
|
+
* File watcher created notification
|
|
250
333
|
*/
|
|
251
|
-
|
|
334
|
+
interface WatcherCreatedMessage {
|
|
335
|
+
type: 'watcher:created';
|
|
336
|
+
channel: string;
|
|
337
|
+
data: {
|
|
338
|
+
id: string;
|
|
339
|
+
path: string;
|
|
340
|
+
};
|
|
341
|
+
}
|
|
252
342
|
/**
|
|
253
|
-
*
|
|
343
|
+
* File change event
|
|
344
|
+
* Note: content field may be base64 encoded depending on encoding field
|
|
254
345
|
*/
|
|
255
|
-
|
|
346
|
+
interface FileChangedMessage {
|
|
347
|
+
type: 'file:changed';
|
|
348
|
+
channel: string;
|
|
349
|
+
data: {
|
|
350
|
+
event: 'add' | 'change' | 'unlink' | 'addDir' | 'unlinkDir';
|
|
351
|
+
path: string;
|
|
352
|
+
content?: string;
|
|
353
|
+
encoding?: 'raw' | 'base64';
|
|
354
|
+
};
|
|
355
|
+
}
|
|
256
356
|
/**
|
|
257
|
-
*
|
|
357
|
+
* File watcher destroyed notification
|
|
258
358
|
*/
|
|
259
|
-
|
|
359
|
+
interface WatcherDestroyedMessage {
|
|
360
|
+
type: 'watcher:destroyed';
|
|
361
|
+
channel: string;
|
|
362
|
+
data: {
|
|
363
|
+
id: string;
|
|
364
|
+
};
|
|
365
|
+
}
|
|
260
366
|
/**
|
|
261
|
-
*
|
|
367
|
+
* System signal event
|
|
262
368
|
*/
|
|
263
|
-
|
|
369
|
+
interface SignalMessage {
|
|
370
|
+
type: 'signal';
|
|
371
|
+
channel: 'signals';
|
|
372
|
+
data: {
|
|
373
|
+
signal: 'port' | 'error' | 'server-ready';
|
|
374
|
+
port?: number;
|
|
375
|
+
url?: string;
|
|
376
|
+
message?: string;
|
|
377
|
+
};
|
|
378
|
+
}
|
|
264
379
|
/**
|
|
265
|
-
*
|
|
380
|
+
* Sandbox created notification
|
|
266
381
|
*/
|
|
267
|
-
interface
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
onData?: (data: Uint8Array) => void;
|
|
274
|
-
/** Exit handler */
|
|
275
|
-
onExit?: (exitCode: number) => void;
|
|
276
|
-
/** Write data to this terminal session */
|
|
277
|
-
write(data: Uint8Array | string): Promise<void>;
|
|
278
|
-
/** Resize this terminal session */
|
|
279
|
-
resize(cols: number, rows: number): Promise<void>;
|
|
280
|
-
/** Kill this terminal session */
|
|
281
|
-
kill(): Promise<void>;
|
|
382
|
+
interface SandboxCreatedMessage {
|
|
383
|
+
type: 'sandbox.created';
|
|
384
|
+
data: {
|
|
385
|
+
subdomain: string;
|
|
386
|
+
url: string;
|
|
387
|
+
};
|
|
282
388
|
}
|
|
283
389
|
/**
|
|
284
|
-
*
|
|
390
|
+
* Sandbox deleted notification
|
|
285
391
|
*/
|
|
286
|
-
interface
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
/** Terminal rows */
|
|
292
|
-
rows?: number;
|
|
293
|
-
/** Environment variables */
|
|
294
|
-
env?: Record<string, string>;
|
|
392
|
+
interface SandboxDeletedMessage {
|
|
393
|
+
type: 'sandbox.deleted';
|
|
394
|
+
data: {
|
|
395
|
+
subdomain: string;
|
|
396
|
+
};
|
|
295
397
|
}
|
|
296
|
-
|
|
398
|
+
type WebSocketConstructor$1 = new (url: string) => WebSocket;
|
|
399
|
+
interface WebSocketManagerConfig {
|
|
400
|
+
/** WebSocket URL (will be generated from client config if not provided) */
|
|
401
|
+
url: string;
|
|
402
|
+
/** WebSocket implementation */
|
|
403
|
+
WebSocket: WebSocketConstructor$1;
|
|
404
|
+
/** Enable automatic reconnection on disconnect (default: true) */
|
|
405
|
+
autoReconnect?: boolean;
|
|
406
|
+
/** Reconnection delay in milliseconds (default: 1000) */
|
|
407
|
+
reconnectDelay?: number;
|
|
408
|
+
/** Maximum reconnection attempts (default: 5, 0 = infinite) */
|
|
409
|
+
maxReconnectAttempts?: number;
|
|
410
|
+
/** Enable debug logging (default: false) */
|
|
411
|
+
debug?: boolean;
|
|
412
|
+
/** WebSocket protocol: 'binary' (default, recommended) or 'json' (for debugging) */
|
|
413
|
+
protocol?: 'json' | 'binary';
|
|
414
|
+
}
|
|
415
|
+
type MessageHandler<T = any> = (message: T) => void;
|
|
416
|
+
type ErrorHandler = (error: Event) => void;
|
|
417
|
+
type ConnectionHandler = () => void;
|
|
297
418
|
/**
|
|
298
|
-
*
|
|
419
|
+
* WebSocket Manager for handling real-time communication
|
|
299
420
|
*
|
|
300
|
-
*
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
*
|
|
421
|
+
* @example
|
|
422
|
+
* ```typescript
|
|
423
|
+
* import { ComputeClient } from '@computesdk/client'
|
|
424
|
+
*
|
|
425
|
+
* const client = new ComputeClient({ sandboxUrl: 'https://sandbox-123.sandbox.computesdk.com' });
|
|
426
|
+
* await client.generateToken();
|
|
427
|
+
*
|
|
428
|
+
* // Create WebSocket manager
|
|
429
|
+
* const ws = client.createWebSocketManager();
|
|
430
|
+
*
|
|
431
|
+
* // Listen for connection
|
|
432
|
+
* ws.on('open', () => {
|
|
433
|
+
* console.log('Connected!');
|
|
434
|
+
* });
|
|
435
|
+
*
|
|
436
|
+
* // Subscribe to terminal output
|
|
437
|
+
* ws.subscribe('terminal:term_abc123');
|
|
438
|
+
* ws.on('terminal:output', (msg) => {
|
|
439
|
+
* console.log('Terminal output:', msg.data.output);
|
|
440
|
+
* });
|
|
441
|
+
*
|
|
442
|
+
* // Send terminal input
|
|
443
|
+
* ws.sendTerminalInput('term_abc123', 'ls -la\n');
|
|
444
|
+
*
|
|
445
|
+
* // Subscribe to file changes
|
|
446
|
+
* ws.subscribe('watcher:watcher_xyz789');
|
|
447
|
+
* ws.on('file:changed', (msg) => {
|
|
448
|
+
* console.log('File changed:', msg.data.path, msg.data.event);
|
|
449
|
+
* });
|
|
450
|
+
*
|
|
451
|
+
* // Subscribe to signals
|
|
452
|
+
* ws.subscribe('signals');
|
|
453
|
+
* ws.on('signal', (msg) => {
|
|
454
|
+
* console.log('Signal:', msg.data);
|
|
455
|
+
* });
|
|
456
|
+
* ```
|
|
304
457
|
*/
|
|
305
|
-
declare
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
458
|
+
declare class WebSocketManager {
|
|
459
|
+
private config;
|
|
460
|
+
private ws;
|
|
461
|
+
private eventHandlers;
|
|
462
|
+
private reconnectAttempts;
|
|
463
|
+
private reconnectTimer;
|
|
464
|
+
private subscribedChannels;
|
|
465
|
+
private isManualClose;
|
|
466
|
+
constructor(config: WebSocketManagerConfig);
|
|
314
467
|
/**
|
|
315
|
-
*
|
|
316
|
-
*
|
|
317
|
-
* @param message Error message
|
|
318
|
-
* @param provider Provider identifier
|
|
319
|
-
* @param sandboxId Optional sandbox identifier
|
|
468
|
+
* Connect to WebSocket server
|
|
320
469
|
*/
|
|
321
|
-
|
|
322
|
-
}
|
|
323
|
-
/**
|
|
324
|
-
* Error thrown when code execution fails
|
|
325
|
-
*/
|
|
326
|
-
declare class ExecutionError extends ComputeError {
|
|
327
|
-
/** Error code */
|
|
328
|
-
readonly code = "EXECUTION_ERROR";
|
|
329
|
-
/** Execution errors are generally not retryable */
|
|
330
|
-
readonly isRetryable = false;
|
|
331
|
-
/** Exit code from the failed execution */
|
|
332
|
-
readonly exitCode: number;
|
|
470
|
+
connect(): Promise<void>;
|
|
333
471
|
/**
|
|
334
|
-
*
|
|
335
|
-
*
|
|
336
|
-
* @param message Error message
|
|
337
|
-
* @param provider Provider identifier
|
|
338
|
-
* @param exitCode Exit code from the execution
|
|
339
|
-
* @param sandboxId Optional sandbox identifier
|
|
472
|
+
* Disconnect from WebSocket server
|
|
340
473
|
*/
|
|
341
|
-
|
|
342
|
-
}
|
|
343
|
-
/**
|
|
344
|
-
* Error thrown when code execution times out
|
|
345
|
-
*/
|
|
346
|
-
declare class TimeoutError extends ComputeError {
|
|
347
|
-
/** Error code */
|
|
348
|
-
readonly code = "TIMEOUT_ERROR";
|
|
349
|
-
/** Timeout errors may be retryable with a longer timeout */
|
|
350
|
-
readonly isRetryable = true;
|
|
351
|
-
/** Timeout duration in milliseconds */
|
|
352
|
-
readonly timeoutMs: number;
|
|
474
|
+
disconnect(): void;
|
|
353
475
|
/**
|
|
354
|
-
*
|
|
355
|
-
*
|
|
356
|
-
* @param message Error message
|
|
357
|
-
* @param provider Provider identifier
|
|
358
|
-
* @param timeoutMs Timeout duration in milliseconds
|
|
359
|
-
* @param sandboxId Optional sandbox identifier
|
|
476
|
+
* Check if WebSocket is connected
|
|
360
477
|
*/
|
|
361
|
-
|
|
362
|
-
}
|
|
363
|
-
/**
|
|
364
|
-
* Error thrown when provider-specific operations fail
|
|
365
|
-
*/
|
|
366
|
-
declare class ProviderError extends ComputeError {
|
|
367
|
-
/** Error code */
|
|
368
|
-
readonly code = "PROVIDER_ERROR";
|
|
369
|
-
/** Provider errors may be retryable */
|
|
370
|
-
readonly isRetryable = true;
|
|
371
|
-
/** Original error from the provider */
|
|
372
|
-
readonly originalError?: Error;
|
|
478
|
+
isConnected(): boolean;
|
|
373
479
|
/**
|
|
374
|
-
*
|
|
375
|
-
*
|
|
376
|
-
* @param message Error message
|
|
377
|
-
* @param provider Provider identifier
|
|
378
|
-
* @param originalError Optional original error from the provider
|
|
379
|
-
* @param sandboxId Optional sandbox identifier
|
|
480
|
+
* Attempt to reconnect to WebSocket server
|
|
380
481
|
*/
|
|
381
|
-
|
|
382
|
-
}
|
|
383
|
-
/**
|
|
384
|
-
* Error thrown when configuration is invalid
|
|
385
|
-
*/
|
|
386
|
-
declare class ConfigurationError extends ComputeError {
|
|
387
|
-
/** Error code */
|
|
388
|
-
readonly code = "CONFIGURATION_ERROR";
|
|
389
|
-
/** Configuration errors are not retryable without changes */
|
|
390
|
-
readonly isRetryable = false;
|
|
482
|
+
private attemptReconnect;
|
|
391
483
|
/**
|
|
392
|
-
*
|
|
393
|
-
*
|
|
394
|
-
* @param message Error message
|
|
395
|
-
* @param provider Provider identifier
|
|
396
|
-
* @param sandboxId Optional sandbox identifier
|
|
484
|
+
* Subscribe to a channel
|
|
485
|
+
* @param channel - Channel name (e.g., 'terminal:term_abc123', 'watcher:watcher_xyz789', 'signals')
|
|
397
486
|
*/
|
|
398
|
-
|
|
399
|
-
}
|
|
400
|
-
/**
|
|
401
|
-
* Error thrown when authentication fails
|
|
402
|
-
*/
|
|
403
|
-
declare class AuthenticationError extends ComputeError {
|
|
404
|
-
/** Error code */
|
|
405
|
-
readonly code = "AUTHENTICATION_ERROR";
|
|
406
|
-
/** Authentication errors are not retryable without new credentials */
|
|
407
|
-
readonly isRetryable = false;
|
|
487
|
+
subscribe(channel: string): void;
|
|
408
488
|
/**
|
|
409
|
-
*
|
|
410
|
-
*
|
|
411
|
-
* @param message Error message
|
|
412
|
-
* @param provider Provider identifier
|
|
413
|
-
* @param sandboxId Optional sandbox identifier
|
|
489
|
+
* Unsubscribe from a channel
|
|
414
490
|
*/
|
|
415
|
-
|
|
416
|
-
}
|
|
417
|
-
/**
|
|
418
|
-
* Error thrown when the provider is not available
|
|
419
|
-
*/
|
|
420
|
-
declare class ProviderUnavailableError extends ComputeError {
|
|
421
|
-
/** Error code */
|
|
422
|
-
readonly code = "PROVIDER_UNAVAILABLE";
|
|
423
|
-
/** Provider unavailability may be temporary */
|
|
424
|
-
readonly isRetryable = true;
|
|
491
|
+
unsubscribe(channel: string): void;
|
|
425
492
|
/**
|
|
426
|
-
*
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
*
|
|
493
|
+
* Get list of subscribed channels
|
|
494
|
+
*/
|
|
495
|
+
getSubscribedChannels(): string[];
|
|
496
|
+
/**
|
|
497
|
+
* Send raw message to server
|
|
498
|
+
*/
|
|
499
|
+
private sendRaw;
|
|
500
|
+
/**
|
|
501
|
+
* Send input to a terminal (sent as-is, not encoded)
|
|
502
|
+
*/
|
|
503
|
+
sendTerminalInput(terminalId: string, input: string): void;
|
|
504
|
+
/**
|
|
505
|
+
* Resize terminal window
|
|
506
|
+
*/
|
|
507
|
+
resizeTerminal(terminalId: string, cols: number, rows: number): void;
|
|
508
|
+
/**
|
|
509
|
+
* Start a pending streaming command
|
|
510
|
+
* Used in two-phase streaming flow: HTTP request creates pending command,
|
|
511
|
+
* then this signal triggers execution after client has subscribed.
|
|
512
|
+
*/
|
|
513
|
+
startCommand(cmdId: string): void;
|
|
514
|
+
/**
|
|
515
|
+
* Register event handler
|
|
431
516
|
*/
|
|
432
|
-
|
|
517
|
+
on(event: 'open', handler: ConnectionHandler): void;
|
|
518
|
+
on(event: 'close', handler: ConnectionHandler): void;
|
|
519
|
+
on(event: 'error', handler: ErrorHandler): void;
|
|
520
|
+
on(event: 'reconnect-failed', handler: ConnectionHandler): void;
|
|
521
|
+
on(event: 'terminal:created', handler: MessageHandler<TerminalCreatedMessage>): void;
|
|
522
|
+
on(event: 'terminal:output', handler: MessageHandler<TerminalOutputMessage>): void;
|
|
523
|
+
on(event: 'terminal:destroyed', handler: MessageHandler<TerminalDestroyedMessage>): void;
|
|
524
|
+
on(event: 'terminal:error', handler: MessageHandler<TerminalErrorMessage>): void;
|
|
525
|
+
on(event: 'command:stdout', handler: MessageHandler<CommandStdoutMessage>): void;
|
|
526
|
+
on(event: 'command:stderr', handler: MessageHandler<CommandStderrMessage>): void;
|
|
527
|
+
on(event: 'command:exit', handler: MessageHandler<CommandExitMessage>): void;
|
|
528
|
+
on(event: 'watcher:created', handler: MessageHandler<WatcherCreatedMessage>): void;
|
|
529
|
+
on(event: 'file:changed', handler: MessageHandler<FileChangedMessage>): void;
|
|
530
|
+
on(event: 'watcher:destroyed', handler: MessageHandler<WatcherDestroyedMessage>): void;
|
|
531
|
+
on(event: 'signal', handler: MessageHandler<SignalMessage>): void;
|
|
532
|
+
on(event: 'sandbox.created', handler: MessageHandler<SandboxCreatedMessage>): void;
|
|
533
|
+
on(event: 'sandbox.deleted', handler: MessageHandler<SandboxDeletedMessage>): void;
|
|
534
|
+
/**
|
|
535
|
+
* Unregister event handler
|
|
536
|
+
*/
|
|
537
|
+
off(event: string, handler: MessageHandler): void;
|
|
538
|
+
/**
|
|
539
|
+
* Unregister all event handlers for an event
|
|
540
|
+
*/
|
|
541
|
+
offAll(event: string): void;
|
|
542
|
+
/**
|
|
543
|
+
* Emit event to registered handlers
|
|
544
|
+
*/
|
|
545
|
+
private emit;
|
|
546
|
+
/**
|
|
547
|
+
* Handle incoming message
|
|
548
|
+
*/
|
|
549
|
+
private handleMessage;
|
|
550
|
+
/**
|
|
551
|
+
* Log debug message if debug mode is enabled
|
|
552
|
+
*/
|
|
553
|
+
private log;
|
|
554
|
+
/**
|
|
555
|
+
* Get current connection state
|
|
556
|
+
*/
|
|
557
|
+
getState(): 'connecting' | 'open' | 'closing' | 'closed';
|
|
558
|
+
/**
|
|
559
|
+
* Get reconnection attempt count
|
|
560
|
+
*/
|
|
561
|
+
getReconnectAttempts(): number;
|
|
433
562
|
}
|
|
434
563
|
|
|
435
564
|
/**
|
|
436
|
-
*
|
|
437
|
-
*
|
|
438
|
-
* This file manages configuration and provider selection logic.
|
|
565
|
+
* Command - Represents a command execution in a terminal
|
|
439
566
|
*/
|
|
440
567
|
|
|
441
|
-
declare global {
|
|
442
|
-
var DurableObject: any;
|
|
443
|
-
var WebSocketPair: any;
|
|
444
|
-
}
|
|
445
|
-
declare const DEFAULT_TIMEOUT = 300000;
|
|
446
568
|
/**
|
|
447
|
-
*
|
|
569
|
+
* Command execution result with wait capability
|
|
448
570
|
*/
|
|
449
|
-
declare
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
571
|
+
declare class Command {
|
|
572
|
+
readonly id: string;
|
|
573
|
+
readonly terminalId: string;
|
|
574
|
+
readonly command: string;
|
|
575
|
+
private _status;
|
|
576
|
+
private _stdout;
|
|
577
|
+
private _stderr;
|
|
578
|
+
private _exitCode?;
|
|
579
|
+
private _durationMs?;
|
|
580
|
+
private _startedAt;
|
|
581
|
+
private _finishedAt?;
|
|
582
|
+
private waitHandler?;
|
|
583
|
+
private retrieveHandler?;
|
|
584
|
+
constructor(data: {
|
|
585
|
+
cmdId: string;
|
|
586
|
+
terminalId: string;
|
|
587
|
+
command: string;
|
|
588
|
+
status: 'running' | 'completed' | 'failed';
|
|
589
|
+
stdout: string;
|
|
590
|
+
stderr: string;
|
|
591
|
+
exitCode?: number;
|
|
592
|
+
durationMs?: number;
|
|
593
|
+
startedAt: string;
|
|
594
|
+
finishedAt?: string;
|
|
595
|
+
});
|
|
596
|
+
get status(): 'running' | 'completed' | 'failed';
|
|
597
|
+
get stdout(): string;
|
|
598
|
+
get stderr(): string;
|
|
599
|
+
get exitCode(): number | undefined;
|
|
600
|
+
get durationMs(): number | undefined;
|
|
601
|
+
get startedAt(): string;
|
|
602
|
+
get finishedAt(): string | undefined;
|
|
603
|
+
/**
|
|
604
|
+
* Set the wait handler (called by TerminalCommands)
|
|
605
|
+
* @internal
|
|
606
|
+
*/
|
|
607
|
+
setWaitHandler(handler: (timeout?: number) => Promise<CommandDetailsResponse>): void;
|
|
608
|
+
/**
|
|
609
|
+
* Set the retrieve handler (called by TerminalCommands)
|
|
610
|
+
* @internal
|
|
611
|
+
*/
|
|
612
|
+
setRetrieveHandler(handler: () => Promise<CommandDetailsResponse>): void;
|
|
613
|
+
/**
|
|
614
|
+
* Wait for the command to complete
|
|
615
|
+
* @param timeout - Optional timeout in seconds (0 = no timeout)
|
|
616
|
+
* @returns This command with updated status
|
|
617
|
+
*/
|
|
618
|
+
wait(timeout?: number): Promise<this>;
|
|
619
|
+
/**
|
|
620
|
+
* Refresh the command status from the server
|
|
621
|
+
* @returns This command with updated status
|
|
622
|
+
*/
|
|
623
|
+
refresh(): Promise<this>;
|
|
624
|
+
/**
|
|
625
|
+
* Update internal state from API response
|
|
626
|
+
*/
|
|
627
|
+
private updateFromResponse;
|
|
628
|
+
}
|
|
629
|
+
|
|
454
630
|
/**
|
|
455
|
-
*
|
|
456
|
-
*
|
|
457
|
-
* @returns Array of available provider types
|
|
631
|
+
* TerminalCommand - Resource namespace for terminal commands
|
|
458
632
|
*/
|
|
459
|
-
|
|
633
|
+
|
|
460
634
|
/**
|
|
461
|
-
*
|
|
635
|
+
* Command resource namespace for a terminal
|
|
462
636
|
*
|
|
463
|
-
* @
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
/**
|
|
467
|
-
* Validate and normalize container configuration
|
|
637
|
+
* @example
|
|
638
|
+
* ```typescript
|
|
639
|
+
* const terminal = await sandbox.terminal.create({ pty: false });
|
|
468
640
|
*
|
|
469
|
-
*
|
|
470
|
-
*
|
|
471
|
-
|
|
472
|
-
declare function normalizeContainerConfig(container: string | ContainerConfig | undefined): ContainerConfig | undefined;
|
|
473
|
-
/**
|
|
474
|
-
* Get the appropriate runtime based on provider and configuration
|
|
641
|
+
* // Run a command
|
|
642
|
+
* const cmd = await terminal.command.run('npm test');
|
|
643
|
+
* console.log(cmd.stdout);
|
|
475
644
|
*
|
|
476
|
-
*
|
|
477
|
-
*
|
|
478
|
-
*
|
|
479
|
-
|
|
480
|
-
declare function getDefaultRuntime(provider: ProviderType, runtime?: Runtime): Runtime;
|
|
481
|
-
/**
|
|
482
|
-
* Validate API key for selected provider
|
|
645
|
+
* // Run in background and wait
|
|
646
|
+
* const cmd = await terminal.command.run('npm install', { background: true });
|
|
647
|
+
* await cmd.wait();
|
|
648
|
+
* console.log(cmd.exitCode);
|
|
483
649
|
*
|
|
484
|
-
*
|
|
485
|
-
*
|
|
486
|
-
*/
|
|
487
|
-
declare function validateProviderApiKey(provider: ProviderType): void;
|
|
488
|
-
/**
|
|
489
|
-
* Normalize and validate sandbox configuration
|
|
650
|
+
* // List commands
|
|
651
|
+
* const commands = await terminal.command.list();
|
|
490
652
|
*
|
|
491
|
-
*
|
|
492
|
-
*
|
|
653
|
+
* // Retrieve a specific command
|
|
654
|
+
* const cmd = await terminal.command.retrieve(cmdId);
|
|
655
|
+
* ```
|
|
493
656
|
*/
|
|
494
|
-
declare
|
|
657
|
+
declare class TerminalCommand {
|
|
658
|
+
private terminalId;
|
|
659
|
+
private runHandler;
|
|
660
|
+
private listHandler;
|
|
661
|
+
private retrieveHandler;
|
|
662
|
+
private waitHandler;
|
|
663
|
+
constructor(terminalId: string, handlers: {
|
|
664
|
+
run: (command: string, background?: boolean) => Promise<CommandExecutionResponse>;
|
|
665
|
+
list: () => Promise<CommandsListResponse>;
|
|
666
|
+
retrieve: (cmdId: string) => Promise<CommandDetailsResponse>;
|
|
667
|
+
wait: (cmdId: string, timeout?: number) => Promise<CommandDetailsResponse>;
|
|
668
|
+
});
|
|
669
|
+
/**
|
|
670
|
+
* Run a command in the terminal
|
|
671
|
+
* @param command - The command to execute
|
|
672
|
+
* @param options - Execution options
|
|
673
|
+
* @param options.background - If true, returns immediately without waiting for completion
|
|
674
|
+
* @returns Command object with results or status
|
|
675
|
+
*/
|
|
676
|
+
run(command: string, options?: {
|
|
677
|
+
background?: boolean;
|
|
678
|
+
}): Promise<Command>;
|
|
679
|
+
/**
|
|
680
|
+
* List all commands executed in this terminal
|
|
681
|
+
* @returns Array of Command objects
|
|
682
|
+
*/
|
|
683
|
+
list(): Promise<Command[]>;
|
|
684
|
+
/**
|
|
685
|
+
* Retrieve a specific command by ID
|
|
686
|
+
* @param cmdId - The command ID
|
|
687
|
+
* @returns Command object with full details
|
|
688
|
+
*/
|
|
689
|
+
retrieve(cmdId: string): Promise<Command>;
|
|
690
|
+
}
|
|
495
691
|
|
|
496
692
|
/**
|
|
497
|
-
*
|
|
693
|
+
* Terminal class for managing terminal sessions with WebSocket integration
|
|
498
694
|
*/
|
|
499
695
|
|
|
500
696
|
/**
|
|
501
|
-
*
|
|
502
|
-
*/
|
|
503
|
-
declare function executeSandbox(params: ExecuteSandboxParams): Promise<ExecutionResult>;
|
|
504
|
-
/**
|
|
505
|
-
* Parameters for the runCode function
|
|
697
|
+
* Terminal event handlers
|
|
506
698
|
*/
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
/** Runtime to use */
|
|
513
|
-
runtime?: Runtime;
|
|
514
|
-
}
|
|
515
|
-
/**
|
|
516
|
-
* Execute code in a runtime environment
|
|
517
|
-
*/
|
|
518
|
-
declare function runCode(params: RunCodeParams): Promise<ExecutionResult>;
|
|
519
|
-
/**
|
|
520
|
-
* Parameters for the runCommand function
|
|
521
|
-
*/
|
|
522
|
-
interface RunCommandParams {
|
|
523
|
-
/** Sandbox to execute in */
|
|
524
|
-
sandbox: ComputeSandbox;
|
|
525
|
-
/** Command to execute */
|
|
526
|
-
command: string;
|
|
527
|
-
/** Command arguments */
|
|
528
|
-
args?: string[];
|
|
529
|
-
}
|
|
530
|
-
/**
|
|
531
|
-
* Execute shell commands
|
|
532
|
-
*/
|
|
533
|
-
declare function runCommand(params: RunCommandParams): Promise<ExecutionResult>;
|
|
534
|
-
/**
|
|
535
|
-
* Options for retry function
|
|
536
|
-
*/
|
|
537
|
-
interface RetryOptions {
|
|
538
|
-
/** Maximum number of attempts (default: 3) */
|
|
539
|
-
maxAttempts?: number;
|
|
540
|
-
/** Base delay in milliseconds (default: 1000) */
|
|
541
|
-
delay?: number;
|
|
542
|
-
/** Backoff multiplier (default: 2) */
|
|
543
|
-
backoff?: number;
|
|
544
|
-
/** Callback called on each retry attempt */
|
|
545
|
-
onRetry?: (error: Error, attempt: number) => void;
|
|
546
|
-
}
|
|
547
|
-
/**
|
|
548
|
-
* Retry function with exponential backoff
|
|
549
|
-
*/
|
|
550
|
-
declare function retry<T>(fn: () => Promise<T>, options?: RetryOptions): Promise<T>;
|
|
551
|
-
|
|
699
|
+
type TerminalEventHandler = {
|
|
700
|
+
output: (data: string) => void;
|
|
701
|
+
error: (error: string) => void;
|
|
702
|
+
destroyed: () => void;
|
|
703
|
+
};
|
|
552
704
|
/**
|
|
553
|
-
*
|
|
705
|
+
* TerminalInstance - A connected terminal session with WebSocket support
|
|
554
706
|
*
|
|
555
|
-
* This
|
|
556
|
-
*/
|
|
557
|
-
|
|
558
|
-
/**
|
|
559
|
-
* Create a provider registry for managing multiple providers
|
|
707
|
+
* This is the object returned by sandbox.terminal.create()
|
|
560
708
|
*
|
|
561
|
-
* @
|
|
562
|
-
*
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
*
|
|
709
|
+
* @example
|
|
710
|
+
* ```typescript
|
|
711
|
+
* // PTY mode - Interactive shell
|
|
712
|
+
* const pty = await sandbox.terminal.create({ pty: true });
|
|
713
|
+
* pty.on('output', (data) => console.log(data));
|
|
714
|
+
* pty.write('ls -la\n');
|
|
715
|
+
* await pty.destroy();
|
|
716
|
+
*
|
|
717
|
+
* // Exec mode - Command tracking
|
|
718
|
+
* const exec = await sandbox.terminal.create({ pty: false });
|
|
719
|
+
* const cmd = await exec.command.run('npm test');
|
|
720
|
+
* console.log(cmd.exitCode);
|
|
568
721
|
*
|
|
569
|
-
*
|
|
722
|
+
* // Background execution with wait
|
|
723
|
+
* const cmd = await exec.command.run('npm install', { background: true });
|
|
724
|
+
* await cmd.wait();
|
|
725
|
+
* console.log(cmd.stdout);
|
|
726
|
+
* ```
|
|
570
727
|
*/
|
|
571
|
-
declare
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
protected readonly timeout: number;
|
|
728
|
+
declare class TerminalInstance {
|
|
729
|
+
private _id;
|
|
730
|
+
private _pty;
|
|
731
|
+
private _status;
|
|
732
|
+
private _channel;
|
|
733
|
+
private _ws;
|
|
734
|
+
private _encoding;
|
|
735
|
+
private _eventHandlers;
|
|
580
736
|
/**
|
|
581
|
-
*
|
|
582
|
-
*
|
|
583
|
-
* @param provider Provider identifier
|
|
584
|
-
* @param timeout Execution timeout in milliseconds
|
|
737
|
+
* Command namespace for exec mode terminals
|
|
585
738
|
*/
|
|
586
|
-
|
|
739
|
+
readonly command: TerminalCommand;
|
|
740
|
+
private _executeHandler?;
|
|
741
|
+
private _listCommandsHandler?;
|
|
742
|
+
private _retrieveCommandHandler?;
|
|
743
|
+
private _waitCommandHandler?;
|
|
744
|
+
private _destroyHandler?;
|
|
745
|
+
constructor(id: string, pty: boolean, status: 'running' | 'stopped' | 'active' | 'ready', channel: string | null, ws: WebSocketManager | null, encoding?: 'raw' | 'base64');
|
|
587
746
|
/**
|
|
588
|
-
*
|
|
589
|
-
*
|
|
590
|
-
* @param code Code to execute
|
|
591
|
-
* @param runtime Optional runtime to use
|
|
592
|
-
* @returns Execution result
|
|
747
|
+
* Set up WebSocket event handlers (PTY mode only)
|
|
593
748
|
*/
|
|
594
|
-
|
|
749
|
+
private setupWebSocketHandlers;
|
|
595
750
|
/**
|
|
596
|
-
*
|
|
597
|
-
*
|
|
598
|
-
* @returns Promise that resolves when the sandbox is killed
|
|
751
|
+
* Terminal ID
|
|
599
752
|
*/
|
|
600
|
-
|
|
753
|
+
get id(): string;
|
|
601
754
|
/**
|
|
602
|
-
* Get
|
|
603
|
-
*
|
|
604
|
-
* @returns Sandbox information
|
|
755
|
+
* Get terminal ID (deprecated, use .id property)
|
|
756
|
+
* @deprecated Use .id property instead
|
|
605
757
|
*/
|
|
606
|
-
|
|
758
|
+
getId(): string;
|
|
607
759
|
/**
|
|
608
|
-
*
|
|
609
|
-
*
|
|
610
|
-
* @param code Code to execute
|
|
611
|
-
* @param runtime Optional runtime to use
|
|
612
|
-
* @returns Execution result
|
|
760
|
+
* Terminal status
|
|
613
761
|
*/
|
|
614
|
-
|
|
762
|
+
get status(): 'running' | 'stopped' | 'active' | 'ready';
|
|
615
763
|
/**
|
|
616
|
-
*
|
|
617
|
-
*
|
|
618
|
-
* @param command Command to execute
|
|
619
|
-
* @param args Command arguments
|
|
620
|
-
* @returns Execution result
|
|
764
|
+
* Get terminal status (deprecated, use .status property)
|
|
765
|
+
* @deprecated Use .status property instead
|
|
621
766
|
*/
|
|
622
|
-
|
|
767
|
+
getStatus(): 'running' | 'stopped' | 'active' | 'ready';
|
|
623
768
|
/**
|
|
624
|
-
*
|
|
625
|
-
*
|
|
626
|
-
* @param code Code to execute
|
|
627
|
-
* @param runtime Optional runtime to use
|
|
628
|
-
* @returns Execution result
|
|
769
|
+
* Terminal channel (null for exec mode)
|
|
629
770
|
*/
|
|
630
|
-
|
|
771
|
+
get channel(): string | null;
|
|
631
772
|
/**
|
|
632
|
-
*
|
|
633
|
-
*
|
|
634
|
-
* @returns Promise that resolves when the sandbox is killed
|
|
773
|
+
* Get terminal channel (deprecated, use .channel property)
|
|
774
|
+
* @deprecated Use .channel property instead
|
|
635
775
|
*/
|
|
636
|
-
|
|
776
|
+
getChannel(): string | null;
|
|
637
777
|
/**
|
|
638
|
-
*
|
|
639
|
-
*
|
|
640
|
-
* @returns Sandbox information
|
|
778
|
+
* Whether this is a PTY terminal
|
|
641
779
|
*/
|
|
642
|
-
|
|
780
|
+
get pty(): boolean;
|
|
643
781
|
/**
|
|
644
|
-
*
|
|
645
|
-
*
|
|
646
|
-
* @param code Code to execute
|
|
647
|
-
* @param runtime Optional runtime to use
|
|
648
|
-
* @returns Execution result
|
|
782
|
+
* Get terminal PTY mode (deprecated, use .pty property)
|
|
783
|
+
* @deprecated Use .pty property instead
|
|
649
784
|
*/
|
|
650
|
-
|
|
785
|
+
isPTY(): boolean;
|
|
651
786
|
/**
|
|
652
|
-
*
|
|
653
|
-
*
|
|
654
|
-
* @param command Command to execute
|
|
655
|
-
* @param args Command arguments
|
|
656
|
-
* @returns Execution result
|
|
787
|
+
* Check if terminal is running
|
|
657
788
|
*/
|
|
658
|
-
|
|
659
|
-
}
|
|
660
|
-
/**
|
|
661
|
-
* Helper class for implementing FileSystem with error handling
|
|
662
|
-
*/
|
|
663
|
-
declare abstract class BaseFileSystem implements SandboxFileSystem {
|
|
664
|
-
protected provider: string;
|
|
665
|
-
protected sandboxId: string;
|
|
666
|
-
constructor(provider: string, sandboxId: string);
|
|
667
|
-
readFile(path: string): Promise<string>;
|
|
668
|
-
writeFile(path: string, content: string): Promise<void>;
|
|
669
|
-
mkdir(path: string): Promise<void>;
|
|
670
|
-
readdir(path: string): Promise<FileEntry[]>;
|
|
671
|
-
exists(path: string): Promise<boolean>;
|
|
672
|
-
remove(path: string): Promise<void>;
|
|
673
|
-
protected abstract doReadFile(path: string): Promise<string>;
|
|
674
|
-
protected abstract doWriteFile(path: string, content: string): Promise<void>;
|
|
675
|
-
protected abstract doMkdir(path: string): Promise<void>;
|
|
676
|
-
protected abstract doReaddir(path: string): Promise<FileEntry[]>;
|
|
677
|
-
protected abstract doExists(path: string): Promise<boolean>;
|
|
678
|
-
protected abstract doRemove(path: string): Promise<void>;
|
|
679
|
-
}
|
|
680
|
-
/**
|
|
681
|
-
* Helper class for implementing Terminal with error handling
|
|
682
|
-
*/
|
|
683
|
-
declare abstract class BaseTerminal implements SandboxTerminal {
|
|
684
|
-
protected provider: string;
|
|
685
|
-
protected sandboxId: string;
|
|
686
|
-
constructor(provider: string, sandboxId: string);
|
|
687
|
-
create(options?: TerminalCreateOptions): Promise<InteractiveTerminalSession>;
|
|
688
|
-
list(): Promise<InteractiveTerminalSession[]>;
|
|
689
|
-
protected abstract doCreate(options?: TerminalCreateOptions): Promise<InteractiveTerminalSession>;
|
|
690
|
-
protected abstract doList(): Promise<InteractiveTerminalSession[]>;
|
|
691
|
-
}
|
|
692
|
-
|
|
693
|
-
declare class ComputeSDK {
|
|
789
|
+
isRunning(): boolean;
|
|
694
790
|
/**
|
|
695
|
-
*
|
|
696
|
-
*
|
|
697
|
-
* @param config Optional sandbox configuration
|
|
698
|
-
* @returns Configured sandbox instance
|
|
791
|
+
* Write input to the terminal (PTY mode only)
|
|
699
792
|
*/
|
|
700
|
-
|
|
793
|
+
write(input: string): void;
|
|
701
794
|
/**
|
|
702
|
-
*
|
|
703
|
-
*
|
|
704
|
-
* @returns Array of available provider types
|
|
795
|
+
* Resize terminal window (PTY mode only)
|
|
705
796
|
*/
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
797
|
+
resize(cols: number, rows: number): void;
|
|
798
|
+
/**
|
|
799
|
+
* Set execute command handler (called by Sandbox)
|
|
800
|
+
* @internal
|
|
801
|
+
*/
|
|
802
|
+
setExecuteHandler(handler: (command: string, background?: boolean) => Promise<CommandExecutionResponse>): void;
|
|
803
|
+
/**
|
|
804
|
+
* Set list commands handler (called by Sandbox)
|
|
805
|
+
* @internal
|
|
806
|
+
*/
|
|
807
|
+
setListCommandsHandler(handler: () => Promise<CommandsListResponse>): void;
|
|
808
|
+
/**
|
|
809
|
+
* Set retrieve command handler (called by Sandbox)
|
|
810
|
+
* @internal
|
|
811
|
+
*/
|
|
812
|
+
setRetrieveCommandHandler(handler: (cmdId: string) => Promise<CommandDetailsResponse>): void;
|
|
813
|
+
/**
|
|
814
|
+
* Set wait command handler (called by Sandbox)
|
|
815
|
+
* @internal
|
|
816
|
+
*/
|
|
817
|
+
setWaitCommandHandler(handler: (cmdId: string, timeout?: number) => Promise<CommandDetailsResponse>): void;
|
|
818
|
+
/**
|
|
819
|
+
* Set destroy handler (called by Sandbox)
|
|
820
|
+
* @internal
|
|
821
|
+
*/
|
|
822
|
+
setDestroyHandler(handler: () => Promise<void>): void;
|
|
823
|
+
/**
|
|
824
|
+
* Execute a command in the terminal (deprecated, use command.run())
|
|
825
|
+
* @deprecated Use terminal.command.run() instead
|
|
826
|
+
*/
|
|
827
|
+
execute(command: string, options?: {
|
|
828
|
+
background?: boolean;
|
|
829
|
+
}): Promise<CommandExecutionResponse>;
|
|
830
|
+
/**
|
|
831
|
+
* Destroy the terminal
|
|
832
|
+
*/
|
|
833
|
+
destroy(): Promise<void>;
|
|
834
|
+
/**
|
|
835
|
+
* Clean up resources
|
|
836
|
+
*/
|
|
837
|
+
private cleanup;
|
|
838
|
+
/**
|
|
839
|
+
* Register event handler
|
|
840
|
+
*/
|
|
841
|
+
on<K extends keyof TerminalEventHandler>(event: K, handler: TerminalEventHandler[K]): void;
|
|
842
|
+
/**
|
|
843
|
+
* Unregister event handler
|
|
844
|
+
*/
|
|
845
|
+
off<K extends keyof TerminalEventHandler>(event: K, handler: TerminalEventHandler[K]): void;
|
|
846
|
+
/**
|
|
847
|
+
* Emit event to registered handlers
|
|
848
|
+
*/
|
|
849
|
+
private emit;
|
|
850
|
+
}
|
|
851
|
+
|
|
852
|
+
/**
|
|
853
|
+
* FileWatcher class for monitoring file system changes with WebSocket integration
|
|
854
|
+
*/
|
|
855
|
+
|
|
856
|
+
/**
|
|
857
|
+
* File change event data
|
|
858
|
+
*/
|
|
859
|
+
interface FileChangeEvent {
|
|
860
|
+
event: 'add' | 'change' | 'unlink' | 'addDir' | 'unlinkDir';
|
|
861
|
+
path: string;
|
|
862
|
+
content?: string;
|
|
863
|
+
}
|
|
864
|
+
/**
|
|
865
|
+
* FileWatcher event handlers
|
|
866
|
+
*/
|
|
867
|
+
type FileWatcherEventHandler = {
|
|
868
|
+
change: (event: FileChangeEvent) => void;
|
|
869
|
+
destroyed: () => void;
|
|
870
|
+
};
|
|
871
|
+
/**
|
|
872
|
+
* FileWatcher class for monitoring file system changes
|
|
873
|
+
*
|
|
874
|
+
* @example
|
|
875
|
+
* ```typescript
|
|
876
|
+
* const client = new ComputeClient({ sandboxUrl: '...' });
|
|
877
|
+
* await client.generateToken();
|
|
878
|
+
*
|
|
879
|
+
* const watcher = await client.createWatcher('/home/project', {
|
|
880
|
+
* ignored: ['node_modules', '.git']
|
|
881
|
+
* });
|
|
882
|
+
*
|
|
883
|
+
* watcher.on('change', (event) => {
|
|
884
|
+
* console.log(`File ${event.event}: ${event.path}`);
|
|
885
|
+
* });
|
|
886
|
+
*
|
|
887
|
+
* await watcher.destroy();
|
|
888
|
+
* ```
|
|
889
|
+
*/
|
|
890
|
+
declare class FileWatcher {
|
|
891
|
+
private id;
|
|
892
|
+
private path;
|
|
893
|
+
private status;
|
|
894
|
+
private channel;
|
|
895
|
+
private includeContent;
|
|
896
|
+
private ignored;
|
|
897
|
+
private encoding;
|
|
898
|
+
private ws;
|
|
899
|
+
private eventHandlers;
|
|
900
|
+
constructor(id: string, path: string, status: 'active' | 'stopped', channel: string, includeContent: boolean, ignored: string[], ws: WebSocketManager, encoding?: 'raw' | 'base64');
|
|
901
|
+
/**
|
|
902
|
+
* Set up WebSocket event handlers
|
|
903
|
+
*/
|
|
904
|
+
private setupWebSocketHandlers;
|
|
905
|
+
/**
|
|
906
|
+
* Get watcher ID
|
|
907
|
+
*/
|
|
908
|
+
getId(): string;
|
|
909
|
+
/**
|
|
910
|
+
* Get watched path
|
|
911
|
+
*/
|
|
912
|
+
getPath(): string;
|
|
913
|
+
/**
|
|
914
|
+
* Get watcher status
|
|
915
|
+
*/
|
|
916
|
+
getStatus(): 'active' | 'stopped';
|
|
917
|
+
/**
|
|
918
|
+
* Get watcher channel
|
|
919
|
+
*/
|
|
920
|
+
getChannel(): string;
|
|
921
|
+
/**
|
|
922
|
+
* Check if content is included in events
|
|
923
|
+
*/
|
|
924
|
+
isIncludingContent(): boolean;
|
|
925
|
+
/**
|
|
926
|
+
* Get ignored patterns
|
|
927
|
+
*/
|
|
928
|
+
getIgnoredPatterns(): string[];
|
|
929
|
+
/**
|
|
930
|
+
* Check if watcher is active
|
|
931
|
+
*/
|
|
932
|
+
isActive(): boolean;
|
|
933
|
+
/**
|
|
934
|
+
* Destroy the watcher (uses REST API, not WebSocket)
|
|
935
|
+
*/
|
|
936
|
+
private destroyWatcher?;
|
|
937
|
+
/**
|
|
938
|
+
* Set destroy handler (called by client)
|
|
939
|
+
*/
|
|
940
|
+
setDestroyHandler(handler: () => Promise<void>): void;
|
|
941
|
+
/**
|
|
942
|
+
* Destroy the watcher
|
|
943
|
+
*/
|
|
944
|
+
destroy(): Promise<void>;
|
|
945
|
+
/**
|
|
946
|
+
* Clean up resources
|
|
947
|
+
*/
|
|
948
|
+
private cleanup;
|
|
949
|
+
/**
|
|
950
|
+
* Register event handler
|
|
951
|
+
*/
|
|
952
|
+
on<K extends keyof FileWatcherEventHandler>(event: K, handler: FileWatcherEventHandler[K]): void;
|
|
953
|
+
/**
|
|
954
|
+
* Unregister event handler
|
|
955
|
+
*/
|
|
956
|
+
off<K extends keyof FileWatcherEventHandler>(event: K, handler: FileWatcherEventHandler[K]): void;
|
|
957
|
+
/**
|
|
958
|
+
* Emit event to registered handlers
|
|
959
|
+
*/
|
|
960
|
+
private emit;
|
|
961
|
+
}
|
|
962
|
+
|
|
963
|
+
/**
|
|
964
|
+
* SignalService class for monitoring system signals with WebSocket integration
|
|
965
|
+
*/
|
|
966
|
+
|
|
967
|
+
/**
|
|
968
|
+
* Port signal data
|
|
969
|
+
*/
|
|
970
|
+
interface PortSignalEvent {
|
|
971
|
+
signal: 'port' | 'server-ready';
|
|
972
|
+
port: number;
|
|
973
|
+
url: string;
|
|
974
|
+
type?: 'open' | 'close';
|
|
975
|
+
}
|
|
976
|
+
/**
|
|
977
|
+
* Error signal data
|
|
978
|
+
*/
|
|
979
|
+
interface ErrorSignalEvent {
|
|
980
|
+
signal: 'error';
|
|
981
|
+
message: string;
|
|
982
|
+
}
|
|
983
|
+
/**
|
|
984
|
+
* Generic signal event (union type)
|
|
985
|
+
*/
|
|
986
|
+
type SignalEvent = PortSignalEvent | ErrorSignalEvent;
|
|
987
|
+
/**
|
|
988
|
+
* SignalService event handlers
|
|
989
|
+
*/
|
|
990
|
+
type SignalServiceEventHandler = {
|
|
991
|
+
port: (event: PortSignalEvent) => void;
|
|
992
|
+
error: (event: ErrorSignalEvent) => void;
|
|
993
|
+
signal: (event: SignalEvent) => void;
|
|
994
|
+
};
|
|
995
|
+
/**
|
|
996
|
+
* SignalService class for monitoring system signals and events
|
|
997
|
+
*
|
|
998
|
+
* @example
|
|
999
|
+
* ```typescript
|
|
1000
|
+
* const client = new ComputeClient({ sandboxUrl: '...' });
|
|
1001
|
+
* await client.generateToken();
|
|
1002
|
+
*
|
|
1003
|
+
* const signals = await client.startSignals();
|
|
1004
|
+
*
|
|
1005
|
+
* signals.on('port', (event) => {
|
|
1006
|
+
* console.log(`Port ${event.port} ${event.type}: ${event.url}`);
|
|
1007
|
+
* });
|
|
1008
|
+
*
|
|
1009
|
+
* signals.on('error', (event) => {
|
|
1010
|
+
* console.error(`Error: ${event.message}`);
|
|
1011
|
+
* });
|
|
1012
|
+
*
|
|
1013
|
+
* await signals.stop();
|
|
1014
|
+
* ```
|
|
1015
|
+
*/
|
|
1016
|
+
declare class SignalService {
|
|
1017
|
+
private status;
|
|
1018
|
+
private channel;
|
|
1019
|
+
private ws;
|
|
1020
|
+
private eventHandlers;
|
|
1021
|
+
constructor(status: 'active' | 'stopped', channel: string, ws: WebSocketManager);
|
|
1022
|
+
/**
|
|
1023
|
+
* Set up WebSocket event handlers
|
|
1024
|
+
*/
|
|
1025
|
+
private setupWebSocketHandlers;
|
|
1026
|
+
/**
|
|
1027
|
+
* Get service status
|
|
1028
|
+
*/
|
|
1029
|
+
getStatus(): 'active' | 'stopped';
|
|
1030
|
+
/**
|
|
1031
|
+
* Get service channel
|
|
1032
|
+
*/
|
|
1033
|
+
getChannel(): string;
|
|
1034
|
+
/**
|
|
1035
|
+
* Check if service is active
|
|
1036
|
+
*/
|
|
1037
|
+
isActive(): boolean;
|
|
1038
|
+
/**
|
|
1039
|
+
* Stop the signal service (uses REST API, not WebSocket)
|
|
1040
|
+
*/
|
|
1041
|
+
private stopService?;
|
|
1042
|
+
/**
|
|
1043
|
+
* Set stop handler (called by client)
|
|
1044
|
+
*/
|
|
1045
|
+
setStopHandler(handler: () => Promise<void>): void;
|
|
1046
|
+
/**
|
|
1047
|
+
* Stop the signal service
|
|
1048
|
+
*/
|
|
1049
|
+
stop(): Promise<void>;
|
|
1050
|
+
/**
|
|
1051
|
+
* Clean up resources
|
|
1052
|
+
*/
|
|
1053
|
+
private cleanup;
|
|
1054
|
+
/**
|
|
1055
|
+
* Register event handler
|
|
1056
|
+
*/
|
|
1057
|
+
on<K extends keyof SignalServiceEventHandler>(event: K, handler: SignalServiceEventHandler[K]): void;
|
|
1058
|
+
/**
|
|
1059
|
+
* Unregister event handler
|
|
1060
|
+
*/
|
|
1061
|
+
off<K extends keyof SignalServiceEventHandler>(event: K, handler: SignalServiceEventHandler[K]): void;
|
|
1062
|
+
/**
|
|
1063
|
+
* Emit event to registered handlers
|
|
1064
|
+
*/
|
|
1065
|
+
private emit;
|
|
1066
|
+
}
|
|
1067
|
+
|
|
1068
|
+
/**
|
|
1069
|
+
* Terminal - Resource namespace for terminal management
|
|
1070
|
+
*/
|
|
1071
|
+
|
|
1072
|
+
/**
|
|
1073
|
+
* Terminal resource namespace
|
|
1074
|
+
*
|
|
1075
|
+
* @example
|
|
1076
|
+
* ```typescript
|
|
1077
|
+
* // Create a PTY terminal (interactive shell)
|
|
1078
|
+
* const pty = await sandbox.terminal.create({ pty: true, shell: '/bin/bash' });
|
|
1079
|
+
* pty.on('output', (data) => console.log(data));
|
|
1080
|
+
* pty.write('ls -la\n');
|
|
1081
|
+
*
|
|
1082
|
+
* // Create an exec terminal (command tracking)
|
|
1083
|
+
* const exec = await sandbox.terminal.create({ pty: false });
|
|
1084
|
+
* const cmd = await exec.command.run('npm test');
|
|
1085
|
+
* console.log(cmd.exitCode);
|
|
1086
|
+
*
|
|
1087
|
+
* // List all terminals
|
|
1088
|
+
* const terminals = await sandbox.terminal.list();
|
|
1089
|
+
*
|
|
1090
|
+
* // Retrieve a specific terminal
|
|
1091
|
+
* const terminal = await sandbox.terminal.retrieve(id);
|
|
1092
|
+
*
|
|
1093
|
+
* // Destroy a terminal
|
|
1094
|
+
* await sandbox.terminal.destroy(id);
|
|
1095
|
+
* ```
|
|
1096
|
+
*/
|
|
1097
|
+
declare class Terminal {
|
|
1098
|
+
private createHandler;
|
|
1099
|
+
private listHandler;
|
|
1100
|
+
private retrieveHandler;
|
|
1101
|
+
private destroyHandler;
|
|
1102
|
+
constructor(handlers: {
|
|
1103
|
+
create: (options?: {
|
|
1104
|
+
shell?: string;
|
|
1105
|
+
encoding?: 'raw' | 'base64';
|
|
1106
|
+
pty?: boolean;
|
|
1107
|
+
}) => Promise<TerminalInstance>;
|
|
1108
|
+
list: () => Promise<TerminalResponse[]>;
|
|
1109
|
+
retrieve: (id: string) => Promise<TerminalInstance>;
|
|
1110
|
+
destroy: (id: string) => Promise<void>;
|
|
1111
|
+
});
|
|
1112
|
+
/**
|
|
1113
|
+
* Create a new terminal session
|
|
1114
|
+
*
|
|
1115
|
+
* @param options - Terminal creation options
|
|
1116
|
+
* @param options.shell - Shell to use (e.g., '/bin/bash') - PTY mode only
|
|
1117
|
+
* @param options.encoding - Encoding: 'raw' (default) or 'base64' (binary-safe)
|
|
1118
|
+
* @param options.pty - Terminal mode: true = PTY (interactive), false = exec (command tracking)
|
|
1119
|
+
* @returns TerminalInstance
|
|
1120
|
+
*/
|
|
1121
|
+
create(options?: {
|
|
1122
|
+
shell?: string;
|
|
1123
|
+
encoding?: 'raw' | 'base64';
|
|
1124
|
+
pty?: boolean;
|
|
1125
|
+
}): Promise<TerminalInstance>;
|
|
1126
|
+
/**
|
|
1127
|
+
* List all active terminals
|
|
1128
|
+
* @returns Array of terminal responses
|
|
1129
|
+
*/
|
|
1130
|
+
list(): Promise<TerminalResponse[]>;
|
|
1131
|
+
/**
|
|
1132
|
+
* Retrieve a specific terminal by ID
|
|
1133
|
+
* @param id - The terminal ID
|
|
1134
|
+
* @returns Terminal instance
|
|
1135
|
+
*/
|
|
1136
|
+
retrieve(id: string): Promise<TerminalInstance>;
|
|
1137
|
+
/**
|
|
1138
|
+
* Destroy a terminal by ID
|
|
1139
|
+
* @param id - The terminal ID
|
|
1140
|
+
*/
|
|
1141
|
+
destroy(id: string): Promise<void>;
|
|
1142
|
+
}
|
|
1143
|
+
|
|
1144
|
+
/**
|
|
1145
|
+
* Overlay - Resource namespace for filesystem overlay operations
|
|
1146
|
+
*
|
|
1147
|
+
* Overlays enable instant sandbox setup from template directories by copying
|
|
1148
|
+
* files directly for isolation, with heavy directories copied in the background.
|
|
1149
|
+
*/
|
|
1150
|
+
/**
|
|
1151
|
+
* Options for waiting for overlay copy completion
|
|
1152
|
+
*/
|
|
1153
|
+
interface WaitForCompletionOptions {
|
|
1154
|
+
/** Maximum number of retry attempts (default: 60) */
|
|
1155
|
+
maxRetries?: number;
|
|
1156
|
+
/** Initial delay between retries in milliseconds (default: 500) */
|
|
1157
|
+
initialDelayMs?: number;
|
|
1158
|
+
/** Maximum delay between retries in milliseconds (default: 5000) */
|
|
1159
|
+
maxDelayMs?: number;
|
|
1160
|
+
/** Backoff multiplier for exponential backoff (default: 1.5) */
|
|
1161
|
+
backoffFactor?: number;
|
|
1162
|
+
}
|
|
1163
|
+
/**
|
|
1164
|
+
* Strategy for creating an overlay
|
|
1165
|
+
* - 'copy': Full copy of all files (standard behavior)
|
|
1166
|
+
* - 'smart': Use symlinks for immutable packages (e.g. node_modules) for instant creation
|
|
1167
|
+
*/
|
|
1168
|
+
type OverlayStrategy = 'copy' | 'smart';
|
|
1169
|
+
/**
|
|
1170
|
+
* Options for creating an overlay
|
|
1171
|
+
*/
|
|
1172
|
+
interface CreateOverlayOptions {
|
|
1173
|
+
/** Absolute path to source directory (template) */
|
|
1174
|
+
source: string;
|
|
1175
|
+
/** Relative path in sandbox where overlay will be mounted */
|
|
1176
|
+
target: string;
|
|
1177
|
+
/** Glob patterns to ignore (e.g., ["node_modules", "*.log"]) */
|
|
1178
|
+
ignore?: string[];
|
|
1179
|
+
/** Strategy to use (default: 'smart') */
|
|
1180
|
+
strategy?: OverlayStrategy;
|
|
1181
|
+
/** If true, wait for background copy to complete before returning (default: false) */
|
|
1182
|
+
waitForCompletion?: boolean | WaitForCompletionOptions;
|
|
1183
|
+
}
|
|
1184
|
+
/**
|
|
1185
|
+
* Copy status for overlay background operations
|
|
1186
|
+
*/
|
|
1187
|
+
type OverlayCopyStatus = 'pending' | 'in_progress' | 'complete' | 'failed';
|
|
1188
|
+
/**
|
|
1189
|
+
* Statistics about an overlay
|
|
1190
|
+
*/
|
|
1191
|
+
interface OverlayStats {
|
|
1192
|
+
/** Number of copied files */
|
|
1193
|
+
copiedFiles: number;
|
|
1194
|
+
/** Number of copied directories (heavy dirs copied in background) */
|
|
1195
|
+
copiedDirs: number;
|
|
1196
|
+
/** Paths that were skipped (e.g., .git, ignored patterns) */
|
|
1197
|
+
skipped: string[];
|
|
1198
|
+
}
|
|
1199
|
+
/**
|
|
1200
|
+
* Overlay information (client-side normalized type)
|
|
1201
|
+
*/
|
|
1202
|
+
interface OverlayInfo {
|
|
1203
|
+
/** Unique overlay identifier */
|
|
1204
|
+
id: string;
|
|
1205
|
+
/** Absolute path to source directory */
|
|
1206
|
+
source: string;
|
|
1207
|
+
/** Relative path in sandbox */
|
|
1208
|
+
target: string;
|
|
1209
|
+
/** Strategy used for the overlay */
|
|
1210
|
+
strategy: OverlayStrategy;
|
|
1211
|
+
/** When the overlay was created */
|
|
1212
|
+
createdAt: string;
|
|
1213
|
+
/** Statistics about the overlay */
|
|
1214
|
+
stats: OverlayStats;
|
|
1215
|
+
/** Copy status for background operations */
|
|
1216
|
+
copyStatus: OverlayCopyStatus;
|
|
1217
|
+
/** Error message if copy failed */
|
|
1218
|
+
copyError?: string;
|
|
1219
|
+
}
|
|
1220
|
+
/**
|
|
1221
|
+
* API response for overlay operations (snake_case from server)
|
|
1222
|
+
*/
|
|
1223
|
+
interface OverlayResponse {
|
|
1224
|
+
id: string;
|
|
1225
|
+
source: string;
|
|
1226
|
+
target: string;
|
|
1227
|
+
strategy?: string;
|
|
1228
|
+
created_at: string;
|
|
1229
|
+
stats: {
|
|
1230
|
+
copied_files: number;
|
|
1231
|
+
copied_dirs: number;
|
|
1232
|
+
skipped: string[];
|
|
1233
|
+
};
|
|
1234
|
+
copy_status: string;
|
|
1235
|
+
copy_error?: string;
|
|
1236
|
+
}
|
|
1237
|
+
/**
|
|
1238
|
+
* API response for listing overlays
|
|
1239
|
+
*/
|
|
1240
|
+
interface OverlayListResponse {
|
|
1241
|
+
overlays: OverlayResponse[];
|
|
1242
|
+
}
|
|
1243
|
+
/**
|
|
1244
|
+
* Overlay resource namespace
|
|
1245
|
+
*
|
|
1246
|
+
* @example
|
|
1247
|
+
* ```typescript
|
|
1248
|
+
* // Create an overlay from a template directory
|
|
1249
|
+
* const overlay = await sandbox.filesystem.overlay.create({
|
|
1250
|
+
* source: '/templates/nextjs',
|
|
1251
|
+
* target: 'project',
|
|
1252
|
+
* });
|
|
1253
|
+
* console.log(overlay.copyStatus); // 'pending' | 'in_progress' | 'complete' | 'failed'
|
|
1254
|
+
*
|
|
1255
|
+
* // Create an overlay and wait for background copy to complete
|
|
1256
|
+
* const overlay = await sandbox.filesystem.overlay.create({
|
|
1257
|
+
* source: '/templates/nextjs',
|
|
1258
|
+
* target: 'project',
|
|
1259
|
+
* waitForCompletion: true, // blocks until copy is complete
|
|
1260
|
+
* });
|
|
1261
|
+
*
|
|
1262
|
+
* // Wait for an existing overlay's copy to complete
|
|
1263
|
+
* const overlay = await sandbox.filesystem.overlay.waitForCompletion('overlay-id');
|
|
1264
|
+
*
|
|
1265
|
+
* // List all overlays
|
|
1266
|
+
* const overlays = await sandbox.filesystem.overlay.list();
|
|
1267
|
+
*
|
|
1268
|
+
* // Get a specific overlay (useful for polling copy status)
|
|
1269
|
+
* const overlay = await sandbox.filesystem.overlay.retrieve('overlay-id');
|
|
1270
|
+
* if (overlay.copyStatus === 'complete') {
|
|
1271
|
+
* console.log('Background copy finished!');
|
|
1272
|
+
* }
|
|
1273
|
+
*
|
|
1274
|
+
* // Delete an overlay
|
|
1275
|
+
* await sandbox.filesystem.overlay.destroy('overlay-id');
|
|
1276
|
+
* ```
|
|
1277
|
+
*/
|
|
1278
|
+
declare class Overlay {
|
|
1279
|
+
private createHandler;
|
|
1280
|
+
private listHandler;
|
|
1281
|
+
private retrieveHandler;
|
|
1282
|
+
private destroyHandler;
|
|
1283
|
+
constructor(handlers: {
|
|
1284
|
+
create: (options: CreateOverlayOptions) => Promise<OverlayResponse>;
|
|
1285
|
+
list: () => Promise<OverlayListResponse>;
|
|
1286
|
+
retrieve: (id: string) => Promise<OverlayResponse>;
|
|
1287
|
+
destroy: (id: string) => Promise<void>;
|
|
1288
|
+
});
|
|
1289
|
+
/**
|
|
1290
|
+
* Create a new overlay from a template directory
|
|
1291
|
+
*
|
|
1292
|
+
* The overlay copies files from the source directory into the target path
|
|
1293
|
+
* for better isolation. Heavy directories (node_modules, .venv, etc.) are
|
|
1294
|
+
* copied in the background. Use the `ignore` option to exclude files/directories.
|
|
1295
|
+
*
|
|
1296
|
+
* @param options - Overlay creation options
|
|
1297
|
+
* @param options.source - Absolute path to source directory
|
|
1298
|
+
* @param options.target - Relative path in sandbox
|
|
1299
|
+
* @param options.ignore - Glob patterns to ignore (e.g., ["node_modules", "*.log"])
|
|
1300
|
+
* @param options.strategy - Strategy to use ('copy' or 'smart')
|
|
1301
|
+
* @param options.waitForCompletion - If true or options object, wait for background copy to complete
|
|
1302
|
+
* @returns Overlay info with copy status
|
|
1303
|
+
*/
|
|
1304
|
+
create(options: CreateOverlayOptions): Promise<OverlayInfo>;
|
|
1305
|
+
/**
|
|
1306
|
+
* List all overlays for the current sandbox
|
|
1307
|
+
* @returns Array of overlay info
|
|
1308
|
+
*/
|
|
1309
|
+
list(): Promise<OverlayInfo[]>;
|
|
1310
|
+
/**
|
|
1311
|
+
* Retrieve a specific overlay by ID
|
|
1312
|
+
*
|
|
1313
|
+
* Useful for polling the copy status of an overlay.
|
|
1314
|
+
*
|
|
1315
|
+
* @param id - Overlay ID
|
|
1316
|
+
* @returns Overlay info
|
|
1317
|
+
*/
|
|
1318
|
+
retrieve(id: string): Promise<OverlayInfo>;
|
|
1319
|
+
/**
|
|
1320
|
+
* Destroy (delete) an overlay
|
|
1321
|
+
* @param id - Overlay ID
|
|
1322
|
+
*/
|
|
1323
|
+
destroy(id: string): Promise<void>;
|
|
1324
|
+
/**
|
|
1325
|
+
* Wait for an overlay's background copy to complete
|
|
1326
|
+
*
|
|
1327
|
+
* Polls the overlay status with exponential backoff until the copy
|
|
1328
|
+
* is complete or fails. Throws an error if the copy fails or times out.
|
|
1329
|
+
*
|
|
1330
|
+
* @param id - Overlay ID
|
|
1331
|
+
* @param options - Polling options
|
|
1332
|
+
* @returns Overlay info with final copy status
|
|
1333
|
+
* @throws Error if copy fails or times out
|
|
1334
|
+
*/
|
|
1335
|
+
waitForCompletion(id: string, options?: WaitForCompletionOptions): Promise<OverlayInfo>;
|
|
1336
|
+
/**
|
|
1337
|
+
* Convert API response to OverlayInfo
|
|
1338
|
+
*/
|
|
1339
|
+
private toOverlayInfo;
|
|
1340
|
+
/**
|
|
1341
|
+
* Validate and return strategy, defaulting to 'copy' for unknown/missing values (legacy support)
|
|
1342
|
+
*/
|
|
1343
|
+
private validateStrategy;
|
|
1344
|
+
/**
|
|
1345
|
+
* Validate and return copy status, defaulting to 'pending' for unknown values
|
|
1346
|
+
*/
|
|
1347
|
+
private validateCopyStatus;
|
|
1348
|
+
}
|
|
1349
|
+
|
|
1350
|
+
/**
|
|
1351
|
+
* Server - Resource namespace for managed server operations
|
|
1352
|
+
*/
|
|
1353
|
+
|
|
1354
|
+
/**
|
|
1355
|
+
* Options for starting a managed server
|
|
1356
|
+
*/
|
|
1357
|
+
interface ServerStartOptions {
|
|
1358
|
+
/** Unique server identifier (URL-safe) */
|
|
1359
|
+
slug: string;
|
|
1360
|
+
/** Install command to run before starting (optional, runs blocking, e.g., "npm install") */
|
|
1361
|
+
install?: string;
|
|
1362
|
+
/** Command to start the server (e.g., "npm run dev") */
|
|
1363
|
+
start: string;
|
|
1364
|
+
/** Working directory (optional) */
|
|
1365
|
+
path?: string;
|
|
1366
|
+
/** Path to .env file relative to path (optional) */
|
|
1367
|
+
env_file?: string;
|
|
1368
|
+
/** Inline environment variables (merged with env_file if both provided) */
|
|
1369
|
+
environment?: Record<string, string>;
|
|
1370
|
+
/** Requested port number (preallocated before start) */
|
|
1371
|
+
port?: number;
|
|
1372
|
+
/** If true, fail instead of auto-incrementing when port is taken */
|
|
1373
|
+
strict_port?: boolean;
|
|
1374
|
+
/** Whether to auto-start the server on daemon boot (default: true) */
|
|
1375
|
+
autostart?: boolean;
|
|
1376
|
+
/** Inline overlay to create before starting the server */
|
|
1377
|
+
overlay?: Omit<CreateOverlayOptions, 'waitForCompletion'>;
|
|
1378
|
+
/** Additional overlays to create before starting the server */
|
|
1379
|
+
overlays?: Array<Omit<CreateOverlayOptions, 'waitForCompletion'>>;
|
|
1380
|
+
/** Overlay IDs this server depends on (waits for copy completion) */
|
|
1381
|
+
depends_on?: string[];
|
|
1382
|
+
/**
|
|
1383
|
+
* When to automatically restart the server:
|
|
1384
|
+
* - `never`: No automatic restart (default)
|
|
1385
|
+
* - `on-failure`: Restart only on non-zero exit code
|
|
1386
|
+
* - `always`: Always restart on exit (including exit code 0)
|
|
1387
|
+
*/
|
|
1388
|
+
restart_policy?: RestartPolicy;
|
|
1389
|
+
/** Maximum restart attempts (0 = unlimited, default: 0) */
|
|
1390
|
+
max_restarts?: number;
|
|
1391
|
+
/** Delay between restart attempts in milliseconds (default: 1000) */
|
|
1392
|
+
restart_delay_ms?: number;
|
|
1393
|
+
/** Graceful shutdown timeout in milliseconds - SIGTERM → wait → SIGKILL (default: 10000) */
|
|
1394
|
+
stop_timeout_ms?: number;
|
|
1395
|
+
/**
|
|
1396
|
+
* Health check configuration for monitoring server availability
|
|
1397
|
+
* When configured, the server will be polled to verify it's responding to requests
|
|
1398
|
+
*/
|
|
1399
|
+
health_check?: HealthCheckConfig;
|
|
1400
|
+
}
|
|
1401
|
+
/**
|
|
1402
|
+
* Server resource namespace
|
|
1403
|
+
*
|
|
1404
|
+
* @example
|
|
1405
|
+
* ```typescript
|
|
1406
|
+
* // Start a basic server
|
|
1407
|
+
* const server = await sandbox.server.start({
|
|
1408
|
+
* slug: 'api',
|
|
1409
|
+
* start: 'npm start',
|
|
1410
|
+
* path: '/app',
|
|
1411
|
+
* });
|
|
1412
|
+
*
|
|
1413
|
+
* // Start with install command (runs before start)
|
|
1414
|
+
* const server = await sandbox.server.start({
|
|
1415
|
+
* slug: 'web',
|
|
1416
|
+
* install: 'npm install',
|
|
1417
|
+
* start: 'npm run dev',
|
|
1418
|
+
* path: '/app',
|
|
1419
|
+
* });
|
|
1420
|
+
*
|
|
1421
|
+
* // Start with supervisor settings (auto-restart on failure)
|
|
1422
|
+
* const server = await sandbox.server.start({
|
|
1423
|
+
* slug: 'web',
|
|
1424
|
+
* start: 'node server.js',
|
|
1425
|
+
* path: '/app',
|
|
1426
|
+
* environment: { NODE_ENV: 'production', PORT: '3000' },
|
|
1427
|
+
* restart_policy: 'on-failure',
|
|
1428
|
+
* max_restarts: 5,
|
|
1429
|
+
* restart_delay_ms: 2000,
|
|
1430
|
+
* });
|
|
1431
|
+
*
|
|
1432
|
+
* // Start with inline overlay dependencies
|
|
1433
|
+
* const server = await sandbox.server.start({
|
|
1434
|
+
* slug: 'web',
|
|
1435
|
+
* start: 'npm run dev',
|
|
1436
|
+
* path: '/app',
|
|
1437
|
+
* overlay: {
|
|
1438
|
+
* source: '/templates/nextjs',
|
|
1439
|
+
* target: 'app',
|
|
1440
|
+
* strategy: 'smart',
|
|
1441
|
+
* },
|
|
1442
|
+
* });
|
|
1443
|
+
*
|
|
1444
|
+
* // List all servers
|
|
1445
|
+
* const servers = await sandbox.server.list();
|
|
1446
|
+
*
|
|
1447
|
+
* // Retrieve a specific server
|
|
1448
|
+
* const server = await sandbox.server.retrieve('api');
|
|
1449
|
+
*
|
|
1450
|
+
* // Stop a server (graceful shutdown with SIGTERM → SIGKILL)
|
|
1451
|
+
* await sandbox.server.stop('api');
|
|
1452
|
+
*
|
|
1453
|
+
* // Delete a server config
|
|
1454
|
+
* await sandbox.server.delete('api');
|
|
1455
|
+
*
|
|
1456
|
+
* // Restart a server
|
|
1457
|
+
* await sandbox.server.restart('api');
|
|
1458
|
+
* ```
|
|
1459
|
+
*/
|
|
1460
|
+
/**
|
|
1461
|
+
* Options for retrieving server logs
|
|
1462
|
+
*/
|
|
1463
|
+
interface ServerLogsOptions {
|
|
1464
|
+
/** Which output stream to return: 'stdout', 'stderr', or 'combined' (default) */
|
|
1465
|
+
stream?: ServerLogStream;
|
|
1466
|
+
}
|
|
1467
|
+
/**
|
|
1468
|
+
* Server logs info returned from the logs method
|
|
1469
|
+
*/
|
|
1470
|
+
interface ServerLogsInfo {
|
|
1471
|
+
/** Server slug identifier */
|
|
1472
|
+
slug: string;
|
|
1473
|
+
/** Which stream was returned */
|
|
1474
|
+
stream: ServerLogStream;
|
|
1475
|
+
/** The captured logs */
|
|
1476
|
+
logs: string;
|
|
1477
|
+
}
|
|
1478
|
+
declare class Server {
|
|
1479
|
+
private startHandler;
|
|
1480
|
+
private listHandler;
|
|
1481
|
+
private retrieveHandler;
|
|
1482
|
+
private stopHandler;
|
|
1483
|
+
private deleteHandler;
|
|
1484
|
+
private restartHandler;
|
|
1485
|
+
private updateStatusHandler;
|
|
1486
|
+
private logsHandler;
|
|
1487
|
+
constructor(handlers: {
|
|
1488
|
+
start: (options: ServerStartOptions) => Promise<ServerResponse>;
|
|
1489
|
+
list: () => Promise<ServersListResponse>;
|
|
1490
|
+
retrieve: (slug: string) => Promise<ServerResponse>;
|
|
1491
|
+
stop: (slug: string) => Promise<ServerStopResponse | void>;
|
|
1492
|
+
delete: (slug: string) => Promise<void>;
|
|
1493
|
+
restart: (slug: string) => Promise<ServerResponse>;
|
|
1494
|
+
updateStatus: (slug: string, status: ServerStatus) => Promise<void>;
|
|
1495
|
+
logs: (slug: string, options?: ServerLogsOptions) => Promise<ServerLogsResponse>;
|
|
1496
|
+
});
|
|
1497
|
+
/**
|
|
1498
|
+
* Start a new managed server with optional supervisor settings
|
|
1499
|
+
*
|
|
1500
|
+
* **Install Phase:**
|
|
1501
|
+
* If `install` is provided, it runs blocking before `start` (e.g., "npm install").
|
|
1502
|
+
* The server status will be `installing` during this phase.
|
|
1503
|
+
*
|
|
1504
|
+
* **Restart Policies:**
|
|
1505
|
+
* - `never` (default): No automatic restart on exit
|
|
1506
|
+
* - `on-failure`: Restart only on non-zero exit code
|
|
1507
|
+
* - `always`: Always restart on exit (including exit code 0)
|
|
1508
|
+
*
|
|
1509
|
+
* **Graceful Shutdown:**
|
|
1510
|
+
* When stopping a server, it first sends SIGTERM and waits for `stop_timeout_ms`
|
|
1511
|
+
* before sending SIGKILL if the process hasn't exited.
|
|
1512
|
+
*
|
|
1513
|
+
* @param options - Server configuration
|
|
1514
|
+
* @returns Server info
|
|
1515
|
+
*
|
|
1516
|
+
* @example
|
|
1517
|
+
* ```typescript
|
|
1518
|
+
* // Basic server
|
|
1519
|
+
* const server = await sandbox.server.start({
|
|
1520
|
+
* slug: 'web',
|
|
1521
|
+
* start: 'npm run dev',
|
|
1522
|
+
* path: '/app',
|
|
1523
|
+
* });
|
|
1524
|
+
*
|
|
1525
|
+
* // With install command
|
|
1526
|
+
* const server = await sandbox.server.start({
|
|
1527
|
+
* slug: 'api',
|
|
1528
|
+
* install: 'npm install',
|
|
1529
|
+
* start: 'node server.js',
|
|
1530
|
+
* environment: { NODE_ENV: 'production' },
|
|
1531
|
+
* restart_policy: 'always',
|
|
1532
|
+
* max_restarts: 0, // unlimited
|
|
1533
|
+
* });
|
|
1534
|
+
* ```
|
|
1535
|
+
*/
|
|
1536
|
+
start(options: ServerStartOptions): Promise<ServerInfo>;
|
|
1537
|
+
/**
|
|
1538
|
+
* List all managed servers
|
|
1539
|
+
* @returns Array of server info
|
|
1540
|
+
*/
|
|
1541
|
+
list(): Promise<ServerInfo[]>;
|
|
1542
|
+
/**
|
|
1543
|
+
* Retrieve a specific server by slug
|
|
1544
|
+
* @param slug - The server slug
|
|
1545
|
+
* @returns Server info
|
|
1546
|
+
*/
|
|
1547
|
+
retrieve(slug: string): Promise<ServerInfo>;
|
|
1548
|
+
/**
|
|
1549
|
+
* Stop a server by slug (non-destructive)
|
|
1550
|
+
* @param slug - The server slug
|
|
1551
|
+
*/
|
|
1552
|
+
stop(slug: string): Promise<void>;
|
|
1553
|
+
/**
|
|
1554
|
+
* Delete a server config by slug (stops + removes persistence)
|
|
1555
|
+
* @param slug - The server slug
|
|
1556
|
+
*/
|
|
1557
|
+
delete(slug: string): Promise<void>;
|
|
1558
|
+
/**
|
|
1559
|
+
* Restart a server by slug
|
|
1560
|
+
* @param slug - The server slug
|
|
1561
|
+
* @returns Server info
|
|
1562
|
+
*/
|
|
1563
|
+
restart(slug: string): Promise<ServerInfo>;
|
|
1564
|
+
/**
|
|
1565
|
+
* Update server status (internal use)
|
|
1566
|
+
* @param slug - The server slug
|
|
1567
|
+
* @param status - New status
|
|
1568
|
+
*/
|
|
1569
|
+
updateStatus(slug: string, status: ServerStatus): Promise<void>;
|
|
1570
|
+
/**
|
|
1571
|
+
* Retrieve captured output (logs) for a managed server
|
|
1572
|
+
* @param slug - The server slug
|
|
1573
|
+
* @param options - Options for log retrieval
|
|
1574
|
+
* @returns Server logs info
|
|
1575
|
+
*
|
|
1576
|
+
* @example
|
|
1577
|
+
* ```typescript
|
|
1578
|
+
* // Get combined logs (default)
|
|
1579
|
+
* const logs = await sandbox.server.logs('api');
|
|
1580
|
+
* console.log(logs.logs);
|
|
1581
|
+
*
|
|
1582
|
+
* // Get only stdout
|
|
1583
|
+
* const stdout = await sandbox.server.logs('api', { stream: 'stdout' });
|
|
1584
|
+
*
|
|
1585
|
+
* // Get only stderr
|
|
1586
|
+
* const stderr = await sandbox.server.logs('api', { stream: 'stderr' });
|
|
1587
|
+
* ```
|
|
1588
|
+
*/
|
|
1589
|
+
logs(slug: string, options?: ServerLogsOptions): Promise<ServerLogsInfo>;
|
|
1590
|
+
}
|
|
1591
|
+
|
|
1592
|
+
/**
|
|
1593
|
+
* Watcher - Resource namespace for file watcher operations
|
|
1594
|
+
*/
|
|
1595
|
+
|
|
1596
|
+
/**
|
|
1597
|
+
* Watcher resource namespace
|
|
1598
|
+
*
|
|
1599
|
+
* @example
|
|
1600
|
+
* ```typescript
|
|
1601
|
+
* // Create a file watcher
|
|
1602
|
+
* const watcher = await sandbox.watcher.create('/project', {
|
|
1603
|
+
* ignored: ['node_modules', '.git'],
|
|
1604
|
+
* includeContent: true,
|
|
1605
|
+
* });
|
|
1606
|
+
* watcher.on('change', (event) => {
|
|
1607
|
+
* console.log(`${event.event}: ${event.path}`);
|
|
1608
|
+
* });
|
|
1609
|
+
*
|
|
1610
|
+
* // List all watchers
|
|
1611
|
+
* const watchers = await sandbox.watcher.list();
|
|
1612
|
+
*
|
|
1613
|
+
* // Retrieve a specific watcher
|
|
1614
|
+
* const watcher = await sandbox.watcher.retrieve(id);
|
|
1615
|
+
*
|
|
1616
|
+
* // Destroy a watcher
|
|
1617
|
+
* await sandbox.watcher.destroy(id);
|
|
1618
|
+
* ```
|
|
1619
|
+
*/
|
|
1620
|
+
declare class Watcher {
|
|
1621
|
+
private createHandler;
|
|
1622
|
+
private listHandler;
|
|
1623
|
+
private retrieveHandler;
|
|
1624
|
+
private destroyHandler;
|
|
1625
|
+
constructor(handlers: {
|
|
1626
|
+
create: (path: string, options?: {
|
|
1627
|
+
includeContent?: boolean;
|
|
1628
|
+
ignored?: string[];
|
|
1629
|
+
encoding?: 'raw' | 'base64';
|
|
1630
|
+
}) => Promise<FileWatcher>;
|
|
1631
|
+
list: () => Promise<WatchersListResponse>;
|
|
1632
|
+
retrieve: (id: string) => Promise<WatcherResponse>;
|
|
1633
|
+
destroy: (id: string) => Promise<void>;
|
|
1634
|
+
});
|
|
1635
|
+
/**
|
|
1636
|
+
* Create a new file watcher
|
|
1637
|
+
* @param path - Path to watch
|
|
1638
|
+
* @param options - Watcher options
|
|
1639
|
+
* @param options.includeContent - Include file content in change events
|
|
1640
|
+
* @param options.ignored - Patterns to ignore
|
|
1641
|
+
* @param options.encoding - Encoding: 'raw' (default) or 'base64' (binary-safe)
|
|
1642
|
+
* @returns FileWatcher instance
|
|
1643
|
+
*/
|
|
1644
|
+
create(path: string, options?: {
|
|
1645
|
+
includeContent?: boolean;
|
|
1646
|
+
ignored?: string[];
|
|
1647
|
+
encoding?: 'raw' | 'base64';
|
|
1648
|
+
}): Promise<FileWatcher>;
|
|
1649
|
+
/**
|
|
1650
|
+
* List all active file watchers
|
|
1651
|
+
* @returns Array of watcher info
|
|
1652
|
+
*/
|
|
1653
|
+
list(): Promise<WatcherInfo[]>;
|
|
1654
|
+
/**
|
|
1655
|
+
* Retrieve a specific watcher by ID
|
|
1656
|
+
* @param id - The watcher ID
|
|
1657
|
+
* @returns Watcher info
|
|
1658
|
+
*/
|
|
1659
|
+
retrieve(id: string): Promise<WatcherInfo>;
|
|
1660
|
+
/**
|
|
1661
|
+
* Destroy a watcher by ID
|
|
1662
|
+
* @param id - The watcher ID
|
|
1663
|
+
*/
|
|
1664
|
+
destroy(id: string): Promise<void>;
|
|
1665
|
+
}
|
|
1666
|
+
|
|
1667
|
+
/**
|
|
1668
|
+
* SessionToken - Resource namespace for session token management
|
|
1669
|
+
*/
|
|
1670
|
+
|
|
1671
|
+
/**
|
|
1672
|
+
* Session token info
|
|
1673
|
+
*/
|
|
1674
|
+
interface SessionTokenInfo {
|
|
1675
|
+
id: string;
|
|
1676
|
+
token?: string;
|
|
1677
|
+
description?: string;
|
|
1678
|
+
createdAt: string;
|
|
1679
|
+
expiresAt: string;
|
|
1680
|
+
lastUsedAt?: string;
|
|
1681
|
+
}
|
|
1682
|
+
/**
|
|
1683
|
+
* SessionToken resource namespace
|
|
1684
|
+
*
|
|
1685
|
+
* @example
|
|
1686
|
+
* ```typescript
|
|
1687
|
+
* // Create a session token (requires access token)
|
|
1688
|
+
* const token = await sandbox.sessionToken.create({
|
|
1689
|
+
* description: 'My Application',
|
|
1690
|
+
* expiresIn: 604800, // 7 days
|
|
1691
|
+
* });
|
|
1692
|
+
* console.log(token.token);
|
|
1693
|
+
*
|
|
1694
|
+
* // List all session tokens
|
|
1695
|
+
* const tokens = await sandbox.sessionToken.list();
|
|
1696
|
+
*
|
|
1697
|
+
* // Retrieve a specific token
|
|
1698
|
+
* const token = await sandbox.sessionToken.retrieve(id);
|
|
1699
|
+
*
|
|
1700
|
+
* // Revoke a token
|
|
1701
|
+
* await sandbox.sessionToken.revoke(id);
|
|
1702
|
+
* ```
|
|
1703
|
+
*/
|
|
1704
|
+
declare class SessionToken {
|
|
1705
|
+
private createHandler;
|
|
1706
|
+
private listHandler;
|
|
1707
|
+
private retrieveHandler;
|
|
1708
|
+
private revokeHandler;
|
|
1709
|
+
constructor(handlers: {
|
|
1710
|
+
create: (options?: {
|
|
1711
|
+
description?: string;
|
|
1712
|
+
expiresIn?: number;
|
|
1713
|
+
}) => Promise<SessionTokenResponse>;
|
|
1714
|
+
list: () => Promise<SessionTokenListResponse>;
|
|
1715
|
+
retrieve: (id: string) => Promise<SessionTokenResponse>;
|
|
1716
|
+
revoke: (id: string) => Promise<void>;
|
|
1717
|
+
});
|
|
1718
|
+
/**
|
|
1719
|
+
* Create a new session token (requires access token)
|
|
1720
|
+
* @param options - Token configuration
|
|
1721
|
+
* @param options.description - Description for the token
|
|
1722
|
+
* @param options.expiresIn - Expiration time in seconds (default: 7 days)
|
|
1723
|
+
* @returns Session token info including the token value
|
|
1724
|
+
*/
|
|
1725
|
+
create(options?: {
|
|
1726
|
+
description?: string;
|
|
1727
|
+
expiresIn?: number;
|
|
1728
|
+
}): Promise<SessionTokenInfo>;
|
|
1729
|
+
/**
|
|
1730
|
+
* List all session tokens
|
|
1731
|
+
* @returns Array of session token info
|
|
1732
|
+
*/
|
|
1733
|
+
list(): Promise<SessionTokenInfo[]>;
|
|
1734
|
+
/**
|
|
1735
|
+
* Retrieve a specific session token by ID
|
|
1736
|
+
* @param id - The token ID
|
|
1737
|
+
* @returns Session token info
|
|
1738
|
+
*/
|
|
1739
|
+
retrieve(id: string): Promise<SessionTokenInfo>;
|
|
1740
|
+
/**
|
|
1741
|
+
* Revoke a session token
|
|
1742
|
+
* @param id - The token ID to revoke
|
|
1743
|
+
*/
|
|
1744
|
+
revoke(id: string): Promise<void>;
|
|
1745
|
+
}
|
|
1746
|
+
|
|
1747
|
+
/**
|
|
1748
|
+
* MagicLink - Resource namespace for magic link operations
|
|
1749
|
+
*/
|
|
1750
|
+
|
|
1751
|
+
/**
|
|
1752
|
+
* Magic link info
|
|
1753
|
+
*/
|
|
1754
|
+
interface MagicLinkInfo {
|
|
1755
|
+
url: string;
|
|
1756
|
+
expiresAt: string;
|
|
1757
|
+
redirectUrl: string;
|
|
1758
|
+
}
|
|
1759
|
+
/**
|
|
1760
|
+
* MagicLink resource namespace
|
|
1761
|
+
*
|
|
1762
|
+
* @example
|
|
1763
|
+
* ```typescript
|
|
1764
|
+
* // Create a magic link (requires access token)
|
|
1765
|
+
* const link = await sandbox.magicLink.create({
|
|
1766
|
+
* redirectUrl: '/dashboard',
|
|
1767
|
+
* });
|
|
1768
|
+
* console.log(link.url);
|
|
1769
|
+
* ```
|
|
1770
|
+
*/
|
|
1771
|
+
declare class MagicLink {
|
|
1772
|
+
private createHandler;
|
|
1773
|
+
constructor(handlers: {
|
|
1774
|
+
create: (options?: {
|
|
1775
|
+
redirectUrl?: string;
|
|
1776
|
+
}) => Promise<MagicLinkResponse>;
|
|
1777
|
+
});
|
|
1778
|
+
/**
|
|
1779
|
+
* Create a magic link for browser authentication (requires access token)
|
|
1780
|
+
*
|
|
1781
|
+
* Magic links are one-time URLs that automatically create a session token
|
|
1782
|
+
* and set it as a cookie in the user's browser.
|
|
1783
|
+
*
|
|
1784
|
+
* @param options - Magic link configuration
|
|
1785
|
+
* @param options.redirectUrl - URL to redirect to after authentication
|
|
1786
|
+
* @returns Magic link info including the URL
|
|
1787
|
+
*/
|
|
1788
|
+
create(options?: {
|
|
1789
|
+
redirectUrl?: string;
|
|
1790
|
+
}): Promise<MagicLinkInfo>;
|
|
1791
|
+
}
|
|
1792
|
+
|
|
1793
|
+
/**
|
|
1794
|
+
* Signal - Resource namespace for signal service operations
|
|
1795
|
+
*/
|
|
1796
|
+
|
|
1797
|
+
/**
|
|
1798
|
+
* Signal service status info
|
|
1799
|
+
*/
|
|
1800
|
+
interface SignalStatusInfo {
|
|
1801
|
+
status: 'active' | 'stopped';
|
|
1802
|
+
channel: string;
|
|
1803
|
+
wsUrl: string;
|
|
1804
|
+
}
|
|
1805
|
+
/**
|
|
1806
|
+
* Signal resource namespace
|
|
1807
|
+
*
|
|
1808
|
+
* @example
|
|
1809
|
+
* ```typescript
|
|
1810
|
+
* // Start the signal service
|
|
1811
|
+
* const signals = await sandbox.signal.start();
|
|
1812
|
+
* signals.on('port', (event) => {
|
|
1813
|
+
* console.log(`Port ${event.port} opened: ${event.url}`);
|
|
1814
|
+
* });
|
|
1815
|
+
*
|
|
1816
|
+
* // Get signal service status
|
|
1817
|
+
* const status = await sandbox.signal.status();
|
|
1818
|
+
*
|
|
1819
|
+
* // Emit signals
|
|
1820
|
+
* await sandbox.signal.emitPort(3000, 'open', 'http://localhost:3000');
|
|
1821
|
+
* await sandbox.signal.emitError('Something went wrong');
|
|
1822
|
+
*
|
|
1823
|
+
* // Stop the signal service
|
|
1824
|
+
* await sandbox.signal.stop();
|
|
1825
|
+
* ```
|
|
1826
|
+
*/
|
|
1827
|
+
declare class Signal {
|
|
1828
|
+
private startHandler;
|
|
1829
|
+
private statusHandler;
|
|
1830
|
+
private stopHandler;
|
|
1831
|
+
private emitPortHandler;
|
|
1832
|
+
private emitErrorHandler;
|
|
1833
|
+
private emitServerReadyHandler;
|
|
1834
|
+
constructor(handlers: {
|
|
1835
|
+
start: () => Promise<SignalService>;
|
|
1836
|
+
status: () => Promise<SignalServiceResponse>;
|
|
1837
|
+
stop: () => Promise<void>;
|
|
1838
|
+
emitPort: (port: number, type: 'open' | 'close', url: string) => Promise<PortSignalResponse>;
|
|
1839
|
+
emitError: (message: string) => Promise<GenericSignalResponse>;
|
|
1840
|
+
emitServerReady: (port: number, url: string) => Promise<PortSignalResponse>;
|
|
1841
|
+
});
|
|
1842
|
+
/**
|
|
1843
|
+
* Start the signal service
|
|
1844
|
+
* @returns SignalService instance with event handling
|
|
1845
|
+
*/
|
|
1846
|
+
start(): Promise<SignalService>;
|
|
1847
|
+
/**
|
|
1848
|
+
* Get the signal service status
|
|
1849
|
+
* @returns Signal service status info
|
|
1850
|
+
*/
|
|
1851
|
+
status(): Promise<SignalStatusInfo>;
|
|
1852
|
+
/**
|
|
1853
|
+
* Stop the signal service
|
|
1854
|
+
*/
|
|
1855
|
+
stop(): Promise<void>;
|
|
1856
|
+
/**
|
|
1857
|
+
* Emit a port signal
|
|
1858
|
+
* @param port - Port number
|
|
1859
|
+
* @param type - Signal type ('open' or 'close')
|
|
1860
|
+
* @param url - URL associated with the port
|
|
1861
|
+
*/
|
|
1862
|
+
emitPort(port: number, type: 'open' | 'close', url: string): Promise<void>;
|
|
1863
|
+
/**
|
|
1864
|
+
* Emit an error signal
|
|
1865
|
+
* @param message - Error message
|
|
1866
|
+
*/
|
|
1867
|
+
emitError(message: string): Promise<void>;
|
|
1868
|
+
/**
|
|
1869
|
+
* Emit a server ready signal
|
|
1870
|
+
* @param port - Port number
|
|
1871
|
+
* @param url - Server URL
|
|
1872
|
+
*/
|
|
1873
|
+
emitServerReady(port: number, url: string): Promise<void>;
|
|
1874
|
+
}
|
|
1875
|
+
|
|
1876
|
+
/**
|
|
1877
|
+
* File - Resource namespace for file operations
|
|
1878
|
+
*/
|
|
1879
|
+
|
|
1880
|
+
/**
|
|
1881
|
+
* File resource namespace
|
|
1882
|
+
*
|
|
1883
|
+
* @example
|
|
1884
|
+
* ```typescript
|
|
1885
|
+
* // Create a file
|
|
1886
|
+
* const file = await sandbox.file.create('/project/hello.txt', 'Hello, World!');
|
|
1887
|
+
*
|
|
1888
|
+
* // List files in a directory
|
|
1889
|
+
* const files = await sandbox.file.list('/project');
|
|
1890
|
+
*
|
|
1891
|
+
* // Retrieve file content
|
|
1892
|
+
* const content = await sandbox.file.retrieve('/project/hello.txt');
|
|
1893
|
+
*
|
|
1894
|
+
* // Destroy (delete) a file
|
|
1895
|
+
* await sandbox.file.destroy('/project/hello.txt');
|
|
1896
|
+
*
|
|
1897
|
+
* // Batch write multiple files
|
|
1898
|
+
* const results = await sandbox.file.batchWrite([
|
|
1899
|
+
* { path: '/project/a.txt', operation: 'write', content: 'A' },
|
|
1900
|
+
* { path: '/project/b.txt', operation: 'write', content: 'B' },
|
|
1901
|
+
* ]);
|
|
1902
|
+
*
|
|
1903
|
+
* // Batch delete files
|
|
1904
|
+
* const results = await sandbox.file.batchWrite([
|
|
1905
|
+
* { path: '/project/old.txt', operation: 'delete' },
|
|
1906
|
+
* ]);
|
|
1907
|
+
* ```
|
|
1908
|
+
*/
|
|
1909
|
+
declare class File {
|
|
1910
|
+
private createHandler;
|
|
1911
|
+
private listHandler;
|
|
1912
|
+
private retrieveHandler;
|
|
1913
|
+
private destroyHandler;
|
|
1914
|
+
private batchWriteHandler;
|
|
1915
|
+
private existsHandler;
|
|
1916
|
+
constructor(handlers: {
|
|
1917
|
+
create: (path: string, content?: string) => Promise<FileResponse>;
|
|
1918
|
+
list: (path: string) => Promise<FilesListResponse>;
|
|
1919
|
+
retrieve: (path: string) => Promise<string>;
|
|
1920
|
+
destroy: (path: string) => Promise<void>;
|
|
1921
|
+
batchWrite: (files: Array<{
|
|
1922
|
+
path: string;
|
|
1923
|
+
operation: BatchFileOperation;
|
|
1924
|
+
content?: string;
|
|
1925
|
+
}>) => Promise<BatchWriteResponse>;
|
|
1926
|
+
exists: (path: string) => Promise<boolean>;
|
|
1927
|
+
});
|
|
1928
|
+
/**
|
|
1929
|
+
* Create a new file with optional content
|
|
1930
|
+
* @param path - File path
|
|
1931
|
+
* @param content - File content (optional)
|
|
1932
|
+
* @returns File info
|
|
1933
|
+
*/
|
|
1934
|
+
create(path: string, content?: string): Promise<FileInfo>;
|
|
1935
|
+
/**
|
|
1936
|
+
* List files at the specified path
|
|
1937
|
+
* @param path - Directory path (default: '/')
|
|
1938
|
+
* @returns Array of file info
|
|
1939
|
+
*/
|
|
1940
|
+
list(path?: string): Promise<FileInfo[]>;
|
|
1941
|
+
/**
|
|
1942
|
+
* Retrieve file content
|
|
1943
|
+
* @param path - File path
|
|
1944
|
+
* @returns File content as string
|
|
1945
|
+
*/
|
|
1946
|
+
retrieve(path: string): Promise<string>;
|
|
1947
|
+
/**
|
|
1948
|
+
* Destroy (delete) a file or directory
|
|
1949
|
+
* @param path - File or directory path
|
|
1950
|
+
*/
|
|
1951
|
+
destroy(path: string): Promise<void>;
|
|
1952
|
+
/**
|
|
1953
|
+
* Batch file operations (write or delete multiple files)
|
|
1954
|
+
*
|
|
1955
|
+
* Features:
|
|
1956
|
+
* - Deduplication: Last operation wins per path
|
|
1957
|
+
* - File locking: Prevents race conditions
|
|
1958
|
+
* - Deterministic ordering: Alphabetical path sorting
|
|
1959
|
+
* - Partial failure handling: Returns per-file results
|
|
1960
|
+
*
|
|
1961
|
+
* @param files - Array of file operations
|
|
1962
|
+
* @returns Results for each file operation
|
|
1963
|
+
*/
|
|
1964
|
+
batchWrite(files: Array<{
|
|
1965
|
+
path: string;
|
|
1966
|
+
operation: BatchFileOperation;
|
|
1967
|
+
content?: string;
|
|
1968
|
+
}>): Promise<BatchWriteResult[]>;
|
|
1969
|
+
/**
|
|
1970
|
+
* Check if a file exists
|
|
1971
|
+
* @param path - File path
|
|
1972
|
+
* @returns True if file exists
|
|
1973
|
+
*/
|
|
1974
|
+
exists(path: string): Promise<boolean>;
|
|
1975
|
+
}
|
|
1976
|
+
|
|
1977
|
+
/**
|
|
1978
|
+
* Env - Resource namespace for environment variable operations
|
|
1979
|
+
*/
|
|
1980
|
+
|
|
1981
|
+
/**
|
|
1982
|
+
* Env resource namespace
|
|
1983
|
+
*
|
|
1984
|
+
* @example
|
|
1985
|
+
* ```typescript
|
|
1986
|
+
* // Retrieve environment variables
|
|
1987
|
+
* const vars = await sandbox.env.retrieve('.env');
|
|
1988
|
+
* console.log(vars);
|
|
1989
|
+
*
|
|
1990
|
+
* // Update environment variables (merges with existing)
|
|
1991
|
+
* await sandbox.env.update('.env', {
|
|
1992
|
+
* API_KEY: 'secret',
|
|
1993
|
+
* DEBUG: 'true',
|
|
1994
|
+
* });
|
|
1995
|
+
*
|
|
1996
|
+
* // Remove environment variables
|
|
1997
|
+
* await sandbox.env.remove('.env', ['OLD_KEY', 'DEPRECATED']);
|
|
1998
|
+
* ```
|
|
1999
|
+
*/
|
|
2000
|
+
declare class Env {
|
|
2001
|
+
private retrieveHandler;
|
|
2002
|
+
private updateHandler;
|
|
2003
|
+
private removeHandler;
|
|
2004
|
+
private existsHandler;
|
|
2005
|
+
constructor(handlers: {
|
|
2006
|
+
retrieve: (file: string) => Promise<EnvGetResponse>;
|
|
2007
|
+
update: (file: string, variables: Record<string, string>) => Promise<EnvSetResponse>;
|
|
2008
|
+
remove: (file: string, keys: string[]) => Promise<EnvDeleteResponse>;
|
|
2009
|
+
exists: (file: string) => Promise<boolean>;
|
|
2010
|
+
});
|
|
2011
|
+
/**
|
|
2012
|
+
* Retrieve environment variables from a file
|
|
2013
|
+
* @param file - Path to the .env file (relative to sandbox root)
|
|
2014
|
+
* @returns Key-value map of environment variables
|
|
2015
|
+
*/
|
|
2016
|
+
retrieve(file: string): Promise<Record<string, string>>;
|
|
2017
|
+
/**
|
|
2018
|
+
* Update (merge) environment variables in a file
|
|
2019
|
+
* @param file - Path to the .env file (relative to sandbox root)
|
|
2020
|
+
* @param variables - Key-value pairs to set
|
|
2021
|
+
* @returns Keys that were updated
|
|
2022
|
+
*/
|
|
2023
|
+
update(file: string, variables: Record<string, string>): Promise<string[]>;
|
|
2024
|
+
/**
|
|
2025
|
+
* Remove environment variables from a file
|
|
2026
|
+
* @param file - Path to the .env file (relative to sandbox root)
|
|
2027
|
+
* @param keys - Keys to remove
|
|
2028
|
+
* @returns Keys that were removed
|
|
2029
|
+
*/
|
|
2030
|
+
remove(file: string, keys: string[]): Promise<string[]>;
|
|
2031
|
+
/**
|
|
2032
|
+
* Check if an environment file exists
|
|
2033
|
+
* @param file - Path to the .env file (relative to sandbox root)
|
|
2034
|
+
* @returns True if file exists
|
|
2035
|
+
*/
|
|
2036
|
+
exists(file: string): Promise<boolean>;
|
|
2037
|
+
}
|
|
2038
|
+
|
|
2039
|
+
/**
|
|
2040
|
+
* Auth - Resource namespace for authentication info
|
|
2041
|
+
*/
|
|
2042
|
+
|
|
2043
|
+
/**
|
|
2044
|
+
* Authentication status info
|
|
2045
|
+
*/
|
|
2046
|
+
interface AuthStatusInfo {
|
|
2047
|
+
authenticated: boolean;
|
|
2048
|
+
tokenType?: 'access_token' | 'session_token';
|
|
2049
|
+
expiresAt?: string;
|
|
2050
|
+
}
|
|
2051
|
+
/**
|
|
2052
|
+
* Authentication endpoints info
|
|
2053
|
+
*/
|
|
2054
|
+
interface AuthEndpointsInfo {
|
|
2055
|
+
createSessionToken: string;
|
|
2056
|
+
listSessionTokens: string;
|
|
2057
|
+
getSessionToken: string;
|
|
2058
|
+
revokeSessionToken: string;
|
|
2059
|
+
createMagicLink: string;
|
|
2060
|
+
authStatus: string;
|
|
2061
|
+
authInfo: string;
|
|
2062
|
+
}
|
|
2063
|
+
/**
|
|
2064
|
+
* Authentication info
|
|
2065
|
+
*/
|
|
2066
|
+
interface AuthInfo {
|
|
2067
|
+
message: string;
|
|
2068
|
+
instructions: string;
|
|
2069
|
+
endpoints: AuthEndpointsInfo;
|
|
2070
|
+
}
|
|
2071
|
+
/**
|
|
2072
|
+
* Auth resource namespace
|
|
2073
|
+
*
|
|
2074
|
+
* @example
|
|
2075
|
+
* ```typescript
|
|
2076
|
+
* // Check authentication status
|
|
2077
|
+
* const status = await sandbox.auth.status();
|
|
2078
|
+
* console.log(status.authenticated);
|
|
2079
|
+
* console.log(status.tokenType);
|
|
2080
|
+
*
|
|
2081
|
+
* // Get authentication info and instructions
|
|
2082
|
+
* const info = await sandbox.auth.info();
|
|
2083
|
+
* console.log(info.instructions);
|
|
2084
|
+
* ```
|
|
2085
|
+
*/
|
|
2086
|
+
declare class Auth {
|
|
2087
|
+
private statusHandler;
|
|
2088
|
+
private infoHandler;
|
|
2089
|
+
constructor(handlers: {
|
|
2090
|
+
status: () => Promise<AuthStatusResponse>;
|
|
2091
|
+
info: () => Promise<AuthInfoResponse>;
|
|
2092
|
+
});
|
|
2093
|
+
/**
|
|
2094
|
+
* Check authentication status
|
|
2095
|
+
* @returns Authentication status info
|
|
2096
|
+
*/
|
|
2097
|
+
status(): Promise<AuthStatusInfo>;
|
|
2098
|
+
/**
|
|
2099
|
+
* Get authentication information and usage instructions
|
|
2100
|
+
* @returns Authentication info
|
|
2101
|
+
*/
|
|
2102
|
+
info(): Promise<AuthInfo>;
|
|
2103
|
+
}
|
|
2104
|
+
|
|
2105
|
+
/**
|
|
2106
|
+
* Run - Resource namespace for code and command execution
|
|
2107
|
+
*/
|
|
2108
|
+
/**
|
|
2109
|
+
* Code execution result
|
|
2110
|
+
*/
|
|
2111
|
+
interface CodeResult {
|
|
2112
|
+
output: string;
|
|
2113
|
+
exitCode: number;
|
|
2114
|
+
language: string;
|
|
2115
|
+
}
|
|
2116
|
+
/**
|
|
2117
|
+
* Command execution result
|
|
2118
|
+
*/
|
|
2119
|
+
interface CommandResult {
|
|
2120
|
+
stdout: string;
|
|
2121
|
+
stderr: string;
|
|
2122
|
+
exitCode: number;
|
|
2123
|
+
durationMs: number;
|
|
2124
|
+
/** Command ID (present for background commands) */
|
|
2125
|
+
cmdId?: string;
|
|
2126
|
+
/** Terminal ID (present for background commands) */
|
|
2127
|
+
terminalId?: string;
|
|
2128
|
+
/** Command status (present for background commands) */
|
|
2129
|
+
status?: 'running' | 'completed' | 'failed';
|
|
2130
|
+
}
|
|
2131
|
+
/**
|
|
2132
|
+
* Supported languages for code execution
|
|
2133
|
+
*/
|
|
2134
|
+
type CodeLanguage = 'python' | 'python3' | 'node' | 'javascript' | 'js' | 'bash' | 'sh' | 'ruby';
|
|
2135
|
+
/**
|
|
2136
|
+
* Code execution options
|
|
2137
|
+
*/
|
|
2138
|
+
interface CodeRunOptions {
|
|
2139
|
+
/** Programming language (optional - will auto-detect if not specified) */
|
|
2140
|
+
language?: CodeLanguage;
|
|
2141
|
+
}
|
|
2142
|
+
/**
|
|
2143
|
+
* Options for waiting for command completion
|
|
2144
|
+
*/
|
|
2145
|
+
interface CommandWaitOptions {
|
|
2146
|
+
/** Timeout in seconds to wait for command completion (default: 300, max: 300) */
|
|
2147
|
+
timeoutSeconds?: number;
|
|
2148
|
+
}
|
|
2149
|
+
/**
|
|
2150
|
+
* Command execution options
|
|
2151
|
+
*/
|
|
2152
|
+
interface CommandRunOptions {
|
|
2153
|
+
/** Shell to use (optional) */
|
|
2154
|
+
shell?: string;
|
|
2155
|
+
/** Run in background (optional) */
|
|
2156
|
+
background?: boolean;
|
|
2157
|
+
/** Working directory for the command (optional) */
|
|
2158
|
+
cwd?: string;
|
|
2159
|
+
/** Environment variables (optional) */
|
|
2160
|
+
env?: Record<string, string>;
|
|
2161
|
+
/** If true, wait for background command to complete before returning (default: false) */
|
|
2162
|
+
waitForCompletion?: boolean | CommandWaitOptions;
|
|
2163
|
+
}
|
|
2164
|
+
/**
|
|
2165
|
+
* Run - Resource namespace for executing code and commands
|
|
2166
|
+
*
|
|
2167
|
+
* @example
|
|
2168
|
+
* ```typescript
|
|
2169
|
+
* // Run code with auto-detection
|
|
2170
|
+
* const result = await sandbox.run.code('print("Hello from Python")');
|
|
2171
|
+
* console.log(result.output); // "Hello from Python\n"
|
|
2172
|
+
* console.log(result.language); // "python"
|
|
2173
|
+
*
|
|
2174
|
+
* // Run code with explicit language
|
|
2175
|
+
* const result = await sandbox.run.code('console.log("Hello")', { language: 'node' });
|
|
2176
|
+
*
|
|
2177
|
+
* // Run a command
|
|
2178
|
+
* const result = await sandbox.run.command('ls -la');
|
|
2179
|
+
* console.log(result.stdout);
|
|
2180
|
+
* console.log(result.exitCode);
|
|
2181
|
+
*
|
|
2182
|
+
* // Run a command in background and wait for completion
|
|
2183
|
+
* const result = await sandbox.run.command('npm install', {
|
|
2184
|
+
* background: true,
|
|
2185
|
+
* waitForCompletion: true, // blocks until command completes
|
|
2186
|
+
* });
|
|
2187
|
+
* console.log(result.exitCode);
|
|
2188
|
+
*
|
|
2189
|
+
* // Run in background without waiting (fire-and-forget)
|
|
2190
|
+
* const result = await sandbox.run.command('npm install', { background: true });
|
|
2191
|
+
* console.log(result.cmdId); // command ID for manual tracking
|
|
2192
|
+
* console.log(result.terminalId); // terminal ID for manual tracking
|
|
2193
|
+
* ```
|
|
2194
|
+
*/
|
|
2195
|
+
declare class Run {
|
|
2196
|
+
private codeHandler;
|
|
2197
|
+
private commandHandler;
|
|
2198
|
+
private waitHandler?;
|
|
2199
|
+
constructor(handlers: {
|
|
2200
|
+
code: (code: string, options?: CodeRunOptions) => Promise<CodeResult>;
|
|
2201
|
+
command: (command: string, options?: CommandRunOptions) => Promise<CommandResult>;
|
|
2202
|
+
wait?: (terminalId: string, cmdId: string, options?: CommandWaitOptions) => Promise<CommandResult>;
|
|
2203
|
+
});
|
|
2204
|
+
/**
|
|
2205
|
+
* Execute code with automatic language detection
|
|
2206
|
+
*
|
|
2207
|
+
* Supports: python, python3, node, javascript, js, bash, sh, ruby
|
|
2208
|
+
*
|
|
2209
|
+
* @param code - The code to execute
|
|
2210
|
+
* @param options - Execution options
|
|
2211
|
+
* @param options.language - Programming language (auto-detected if not specified)
|
|
2212
|
+
* @returns Code execution result with output, exit code, and detected language
|
|
2213
|
+
*/
|
|
2214
|
+
code(code: string, options?: CodeRunOptions): Promise<CodeResult>;
|
|
2215
|
+
/**
|
|
2216
|
+
* Execute a shell command
|
|
2217
|
+
*
|
|
2218
|
+
* @param command - The command to execute
|
|
2219
|
+
* @param options - Execution options
|
|
2220
|
+
* @param options.shell - Shell to use (optional)
|
|
2221
|
+
* @param options.background - Run in background (optional)
|
|
2222
|
+
* @param options.cwd - Working directory for the command (optional)
|
|
2223
|
+
* @param options.env - Environment variables (optional)
|
|
2224
|
+
* @param options.waitForCompletion - If true (with background), wait for command to complete
|
|
2225
|
+
* @returns Command execution result with stdout, stderr, exit code, and duration
|
|
2226
|
+
*/
|
|
2227
|
+
command(command: string, options?: CommandRunOptions): Promise<CommandResult>;
|
|
2228
|
+
/**
|
|
2229
|
+
* Wait for a background command to complete
|
|
2230
|
+
*
|
|
2231
|
+
* Uses the configured wait handler to block until the command
|
|
2232
|
+
* is complete or fails (typically via server-side long-polling).
|
|
2233
|
+
* Throws an error if the command fails or times out.
|
|
2234
|
+
*
|
|
2235
|
+
* @param terminalId - Terminal ID from background command result
|
|
2236
|
+
* @param cmdId - Command ID from background command result
|
|
2237
|
+
* @param options - Wait options passed to the handler
|
|
2238
|
+
* @returns Command result with final status
|
|
2239
|
+
* @throws Error if command fails or times out
|
|
2240
|
+
*/
|
|
2241
|
+
waitForCompletion(terminalId: string, cmdId: string, options?: CommandWaitOptions): Promise<CommandResult>;
|
|
2242
|
+
}
|
|
2243
|
+
|
|
2244
|
+
/**
|
|
2245
|
+
* Client Types
|
|
2246
|
+
*
|
|
2247
|
+
* Types specific to the gateway Sandbox client implementation.
|
|
2248
|
+
* Core universal types are imported from ../types/universal-sandbox
|
|
2249
|
+
*/
|
|
2250
|
+
|
|
2251
|
+
/**
|
|
2252
|
+
* Sandbox status types (client-specific, more limited than universal)
|
|
2253
|
+
*/
|
|
2254
|
+
type SandboxStatus = 'running' | 'stopped' | 'error';
|
|
2255
|
+
/**
|
|
2256
|
+
* Provider-agnostic sandbox info (alias for SandboxInfo for backward compatibility)
|
|
2257
|
+
*/
|
|
2258
|
+
interface ProviderSandboxInfo {
|
|
2259
|
+
/** Unique identifier for the sandbox */
|
|
2260
|
+
id: string;
|
|
2261
|
+
/** Provider hosting the sandbox */
|
|
2262
|
+
provider: string;
|
|
2263
|
+
/** Runtime environment in the sandbox */
|
|
2264
|
+
runtime: Runtime;
|
|
2265
|
+
/** Current status of the sandbox */
|
|
2266
|
+
status: SandboxStatus;
|
|
2267
|
+
/** When the sandbox was created */
|
|
2268
|
+
createdAt: Date;
|
|
2269
|
+
/** Execution timeout in milliseconds */
|
|
2270
|
+
timeout: number;
|
|
2271
|
+
/** Additional provider-specific metadata */
|
|
2272
|
+
metadata?: Record<string, any>;
|
|
2273
|
+
}
|
|
2274
|
+
/**
|
|
2275
|
+
* Error thrown when a command exits with a non-zero status
|
|
2276
|
+
*/
|
|
2277
|
+
declare class CommandExitError extends Error {
|
|
2278
|
+
result: {
|
|
2279
|
+
exitCode: number;
|
|
2280
|
+
stdout: string;
|
|
2281
|
+
stderr: string;
|
|
2282
|
+
error: boolean;
|
|
2283
|
+
};
|
|
2284
|
+
name: string;
|
|
2285
|
+
constructor(result: {
|
|
2286
|
+
exitCode: number;
|
|
2287
|
+
stdout: string;
|
|
2288
|
+
stderr: string;
|
|
2289
|
+
error: boolean;
|
|
2290
|
+
});
|
|
2291
|
+
}
|
|
2292
|
+
/**
|
|
2293
|
+
* Type guard to check if an error is a CommandExitError
|
|
2294
|
+
*/
|
|
2295
|
+
declare function isCommandExitError(error: unknown): error is CommandExitError;
|
|
2296
|
+
|
|
2297
|
+
/**
|
|
2298
|
+
* Child - Resource namespace for child sandbox operations
|
|
2299
|
+
*/
|
|
2300
|
+
|
|
2301
|
+
/**
|
|
2302
|
+
* Child resource namespace for managing child sandboxes
|
|
2303
|
+
*
|
|
2304
|
+
* Child sandboxes are isolated environments within the parent sandbox,
|
|
2305
|
+
* each with their own filesystem. Available only in multi-tenant mode.
|
|
2306
|
+
*
|
|
2307
|
+
* @example
|
|
2308
|
+
* ```typescript
|
|
2309
|
+
* // Create a new child sandbox
|
|
2310
|
+
* const child = await sandbox.child.create({
|
|
2311
|
+
* directory: '/custom/path',
|
|
2312
|
+
* overlays: [
|
|
2313
|
+
* {
|
|
2314
|
+
* source: '/templates/nextjs',
|
|
2315
|
+
* target: 'app',
|
|
2316
|
+
* strategy: 'smart',
|
|
2317
|
+
* },
|
|
2318
|
+
* ],
|
|
2319
|
+
* servers: [
|
|
2320
|
+
* {
|
|
2321
|
+
* slug: 'web',
|
|
2322
|
+
* start: 'npm run dev',
|
|
2323
|
+
* path: '/app',
|
|
2324
|
+
* },
|
|
2325
|
+
* ],
|
|
2326
|
+
* });
|
|
2327
|
+
* console.log(child.url); // https://sandbox-12345.sandbox.computesdk.com
|
|
2328
|
+
*
|
|
2329
|
+
* // List all children
|
|
2330
|
+
* const all = await sandbox.child.list();
|
|
2331
|
+
*
|
|
2332
|
+
* // Get a specific child
|
|
2333
|
+
* const info = await sandbox.child.retrieve('sandbox-12345');
|
|
2334
|
+
*
|
|
2335
|
+
* // Delete a child sandbox
|
|
2336
|
+
* await sandbox.child.destroy('sandbox-12345');
|
|
2337
|
+
*
|
|
2338
|
+
* // Delete child and its files
|
|
2339
|
+
* await sandbox.child.destroy('sandbox-12345', { deleteFiles: true });
|
|
2340
|
+
* ```
|
|
2341
|
+
*/
|
|
2342
|
+
declare class Child {
|
|
2343
|
+
private createHandler;
|
|
2344
|
+
private listHandler;
|
|
2345
|
+
private retrieveHandler;
|
|
2346
|
+
private destroyHandler;
|
|
2347
|
+
constructor(handlers: {
|
|
2348
|
+
create: (options?: CreateSandboxOptions$1) => Promise<SandboxInfo>;
|
|
2349
|
+
list: () => Promise<SandboxesListResponse>;
|
|
2350
|
+
retrieve: (subdomain: string) => Promise<SandboxInfo>;
|
|
2351
|
+
destroy: (subdomain: string, deleteFiles: boolean) => Promise<void>;
|
|
2352
|
+
});
|
|
2353
|
+
/**
|
|
2354
|
+
* Create a new child sandbox
|
|
2355
|
+
* @returns Child sandbox info including URL and subdomain
|
|
2356
|
+
*/
|
|
2357
|
+
create(options?: CreateSandboxOptions$1): Promise<SandboxInfo>;
|
|
2358
|
+
/**
|
|
2359
|
+
* List all child sandboxes
|
|
2360
|
+
* @returns Array of child sandbox info
|
|
2361
|
+
*/
|
|
2362
|
+
list(): Promise<SandboxInfo[]>;
|
|
2363
|
+
/**
|
|
2364
|
+
* Retrieve a specific child sandbox by subdomain
|
|
2365
|
+
* @param subdomain - The child subdomain (e.g., 'sandbox-12345')
|
|
2366
|
+
* @returns Child sandbox info
|
|
2367
|
+
*/
|
|
2368
|
+
retrieve(subdomain: string): Promise<SandboxInfo>;
|
|
2369
|
+
/**
|
|
2370
|
+
* Destroy (delete) a child sandbox
|
|
2371
|
+
* @param subdomain - The child subdomain
|
|
2372
|
+
* @param options - Destroy options
|
|
2373
|
+
* @param options.deleteFiles - Whether to delete the child's files (default: false)
|
|
2374
|
+
*/
|
|
2375
|
+
destroy(subdomain: string, options?: {
|
|
2376
|
+
deleteFiles?: boolean;
|
|
2377
|
+
}): Promise<void>;
|
|
2378
|
+
}
|
|
2379
|
+
|
|
2380
|
+
/**
|
|
2381
|
+
* Binary WebSocket Protocol Implementation
|
|
2382
|
+
*
|
|
2383
|
+
* Implements the ComputeSDK binary protocol for WebSocket communication.
|
|
2384
|
+
* Provides 50-90% size reduction compared to JSON protocol.
|
|
2385
|
+
*
|
|
2386
|
+
* Binary Message Format:
|
|
2387
|
+
* [1 byte: message type]
|
|
2388
|
+
* [2 bytes: channel length (uint16, big-endian)]
|
|
2389
|
+
* [N bytes: channel string (UTF-8)]
|
|
2390
|
+
* [2 bytes: msg type length (uint16, big-endian)]
|
|
2391
|
+
* [N bytes: msg type string (UTF-8)]
|
|
2392
|
+
* [4 bytes: data length (uint32, big-endian)]
|
|
2393
|
+
* [N bytes: data (key-value encoded for complex objects, raw bytes for binary data)]
|
|
2394
|
+
*
|
|
2395
|
+
* Key-Value Encoding Format:
|
|
2396
|
+
* [2 bytes: num_fields (uint16, big-endian)]
|
|
2397
|
+
* For each field:
|
|
2398
|
+
* [2 bytes: key_length (uint16, big-endian)]
|
|
2399
|
+
* [N bytes: key string (UTF-8)]
|
|
2400
|
+
* [1 byte: value_type (0x01=string, 0x02=number, 0x03=boolean, 0x04=bytes)]
|
|
2401
|
+
* [4 bytes: value_length (uint32, big-endian)]
|
|
2402
|
+
* [N bytes: value data]
|
|
2403
|
+
*/
|
|
2404
|
+
declare enum MessageType {
|
|
2405
|
+
Subscribe = 1,
|
|
2406
|
+
Unsubscribe = 2,
|
|
2407
|
+
Data = 3,
|
|
2408
|
+
Error = 4,
|
|
2409
|
+
Connected = 5
|
|
2410
|
+
}
|
|
2411
|
+
/**
|
|
2412
|
+
* Encode a WebSocket message to binary format
|
|
2413
|
+
* @param message - The message object to encode
|
|
2414
|
+
* @returns ArrayBuffer containing the encoded binary message
|
|
2415
|
+
*/
|
|
2416
|
+
declare function encodeBinaryMessage(message: any): ArrayBuffer;
|
|
2417
|
+
/**
|
|
2418
|
+
* Decode a binary WebSocket message
|
|
2419
|
+
* @param buffer - The binary data to decode (ArrayBuffer or Uint8Array)
|
|
2420
|
+
* @returns Decoded message object
|
|
2421
|
+
*/
|
|
2422
|
+
declare function decodeBinaryMessage(buffer: ArrayBuffer | Uint8Array): any;
|
|
2423
|
+
|
|
2424
|
+
/**
|
|
2425
|
+
* ComputeSDK Client - Universal Sandbox Implementation
|
|
2426
|
+
*
|
|
2427
|
+
* This package provides a Sandbox for interacting with ComputeSDK sandboxes
|
|
2428
|
+
* through API endpoints at ${sandboxId}.sandbox.computesdk.com
|
|
2429
|
+
*
|
|
2430
|
+
* Works in browser, Node.js, and edge runtimes.
|
|
2431
|
+
* Browser: Uses native WebSocket and fetch
|
|
2432
|
+
* Node.js: Pass WebSocket implementation (e.g., 'ws' library)
|
|
2433
|
+
*/
|
|
2434
|
+
|
|
2435
|
+
/**
|
|
2436
|
+
* Extended filesystem interface with overlay support
|
|
2437
|
+
*/
|
|
2438
|
+
interface ExtendedFileSystem extends SandboxFileSystem {
|
|
2439
|
+
/** Overlay operations for template directories */
|
|
2440
|
+
readonly overlay: Overlay;
|
|
2441
|
+
}
|
|
2442
|
+
|
|
2443
|
+
/**
|
|
2444
|
+
* WebSocket constructor type
|
|
2445
|
+
*/
|
|
2446
|
+
type WebSocketConstructor = new (url: string) => WebSocket;
|
|
2447
|
+
/**
|
|
2448
|
+
* Configuration options for creating a Sandbox
|
|
2449
|
+
*/
|
|
2450
|
+
interface SandboxConfig {
|
|
2451
|
+
/** API endpoint URL (e.g., https://sandbox-123.sandbox.computesdk.com). Optional in browser - can be auto-detected from URL query param or localStorage */
|
|
2452
|
+
sandboxUrl?: string;
|
|
2453
|
+
/** Sandbox ID */
|
|
2454
|
+
sandboxId: string;
|
|
2455
|
+
/** Provider name (e.g., 'e2b', 'gateway') */
|
|
2456
|
+
provider: string;
|
|
2457
|
+
/** Access token or session token for authentication. Optional in browser - can be auto-detected from URL query param or localStorage */
|
|
2458
|
+
token?: string;
|
|
2459
|
+
/** Optional headers to include with all requests */
|
|
2460
|
+
headers?: Record<string, string>;
|
|
2461
|
+
/** Request timeout in milliseconds (default: 30000) */
|
|
2462
|
+
timeout?: number;
|
|
2463
|
+
/** WebSocket implementation (optional, uses global WebSocket if not provided) */
|
|
2464
|
+
WebSocket?: WebSocketConstructor;
|
|
2465
|
+
/** WebSocket protocol: 'binary' (default, recommended) or 'json' (for debugging) */
|
|
2466
|
+
protocol?: 'json' | 'binary';
|
|
2467
|
+
/** Optional metadata associated with the sandbox */
|
|
2468
|
+
metadata?: Record<string, unknown>;
|
|
2469
|
+
/**
|
|
2470
|
+
* Handler called when destroy() is invoked.
|
|
2471
|
+
* If provided, this is called to destroy the sandbox (e.g., via gateway API).
|
|
2472
|
+
* If not provided, destroy() only disconnects the WebSocket.
|
|
2473
|
+
* @internal
|
|
2474
|
+
*/
|
|
2475
|
+
destroyHandler?: () => Promise<void>;
|
|
2476
|
+
}
|
|
2477
|
+
/**
|
|
2478
|
+
* Health check response
|
|
2479
|
+
*/
|
|
2480
|
+
interface HealthResponse {
|
|
2481
|
+
status: string;
|
|
2482
|
+
timestamp: string;
|
|
2483
|
+
}
|
|
2484
|
+
/**
|
|
2485
|
+
* Server info response
|
|
2486
|
+
*/
|
|
2487
|
+
interface InfoResponse {
|
|
2488
|
+
message: string;
|
|
2489
|
+
data: {
|
|
2490
|
+
auth_enabled: boolean;
|
|
2491
|
+
main_subdomain: string;
|
|
2492
|
+
sandbox_count: number;
|
|
2493
|
+
sandbox_url: string;
|
|
2494
|
+
version: string;
|
|
2495
|
+
};
|
|
2496
|
+
}
|
|
2497
|
+
/**
|
|
2498
|
+
* Session token response
|
|
2499
|
+
*/
|
|
2500
|
+
interface SessionTokenResponse {
|
|
2501
|
+
id: string;
|
|
2502
|
+
token: string;
|
|
2503
|
+
description?: string;
|
|
2504
|
+
createdAt: string;
|
|
2505
|
+
expiresAt: string;
|
|
2506
|
+
expiresIn: number;
|
|
2507
|
+
}
|
|
2508
|
+
/**
|
|
2509
|
+
* Session token list response
|
|
2510
|
+
*/
|
|
2511
|
+
interface SessionTokenListResponse {
|
|
2512
|
+
message: string;
|
|
2513
|
+
data: {
|
|
2514
|
+
tokens: Array<{
|
|
2515
|
+
id: string;
|
|
2516
|
+
description?: string;
|
|
2517
|
+
created_at: string;
|
|
2518
|
+
expires_at: string;
|
|
2519
|
+
last_used_at?: string;
|
|
2520
|
+
}>;
|
|
2521
|
+
};
|
|
2522
|
+
}
|
|
2523
|
+
/**
|
|
2524
|
+
* Magic link response
|
|
2525
|
+
*/
|
|
2526
|
+
interface MagicLinkResponse {
|
|
2527
|
+
message: string;
|
|
2528
|
+
data: {
|
|
2529
|
+
magic_url: string;
|
|
2530
|
+
expires_at: string;
|
|
2531
|
+
redirect_url: string;
|
|
2532
|
+
};
|
|
2533
|
+
}
|
|
2534
|
+
/**
|
|
2535
|
+
* Authentication status response
|
|
2536
|
+
*/
|
|
2537
|
+
interface AuthStatusResponse {
|
|
2538
|
+
message: string;
|
|
2539
|
+
data: {
|
|
2540
|
+
authenticated: boolean;
|
|
2541
|
+
token_type?: 'access_token' | 'session_token';
|
|
2542
|
+
expires_at?: string;
|
|
2543
|
+
};
|
|
2544
|
+
}
|
|
2545
|
+
/**
|
|
2546
|
+
* Authentication information response
|
|
2547
|
+
*/
|
|
2548
|
+
interface AuthInfoResponse {
|
|
2549
|
+
message: string;
|
|
2550
|
+
data: {
|
|
2551
|
+
message: string;
|
|
2552
|
+
instructions: string;
|
|
2553
|
+
endpoints: {
|
|
2554
|
+
create_session_token: string;
|
|
2555
|
+
list_session_tokens: string;
|
|
2556
|
+
get_session_token: string;
|
|
2557
|
+
revoke_session_token: string;
|
|
2558
|
+
create_magic_link: string;
|
|
2559
|
+
auth_status: string;
|
|
2560
|
+
auth_info: string;
|
|
2561
|
+
};
|
|
2562
|
+
};
|
|
2563
|
+
}
|
|
2564
|
+
/**
|
|
2565
|
+
* File information
|
|
2566
|
+
*/
|
|
2567
|
+
interface FileInfo {
|
|
2568
|
+
name: string;
|
|
2569
|
+
path: string;
|
|
2570
|
+
size: number;
|
|
2571
|
+
is_dir: boolean;
|
|
2572
|
+
modified_at: string;
|
|
2573
|
+
}
|
|
2574
|
+
/**
|
|
2575
|
+
* Files list response
|
|
2576
|
+
*/
|
|
2577
|
+
interface FilesListResponse {
|
|
2578
|
+
message: string;
|
|
2579
|
+
data: {
|
|
2580
|
+
files: FileInfo[];
|
|
2581
|
+
path: string;
|
|
2582
|
+
};
|
|
2583
|
+
}
|
|
2584
|
+
/**
|
|
2585
|
+
* File response
|
|
2586
|
+
*/
|
|
2587
|
+
interface FileResponse {
|
|
2588
|
+
message: string;
|
|
2589
|
+
data: {
|
|
2590
|
+
file: FileInfo;
|
|
2591
|
+
content?: string;
|
|
2592
|
+
};
|
|
2593
|
+
}
|
|
2594
|
+
/**
|
|
2595
|
+
* Command execution response (used by both /run/command and /terminals/{id}/execute)
|
|
2596
|
+
*/
|
|
2597
|
+
interface CommandExecutionResponse {
|
|
2598
|
+
message: string;
|
|
2599
|
+
data: {
|
|
2600
|
+
terminal_id?: string;
|
|
2601
|
+
cmd_id?: string;
|
|
2602
|
+
command: string;
|
|
2603
|
+
stdout: string;
|
|
2604
|
+
stderr: string;
|
|
2605
|
+
exit_code?: number;
|
|
2606
|
+
duration_ms?: number;
|
|
2607
|
+
status?: 'running' | 'completed' | 'failed';
|
|
2608
|
+
channel?: string;
|
|
2609
|
+
pty?: boolean;
|
|
2610
|
+
};
|
|
2611
|
+
}
|
|
2612
|
+
/**
|
|
2613
|
+
* Command details response
|
|
2614
|
+
*/
|
|
2615
|
+
interface CommandDetailsResponse {
|
|
2616
|
+
message: string;
|
|
2617
|
+
data: {
|
|
2618
|
+
cmd_id: string;
|
|
2619
|
+
command: string;
|
|
2620
|
+
status: 'running' | 'completed' | 'failed';
|
|
2621
|
+
stdout: string;
|
|
2622
|
+
stderr: string;
|
|
2623
|
+
started_at: string;
|
|
2624
|
+
finished_at?: string;
|
|
2625
|
+
duration_ms?: number;
|
|
2626
|
+
exit_code?: number;
|
|
2627
|
+
};
|
|
2628
|
+
}
|
|
2629
|
+
/**
|
|
2630
|
+
* Command list item
|
|
2631
|
+
*/
|
|
2632
|
+
interface CommandListItem {
|
|
2633
|
+
cmd_id: string;
|
|
2634
|
+
command: string;
|
|
2635
|
+
status: 'running' | 'completed' | 'failed';
|
|
2636
|
+
started_at: string;
|
|
2637
|
+
finished_at?: string;
|
|
2638
|
+
duration_ms?: number;
|
|
2639
|
+
exit_code?: number;
|
|
2640
|
+
}
|
|
2641
|
+
/**
|
|
2642
|
+
* Commands list response
|
|
2643
|
+
*/
|
|
2644
|
+
interface CommandsListResponse {
|
|
2645
|
+
message: string;
|
|
2646
|
+
data: {
|
|
2647
|
+
commands: CommandListItem[];
|
|
2648
|
+
count: number;
|
|
2649
|
+
};
|
|
2650
|
+
}
|
|
2651
|
+
/**
|
|
2652
|
+
* Code execution response (POST /run/code)
|
|
2653
|
+
*/
|
|
2654
|
+
interface CodeExecutionResponse {
|
|
2655
|
+
data: {
|
|
2656
|
+
output: string;
|
|
2657
|
+
exit_code: number;
|
|
2658
|
+
language: string;
|
|
2659
|
+
};
|
|
2660
|
+
}
|
|
2661
|
+
/**
|
|
2662
|
+
* File watcher information
|
|
2663
|
+
*/
|
|
2664
|
+
interface WatcherInfo {
|
|
2665
|
+
id: string;
|
|
2666
|
+
path: string;
|
|
2667
|
+
includeContent: boolean;
|
|
2668
|
+
ignored: string[];
|
|
2669
|
+
status: 'active' | 'stopped';
|
|
2670
|
+
channel: string;
|
|
2671
|
+
encoding?: 'raw' | 'base64';
|
|
2672
|
+
}
|
|
2673
|
+
/**
|
|
2674
|
+
* File watcher response
|
|
2675
|
+
*/
|
|
2676
|
+
interface WatcherResponse {
|
|
2677
|
+
message: string;
|
|
2678
|
+
data: WatcherInfo & {
|
|
2679
|
+
ws_url: string;
|
|
2680
|
+
};
|
|
2681
|
+
}
|
|
2682
|
+
/**
|
|
2683
|
+
* File watchers list response
|
|
2684
|
+
*/
|
|
2685
|
+
interface WatchersListResponse {
|
|
2686
|
+
message: string;
|
|
2687
|
+
data: {
|
|
2688
|
+
watchers: WatcherInfo[];
|
|
2689
|
+
};
|
|
2690
|
+
}
|
|
2691
|
+
/**
|
|
2692
|
+
* Signal service response
|
|
2693
|
+
*/
|
|
2694
|
+
interface SignalServiceResponse {
|
|
2695
|
+
message: string;
|
|
2696
|
+
data: {
|
|
2697
|
+
status: 'active' | 'stopped';
|
|
2698
|
+
channel: string;
|
|
2699
|
+
ws_url: string;
|
|
2700
|
+
};
|
|
2701
|
+
}
|
|
2702
|
+
/**
|
|
2703
|
+
* Port signal response
|
|
2704
|
+
*/
|
|
2705
|
+
interface PortSignalResponse {
|
|
2706
|
+
message: string;
|
|
2707
|
+
data: {
|
|
2708
|
+
port: number;
|
|
2709
|
+
type: 'open' | 'close';
|
|
2710
|
+
url: string;
|
|
2711
|
+
};
|
|
2712
|
+
}
|
|
2713
|
+
/**
|
|
2714
|
+
* Generic signal response
|
|
2715
|
+
*/
|
|
2716
|
+
interface GenericSignalResponse {
|
|
2717
|
+
message: string;
|
|
2718
|
+
data: {
|
|
2719
|
+
message: string;
|
|
2720
|
+
};
|
|
2721
|
+
}
|
|
2722
|
+
/**
|
|
2723
|
+
* Sandbox information
|
|
2724
|
+
*/
|
|
2725
|
+
interface SandboxInfo {
|
|
2726
|
+
subdomain: string;
|
|
2727
|
+
directory: string;
|
|
2728
|
+
is_main: boolean;
|
|
2729
|
+
created_at: string;
|
|
2730
|
+
url: string;
|
|
2731
|
+
overlays?: SandboxOverlayInfo[];
|
|
2732
|
+
servers?: SandboxServerInfo[];
|
|
2733
|
+
}
|
|
2734
|
+
/**
|
|
2735
|
+
* Sandboxes list response
|
|
2736
|
+
*/
|
|
2737
|
+
interface SandboxesListResponse {
|
|
2738
|
+
sandboxes: SandboxInfo[];
|
|
2739
|
+
}
|
|
2740
|
+
/**
|
|
2741
|
+
* Terminal response
|
|
2742
|
+
*/
|
|
2743
|
+
interface TerminalResponse {
|
|
2744
|
+
message: string;
|
|
2745
|
+
data: {
|
|
2746
|
+
id: string;
|
|
2747
|
+
pty: boolean;
|
|
2748
|
+
status: 'running' | 'stopped' | 'ready' | 'active';
|
|
2749
|
+
channel?: string;
|
|
2750
|
+
ws_url?: string;
|
|
2751
|
+
encoding?: 'raw' | 'base64';
|
|
2752
|
+
};
|
|
2753
|
+
}
|
|
2754
|
+
/**
|
|
2755
|
+
* Terminal response
|
|
2756
|
+
*/
|
|
2757
|
+
interface TerminalResponse {
|
|
2758
|
+
message: string;
|
|
2759
|
+
data: {
|
|
2760
|
+
id: string;
|
|
2761
|
+
pty: boolean;
|
|
2762
|
+
status: 'running' | 'stopped' | 'ready' | 'active';
|
|
2763
|
+
channel?: string;
|
|
2764
|
+
ws_url?: string;
|
|
2765
|
+
encoding?: 'raw' | 'base64';
|
|
2766
|
+
};
|
|
2767
|
+
}
|
|
2768
|
+
/**
|
|
2769
|
+
* Server status types
|
|
2770
|
+
*
|
|
2771
|
+
* - `installing`: Running install command (e.g., npm install) before starting
|
|
2772
|
+
* - `starting`: Initial startup of the server process
|
|
2773
|
+
* - `running`: Server process is running
|
|
2774
|
+
* - `ready`: Server is running and ready to accept traffic
|
|
2775
|
+
* - `failed`: Server failed to start or encountered a fatal error
|
|
2776
|
+
* - `stopped`: Server was intentionally stopped
|
|
2777
|
+
* - `restarting`: Server is being automatically restarted by the supervisor
|
|
2778
|
+
*/
|
|
2779
|
+
type ServerStatus = 'installing' | 'starting' | 'running' | 'ready' | 'failed' | 'stopped' | 'restarting';
|
|
2780
|
+
/**
|
|
2781
|
+
* Server restart policy
|
|
2782
|
+
* - `never`: No automatic restart (default)
|
|
2783
|
+
* - `on-failure`: Restart only on non-zero exit code
|
|
2784
|
+
* - `always`: Always restart on exit (including exit code 0)
|
|
2785
|
+
*/
|
|
2786
|
+
type RestartPolicy = 'never' | 'on-failure' | 'always';
|
|
2787
|
+
/**
|
|
2788
|
+
* Health check configuration for servers
|
|
2789
|
+
* Polls the server to verify it's responding to requests
|
|
2790
|
+
*/
|
|
2791
|
+
interface HealthCheckConfig {
|
|
2792
|
+
/** Path to poll for health checks (default: "/") */
|
|
2793
|
+
path?: string;
|
|
2794
|
+
/** Interval between health checks in milliseconds (default: 2000) */
|
|
2795
|
+
interval_ms?: number;
|
|
2796
|
+
/** Timeout for each health check request in milliseconds (default: 1500) */
|
|
2797
|
+
timeout_ms?: number;
|
|
2798
|
+
/** Delay before starting health checks after port detection in milliseconds (default: 5000) */
|
|
2799
|
+
delay_ms?: number;
|
|
2800
|
+
}
|
|
2801
|
+
/**
|
|
2802
|
+
* Health check status information returned from server
|
|
2803
|
+
*/
|
|
2804
|
+
interface HealthCheckStatus {
|
|
2805
|
+
/** When the last health check was performed (ISO 8601) */
|
|
2806
|
+
last_check?: string;
|
|
2807
|
+
/** HTTP status code from the last health check */
|
|
2808
|
+
last_status?: number;
|
|
2809
|
+
/** Number of consecutive failed health checks */
|
|
2810
|
+
consecutive_failures: number;
|
|
2811
|
+
}
|
|
2812
|
+
/**
|
|
2813
|
+
* Server information
|
|
2814
|
+
*/
|
|
2815
|
+
interface ServerInfo {
|
|
2816
|
+
/** Unique server identifier */
|
|
2817
|
+
slug: string;
|
|
2818
|
+
/** Install command (optional, runs blocking before start) */
|
|
2819
|
+
install?: string;
|
|
2820
|
+
/** Command used to start the server */
|
|
2821
|
+
start: string;
|
|
2822
|
+
/** Working directory path */
|
|
2823
|
+
path: string;
|
|
2824
|
+
/** Original path before resolution */
|
|
2825
|
+
original_path?: string;
|
|
2826
|
+
/** Path to .env file */
|
|
2827
|
+
env_file?: string;
|
|
2828
|
+
/** Inline environment variables */
|
|
2829
|
+
environment?: Record<string, string>;
|
|
2830
|
+
/** Whether to auto-start the server on daemon boot */
|
|
2831
|
+
autostart?: boolean;
|
|
2832
|
+
/** If true, port allocation is strict (no auto-increment) */
|
|
2833
|
+
strict_port?: boolean;
|
|
2834
|
+
/** Overlay IDs this server depends on */
|
|
2835
|
+
depends_on?: string[];
|
|
2836
|
+
/** Auto-detected port number (populated when port monitor detects listening port) */
|
|
2837
|
+
port?: number;
|
|
2838
|
+
/** Generated URL from subdomain + port (populated when port is detected) */
|
|
2839
|
+
url?: string;
|
|
2840
|
+
/** Server lifecycle status */
|
|
2841
|
+
status: ServerStatus;
|
|
2842
|
+
/** Process ID (direct process, not shell wrapper) */
|
|
2843
|
+
pid?: number;
|
|
2844
|
+
/** Configured restart policy */
|
|
2845
|
+
restart_policy?: RestartPolicy;
|
|
2846
|
+
/** Maximum restart attempts (0 = unlimited) */
|
|
2847
|
+
max_restarts?: number;
|
|
2848
|
+
/** Delay between restarts in nanoseconds (input uses milliseconds via restart_delay_ms) */
|
|
2849
|
+
restart_delay?: number;
|
|
2850
|
+
/** Graceful shutdown timeout in nanoseconds (input uses milliseconds via stop_timeout_ms) */
|
|
2851
|
+
stop_timeout?: number;
|
|
2852
|
+
/** Number of times the server has been automatically restarted */
|
|
2853
|
+
restart_count?: number;
|
|
2854
|
+
/** Last exit code (null if process is still running) */
|
|
2855
|
+
exit_code?: number | null;
|
|
2856
|
+
/** Health check configuration (if configured) */
|
|
2857
|
+
health_check?: HealthCheckConfig;
|
|
2858
|
+
/** Whether the server is healthy (only present if health_check is configured) */
|
|
2859
|
+
healthy?: boolean;
|
|
2860
|
+
/** Health check status details (only present if health_check is configured) */
|
|
2861
|
+
health_status?: HealthCheckStatus;
|
|
2862
|
+
/** When the server was created */
|
|
2863
|
+
created_at: string;
|
|
2864
|
+
/** When the server was last updated */
|
|
2865
|
+
updated_at: string;
|
|
2866
|
+
}
|
|
2867
|
+
/**
|
|
2868
|
+
* Sandbox server info returned by setup flows
|
|
2869
|
+
*/
|
|
2870
|
+
interface SandboxServerInfo {
|
|
2871
|
+
slug: string;
|
|
2872
|
+
port?: number;
|
|
2873
|
+
url?: string;
|
|
2874
|
+
status: ServerStatus;
|
|
2875
|
+
/** Whether the server is healthy (only present if health_check is configured) */
|
|
2876
|
+
healthy?: boolean;
|
|
2877
|
+
/** Health check status details (only present if health_check is configured) */
|
|
2878
|
+
health_check?: HealthCheckStatus;
|
|
2879
|
+
}
|
|
2880
|
+
/**
|
|
2881
|
+
* Sandbox overlay info returned by setup flows
|
|
2882
|
+
*/
|
|
2883
|
+
interface SandboxOverlayInfo {
|
|
2884
|
+
id: string;
|
|
2885
|
+
source: string;
|
|
2886
|
+
target: string;
|
|
2887
|
+
copy_status: string;
|
|
2888
|
+
}
|
|
2889
|
+
/**
|
|
2890
|
+
* Ready response (public endpoint)
|
|
2891
|
+
*/
|
|
2892
|
+
interface ReadyResponse {
|
|
2893
|
+
/** Whether all servers have ports allocated (URLs available) */
|
|
2894
|
+
ready: boolean;
|
|
2895
|
+
/** Whether all servers with health checks are passing */
|
|
2896
|
+
healthy?: boolean;
|
|
2897
|
+
servers: SandboxServerInfo[];
|
|
2898
|
+
overlays: SandboxOverlayInfo[];
|
|
2899
|
+
}
|
|
2900
|
+
/**
|
|
2901
|
+
* Servers list response
|
|
2902
|
+
*/
|
|
2903
|
+
interface ServersListResponse {
|
|
2904
|
+
status: string;
|
|
2905
|
+
message: string;
|
|
2906
|
+
data: {
|
|
2907
|
+
servers: ServerInfo[];
|
|
2908
|
+
};
|
|
2909
|
+
}
|
|
2910
|
+
/**
|
|
2911
|
+
* Server response
|
|
2912
|
+
*/
|
|
2913
|
+
interface ServerResponse {
|
|
2914
|
+
status: string;
|
|
2915
|
+
message: string;
|
|
2916
|
+
data: {
|
|
2917
|
+
server: ServerInfo;
|
|
2918
|
+
};
|
|
2919
|
+
}
|
|
2920
|
+
/**
|
|
2921
|
+
* Server stop response
|
|
2922
|
+
*/
|
|
2923
|
+
interface ServerStopResponse {
|
|
2924
|
+
status: string;
|
|
2925
|
+
message: string;
|
|
2926
|
+
data: {
|
|
2927
|
+
slug: string;
|
|
2928
|
+
};
|
|
2929
|
+
}
|
|
2930
|
+
/**
|
|
2931
|
+
* Server logs stream type
|
|
2932
|
+
*/
|
|
2933
|
+
type ServerLogStream = 'stdout' | 'stderr' | 'combined';
|
|
2934
|
+
/**
|
|
2935
|
+
* Server logs response
|
|
2936
|
+
*/
|
|
2937
|
+
interface ServerLogsResponse {
|
|
2938
|
+
status: string;
|
|
2939
|
+
message: string;
|
|
2940
|
+
data: {
|
|
2941
|
+
slug: string;
|
|
2942
|
+
stream: ServerLogStream;
|
|
2943
|
+
logs: string;
|
|
2944
|
+
};
|
|
2945
|
+
}
|
|
2946
|
+
/**
|
|
2947
|
+
* Server status update response
|
|
2948
|
+
*/
|
|
2949
|
+
interface ServerStatusUpdateResponse {
|
|
2950
|
+
status: string;
|
|
2951
|
+
message: string;
|
|
2952
|
+
data: {
|
|
2953
|
+
slug: string;
|
|
2954
|
+
status: ServerStatus;
|
|
2955
|
+
};
|
|
2956
|
+
}
|
|
2957
|
+
/**
|
|
2958
|
+
* Environment variables response
|
|
2959
|
+
*/
|
|
2960
|
+
interface EnvGetResponse {
|
|
2961
|
+
status: string;
|
|
2962
|
+
message: string;
|
|
2963
|
+
data: {
|
|
2964
|
+
file: string;
|
|
2965
|
+
variables: Record<string, string>;
|
|
2966
|
+
};
|
|
2967
|
+
}
|
|
2968
|
+
/**
|
|
2969
|
+
* Environment set response
|
|
2970
|
+
*/
|
|
2971
|
+
interface EnvSetResponse {
|
|
2972
|
+
status: string;
|
|
2973
|
+
message: string;
|
|
2974
|
+
data: {
|
|
2975
|
+
file: string;
|
|
2976
|
+
keys: string[];
|
|
2977
|
+
};
|
|
2978
|
+
}
|
|
2979
|
+
/**
|
|
2980
|
+
* Environment delete response
|
|
2981
|
+
*/
|
|
2982
|
+
interface EnvDeleteResponse {
|
|
2983
|
+
status: string;
|
|
2984
|
+
message: string;
|
|
2985
|
+
data: {
|
|
2986
|
+
file: string;
|
|
2987
|
+
keys: string[];
|
|
2988
|
+
};
|
|
2989
|
+
}
|
|
2990
|
+
/**
|
|
2991
|
+
* Batch file operation type
|
|
2992
|
+
*/
|
|
2993
|
+
type BatchFileOperation = 'write' | 'delete';
|
|
2994
|
+
/**
|
|
2995
|
+
* Batch file operation result
|
|
2996
|
+
*/
|
|
2997
|
+
interface BatchWriteResult {
|
|
2998
|
+
path: string;
|
|
2999
|
+
success: boolean;
|
|
3000
|
+
error?: string;
|
|
3001
|
+
file?: FileInfo;
|
|
3002
|
+
}
|
|
3003
|
+
/**
|
|
3004
|
+
* Batch file operation response
|
|
3005
|
+
*/
|
|
3006
|
+
interface BatchWriteResponse {
|
|
3007
|
+
message: string;
|
|
3008
|
+
data: {
|
|
3009
|
+
results: BatchWriteResult[];
|
|
3010
|
+
};
|
|
3011
|
+
}
|
|
3012
|
+
/**
|
|
3013
|
+
* Sandbox - Full-featured gateway sandbox implementation
|
|
3014
|
+
*
|
|
3015
|
+
* Provides complete feature set including:
|
|
3016
|
+
* - Interactive terminals (PTY and exec modes)
|
|
3017
|
+
* - Managed servers
|
|
3018
|
+
* - File watchers with real-time events
|
|
3019
|
+
* - Authentication (session tokens, magic links)
|
|
3020
|
+
* - Environment management
|
|
3021
|
+
* - Signal service for port/error events
|
|
3022
|
+
* - Child sandbox creation
|
|
3023
|
+
*
|
|
3024
|
+
* This is the most feature-rich implementation available.
|
|
3025
|
+
*
|
|
3026
|
+
* @example
|
|
3027
|
+
* ```typescript
|
|
3028
|
+
* import { Sandbox } from 'computesdk'
|
|
3029
|
+
*
|
|
3030
|
+
* // Pattern 1: Admin operations (requires access token)
|
|
3031
|
+
* const sandbox = new Sandbox({
|
|
3032
|
+
* sandboxUrl: 'https://sandbox-123.sandbox.computesdk.com',
|
|
3033
|
+
* token: accessToken, // From edge service
|
|
3034
|
+
* });
|
|
3035
|
+
*
|
|
3036
|
+
* // Create session token for delegated operations
|
|
3037
|
+
* const sessionToken = await sandbox.createSessionToken({
|
|
3038
|
+
* description: 'My Application',
|
|
3039
|
+
* expiresIn: 604800, // 7 days
|
|
3040
|
+
* });
|
|
3041
|
+
*
|
|
3042
|
+
* // Pattern 2: Delegated operations (binary protocol by default)
|
|
3043
|
+
* const sandbox2 = new Sandbox({
|
|
3044
|
+
* sandboxUrl: 'https://sandbox-123.sandbox.computesdk.com',
|
|
3045
|
+
* token: sessionToken.data.token,
|
|
3046
|
+
* // protocol: 'binary' is the default (50-90% size reduction)
|
|
3047
|
+
* });
|
|
3048
|
+
*
|
|
3049
|
+
* // Execute a one-off command
|
|
3050
|
+
* const result = await sandbox.execute({ command: 'ls -la' });
|
|
3051
|
+
* console.log(result.data.stdout);
|
|
3052
|
+
*
|
|
3053
|
+
* // Run code
|
|
3054
|
+
* const codeResult = await sandbox.runCode('console.log("Hello!")', 'node');
|
|
3055
|
+
*
|
|
3056
|
+
* // Work with files
|
|
3057
|
+
* const files = await sandbox.listFiles('/home/project');
|
|
3058
|
+
* await sandbox.writeFile('/home/project/test.txt', 'Hello, World!');
|
|
3059
|
+
* const content = await sandbox.readFile('/home/project/test.txt');
|
|
3060
|
+
*
|
|
3061
|
+
* // Create a PTY terminal with real-time output (interactive shell)
|
|
3062
|
+
* const terminal = await sandbox.createTerminal({ pty: true });
|
|
3063
|
+
* terminal.on('output', (data) => console.log(data));
|
|
3064
|
+
* terminal.write('ls -la\n');
|
|
3065
|
+
* await terminal.destroy();
|
|
3066
|
+
*
|
|
3067
|
+
* // Create an exec terminal for command tracking
|
|
3068
|
+
* const execTerminal = await sandbox.createTerminal({ pty: false });
|
|
3069
|
+
* const result = await execTerminal.execute('npm install', { background: true });
|
|
3070
|
+
* const cmd = await sandbox.getCommand(execTerminal.getId(), result.data.cmd_id);
|
|
3071
|
+
* console.log(cmd.data.status); // "running" | "completed" | "failed"
|
|
3072
|
+
* await execTerminal.destroy();
|
|
3073
|
+
*
|
|
3074
|
+
* // Watch for file changes
|
|
3075
|
+
* const watcher = await sandbox.createWatcher('/home/project', {
|
|
3076
|
+
* ignored: ['node_modules', '.git']
|
|
3077
|
+
* });
|
|
3078
|
+
* watcher.on('change', (event) => {
|
|
3079
|
+
* console.log(`${event.event}: ${event.path}`);
|
|
3080
|
+
* });
|
|
3081
|
+
* await watcher.destroy();
|
|
3082
|
+
*
|
|
3083
|
+
* // Monitor system signals
|
|
3084
|
+
* const signals = await sandbox.startSignals();
|
|
3085
|
+
* signals.on('port', (event) => {
|
|
3086
|
+
* console.log(`Port ${event.port} opened: ${event.url}`);
|
|
3087
|
+
* });
|
|
3088
|
+
* await signals.stop();
|
|
3089
|
+
*
|
|
3090
|
+
* // Clean up
|
|
3091
|
+
* await sandbox.disconnect();
|
|
3092
|
+
* ```
|
|
3093
|
+
*/
|
|
3094
|
+
declare class Sandbox {
|
|
3095
|
+
readonly sandboxId: string;
|
|
3096
|
+
readonly provider: string;
|
|
3097
|
+
readonly filesystem: ExtendedFileSystem;
|
|
3098
|
+
readonly terminal: Terminal;
|
|
3099
|
+
readonly run: Run;
|
|
3100
|
+
readonly server: Server;
|
|
3101
|
+
readonly watcher: Watcher;
|
|
3102
|
+
readonly sessionToken: SessionToken;
|
|
3103
|
+
readonly magicLink: MagicLink;
|
|
3104
|
+
readonly signal: Signal;
|
|
3105
|
+
readonly file: File;
|
|
3106
|
+
readonly env: Env;
|
|
3107
|
+
readonly auth: Auth;
|
|
3108
|
+
readonly child: Child;
|
|
3109
|
+
private config;
|
|
3110
|
+
private _token;
|
|
3111
|
+
private _ws;
|
|
3112
|
+
private WebSocketImpl;
|
|
3113
|
+
private _terminals;
|
|
3114
|
+
constructor(config: SandboxConfig);
|
|
3115
|
+
/**
|
|
3116
|
+
* Get or create internal WebSocket manager
|
|
3117
|
+
*/
|
|
3118
|
+
private ensureWebSocket;
|
|
3119
|
+
/**
|
|
3120
|
+
* Create and configure a TerminalInstance from response data
|
|
3121
|
+
*/
|
|
3122
|
+
private hydrateTerminal;
|
|
3123
|
+
private request;
|
|
3124
|
+
/**
|
|
3125
|
+
* Check service health
|
|
3126
|
+
*/
|
|
3127
|
+
health(): Promise<HealthResponse>;
|
|
3128
|
+
/**
|
|
3129
|
+
* Create a session token (requires access token)
|
|
3130
|
+
*
|
|
3131
|
+
* Session tokens are delegated credentials that can authenticate API requests
|
|
3132
|
+
* without exposing your access token. Only access tokens can create session tokens.
|
|
3133
|
+
*
|
|
3134
|
+
* @param options - Token configuration
|
|
3135
|
+
* @throws {Error} 403 Forbidden if called with a session token
|
|
3136
|
+
*/
|
|
3137
|
+
createSessionToken(options?: {
|
|
3138
|
+
description?: string;
|
|
3139
|
+
expiresIn?: number;
|
|
3140
|
+
}): Promise<SessionTokenResponse>;
|
|
3141
|
+
/**
|
|
3142
|
+
* List all session tokens (requires access token)
|
|
3143
|
+
*
|
|
3144
|
+
* @throws {Error} 403 Forbidden if called with a session token
|
|
3145
|
+
*/
|
|
3146
|
+
listSessionTokens(): Promise<SessionTokenListResponse>;
|
|
3147
|
+
/**
|
|
3148
|
+
* Get details of a specific session token (requires access token)
|
|
3149
|
+
*
|
|
3150
|
+
* @param tokenId - The token ID
|
|
3151
|
+
* @throws {Error} 403 Forbidden if called with a session token
|
|
3152
|
+
*/
|
|
3153
|
+
getSessionToken(tokenId: string): Promise<SessionTokenResponse>;
|
|
3154
|
+
/**
|
|
3155
|
+
* Revoke a session token (requires access token)
|
|
3156
|
+
*
|
|
3157
|
+
* @param tokenId - The token ID to revoke
|
|
3158
|
+
* @throws {Error} 403 Forbidden if called with a session token
|
|
3159
|
+
*/
|
|
3160
|
+
revokeSessionToken(tokenId: string): Promise<void>;
|
|
3161
|
+
/**
|
|
3162
|
+
* Generate a magic link for browser authentication (requires access token)
|
|
3163
|
+
*
|
|
3164
|
+
* Magic links are one-time URLs that automatically create a session token
|
|
3165
|
+
* and set it as a cookie in the user's browser. This provides an easy way
|
|
3166
|
+
* to authenticate users in browser-based applications.
|
|
3167
|
+
*
|
|
3168
|
+
* The generated link:
|
|
3169
|
+
* - Expires after 5 minutes or first use (whichever comes first)
|
|
3170
|
+
* - Automatically creates a new session token (7 day expiry)
|
|
3171
|
+
* - Sets the session token as an HttpOnly cookie
|
|
3172
|
+
* - Redirects to the specified URL
|
|
3173
|
+
*
|
|
3174
|
+
* @param options - Magic link configuration
|
|
3175
|
+
* @throws {Error} 403 Forbidden if called with a session token
|
|
3176
|
+
*/
|
|
3177
|
+
createMagicLink(options?: {
|
|
3178
|
+
redirectUrl?: string;
|
|
3179
|
+
}): Promise<MagicLinkResponse>;
|
|
3180
|
+
/**
|
|
3181
|
+
* Check authentication status
|
|
3182
|
+
* Does not require authentication
|
|
3183
|
+
*/
|
|
3184
|
+
getAuthStatus(): Promise<AuthStatusResponse>;
|
|
3185
|
+
/**
|
|
3186
|
+
* Get authentication information and usage instructions
|
|
3187
|
+
* Does not require authentication
|
|
3188
|
+
*/
|
|
3189
|
+
getAuthInfo(): Promise<AuthInfoResponse>;
|
|
3190
|
+
/**
|
|
3191
|
+
* Set authentication token manually
|
|
3192
|
+
* @param token - Access token or session token
|
|
3193
|
+
*/
|
|
3194
|
+
setToken(token: string): void;
|
|
3195
|
+
/**
|
|
3196
|
+
* Get current authentication token
|
|
3197
|
+
*/
|
|
3198
|
+
getToken(): string | null;
|
|
3199
|
+
/**
|
|
3200
|
+
* Get current sandbox URL
|
|
3201
|
+
*/
|
|
3202
|
+
getSandboxUrl(): string;
|
|
3203
|
+
/**
|
|
3204
|
+
* Execute a one-off command without creating a persistent terminal
|
|
3205
|
+
*
|
|
3206
|
+
* @example
|
|
3207
|
+
* ```typescript
|
|
3208
|
+
* // Synchronous execution (waits for completion)
|
|
3209
|
+
* const result = await sandbox.execute({ command: 'npm test' });
|
|
3210
|
+
* console.log(result.data.exit_code);
|
|
3211
|
+
*
|
|
3212
|
+
* // Background execution (returns immediately)
|
|
3213
|
+
* const result = await sandbox.execute({
|
|
3214
|
+
* command: 'npm install',
|
|
3215
|
+
* background: true
|
|
3216
|
+
* });
|
|
3217
|
+
* // Use result.data.terminal_id and result.data.cmd_id to track
|
|
3218
|
+
* const cmd = await sandbox.getCommand(result.data.terminal_id!, result.data.cmd_id!);
|
|
3219
|
+
* ```
|
|
3220
|
+
*/
|
|
3221
|
+
execute(options: {
|
|
3222
|
+
command: string;
|
|
3223
|
+
shell?: string;
|
|
3224
|
+
background?: boolean;
|
|
3225
|
+
}): Promise<CommandExecutionResponse>;
|
|
3226
|
+
/**
|
|
3227
|
+
* Execute code with automatic language detection (POST /run/code)
|
|
3228
|
+
*
|
|
3229
|
+
* @param code - The code to execute
|
|
3230
|
+
* @param language - Programming language (optional - auto-detects if not specified)
|
|
3231
|
+
* @returns Code execution result with output, exit code, and detected language
|
|
3232
|
+
*
|
|
3233
|
+
* @example
|
|
3234
|
+
* ```typescript
|
|
3235
|
+
* // Auto-detect language
|
|
3236
|
+
* const result = await sandbox.runCodeRequest('print("Hello")');
|
|
3237
|
+
* console.log(result.data.output); // "Hello\n"
|
|
3238
|
+
* console.log(result.data.language); // "python"
|
|
3239
|
+
*
|
|
3240
|
+
* // Explicit language
|
|
3241
|
+
* const result = await sandbox.runCodeRequest('console.log("Hi")', 'node');
|
|
3242
|
+
* ```
|
|
3243
|
+
*/
|
|
3244
|
+
runCodeRequest(code: string, language?: string): Promise<CodeExecutionResponse>;
|
|
3245
|
+
/**
|
|
3246
|
+
* Execute a command and get the result
|
|
3247
|
+
* Lower-level method that returns the raw API response
|
|
3248
|
+
*
|
|
3249
|
+
* @param options.command - Command to execute
|
|
3250
|
+
* @param options.shell - Shell to use (optional)
|
|
3251
|
+
* @param options.background - Run in background (optional)
|
|
3252
|
+
* @param options.cwd - Working directory for the command (optional)
|
|
3253
|
+
* @param options.env - Environment variables (optional)
|
|
3254
|
+
* @returns Command execution result
|
|
3255
|
+
*
|
|
3256
|
+
* @example
|
|
3257
|
+
* ```typescript
|
|
3258
|
+
* const result = await sandbox.runCommandRequest({ command: 'ls -la' });
|
|
3259
|
+
* console.log(result.data.stdout);
|
|
3260
|
+
* ```
|
|
3261
|
+
*/
|
|
3262
|
+
runCommandRequest(options: {
|
|
3263
|
+
command: string;
|
|
3264
|
+
shell?: string;
|
|
3265
|
+
background?: boolean;
|
|
3266
|
+
stream?: boolean;
|
|
3267
|
+
cwd?: string;
|
|
3268
|
+
env?: Record<string, string>;
|
|
3269
|
+
}): Promise<CommandExecutionResponse>;
|
|
3270
|
+
/**
|
|
3271
|
+
* List files at the specified path
|
|
3272
|
+
*/
|
|
3273
|
+
listFiles(path?: string): Promise<FilesListResponse>;
|
|
3274
|
+
/**
|
|
3275
|
+
* Create a new file with optional content
|
|
3276
|
+
*/
|
|
3277
|
+
createFile(path: string, content?: string): Promise<FileResponse>;
|
|
3278
|
+
/**
|
|
3279
|
+
* Get file metadata (without content)
|
|
3280
|
+
*/
|
|
3281
|
+
getFile(path: string): Promise<FileResponse>;
|
|
3282
|
+
/**
|
|
3283
|
+
* Encode a file path for use in URLs
|
|
3284
|
+
* Strips leading slash and encodes each segment separately to preserve path structure
|
|
3285
|
+
*/
|
|
3286
|
+
private encodeFilePath;
|
|
3287
|
+
/**
|
|
3288
|
+
* Read file content
|
|
3289
|
+
*/
|
|
3290
|
+
readFile(path: string): Promise<string>;
|
|
3291
|
+
/**
|
|
3292
|
+
* Write file content (creates or updates)
|
|
3293
|
+
*/
|
|
3294
|
+
writeFile(path: string, content: string): Promise<FileResponse>;
|
|
3295
|
+
/**
|
|
3296
|
+
* Delete a file or directory
|
|
3297
|
+
*/
|
|
3298
|
+
deleteFile(path: string): Promise<void>;
|
|
3299
|
+
/**
|
|
3300
|
+
* Check if a file exists (HEAD request)
|
|
3301
|
+
* @returns true if file exists, false otherwise
|
|
3302
|
+
*/
|
|
3303
|
+
checkFileExists(path: string): Promise<boolean>;
|
|
3304
|
+
/**
|
|
3305
|
+
* Batch file operations (write or delete multiple files)
|
|
3306
|
+
*
|
|
3307
|
+
* Features:
|
|
3308
|
+
* - Deduplication: Last operation wins per path
|
|
3309
|
+
* - File locking: Prevents race conditions
|
|
3310
|
+
* - Deterministic ordering: Alphabetical path sorting
|
|
3311
|
+
* - Partial failure handling: Returns 207 Multi-Status with per-file results
|
|
3312
|
+
*
|
|
3313
|
+
* @param files - Array of file operations
|
|
3314
|
+
* @returns Results for each file operation
|
|
3315
|
+
*
|
|
3316
|
+
* @example
|
|
3317
|
+
* ```typescript
|
|
3318
|
+
* // Write multiple files
|
|
3319
|
+
* const results = await sandbox.batchWriteFiles([
|
|
3320
|
+
* { path: '/app/file1.txt', operation: 'write', content: 'Hello' },
|
|
3321
|
+
* { path: '/app/file2.txt', operation: 'write', content: 'World' },
|
|
3322
|
+
* ]);
|
|
3323
|
+
*
|
|
3324
|
+
* // Mixed operations (write and delete)
|
|
3325
|
+
* const results = await sandbox.batchWriteFiles([
|
|
3326
|
+
* { path: '/app/new.txt', operation: 'write', content: 'New file' },
|
|
3327
|
+
* { path: '/app/old.txt', operation: 'delete' },
|
|
3328
|
+
* ]);
|
|
3329
|
+
* ```
|
|
3330
|
+
*/
|
|
3331
|
+
batchWriteFiles(files: Array<{
|
|
3332
|
+
path: string;
|
|
3333
|
+
operation: 'write' | 'delete';
|
|
3334
|
+
content?: string;
|
|
3335
|
+
}>): Promise<BatchWriteResponse>;
|
|
3336
|
+
/**
|
|
3337
|
+
* Create a new filesystem overlay from a template directory
|
|
3338
|
+
*
|
|
3339
|
+
* Overlays enable instant sandbox setup by symlinking template files first,
|
|
3340
|
+
* then copying heavy directories (node_modules, .venv, etc.) in the background.
|
|
3341
|
+
*
|
|
3342
|
+
* @param options - Overlay creation options
|
|
3343
|
+
* @param options.source - Absolute path to source directory (template)
|
|
3344
|
+
* @param options.target - Relative path in sandbox where overlay will be mounted
|
|
3345
|
+
* @returns Overlay response with copy status
|
|
3346
|
+
*
|
|
3347
|
+
* @example
|
|
3348
|
+
* ```typescript
|
|
3349
|
+
* // Prefer using sandbox.filesystem.overlay.create() for camelCase response
|
|
3350
|
+
* const overlay = await sandbox.filesystem.overlay.create({
|
|
3351
|
+
* source: '/templates/nextjs',
|
|
3352
|
+
* target: 'project',
|
|
3353
|
+
* });
|
|
3354
|
+
* console.log(overlay.copyStatus); // 'pending' | 'in_progress' | 'complete' | 'failed'
|
|
3355
|
+
* ```
|
|
3356
|
+
*/
|
|
3357
|
+
createOverlay(options: CreateOverlayOptions): Promise<OverlayResponse>;
|
|
3358
|
+
/**
|
|
3359
|
+
* List all filesystem overlays for the current sandbox
|
|
3360
|
+
* @returns List of overlays with their copy status
|
|
3361
|
+
*/
|
|
3362
|
+
listOverlays(): Promise<OverlayListResponse>;
|
|
3363
|
+
/**
|
|
3364
|
+
* Get a specific filesystem overlay by ID
|
|
3365
|
+
*
|
|
3366
|
+
* Useful for polling the copy status of an overlay.
|
|
3367
|
+
*
|
|
3368
|
+
* @param id - Overlay ID
|
|
3369
|
+
* @returns Overlay details with current copy status
|
|
3370
|
+
*/
|
|
3371
|
+
getOverlay(id: string): Promise<OverlayResponse>;
|
|
3372
|
+
/**
|
|
3373
|
+
* Delete a filesystem overlay
|
|
3374
|
+
* @param id - Overlay ID
|
|
3375
|
+
*/
|
|
3376
|
+
deleteOverlay(id: string): Promise<void>;
|
|
3377
|
+
/**
|
|
3378
|
+
* Create a new persistent terminal session
|
|
3379
|
+
*
|
|
3380
|
+
* Terminal Modes:
|
|
3381
|
+
* - **PTY mode** (pty: true): Interactive shell with real-time WebSocket streaming
|
|
3382
|
+
* - Use for: Interactive shells, vim/nano, real-time output
|
|
3383
|
+
* - Methods: write(), resize(), on('output')
|
|
3384
|
+
*
|
|
3385
|
+
* - **Exec mode** (pty: false, default): Command tracking with HTTP polling
|
|
3386
|
+
* - Use for: CI/CD, automation, command tracking, exit codes
|
|
3387
|
+
* - Methods: execute(), getCommand(), listCommands(), waitForCommand()
|
|
3388
|
+
*
|
|
3389
|
+
* @example
|
|
3390
|
+
* ```typescript
|
|
3391
|
+
* // PTY mode - Interactive shell
|
|
3392
|
+
* const pty = await sandbox.createTerminal({ pty: true, shell: '/bin/bash' });
|
|
3393
|
+
* pty.on('output', (data) => console.log(data));
|
|
3394
|
+
* pty.write('npm install\n');
|
|
3395
|
+
*
|
|
3396
|
+
* // Exec mode - Command tracking
|
|
3397
|
+
* const exec = await sandbox.createTerminal({ pty: false });
|
|
3398
|
+
* const result = await exec.execute('npm test', { background: true });
|
|
3399
|
+
* const cmd = await sandbox.waitForCommand(exec.getId(), result.data.cmd_id);
|
|
3400
|
+
* console.log(cmd.data.exit_code);
|
|
3401
|
+
*
|
|
3402
|
+
* // Backward compatible - creates PTY terminal
|
|
3403
|
+
* const terminal = await sandbox.createTerminal('/bin/bash');
|
|
3404
|
+
* ```
|
|
3405
|
+
*
|
|
3406
|
+
* @param options - Terminal creation options
|
|
3407
|
+
* @param options.shell - Shell to use (e.g., '/bin/bash', '/bin/sh') - PTY mode only
|
|
3408
|
+
* @param options.encoding - Encoding for terminal I/O: 'raw' (default) or 'base64' (binary-safe)
|
|
3409
|
+
* @param options.pty - Terminal mode: true = PTY (interactive shell), false = exec (command tracking, default)
|
|
3410
|
+
* @returns Terminal instance with event handling
|
|
3411
|
+
*/
|
|
3412
|
+
createTerminal(shellOrOptions?: string | {
|
|
3413
|
+
shell?: string;
|
|
3414
|
+
encoding?: 'raw' | 'base64';
|
|
3415
|
+
pty?: boolean;
|
|
3416
|
+
}, encoding?: 'raw' | 'base64'): Promise<TerminalInstance>;
|
|
3417
|
+
/**
|
|
3418
|
+
* List all active terminals (fetches from API)
|
|
3419
|
+
*/
|
|
3420
|
+
listTerminals(): Promise<TerminalResponse[]>;
|
|
3421
|
+
/**
|
|
3422
|
+
* Get terminal by ID
|
|
3423
|
+
*/
|
|
3424
|
+
getTerminal(id: string): Promise<TerminalInstance>;
|
|
3425
|
+
/**
|
|
3426
|
+
* List all commands executed in a terminal (exec mode only)
|
|
3427
|
+
* @param terminalId - The terminal ID
|
|
3428
|
+
* @returns List of all commands with their status
|
|
3429
|
+
* @throws {Error} If terminal is in PTY mode (command tracking not available)
|
|
3430
|
+
*/
|
|
3431
|
+
listCommands(terminalId: string): Promise<CommandsListResponse>;
|
|
3432
|
+
/**
|
|
3433
|
+
* Get details of a specific command execution (exec mode only)
|
|
3434
|
+
* @param terminalId - The terminal ID
|
|
3435
|
+
* @param cmdId - The command ID
|
|
3436
|
+
* @returns Command execution details including stdout, stderr, and exit code
|
|
3437
|
+
* @throws {Error} If terminal is in PTY mode or command not found
|
|
3438
|
+
*/
|
|
3439
|
+
getCommand(terminalId: string, cmdId: string): Promise<CommandDetailsResponse>;
|
|
3440
|
+
/**
|
|
3441
|
+
* Wait for a command to complete (HTTP long-polling, exec mode only)
|
|
3442
|
+
* @param terminalId - The terminal ID
|
|
3443
|
+
* @param cmdId - The command ID
|
|
3444
|
+
* @param timeout - Optional timeout in seconds (0 = no timeout)
|
|
3445
|
+
* @returns Command execution details when completed
|
|
3446
|
+
* @throws {Error} If terminal is in PTY mode, command not found, or timeout occurs
|
|
3447
|
+
*/
|
|
3448
|
+
waitForCommand(terminalId: string, cmdId: string, timeout?: number): Promise<CommandDetailsResponse>;
|
|
3449
|
+
/**
|
|
3450
|
+
* Wait for a background command to complete using long-polling
|
|
3451
|
+
*
|
|
3452
|
+
* Uses the server's long-polling endpoint with configurable timeout.
|
|
3453
|
+
* The tunnel supports up to 5 minutes (300 seconds) via X-Request-Timeout header.
|
|
3454
|
+
*
|
|
3455
|
+
* @param terminalId - The terminal ID
|
|
3456
|
+
* @param cmdId - The command ID
|
|
3457
|
+
* @param options - Wait options (timeoutSeconds, default 300)
|
|
3458
|
+
* @returns Command result with final status
|
|
3459
|
+
* @throws Error if command fails or times out
|
|
3460
|
+
* @internal
|
|
3461
|
+
*/
|
|
3462
|
+
private waitForCommandCompletion;
|
|
3463
|
+
/**
|
|
3464
|
+
* Wait for a command with extended timeout support
|
|
3465
|
+
* Uses X-Request-Timeout header for tunnel timeout configuration
|
|
3466
|
+
* @internal
|
|
3467
|
+
*/
|
|
3468
|
+
private waitForCommandWithTimeout;
|
|
3469
|
+
/**
|
|
3470
|
+
* Create a new file watcher with WebSocket integration
|
|
3471
|
+
* @param path - Path to watch
|
|
3472
|
+
* @param options - Watcher options
|
|
3473
|
+
* @param options.includeContent - Include file content in change events
|
|
3474
|
+
* @param options.ignored - Patterns to ignore
|
|
3475
|
+
* @param options.encoding - Encoding for file content: 'raw' (default) or 'base64' (binary-safe)
|
|
3476
|
+
* @returns FileWatcher instance with event handling
|
|
3477
|
+
*/
|
|
3478
|
+
createWatcher(path: string, options?: {
|
|
3479
|
+
includeContent?: boolean;
|
|
3480
|
+
ignored?: string[];
|
|
3481
|
+
encoding?: 'raw' | 'base64';
|
|
3482
|
+
}): Promise<FileWatcher>;
|
|
3483
|
+
/**
|
|
3484
|
+
* List all active file watchers (fetches from API)
|
|
3485
|
+
*/
|
|
3486
|
+
listWatchers(): Promise<WatchersListResponse>;
|
|
3487
|
+
/**
|
|
3488
|
+
* Get file watcher by ID
|
|
3489
|
+
*/
|
|
3490
|
+
getWatcher(id: string): Promise<WatcherResponse>;
|
|
3491
|
+
/**
|
|
3492
|
+
* Start the signal service with WebSocket integration
|
|
3493
|
+
* @returns SignalService instance with event handling
|
|
3494
|
+
*/
|
|
3495
|
+
startSignals(): Promise<SignalService>;
|
|
3496
|
+
/**
|
|
3497
|
+
* Get the signal service status (fetches from API)
|
|
3498
|
+
*/
|
|
3499
|
+
getSignalStatus(): Promise<SignalServiceResponse>;
|
|
3500
|
+
/**
|
|
3501
|
+
* Emit a port signal
|
|
3502
|
+
*/
|
|
3503
|
+
emitPortSignal(port: number, type: 'open' | 'close', url: string): Promise<PortSignalResponse>;
|
|
3504
|
+
/**
|
|
3505
|
+
* Emit a port signal (alternative endpoint using path parameters)
|
|
3506
|
+
*/
|
|
3507
|
+
emitPortSignalAlt(port: number, type: 'open' | 'close'): Promise<PortSignalResponse>;
|
|
3508
|
+
/**
|
|
3509
|
+
* Emit an error signal
|
|
3510
|
+
*/
|
|
3511
|
+
emitErrorSignal(message: string): Promise<GenericSignalResponse>;
|
|
3512
|
+
/**
|
|
3513
|
+
* Emit a server ready signal
|
|
3514
|
+
*/
|
|
3515
|
+
emitServerReadySignal(port: number, url: string): Promise<PortSignalResponse>;
|
|
3516
|
+
/**
|
|
3517
|
+
* Get environment variables from a .env file
|
|
3518
|
+
* @param file - Path to the .env file (relative to sandbox root)
|
|
3519
|
+
*/
|
|
3520
|
+
getEnv(file: string): Promise<EnvGetResponse>;
|
|
3521
|
+
/**
|
|
3522
|
+
* Set (merge) environment variables in a .env file
|
|
3523
|
+
* @param file - Path to the .env file (relative to sandbox root)
|
|
3524
|
+
* @param variables - Key-value pairs to set
|
|
3525
|
+
*/
|
|
3526
|
+
setEnv(file: string, variables: Record<string, string>): Promise<EnvSetResponse>;
|
|
3527
|
+
/**
|
|
3528
|
+
* Delete environment variables from a .env file
|
|
3529
|
+
* @param file - Path to the .env file (relative to sandbox root)
|
|
3530
|
+
* @param keys - Keys to delete
|
|
3531
|
+
*/
|
|
3532
|
+
deleteEnv(file: string, keys: string[]): Promise<EnvDeleteResponse>;
|
|
3533
|
+
/**
|
|
3534
|
+
* Check if an environment file exists (HEAD request)
|
|
3535
|
+
* @param file - Path to the .env file (relative to sandbox root)
|
|
3536
|
+
* @returns true if file exists, false otherwise
|
|
3537
|
+
*/
|
|
3538
|
+
checkEnvFile(file: string): Promise<boolean>;
|
|
3539
|
+
/**
|
|
3540
|
+
* List all managed servers
|
|
3541
|
+
*/
|
|
3542
|
+
listServers(): Promise<ServersListResponse>;
|
|
3543
|
+
/**
|
|
3544
|
+
* Start a new managed server with optional supervisor settings
|
|
3545
|
+
*
|
|
3546
|
+
* @param options - Server configuration
|
|
3547
|
+
* @param options.slug - Unique server identifier
|
|
3548
|
+
* @param options.install - Install command (optional, runs blocking before start, e.g., "npm install")
|
|
3549
|
+
* @param options.start - Command to start the server (e.g., "npm run dev")
|
|
3550
|
+
* @param options.path - Working directory (optional)
|
|
3551
|
+
* @param options.env_file - Path to .env file relative to path (optional)
|
|
3552
|
+
* @param options.environment - Inline environment variables (merged with env_file if both provided)
|
|
3553
|
+
* @param options.port - Requested port (preallocated before start)
|
|
3554
|
+
* @param options.strict_port - If true, fail instead of auto-incrementing when port is taken
|
|
3555
|
+
* @param options.autostart - Auto-start on daemon boot (default: true)
|
|
3556
|
+
* @param options.overlay - Inline overlay to create before starting
|
|
3557
|
+
* @param options.overlays - Additional overlays to create before starting
|
|
3558
|
+
* @param options.depends_on - Overlay IDs this server depends on
|
|
3559
|
+
* @param options.restart_policy - When to automatically restart: 'never' (default), 'on-failure', 'always'
|
|
3560
|
+
* @param options.max_restarts - Maximum restart attempts, 0 = unlimited (default: 0)
|
|
3561
|
+
* @param options.restart_delay_ms - Delay between restart attempts in milliseconds (default: 1000)
|
|
3562
|
+
* @param options.stop_timeout_ms - Graceful shutdown timeout in milliseconds (default: 10000)
|
|
3563
|
+
*
|
|
3564
|
+
* @example
|
|
3565
|
+
* ```typescript
|
|
3566
|
+
* // Basic server
|
|
3567
|
+
* await sandbox.startServer({
|
|
3568
|
+
* slug: 'web',
|
|
3569
|
+
* start: 'npm run dev',
|
|
3570
|
+
* path: '/app',
|
|
3571
|
+
* });
|
|
3572
|
+
*
|
|
3573
|
+
* // With install command and supervisor settings
|
|
3574
|
+
* await sandbox.startServer({
|
|
3575
|
+
* slug: 'api',
|
|
3576
|
+
* install: 'npm install',
|
|
3577
|
+
* start: 'node server.js',
|
|
3578
|
+
* path: '/app',
|
|
3579
|
+
* environment: { NODE_ENV: 'production', PORT: '3000' },
|
|
3580
|
+
* restart_policy: 'on-failure',
|
|
3581
|
+
* max_restarts: 5,
|
|
3582
|
+
* restart_delay_ms: 2000,
|
|
3583
|
+
* stop_timeout_ms: 5000,
|
|
3584
|
+
* });
|
|
3585
|
+
*
|
|
3586
|
+
* // With inline overlay dependencies
|
|
3587
|
+
* await sandbox.startServer({
|
|
3588
|
+
* slug: 'web',
|
|
3589
|
+
* start: 'npm run dev',
|
|
3590
|
+
* path: '/app',
|
|
3591
|
+
* overlay: {
|
|
3592
|
+
* source: '/templates/nextjs',
|
|
3593
|
+
* target: 'app',
|
|
3594
|
+
* strategy: 'smart',
|
|
3595
|
+
* },
|
|
3596
|
+
* });
|
|
3597
|
+
* ```
|
|
3598
|
+
*/
|
|
3599
|
+
startServer(options: {
|
|
3600
|
+
slug: string;
|
|
3601
|
+
install?: string;
|
|
3602
|
+
start: string;
|
|
3603
|
+
path?: string;
|
|
3604
|
+
env_file?: string;
|
|
3605
|
+
environment?: Record<string, string>;
|
|
3606
|
+
port?: number;
|
|
3607
|
+
strict_port?: boolean;
|
|
3608
|
+
autostart?: boolean;
|
|
3609
|
+
overlay?: Omit<CreateOverlayOptions, 'waitForCompletion'>;
|
|
3610
|
+
overlays?: Array<Omit<CreateOverlayOptions, 'waitForCompletion'>>;
|
|
3611
|
+
depends_on?: string[];
|
|
3612
|
+
restart_policy?: RestartPolicy;
|
|
3613
|
+
max_restarts?: number;
|
|
3614
|
+
restart_delay_ms?: number;
|
|
3615
|
+
stop_timeout_ms?: number;
|
|
3616
|
+
}): Promise<ServerResponse>;
|
|
3617
|
+
/**
|
|
3618
|
+
* Get information about a specific server
|
|
3619
|
+
* @param slug - Server slug
|
|
3620
|
+
*/
|
|
3621
|
+
getServer(slug: string): Promise<ServerResponse>;
|
|
3622
|
+
/**
|
|
3623
|
+
* Stop a managed server (non-destructive)
|
|
3624
|
+
* @param slug - Server slug
|
|
3625
|
+
*/
|
|
3626
|
+
stopServer(slug: string): Promise<ServerStopResponse>;
|
|
3627
|
+
/**
|
|
3628
|
+
* Delete a managed server configuration
|
|
3629
|
+
* @param slug - Server slug
|
|
3630
|
+
*/
|
|
3631
|
+
deleteServer(slug: string): Promise<void>;
|
|
3632
|
+
/**
|
|
3633
|
+
* Restart a managed server
|
|
3634
|
+
* @param slug - Server slug
|
|
3635
|
+
*/
|
|
3636
|
+
restartServer(slug: string): Promise<ServerResponse>;
|
|
3637
|
+
/**
|
|
3638
|
+
* Get logs for a managed server
|
|
3639
|
+
* @param slug - Server slug
|
|
3640
|
+
* @param options - Options for log retrieval
|
|
3641
|
+
*/
|
|
3642
|
+
getServerLogs(slug: string, options?: {
|
|
3643
|
+
stream?: ServerLogStream;
|
|
3644
|
+
}): Promise<ServerLogsResponse>;
|
|
3645
|
+
/**
|
|
3646
|
+
* Update server status (internal use)
|
|
3647
|
+
* @param slug - Server slug
|
|
3648
|
+
* @param status - New server status
|
|
3649
|
+
*/
|
|
3650
|
+
updateServerStatus(slug: string, status: ServerStatus): Promise<ServerStatusUpdateResponse>;
|
|
3651
|
+
/**
|
|
3652
|
+
* Get readiness status for autostarted servers and overlays
|
|
3653
|
+
*/
|
|
3654
|
+
ready(): Promise<ReadyResponse>;
|
|
3655
|
+
/**
|
|
3656
|
+
* Create a new sandbox environment
|
|
3657
|
+
*/
|
|
3658
|
+
createSandbox(options?: CreateSandboxOptions$1): Promise<SandboxInfo>;
|
|
3659
|
+
/**
|
|
3660
|
+
* List all sandboxes
|
|
3661
|
+
*/
|
|
3662
|
+
listSandboxes(): Promise<SandboxesListResponse>;
|
|
3663
|
+
/**
|
|
3664
|
+
* Get sandbox details
|
|
3665
|
+
*/
|
|
3666
|
+
getSandbox(subdomain: string): Promise<SandboxInfo>;
|
|
3667
|
+
/**
|
|
3668
|
+
* Delete a sandbox
|
|
3669
|
+
*/
|
|
3670
|
+
deleteSandbox(subdomain: string, deleteFiles?: boolean): Promise<void>;
|
|
3671
|
+
/**
|
|
3672
|
+
* Get WebSocket URL for real-time communication
|
|
3673
|
+
* @private
|
|
3674
|
+
*/
|
|
3675
|
+
private getWebSocketUrl;
|
|
3676
|
+
/**
|
|
3677
|
+
* Execute code in the sandbox (convenience method)
|
|
3678
|
+
*
|
|
3679
|
+
* Delegates to sandbox.run.code() - prefer using that directly for new code.
|
|
3680
|
+
*
|
|
3681
|
+
* @param code - The code to execute
|
|
3682
|
+
* @param language - Programming language (auto-detected if not specified)
|
|
3683
|
+
* @returns Code execution result
|
|
3684
|
+
*/
|
|
3685
|
+
runCode(code: string, language?: 'node' | 'python'): Promise<{
|
|
3686
|
+
output: string;
|
|
3687
|
+
exitCode: number;
|
|
3688
|
+
language: string;
|
|
3689
|
+
}>;
|
|
3690
|
+
/**
|
|
3691
|
+
* Execute shell command in the sandbox
|
|
3692
|
+
*
|
|
3693
|
+
* Sends clean command string to server - no preprocessing or shell wrapping.
|
|
3694
|
+
* The server handles shell invocation, working directory, and backgrounding.
|
|
3695
|
+
*
|
|
3696
|
+
* @param command - The command to execute (raw string, e.g., "npm install")
|
|
3697
|
+
* @param options - Execution options
|
|
3698
|
+
* @param options.background - Run in background (server uses goroutines)
|
|
3699
|
+
* @param options.cwd - Working directory (server uses cmd.Dir)
|
|
3700
|
+
* @param options.env - Environment variables (server uses cmd.Env)
|
|
3701
|
+
* @param options.onStdout - Callback for streaming stdout data
|
|
3702
|
+
* @param options.onStderr - Callback for streaming stderr data
|
|
3703
|
+
* @returns Command execution result
|
|
3704
|
+
*
|
|
3705
|
+
* @example
|
|
3706
|
+
* ```typescript
|
|
3707
|
+
* // Simple command
|
|
3708
|
+
* await sandbox.runCommand('ls -la')
|
|
3709
|
+
*
|
|
3710
|
+
* // With working directory
|
|
3711
|
+
* await sandbox.runCommand('npm install', { cwd: '/app' })
|
|
3712
|
+
*
|
|
3713
|
+
* // Background with env vars
|
|
3714
|
+
* await sandbox.runCommand('node server.js', {
|
|
3715
|
+
* background: true,
|
|
3716
|
+
* env: { PORT: '3000' }
|
|
3717
|
+
* })
|
|
3718
|
+
*
|
|
3719
|
+
* // With streaming output
|
|
3720
|
+
* await sandbox.runCommand('npm install', {
|
|
3721
|
+
* onStdout: (data) => console.log(data),
|
|
3722
|
+
* onStderr: (data) => console.error(data),
|
|
3723
|
+
* })
|
|
3724
|
+
* ```
|
|
3725
|
+
*/
|
|
3726
|
+
runCommand(command: string, options?: {
|
|
3727
|
+
background?: boolean;
|
|
3728
|
+
cwd?: string;
|
|
3729
|
+
env?: Record<string, string>;
|
|
3730
|
+
onStdout?: (data: string) => void;
|
|
3731
|
+
onStderr?: (data: string) => void;
|
|
3732
|
+
}): Promise<{
|
|
3733
|
+
stdout: string;
|
|
3734
|
+
stderr: string;
|
|
3735
|
+
exitCode: number;
|
|
3736
|
+
durationMs: number;
|
|
3737
|
+
}>;
|
|
3738
|
+
/**
|
|
3739
|
+
* Get server information
|
|
3740
|
+
* Returns details about the server including auth status, main subdomain, sandbox count, and version
|
|
3741
|
+
*/
|
|
3742
|
+
getServerInfo(): Promise<InfoResponse>;
|
|
3743
|
+
/**
|
|
3744
|
+
* Get sandbox information
|
|
3745
|
+
*/
|
|
3746
|
+
getInfo(): Promise<{
|
|
3747
|
+
id: string;
|
|
3748
|
+
provider: string;
|
|
3749
|
+
runtime: 'node' | 'python';
|
|
3750
|
+
status: 'running' | 'stopped' | 'error';
|
|
3751
|
+
createdAt: Date;
|
|
3752
|
+
timeout: number;
|
|
3753
|
+
metadata?: Record<string, any>;
|
|
3754
|
+
}>;
|
|
3755
|
+
/**
|
|
3756
|
+
* Get URL for accessing sandbox on a specific port (Sandbox interface method)
|
|
3757
|
+
*/
|
|
3758
|
+
getUrl(options: {
|
|
3759
|
+
port: number;
|
|
3760
|
+
protocol?: string;
|
|
3761
|
+
}): Promise<string>;
|
|
3762
|
+
/**
|
|
3763
|
+
* Get provider instance
|
|
3764
|
+
* Note: Not available when using Sandbox directly - only available through gateway provider
|
|
3765
|
+
*/
|
|
3766
|
+
getProvider(): never;
|
|
3767
|
+
/**
|
|
3768
|
+
* Get native provider instance
|
|
3769
|
+
* Returns the Sandbox itself since this IS the sandbox implementation
|
|
3770
|
+
*/
|
|
3771
|
+
getInstance(): this;
|
|
3772
|
+
/**
|
|
3773
|
+
* Destroy the sandbox (Sandbox interface method)
|
|
3774
|
+
*
|
|
3775
|
+
* If a destroyHandler was provided (e.g., from gateway), calls it to destroy
|
|
3776
|
+
* the sandbox on the backend. Otherwise, only disconnects the WebSocket.
|
|
3777
|
+
*/
|
|
3778
|
+
destroy(): Promise<void>;
|
|
3779
|
+
/**
|
|
3780
|
+
* Disconnect WebSocket
|
|
3781
|
+
*
|
|
3782
|
+
* Note: This only disconnects the WebSocket. Terminals, watchers, and signals
|
|
3783
|
+
* will continue running on the server until explicitly destroyed via their
|
|
3784
|
+
* respective destroy() methods or the DELETE endpoints.
|
|
3785
|
+
*/
|
|
3786
|
+
disconnect(): Promise<void>;
|
|
3787
|
+
}
|
|
3788
|
+
|
|
3789
|
+
/**
|
|
3790
|
+
* Helpers for building setup payloads used by COMPUTESDK_SETUP_B64 or POST /sandboxes
|
|
3791
|
+
*/
|
|
3792
|
+
|
|
3793
|
+
type SetupOverlayConfig = Omit<CreateOverlayOptions, 'waitForCompletion'>;
|
|
3794
|
+
interface SetupPayload {
|
|
3795
|
+
overlays?: SetupOverlayConfig[];
|
|
3796
|
+
servers?: ServerStartOptions[];
|
|
3797
|
+
}
|
|
3798
|
+
interface BuildSetupPayloadOptions {
|
|
3799
|
+
overlays?: CreateOverlayOptions[];
|
|
3800
|
+
servers?: ServerStartOptions[];
|
|
3801
|
+
}
|
|
3802
|
+
/**
|
|
3803
|
+
* Build a setup payload for COMPUTESDK_SETUP_B64 or POST /sandboxes
|
|
3804
|
+
*/
|
|
3805
|
+
declare const buildSetupPayload: (options: BuildSetupPayloadOptions) => SetupPayload;
|
|
3806
|
+
/**
|
|
3807
|
+
* Build and base64-encode a setup payload for COMPUTESDK_SETUP_B64
|
|
3808
|
+
*/
|
|
3809
|
+
declare const encodeSetupPayload: (options: BuildSetupPayloadOptions) => string;
|
|
3810
|
+
|
|
3811
|
+
/**
|
|
3812
|
+
* Unified Provider Configuration
|
|
3813
|
+
*
|
|
3814
|
+
* Single source of truth for all provider auth requirements.
|
|
3815
|
+
* Used by both explicit mode (computesdk) and magic mode (workbench).
|
|
3816
|
+
*/
|
|
3817
|
+
/**
|
|
3818
|
+
* Provider auth requirements
|
|
3819
|
+
*
|
|
3820
|
+
* Structure: { provider: [[option1_vars], [option2_vars], ...] }
|
|
3821
|
+
* - Outer array: OR conditions (any option can satisfy auth)
|
|
3822
|
+
* - Inner arrays: AND conditions (all vars in option must be present)
|
|
3823
|
+
*
|
|
3824
|
+
* Example: vercel: [['OIDC_TOKEN'], ['TOKEN', 'TEAM_ID', 'PROJECT_ID']]
|
|
3825
|
+
* -> Ready if OIDC_TOKEN is set, OR if all three traditional vars are set
|
|
3826
|
+
*/
|
|
3827
|
+
declare const PROVIDER_AUTH: {
|
|
3828
|
+
readonly e2b: readonly [readonly ["E2B_API_KEY"]];
|
|
3829
|
+
readonly modal: readonly [readonly ["MODAL_TOKEN_ID", "MODAL_TOKEN_SECRET"]];
|
|
3830
|
+
readonly railway: readonly [readonly ["RAILWAY_API_KEY", "RAILWAY_PROJECT_ID", "RAILWAY_ENVIRONMENT_ID"]];
|
|
3831
|
+
readonly render: readonly [readonly ["RENDER_API_KEY", "RENDER_OWNER_ID"]];
|
|
3832
|
+
readonly daytona: readonly [readonly ["DAYTONA_API_KEY"]];
|
|
3833
|
+
readonly vercel: readonly [readonly ["VERCEL_OIDC_TOKEN"], readonly ["VERCEL_TOKEN", "VERCEL_TEAM_ID", "VERCEL_PROJECT_ID"]];
|
|
3834
|
+
readonly runloop: readonly [readonly ["RUNLOOP_API_KEY"]];
|
|
3835
|
+
readonly cloudflare: readonly [readonly ["CLOUDFLARE_API_TOKEN", "CLOUDFLARE_ACCOUNT_ID"]];
|
|
3836
|
+
readonly codesandbox: readonly [readonly ["CSB_API_KEY"]];
|
|
3837
|
+
readonly blaxel: readonly [readonly ["BL_API_KEY", "BL_WORKSPACE"]];
|
|
3838
|
+
readonly namespace: readonly [readonly ["NSC_TOKEN"]];
|
|
3839
|
+
};
|
|
3840
|
+
/**
|
|
3841
|
+
* All supported provider names (excluding gateway which is special)
|
|
3842
|
+
*/
|
|
3843
|
+
declare const PROVIDER_NAMES: ProviderName[];
|
|
3844
|
+
/**
|
|
3845
|
+
* Provider name type derived from PROVIDER_AUTH
|
|
3846
|
+
*/
|
|
3847
|
+
type ProviderName = keyof typeof PROVIDER_AUTH;
|
|
3848
|
+
/**
|
|
3849
|
+
* Header mapping for each provider
|
|
3850
|
+
* Maps config field names to HTTP header names
|
|
3851
|
+
*/
|
|
3852
|
+
declare const PROVIDER_HEADERS: Record<ProviderName, Record<string, string>>;
|
|
3853
|
+
/**
|
|
3854
|
+
* Environment variable to config field mapping for each provider
|
|
3855
|
+
*/
|
|
3856
|
+
declare const PROVIDER_ENV_MAP: Record<ProviderName, Record<string, string>>;
|
|
3857
|
+
/**
|
|
3858
|
+
* Dashboard URLs for each provider (for error messages)
|
|
3859
|
+
*/
|
|
3860
|
+
declare const PROVIDER_DASHBOARD_URLS: Record<ProviderName, string>;
|
|
3861
|
+
/**
|
|
3862
|
+
* Check if a provider name is valid
|
|
3863
|
+
*/
|
|
3864
|
+
declare function isValidProvider(name: string): name is ProviderName;
|
|
3865
|
+
/**
|
|
3866
|
+
* Build headers from provider config
|
|
3867
|
+
*/
|
|
3868
|
+
declare function buildProviderHeaders(provider: ProviderName, config: Record<string, string | undefined>): Record<string, string>;
|
|
3869
|
+
/**
|
|
3870
|
+
* Get provider config from environment variables
|
|
3871
|
+
*/
|
|
3872
|
+
declare function getProviderConfigFromEnv(provider: ProviderName): Record<string, string>;
|
|
3873
|
+
/**
|
|
3874
|
+
* Check if provider has complete auth from environment
|
|
3875
|
+
*/
|
|
3876
|
+
declare function isProviderAuthComplete(provider: ProviderName): boolean;
|
|
3877
|
+
/**
|
|
3878
|
+
* Get missing env vars for a provider (returns the option closest to completion)
|
|
3879
|
+
*/
|
|
3880
|
+
declare function getMissingEnvVars(provider: ProviderName): string[];
|
|
3881
|
+
|
|
3882
|
+
/**
|
|
3883
|
+
* Compute API - Gateway HTTP Implementation
|
|
3884
|
+
*
|
|
3885
|
+
* Provides the unified compute.* API using direct HTTP calls to the gateway.
|
|
3886
|
+
* The `compute` export works as both a singleton and a callable function:
|
|
3887
|
+
*
|
|
3888
|
+
* - Singleton: `compute.sandbox.create()` (auto-detects from env vars)
|
|
3889
|
+
* - Callable: `compute({ provider: 'e2b', ... }).sandbox.create()` (explicit config)
|
|
3890
|
+
*/
|
|
3891
|
+
|
|
3892
|
+
/**
|
|
3893
|
+
* Explicit compute configuration for callable mode
|
|
3894
|
+
*/
|
|
3895
|
+
interface ExplicitComputeConfig {
|
|
3896
|
+
/** Provider name to use */
|
|
3897
|
+
provider: ProviderName;
|
|
3898
|
+
/**
|
|
3899
|
+
* ComputeSDK API key (required for gateway mode)
|
|
3900
|
+
* @deprecated Use `computesdkApiKey` for clarity
|
|
3901
|
+
*/
|
|
3902
|
+
apiKey?: string;
|
|
3903
|
+
/** ComputeSDK API key (required for gateway mode) */
|
|
3904
|
+
computesdkApiKey?: string;
|
|
3905
|
+
/** Optional gateway URL override */
|
|
3906
|
+
gatewayUrl?: string;
|
|
3907
|
+
/** HTTP request timeout for gateway calls in milliseconds */
|
|
3908
|
+
requestTimeoutMs?: number;
|
|
3909
|
+
/**
|
|
3910
|
+
* WebSocket implementation for environments without native WebSocket support.
|
|
3911
|
+
* In Node.js < 22, pass the 'ws' package: `import WebSocket from 'ws'`
|
|
3912
|
+
*/
|
|
3913
|
+
WebSocket?: WebSocketConstructor;
|
|
3914
|
+
/** Provider-specific configurations */
|
|
3915
|
+
e2b?: {
|
|
3916
|
+
apiKey?: string;
|
|
3917
|
+
projectId?: string;
|
|
3918
|
+
templateId?: string;
|
|
3919
|
+
};
|
|
3920
|
+
modal?: {
|
|
3921
|
+
tokenId?: string;
|
|
3922
|
+
tokenSecret?: string;
|
|
3923
|
+
};
|
|
3924
|
+
railway?: {
|
|
3925
|
+
apiToken?: string;
|
|
3926
|
+
projectId?: string;
|
|
3927
|
+
environmentId?: string;
|
|
3928
|
+
};
|
|
3929
|
+
render?: {
|
|
3930
|
+
apiKey?: string;
|
|
3931
|
+
serviceId?: string;
|
|
3932
|
+
};
|
|
3933
|
+
daytona?: {
|
|
3934
|
+
apiKey?: string;
|
|
3935
|
+
};
|
|
3936
|
+
vercel?: {
|
|
3937
|
+
oidcToken?: string;
|
|
3938
|
+
token?: string;
|
|
3939
|
+
teamId?: string;
|
|
3940
|
+
projectId?: string;
|
|
3941
|
+
};
|
|
3942
|
+
runloop?: {
|
|
3943
|
+
apiKey?: string;
|
|
3944
|
+
};
|
|
3945
|
+
cloudflare?: {
|
|
3946
|
+
apiToken?: string;
|
|
3947
|
+
accountId?: string;
|
|
3948
|
+
};
|
|
3949
|
+
codesandbox?: {
|
|
3950
|
+
apiKey?: string;
|
|
3951
|
+
};
|
|
3952
|
+
blaxel?: {
|
|
3953
|
+
apiKey?: string;
|
|
3954
|
+
workspace?: string;
|
|
3955
|
+
};
|
|
3956
|
+
namespace?: {
|
|
3957
|
+
token?: string;
|
|
3958
|
+
};
|
|
3959
|
+
}
|
|
3960
|
+
/**
|
|
3961
|
+
* Options for creating a sandbox via the gateway
|
|
3962
|
+
*
|
|
3963
|
+
* Note: Runtime is determined by the provider, not specified at creation time.
|
|
3964
|
+
* Use sandbox.runCode(code, runtime) to specify which runtime to use for execution.
|
|
3965
|
+
*/
|
|
3966
|
+
interface CreateSandboxOptions {
|
|
3967
|
+
timeout?: number;
|
|
3968
|
+
templateId?: string;
|
|
3969
|
+
metadata?: Record<string, any>;
|
|
3970
|
+
envs?: Record<string, string>;
|
|
3971
|
+
name?: string;
|
|
3972
|
+
namespace?: string;
|
|
3973
|
+
directory?: string;
|
|
3974
|
+
overlays?: SetupOverlayConfig[];
|
|
3975
|
+
servers?: ServerStartOptions[];
|
|
3976
|
+
/** Docker image to use for the sandbox (for infrastructure providers like Railway) */
|
|
3977
|
+
image?: string;
|
|
3978
|
+
/** Provider-specific snapshot to create from (e.g., Vercel snapshots) */
|
|
3979
|
+
snapshotId?: string;
|
|
3980
|
+
}
|
|
3981
|
+
/**
|
|
3982
|
+
* Options for finding or creating a named sandbox
|
|
3983
|
+
*/
|
|
3984
|
+
interface FindOrCreateSandboxOptions extends CreateSandboxOptions {
|
|
3985
|
+
name: string;
|
|
3986
|
+
namespace?: string;
|
|
3987
|
+
}
|
|
3988
|
+
/**
|
|
3989
|
+
* Options for finding a named sandbox
|
|
3990
|
+
*/
|
|
3991
|
+
interface FindSandboxOptions {
|
|
3992
|
+
name: string;
|
|
3993
|
+
namespace?: string;
|
|
3994
|
+
}
|
|
3995
|
+
/**
|
|
3996
|
+
* Options for extending sandbox timeout
|
|
3997
|
+
*/
|
|
3998
|
+
interface ExtendTimeoutOptions {
|
|
3999
|
+
duration?: number;
|
|
4000
|
+
}
|
|
4001
|
+
/**
|
|
4002
|
+
* Compute singleton implementation
|
|
4003
|
+
*/
|
|
4004
|
+
declare class ComputeManager {
|
|
4005
|
+
private config;
|
|
4006
|
+
private autoConfigured;
|
|
4007
|
+
/**
|
|
4008
|
+
* Lazy auto-configure from environment if not explicitly configured
|
|
4009
|
+
*/
|
|
4010
|
+
private ensureConfigured;
|
|
4011
|
+
/**
|
|
4012
|
+
* Get gateway config, throwing if not configured
|
|
4013
|
+
*/
|
|
4014
|
+
private getGatewayConfig;
|
|
4015
|
+
/**
|
|
4016
|
+
* Explicitly configure the compute singleton
|
|
4017
|
+
*
|
|
4018
|
+
* @example
|
|
4019
|
+
* ```typescript
|
|
4020
|
+
* import { compute } from 'computesdk';
|
|
4021
|
+
*
|
|
4022
|
+
* compute.setConfig({
|
|
4023
|
+
* provider: 'e2b',
|
|
4024
|
+
* apiKey: 'computesdk_xxx',
|
|
4025
|
+
* e2b: { apiKey: 'e2b_xxx' }
|
|
4026
|
+
* });
|
|
4027
|
+
*
|
|
4028
|
+
* const sandbox = await compute.sandbox.create();
|
|
4029
|
+
* ```
|
|
4030
|
+
*/
|
|
4031
|
+
setConfig(config: ExplicitComputeConfig): void;
|
|
4032
|
+
sandbox: {
|
|
4033
|
+
/**
|
|
4034
|
+
* Create a new sandbox
|
|
4035
|
+
*
|
|
4036
|
+
* @example
|
|
4037
|
+
* ```typescript
|
|
4038
|
+
* const sandbox = await compute.sandbox.create({
|
|
4039
|
+
* directory: '/custom/path',
|
|
4040
|
+
* overlays: [
|
|
4041
|
+
* {
|
|
4042
|
+
* source: '/templates/nextjs',
|
|
4043
|
+
* target: 'app',
|
|
4044
|
+
* strategy: 'smart',
|
|
4045
|
+
* },
|
|
4046
|
+
* ],
|
|
4047
|
+
* servers: [
|
|
4048
|
+
* {
|
|
4049
|
+
* slug: 'web',
|
|
4050
|
+
* start: 'npm run dev',
|
|
4051
|
+
* path: '/app',
|
|
4052
|
+
* },
|
|
4053
|
+
* ],
|
|
4054
|
+
* });
|
|
4055
|
+
* ```
|
|
4056
|
+
*/
|
|
4057
|
+
create: (options?: CreateSandboxOptions) => Promise<Sandbox>;
|
|
4058
|
+
/**
|
|
4059
|
+
* Get an existing sandbox by ID
|
|
4060
|
+
*/
|
|
4061
|
+
getById: (sandboxId: string) => Promise<Sandbox | null>;
|
|
4062
|
+
/**
|
|
4063
|
+
* List all active sandboxes
|
|
4064
|
+
*/
|
|
4065
|
+
list: () => Promise<Sandbox[]>;
|
|
4066
|
+
/**
|
|
4067
|
+
* Destroy a sandbox
|
|
4068
|
+
*/
|
|
4069
|
+
destroy: (sandboxId: string) => Promise<void>;
|
|
4070
|
+
/**
|
|
4071
|
+
* Find existing or create new sandbox by (namespace, name)
|
|
4072
|
+
*/
|
|
4073
|
+
findOrCreate: (options: FindOrCreateSandboxOptions) => Promise<Sandbox>;
|
|
4074
|
+
/**
|
|
4075
|
+
* Find existing sandbox by (namespace, name) without creating
|
|
4076
|
+
*/
|
|
4077
|
+
find: (options: FindSandboxOptions) => Promise<Sandbox | null>;
|
|
4078
|
+
/**
|
|
4079
|
+
* Extend sandbox timeout/expiration
|
|
4080
|
+
*/
|
|
4081
|
+
extendTimeout: (sandboxId: string, options?: ExtendTimeoutOptions) => Promise<void>;
|
|
4082
|
+
};
|
|
4083
|
+
}
|
|
4084
|
+
/**
|
|
4085
|
+
* Callable compute interface - dual nature as both singleton and factory
|
|
4086
|
+
*
|
|
4087
|
+
* This interface represents the compute export's two modes:
|
|
4088
|
+
* 1. As a ComputeManager singleton (accessed via properties like compute.sandbox)
|
|
4089
|
+
* 2. As a factory function (called with config to create new instances)
|
|
4090
|
+
*/
|
|
4091
|
+
interface CallableCompute extends ComputeManager {
|
|
4092
|
+
/** Create a new compute instance with explicit configuration */
|
|
4093
|
+
(config: ExplicitComputeConfig): ComputeManager;
|
|
4094
|
+
/** Explicitly configure the singleton */
|
|
4095
|
+
setConfig(config: ExplicitComputeConfig): void;
|
|
4096
|
+
}
|
|
4097
|
+
/**
|
|
4098
|
+
* Callable compute - works as both singleton and factory function
|
|
4099
|
+
*
|
|
4100
|
+
* @example
|
|
4101
|
+
* ```typescript
|
|
4102
|
+
* import { compute } from 'computesdk';
|
|
4103
|
+
*
|
|
4104
|
+
* // Singleton mode (auto-detects from env vars)
|
|
4105
|
+
* const sandbox1 = await compute.sandbox.create();
|
|
4106
|
+
*
|
|
4107
|
+
* // Callable mode (explicit config)
|
|
4108
|
+
* const sandbox2 = await compute({
|
|
4109
|
+
* provider: 'e2b',
|
|
4110
|
+
* apiKey: 'computesdk_xxx',
|
|
4111
|
+
* e2b: { apiKey: 'e2b_xxx' }
|
|
4112
|
+
* }).sandbox.create();
|
|
4113
|
+
* ```
|
|
4114
|
+
*/
|
|
4115
|
+
declare const compute: CallableCompute;
|
|
4116
|
+
|
|
4117
|
+
/**
|
|
4118
|
+
* Auto-Detection Module
|
|
4119
|
+
*
|
|
4120
|
+
* Automatically detects gateway mode and provider from environment variables.
|
|
4121
|
+
* Enables zero-config usage of ComputeSDK.
|
|
4122
|
+
*/
|
|
4123
|
+
|
|
4124
|
+
/**
|
|
4125
|
+
* Check if gateway mode is enabled
|
|
4126
|
+
* Gateway mode requires COMPUTESDK_API_KEY to be set
|
|
4127
|
+
*/
|
|
4128
|
+
declare function isGatewayModeEnabled(): boolean;
|
|
4129
|
+
/**
|
|
4130
|
+
* Detect which provider to use from environment variables
|
|
4131
|
+
*
|
|
4132
|
+
* Detection order:
|
|
4133
|
+
* 1. Check for explicit COMPUTESDK_PROVIDER override
|
|
4134
|
+
* 2. Auto-detect based on PROVIDER_PRIORITY order
|
|
4135
|
+
*
|
|
4136
|
+
* @returns Provider name or null if none detected
|
|
4137
|
+
*/
|
|
4138
|
+
declare function detectProvider(): string | null;
|
|
4139
|
+
/**
|
|
4140
|
+
* Build provider-specific headers from environment variables
|
|
4141
|
+
* These headers are passed through to the gateway
|
|
4142
|
+
*/
|
|
4143
|
+
declare function getProviderHeaders(provider: string): Record<string, string>;
|
|
4144
|
+
/**
|
|
4145
|
+
* Gateway configuration object
|
|
4146
|
+
*/
|
|
4147
|
+
interface GatewayConfig {
|
|
4148
|
+
apiKey: string;
|
|
4149
|
+
gatewayUrl: string;
|
|
4150
|
+
provider: string;
|
|
4151
|
+
providerHeaders: Record<string, string>;
|
|
4152
|
+
requestTimeoutMs?: number;
|
|
4153
|
+
WebSocket?: WebSocketConstructor;
|
|
4154
|
+
}
|
|
4155
|
+
/**
|
|
4156
|
+
* Main auto-configuration function
|
|
4157
|
+
* Returns gateway configuration or null if auto-detection not possible
|
|
4158
|
+
*
|
|
4159
|
+
* @throws Error if COMPUTESDK_API_KEY is set but no provider detected
|
|
4160
|
+
*/
|
|
4161
|
+
declare function autoConfigureCompute(): GatewayConfig | null;
|
|
4162
|
+
|
|
4163
|
+
/**
|
|
4164
|
+
* ComputeSDK Constants
|
|
4165
|
+
*
|
|
4166
|
+
* Default configuration values and provider definitions
|
|
4167
|
+
*/
|
|
4168
|
+
|
|
4169
|
+
/**
|
|
4170
|
+
* Default gateway URL for sandbox lifecycle operations
|
|
4171
|
+
*/
|
|
4172
|
+
declare const GATEWAY_URL = "https://gateway.computesdk.com";
|
|
4173
|
+
/**
|
|
4174
|
+
* Provider detection priority order
|
|
4175
|
+
* When multiple provider credentials are detected, use the first one in this list
|
|
4176
|
+
*/
|
|
4177
|
+
declare const PROVIDER_PRIORITY: readonly ["e2b", "railway", "render", "daytona", "modal", "runloop", "vercel", "cloudflare", "codesandbox", "blaxel", "namespace"];
|
|
4178
|
+
/**
|
|
4179
|
+
* Required environment variables for each provider
|
|
4180
|
+
* @deprecated Use PROVIDER_AUTH from provider-config instead
|
|
4181
|
+
*/
|
|
4182
|
+
declare const PROVIDER_ENV_VARS: {
|
|
4183
|
+
readonly e2b: readonly ["E2B_API_KEY"];
|
|
4184
|
+
readonly railway: readonly ["RAILWAY_API_KEY", "RAILWAY_PROJECT_ID", "RAILWAY_ENVIRONMENT_ID"];
|
|
4185
|
+
readonly render: readonly ["RENDER_API_KEY", "RENDER_OWNER_ID"];
|
|
4186
|
+
readonly daytona: readonly ["DAYTONA_API_KEY"];
|
|
4187
|
+
readonly modal: readonly ["MODAL_TOKEN_ID", "MODAL_TOKEN_SECRET"];
|
|
4188
|
+
readonly runloop: readonly ["RUNLOOP_API_KEY"];
|
|
4189
|
+
readonly vercel: readonly ["VERCEL_TOKEN", "VERCEL_TEAM_ID", "VERCEL_PROJECT_ID"];
|
|
4190
|
+
readonly cloudflare: readonly ["CLOUDFLARE_API_TOKEN", "CLOUDFLARE_ACCOUNT_ID"];
|
|
4191
|
+
readonly codesandbox: readonly ["CSB_API_KEY"];
|
|
4192
|
+
readonly blaxel: readonly ["BL_API_KEY", "BL_WORKSPACE"];
|
|
4193
|
+
readonly namespace: readonly ["NSC_TOKEN"];
|
|
4194
|
+
};
|
|
715
4195
|
|
|
716
|
-
export {
|
|
4196
|
+
export { type CallableCompute, type CodeResult$1 as CodeResult, CommandExitError, type CommandResult$1 as CommandResult, type CreateSandboxOptions$1 as CreateSandboxOptions, type ExplicitComputeConfig, type FileEntry, FileWatcher, GATEWAY_URL, Sandbox as GatewaySandbox, MessageType, PROVIDER_AUTH, PROVIDER_DASHBOARD_URLS, PROVIDER_ENV_MAP, PROVIDER_ENV_VARS, PROVIDER_HEADERS, PROVIDER_NAMES, PROVIDER_PRIORITY, type ProviderName, type ProviderSandboxInfo, type RunCommandOptions, type Runtime, Sandbox, type SandboxFileSystem, type SandboxInfo$1 as SandboxInfo, type Sandbox$1 as SandboxInterface, type SandboxStatus, type SetupOverlayConfig, type SetupPayload, SignalService, TerminalInstance, type WebSocketConstructor, autoConfigureCompute, buildProviderHeaders, buildSetupPayload, compute, decodeBinaryMessage, detectProvider, encodeBinaryMessage, encodeSetupPayload, getMissingEnvVars, getProviderConfigFromEnv, getProviderHeaders, isCommandExitError, isGatewayModeEnabled, isProviderAuthComplete, isValidProvider };
|