@axiom-lattice/opensandbox-gateway 0.1.2 → 0.1.3
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/.turbo/turbo-build.log +5 -5
- package/CHANGELOG.md +6 -0
- package/README.md +58 -1
- package/dist/{chunk-FTPJIUJT.mjs → chunk-R4WOPZ76.mjs} +12 -5
- package/dist/chunk-R4WOPZ76.mjs.map +1 -0
- package/dist/cli.mjs +1 -1
- package/dist/index.mjs +1 -1
- package/package.json +1 -1
- package/src/services/OpenSandboxRuntimeService.ts +10 -3
- package/dist/chunk-FTPJIUJT.mjs.map +0 -1
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
> @axiom-lattice/opensandbox-gateway@0.1.
|
|
2
|
+
> @axiom-lattice/opensandbox-gateway@0.1.3 build /home/runner/work/agentic/agentic/packages/opensandbox-gateway
|
|
3
3
|
> tsup src/index.ts src/cli.ts --format esm --dts --clean --sourcemap
|
|
4
4
|
|
|
5
5
|
[34mCLI[39m Building entry: src/cli.ts, src/index.ts
|
|
@@ -10,12 +10,12 @@
|
|
|
10
10
|
[34mESM[39m Build start
|
|
11
11
|
[32mESM[39m [1mdist/cli.mjs [22m[32m245.00 B[39m
|
|
12
12
|
[32mESM[39m [1mdist/index.mjs [22m[32m196.00 B[39m
|
|
13
|
-
[32mESM[39m [1mdist/chunk-
|
|
13
|
+
[32mESM[39m [1mdist/chunk-R4WOPZ76.mjs [22m[32m36.78 KB[39m
|
|
14
14
|
[32mESM[39m [1mdist/cli.mjs.map [22m[32m387.00 B[39m
|
|
15
15
|
[32mESM[39m [1mdist/index.mjs.map [22m[32m71.00 B[39m
|
|
16
|
-
[32mESM[39m [1mdist/chunk-
|
|
17
|
-
[32mESM[39m ⚡️ Build success in
|
|
16
|
+
[32mESM[39m [1mdist/chunk-R4WOPZ76.mjs.map [22m[32m77.28 KB[39m
|
|
17
|
+
[32mESM[39m ⚡️ Build success in 236ms
|
|
18
18
|
[34mDTS[39m Build start
|
|
19
|
-
[32mDTS[39m ⚡️ Build success in
|
|
19
|
+
[32mDTS[39m ⚡️ Build success in 32371ms
|
|
20
20
|
[32mDTS[39m [1mdist/cli.d.mts [22m[32m20.00 B[39m
|
|
21
21
|
[32mDTS[39m [1mdist/index.d.mts [22m[32m10.55 KB[39m
|
package/CHANGELOG.md
CHANGED
package/README.md
CHANGED
|
@@ -11,10 +11,67 @@ It exposes the same HTTP API — Core's `MicrosandboxRemoteProvider` and `Micros
|
|
|
11
11
|
- Python 3.10+ with [uv](https://docs.astral.sh/uv/getting-started/installation/)
|
|
12
12
|
- OpenSandbox Server (`uv tool install opensandbox-server`)
|
|
13
13
|
|
|
14
|
+
## OpenSandbox Server Setup
|
|
15
|
+
|
|
16
|
+
The gateway requires a running [OpenSandbox Server](https://github.com/opensandbox-group/OpenSandbox) instance.
|
|
17
|
+
|
|
18
|
+
### Install
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
uv tool install opensandbox-server
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
### Configure
|
|
25
|
+
|
|
26
|
+
**Option A: No config (simplest, for local dev)**
|
|
27
|
+
|
|
28
|
+
Start without a config file — defaults to Docker runtime on `0.0.0.0:8080`:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
OPENSANDBOX_INSECURE_SERVER=YES opensandbox-server
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
`OPENSANDBOX_INSECURE_SERVER=YES` is required when `api_key` is not set (safe for local dev only).
|
|
35
|
+
|
|
36
|
+
**Option B: Config file (recommended for production)**
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
# Generate a Docker-mode config template
|
|
40
|
+
opensandbox-server init-config ~/.sandbox.toml --example docker
|
|
41
|
+
|
|
42
|
+
# Edit the file to set api_key, port, etc.
|
|
43
|
+
# Then start:
|
|
44
|
+
opensandbox-server --config ~/.sandbox.toml
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Key `~/.sandbox.toml` settings:
|
|
48
|
+
|
|
49
|
+
```toml
|
|
50
|
+
[server]
|
|
51
|
+
host = "0.0.0.0"
|
|
52
|
+
port = 8080
|
|
53
|
+
api_key = "your-secret-key" # Required for production
|
|
54
|
+
|
|
55
|
+
[runtime]
|
|
56
|
+
type = "docker" # "docker" or "kubernetes"
|
|
57
|
+
|
|
58
|
+
[runtime.docker]
|
|
59
|
+
network_mode = "host" # "host" or "bridge"
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Verify
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
curl http://localhost:8080/health
|
|
66
|
+
# → {"status":"healthy"}
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Full server documentation: [OpenSandbox Server docs](https://github.com/opensandbox-group/OpenSandbox/blob/main/docs/components/server.md)
|
|
70
|
+
|
|
14
71
|
## Quick Start
|
|
15
72
|
|
|
16
73
|
```bash
|
|
17
|
-
# 1. Start OpenSandbox Server (Docker mode)
|
|
74
|
+
# 1. Start OpenSandbox Server (Docker mode, no config)
|
|
18
75
|
OPENSANDBOX_INSECURE_SERVER=YES opensandbox-server &
|
|
19
76
|
# → http://localhost:8080
|
|
20
77
|
|
|
@@ -96,7 +96,8 @@ var OpenSandboxRuntimeService = class {
|
|
|
96
96
|
const info = result.items[0];
|
|
97
97
|
const sandbox = await Sandbox.resume({
|
|
98
98
|
sandboxId: info.id,
|
|
99
|
-
connectionConfig: this.connectionConfig
|
|
99
|
+
connectionConfig: this.connectionConfig,
|
|
100
|
+
readyTimeoutSeconds: 1800
|
|
100
101
|
});
|
|
101
102
|
const entry = {
|
|
102
103
|
sandbox,
|
|
@@ -153,6 +154,7 @@ var OpenSandboxRuntimeService = class {
|
|
|
153
154
|
connectionConfig: this.connectionConfig,
|
|
154
155
|
image: input.image ?? this.defaultImage,
|
|
155
156
|
timeoutSeconds: this.defaultTimeout,
|
|
157
|
+
readyTimeoutSeconds: 1800,
|
|
156
158
|
resource: {
|
|
157
159
|
cpu: String(input.cpus ?? this.defaultCpus),
|
|
158
160
|
memory: `${input.memoryMib ?? this.defaultMemoryMib}Mi`
|
|
@@ -188,7 +190,8 @@ var OpenSandboxRuntimeService = class {
|
|
|
188
190
|
try {
|
|
189
191
|
const resumed = await Sandbox.resume({
|
|
190
192
|
sandboxId: entry.sandboxId,
|
|
191
|
-
connectionConfig: this.connectionConfig
|
|
193
|
+
connectionConfig: this.connectionConfig,
|
|
194
|
+
readyTimeoutSeconds: 1800
|
|
192
195
|
});
|
|
193
196
|
const info = await resumed.getInfo();
|
|
194
197
|
entry.sandbox = resumed;
|
|
@@ -449,12 +452,16 @@ var OpenSandboxRuntimeService = class {
|
|
|
449
452
|
const result = await manager.listSandboxInfos(filter);
|
|
450
453
|
const items = result.items.filter((info) => {
|
|
451
454
|
if (_query.search) {
|
|
452
|
-
const haystack = [
|
|
455
|
+
const haystack = [
|
|
456
|
+
info.id,
|
|
457
|
+
info.metadata?.[NAME_METADATA_KEY],
|
|
458
|
+
info.image?.uri
|
|
459
|
+
].filter(Boolean).join(" ").toLowerCase();
|
|
453
460
|
return haystack.includes(_query.search.toLowerCase());
|
|
454
461
|
}
|
|
455
462
|
return true;
|
|
456
463
|
}).map((info) => ({
|
|
457
|
-
name: info.id,
|
|
464
|
+
name: info.metadata?.[NAME_METADATA_KEY] ?? info.id,
|
|
458
465
|
status: info.status.state.toLowerCase(),
|
|
459
466
|
image: info.image?.uri ?? "unknown",
|
|
460
467
|
cpus: void 0,
|
|
@@ -1078,4 +1085,4 @@ export {
|
|
|
1078
1085
|
buildApp,
|
|
1079
1086
|
startServer
|
|
1080
1087
|
};
|
|
1081
|
-
//# sourceMappingURL=chunk-
|
|
1088
|
+
//# sourceMappingURL=chunk-R4WOPZ76.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/services/OpenSandboxRuntimeService.ts","../src/lib/errors.ts","../src/app.ts","../src/lib/http.ts","../src/routes/health.ts","../src/controllers/images.ts","../src/schemas/images.ts","../src/routes/images.ts","../src/schemas/sandbox.ts","../src/controllers/sandbox.ts","../src/routes/sandbox.ts","../src/controllers/volume-fs.ts","../src/schemas/volume-fs.ts","../src/routes/volume-fs.ts","../src/services/ImageService.ts","../src/swagger.ts","../src/lib/server-cli.ts","../src/server.ts"],"sourcesContent":["import { ConnectionConfig, Sandbox, type Volume } from \"@alibaba-group/opensandbox\";\nimport { SandboxManager, type SandboxFilter } from \"@alibaba-group/opensandbox\";\nimport { SandboxException } from \"@alibaba-group/opensandbox\";\nimport type { RuntimeService } from \"../types/runtime-service\";\nimport type { EnsureSandboxInput, ListSandboxesQuery, ShellExecInput } from \"../schemas/sandbox\";\nimport type { SandboxLogsInput } from \"../schemas/sandbox\";\nimport type { SandboxRuntimeMetrics } from \"../types/runtime-service\";\nimport { HttpError } from \"../lib/errors\";\n\ntype CachedEntry = {\n sandbox: Sandbox;\n sandboxId: string;\n createdAt: string;\n lastUsedAt: number;\n};\n\ntype VolumeDefinition = NonNullable<EnsureSandboxInput[\"volumes\"]>[string];\n\nconst NAME_METADATA_KEY = \"axiom-lattice/name\";\n\nfunction getEnv(key: string, fallback: string): string {\n return process.env[key] ?? fallback;\n}\n\nfunction getEnvNumber(key: string, fallback: number): number {\n const v = process.env[key];\n return v ? Number(v) : fallback;\n}\n\nexport class OpenSandboxRuntimeService implements RuntimeService {\n private cache = new Map<string, CachedEntry>();\n private pendingCreates = new Map<string, Promise<CachedEntry>>();\n private connectionConfig: ConnectionConfig;\n private defaultImage: string;\n private defaultCpus: number;\n private defaultMemoryMib: number;\n private defaultTimeout: number;\n private idleTimeoutMs: number;\n\n constructor() {\n this.connectionConfig = new ConnectionConfig({\n domain: getEnv(\"OPEN_SANDBOX_DOMAIN\", \"localhost:8080\"),\n protocol: (getEnv(\"OPEN_SANDBOX_PROTOCOL\", \"http\") as \"http\" | \"https\"),\n apiKey: process.env[\"OPEN_SANDBOX_API_KEY\"],\n useServerProxy: getEnv(\"OPEN_SANDBOX_USE_SERVER_PROXY\", \"false\") === \"true\",\n });\n\n this.defaultImage = getEnv(\"OPEN_SANDBOX_DEFAULT_IMAGE\", \"ubuntu:22.04\");\n this.defaultCpus = getEnvNumber(\"OPEN_SANDBOX_DEFAULT_CPUS\", 1);\n this.defaultMemoryMib = getEnvNumber(\"OPEN_SANDBOX_DEFAULT_MEMORY_MIB\", 2048);\n this.defaultTimeout = getEnvNumber(\"OPEN_SANDBOX_DEFAULT_TIMEOUT\", 600);\n this.idleTimeoutMs = getEnvNumber(\"SANDBOX_IDLE_TIMEOUT_MS\", 600_000);\n }\n\n private mapVolumes(volumes?: Record<string, VolumeDefinition>): Volume[] {\n if (!volumes) return [];\n return Object.entries(volumes).map(([mountPath, def]) => {\n if (def.type === \"bind\" && def.source) {\n return { name: mountPath, host: { path: def.source }, mountPath, readOnly: def.readonly };\n }\n if (def.type === \"named\" && def.name) {\n return { name: mountPath, pvc: { claimName: def.name }, mountPath, readOnly: def.readonly };\n }\n if (def.type === \"tmpfs\") {\n throw new HttpError(400, \"INVALID_REQUEST\", \"tmpfs volumes are not supported by OpenSandbox\");\n }\n throw new HttpError(400, \"INVALID_REQUEST\", `Unsupported volume type at ${mountPath}`);\n });\n }\n\n private getCached(name: string): CachedEntry {\n const entry = this.cache.get(name);\n if (!entry) {\n throw new HttpError(404, \"SANDBOX_NOT_FOUND\", `Sandbox '${name}' not found`);\n }\n return entry;\n }\n\n private async findByNameViaMetadata(name: string): Promise<CachedEntry | null> {\n try {\n const manager = SandboxManager.create({ connectionConfig: this.connectionConfig });\n const result = await manager.listSandboxInfos({\n metadata: { [NAME_METADATA_KEY]: name },\n pageSize: 1,\n });\n\n if (result.items.length === 0) {\n return null;\n }\n\n const info = result.items[0];\n const sandbox = await Sandbox.resume({\n sandboxId: info.id,\n connectionConfig: this.connectionConfig,\n readyTimeoutSeconds: 1800,\n });\n\n const entry: CachedEntry = {\n sandbox,\n sandboxId: info.id,\n createdAt: info.createdAt ? new Date(info.createdAt).toISOString() : new Date().toISOString(),\n lastUsedAt: Date.now(),\n };\n this.cache.set(name, entry);\n return entry;\n } catch (err) {\n if (err instanceof SandboxException && err.error.code === \"NOT_FOUND\") {\n return null;\n }\n console.warn(`[OpenSandboxRuntimeService] metadata lookup for name=${name} failed:`, err);\n return null;\n }\n }\n\n async ensureSandbox(\n name: string,\n input: EnsureSandboxInput\n ): Promise<{ name: string; status: string }> {\n // 1. Check cache\n const cached = this.cache.get(name);\n if (cached) {\n try {\n const info = await cached.sandbox.getInfo();\n if (info.status.state === \"Running\") {\n cached.lastUsedAt = Date.now();\n await cached.sandbox.renew(this.defaultTimeout).catch(() => {\n });\n return { name, status: \"running\" };\n }\n this.cache.delete(name);\n } catch {\n this.cache.delete(name);\n }\n }\n\n // 2. Dedup concurrent creates for same name\n const inflight = this.pendingCreates.get(name);\n if (inflight) {\n await inflight;\n return { name, status: \"running\" };\n }\n\n // 3. Try metadata recovery (crash recovery)\n const recovered = await this.findByNameViaMetadata(name);\n if (recovered) {\n return { name, status: \"running\" };\n }\n\n // 4. Create new sandbox\n const creation = this.doCreateSandbox(name, input);\n this.pendingCreates.set(name, creation);\n try {\n await creation;\n return { name, status: \"running\" };\n } finally {\n this.pendingCreates.delete(name);\n }\n }\n\n private async doCreateSandbox(\n name: string,\n input: EnsureSandboxInput\n ): Promise<CachedEntry> {\n const sandbox = await Sandbox.create({\n connectionConfig: this.connectionConfig,\n image: input.image ?? this.defaultImage,\n timeoutSeconds: this.defaultTimeout,\n readyTimeoutSeconds: 1800,\n resource: {\n cpu: String(input.cpus ?? this.defaultCpus),\n memory: `${input.memoryMib ?? this.defaultMemoryMib}Mi`,\n },\n env: input.env ?? {},\n metadata: { [NAME_METADATA_KEY]: name },\n volumes: this.mapVolumes(input.volumes),\n entrypoint: [\"tail\", \"-f\", \"/dev/null\"],\n });\n\n const info = await sandbox.getInfo();\n\n const entry: CachedEntry = {\n sandbox,\n sandboxId: info.id,\n createdAt: info.createdAt ? new Date(info.createdAt).toISOString() : new Date().toISOString(),\n lastUsedAt: Date.now(),\n };\n this.cache.set(name, entry);\n return entry;\n }\n\n private wrapError(err: unknown, code: string, message: string): never {\n if (err instanceof HttpError) throw err;\n if (err instanceof SandboxException) {\n throw new HttpError(\n err.error.code === \"NOT_FOUND\" ? 404\n : err.error.code === \"FORBIDDEN\" ? 403\n : err.error.code === \"CONFLICT\" ? 409\n : err.error.code === \"INVALID_REQUEST\" ? 400\n : 500,\n err.error.code,\n err.error.message ?? message\n );\n }\n throw new HttpError(500, code, message);\n }\n\n async startSandbox(name: string): Promise<{ name: string; status: string }> {\n const entry = this.getCached(name);\n try {\n const resumed = await Sandbox.resume({\n sandboxId: entry.sandboxId,\n connectionConfig: this.connectionConfig,\n readyTimeoutSeconds: 1800,\n });\n // Update cache with new Sandbox instance (sandboxId may change on K8s)\n const info = await resumed.getInfo();\n entry.sandbox = resumed;\n entry.sandboxId = info.id;\n entry.lastUsedAt = Date.now();\n return { name, status: \"running\" };\n } catch (err) {\n throw this.wrapError(err, \"SANDBOX_NOT_FOUND\", `Failed to start sandbox '${name}'`);\n }\n }\n\n async stopSandbox(name: string): Promise<{ name: string; status: string }> {\n const entry = this.getCached(name);\n try {\n await entry.sandbox.pause();\n return { name, status: \"stopped\" };\n } catch (err) {\n throw this.wrapError(err, \"INTERNAL_ERROR\", `Failed to stop sandbox '${name}'`);\n }\n }\n\n async killSandbox(name: string): Promise<{ name: string; status: string }> {\n const entry = this.cache.get(name);\n if (!entry) {\n throw new HttpError(404, \"SANDBOX_NOT_FOUND\", `Sandbox '${name}' not found`);\n }\n try {\n await entry.sandbox.kill();\n } catch {\n // kill failure is non-fatal\n }\n try {\n await entry.sandbox.close();\n } catch {\n // close failure is non-fatal\n }\n this.cache.delete(name);\n return { name, status: \"unknown\" };\n }\n\n async deleteSandbox(name: string): Promise<{ name: string; status: string }> {\n return this.killSandbox(name);\n }\n\n async getStatus(name: string): Promise<{ name: string; status: string }> {\n const entry = this.cache.get(name);\n if (entry) {\n try {\n const info = await entry.sandbox.getInfo();\n const status = info.status.state.toLowerCase();\n return { name, status };\n } catch {\n return { name, status: \"unknown\" };\n }\n }\n // Try server-side lookup\n try {\n const manager = SandboxManager.create({ connectionConfig: this.connectionConfig });\n const result = await manager.listSandboxInfos({\n metadata: { [NAME_METADATA_KEY]: name },\n pageSize: 1,\n });\n if (result.items.length > 0) {\n return { name, status: result.items[0].status.state.toLowerCase() };\n }\n } catch {\n // ignore\n }\n return { name, status: \"unknown\" };\n }\n\n private resolvePath(path: string): string {\n if (path === \"~\" || path === \"~/\") return \"/\";\n if (path.startsWith(\"~/\")) return `/${path.slice(2)}`;\n return path;\n }\n\n async readFile(sandboxName: string, path: string): Promise<{ path: string; content: string }> {\n const resolvedPath = this.resolvePath(path);\n const entry = this.getCached(sandboxName);\n try {\n const content = await entry.sandbox.files.readFile(resolvedPath);\n return { path: resolvedPath, content };\n } catch (err) {\n throw this.wrapError(err, \"INTERNAL_ERROR\", `Failed to read file '${resolvedPath}' in sandbox '${sandboxName}'`);\n }\n }\n\n async writeFile(sandboxName: string, path: string, content: string): Promise<{ path: string }> {\n const resolvedPath = this.resolvePath(path);\n const entry = this.getCached(sandboxName);\n try {\n // Create parent directories if needed\n const parentDir = resolvedPath.split(\"/\").slice(0, -1).join(\"/\") || \"/\";\n await entry.sandbox.files.createDirectories([{ path: parentDir }]).catch(() => {\n // parent may already exist\n });\n await entry.sandbox.files.writeFiles([{ path: resolvedPath, data: content }]);\n return { path: resolvedPath };\n } catch (err) {\n throw this.wrapError(err, \"INTERNAL_ERROR\", `Failed to write file '${resolvedPath}' in sandbox '${sandboxName}'`);\n }\n }\n\n async listPath(\n sandboxName: string,\n path: string,\n recursive?: boolean\n ): Promise<{ entries: Array<{ path: string; type: string }> }> {\n const resolvedPath = this.resolvePath(path);\n const entry = this.getCached(sandboxName);\n try {\n const files = await entry.sandbox.files.listDirectory({\n path: resolvedPath,\n depth: recursive ? undefined : 1,\n });\n return {\n entries: files.map((f) => ({\n path: f.path,\n type: f.isDir === true ? \"directory\" : f.isSymlink === true ? \"symlink\" : \"file\",\n })),\n };\n } catch (err) {\n throw this.wrapError(err, \"INTERNAL_ERROR\", `Failed to list path '${resolvedPath}' in sandbox '${sandboxName}'`);\n }\n }\n\n async findFiles(sandboxName: string, path: string, pattern: string): Promise<{ files: string[] }> {\n const resolvedPath = this.resolvePath(path);\n const entry = this.getCached(sandboxName);\n try {\n const results = await entry.sandbox.files.search({\n path: resolvedPath,\n pattern: pattern || \"*\",\n });\n return { files: results.map((r) => r.path) };\n } catch (err) {\n // Fallback to shell find command\n try {\n const result = await entry.sandbox.commands.run(\n `find ${resolvedPath} -name '${pattern}' -type f`,\n { timeoutSeconds: 30 }\n );\n return { files: result.logs.stdout.map((s) => s.text).join(\"\").split(\"\\n\").filter(Boolean) };\n } catch {\n throw this.wrapError(err, \"INTERNAL_ERROR\", `Failed to find files in '${resolvedPath}'`);\n }\n }\n }\n\n async searchInFile(\n sandboxName: string,\n path: string,\n query: string\n ): Promise<{ matches: Array<{ line: number; content: string }> }> {\n const resolvedPath = this.resolvePath(path);\n const entry = this.getCached(sandboxName);\n try {\n const result = await entry.sandbox.commands.run(\n `grep -n -E '${query.replace(/'/g, \"'\\\\''\")}' ${resolvedPath}`,\n { timeoutSeconds: 30 }\n );\n const stdout = result.logs.stdout.map((s) => s.text).join(\"\");\n if (!stdout.trim()) return { matches: [] };\n return {\n matches: stdout.split(\"\\n\").filter(Boolean).map((line) => {\n const idx = line.indexOf(\":\");\n return { line: Number(line.slice(0, idx)), content: line.slice(idx + 1) };\n }),\n };\n } catch (err: unknown) {\n // grep returns exit code 1 for no matches — may throw or not\n if (err instanceof SandboxException) return { matches: [] };\n if (typeof err === \"object\" && err !== null && \"code\" in err && (err as { code: number }).code === 1) {\n return { matches: [] };\n }\n return { matches: [] };\n }\n }\n\n async replaceInFile(\n sandboxName: string,\n input: { path: string; search: string; replace: string }\n ): Promise<{ replaced: number }> {\n const resolvedPath = this.resolvePath(input.path);\n const entry = this.getCached(sandboxName);\n try {\n const original = await entry.sandbox.files.readFile(resolvedPath);\n if (!input.search) return { replaced: 0 };\n const occurrences = original.split(input.search).length - 1;\n if (occurrences === 0) return { replaced: 0 };\n const updated = original.split(input.search).join(input.replace);\n await entry.sandbox.files.writeFiles([{ path: resolvedPath, data: updated }]);\n return { replaced: occurrences };\n } catch (err) {\n throw this.wrapError(err, \"INTERNAL_ERROR\", `Failed to replace in file '${resolvedPath}'`);\n }\n }\n\n async uploadFile(sandboxName: string, path: string, contentBase64: string): Promise<{ path: string }> {\n const resolvedPath = this.resolvePath(path);\n const entry = this.getCached(sandboxName);\n try {\n const data = Buffer.from(contentBase64, \"base64\").toString(\"utf-8\");\n await entry.sandbox.files.writeFiles([{ path: resolvedPath, data }]);\n return { path: resolvedPath };\n } catch (err) {\n throw this.wrapError(err, \"INTERNAL_ERROR\", `Failed to upload file '${resolvedPath}'`);\n }\n }\n\n async downloadFile(sandboxName: string, path: string): Promise<{ path: string; contentBase64: string }> {\n const resolvedPath = this.resolvePath(path);\n const entry = this.getCached(sandboxName);\n try {\n const data = await entry.sandbox.files.readBytes(resolvedPath);\n const b64 = Buffer.from(data).toString(\"base64\");\n return { path: resolvedPath, contentBase64: b64 };\n } catch (err) {\n throw this.wrapError(err, \"INTERNAL_ERROR\", `Failed to download file '${resolvedPath}'`);\n }\n }\n\n async execCommand(input: ShellExecInput): Promise<{ stdout: string; stderr: string; exitCode: number }> {\n const entry = this.getCached(input.sandboxName);\n try {\n const result = await entry.sandbox.commands.run(input.command, {\n workingDirectory: input.exec_dir,\n timeoutSeconds: input.timeout ? Math.ceil(input.timeout / 1000) : undefined,\n });\n return {\n stdout: result.logs.stdout.map((s) => s.text).join(\"\"),\n stderr: result.logs.stderr.map((s) => s.text).join(\"\"),\n exitCode: result.exitCode ?? 0,\n };\n } catch (err) {\n throw this.wrapError(err, \"INTERNAL_ERROR\", `Command execution failed in sandbox '${input.sandboxName}'`);\n }\n }\n\n async getSandbox(\n name: string\n ): Promise<{\n name: string;\n status: string;\n image: unknown;\n cpus?: number;\n memoryMib?: number;\n env: unknown;\n volumes: Record<string, unknown>;\n metrics?: SandboxRuntimeMetrics;\n createdAt: string;\n updatedAt: string;\n } | undefined> {\n // Try cache first\n const entry = this.cache.get(name);\n if (entry) {\n try {\n const info = await entry.sandbox.getInfo();\n return {\n name,\n status: info.status.state.toLowerCase(),\n image: info.image?.uri ?? \"unknown\",\n cpus: undefined,\n memoryMib: undefined,\n env: {},\n volumes: {},\n metrics: undefined,\n createdAt: info.createdAt ? new Date(info.createdAt).toISOString() : entry.createdAt,\n updatedAt: info.createdAt ? new Date(info.createdAt).toISOString() : entry.createdAt,\n };\n } catch {\n this.cache.delete(name);\n }\n }\n\n // Try server-side lookup via metadata\n try {\n const manager = SandboxManager.create({ connectionConfig: this.connectionConfig });\n const result = await manager.listSandboxInfos({\n metadata: { [NAME_METADATA_KEY]: name },\n pageSize: 1,\n });\n if (result.items.length > 0) {\n const info = result.items[0];\n return {\n name,\n status: info.status.state.toLowerCase(),\n image: info.image?.uri ?? \"unknown\",\n cpus: undefined,\n memoryMib: undefined,\n env: {},\n volumes: {},\n metrics: undefined,\n createdAt: info.createdAt ? new Date(info.createdAt).toISOString() : \"\",\n updatedAt: info.createdAt ? new Date(info.createdAt).toISOString() : \"\",\n };\n }\n } catch {\n // ignore\n }\n\n return undefined;\n }\n\n async listSandboxes(_query: ListSandboxesQuery): Promise<{\n items: Array<{\n name: string;\n status: string;\n image: unknown;\n cpus?: number;\n memoryMib?: number;\n envCount: number;\n volumeCount: number;\n createdAt: string;\n updatedAt: string;\n }>;\n total: number;\n }> {\n try {\n const manager = SandboxManager.create({ connectionConfig: this.connectionConfig });\n const filter: SandboxFilter = {};\n if (_query.status) filter.states = [_query.status];\n const result = await manager.listSandboxInfos(filter);\n\n const items = result.items\n .filter((info) => {\n if (_query.search) {\n const haystack = [\n info.id,\n info.metadata?.[NAME_METADATA_KEY],\n info.image?.uri,\n ].filter(Boolean).join(\" \").toLowerCase();\n return haystack.includes(_query.search.toLowerCase());\n }\n return true;\n })\n .map((info) => ({\n name: info.metadata?.[NAME_METADATA_KEY] ?? info.id,\n status: info.status.state.toLowerCase(),\n image: info.image?.uri ?? \"unknown\",\n cpus: undefined,\n memoryMib: undefined,\n envCount: 0,\n volumeCount: 0,\n createdAt: info.createdAt ? new Date(info.createdAt).toISOString() : \"\",\n updatedAt: info.createdAt ? new Date(info.createdAt).toISOString() : \"\",\n }));\n\n return { items, total: items.length };\n } catch {\n return { items: [], total: 0 };\n }\n }\n\n async getSandboxLogs(\n _name: string,\n _opts: SandboxLogsInput\n ): Promise<{\n entries: Array<{\n timestamp: string;\n source: string;\n sessionId: number | null;\n text: string;\n }>;\n }> {\n return { entries: [] };\n }\n}\n","export class HttpError extends Error {\n constructor(\n public statusCode: number,\n public code: string,\n message: string\n ) {\n super(message);\n }\n}\n\nexport function toErrorResponse(error: unknown): {\n statusCode: number;\n body: {\n success: false;\n error: {\n code: string;\n message: string;\n };\n };\n} {\n if (error instanceof HttpError) {\n return {\n statusCode: error.statusCode,\n body: {\n success: false,\n error: {\n code: error.code,\n message: error.message,\n },\n },\n };\n }\n\n return {\n statusCode: 500,\n body: {\n success: false,\n error: {\n code: \"INTERNAL_ERROR\",\n message: error instanceof Error ? error.message : String(error),\n },\n },\n };\n}\n","import type { FastifyInstance } from \"fastify\";\nimport cors from \"@fastify/cors\";\nimport multipart from \"@fastify/multipart\";\nimport sensible from \"@fastify/sensible\";\nimport fastify from \"fastify\";\nimport { toErrorResponse } from \"./lib/errors\";\nimport { registerHealthRoutes } from \"./routes/health\";\nimport { registerImageRoutes } from \"./routes/images\";\nimport { registerSandboxRoutes } from \"./routes/sandbox\";\nimport { registerVolumeFsRoutes } from \"./routes/volume-fs\";\nimport { ImageService } from \"./services/ImageService\";\nimport { OpenSandboxRuntimeService } from \"./services/OpenSandboxRuntimeService\";\nimport { configureSwagger } from \"./swagger\";\n\nexport async function buildApp({\n apiKey,\n}: {\n apiKey?: string;\n} = {}): Promise<FastifyInstance> {\n const runtimeService = new OpenSandboxRuntimeService();\n const imageService = new ImageService();\n\n const app = fastify({\n logger: false,\n bodyLimit: Number(process.env[\"BODY_LIMIT\"]) || 100 * 1024 * 1024,\n });\n\n await app.register(cors, {\n delegator: (request, callback) => {\n callback(null, {\n origin: true,\n methods: request.headers[\"access-control-request-method\"] ?? \"*\",\n allowedHeaders: request.headers[\"access-control-request-headers\"],\n });\n },\n });\n await app.register(sensible);\n await app.register(multipart);\n\n if (apiKey) {\n app.addHook(\"onRequest\", async (request, reply) => {\n if (request.method === \"OPTIONS\" || !request.url.startsWith(\"/api/\")) {\n return;\n }\n if (request.headers.authorization !== `Bearer ${apiKey}`) {\n await reply.code(401).send({\n success: false,\n error: { code: \"UNAUTHORIZED\", message: \"Unauthorized\" },\n });\n }\n });\n }\n\n registerHealthRoutes(app);\n registerSandboxRoutes(app, runtimeService);\n registerImageRoutes(app, imageService);\n registerVolumeFsRoutes(app);\n\n app.setErrorHandler((error, _request, reply) => {\n const { statusCode, body } = toErrorResponse(error);\n reply.status(statusCode).send(body);\n });\n\n await configureSwagger(app);\n\n return app;\n}\n","export type SuccessResponse<T> = {\n success: true;\n data: T;\n};\n\nexport function ok<T>(data: T): SuccessResponse<T> {\n return {\n success: true,\n data,\n };\n}\n","import type { FastifyInstance } from \"fastify\";\nimport { ok } from \"../lib/http\";\n\nexport function registerHealthRoutes(app: FastifyInstance): void {\n app.get(\"/health\", async () => ok({ status: \"ok\" }));\n}\n","import type { FastifyReply, FastifyRequest } from \"fastify\";\nimport { ZodError } from \"zod\";\nimport { HttpError } from \"../lib/errors\";\nimport { ok } from \"../lib/http\";\nimport { ImageService } from \"../services/ImageService\";\nimport { imageRefQuerySchema, pullImageSchema } from \"../schemas/images\";\n\nfunction parseOrThrow<T>(parse: () => T): T {\n try {\n return parse();\n } catch (error) {\n if (error instanceof ZodError) {\n throw new HttpError(400, \"INVALID_REQUEST\", error.issues[0]?.message ?? \"Invalid request\");\n }\n\n throw error;\n }\n}\n\nexport function createImageController(imageService: ImageService) {\n return {\n listImages: async (_request: FastifyRequest, reply: FastifyReply) => {\n return reply.send(ok(await imageService.listImages()));\n },\n pullImage: async (request: FastifyRequest<{ Body: unknown }>, reply: FastifyReply) => {\n const body = parseOrThrow(() => pullImageSchema.parse(request.body ?? {}));\n return reply.send(ok(await imageService.pullImage(body)));\n },\n getImage: async (request: FastifyRequest<{ Querystring: unknown }>, reply: FastifyReply) => {\n const query = parseOrThrow(() => imageRefQuerySchema.parse(request.query ?? {}));\n return reply.send(ok(await imageService.getImage(query.ref)));\n },\n deleteImage: async (request: FastifyRequest<{ Querystring: unknown }>, reply: FastifyReply) => {\n const query = parseOrThrow(() => imageRefQuerySchema.parse(request.query ?? {}));\n return reply.send(ok(await imageService.deleteImage(query.ref)));\n },\n };\n}\n","import z from \"zod\";\n\nexport const imageRefQuerySchema = z.object({\n ref: z.string().min(1),\n});\n\nexport const pullImageSchema = z.object({\n ref: z.string().min(1),\n});\n\nexport type ImageRefQuery = z.infer<typeof imageRefQuerySchema>;\nexport type PullImageInput = z.infer<typeof pullImageSchema>;\n","import type { FastifyInstance } from \"fastify\";\nimport { createImageController } from \"../controllers/images\";\nimport { ImageService } from \"../services/ImageService\";\n\nexport function registerImageRoutes(app: FastifyInstance, imageService: ImageService): void {\n const controller = createImageController(imageService);\n\n app.get(\"/api/images\", controller.listImages);\n app.post(\"/api/images/pull\", controller.pullImage);\n app.get(\"/api/images/detail\", controller.getImage);\n app.delete(\"/api/images/detail\", controller.deleteImage);\n}\n","import z from \"zod\";\n\nconst bindMountSchema = z.object({\n type: z.literal(\"bind\"),\n source: z.string().min(1),\n readonly: z.boolean().optional(),\n});\n\nconst namedMountSchema = z.object({\n type: z.literal(\"named\"),\n name: z.string().min(1),\n readonly: z.boolean().optional(),\n});\n\nconst tmpfsMountSchema = z.object({\n type: z.literal(\"tmpfs\"),\n sizeMib: z.number().int().positive().optional(),\n});\n\nexport const volumeSchema = z.union([\n bindMountSchema,\n namedMountSchema,\n tmpfsMountSchema,\n]);\n\nexport const ensureSandboxSchema = z.object({\n image: z.string().optional(),\n cpus: z.number().int().positive().optional(),\n memoryMib: z.number().int().positive().optional(),\n env: z.record(z.string()).optional(),\n volumes: z.record(volumeSchema).optional(),\n});\n\nexport const sandboxNameParamsSchema = z.object({\n name: z.string().min(1),\n});\n\nexport const listSandboxesQuerySchema = z.object({\n status: z.enum([\"running\", \"stopped\", \"crashed\", \"unknown\"]).optional(),\n image: z.string().min(1).optional(),\n search: z.string().min(1).optional(),\n});\n\nconst sandboxAndPathSchema = z.object({\n sandboxName: z.string().min(1),\n path: z.string().min(1),\n});\n\nexport const readFileSchema = sandboxAndPathSchema;\n\nexport const writeFileSchema = sandboxAndPathSchema.extend({\n content: z.string(),\n});\n\nexport const listPathSchema = sandboxAndPathSchema.extend({\n recursive: z.boolean().optional(),\n});\n\nexport const findFilesSchema = sandboxAndPathSchema.extend({\n pattern: z.string().min(1),\n});\n\nexport const searchInFileSchema = sandboxAndPathSchema.extend({\n query: z.string().min(1),\n});\n\nexport const replaceInFileSchema = sandboxAndPathSchema.extend({\n search: z.string(),\n replace: z.string(),\n});\n\nexport const uploadFileSchema = sandboxAndPathSchema.and(\n z.union([\n z.object({ contentBase64: z.string() }),\n z.object({ content: z.string().transform((content) => Buffer.from(content).toString(\"base64\")) }),\n ])\n);\n\nexport const downloadFileSchema = sandboxAndPathSchema;\n\nexport const shellExecSchema = z.object({\n sandboxName: z.string().min(1),\n command: z.string().min(1),\n exec_dir: z.string().optional(),\n timeout: z.number().int().positive().optional(),\n});\n\nexport const sandboxLogsSchema = z.object({\n tail: z.number().int().positive().optional(),\n since: z.string().optional(),\n until: z.string().optional(),\n sources: z.array(z.string()).optional(),\n});\n\nexport type EnsureSandboxInput = z.infer<typeof ensureSandboxSchema>;\nexport type ListSandboxesQuery = z.infer<typeof listSandboxesQuerySchema>;\nexport type ShellExecInput = z.infer<typeof shellExecSchema>;\nexport type SandboxLogsInput = z.infer<typeof sandboxLogsSchema>;\n","import type { FastifyReply, FastifyRequest } from \"fastify\";\nimport {\n downloadFileSchema,\n ensureSandboxSchema,\n findFilesSchema,\n listSandboxesQuerySchema,\n listPathSchema,\n readFileSchema,\n replaceInFileSchema,\n sandboxLogsSchema,\n sandboxNameParamsSchema,\n searchInFileSchema,\n shellExecSchema,\n uploadFileSchema,\n writeFileSchema,\n} from \"../schemas/sandbox\";\nimport { HttpError } from \"../lib/errors\";\nimport { ok } from \"../lib/http\";\nimport type { RuntimeService } from \"../types/runtime-service\";\n\nexport function createSandboxController(runtimeService: RuntimeService): {\n ensureSandbox(\n request: FastifyRequest<{ Params: { name: string }; Body: unknown }>,\n reply: FastifyReply\n ): Promise<FastifyReply>;\n startSandbox(\n request: FastifyRequest<{ Params: { name: string } }>,\n reply: FastifyReply\n ): Promise<FastifyReply>;\n stopSandbox(\n request: FastifyRequest<{ Params: { name: string } }>,\n reply: FastifyReply\n ): Promise<FastifyReply>;\n killSandbox(\n request: FastifyRequest<{ Params: { name: string } }>,\n reply: FastifyReply\n ): Promise<FastifyReply>;\n deleteSandbox(\n request: FastifyRequest<{ Params: { name: string } }>,\n reply: FastifyReply\n ): Promise<FastifyReply>;\n listSandboxes(\n request: FastifyRequest<{ Querystring: unknown }>,\n reply: FastifyReply\n ): Promise<FastifyReply>;\n getSandbox(\n request: FastifyRequest<{ Params: { name: string } }>,\n reply: FastifyReply\n ): Promise<FastifyReply>;\n getStatus(\n request: FastifyRequest<{ Params: { name: string } }>,\n reply: FastifyReply\n ): Promise<FastifyReply>;\n getSandboxLogs(\n request: FastifyRequest<{ Params: { name: string }; Body: unknown }>,\n reply: FastifyReply\n ): Promise<FastifyReply>;\n readFile(request: FastifyRequest<{ Body: unknown }>, reply: FastifyReply): Promise<FastifyReply>;\n writeFile(request: FastifyRequest<{ Body: unknown }>, reply: FastifyReply): Promise<FastifyReply>;\n listPath(request: FastifyRequest<{ Body: unknown }>, reply: FastifyReply): Promise<FastifyReply>;\n findFiles(request: FastifyRequest<{ Body: unknown }>, reply: FastifyReply): Promise<FastifyReply>;\n searchInFile(request: FastifyRequest<{ Body: unknown }>, reply: FastifyReply): Promise<FastifyReply>;\n replaceInFile(request: FastifyRequest<{ Body: unknown }>, reply: FastifyReply): Promise<FastifyReply>;\n uploadFile(request: FastifyRequest<{ Body: unknown }>, reply: FastifyReply): Promise<FastifyReply>;\n downloadFile(\n request: FastifyRequest<{ Querystring: unknown }>,\n reply: FastifyReply\n ): Promise<FastifyReply>;\n execCommand(request: FastifyRequest<{ Body: unknown }>, reply: FastifyReply): Promise<FastifyReply>;\n} {\n return {\n ensureSandbox: async (\n request: FastifyRequest<{ Params: { name: string }; Body: unknown }>,\n reply: FastifyReply\n ) => {\n const body = ensureSandboxSchema.parse(request.body ?? {});\n const result = await runtimeService.ensureSandbox(request.params.name, body);\n return reply.send(ok(result));\n },\n\n startSandbox: async (request, reply) => {\n return reply.send(ok(await runtimeService.startSandbox(request.params.name)));\n },\n\n stopSandbox: async (request, reply) => {\n return reply.send(ok(await runtimeService.stopSandbox(request.params.name)));\n },\n\n killSandbox: async (request, reply) => {\n return reply.send(ok(await runtimeService.killSandbox(request.params.name)));\n },\n\n deleteSandbox: async (request, reply) => {\n return reply.send(ok(await runtimeService.deleteSandbox(request.params.name)));\n },\n\n listSandboxes: async (request, reply) => {\n const query = listSandboxesQuerySchema.parse(request.query ?? {});\n return reply.send(ok(await runtimeService.listSandboxes(query)));\n },\n\n getSandbox: async (request, reply) => {\n const params = sandboxNameParamsSchema.parse(request.params ?? {});\n const sandbox = await runtimeService.getSandbox(params.name);\n\n if (!sandbox) {\n throw new HttpError(404, \"SANDBOX_NOT_FOUND\", `Sandbox '${params.name}' not found`);\n }\n\n return reply.send(ok(sandbox));\n },\n\n getStatus: async (request, reply) => {\n return reply.send(ok(await runtimeService.getStatus(request.params.name)));\n },\n\n getSandboxLogs: async (request, reply) => {\n const body = sandboxLogsSchema.parse(request.body ?? {});\n return reply.send(ok(await runtimeService.getSandboxLogs(request.params.name, body)));\n },\n\n readFile: async (request, reply) => {\n const body = readFileSchema.parse(request.body ?? {});\n return reply.send(ok(await runtimeService.readFile(body.sandboxName, body.path)));\n },\n\n writeFile: async (request, reply) => {\n const body = writeFileSchema.parse(request.body ?? {});\n return reply.send(ok(await runtimeService.writeFile(body.sandboxName, body.path, body.content)));\n },\n\n listPath: async (request, reply) => {\n const body = listPathSchema.parse(request.body ?? {});\n return reply.send(ok(await runtimeService.listPath(body.sandboxName, body.path, body.recursive)));\n },\n\n findFiles: async (request, reply) => {\n const body = findFilesSchema.parse(request.body ?? {});\n return reply.send(ok(await runtimeService.findFiles(body.sandboxName, body.path, body.pattern)));\n },\n\n searchInFile: async (request, reply) => {\n const body = searchInFileSchema.parse(request.body ?? {});\n return reply.send(ok(await runtimeService.searchInFile(body.sandboxName, body.path, body.query)));\n },\n\n replaceInFile: async (request, reply) => {\n const body = replaceInFileSchema.parse(request.body ?? {});\n return reply.send(\n ok(\n await runtimeService.replaceInFile(body.sandboxName, {\n path: body.path,\n search: body.search,\n replace: body.replace,\n })\n )\n );\n },\n\n uploadFile: async (request, reply) => {\n const body = uploadFileSchema.parse(request.body ?? {});\n const contentBase64 = \"contentBase64\" in body ? body.contentBase64 : Buffer.from(body.content).toString(\"base64\");\n return reply.send(ok(await runtimeService.uploadFile(body.sandboxName, body.path, contentBase64)));\n },\n\n downloadFile: async (request, reply) => {\n const query = downloadFileSchema.parse(request.query ?? {});\n return reply.send(ok(await runtimeService.downloadFile(query.sandboxName, query.path)));\n },\n\n execCommand: async (request, reply) => {\n const body = shellExecSchema.parse(request.body ?? {});\n return reply.send(ok(await runtimeService.execCommand(body)));\n },\n };\n}\n","import type { FastifyInstance } from \"fastify\";\nimport { createSandboxController } from \"../controllers/sandbox\";\nimport type { RuntimeService } from \"../types/runtime-service\";\n\nexport function registerSandboxRoutes(\n app: FastifyInstance,\n runtimeService: RuntimeService\n): void {\n const controller = createSandboxController(runtimeService);\n\n app.get(\"/api/sandboxes\", controller.listSandboxes);\n app.get(\"/api/sandboxes/:name\", controller.getSandbox);\n app.put(\"/api/sandboxes/:name\", controller.ensureSandbox);\n app.post(\"/api/sandboxes/:name/start\", controller.startSandbox);\n app.post(\"/api/sandboxes/:name/stop\", controller.stopSandbox);\n app.post(\"/api/sandboxes/:name/kill\", controller.killSandbox);\n app.delete(\"/api/sandboxes/:name\", controller.deleteSandbox);\n app.get(\"/api/sandboxes/:name/status\", controller.getStatus);\n app.post(\"/api/sandboxes/:name/logs\", controller.getSandboxLogs);\n\n app.post(\"/api/files/read\", controller.readFile);\n app.post(\"/api/files/write\", controller.writeFile);\n app.post(\"/api/files/list\", controller.listPath);\n app.post(\"/api/files/find\", controller.findFiles);\n app.post(\"/api/files/search\", controller.searchInFile);\n app.post(\"/api/files/replace\", controller.replaceInFile);\n app.post(\"/api/files/upload\", controller.uploadFile);\n app.get(\"/api/files/download\", controller.downloadFile);\n\n app.post(\"/api/shell/exec\", controller.execCommand);\n}\n","import type { FastifyReply, FastifyRequest } from \"fastify\";\nimport fs from \"fs/promises\";\nimport os from \"os\";\nimport path from \"path\";\nimport z from \"zod\";\nimport { HttpError } from \"../lib/errors\";\nimport { ok } from \"../lib/http\";\nimport {\n volumeFsReadSchema,\n volumeFsWriteSchema,\n volumeFsListSchema,\n volumeFsUploadSchema,\n volumeFsDownloadSchema,\n} from \"../schemas/volume-fs\";\n\ninterface VolumeFsParams {\n name: string;\n}\n\nfunction getVolumeBasePath(): string {\n return process.env.VOLUME_BASE_PATH ?? path.join(os.homedir(), \".opensandbox\", \"volumes\");\n}\n\nfunction resolveVolumeHostPath(name: string): string {\n return path.join(getVolumeBasePath(), name);\n}\n\nfunction resolveGuestPath(hostRoot: string, guestPath: string): string {\n const normalized = guestPath === \"~\" ? \"\" : guestPath.replace(/^~\\//, \"\");\n const resolved = path.join(\n hostRoot,\n path.normalize(normalized).replace(/^(\\.\\.(\\/|\\\\|$))+/, \"\")\n );\n if (!resolved.startsWith(hostRoot + path.sep) && resolved !== hostRoot) {\n throw new HttpError(403, \"PATH_TRAVERSAL\", \"Path traversal detected\");\n }\n return resolved;\n}\n\nexport function createVolumeFsController(): {\n readFile(\n request: FastifyRequest<{ Params: VolumeFsParams; Body: { path: string } }>,\n reply: FastifyReply\n ): Promise<FastifyReply>;\n writeFile(\n request: FastifyRequest<{ Params: VolumeFsParams; Body: { path: string; content: string } }>,\n reply: FastifyReply\n ): Promise<FastifyReply>;\n listPath(\n request: FastifyRequest<{ Params: VolumeFsParams; Body: { path: string } }>,\n reply: FastifyReply\n ): Promise<FastifyReply>;\n downloadFile(\n request: FastifyRequest<{ Params: VolumeFsParams; Querystring: { path: string } }>,\n reply: FastifyReply\n ): Promise<FastifyReply>;\n uploadFile(\n request: FastifyRequest<{ Params: VolumeFsParams; Body: { path: string; contentBase64: string } }>,\n reply: FastifyReply\n ): Promise<FastifyReply>;\n} {\n return {\n readFile: async (request, reply) => {\n const { name } = request.params;\n\n try {\n const { path: guestPath } = volumeFsReadSchema.parse(request.body ?? {});\n const hostRoot = resolveVolumeHostPath(name);\n const fullPath = resolveGuestPath(hostRoot, guestPath);\n const content = await fs.readFile(fullPath, \"utf-8\");\n return reply.send(ok({ path: guestPath, content }));\n } catch (err: unknown) {\n if (err instanceof z.ZodError) {\n throw new HttpError(400, \"VALIDATION_ERROR\", err.message);\n }\n if (err instanceof HttpError) throw err;\n throw new HttpError(404, \"VOLUME_READ_ERROR\", `Failed to read from volume '${name}': ${String(err)}`);\n }\n },\n\n writeFile: async (request, reply) => {\n const { name } = request.params;\n\n try {\n const { path: guestPath, content } = volumeFsWriteSchema.parse(request.body ?? {});\n const hostRoot = resolveVolumeHostPath(name);\n const fullPath = resolveGuestPath(hostRoot, guestPath);\n await fs.mkdir(path.dirname(fullPath), { recursive: true });\n await fs.writeFile(fullPath, content, \"utf-8\");\n return reply.send(ok({ path: guestPath }));\n } catch (err: unknown) {\n if (err instanceof z.ZodError) {\n throw new HttpError(400, \"VALIDATION_ERROR\", err.message);\n }\n if (err instanceof HttpError) throw err;\n throw new HttpError(500, \"VOLUME_WRITE_ERROR\", `Failed to write to volume '${name}': ${String(err)}`);\n }\n },\n\n listPath: async (request, reply) => {\n const { name } = request.params;\n\n try {\n const { path: guestPath } = volumeFsListSchema.parse(request.body ?? {});\n const hostRoot = resolveVolumeHostPath(name);\n const fullPath = resolveGuestPath(hostRoot, guestPath);\n const dirents = await fs.readdir(fullPath, { withFileTypes: true });\n const entries = dirents.map((d) => ({\n path: guestPath ? `${guestPath}/${d.name}` : d.name,\n kind: d.isDirectory() ? \"directory\" : d.isSymbolicLink() ? \"symlink\" : \"file\",\n size: 0,\n mode: 0,\n }));\n return reply.send(ok({ entries }));\n } catch (err: unknown) {\n if (err instanceof z.ZodError) {\n throw new HttpError(400, \"VALIDATION_ERROR\", err.message);\n }\n if (err instanceof HttpError) throw err;\n throw new HttpError(404, \"VOLUME_LIST_ERROR\", `Failed to list volume '${name}': ${String(err)}`);\n }\n },\n\n downloadFile: async (request, reply) => {\n const { name } = request.params;\n\n try {\n const { path: guestPath } = volumeFsDownloadSchema.parse(request.query ?? {});\n const hostRoot = resolveVolumeHostPath(name);\n const fullPath = resolveGuestPath(hostRoot, guestPath);\n const buf = await fs.readFile(fullPath);\n const contentBase64 = buf.toString(\"base64\");\n return reply.send(ok({ path: guestPath, contentBase64 }));\n } catch (err: unknown) {\n if (err instanceof z.ZodError) {\n throw new HttpError(400, \"VALIDATION_ERROR\", err.message);\n }\n if (err instanceof HttpError) throw err;\n throw new HttpError(404, \"VOLUME_DOWNLOAD_ERROR\", `Failed to download from volume '${name}': ${String(err)}`);\n }\n },\n\n uploadFile: async (request, reply) => {\n const { name } = request.params;\n\n try {\n const { path: guestPath, contentBase64 } = volumeFsUploadSchema.parse(request.body ?? {});\n const hostRoot = resolveVolumeHostPath(name);\n const fullPath = resolveGuestPath(hostRoot, guestPath);\n await fs.mkdir(path.dirname(fullPath), { recursive: true });\n const data = Buffer.from(contentBase64, \"base64\");\n await fs.writeFile(fullPath, data);\n return reply.send(ok({ path: guestPath }));\n } catch (err: unknown) {\n if (err instanceof z.ZodError) {\n throw new HttpError(400, \"VALIDATION_ERROR\", err.message);\n }\n if (err instanceof HttpError) throw err;\n throw new HttpError(500, \"VOLUME_UPLOAD_ERROR\", `Failed to upload to volume '${name}': ${String(err)}`);\n }\n },\n };\n}\n","import z from \"zod\";\n\nexport const volumeFsReadSchema = z.object({\n path: z.string(),\n});\n\nexport const volumeFsWriteSchema = z.object({\n path: z.string(),\n content: z.string(),\n});\n\nexport const volumeFsListSchema = z.object({\n path: z.string(),\n});\n\nexport const volumeFsUploadSchema = z.object({\n path: z.string(),\n contentBase64: z.string().min(1),\n});\n\nexport const volumeFsDownloadSchema = z.object({\n path: z.string(),\n});\n","import type { FastifyInstance } from \"fastify\";\nimport { createVolumeFsController } from \"../controllers/volume-fs\";\n\nexport function registerVolumeFsRoutes(app: FastifyInstance): void {\n const controller = createVolumeFsController();\n\n app.post(\"/api/volumes/:name/fs/read\", controller.readFile);\n app.post(\"/api/volumes/:name/fs/write\", controller.writeFile);\n app.post(\"/api/volumes/:name/fs/list\", controller.listPath);\n app.get(\"/api/volumes/:name/fs/download\", controller.downloadFile);\n app.post(\"/api/volumes/:name/fs/upload\", controller.uploadFile);\n}\n","import type { PullImageInput } from \"../schemas/images\";\n\nexport type ImageRecord = {\n ref: string;\n sourceType: string;\n cached: boolean;\n size?: number;\n createdAt?: string;\n lastUsedAt?: string;\n};\n\nexport class ImageService {\n async listImages(): Promise<{ items: ImageRecord[]; total: number }> {\n return { items: [], total: 0 };\n }\n\n async pullImage(_input: PullImageInput): Promise<ImageRecord> {\n throw new Error(\"Image pull not supported in OpenSandbox gateway\");\n }\n\n async getImage(ref: string): Promise<ImageRecord> {\n return {\n ref,\n sourceType: \"oci\",\n cached: false,\n };\n }\n\n async deleteImage(ref: string): Promise<{ ref: string }> {\n return { ref };\n }\n}\n","import type { FastifyInstance } from \"fastify\";\nimport swagger from \"@fastify/swagger\";\nimport swaggerUi from \"@fastify/swagger-ui\";\n\nconst swaggerConfig = {\n openapi: {\n openapi: \"3.0.0\",\n info: {\n title: \"OpenSandbox Gateway API\",\n description: \"Sandbox lifecycle management backed by OpenSandbox\",\n version: \"1.0.0\",\n },\n servers: [{ url: \"http://localhost:4002\", description: \"Local development\" }],\n components: {\n securitySchemes: {\n bearerAuth: { type: \"http\" as const, scheme: \"bearer\" as const, bearerFormat: \"API Key\" },\n },\n },\n tags: [\n { name: \"Sandboxes\", description: \"Sandbox lifecycle\" },\n { name: \"Files\", description: \"File operations inside sandboxes\" },\n { name: \"Shell\", description: \"Execute commands inside sandboxes\" },\n { name: \"Images\", description: \"Image management (stub)\" },\n { name: \"Volumes\", description: \"Named volume filesystem operations\" },\n { name: \"Health\", description: \"Service health check\" },\n ],\n },\n};\n\nconst swaggerUiConfig = {\n routePrefix: \"/api-docs\",\n uiConfig: { docExpansion: \"list\" as const, deepLinking: true },\n staticCSP: true,\n transformStaticCSP: (header: string) => header,\n};\n\nexport async function configureSwagger(app: FastifyInstance) {\n await app.register(swagger, swaggerConfig);\n await app.register(swaggerUi, swaggerUiConfig);\n}\n","export interface ParsedServerArgs {\n host?: string;\n port?: number;\n}\n\nexport interface ResolvedServerConfig {\n host: string;\n port: number;\n apiKey?: string;\n}\n\nfunction parsePort(raw: string, source: string): number {\n const value = Number(raw);\n if (!Number.isInteger(value) || value <= 0 || value > 65535) {\n throw new Error(`Invalid value for ${source}: ${raw}`);\n }\n return value;\n}\n\nfunction isMissingOptionValue(raw: string | undefined): raw is undefined {\n return !raw || raw.startsWith(\"--\");\n}\n\nexport function parseServerArgs(argv: string[]): ParsedServerArgs {\n const parsed: ParsedServerArgs = {};\n\n for (let index = 0; index < argv.length; index += 1) {\n const token = argv[index];\n\n if (token === \"--port\") {\n const raw = argv[index + 1];\n if (isMissingOptionValue(raw)) {\n throw new Error(\"Missing value for --port\");\n }\n parsed.port = parsePort(raw, \"--port\");\n index += 1;\n continue;\n }\n\n if (token === \"--host\") {\n const raw = argv[index + 1];\n if (isMissingOptionValue(raw)) {\n throw new Error(\"Missing value for --host\");\n }\n parsed.host = raw;\n index += 1;\n }\n }\n\n return parsed;\n}\n\nexport function resolveServerConfig({\n args,\n env,\n}: {\n args: ParsedServerArgs;\n env: NodeJS.ProcessEnv;\n}): ResolvedServerConfig {\n return {\n host: args.host ?? env.HOST ?? \"0.0.0.0\",\n port: args.port ?? (env.PORT ? parsePort(env.PORT, \"PORT\") : 4002),\n apiKey: env.GATEWAY_API_KEY ?? env.MICROSANDBOX_API_KEY,\n };\n}\n","import type { FastifyInstance } from \"fastify\";\nimport { buildApp } from \"./app\";\nimport { parseServerArgs, resolveServerConfig } from \"./lib/server-cli\";\n\nexport async function startServer({\n argv = process.argv.slice(2),\n env = process.env,\n app,\n}: {\n argv?: string[];\n env?: NodeJS.ProcessEnv;\n app?: Pick<FastifyInstance, \"listen\" | \"close\">;\n} = {}): Promise<Pick<FastifyInstance, \"listen\" | \"close\">> {\n const config = resolveServerConfig({ args: parseServerArgs(argv), env });\n const resolvedApp = app ?? (await buildApp({ apiKey: config.apiKey }));\n\n const removeSignalHandlers = (): void => {\n process.off(\"SIGINT\", onSigInt);\n process.off(\"SIGTERM\", onSigTerm);\n };\n\n const close = async (): Promise<undefined> => {\n removeSignalHandlers();\n return resolvedApp.close();\n };\n\n const onSigInt = () => { void shutdown(0); };\n const onSigTerm = () => { void shutdown(0); };\n\n const shutdown = async (code: number): Promise<void> => {\n try {\n await close();\n process.exit(code);\n } catch (error) {\n console.error(\"Failed to shutdown opensandbox-gateway cleanly\", error);\n process.exit(1);\n }\n };\n\n process.once(\"SIGINT\", onSigInt);\n process.once(\"SIGTERM\", onSigTerm);\n\n try {\n await resolvedApp.listen({ port: config.port, host: config.host });\n return { listen: resolvedApp.listen.bind(resolvedApp), close: close as FastifyInstance[\"close\"] };\n } catch (error) {\n removeSignalHandlers();\n throw error;\n }\n}\n"],"mappings":"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","names":["path","z","z","z","z"]}
|
package/dist/cli.mjs
CHANGED
package/dist/index.mjs
CHANGED
package/package.json
CHANGED
|
@@ -40,7 +40,7 @@ export class OpenSandboxRuntimeService implements RuntimeService {
|
|
|
40
40
|
constructor() {
|
|
41
41
|
this.connectionConfig = new ConnectionConfig({
|
|
42
42
|
domain: getEnv("OPEN_SANDBOX_DOMAIN", "localhost:8080"),
|
|
43
|
-
protocol: getEnv("OPEN_SANDBOX_PROTOCOL", "http") as "http" | "https",
|
|
43
|
+
protocol: (getEnv("OPEN_SANDBOX_PROTOCOL", "http") as "http" | "https"),
|
|
44
44
|
apiKey: process.env["OPEN_SANDBOX_API_KEY"],
|
|
45
45
|
useServerProxy: getEnv("OPEN_SANDBOX_USE_SERVER_PROXY", "false") === "true",
|
|
46
46
|
});
|
|
@@ -92,6 +92,7 @@ export class OpenSandboxRuntimeService implements RuntimeService {
|
|
|
92
92
|
const sandbox = await Sandbox.resume({
|
|
93
93
|
sandboxId: info.id,
|
|
94
94
|
connectionConfig: this.connectionConfig,
|
|
95
|
+
readyTimeoutSeconds: 1800,
|
|
95
96
|
});
|
|
96
97
|
|
|
97
98
|
const entry: CachedEntry = {
|
|
@@ -164,6 +165,7 @@ export class OpenSandboxRuntimeService implements RuntimeService {
|
|
|
164
165
|
connectionConfig: this.connectionConfig,
|
|
165
166
|
image: input.image ?? this.defaultImage,
|
|
166
167
|
timeoutSeconds: this.defaultTimeout,
|
|
168
|
+
readyTimeoutSeconds: 1800,
|
|
167
169
|
resource: {
|
|
168
170
|
cpu: String(input.cpus ?? this.defaultCpus),
|
|
169
171
|
memory: `${input.memoryMib ?? this.defaultMemoryMib}Mi`,
|
|
@@ -208,6 +210,7 @@ export class OpenSandboxRuntimeService implements RuntimeService {
|
|
|
208
210
|
const resumed = await Sandbox.resume({
|
|
209
211
|
sandboxId: entry.sandboxId,
|
|
210
212
|
connectionConfig: this.connectionConfig,
|
|
213
|
+
readyTimeoutSeconds: 1800,
|
|
211
214
|
});
|
|
212
215
|
// Update cache with new Sandbox instance (sandboxId may change on K8s)
|
|
213
216
|
const info = await resumed.getInfo();
|
|
@@ -537,13 +540,17 @@ export class OpenSandboxRuntimeService implements RuntimeService {
|
|
|
537
540
|
const items = result.items
|
|
538
541
|
.filter((info) => {
|
|
539
542
|
if (_query.search) {
|
|
540
|
-
const haystack = [
|
|
543
|
+
const haystack = [
|
|
544
|
+
info.id,
|
|
545
|
+
info.metadata?.[NAME_METADATA_KEY],
|
|
546
|
+
info.image?.uri,
|
|
547
|
+
].filter(Boolean).join(" ").toLowerCase();
|
|
541
548
|
return haystack.includes(_query.search.toLowerCase());
|
|
542
549
|
}
|
|
543
550
|
return true;
|
|
544
551
|
})
|
|
545
552
|
.map((info) => ({
|
|
546
|
-
name: info.id,
|
|
553
|
+
name: info.metadata?.[NAME_METADATA_KEY] ?? info.id,
|
|
547
554
|
status: info.status.state.toLowerCase(),
|
|
548
555
|
image: info.image?.uri ?? "unknown",
|
|
549
556
|
cpus: undefined,
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/services/OpenSandboxRuntimeService.ts","../src/lib/errors.ts","../src/app.ts","../src/lib/http.ts","../src/routes/health.ts","../src/controllers/images.ts","../src/schemas/images.ts","../src/routes/images.ts","../src/schemas/sandbox.ts","../src/controllers/sandbox.ts","../src/routes/sandbox.ts","../src/controllers/volume-fs.ts","../src/schemas/volume-fs.ts","../src/routes/volume-fs.ts","../src/services/ImageService.ts","../src/swagger.ts","../src/lib/server-cli.ts","../src/server.ts"],"sourcesContent":["import { ConnectionConfig, Sandbox, type Volume } from \"@alibaba-group/opensandbox\";\nimport { SandboxManager, type SandboxFilter } from \"@alibaba-group/opensandbox\";\nimport { SandboxException } from \"@alibaba-group/opensandbox\";\nimport type { RuntimeService } from \"../types/runtime-service\";\nimport type { EnsureSandboxInput, ListSandboxesQuery, ShellExecInput } from \"../schemas/sandbox\";\nimport type { SandboxLogsInput } from \"../schemas/sandbox\";\nimport type { SandboxRuntimeMetrics } from \"../types/runtime-service\";\nimport { HttpError } from \"../lib/errors\";\n\ntype CachedEntry = {\n sandbox: Sandbox;\n sandboxId: string;\n createdAt: string;\n lastUsedAt: number;\n};\n\ntype VolumeDefinition = NonNullable<EnsureSandboxInput[\"volumes\"]>[string];\n\nconst NAME_METADATA_KEY = \"axiom-lattice/name\";\n\nfunction getEnv(key: string, fallback: string): string {\n return process.env[key] ?? fallback;\n}\n\nfunction getEnvNumber(key: string, fallback: number): number {\n const v = process.env[key];\n return v ? Number(v) : fallback;\n}\n\nexport class OpenSandboxRuntimeService implements RuntimeService {\n private cache = new Map<string, CachedEntry>();\n private pendingCreates = new Map<string, Promise<CachedEntry>>();\n private connectionConfig: ConnectionConfig;\n private defaultImage: string;\n private defaultCpus: number;\n private defaultMemoryMib: number;\n private defaultTimeout: number;\n private idleTimeoutMs: number;\n\n constructor() {\n this.connectionConfig = new ConnectionConfig({\n domain: getEnv(\"OPEN_SANDBOX_DOMAIN\", \"localhost:8080\"),\n protocol: getEnv(\"OPEN_SANDBOX_PROTOCOL\", \"http\") as \"http\" | \"https\",\n apiKey: process.env[\"OPEN_SANDBOX_API_KEY\"],\n useServerProxy: getEnv(\"OPEN_SANDBOX_USE_SERVER_PROXY\", \"false\") === \"true\",\n });\n\n this.defaultImage = getEnv(\"OPEN_SANDBOX_DEFAULT_IMAGE\", \"ubuntu:22.04\");\n this.defaultCpus = getEnvNumber(\"OPEN_SANDBOX_DEFAULT_CPUS\", 1);\n this.defaultMemoryMib = getEnvNumber(\"OPEN_SANDBOX_DEFAULT_MEMORY_MIB\", 2048);\n this.defaultTimeout = getEnvNumber(\"OPEN_SANDBOX_DEFAULT_TIMEOUT\", 600);\n this.idleTimeoutMs = getEnvNumber(\"SANDBOX_IDLE_TIMEOUT_MS\", 600_000);\n }\n\n private mapVolumes(volumes?: Record<string, VolumeDefinition>): Volume[] {\n if (!volumes) return [];\n return Object.entries(volumes).map(([mountPath, def]) => {\n if (def.type === \"bind\" && def.source) {\n return { name: mountPath, host: { path: def.source }, mountPath, readOnly: def.readonly };\n }\n if (def.type === \"named\" && def.name) {\n return { name: mountPath, pvc: { claimName: def.name }, mountPath, readOnly: def.readonly };\n }\n if (def.type === \"tmpfs\") {\n throw new HttpError(400, \"INVALID_REQUEST\", \"tmpfs volumes are not supported by OpenSandbox\");\n }\n throw new HttpError(400, \"INVALID_REQUEST\", `Unsupported volume type at ${mountPath}`);\n });\n }\n\n private getCached(name: string): CachedEntry {\n const entry = this.cache.get(name);\n if (!entry) {\n throw new HttpError(404, \"SANDBOX_NOT_FOUND\", `Sandbox '${name}' not found`);\n }\n return entry;\n }\n\n private async findByNameViaMetadata(name: string): Promise<CachedEntry | null> {\n try {\n const manager = SandboxManager.create({ connectionConfig: this.connectionConfig });\n const result = await manager.listSandboxInfos({\n metadata: { [NAME_METADATA_KEY]: name },\n pageSize: 1,\n });\n\n if (result.items.length === 0) {\n return null;\n }\n\n const info = result.items[0];\n const sandbox = await Sandbox.resume({\n sandboxId: info.id,\n connectionConfig: this.connectionConfig,\n });\n\n const entry: CachedEntry = {\n sandbox,\n sandboxId: info.id,\n createdAt: info.createdAt ? new Date(info.createdAt).toISOString() : new Date().toISOString(),\n lastUsedAt: Date.now(),\n };\n this.cache.set(name, entry);\n return entry;\n } catch (err) {\n if (err instanceof SandboxException && err.error.code === \"NOT_FOUND\") {\n return null;\n }\n console.warn(`[OpenSandboxRuntimeService] metadata lookup for name=${name} failed:`, err);\n return null;\n }\n }\n\n async ensureSandbox(\n name: string,\n input: EnsureSandboxInput\n ): Promise<{ name: string; status: string }> {\n // 1. Check cache\n const cached = this.cache.get(name);\n if (cached) {\n try {\n const info = await cached.sandbox.getInfo();\n if (info.status.state === \"Running\") {\n cached.lastUsedAt = Date.now();\n await cached.sandbox.renew(this.defaultTimeout).catch(() => {\n });\n return { name, status: \"running\" };\n }\n this.cache.delete(name);\n } catch {\n this.cache.delete(name);\n }\n }\n\n // 2. Dedup concurrent creates for same name\n const inflight = this.pendingCreates.get(name);\n if (inflight) {\n await inflight;\n return { name, status: \"running\" };\n }\n\n // 3. Try metadata recovery (crash recovery)\n const recovered = await this.findByNameViaMetadata(name);\n if (recovered) {\n return { name, status: \"running\" };\n }\n\n // 4. Create new sandbox\n const creation = this.doCreateSandbox(name, input);\n this.pendingCreates.set(name, creation);\n try {\n await creation;\n return { name, status: \"running\" };\n } finally {\n this.pendingCreates.delete(name);\n }\n }\n\n private async doCreateSandbox(\n name: string,\n input: EnsureSandboxInput\n ): Promise<CachedEntry> {\n const sandbox = await Sandbox.create({\n connectionConfig: this.connectionConfig,\n image: input.image ?? this.defaultImage,\n timeoutSeconds: this.defaultTimeout,\n resource: {\n cpu: String(input.cpus ?? this.defaultCpus),\n memory: `${input.memoryMib ?? this.defaultMemoryMib}Mi`,\n },\n env: input.env ?? {},\n metadata: { [NAME_METADATA_KEY]: name },\n volumes: this.mapVolumes(input.volumes),\n entrypoint: [\"tail\", \"-f\", \"/dev/null\"],\n });\n\n const info = await sandbox.getInfo();\n\n const entry: CachedEntry = {\n sandbox,\n sandboxId: info.id,\n createdAt: info.createdAt ? new Date(info.createdAt).toISOString() : new Date().toISOString(),\n lastUsedAt: Date.now(),\n };\n this.cache.set(name, entry);\n return entry;\n }\n\n private wrapError(err: unknown, code: string, message: string): never {\n if (err instanceof HttpError) throw err;\n if (err instanceof SandboxException) {\n throw new HttpError(\n err.error.code === \"NOT_FOUND\" ? 404\n : err.error.code === \"FORBIDDEN\" ? 403\n : err.error.code === \"CONFLICT\" ? 409\n : err.error.code === \"INVALID_REQUEST\" ? 400\n : 500,\n err.error.code,\n err.error.message ?? message\n );\n }\n throw new HttpError(500, code, message);\n }\n\n async startSandbox(name: string): Promise<{ name: string; status: string }> {\n const entry = this.getCached(name);\n try {\n const resumed = await Sandbox.resume({\n sandboxId: entry.sandboxId,\n connectionConfig: this.connectionConfig,\n });\n // Update cache with new Sandbox instance (sandboxId may change on K8s)\n const info = await resumed.getInfo();\n entry.sandbox = resumed;\n entry.sandboxId = info.id;\n entry.lastUsedAt = Date.now();\n return { name, status: \"running\" };\n } catch (err) {\n throw this.wrapError(err, \"SANDBOX_NOT_FOUND\", `Failed to start sandbox '${name}'`);\n }\n }\n\n async stopSandbox(name: string): Promise<{ name: string; status: string }> {\n const entry = this.getCached(name);\n try {\n await entry.sandbox.pause();\n return { name, status: \"stopped\" };\n } catch (err) {\n throw this.wrapError(err, \"INTERNAL_ERROR\", `Failed to stop sandbox '${name}'`);\n }\n }\n\n async killSandbox(name: string): Promise<{ name: string; status: string }> {\n const entry = this.cache.get(name);\n if (!entry) {\n throw new HttpError(404, \"SANDBOX_NOT_FOUND\", `Sandbox '${name}' not found`);\n }\n try {\n await entry.sandbox.kill();\n } catch {\n // kill failure is non-fatal\n }\n try {\n await entry.sandbox.close();\n } catch {\n // close failure is non-fatal\n }\n this.cache.delete(name);\n return { name, status: \"unknown\" };\n }\n\n async deleteSandbox(name: string): Promise<{ name: string; status: string }> {\n return this.killSandbox(name);\n }\n\n async getStatus(name: string): Promise<{ name: string; status: string }> {\n const entry = this.cache.get(name);\n if (entry) {\n try {\n const info = await entry.sandbox.getInfo();\n const status = info.status.state.toLowerCase();\n return { name, status };\n } catch {\n return { name, status: \"unknown\" };\n }\n }\n // Try server-side lookup\n try {\n const manager = SandboxManager.create({ connectionConfig: this.connectionConfig });\n const result = await manager.listSandboxInfos({\n metadata: { [NAME_METADATA_KEY]: name },\n pageSize: 1,\n });\n if (result.items.length > 0) {\n return { name, status: result.items[0].status.state.toLowerCase() };\n }\n } catch {\n // ignore\n }\n return { name, status: \"unknown\" };\n }\n\n private resolvePath(path: string): string {\n if (path === \"~\" || path === \"~/\") return \"/\";\n if (path.startsWith(\"~/\")) return `/${path.slice(2)}`;\n return path;\n }\n\n async readFile(sandboxName: string, path: string): Promise<{ path: string; content: string }> {\n const resolvedPath = this.resolvePath(path);\n const entry = this.getCached(sandboxName);\n try {\n const content = await entry.sandbox.files.readFile(resolvedPath);\n return { path: resolvedPath, content };\n } catch (err) {\n throw this.wrapError(err, \"INTERNAL_ERROR\", `Failed to read file '${resolvedPath}' in sandbox '${sandboxName}'`);\n }\n }\n\n async writeFile(sandboxName: string, path: string, content: string): Promise<{ path: string }> {\n const resolvedPath = this.resolvePath(path);\n const entry = this.getCached(sandboxName);\n try {\n // Create parent directories if needed\n const parentDir = resolvedPath.split(\"/\").slice(0, -1).join(\"/\") || \"/\";\n await entry.sandbox.files.createDirectories([{ path: parentDir }]).catch(() => {\n // parent may already exist\n });\n await entry.sandbox.files.writeFiles([{ path: resolvedPath, data: content }]);\n return { path: resolvedPath };\n } catch (err) {\n throw this.wrapError(err, \"INTERNAL_ERROR\", `Failed to write file '${resolvedPath}' in sandbox '${sandboxName}'`);\n }\n }\n\n async listPath(\n sandboxName: string,\n path: string,\n recursive?: boolean\n ): Promise<{ entries: Array<{ path: string; type: string }> }> {\n const resolvedPath = this.resolvePath(path);\n const entry = this.getCached(sandboxName);\n try {\n const files = await entry.sandbox.files.listDirectory({\n path: resolvedPath,\n depth: recursive ? undefined : 1,\n });\n return {\n entries: files.map((f) => ({\n path: f.path,\n type: f.isDir === true ? \"directory\" : f.isSymlink === true ? \"symlink\" : \"file\",\n })),\n };\n } catch (err) {\n throw this.wrapError(err, \"INTERNAL_ERROR\", `Failed to list path '${resolvedPath}' in sandbox '${sandboxName}'`);\n }\n }\n\n async findFiles(sandboxName: string, path: string, pattern: string): Promise<{ files: string[] }> {\n const resolvedPath = this.resolvePath(path);\n const entry = this.getCached(sandboxName);\n try {\n const results = await entry.sandbox.files.search({\n path: resolvedPath,\n pattern: pattern || \"*\",\n });\n return { files: results.map((r) => r.path) };\n } catch (err) {\n // Fallback to shell find command\n try {\n const result = await entry.sandbox.commands.run(\n `find ${resolvedPath} -name '${pattern}' -type f`,\n { timeoutSeconds: 30 }\n );\n return { files: result.logs.stdout.map((s) => s.text).join(\"\").split(\"\\n\").filter(Boolean) };\n } catch {\n throw this.wrapError(err, \"INTERNAL_ERROR\", `Failed to find files in '${resolvedPath}'`);\n }\n }\n }\n\n async searchInFile(\n sandboxName: string,\n path: string,\n query: string\n ): Promise<{ matches: Array<{ line: number; content: string }> }> {\n const resolvedPath = this.resolvePath(path);\n const entry = this.getCached(sandboxName);\n try {\n const result = await entry.sandbox.commands.run(\n `grep -n -E '${query.replace(/'/g, \"'\\\\''\")}' ${resolvedPath}`,\n { timeoutSeconds: 30 }\n );\n const stdout = result.logs.stdout.map((s) => s.text).join(\"\");\n if (!stdout.trim()) return { matches: [] };\n return {\n matches: stdout.split(\"\\n\").filter(Boolean).map((line) => {\n const idx = line.indexOf(\":\");\n return { line: Number(line.slice(0, idx)), content: line.slice(idx + 1) };\n }),\n };\n } catch (err: unknown) {\n // grep returns exit code 1 for no matches — may throw or not\n if (err instanceof SandboxException) return { matches: [] };\n if (typeof err === \"object\" && err !== null && \"code\" in err && (err as { code: number }).code === 1) {\n return { matches: [] };\n }\n return { matches: [] };\n }\n }\n\n async replaceInFile(\n sandboxName: string,\n input: { path: string; search: string; replace: string }\n ): Promise<{ replaced: number }> {\n const resolvedPath = this.resolvePath(input.path);\n const entry = this.getCached(sandboxName);\n try {\n const original = await entry.sandbox.files.readFile(resolvedPath);\n if (!input.search) return { replaced: 0 };\n const occurrences = original.split(input.search).length - 1;\n if (occurrences === 0) return { replaced: 0 };\n const updated = original.split(input.search).join(input.replace);\n await entry.sandbox.files.writeFiles([{ path: resolvedPath, data: updated }]);\n return { replaced: occurrences };\n } catch (err) {\n throw this.wrapError(err, \"INTERNAL_ERROR\", `Failed to replace in file '${resolvedPath}'`);\n }\n }\n\n async uploadFile(sandboxName: string, path: string, contentBase64: string): Promise<{ path: string }> {\n const resolvedPath = this.resolvePath(path);\n const entry = this.getCached(sandboxName);\n try {\n const data = Buffer.from(contentBase64, \"base64\").toString(\"utf-8\");\n await entry.sandbox.files.writeFiles([{ path: resolvedPath, data }]);\n return { path: resolvedPath };\n } catch (err) {\n throw this.wrapError(err, \"INTERNAL_ERROR\", `Failed to upload file '${resolvedPath}'`);\n }\n }\n\n async downloadFile(sandboxName: string, path: string): Promise<{ path: string; contentBase64: string }> {\n const resolvedPath = this.resolvePath(path);\n const entry = this.getCached(sandboxName);\n try {\n const data = await entry.sandbox.files.readBytes(resolvedPath);\n const b64 = Buffer.from(data).toString(\"base64\");\n return { path: resolvedPath, contentBase64: b64 };\n } catch (err) {\n throw this.wrapError(err, \"INTERNAL_ERROR\", `Failed to download file '${resolvedPath}'`);\n }\n }\n\n async execCommand(input: ShellExecInput): Promise<{ stdout: string; stderr: string; exitCode: number }> {\n const entry = this.getCached(input.sandboxName);\n try {\n const result = await entry.sandbox.commands.run(input.command, {\n workingDirectory: input.exec_dir,\n timeoutSeconds: input.timeout ? Math.ceil(input.timeout / 1000) : undefined,\n });\n return {\n stdout: result.logs.stdout.map((s) => s.text).join(\"\"),\n stderr: result.logs.stderr.map((s) => s.text).join(\"\"),\n exitCode: result.exitCode ?? 0,\n };\n } catch (err) {\n throw this.wrapError(err, \"INTERNAL_ERROR\", `Command execution failed in sandbox '${input.sandboxName}'`);\n }\n }\n\n async getSandbox(\n name: string\n ): Promise<{\n name: string;\n status: string;\n image: unknown;\n cpus?: number;\n memoryMib?: number;\n env: unknown;\n volumes: Record<string, unknown>;\n metrics?: SandboxRuntimeMetrics;\n createdAt: string;\n updatedAt: string;\n } | undefined> {\n // Try cache first\n const entry = this.cache.get(name);\n if (entry) {\n try {\n const info = await entry.sandbox.getInfo();\n return {\n name,\n status: info.status.state.toLowerCase(),\n image: info.image?.uri ?? \"unknown\",\n cpus: undefined,\n memoryMib: undefined,\n env: {},\n volumes: {},\n metrics: undefined,\n createdAt: info.createdAt ? new Date(info.createdAt).toISOString() : entry.createdAt,\n updatedAt: info.createdAt ? new Date(info.createdAt).toISOString() : entry.createdAt,\n };\n } catch {\n this.cache.delete(name);\n }\n }\n\n // Try server-side lookup via metadata\n try {\n const manager = SandboxManager.create({ connectionConfig: this.connectionConfig });\n const result = await manager.listSandboxInfos({\n metadata: { [NAME_METADATA_KEY]: name },\n pageSize: 1,\n });\n if (result.items.length > 0) {\n const info = result.items[0];\n return {\n name,\n status: info.status.state.toLowerCase(),\n image: info.image?.uri ?? \"unknown\",\n cpus: undefined,\n memoryMib: undefined,\n env: {},\n volumes: {},\n metrics: undefined,\n createdAt: info.createdAt ? new Date(info.createdAt).toISOString() : \"\",\n updatedAt: info.createdAt ? new Date(info.createdAt).toISOString() : \"\",\n };\n }\n } catch {\n // ignore\n }\n\n return undefined;\n }\n\n async listSandboxes(_query: ListSandboxesQuery): Promise<{\n items: Array<{\n name: string;\n status: string;\n image: unknown;\n cpus?: number;\n memoryMib?: number;\n envCount: number;\n volumeCount: number;\n createdAt: string;\n updatedAt: string;\n }>;\n total: number;\n }> {\n try {\n const manager = SandboxManager.create({ connectionConfig: this.connectionConfig });\n const filter: SandboxFilter = {};\n if (_query.status) filter.states = [_query.status];\n const result = await manager.listSandboxInfos(filter);\n\n const items = result.items\n .filter((info) => {\n if (_query.search) {\n const haystack = [info.id, info.image?.uri].filter(Boolean).join(\" \").toLowerCase();\n return haystack.includes(_query.search.toLowerCase());\n }\n return true;\n })\n .map((info) => ({\n name: info.id,\n status: info.status.state.toLowerCase(),\n image: info.image?.uri ?? \"unknown\",\n cpus: undefined,\n memoryMib: undefined,\n envCount: 0,\n volumeCount: 0,\n createdAt: info.createdAt ? new Date(info.createdAt).toISOString() : \"\",\n updatedAt: info.createdAt ? new Date(info.createdAt).toISOString() : \"\",\n }));\n\n return { items, total: items.length };\n } catch {\n return { items: [], total: 0 };\n }\n }\n\n async getSandboxLogs(\n _name: string,\n _opts: SandboxLogsInput\n ): Promise<{\n entries: Array<{\n timestamp: string;\n source: string;\n sessionId: number | null;\n text: string;\n }>;\n }> {\n return { entries: [] };\n }\n}\n","export class HttpError extends Error {\n constructor(\n public statusCode: number,\n public code: string,\n message: string\n ) {\n super(message);\n }\n}\n\nexport function toErrorResponse(error: unknown): {\n statusCode: number;\n body: {\n success: false;\n error: {\n code: string;\n message: string;\n };\n };\n} {\n if (error instanceof HttpError) {\n return {\n statusCode: error.statusCode,\n body: {\n success: false,\n error: {\n code: error.code,\n message: error.message,\n },\n },\n };\n }\n\n return {\n statusCode: 500,\n body: {\n success: false,\n error: {\n code: \"INTERNAL_ERROR\",\n message: error instanceof Error ? error.message : String(error),\n },\n },\n };\n}\n","import type { FastifyInstance } from \"fastify\";\nimport cors from \"@fastify/cors\";\nimport multipart from \"@fastify/multipart\";\nimport sensible from \"@fastify/sensible\";\nimport fastify from \"fastify\";\nimport { toErrorResponse } from \"./lib/errors\";\nimport { registerHealthRoutes } from \"./routes/health\";\nimport { registerImageRoutes } from \"./routes/images\";\nimport { registerSandboxRoutes } from \"./routes/sandbox\";\nimport { registerVolumeFsRoutes } from \"./routes/volume-fs\";\nimport { ImageService } from \"./services/ImageService\";\nimport { OpenSandboxRuntimeService } from \"./services/OpenSandboxRuntimeService\";\nimport { configureSwagger } from \"./swagger\";\n\nexport async function buildApp({\n apiKey,\n}: {\n apiKey?: string;\n} = {}): Promise<FastifyInstance> {\n const runtimeService = new OpenSandboxRuntimeService();\n const imageService = new ImageService();\n\n const app = fastify({\n logger: false,\n bodyLimit: Number(process.env[\"BODY_LIMIT\"]) || 100 * 1024 * 1024,\n });\n\n await app.register(cors, {\n delegator: (request, callback) => {\n callback(null, {\n origin: true,\n methods: request.headers[\"access-control-request-method\"] ?? \"*\",\n allowedHeaders: request.headers[\"access-control-request-headers\"],\n });\n },\n });\n await app.register(sensible);\n await app.register(multipart);\n\n if (apiKey) {\n app.addHook(\"onRequest\", async (request, reply) => {\n if (request.method === \"OPTIONS\" || !request.url.startsWith(\"/api/\")) {\n return;\n }\n if (request.headers.authorization !== `Bearer ${apiKey}`) {\n await reply.code(401).send({\n success: false,\n error: { code: \"UNAUTHORIZED\", message: \"Unauthorized\" },\n });\n }\n });\n }\n\n registerHealthRoutes(app);\n registerSandboxRoutes(app, runtimeService);\n registerImageRoutes(app, imageService);\n registerVolumeFsRoutes(app);\n\n app.setErrorHandler((error, _request, reply) => {\n const { statusCode, body } = toErrorResponse(error);\n reply.status(statusCode).send(body);\n });\n\n await configureSwagger(app);\n\n return app;\n}\n","export type SuccessResponse<T> = {\n success: true;\n data: T;\n};\n\nexport function ok<T>(data: T): SuccessResponse<T> {\n return {\n success: true,\n data,\n };\n}\n","import type { FastifyInstance } from \"fastify\";\nimport { ok } from \"../lib/http\";\n\nexport function registerHealthRoutes(app: FastifyInstance): void {\n app.get(\"/health\", async () => ok({ status: \"ok\" }));\n}\n","import type { FastifyReply, FastifyRequest } from \"fastify\";\nimport { ZodError } from \"zod\";\nimport { HttpError } from \"../lib/errors\";\nimport { ok } from \"../lib/http\";\nimport { ImageService } from \"../services/ImageService\";\nimport { imageRefQuerySchema, pullImageSchema } from \"../schemas/images\";\n\nfunction parseOrThrow<T>(parse: () => T): T {\n try {\n return parse();\n } catch (error) {\n if (error instanceof ZodError) {\n throw new HttpError(400, \"INVALID_REQUEST\", error.issues[0]?.message ?? \"Invalid request\");\n }\n\n throw error;\n }\n}\n\nexport function createImageController(imageService: ImageService) {\n return {\n listImages: async (_request: FastifyRequest, reply: FastifyReply) => {\n return reply.send(ok(await imageService.listImages()));\n },\n pullImage: async (request: FastifyRequest<{ Body: unknown }>, reply: FastifyReply) => {\n const body = parseOrThrow(() => pullImageSchema.parse(request.body ?? {}));\n return reply.send(ok(await imageService.pullImage(body)));\n },\n getImage: async (request: FastifyRequest<{ Querystring: unknown }>, reply: FastifyReply) => {\n const query = parseOrThrow(() => imageRefQuerySchema.parse(request.query ?? {}));\n return reply.send(ok(await imageService.getImage(query.ref)));\n },\n deleteImage: async (request: FastifyRequest<{ Querystring: unknown }>, reply: FastifyReply) => {\n const query = parseOrThrow(() => imageRefQuerySchema.parse(request.query ?? {}));\n return reply.send(ok(await imageService.deleteImage(query.ref)));\n },\n };\n}\n","import z from \"zod\";\n\nexport const imageRefQuerySchema = z.object({\n ref: z.string().min(1),\n});\n\nexport const pullImageSchema = z.object({\n ref: z.string().min(1),\n});\n\nexport type ImageRefQuery = z.infer<typeof imageRefQuerySchema>;\nexport type PullImageInput = z.infer<typeof pullImageSchema>;\n","import type { FastifyInstance } from \"fastify\";\nimport { createImageController } from \"../controllers/images\";\nimport { ImageService } from \"../services/ImageService\";\n\nexport function registerImageRoutes(app: FastifyInstance, imageService: ImageService): void {\n const controller = createImageController(imageService);\n\n app.get(\"/api/images\", controller.listImages);\n app.post(\"/api/images/pull\", controller.pullImage);\n app.get(\"/api/images/detail\", controller.getImage);\n app.delete(\"/api/images/detail\", controller.deleteImage);\n}\n","import z from \"zod\";\n\nconst bindMountSchema = z.object({\n type: z.literal(\"bind\"),\n source: z.string().min(1),\n readonly: z.boolean().optional(),\n});\n\nconst namedMountSchema = z.object({\n type: z.literal(\"named\"),\n name: z.string().min(1),\n readonly: z.boolean().optional(),\n});\n\nconst tmpfsMountSchema = z.object({\n type: z.literal(\"tmpfs\"),\n sizeMib: z.number().int().positive().optional(),\n});\n\nexport const volumeSchema = z.union([\n bindMountSchema,\n namedMountSchema,\n tmpfsMountSchema,\n]);\n\nexport const ensureSandboxSchema = z.object({\n image: z.string().optional(),\n cpus: z.number().int().positive().optional(),\n memoryMib: z.number().int().positive().optional(),\n env: z.record(z.string()).optional(),\n volumes: z.record(volumeSchema).optional(),\n});\n\nexport const sandboxNameParamsSchema = z.object({\n name: z.string().min(1),\n});\n\nexport const listSandboxesQuerySchema = z.object({\n status: z.enum([\"running\", \"stopped\", \"crashed\", \"unknown\"]).optional(),\n image: z.string().min(1).optional(),\n search: z.string().min(1).optional(),\n});\n\nconst sandboxAndPathSchema = z.object({\n sandboxName: z.string().min(1),\n path: z.string().min(1),\n});\n\nexport const readFileSchema = sandboxAndPathSchema;\n\nexport const writeFileSchema = sandboxAndPathSchema.extend({\n content: z.string(),\n});\n\nexport const listPathSchema = sandboxAndPathSchema.extend({\n recursive: z.boolean().optional(),\n});\n\nexport const findFilesSchema = sandboxAndPathSchema.extend({\n pattern: z.string().min(1),\n});\n\nexport const searchInFileSchema = sandboxAndPathSchema.extend({\n query: z.string().min(1),\n});\n\nexport const replaceInFileSchema = sandboxAndPathSchema.extend({\n search: z.string(),\n replace: z.string(),\n});\n\nexport const uploadFileSchema = sandboxAndPathSchema.and(\n z.union([\n z.object({ contentBase64: z.string() }),\n z.object({ content: z.string().transform((content) => Buffer.from(content).toString(\"base64\")) }),\n ])\n);\n\nexport const downloadFileSchema = sandboxAndPathSchema;\n\nexport const shellExecSchema = z.object({\n sandboxName: z.string().min(1),\n command: z.string().min(1),\n exec_dir: z.string().optional(),\n timeout: z.number().int().positive().optional(),\n});\n\nexport const sandboxLogsSchema = z.object({\n tail: z.number().int().positive().optional(),\n since: z.string().optional(),\n until: z.string().optional(),\n sources: z.array(z.string()).optional(),\n});\n\nexport type EnsureSandboxInput = z.infer<typeof ensureSandboxSchema>;\nexport type ListSandboxesQuery = z.infer<typeof listSandboxesQuerySchema>;\nexport type ShellExecInput = z.infer<typeof shellExecSchema>;\nexport type SandboxLogsInput = z.infer<typeof sandboxLogsSchema>;\n","import type { FastifyReply, FastifyRequest } from \"fastify\";\nimport {\n downloadFileSchema,\n ensureSandboxSchema,\n findFilesSchema,\n listSandboxesQuerySchema,\n listPathSchema,\n readFileSchema,\n replaceInFileSchema,\n sandboxLogsSchema,\n sandboxNameParamsSchema,\n searchInFileSchema,\n shellExecSchema,\n uploadFileSchema,\n writeFileSchema,\n} from \"../schemas/sandbox\";\nimport { HttpError } from \"../lib/errors\";\nimport { ok } from \"../lib/http\";\nimport type { RuntimeService } from \"../types/runtime-service\";\n\nexport function createSandboxController(runtimeService: RuntimeService): {\n ensureSandbox(\n request: FastifyRequest<{ Params: { name: string }; Body: unknown }>,\n reply: FastifyReply\n ): Promise<FastifyReply>;\n startSandbox(\n request: FastifyRequest<{ Params: { name: string } }>,\n reply: FastifyReply\n ): Promise<FastifyReply>;\n stopSandbox(\n request: FastifyRequest<{ Params: { name: string } }>,\n reply: FastifyReply\n ): Promise<FastifyReply>;\n killSandbox(\n request: FastifyRequest<{ Params: { name: string } }>,\n reply: FastifyReply\n ): Promise<FastifyReply>;\n deleteSandbox(\n request: FastifyRequest<{ Params: { name: string } }>,\n reply: FastifyReply\n ): Promise<FastifyReply>;\n listSandboxes(\n request: FastifyRequest<{ Querystring: unknown }>,\n reply: FastifyReply\n ): Promise<FastifyReply>;\n getSandbox(\n request: FastifyRequest<{ Params: { name: string } }>,\n reply: FastifyReply\n ): Promise<FastifyReply>;\n getStatus(\n request: FastifyRequest<{ Params: { name: string } }>,\n reply: FastifyReply\n ): Promise<FastifyReply>;\n getSandboxLogs(\n request: FastifyRequest<{ Params: { name: string }; Body: unknown }>,\n reply: FastifyReply\n ): Promise<FastifyReply>;\n readFile(request: FastifyRequest<{ Body: unknown }>, reply: FastifyReply): Promise<FastifyReply>;\n writeFile(request: FastifyRequest<{ Body: unknown }>, reply: FastifyReply): Promise<FastifyReply>;\n listPath(request: FastifyRequest<{ Body: unknown }>, reply: FastifyReply): Promise<FastifyReply>;\n findFiles(request: FastifyRequest<{ Body: unknown }>, reply: FastifyReply): Promise<FastifyReply>;\n searchInFile(request: FastifyRequest<{ Body: unknown }>, reply: FastifyReply): Promise<FastifyReply>;\n replaceInFile(request: FastifyRequest<{ Body: unknown }>, reply: FastifyReply): Promise<FastifyReply>;\n uploadFile(request: FastifyRequest<{ Body: unknown }>, reply: FastifyReply): Promise<FastifyReply>;\n downloadFile(\n request: FastifyRequest<{ Querystring: unknown }>,\n reply: FastifyReply\n ): Promise<FastifyReply>;\n execCommand(request: FastifyRequest<{ Body: unknown }>, reply: FastifyReply): Promise<FastifyReply>;\n} {\n return {\n ensureSandbox: async (\n request: FastifyRequest<{ Params: { name: string }; Body: unknown }>,\n reply: FastifyReply\n ) => {\n const body = ensureSandboxSchema.parse(request.body ?? {});\n const result = await runtimeService.ensureSandbox(request.params.name, body);\n return reply.send(ok(result));\n },\n\n startSandbox: async (request, reply) => {\n return reply.send(ok(await runtimeService.startSandbox(request.params.name)));\n },\n\n stopSandbox: async (request, reply) => {\n return reply.send(ok(await runtimeService.stopSandbox(request.params.name)));\n },\n\n killSandbox: async (request, reply) => {\n return reply.send(ok(await runtimeService.killSandbox(request.params.name)));\n },\n\n deleteSandbox: async (request, reply) => {\n return reply.send(ok(await runtimeService.deleteSandbox(request.params.name)));\n },\n\n listSandboxes: async (request, reply) => {\n const query = listSandboxesQuerySchema.parse(request.query ?? {});\n return reply.send(ok(await runtimeService.listSandboxes(query)));\n },\n\n getSandbox: async (request, reply) => {\n const params = sandboxNameParamsSchema.parse(request.params ?? {});\n const sandbox = await runtimeService.getSandbox(params.name);\n\n if (!sandbox) {\n throw new HttpError(404, \"SANDBOX_NOT_FOUND\", `Sandbox '${params.name}' not found`);\n }\n\n return reply.send(ok(sandbox));\n },\n\n getStatus: async (request, reply) => {\n return reply.send(ok(await runtimeService.getStatus(request.params.name)));\n },\n\n getSandboxLogs: async (request, reply) => {\n const body = sandboxLogsSchema.parse(request.body ?? {});\n return reply.send(ok(await runtimeService.getSandboxLogs(request.params.name, body)));\n },\n\n readFile: async (request, reply) => {\n const body = readFileSchema.parse(request.body ?? {});\n return reply.send(ok(await runtimeService.readFile(body.sandboxName, body.path)));\n },\n\n writeFile: async (request, reply) => {\n const body = writeFileSchema.parse(request.body ?? {});\n return reply.send(ok(await runtimeService.writeFile(body.sandboxName, body.path, body.content)));\n },\n\n listPath: async (request, reply) => {\n const body = listPathSchema.parse(request.body ?? {});\n return reply.send(ok(await runtimeService.listPath(body.sandboxName, body.path, body.recursive)));\n },\n\n findFiles: async (request, reply) => {\n const body = findFilesSchema.parse(request.body ?? {});\n return reply.send(ok(await runtimeService.findFiles(body.sandboxName, body.path, body.pattern)));\n },\n\n searchInFile: async (request, reply) => {\n const body = searchInFileSchema.parse(request.body ?? {});\n return reply.send(ok(await runtimeService.searchInFile(body.sandboxName, body.path, body.query)));\n },\n\n replaceInFile: async (request, reply) => {\n const body = replaceInFileSchema.parse(request.body ?? {});\n return reply.send(\n ok(\n await runtimeService.replaceInFile(body.sandboxName, {\n path: body.path,\n search: body.search,\n replace: body.replace,\n })\n )\n );\n },\n\n uploadFile: async (request, reply) => {\n const body = uploadFileSchema.parse(request.body ?? {});\n const contentBase64 = \"contentBase64\" in body ? body.contentBase64 : Buffer.from(body.content).toString(\"base64\");\n return reply.send(ok(await runtimeService.uploadFile(body.sandboxName, body.path, contentBase64)));\n },\n\n downloadFile: async (request, reply) => {\n const query = downloadFileSchema.parse(request.query ?? {});\n return reply.send(ok(await runtimeService.downloadFile(query.sandboxName, query.path)));\n },\n\n execCommand: async (request, reply) => {\n const body = shellExecSchema.parse(request.body ?? {});\n return reply.send(ok(await runtimeService.execCommand(body)));\n },\n };\n}\n","import type { FastifyInstance } from \"fastify\";\nimport { createSandboxController } from \"../controllers/sandbox\";\nimport type { RuntimeService } from \"../types/runtime-service\";\n\nexport function registerSandboxRoutes(\n app: FastifyInstance,\n runtimeService: RuntimeService\n): void {\n const controller = createSandboxController(runtimeService);\n\n app.get(\"/api/sandboxes\", controller.listSandboxes);\n app.get(\"/api/sandboxes/:name\", controller.getSandbox);\n app.put(\"/api/sandboxes/:name\", controller.ensureSandbox);\n app.post(\"/api/sandboxes/:name/start\", controller.startSandbox);\n app.post(\"/api/sandboxes/:name/stop\", controller.stopSandbox);\n app.post(\"/api/sandboxes/:name/kill\", controller.killSandbox);\n app.delete(\"/api/sandboxes/:name\", controller.deleteSandbox);\n app.get(\"/api/sandboxes/:name/status\", controller.getStatus);\n app.post(\"/api/sandboxes/:name/logs\", controller.getSandboxLogs);\n\n app.post(\"/api/files/read\", controller.readFile);\n app.post(\"/api/files/write\", controller.writeFile);\n app.post(\"/api/files/list\", controller.listPath);\n app.post(\"/api/files/find\", controller.findFiles);\n app.post(\"/api/files/search\", controller.searchInFile);\n app.post(\"/api/files/replace\", controller.replaceInFile);\n app.post(\"/api/files/upload\", controller.uploadFile);\n app.get(\"/api/files/download\", controller.downloadFile);\n\n app.post(\"/api/shell/exec\", controller.execCommand);\n}\n","import type { FastifyReply, FastifyRequest } from \"fastify\";\nimport fs from \"fs/promises\";\nimport os from \"os\";\nimport path from \"path\";\nimport z from \"zod\";\nimport { HttpError } from \"../lib/errors\";\nimport { ok } from \"../lib/http\";\nimport {\n volumeFsReadSchema,\n volumeFsWriteSchema,\n volumeFsListSchema,\n volumeFsUploadSchema,\n volumeFsDownloadSchema,\n} from \"../schemas/volume-fs\";\n\ninterface VolumeFsParams {\n name: string;\n}\n\nfunction getVolumeBasePath(): string {\n return process.env.VOLUME_BASE_PATH ?? path.join(os.homedir(), \".opensandbox\", \"volumes\");\n}\n\nfunction resolveVolumeHostPath(name: string): string {\n return path.join(getVolumeBasePath(), name);\n}\n\nfunction resolveGuestPath(hostRoot: string, guestPath: string): string {\n const normalized = guestPath === \"~\" ? \"\" : guestPath.replace(/^~\\//, \"\");\n const resolved = path.join(\n hostRoot,\n path.normalize(normalized).replace(/^(\\.\\.(\\/|\\\\|$))+/, \"\")\n );\n if (!resolved.startsWith(hostRoot + path.sep) && resolved !== hostRoot) {\n throw new HttpError(403, \"PATH_TRAVERSAL\", \"Path traversal detected\");\n }\n return resolved;\n}\n\nexport function createVolumeFsController(): {\n readFile(\n request: FastifyRequest<{ Params: VolumeFsParams; Body: { path: string } }>,\n reply: FastifyReply\n ): Promise<FastifyReply>;\n writeFile(\n request: FastifyRequest<{ Params: VolumeFsParams; Body: { path: string; content: string } }>,\n reply: FastifyReply\n ): Promise<FastifyReply>;\n listPath(\n request: FastifyRequest<{ Params: VolumeFsParams; Body: { path: string } }>,\n reply: FastifyReply\n ): Promise<FastifyReply>;\n downloadFile(\n request: FastifyRequest<{ Params: VolumeFsParams; Querystring: { path: string } }>,\n reply: FastifyReply\n ): Promise<FastifyReply>;\n uploadFile(\n request: FastifyRequest<{ Params: VolumeFsParams; Body: { path: string; contentBase64: string } }>,\n reply: FastifyReply\n ): Promise<FastifyReply>;\n} {\n return {\n readFile: async (request, reply) => {\n const { name } = request.params;\n\n try {\n const { path: guestPath } = volumeFsReadSchema.parse(request.body ?? {});\n const hostRoot = resolveVolumeHostPath(name);\n const fullPath = resolveGuestPath(hostRoot, guestPath);\n const content = await fs.readFile(fullPath, \"utf-8\");\n return reply.send(ok({ path: guestPath, content }));\n } catch (err: unknown) {\n if (err instanceof z.ZodError) {\n throw new HttpError(400, \"VALIDATION_ERROR\", err.message);\n }\n if (err instanceof HttpError) throw err;\n throw new HttpError(404, \"VOLUME_READ_ERROR\", `Failed to read from volume '${name}': ${String(err)}`);\n }\n },\n\n writeFile: async (request, reply) => {\n const { name } = request.params;\n\n try {\n const { path: guestPath, content } = volumeFsWriteSchema.parse(request.body ?? {});\n const hostRoot = resolveVolumeHostPath(name);\n const fullPath = resolveGuestPath(hostRoot, guestPath);\n await fs.mkdir(path.dirname(fullPath), { recursive: true });\n await fs.writeFile(fullPath, content, \"utf-8\");\n return reply.send(ok({ path: guestPath }));\n } catch (err: unknown) {\n if (err instanceof z.ZodError) {\n throw new HttpError(400, \"VALIDATION_ERROR\", err.message);\n }\n if (err instanceof HttpError) throw err;\n throw new HttpError(500, \"VOLUME_WRITE_ERROR\", `Failed to write to volume '${name}': ${String(err)}`);\n }\n },\n\n listPath: async (request, reply) => {\n const { name } = request.params;\n\n try {\n const { path: guestPath } = volumeFsListSchema.parse(request.body ?? {});\n const hostRoot = resolveVolumeHostPath(name);\n const fullPath = resolveGuestPath(hostRoot, guestPath);\n const dirents = await fs.readdir(fullPath, { withFileTypes: true });\n const entries = dirents.map((d) => ({\n path: guestPath ? `${guestPath}/${d.name}` : d.name,\n kind: d.isDirectory() ? \"directory\" : d.isSymbolicLink() ? \"symlink\" : \"file\",\n size: 0,\n mode: 0,\n }));\n return reply.send(ok({ entries }));\n } catch (err: unknown) {\n if (err instanceof z.ZodError) {\n throw new HttpError(400, \"VALIDATION_ERROR\", err.message);\n }\n if (err instanceof HttpError) throw err;\n throw new HttpError(404, \"VOLUME_LIST_ERROR\", `Failed to list volume '${name}': ${String(err)}`);\n }\n },\n\n downloadFile: async (request, reply) => {\n const { name } = request.params;\n\n try {\n const { path: guestPath } = volumeFsDownloadSchema.parse(request.query ?? {});\n const hostRoot = resolveVolumeHostPath(name);\n const fullPath = resolveGuestPath(hostRoot, guestPath);\n const buf = await fs.readFile(fullPath);\n const contentBase64 = buf.toString(\"base64\");\n return reply.send(ok({ path: guestPath, contentBase64 }));\n } catch (err: unknown) {\n if (err instanceof z.ZodError) {\n throw new HttpError(400, \"VALIDATION_ERROR\", err.message);\n }\n if (err instanceof HttpError) throw err;\n throw new HttpError(404, \"VOLUME_DOWNLOAD_ERROR\", `Failed to download from volume '${name}': ${String(err)}`);\n }\n },\n\n uploadFile: async (request, reply) => {\n const { name } = request.params;\n\n try {\n const { path: guestPath, contentBase64 } = volumeFsUploadSchema.parse(request.body ?? {});\n const hostRoot = resolveVolumeHostPath(name);\n const fullPath = resolveGuestPath(hostRoot, guestPath);\n await fs.mkdir(path.dirname(fullPath), { recursive: true });\n const data = Buffer.from(contentBase64, \"base64\");\n await fs.writeFile(fullPath, data);\n return reply.send(ok({ path: guestPath }));\n } catch (err: unknown) {\n if (err instanceof z.ZodError) {\n throw new HttpError(400, \"VALIDATION_ERROR\", err.message);\n }\n if (err instanceof HttpError) throw err;\n throw new HttpError(500, \"VOLUME_UPLOAD_ERROR\", `Failed to upload to volume '${name}': ${String(err)}`);\n }\n },\n };\n}\n","import z from \"zod\";\n\nexport const volumeFsReadSchema = z.object({\n path: z.string(),\n});\n\nexport const volumeFsWriteSchema = z.object({\n path: z.string(),\n content: z.string(),\n});\n\nexport const volumeFsListSchema = z.object({\n path: z.string(),\n});\n\nexport const volumeFsUploadSchema = z.object({\n path: z.string(),\n contentBase64: z.string().min(1),\n});\n\nexport const volumeFsDownloadSchema = z.object({\n path: z.string(),\n});\n","import type { FastifyInstance } from \"fastify\";\nimport { createVolumeFsController } from \"../controllers/volume-fs\";\n\nexport function registerVolumeFsRoutes(app: FastifyInstance): void {\n const controller = createVolumeFsController();\n\n app.post(\"/api/volumes/:name/fs/read\", controller.readFile);\n app.post(\"/api/volumes/:name/fs/write\", controller.writeFile);\n app.post(\"/api/volumes/:name/fs/list\", controller.listPath);\n app.get(\"/api/volumes/:name/fs/download\", controller.downloadFile);\n app.post(\"/api/volumes/:name/fs/upload\", controller.uploadFile);\n}\n","import type { PullImageInput } from \"../schemas/images\";\n\nexport type ImageRecord = {\n ref: string;\n sourceType: string;\n cached: boolean;\n size?: number;\n createdAt?: string;\n lastUsedAt?: string;\n};\n\nexport class ImageService {\n async listImages(): Promise<{ items: ImageRecord[]; total: number }> {\n return { items: [], total: 0 };\n }\n\n async pullImage(_input: PullImageInput): Promise<ImageRecord> {\n throw new Error(\"Image pull not supported in OpenSandbox gateway\");\n }\n\n async getImage(ref: string): Promise<ImageRecord> {\n return {\n ref,\n sourceType: \"oci\",\n cached: false,\n };\n }\n\n async deleteImage(ref: string): Promise<{ ref: string }> {\n return { ref };\n }\n}\n","import type { FastifyInstance } from \"fastify\";\nimport swagger from \"@fastify/swagger\";\nimport swaggerUi from \"@fastify/swagger-ui\";\n\nconst swaggerConfig = {\n openapi: {\n openapi: \"3.0.0\",\n info: {\n title: \"OpenSandbox Gateway API\",\n description: \"Sandbox lifecycle management backed by OpenSandbox\",\n version: \"1.0.0\",\n },\n servers: [{ url: \"http://localhost:4002\", description: \"Local development\" }],\n components: {\n securitySchemes: {\n bearerAuth: { type: \"http\" as const, scheme: \"bearer\" as const, bearerFormat: \"API Key\" },\n },\n },\n tags: [\n { name: \"Sandboxes\", description: \"Sandbox lifecycle\" },\n { name: \"Files\", description: \"File operations inside sandboxes\" },\n { name: \"Shell\", description: \"Execute commands inside sandboxes\" },\n { name: \"Images\", description: \"Image management (stub)\" },\n { name: \"Volumes\", description: \"Named volume filesystem operations\" },\n { name: \"Health\", description: \"Service health check\" },\n ],\n },\n};\n\nconst swaggerUiConfig = {\n routePrefix: \"/api-docs\",\n uiConfig: { docExpansion: \"list\" as const, deepLinking: true },\n staticCSP: true,\n transformStaticCSP: (header: string) => header,\n};\n\nexport async function configureSwagger(app: FastifyInstance) {\n await app.register(swagger, swaggerConfig);\n await app.register(swaggerUi, swaggerUiConfig);\n}\n","export interface ParsedServerArgs {\n host?: string;\n port?: number;\n}\n\nexport interface ResolvedServerConfig {\n host: string;\n port: number;\n apiKey?: string;\n}\n\nfunction parsePort(raw: string, source: string): number {\n const value = Number(raw);\n if (!Number.isInteger(value) || value <= 0 || value > 65535) {\n throw new Error(`Invalid value for ${source}: ${raw}`);\n }\n return value;\n}\n\nfunction isMissingOptionValue(raw: string | undefined): raw is undefined {\n return !raw || raw.startsWith(\"--\");\n}\n\nexport function parseServerArgs(argv: string[]): ParsedServerArgs {\n const parsed: ParsedServerArgs = {};\n\n for (let index = 0; index < argv.length; index += 1) {\n const token = argv[index];\n\n if (token === \"--port\") {\n const raw = argv[index + 1];\n if (isMissingOptionValue(raw)) {\n throw new Error(\"Missing value for --port\");\n }\n parsed.port = parsePort(raw, \"--port\");\n index += 1;\n continue;\n }\n\n if (token === \"--host\") {\n const raw = argv[index + 1];\n if (isMissingOptionValue(raw)) {\n throw new Error(\"Missing value for --host\");\n }\n parsed.host = raw;\n index += 1;\n }\n }\n\n return parsed;\n}\n\nexport function resolveServerConfig({\n args,\n env,\n}: {\n args: ParsedServerArgs;\n env: NodeJS.ProcessEnv;\n}): ResolvedServerConfig {\n return {\n host: args.host ?? env.HOST ?? \"0.0.0.0\",\n port: args.port ?? (env.PORT ? parsePort(env.PORT, \"PORT\") : 4002),\n apiKey: env.GATEWAY_API_KEY ?? env.MICROSANDBOX_API_KEY,\n };\n}\n","import type { FastifyInstance } from \"fastify\";\nimport { buildApp } from \"./app\";\nimport { parseServerArgs, resolveServerConfig } from \"./lib/server-cli\";\n\nexport async function startServer({\n argv = process.argv.slice(2),\n env = process.env,\n app,\n}: {\n argv?: string[];\n env?: NodeJS.ProcessEnv;\n app?: Pick<FastifyInstance, \"listen\" | \"close\">;\n} = {}): Promise<Pick<FastifyInstance, \"listen\" | \"close\">> {\n const config = resolveServerConfig({ args: parseServerArgs(argv), env });\n const resolvedApp = app ?? (await buildApp({ apiKey: config.apiKey }));\n\n const removeSignalHandlers = (): void => {\n process.off(\"SIGINT\", onSigInt);\n process.off(\"SIGTERM\", onSigTerm);\n };\n\n const close = async (): Promise<undefined> => {\n removeSignalHandlers();\n return resolvedApp.close();\n };\n\n const onSigInt = () => { void shutdown(0); };\n const onSigTerm = () => { void shutdown(0); };\n\n const shutdown = async (code: number): Promise<void> => {\n try {\n await close();\n process.exit(code);\n } catch (error) {\n console.error(\"Failed to shutdown opensandbox-gateway cleanly\", error);\n process.exit(1);\n }\n };\n\n process.once(\"SIGINT\", onSigInt);\n process.once(\"SIGTERM\", onSigTerm);\n\n try {\n await resolvedApp.listen({ port: config.port, host: config.host });\n return { listen: resolvedApp.listen.bind(resolvedApp), close: close as FastifyInstance[\"close\"] };\n } catch (error) {\n removeSignalHandlers();\n throw error;\n }\n}\n"],"mappings":"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","names":["path","z","z","z","z"]}
|