Skip to content

Commit 5512446

Browse files
committed
Add sandbox operations
1 parent 8c5cc1c commit 5512446

21 files changed

Lines changed: 6219 additions & 20 deletions

README.md

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,52 @@ stream.pipe(fs.createWriteStream('./downloaded.txt'));
130130
await storage.delete('myfile.txt');
131131
```
132132

133+
### 7. Sandboxes
134+
135+
Create isolated sandboxes, then drive them with **gRPC**: run shell commands and manage files inside the sandbox VM. The SDK uses TLS to the sandbox `grpcServerUrl` and sends the API key in the `x-api-key` metadata header.
136+
137+
```js
138+
const { YepCodeSandbox } = require('@yepcode/run');
139+
140+
const sandboxes = new YepCodeSandbox({ apiToken: '****' });
141+
142+
const instance = await sandboxes.create({
143+
imageId: 'your-image-id', // required by the API
144+
name: 'my-sandbox',
145+
timeoutMs: 300_000,
146+
publicHttpPorts: [8080],
147+
// Traefik basicAuth `user:secret` — plain `user:password` or hashed (bcrypt $2y$/$2a$, Apache MD5 $apr1$, SHA-1)
148+
publicHttpPortsBasicAuth: 'user:password',
149+
metadata: { purpose: 'demo' },
150+
});
151+
152+
// REST helpers on YepCodeSandbox (by sandbox id)
153+
// await sandboxes.updateTimeout(instance.data.id, { timeoutMs: 120_000 });
154+
// await sandboxes.kill(instance.data.id);
155+
156+
// Instance API (REST + gRPC)
157+
await instance.updateTimeout({ timeoutMs: 120_000 });
158+
159+
await instance.mkDir('/tmp/work');
160+
await instance.uploadFile('/tmp/work/hello.txt', Buffer.from('hello'));
161+
const bytes = await instance.downloadFile('/tmp/work/hello.txt');
162+
163+
const run = await instance.runCommand({
164+
command: 'pwd',
165+
args: [],
166+
workingDirectory: '/',
167+
env: { MY_VAR: 'value' },
168+
});
169+
console.log(run.stdout.toString(), run.exitCode);
170+
171+
await instance.kill();
172+
```
173+
174+
**Behaviour notes**
175+
176+
- `runCommand`, `uploadFile`, `mkDir`, and `downloadFile` wait until gRPC health reports **ready** (poll every 250 ms, up to **10 s**), then reuse that readiness for later calls on the same instance.
177+
- `instance.data` is the current **Sandbox** payload (`grpcServerUrl`, `grpcApiKey`, `id`, `imageId`, etc.); see [SandboxInstance](#sandboxinstance).
178+
133179
## Prompt to use if you are asking LLM to write code
134180

135181
You can use the following prompt to ask LLM to write code that the YepCode Run SDK can execute.
@@ -392,6 +438,114 @@ interface Process {
392438
}
393439
```
394440

441+
### YepCodeSandbox
442+
443+
High-level wrapper around [`YepCodeApi`](#yepcodeapi) for sandbox **REST** operations. `create` returns a [`SandboxInstance`](#sandboxinstance) bound to the same API client for `updateTimeout` / `kill` on that instance.
444+
445+
#### Constructor
446+
447+
```typescript
448+
constructor(config?: YepCodeApiConfig)
449+
```
450+
451+
Uses the same options as [`YepCodeApi`](#yepcodeapi) (`apiToken`, `apiHost`, `teamId`, `clientId` / `clientSecret`, etc.).
452+
453+
#### Methods
454+
455+
| Method | Returns | Description |
456+
|--------|---------|-------------|
457+
| `create(data: CreateSandboxInput)` | `Promise<SandboxInstance>` | Create sandbox and return a connected instance |
458+
| `updateTimeout(id: string, data: UpdateSandboxTimeoutInput)` | `Promise<Sandbox>` | Update timeout by sandbox **id** |
459+
| `kill(id: string)` | `Promise<Sandbox>` | Kill sandbox by **id** |
460+
461+
```typescript
462+
interface CreateSandboxInput {
463+
imageId: string;
464+
name?: string;
465+
metadata?: Record<string, string>;
466+
timeoutMs?: number;
467+
publicHttpPorts?: number[];
468+
/**
469+
* Traefik basicAuth `users` format: `username:passwordOrHash`.
470+
* Plain `user:password` or hashed (Traefik: bcrypt `$2y$` / `$2a$`, Apache MD5 `$apr1$`, SHA-1).
471+
*/
472+
publicHttpPortsBasicAuth?: string;
473+
}
474+
475+
interface UpdateSandboxTimeoutInput {
476+
timeoutMs: number;
477+
}
478+
```
479+
480+
### SandboxInstance
481+
482+
Represents one sandbox. **gRPC** is used for commands and in-VM file storage; **REST** (via the linked `YepCodeApi`) for `updateTimeout` and `kill`.
483+
484+
#### `data` (getter)
485+
486+
Current **Sandbox** record:
487+
488+
```typescript
489+
interface Sandbox {
490+
id: string;
491+
name: string;
492+
grpcServerUrl: string;
493+
grpcApiKey: string;
494+
imageId: string;
495+
publicHttpPorts?: number[];
496+
metadata?: Record<string, string>;
497+
timeoutAt: string;
498+
}
499+
```
500+
501+
#### Methods
502+
503+
| Method | Returns | Description |
504+
|--------|---------|-------------|
505+
| `updateTimeout(input: UpdateSandboxTimeoutInput)` | `Promise<SandboxInstance>` | Refresh timeout; updates `data` |
506+
| `kill()` | `Promise<SandboxInstance>` | Stop sandbox; updates `data` |
507+
| `runCommand(input: RunCommandInput)` | `Promise<RunCommandResult>` | gRPC `RunCommand` (streaming stdout/stderr); waits for health first |
508+
| `uploadFile(path: string, content: Buffer \| Uint8Array)` | `Promise<SandboxStorageUploadResult>` | gRPC client-streaming upload |
509+
| `mkDir(path: string)` | `Promise<SandboxStorageMkDirResult>` | gRPC `MakeDirectory` |
510+
| `downloadFile(path: string)` | `Promise<Buffer>` | gRPC server-streaming download |
511+
512+
```typescript
513+
interface RunCommandInput {
514+
command: string;
515+
args?: string[];
516+
workingDirectory?: string;
517+
env?: Record<string, string>;
518+
background?: boolean;
519+
timeoutSeconds?: number;
520+
}
521+
522+
interface RunCommandResult {
523+
pid?: number;
524+
startedAt?: number;
525+
stdout: Buffer;
526+
stderr: Buffer;
527+
exitCode?: number;
528+
exited?: boolean;
529+
status?: number;
530+
error?: string;
531+
endStartedAt?: number;
532+
finishedAt?: number;
533+
}
534+
535+
interface SandboxStorageUploadResult {
536+
success: boolean;
537+
absolutePath?: string;
538+
bytesWritten?: number;
539+
errorMessage?: string;
540+
}
541+
542+
interface SandboxStorageMkDirResult {
543+
success: boolean;
544+
absolutePath?: string;
545+
errorMessage?: string;
546+
}
547+
```
548+
395549
### YepCodeStorage
396550

397551
Manages file storage in your YepCode workspace. Allows you to upload, list, download, and delete files using the YepCode API.

0 commit comments

Comments
 (0)