@alibaba-group/opensandbox 0.1.0-dev1
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 +212 -0
- package/dist/adapters/commandsAdapter.d.ts +22 -0
- package/dist/adapters/commandsAdapter.d.ts.map +1 -0
- package/dist/adapters/commandsAdapter.js +76 -0
- package/dist/adapters/filesystemAdapter.d.ts +52 -0
- package/dist/adapters/filesystemAdapter.d.ts.map +1 -0
- package/dist/adapters/filesystemAdapter.js +398 -0
- package/dist/adapters/healthAdapter.d.ts +8 -0
- package/dist/adapters/healthAdapter.d.ts.map +1 -0
- package/dist/adapters/healthAdapter.js +25 -0
- package/dist/adapters/metricsAdapter.d.ts +9 -0
- package/dist/adapters/metricsAdapter.d.ts.map +1 -0
- package/dist/adapters/metricsAdapter.js +43 -0
- package/dist/adapters/openapiError.d.ts +5 -0
- package/dist/adapters/openapiError.d.ts.map +1 -0
- package/dist/adapters/openapiError.js +33 -0
- package/dist/adapters/sandboxesAdapter.d.ts +18 -0
- package/dist/adapters/sandboxesAdapter.d.ts.map +1 -0
- package/dist/adapters/sandboxesAdapter.js +146 -0
- package/dist/adapters/sse.d.ts +9 -0
- package/dist/adapters/sse.d.ts.map +1 -0
- package/dist/adapters/sse.js +84 -0
- package/dist/api/execd.d.ts +1555 -0
- package/dist/api/execd.d.ts.map +1 -0
- package/dist/api/execd.js +14 -0
- package/dist/api/lifecycle.d.ts +787 -0
- package/dist/api/lifecycle.d.ts.map +1 -0
- package/dist/api/lifecycle.js +14 -0
- package/dist/config/connection.d.ts +58 -0
- package/dist/config/connection.d.ts.map +1 -0
- package/dist/config/connection.js +171 -0
- package/dist/core/constants.d.ts +9 -0
- package/dist/core/constants.d.ts.map +1 -0
- package/dist/core/constants.js +24 -0
- package/dist/core/exceptions.d.ts +74 -0
- package/dist/core/exceptions.d.ts.map +1 -0
- package/dist/core/exceptions.js +103 -0
- package/dist/factory/adapterFactory.d.ts +33 -0
- package/dist/factory/adapterFactory.d.ts.map +1 -0
- package/dist/factory/adapterFactory.js +14 -0
- package/dist/factory/defaultAdapterFactory.d.ts +7 -0
- package/dist/factory/defaultAdapterFactory.d.ts.map +1 -0
- package/dist/factory/defaultAdapterFactory.js +61 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +20 -0
- package/dist/internal.d.ts +22 -0
- package/dist/internal.d.ts.map +1 -0
- package/dist/internal.js +30 -0
- package/dist/manager.d.ts +40 -0
- package/dist/manager.d.ts.map +1 -0
- package/dist/manager.js +71 -0
- package/dist/models/execd.d.ts +54 -0
- package/dist/models/execd.d.ts.map +1 -0
- package/dist/models/execd.js +14 -0
- package/dist/models/execution.d.ts +52 -0
- package/dist/models/execution.d.ts.map +1 -0
- package/dist/models/execution.js +14 -0
- package/dist/models/executionEventDispatcher.d.ts +15 -0
- package/dist/models/executionEventDispatcher.d.ts.map +1 -0
- package/dist/models/executionEventDispatcher.js +95 -0
- package/dist/models/filesystem.d.ts +77 -0
- package/dist/models/filesystem.d.ts.map +1 -0
- package/dist/models/filesystem.js +14 -0
- package/dist/models/sandboxes.d.ts +105 -0
- package/dist/models/sandboxes.d.ts.map +1 -0
- package/dist/models/sandboxes.js +15 -0
- package/dist/openapi/execdClient.d.ts +25 -0
- package/dist/openapi/execdClient.d.ts.map +1 -0
- package/dist/openapi/execdClient.js +21 -0
- package/dist/openapi/lifecycleClient.d.ts +28 -0
- package/dist/openapi/lifecycleClient.d.ts.map +1 -0
- package/dist/openapi/lifecycleClient.js +35 -0
- package/dist/sandbox.d.ts +132 -0
- package/dist/sandbox.d.ts.map +1 -0
- package/dist/sandbox.js +250 -0
- package/dist/services/execdCommands.d.ts +19 -0
- package/dist/services/execdCommands.d.ts.map +1 -0
- package/dist/services/execdCommands.js +14 -0
- package/dist/services/execdHealth.d.ts +4 -0
- package/dist/services/execdHealth.d.ts.map +1 -0
- package/dist/services/execdHealth.js +14 -0
- package/dist/services/execdMetrics.d.ts +5 -0
- package/dist/services/execdMetrics.d.ts.map +1 -0
- package/dist/services/execdMetrics.js +14 -0
- package/dist/services/filesystem.d.ts +30 -0
- package/dist/services/filesystem.d.ts.map +1 -0
- package/dist/services/filesystem.js +14 -0
- package/dist/services/sandboxes.d.ts +12 -0
- package/dist/services/sandboxes.d.ts.map +1 -0
- package/dist/services/sandboxes.js +14 -0
- package/package.json +52 -0
package/README.md
ADDED
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
# Alibaba Sandbox SDK for JavaScript/TypeScript
|
|
2
|
+
|
|
3
|
+
English | [中文](README_zh.md)
|
|
4
|
+
|
|
5
|
+
A TypeScript/JavaScript SDK for low-level interaction with OpenSandbox. It provides the ability to create, manage, and interact with secure sandbox environments, including executing shell commands, managing files, and reading resource metrics.
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
### npm
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install @alibaba-group/opensandbox
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
### pnpm
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
pnpm add @alibaba-group/opensandbox
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
### yarn
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
yarn add @alibaba-group/opensandbox
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Quick Start
|
|
28
|
+
|
|
29
|
+
The following example shows how to create a sandbox and execute a shell command.
|
|
30
|
+
|
|
31
|
+
> **Note**: Before running this example, ensure the OpenSandbox service is running. See the root [README.md](../../../README.md) for startup instructions.
|
|
32
|
+
|
|
33
|
+
```ts
|
|
34
|
+
import { ConnectionConfig, Sandbox, SandboxException } from "@alibaba-group/opensandbox";
|
|
35
|
+
|
|
36
|
+
const config = new ConnectionConfig({
|
|
37
|
+
domain: "api.opensandbox.io",
|
|
38
|
+
apiKey: "your-api-key",
|
|
39
|
+
// protocol: "https",
|
|
40
|
+
// requestTimeoutSeconds: 60,
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
try {
|
|
44
|
+
const sandbox = await Sandbox.create({
|
|
45
|
+
connectionConfig: config,
|
|
46
|
+
image: "ubuntu",
|
|
47
|
+
timeoutSeconds: 10 * 60,
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
const execution = await sandbox.commands.run("echo 'Hello Sandbox!'");
|
|
51
|
+
console.log(execution.logs.stdout[0]?.text);
|
|
52
|
+
|
|
53
|
+
// Optional but recommended: terminate the remote instance when you are done.
|
|
54
|
+
await sandbox.kill();
|
|
55
|
+
} catch (err) {
|
|
56
|
+
if (err instanceof SandboxException) {
|
|
57
|
+
console.error(`Sandbox Error: [${err.error.code}] ${err.error.message ?? ""}`);
|
|
58
|
+
} else {
|
|
59
|
+
console.error(err);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Usage Examples
|
|
65
|
+
|
|
66
|
+
### 1. Lifecycle Management
|
|
67
|
+
|
|
68
|
+
Manage the sandbox lifecycle, including renewal, pausing, and resuming.
|
|
69
|
+
|
|
70
|
+
```ts
|
|
71
|
+
const info = await sandbox.getInfo();
|
|
72
|
+
console.log("State:", info.status.state);
|
|
73
|
+
console.log("Created:", info.createdAt);
|
|
74
|
+
console.log("Expires:", info.expiresAt);
|
|
75
|
+
|
|
76
|
+
await sandbox.pause();
|
|
77
|
+
|
|
78
|
+
// Resume returns a fresh, connected Sandbox instance.
|
|
79
|
+
const resumed = await sandbox.resume();
|
|
80
|
+
|
|
81
|
+
// Renew: expiresAt = now + timeoutSeconds
|
|
82
|
+
await resumed.renew(30 * 60);
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### 2. Custom Health Check
|
|
86
|
+
|
|
87
|
+
Define custom logic to determine whether the sandbox is ready/healthy. This overrides the default ping check used during readiness checks.
|
|
88
|
+
|
|
89
|
+
```ts
|
|
90
|
+
const sandbox = await Sandbox.create({
|
|
91
|
+
connectionConfig: config,
|
|
92
|
+
image: "nginx:latest",
|
|
93
|
+
healthCheck: async (sbx) => {
|
|
94
|
+
// Example: consider the sandbox healthy when port 80 endpoint becomes available
|
|
95
|
+
const ep = await sbx.getEndpoint(80);
|
|
96
|
+
return !!ep.endpoint;
|
|
97
|
+
},
|
|
98
|
+
});
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### 3. Command Execution & Streaming
|
|
102
|
+
|
|
103
|
+
Execute commands and handle output streams in real-time.
|
|
104
|
+
|
|
105
|
+
```ts
|
|
106
|
+
import type { ExecutionHandlers } from "@alibaba-group/opensandbox";
|
|
107
|
+
|
|
108
|
+
const handlers: ExecutionHandlers = {
|
|
109
|
+
onStdout: (m) => console.log("STDOUT:", m.text),
|
|
110
|
+
onStderr: (m) => console.error("STDERR:", m.text),
|
|
111
|
+
onExecutionComplete: (c) => console.log("Finished in", c.executionTimeMs, "ms"),
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
await sandbox.commands.run(
|
|
115
|
+
'for i in 1 2 3; do echo "Count $i"; sleep 0.2; done',
|
|
116
|
+
undefined,
|
|
117
|
+
handlers,
|
|
118
|
+
);
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### 4. Comprehensive File Operations
|
|
122
|
+
|
|
123
|
+
Manage files and directories, including read, write, list/search, and delete.
|
|
124
|
+
|
|
125
|
+
```ts
|
|
126
|
+
await sandbox.files.createDirectories([{ path: "/tmp/demo", mode: 0o755 }]);
|
|
127
|
+
|
|
128
|
+
await sandbox.files.writeFiles([
|
|
129
|
+
{ path: "/tmp/demo/hello.txt", data: "Hello World", mode: 0o644 },
|
|
130
|
+
]);
|
|
131
|
+
|
|
132
|
+
const content = await sandbox.files.readFile("/tmp/demo/hello.txt");
|
|
133
|
+
console.log("Content:", content);
|
|
134
|
+
|
|
135
|
+
const files = await sandbox.files.search({ path: "/tmp/demo", pattern: "*.txt" });
|
|
136
|
+
console.log(files.map((f) => f.path));
|
|
137
|
+
|
|
138
|
+
await sandbox.files.deleteDirectories(["/tmp/demo"]);
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### 5. Endpoints
|
|
142
|
+
|
|
143
|
+
`getEndpoint()` returns an endpoint **without a scheme** (for example `"localhost:44772"`). Use `getEndpointUrl()` if you want a ready-to-use absolute URL (for example `"http://localhost:44772"`).
|
|
144
|
+
|
|
145
|
+
```ts
|
|
146
|
+
const { endpoint } = await sandbox.getEndpoint(44772);
|
|
147
|
+
const url = await sandbox.getEndpointUrl(44772);
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### 6. Sandbox Management (Admin)
|
|
151
|
+
|
|
152
|
+
Use `SandboxManager` for administrative tasks and finding existing sandboxes.
|
|
153
|
+
|
|
154
|
+
```ts
|
|
155
|
+
import { SandboxManager } from "@alibaba-group/opensandbox";
|
|
156
|
+
|
|
157
|
+
const manager = SandboxManager.create({ connectionConfig: config });
|
|
158
|
+
const list = await manager.listSandboxInfos({ states: ["Running"], pageSize: 10 });
|
|
159
|
+
console.log(list.items.map((s) => s.id));
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
## Configuration
|
|
163
|
+
|
|
164
|
+
### 1. Connection Configuration
|
|
165
|
+
|
|
166
|
+
The `ConnectionConfig` class manages API server connection settings.
|
|
167
|
+
|
|
168
|
+
| Parameter | Description | Default | Environment Variable |
|
|
169
|
+
| --- | --- | --- | --- |
|
|
170
|
+
| `apiKey` | API key for authentication | Optional | `OPEN_SANDBOX_API_KEY` |
|
|
171
|
+
| `domain` | Sandbox service domain (`host[:port]`) | `localhost:8080` | `OPEN_SANDBOX_DOMAIN` |
|
|
172
|
+
| `protocol` | HTTP protocol (`http`/`https`) | `http` | - |
|
|
173
|
+
| `requestTimeoutSeconds` | Request timeout applied to SDK HTTP calls | `30` | - |
|
|
174
|
+
| `debug` | Enable basic HTTP debug logging | `false` | - |
|
|
175
|
+
| `headers` | Extra headers applied to every request | `{}` | - |
|
|
176
|
+
|
|
177
|
+
```ts
|
|
178
|
+
import { ConnectionConfig } from "@alibaba-group/opensandbox";
|
|
179
|
+
|
|
180
|
+
// 1. Basic configuration
|
|
181
|
+
const config = new ConnectionConfig({
|
|
182
|
+
domain: "api.opensandbox.io",
|
|
183
|
+
apiKey: "your-key",
|
|
184
|
+
requestTimeoutSeconds: 60,
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
// 2. Advanced: custom headers
|
|
188
|
+
const config2 = new ConnectionConfig({
|
|
189
|
+
domain: "api.opensandbox.io",
|
|
190
|
+
apiKey: "your-key",
|
|
191
|
+
headers: { "X-Custom-Header": "value" },
|
|
192
|
+
});
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
### 2. Sandbox Creation Configuration
|
|
196
|
+
|
|
197
|
+
`Sandbox.create()` allows configuring the sandbox environment.
|
|
198
|
+
|
|
199
|
+
| Parameter | Description | Default |
|
|
200
|
+
| --- | --- | --- |
|
|
201
|
+
| `image` | Docker image to use | Required |
|
|
202
|
+
| `timeoutSeconds` | Automatic termination timeout (server-side TTL) | 10 minutes |
|
|
203
|
+
| `entrypoint` | Container entrypoint command | `["tail","-f","/dev/null"]` |
|
|
204
|
+
| `resource` | CPU and memory limits (string map) | `{"cpu":"1","memory":"2Gi"}` |
|
|
205
|
+
| `env` | Environment variables | `{}` |
|
|
206
|
+
| `metadata` | Custom metadata tags | `{}` |
|
|
207
|
+
| `extensions` | Extra server-defined fields | `{}` |
|
|
208
|
+
| `skipHealthCheck` | Skip readiness checks (`Running` + health check) | `false` |
|
|
209
|
+
| `healthCheck` | Custom readiness check | - |
|
|
210
|
+
| `readyTimeoutSeconds` | Max time to wait for readiness | 30 seconds |
|
|
211
|
+
| `healthCheckPollingInterval` | Poll interval while waiting (milliseconds) | 200 ms |
|
|
212
|
+
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { ExecdClient } from "../openapi/execdClient.js";
|
|
2
|
+
import type { CommandExecution, RunCommandOpts, ServerStreamEvent } from "../models/execd.js";
|
|
3
|
+
import type { ExecdCommands } from "../services/execdCommands.js";
|
|
4
|
+
import type { ExecutionHandlers } from "../models/execution.js";
|
|
5
|
+
export interface CommandsAdapterOptions {
|
|
6
|
+
/**
|
|
7
|
+
* Must match the baseUrl used by the ExecdClient.
|
|
8
|
+
*/
|
|
9
|
+
baseUrl: string;
|
|
10
|
+
fetch?: typeof fetch;
|
|
11
|
+
headers?: Record<string, string>;
|
|
12
|
+
}
|
|
13
|
+
export declare class CommandsAdapter implements ExecdCommands {
|
|
14
|
+
private readonly client;
|
|
15
|
+
private readonly opts;
|
|
16
|
+
private readonly fetch;
|
|
17
|
+
constructor(client: ExecdClient, opts: CommandsAdapterOptions);
|
|
18
|
+
interrupt(sessionId: string): Promise<void>;
|
|
19
|
+
runStream(command: string, opts?: RunCommandOpts, signal?: AbortSignal): AsyncIterable<ServerStreamEvent>;
|
|
20
|
+
run(command: string, opts?: RunCommandOpts, handlers?: ExecutionHandlers, signal?: AbortSignal): Promise<CommandExecution>;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=commandsAdapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"commandsAdapter.d.ts","sourceRoot":"","sources":["../../src/adapters/commandsAdapter.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAI7D,OAAO,KAAK,EAAE,gBAAgB,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAC9F,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAClE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAoBhE,MAAM,WAAW,sBAAsB;IACrC;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED,qBAAa,eAAgB,YAAW,aAAa;IAIjD,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,IAAI;IAJvB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAe;gBAGlB,MAAM,EAAE,WAAW,EACnB,IAAI,EAAE,sBAAsB;IAKzC,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAO1C,SAAS,CACd,OAAO,EAAE,MAAM,EACf,IAAI,CAAC,EAAE,cAAc,EACrB,MAAM,CAAC,EAAE,WAAW,GACnB,aAAa,CAAC,iBAAiB,CAAC;IAoB7B,GAAG,CACP,OAAO,EAAE,MAAM,EACf,IAAI,CAAC,EAAE,cAAc,EACrB,QAAQ,CAAC,EAAE,iBAAiB,EAC5B,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,gBAAgB,CAAC;CAgB7B"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
// Copyright 2026 Alibaba Group Holding Ltd.
|
|
2
|
+
//
|
|
3
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
// you may not use this file except in compliance with the License.
|
|
5
|
+
// You may obtain a copy of the License at
|
|
6
|
+
//
|
|
7
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
//
|
|
9
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
// See the License for the specific language governing permissions and
|
|
13
|
+
// limitations under the License.
|
|
14
|
+
import { throwOnOpenApiFetchError } from "./openapiError.js";
|
|
15
|
+
import { parseJsonEventStream } from "./sse.js";
|
|
16
|
+
import { ExecutionEventDispatcher } from "../models/executionEventDispatcher.js";
|
|
17
|
+
function joinUrl(baseUrl, pathname) {
|
|
18
|
+
const base = baseUrl.endsWith("/") ? baseUrl.slice(0, -1) : baseUrl;
|
|
19
|
+
const path = pathname.startsWith("/") ? pathname : `/${pathname}`;
|
|
20
|
+
return `${base}${path}`;
|
|
21
|
+
}
|
|
22
|
+
function toRunCommandRequest(command, opts) {
|
|
23
|
+
return {
|
|
24
|
+
command,
|
|
25
|
+
cwd: opts?.workingDirectory,
|
|
26
|
+
background: !!opts?.background,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
export class CommandsAdapter {
|
|
30
|
+
client;
|
|
31
|
+
opts;
|
|
32
|
+
fetch;
|
|
33
|
+
constructor(client, opts) {
|
|
34
|
+
this.client = client;
|
|
35
|
+
this.opts = opts;
|
|
36
|
+
this.fetch = opts.fetch ?? fetch;
|
|
37
|
+
}
|
|
38
|
+
async interrupt(sessionId) {
|
|
39
|
+
const { error, response } = await this.client.DELETE("/command", {
|
|
40
|
+
params: { query: { id: sessionId } },
|
|
41
|
+
});
|
|
42
|
+
throwOnOpenApiFetchError({ error, response }, "Interrupt command failed");
|
|
43
|
+
}
|
|
44
|
+
async *runStream(command, opts, signal) {
|
|
45
|
+
const url = joinUrl(this.opts.baseUrl, "/command");
|
|
46
|
+
const body = JSON.stringify(toRunCommandRequest(command, opts));
|
|
47
|
+
const res = await this.fetch(url, {
|
|
48
|
+
method: "POST",
|
|
49
|
+
headers: {
|
|
50
|
+
"accept": "text/event-stream",
|
|
51
|
+
"content-type": "application/json",
|
|
52
|
+
...(this.opts.headers ?? {}),
|
|
53
|
+
},
|
|
54
|
+
body,
|
|
55
|
+
signal,
|
|
56
|
+
});
|
|
57
|
+
for await (const ev of parseJsonEventStream(res, { fallbackErrorMessage: "Run command failed" })) {
|
|
58
|
+
yield ev;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
async run(command, opts, handlers, signal) {
|
|
62
|
+
const execution = {
|
|
63
|
+
logs: { stdout: [], stderr: [] },
|
|
64
|
+
result: [],
|
|
65
|
+
};
|
|
66
|
+
const dispatcher = new ExecutionEventDispatcher(execution, handlers);
|
|
67
|
+
for await (const ev of this.runStream(command, opts, signal)) {
|
|
68
|
+
// Keep legacy behavior: if server sends "init" with empty id, preserve previous id.
|
|
69
|
+
if (ev.type === "init" && (ev.text ?? "") === "" && execution.id) {
|
|
70
|
+
ev.text = execution.id;
|
|
71
|
+
}
|
|
72
|
+
await dispatcher.dispatch(ev);
|
|
73
|
+
}
|
|
74
|
+
return execution;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { ExecdClient } from "../openapi/execdClient.js";
|
|
2
|
+
import type { SandboxFiles } from "../services/filesystem.js";
|
|
3
|
+
import type { ContentReplaceEntry, FileInfo, MoveEntry, SearchEntry, SearchFilesResponse, SetPermissionEntry, WriteEntry } from "../models/filesystem.js";
|
|
4
|
+
export interface FilesystemAdapterOptions {
|
|
5
|
+
/**
|
|
6
|
+
* Must match the baseUrl used by the ExecdClient, used for binary endpoints
|
|
7
|
+
* like download/upload where we bypass JSON parsing.
|
|
8
|
+
*/
|
|
9
|
+
baseUrl: string;
|
|
10
|
+
fetch?: typeof fetch;
|
|
11
|
+
headers?: Record<string, string>;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Filesystem adapter that exposes user-facing file APIs (`sandbox.files`).
|
|
15
|
+
*
|
|
16
|
+
* This adapter owns all request/response conversions:
|
|
17
|
+
* - Maps friendly method shapes to API payloads
|
|
18
|
+
* - Parses timestamps into `Date`
|
|
19
|
+
* - Implements streaming upload/download helpers
|
|
20
|
+
*/
|
|
21
|
+
export declare class FilesystemAdapter implements SandboxFiles {
|
|
22
|
+
private readonly client;
|
|
23
|
+
private readonly opts;
|
|
24
|
+
private readonly fetch;
|
|
25
|
+
private static readonly Api;
|
|
26
|
+
constructor(client: ExecdClient, opts: FilesystemAdapterOptions);
|
|
27
|
+
private parseIsoDate;
|
|
28
|
+
private static readonly _ApiFileInfo;
|
|
29
|
+
private mapApiFileInfo;
|
|
30
|
+
getFileInfo(paths: string[]): Promise<Record<string, FileInfo>>;
|
|
31
|
+
deleteFiles(paths: string[]): Promise<void>;
|
|
32
|
+
createDirectories(entries: Pick<WriteEntry, "path" | "mode" | "owner" | "group">[]): Promise<void>;
|
|
33
|
+
deleteDirectories(paths: string[]): Promise<void>;
|
|
34
|
+
setPermissions(entries: SetPermissionEntry[]): Promise<void>;
|
|
35
|
+
moveFiles(entries: MoveEntry[]): Promise<void>;
|
|
36
|
+
replaceContents(entries: ContentReplaceEntry[]): Promise<void>;
|
|
37
|
+
search(entry: SearchEntry): Promise<SearchFilesResponse>;
|
|
38
|
+
private uploadFile;
|
|
39
|
+
readBytes(path: string, opts?: {
|
|
40
|
+
range?: string;
|
|
41
|
+
}): Promise<Uint8Array>;
|
|
42
|
+
readBytesStream(path: string, opts?: {
|
|
43
|
+
range?: string;
|
|
44
|
+
}): AsyncIterable<Uint8Array>;
|
|
45
|
+
private downloadStream;
|
|
46
|
+
readFile(path: string, opts?: {
|
|
47
|
+
encoding?: string;
|
|
48
|
+
range?: string;
|
|
49
|
+
}): Promise<string>;
|
|
50
|
+
writeFiles(entries: WriteEntry[]): Promise<void>;
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=filesystemAdapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"filesystemAdapter.d.ts","sourceRoot":"","sources":["../../src/adapters/filesystemAdapter.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAE7D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAE9D,OAAO,KAAK,EACV,mBAAmB,EACnB,QAAQ,EAGR,SAAS,EAIT,WAAW,EACX,mBAAmB,EACnB,kBAAkB,EAClB,UAAU,EACX,MAAM,yBAAyB,CAAC;AAqGjC,MAAM,WAAW,wBAAwB;IACvC;;;OAGG;IACH,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAcD;;;;;;;GAOG;AACH,qBAAa,iBAAkB,YAAW,YAAY;IAoBlD,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,IAAI;IApBvB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAe;IAErC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAczB;gBAGiB,MAAM,EAAE,WAAW,EACnB,IAAI,EAAE,wBAAwB;IAKjD,OAAO,CAAC,YAAY;IAWpB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,YAAY,CACsC;IAE1E,OAAO,CAAC,cAAc;IAoBhB,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAwB/D,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAO3C,iBAAiB,CACrB,OAAO,EAAE,IAAI,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,CAAC,EAAE,GAC/D,OAAO,CAAC,IAAI,CAAC;IAYV,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAOjD,cAAc,CAAC,OAAO,EAAE,kBAAkB,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAa5D,SAAS,CAAC,OAAO,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAa9C,eAAe,CAAC,OAAO,EAAE,mBAAmB,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAa9D,MAAM,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,mBAAmB,CAAC;YAiBhD,UAAU;IAmGlB,SAAS,CACb,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,GACxB,OAAO,CAAC,UAAU,CAAC;IA6BtB,eAAe,CACb,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,GACxB,aAAa,CAAC,UAAU,CAAC;YAIb,cAAc;IAuCvB,QAAQ,CACZ,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,GAC3C,OAAO,CAAC,MAAM,CAAC;IAMZ,UAAU,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;CAWvD"}
|