@cloudflare/sandbox 0.13.0-next.769.1 → 1.0.0-rc.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +62 -219
- package/dist/index.d.mts +548 -0
- package/dist/index.mjs +2452 -0
- package/package.json +17 -118
- package/Dockerfile +0 -327
- package/dist/bridge/index.d.ts +0 -181
- package/dist/bridge/index.d.ts.map +0 -1
- package/dist/bridge/index.js +0 -3053
- package/dist/bridge/index.js.map +0 -1
- package/dist/contexts-1EsLHByO.d.ts +0 -463
- package/dist/contexts-1EsLHByO.d.ts.map +0 -1
- package/dist/dist-Duor5GbS.js +0 -752
- package/dist/dist-Duor5GbS.js.map +0 -1
- package/dist/errors/index.d.ts +0 -4
- package/dist/errors/index.js +0 -4
- package/dist/errors-CXR0xBpw.js +0 -285
- package/dist/errors-CXR0xBpw.js.map +0 -1
- package/dist/errors-QYlSkVGz.js +0 -893
- package/dist/errors-QYlSkVGz.js.map +0 -1
- package/dist/extensions/index.d.ts +0 -4
- package/dist/extensions/index.js +0 -6
- package/dist/extensions-CFB2xHqY.js +0 -1023
- package/dist/extensions-CFB2xHqY.js.map +0 -1
- package/dist/filesystem-BWAZCZER.d.ts +0 -732
- package/dist/filesystem-BWAZCZER.d.ts.map +0 -1
- package/dist/git/index.d.ts +0 -63
- package/dist/git/index.d.ts.map +0 -1
- package/dist/git/index.js +0 -338
- package/dist/git/index.js.map +0 -1
- package/dist/index-Bs4bqXDR.d.ts +0 -438
- package/dist/index-Bs4bqXDR.d.ts.map +0 -1
- package/dist/index-HNYBk-az.d.ts +0 -444
- package/dist/index-HNYBk-az.d.ts.map +0 -1
- package/dist/index.d.ts +0 -576
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -33
- package/dist/index.js.map +0 -1
- package/dist/interpreter/index.d.ts +0 -311
- package/dist/interpreter/index.d.ts.map +0 -1
- package/dist/interpreter/index.js +0 -292
- package/dist/interpreter/index.js.map +0 -1
- package/dist/openai/index.d.ts +0 -68
- package/dist/openai/index.d.ts.map +0 -1
- package/dist/openai/index.js +0 -367
- package/dist/openai/index.js.map +0 -1
- package/dist/opencode/index.d.ts +0 -182
- package/dist/opencode/index.d.ts.map +0 -1
- package/dist/opencode/index.js +0 -454
- package/dist/opencode/index.js.map +0 -1
- package/dist/process-types-GStiZ8f8.d.ts +0 -73
- package/dist/process-types-GStiZ8f8.d.ts.map +0 -1
- package/dist/sandbox-BbAabq93.d.ts +0 -42
- package/dist/sandbox-BbAabq93.d.ts.map +0 -1
- package/dist/sandbox-cmlgGVYX.js +0 -10056
- package/dist/sandbox-cmlgGVYX.js.map +0 -1
- package/dist/sidecar/index.d.ts +0 -77
- package/dist/sidecar/index.d.ts.map +0 -1
- package/dist/sidecar/index.js +0 -201
- package/dist/sidecar/index.js.map +0 -1
- package/dist/xterm/index.d.ts +0 -93
- package/dist/xterm/index.d.ts.map +0 -1
- package/dist/xterm/index.js +0 -220
- package/dist/xterm/index.js.map +0 -1
package/package.json
CHANGED
|
@@ -1,129 +1,28 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cloudflare/sandbox",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.0-rc.0",
|
|
4
|
+
"description": "Structured workspace file operations for Cloudflare sandboxes",
|
|
5
|
+
"license": "Apache-2.0",
|
|
4
6
|
"repository": {
|
|
5
7
|
"type": "git",
|
|
6
|
-
"url": "https://github.com/cloudflare/sandbox-sdk"
|
|
7
|
-
},
|
|
8
|
-
"description": "A sandboxed environment for running commands",
|
|
9
|
-
"type": "module",
|
|
10
|
-
"dependencies": {
|
|
11
|
-
"@cloudflare/containers": "^0.3.7",
|
|
12
|
-
"aws4fetch": "^1.0.20",
|
|
13
|
-
"capnweb": "^0.8.0",
|
|
14
|
-
"hono": "^4.12.26"
|
|
15
|
-
},
|
|
16
|
-
"devDependencies": {
|
|
17
|
-
"@openai/agents": "^0.3.3",
|
|
18
|
-
"@opencode-ai/sdk": "^1.1.40",
|
|
19
|
-
"@repo/shared": "^0.0.0",
|
|
20
|
-
"@types/acorn": "^4.0.6",
|
|
21
|
-
"@types/bun": "^1.3.14",
|
|
22
|
-
"@types/tar-stream": "^3.1.4",
|
|
23
|
-
"@xterm/xterm": "^6.0.0",
|
|
24
|
-
"acorn": "^8.14.0",
|
|
25
|
-
"async-mutex": "^0.5.0",
|
|
26
|
-
"tar-stream": "^3.2.0",
|
|
27
|
-
"wrangler": "^4.102.0"
|
|
28
|
-
},
|
|
29
|
-
"peerDependencies": {
|
|
30
|
-
"@openai/agents": "^0.3.3",
|
|
31
|
-
"@opencode-ai/sdk": "^1.1.40",
|
|
32
|
-
"@xterm/xterm": ">=5.0.0"
|
|
33
|
-
},
|
|
34
|
-
"peerDependenciesMeta": {
|
|
35
|
-
"@openai/agents": {
|
|
36
|
-
"optional": true
|
|
37
|
-
},
|
|
38
|
-
"@opencode-ai/sdk": {
|
|
39
|
-
"optional": true
|
|
40
|
-
},
|
|
41
|
-
"@xterm/xterm": {
|
|
42
|
-
"optional": true
|
|
43
|
-
}
|
|
8
|
+
"url": "git+https://github.com/cloudflare/sandbox-sdk.git"
|
|
44
9
|
},
|
|
45
|
-
"
|
|
46
|
-
"
|
|
47
|
-
"codegen",
|
|
48
|
-
"containers",
|
|
49
|
-
"cloudflare",
|
|
50
|
-
"durable objects"
|
|
10
|
+
"files": [
|
|
11
|
+
"dist"
|
|
51
12
|
],
|
|
52
|
-
"
|
|
53
|
-
|
|
54
|
-
"build:sidecar": "bun run ../../extensions/interpreter/build.ts",
|
|
55
|
-
"check": "biome check && npm run typecheck",
|
|
56
|
-
"fix": "biome check --fix && npm run typecheck",
|
|
57
|
-
"typecheck": "tsc --noEmit && tsc --noEmit -p tsconfig.sidecar.json",
|
|
58
|
-
"docker:local": "scripts/docker-local.sh",
|
|
59
|
-
"test": "vitest run --config vitest.config.ts \"$@\"",
|
|
60
|
-
"test:harness": "vitest run --config vitest.harness.config.ts \"$@\"",
|
|
61
|
-
"test:sidecar": "bun test ../../extensions/interpreter/src/sidecar",
|
|
62
|
-
"test:e2e": "npm run test:e2e:vitest && npm run test:e2e:browser",
|
|
63
|
-
"test:e2e:vitest": "cd ../../tests/e2e/test-worker && ./generate-config.sh && cd ../../.. && vitest run --config vitest.e2e.config.ts \"$@\"",
|
|
64
|
-
"test:e2e:browser": "cd ../../tests/e2e/test-worker && ./generate-config.sh && cd ../../.. && npx playwright install chromium && playwright test --config tests/e2e/browser/playwright.config.ts",
|
|
65
|
-
"test:perf": "cd ../.. && vitest run --config vitest.perf.config.ts \"$@\""
|
|
66
|
-
},
|
|
13
|
+
"type": "module",
|
|
14
|
+
"sideEffects": false,
|
|
67
15
|
"exports": {
|
|
68
16
|
".": {
|
|
69
|
-
"types": "./dist/index.d.
|
|
70
|
-
"import": "./dist/index.
|
|
71
|
-
"require": "./dist/index.js"
|
|
72
|
-
},
|
|
73
|
-
"./extensions": {
|
|
74
|
-
"types": "./dist/extensions/index.d.ts",
|
|
75
|
-
"import": "./dist/extensions/index.js",
|
|
76
|
-
"require": "./dist/extensions/index.js"
|
|
77
|
-
},
|
|
78
|
-
"./errors": {
|
|
79
|
-
"types": "./dist/errors/index.d.ts",
|
|
80
|
-
"import": "./dist/errors/index.js",
|
|
81
|
-
"require": "./dist/errors/index.js"
|
|
82
|
-
},
|
|
83
|
-
"./sidecar": {
|
|
84
|
-
"types": "./dist/sidecar/index.d.ts",
|
|
85
|
-
"import": "./dist/sidecar/index.js",
|
|
86
|
-
"require": "./dist/sidecar/index.js"
|
|
87
|
-
},
|
|
88
|
-
"./interpreter": {
|
|
89
|
-
"types": "./dist/interpreter/index.d.ts",
|
|
90
|
-
"import": "./dist/interpreter/index.js",
|
|
91
|
-
"require": "./dist/interpreter/index.js"
|
|
92
|
-
},
|
|
93
|
-
"./git": {
|
|
94
|
-
"types": "./dist/git/index.d.ts",
|
|
95
|
-
"import": "./dist/git/index.js",
|
|
96
|
-
"require": "./dist/git/index.js"
|
|
97
|
-
},
|
|
98
|
-
"./openai": {
|
|
99
|
-
"types": "./dist/openai/index.d.ts",
|
|
100
|
-
"import": "./dist/openai/index.js",
|
|
101
|
-
"require": "./dist/openai/index.js"
|
|
102
|
-
},
|
|
103
|
-
"./opencode": {
|
|
104
|
-
"types": "./dist/opencode/index.d.ts",
|
|
105
|
-
"import": "./dist/opencode/index.js",
|
|
106
|
-
"require": "./dist/opencode/index.js"
|
|
107
|
-
},
|
|
108
|
-
"./xterm": {
|
|
109
|
-
"types": "./dist/xterm/index.d.ts",
|
|
110
|
-
"import": "./dist/xterm/index.js",
|
|
111
|
-
"require": "./dist/xterm/index.js"
|
|
112
|
-
},
|
|
113
|
-
"./bridge": {
|
|
114
|
-
"types": "./dist/bridge/index.d.ts",
|
|
115
|
-
"import": "./dist/bridge/index.js",
|
|
116
|
-
"require": "./dist/bridge/index.js"
|
|
17
|
+
"types": "./dist/index.d.mts",
|
|
18
|
+
"import": "./dist/index.mjs"
|
|
117
19
|
}
|
|
118
20
|
},
|
|
119
|
-
"
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
"
|
|
123
|
-
"
|
|
124
|
-
"
|
|
125
|
-
|
|
126
|
-
"README.md",
|
|
127
|
-
"LICENSE"
|
|
128
|
-
]
|
|
21
|
+
"publishConfig": {
|
|
22
|
+
"access": "public"
|
|
23
|
+
},
|
|
24
|
+
"dependencies": {
|
|
25
|
+
"aws4fetch": "1.0.20",
|
|
26
|
+
"zod": "4.5.4"
|
|
27
|
+
}
|
|
129
28
|
}
|
package/Dockerfile
DELETED
|
@@ -1,327 +0,0 @@
|
|
|
1
|
-
# Bun version — override via --build-arg BUN_VERSION=$(cat .bun-version)
|
|
2
|
-
ARG BUN_VERSION=1.3.14
|
|
3
|
-
# Node version — override via --build-arg NODE_VERSION=24
|
|
4
|
-
ARG NODE_VERSION=24
|
|
5
|
-
# cloudflared release — shared across glibc and musl image variants.
|
|
6
|
-
# Bump this together with the architecture-specific checksums below.
|
|
7
|
-
ARG CLOUDFLARED_VERSION=2026.3.0
|
|
8
|
-
FROM oven/bun:${BUN_VERSION} AS bun-binary
|
|
9
|
-
FROM node:${NODE_VERSION}-slim AS node-runtime
|
|
10
|
-
|
|
11
|
-
# ============================================================================
|
|
12
|
-
# cloudflared (Cloudflare Tunnel daemon) — enables sandbox.tunnels.*
|
|
13
|
-
# Version pin lives at the top of this Dockerfile as a global ARG, shared
|
|
14
|
-
# by every image variant so they ship the same release.
|
|
15
|
-
# ============================================================================
|
|
16
|
-
FROM alpine:3.21 AS cloudflared-binary
|
|
17
|
-
|
|
18
|
-
ARG TARGETARCH
|
|
19
|
-
ARG CLOUDFLARED_VERSION
|
|
20
|
-
ARG CLOUDFLARED_SHA256_AMD64=4a9e50e6d6d798e90fcd01933151a90bf7edd99a0a55c28ad18f2e16263a5c30
|
|
21
|
-
ARG CLOUDFLARED_SHA256_ARM64=0755ba4cbab59980e6148367fcf53a8f3ec85a97deefd63c2420cf7850769bee
|
|
22
|
-
|
|
23
|
-
# Inject the host's extra CA bundle when downloading behind a TLS-intercepting
|
|
24
|
-
# proxy (e.g. Cloudflare WARP / Zero Trust). No-op when the secret isn't passed.
|
|
25
|
-
RUN --mount=type=secret,id=wrangler_ca \
|
|
26
|
-
if [ -f /run/secrets/wrangler_ca ] && [ -s /run/secrets/wrangler_ca ]; then \
|
|
27
|
-
cat /run/secrets/wrangler_ca >> /etc/ssl/certs/ca-certificates.crt; \
|
|
28
|
-
mkdir -p /usr/local/share/ca-certificates && \
|
|
29
|
-
cp /run/secrets/wrangler_ca /usr/local/share/ca-certificates/wrangler-dev-ca.crt; \
|
|
30
|
-
fi && \
|
|
31
|
-
apk add --no-cache ca-certificates curl && \
|
|
32
|
-
if [ -f /usr/local/share/ca-certificates/wrangler-dev-ca.crt ]; then \
|
|
33
|
-
update-ca-certificates; \
|
|
34
|
-
fi
|
|
35
|
-
|
|
36
|
-
RUN set -eux; \
|
|
37
|
-
arch="${TARGETARCH:-}"; \
|
|
38
|
-
if [ -z "$arch" ]; then \
|
|
39
|
-
arch="$(apk --print-arch)"; \
|
|
40
|
-
fi; \
|
|
41
|
-
case "$arch" in \
|
|
42
|
-
amd64|x86_64) suffix=amd64; sha="${CLOUDFLARED_SHA256_AMD64}" ;; \
|
|
43
|
-
arm64|aarch64) suffix=arm64; sha="${CLOUDFLARED_SHA256_ARM64}" ;; \
|
|
44
|
-
*) echo "Unsupported arch for cloudflared: $arch" >&2; exit 1 ;; \
|
|
45
|
-
esac; \
|
|
46
|
-
url="https://github.com/cloudflare/cloudflared/releases/download/${CLOUDFLARED_VERSION}/cloudflared-linux-${suffix}"; \
|
|
47
|
-
curl -fsSL -o /cloudflared "$url"; \
|
|
48
|
-
echo "$sha /cloudflared" | sha256sum -c -; \
|
|
49
|
-
chmod +x /cloudflared; \
|
|
50
|
-
/cloudflared --version
|
|
51
|
-
|
|
52
|
-
# Sandbox container images (default and python variants)
|
|
53
|
-
# Multi-stage build optimized for Turborepo monorepo
|
|
54
|
-
|
|
55
|
-
# ============================================================================
|
|
56
|
-
# Stage 1: Prune monorepo to only include necessary packages
|
|
57
|
-
# ============================================================================
|
|
58
|
-
FROM node-runtime AS pruner
|
|
59
|
-
|
|
60
|
-
WORKDIR /app
|
|
61
|
-
|
|
62
|
-
RUN npm install -g turbo
|
|
63
|
-
|
|
64
|
-
COPY . .
|
|
65
|
-
|
|
66
|
-
# Prune to only @repo/sandbox-container and its dependencies (@repo/shared)
|
|
67
|
-
# The --docker flag generates out/json and out/full directories
|
|
68
|
-
RUN turbo prune @repo/sandbox-container --docker
|
|
69
|
-
|
|
70
|
-
# ============================================================================
|
|
71
|
-
# Stage 2: Install dependencies and build packages
|
|
72
|
-
# Using glibc-based images (not Alpine) so the standalone binary works on
|
|
73
|
-
# standard Linux distributions (Debian, Ubuntu, RHEL, etc.)
|
|
74
|
-
# ============================================================================
|
|
75
|
-
FROM node-runtime AS builder
|
|
76
|
-
|
|
77
|
-
WORKDIR /app
|
|
78
|
-
|
|
79
|
-
# Install Bun runtime (glibc version for glibc-compatible standalone binary)
|
|
80
|
-
COPY --from=bun-binary /usr/local/bin/bun /usr/local/bin/bun
|
|
81
|
-
|
|
82
|
-
# Copy pruned lockfile and package.json files (for Docker layer caching)
|
|
83
|
-
COPY --from=pruner /app/out/json/ .
|
|
84
|
-
COPY --from=pruner /app/out/package-lock.json ./package-lock.json
|
|
85
|
-
|
|
86
|
-
# Install ALL dependencies with cache mount for npm packages
|
|
87
|
-
RUN --mount=type=cache,target=/root/.npm \
|
|
88
|
-
CI=true npm ci
|
|
89
|
-
|
|
90
|
-
COPY --from=pruner /app/out/full/ .
|
|
91
|
-
|
|
92
|
-
# Build all packages (Turborepo handles dependency order automatically)
|
|
93
|
-
# This builds @repo/shared first, then @repo/sandbox-container (including standalone binary)
|
|
94
|
-
RUN npx turbo run build
|
|
95
|
-
|
|
96
|
-
# ============================================================================
|
|
97
|
-
# Stage 3: Download pre-built Python 3.11.14
|
|
98
|
-
# ============================================================================
|
|
99
|
-
FROM ubuntu:22.04 AS python-builder
|
|
100
|
-
|
|
101
|
-
# Prevent interactive prompts during package installation
|
|
102
|
-
ENV DEBIAN_FRONTEND=noninteractive
|
|
103
|
-
|
|
104
|
-
# Accept architecture from Docker BuildKit (for multi-arch builds)
|
|
105
|
-
ARG TARGETARCH
|
|
106
|
-
|
|
107
|
-
# Install minimal dependencies for downloading
|
|
108
|
-
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
|
|
109
|
-
--mount=type=cache,target=/var/lib/apt,sharing=locked \
|
|
110
|
-
rm -f /etc/apt/apt.conf.d/docker-clean && \
|
|
111
|
-
echo 'Binary::apt::APT::Keep-Downloaded-Packages "true";' >/etc/apt/apt.conf.d/keep-cache && \
|
|
112
|
-
apt-get update && apt-get install -y --no-install-recommends \
|
|
113
|
-
wget ca-certificates
|
|
114
|
-
|
|
115
|
-
# Download and extract pre-built Python 3.11.14 from python-build-standalone
|
|
116
|
-
# Using PGO+LTO optimized builds for better performance
|
|
117
|
-
# Supports multi-arch: amd64 (x86_64) and arm64 (aarch64)
|
|
118
|
-
RUN --mount=type=cache,target=/tmp/python-cache \
|
|
119
|
-
# Map Docker TARGETARCH to python-build-standalone arch naming
|
|
120
|
-
if [ "$TARGETARCH" = "amd64" ]; then \
|
|
121
|
-
PYTHON_ARCH="x86_64-unknown-linux-gnu"; \
|
|
122
|
-
EXPECTED_SHA256="edd8d11aa538953d12822fab418359a692fd1ee4ca2675579fbf0fa31e3688f1"; \
|
|
123
|
-
elif [ "$TARGETARCH" = "arm64" ]; then \
|
|
124
|
-
PYTHON_ARCH="aarch64-unknown-linux-gnu"; \
|
|
125
|
-
EXPECTED_SHA256="08141d31f95d86a23f23e4c741b726de0055f12f83200d1d4867b4e8e6e967c5"; \
|
|
126
|
-
else \
|
|
127
|
-
echo "Unsupported architecture: $TARGETARCH" && exit 1; \
|
|
128
|
-
fi && \
|
|
129
|
-
cd /tmp/python-cache && \
|
|
130
|
-
wget -nc https://github.com/indygreg/python-build-standalone/releases/download/20251028/cpython-3.11.14+20251028-${PYTHON_ARCH}-install_only.tar.gz && \
|
|
131
|
-
# Verify SHA256 checksum for security
|
|
132
|
-
echo "${EXPECTED_SHA256} cpython-3.11.14+20251028-${PYTHON_ARCH}-install_only.tar.gz" | sha256sum -c - && \
|
|
133
|
-
cd /tmp && \
|
|
134
|
-
tar -xzf /tmp/python-cache/cpython-3.11.14+20251028-${PYTHON_ARCH}-install_only.tar.gz && \
|
|
135
|
-
mv python /usr/local/ && \
|
|
136
|
-
rm -rf /tmp/cpython-*
|
|
137
|
-
|
|
138
|
-
# ============================================================================
|
|
139
|
-
# Stage 4: Runtime base - Ubuntu 22.04 with Node.js and Bun (no Python)
|
|
140
|
-
# ============================================================================
|
|
141
|
-
FROM ubuntu:22.04 AS runtime-base
|
|
142
|
-
|
|
143
|
-
# Accept version as build argument (passed from npm_package_version)
|
|
144
|
-
ARG SANDBOX_VERSION=unknown
|
|
145
|
-
|
|
146
|
-
# Prevent interactive prompts during package installation
|
|
147
|
-
ENV DEBIAN_FRONTEND=noninteractive
|
|
148
|
-
|
|
149
|
-
ENV SANDBOX_VERSION=${SANDBOX_VERSION}
|
|
150
|
-
|
|
151
|
-
# Install runtime packages, S3FS-FUSE for bucket mounting, and snapshot tools
|
|
152
|
-
# - fuse3: FUSE filesystem support (replaces legacy fuse, needed by s3fs/squashfuse/fuse-overlayfs)
|
|
153
|
-
# - squashfs-tools: create squashfs archives (mksquashfs)
|
|
154
|
-
# - squashfuse: mount squashfs in userspace (FUSE)
|
|
155
|
-
# - fuse-overlayfs: userspace overlayfs for copy-on-write snapshots
|
|
156
|
-
# Cache-bust: 2 - Clear apt cache to force fresh package list
|
|
157
|
-
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
|
|
158
|
-
--mount=type=cache,target=/var/lib/apt,sharing=locked \
|
|
159
|
-
rm -f /etc/apt/apt.conf.d/docker-clean && \
|
|
160
|
-
echo 'Binary::apt::APT::Keep-Downloaded-Packages "true";' >/etc/apt/apt.conf.d/keep-cache && \
|
|
161
|
-
rm -rf /var/cache/apt/* /var/lib/apt/lists/* && \
|
|
162
|
-
apt-get update && apt-get install -y --no-install-recommends \
|
|
163
|
-
s3fs fuse3 squashfs-tools squashfuse fuse-overlayfs \
|
|
164
|
-
ca-certificates curl wget procps git unzip zip jq file tini \
|
|
165
|
-
inotify-tools \
|
|
166
|
-
libssl3 zlib1g libbz2-1.0 libreadline8 libsqlite3-0 \
|
|
167
|
-
libncursesw6 libtinfo6 libxml2 libxmlsec1 libffi8 liblzma5 libtk8.6 && \
|
|
168
|
-
update-ca-certificates
|
|
169
|
-
|
|
170
|
-
# Enable FUSE in container - allow non-root users to use FUSE
|
|
171
|
-
RUN sed -i 's/#user_allow_other/user_allow_other/' /etc/fuse.conf
|
|
172
|
-
|
|
173
|
-
# fusermount requires /etc/mtab to locate active mounts
|
|
174
|
-
RUN ln -sf /proc/mounts /etc/mtab
|
|
175
|
-
|
|
176
|
-
# Install Node.js from official Node image (defaults to 24 LTS,
|
|
177
|
-
# override via --build-arg NODE_VERSION=<version>)
|
|
178
|
-
COPY --from=node-runtime /usr/local/bin/node /usr/local/bin/node
|
|
179
|
-
COPY --from=node-runtime /usr/local/lib/node_modules /usr/local/lib/node_modules
|
|
180
|
-
RUN ln -s /usr/local/lib/node_modules/npm/bin/npm-cli.js /usr/local/bin/npm && \
|
|
181
|
-
ln -s /usr/local/lib/node_modules/npm/bin/npx-cli.js /usr/local/bin/npx
|
|
182
|
-
|
|
183
|
-
# Install Bun runtime from official image
|
|
184
|
-
COPY --from=bun-binary /usr/local/bin/bun /usr/local/bin/bun
|
|
185
|
-
|
|
186
|
-
# Copy standalone binary
|
|
187
|
-
COPY --from=builder /app/packages/sandbox-container/dist/sandbox /container-server/sandbox
|
|
188
|
-
|
|
189
|
-
# Set up container server directory
|
|
190
|
-
WORKDIR /container-server
|
|
191
|
-
|
|
192
|
-
# Copy legacy JS bundle for backwards compatibility
|
|
193
|
-
# Users with custom startup scripts that call `bun /container-server/dist/index.js` need this
|
|
194
|
-
COPY --from=builder /app/packages/sandbox-container/dist/index.js ./dist/
|
|
195
|
-
|
|
196
|
-
COPY --from=cloudflared-binary /cloudflared /usr/local/bin/cloudflared
|
|
197
|
-
RUN cloudflared --version
|
|
198
|
-
|
|
199
|
-
# Inject the host's extra CA bundle when running locally behind a TLS-
|
|
200
|
-
# intercepting proxy (e.g. Cloudflare WARP / Zero Trust). See
|
|
201
|
-
# DOCKER_README.md for the local-dev setup. No-op when the secret
|
|
202
|
-
# isn't passed.
|
|
203
|
-
RUN --mount=type=secret,id=wrangler_ca \
|
|
204
|
-
if [ -f /run/secrets/wrangler_ca ] && [ -s /run/secrets/wrangler_ca ]; then \
|
|
205
|
-
cp /run/secrets/wrangler_ca /usr/local/share/ca-certificates/wrangler-dev-ca.crt && \
|
|
206
|
-
cat /run/secrets/wrangler_ca >> /etc/ssl/certs/ca-certificates.crt && \
|
|
207
|
-
update-ca-certificates; \
|
|
208
|
-
fi
|
|
209
|
-
|
|
210
|
-
RUN mkdir -p /workspace
|
|
211
|
-
|
|
212
|
-
# Expose the application port (3000 for control)
|
|
213
|
-
EXPOSE 3000
|
|
214
|
-
|
|
215
|
-
# ============================================================================
|
|
216
|
-
# Stage 5a: Default image - lean, no Python
|
|
217
|
-
# ============================================================================
|
|
218
|
-
FROM runtime-base AS default
|
|
219
|
-
|
|
220
|
-
# Disable Python pool (Python not available in this image)
|
|
221
|
-
ENV PYTHON_POOL_MIN_SIZE=0
|
|
222
|
-
ENV JAVASCRIPT_POOL_MIN_SIZE=3
|
|
223
|
-
ENV TYPESCRIPT_POOL_MIN_SIZE=3
|
|
224
|
-
|
|
225
|
-
ENTRYPOINT ["/usr/bin/tini", "--", "/container-server/sandbox"]
|
|
226
|
-
|
|
227
|
-
# ============================================================================
|
|
228
|
-
# Stage 5b: Python image - full, with Python + data science packages
|
|
229
|
-
# ============================================================================
|
|
230
|
-
FROM runtime-base AS python
|
|
231
|
-
|
|
232
|
-
# Copy pre-built Python from python-builder stage
|
|
233
|
-
COPY --from=python-builder /usr/local/python /usr/local/python
|
|
234
|
-
|
|
235
|
-
# Create symlinks and update shared library cache
|
|
236
|
-
RUN ln -s /usr/local/python/bin/python3.11 /usr/local/bin/python3.11 && \
|
|
237
|
-
ln -s /usr/local/python/bin/python3 /usr/local/bin/python3 && \
|
|
238
|
-
ln -s /usr/local/python/bin/pip3 /usr/local/bin/pip3 && \
|
|
239
|
-
echo "/usr/local/python/lib" > /etc/ld.so.conf.d/python.conf && \
|
|
240
|
-
ldconfig
|
|
241
|
-
|
|
242
|
-
# Set Python 3.11 as default python3
|
|
243
|
-
RUN update-alternatives --install /usr/bin/python3 python3 /usr/local/bin/python3.11 1
|
|
244
|
-
|
|
245
|
-
# Install Python packages for data science and the code interpreter extension.
|
|
246
|
-
# The interpreter runtime itself is provisioned by the @cloudflare/sandbox/interpreter
|
|
247
|
-
# extension; this image only provides the Python toolchain it relies on.
|
|
248
|
-
RUN --mount=type=cache,target=/root/.cache/pip \
|
|
249
|
-
pip3 install --no-cache-dir matplotlib numpy pandas ipython
|
|
250
|
-
|
|
251
|
-
# Pre-warm pool sizes consumed by the interpreter extension sidecar
|
|
252
|
-
ENV PYTHON_POOL_MIN_SIZE=3
|
|
253
|
-
ENV JAVASCRIPT_POOL_MIN_SIZE=3
|
|
254
|
-
ENV TYPESCRIPT_POOL_MIN_SIZE=3
|
|
255
|
-
|
|
256
|
-
ENTRYPOINT ["/usr/bin/tini", "--", "/container-server/sandbox"]
|
|
257
|
-
|
|
258
|
-
# ============================================================================
|
|
259
|
-
# Stage 5c: OpenCode image - with OpenCode CLI for AI coding agent
|
|
260
|
-
# ============================================================================
|
|
261
|
-
FROM runtime-base AS opencode
|
|
262
|
-
|
|
263
|
-
RUN --mount=type=secret,id=wrangler_ca \
|
|
264
|
-
if [ -f /run/secrets/wrangler_ca ] && [ -s /run/secrets/wrangler_ca ]; then \
|
|
265
|
-
cp /run/secrets/wrangler_ca /usr/local/share/ca-certificates/wrangler-dev-ca.crt && \
|
|
266
|
-
update-ca-certificates; \
|
|
267
|
-
fi
|
|
268
|
-
|
|
269
|
-
# Install OpenCode CLI via npm (avoids GitHub API rate limits)
|
|
270
|
-
RUN npm i -g opencode-ai \
|
|
271
|
-
&& opencode --version
|
|
272
|
-
|
|
273
|
-
# Disable Python pool (Python not available in this image)
|
|
274
|
-
ENV PYTHON_POOL_MIN_SIZE=0
|
|
275
|
-
ENV JAVASCRIPT_POOL_MIN_SIZE=3
|
|
276
|
-
ENV TYPESCRIPT_POOL_MIN_SIZE=3
|
|
277
|
-
|
|
278
|
-
# Expose OpenCode server port (in addition to 3000 from runtime-base)
|
|
279
|
-
EXPOSE 4096
|
|
280
|
-
|
|
281
|
-
ENTRYPOINT ["/usr/bin/tini", "--", "/container-server/sandbox"]
|
|
282
|
-
|
|
283
|
-
# ============================================================================
|
|
284
|
-
# Stage 5d: Musl image - Alpine-based with musl-linked binary
|
|
285
|
-
# ============================================================================
|
|
286
|
-
FROM alpine:3.21 AS musl
|
|
287
|
-
|
|
288
|
-
ARG SANDBOX_VERSION=unknown
|
|
289
|
-
|
|
290
|
-
ENV SANDBOX_VERSION=${SANDBOX_VERSION}
|
|
291
|
-
|
|
292
|
-
# CA certificate installation
|
|
293
|
-
RUN mkdir -p /usr/local/share/ca-certificates
|
|
294
|
-
RUN --mount=type=secret,id=wrangler_ca \
|
|
295
|
-
if [ -f /run/secrets/wrangler_ca ] && [ -s /run/secrets/wrangler_ca ]; then \
|
|
296
|
-
cp /run/secrets/wrangler_ca /usr/local/share/ca-certificates/wrangler-dev-ca.crt && \
|
|
297
|
-
cat /run/secrets/wrangler_ca >> /etc/ssl/certs/ca-certificates.crt && \
|
|
298
|
-
apk add --no-cache ca-certificates && \
|
|
299
|
-
update-ca-certificates; \
|
|
300
|
-
else \
|
|
301
|
-
apk add --no-cache ca-certificates; \
|
|
302
|
-
fi
|
|
303
|
-
|
|
304
|
-
RUN apk add --no-cache bash file git curl libstdc++ libgcc s3fs-fuse fuse tini
|
|
305
|
-
|
|
306
|
-
RUN sed -i 's/#user_allow_other/user_allow_other/' /etc/fuse.conf
|
|
307
|
-
|
|
308
|
-
# The Alpine variant uses the same cloudflared release asset as the glibc
|
|
309
|
-
# variants. It is a static binary that runs on musl without gcompat.
|
|
310
|
-
COPY --from=cloudflared-binary /cloudflared /usr/local/bin/cloudflared
|
|
311
|
-
RUN cloudflared --version
|
|
312
|
-
|
|
313
|
-
COPY --from=builder /app/packages/sandbox-container/dist/sandbox-musl /container-server/sandbox
|
|
314
|
-
|
|
315
|
-
WORKDIR /container-server
|
|
316
|
-
|
|
317
|
-
COPY --from=builder /app/packages/sandbox-container/dist/index.js ./dist/
|
|
318
|
-
|
|
319
|
-
RUN mkdir -p /workspace
|
|
320
|
-
|
|
321
|
-
EXPOSE 3000
|
|
322
|
-
|
|
323
|
-
ENV PYTHON_POOL_MIN_SIZE=0
|
|
324
|
-
ENV JAVASCRIPT_POOL_MIN_SIZE=0
|
|
325
|
-
ENV TYPESCRIPT_POOL_MIN_SIZE=0
|
|
326
|
-
|
|
327
|
-
ENTRYPOINT ["/sbin/tini", "--", "/container-server/sandbox"]
|
package/dist/bridge/index.d.ts
DELETED
|
@@ -1,181 +0,0 @@
|
|
|
1
|
-
import { DurableObject } from "cloudflare:workers";
|
|
2
|
-
|
|
3
|
-
//#region src/bridge/types.d.ts
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Configuration options for the bridge() factory.
|
|
7
|
-
*/
|
|
8
|
-
interface BridgeConfig {
|
|
9
|
-
/**
|
|
10
|
-
* Override the default binding names used to look up Durable Objects.
|
|
11
|
-
*
|
|
12
|
-
* @default { sandbox: "Sandbox", warmPool: "WarmPool" }
|
|
13
|
-
*/
|
|
14
|
-
bindings?: {
|
|
15
|
-
/** Name of the Sandbox Durable Object binding. @default "Sandbox" */
|
|
16
|
-
sandbox?: string;
|
|
17
|
-
/** Name of the WarmPool Durable Object binding. @default "WarmPool" */
|
|
18
|
-
warmPool?: string;
|
|
19
|
-
};
|
|
20
|
-
/**
|
|
21
|
-
* URL prefix for all bridge API routes.
|
|
22
|
-
*
|
|
23
|
-
* @default "/v1"
|
|
24
|
-
*/
|
|
25
|
-
apiRoutePrefix?: string;
|
|
26
|
-
/**
|
|
27
|
-
* Path for the health-check endpoint.
|
|
28
|
-
*
|
|
29
|
-
* @default "/health"
|
|
30
|
-
*/
|
|
31
|
-
healthRoute?: string;
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* The user-provided worker handlers that bridge() wraps.
|
|
35
|
-
*
|
|
36
|
-
* The bridge wraps `fetch` and `scheduled` with its own logic;
|
|
37
|
-
* all other properties are passed through unchanged.
|
|
38
|
-
*/
|
|
39
|
-
interface WorkerHandlers {
|
|
40
|
-
fetch?(request: Request, env: any, ctx: ExecutionContext): Response | Promise<Response>;
|
|
41
|
-
scheduled?(controller: ScheduledController, env: any, ctx: ExecutionContext): void | Promise<void>;
|
|
42
|
-
[key: string]: unknown;
|
|
43
|
-
}
|
|
44
|
-
/**
|
|
45
|
-
* Minimum environment shape required by the bridge.
|
|
46
|
-
* The actual bindings are looked up dynamically by name.
|
|
47
|
-
*/
|
|
48
|
-
interface BridgeEnv {
|
|
49
|
-
SANDBOX_API_KEY?: string;
|
|
50
|
-
WARM_POOL_TARGET?: string;
|
|
51
|
-
WARM_POOL_REFRESH_INTERVAL?: string;
|
|
52
|
-
[key: string]: unknown;
|
|
53
|
-
}
|
|
54
|
-
//#endregion
|
|
55
|
-
//#region src/bridge/helpers.d.ts
|
|
56
|
-
/**
|
|
57
|
-
* Shell-quote a single argv token so it is safe to embed in a sh command
|
|
58
|
-
* string. Tokens that contain only safe characters are returned unchanged
|
|
59
|
-
* for readability. All others are wrapped in ANSI-C $'...' quoting which
|
|
60
|
-
* can represent newlines, tabs, and other control characters as escape
|
|
61
|
-
* sequences — unlike plain single quotes which pass content literally and
|
|
62
|
-
* break when the value contains a real newline.
|
|
63
|
-
*/
|
|
64
|
-
declare function shellQuote(arg: string): string;
|
|
65
|
-
/**
|
|
66
|
-
* POSIX-normalise a path (resolve `.` / `..` segments) and verify it lives
|
|
67
|
-
* under /workspace. Returns the resolved absolute path on success, or null
|
|
68
|
-
* if the path escapes the workspace.
|
|
69
|
-
*/
|
|
70
|
-
declare function resolveWorkspacePath(userPath: string): string | null;
|
|
71
|
-
//#endregion
|
|
72
|
-
//#region src/bridge/warm-pool.d.ts
|
|
73
|
-
interface WarmPoolConfig {
|
|
74
|
-
/** Target number of warm (unassigned) containers to maintain. @default 0 */
|
|
75
|
-
warmTarget?: number;
|
|
76
|
-
/** How often to check and replenish warm containers (ms). @default 10000 */
|
|
77
|
-
refreshInterval?: number;
|
|
78
|
-
}
|
|
79
|
-
interface PoolStats {
|
|
80
|
-
/** Number of warm (unassigned) containers ready for use */
|
|
81
|
-
warm: number;
|
|
82
|
-
/** Number of containers assigned to sandbox IDs */
|
|
83
|
-
assigned: number;
|
|
84
|
-
/** Total containers tracked by the pool */
|
|
85
|
-
total: number;
|
|
86
|
-
/** Current pool configuration */
|
|
87
|
-
config: Required<WarmPoolConfig>;
|
|
88
|
-
/** Inferred max_instances limit, or null if not yet known */
|
|
89
|
-
maxInstances: number | null;
|
|
90
|
-
}
|
|
91
|
-
/**
|
|
92
|
-
* The WarmPool expects an environment with a `Sandbox` Durable Object binding.
|
|
93
|
-
* This interface describes the minimum shape; the actual binding name is
|
|
94
|
-
* configurable via the bridge, but defaults to "Sandbox".
|
|
95
|
-
*/
|
|
96
|
-
interface WarmPoolEnv {
|
|
97
|
-
Sandbox: DurableObjectNamespace;
|
|
98
|
-
[key: string]: unknown;
|
|
99
|
-
}
|
|
100
|
-
declare class WarmPool extends DurableObject<WarmPoolEnv> {
|
|
101
|
-
private config;
|
|
102
|
-
/** Container UUIDs that are warm and available for assignment */
|
|
103
|
-
private warmContainers;
|
|
104
|
-
/** Maps caller-provided sandbox IDs to container UUIDs (1:1, no sharing) */
|
|
105
|
-
private assignments;
|
|
106
|
-
/** Containers currently starting — excluded from health checks */
|
|
107
|
-
private startingContainers;
|
|
108
|
-
/** Inferred max_instances limit learned from Cloudflare errors, or null */
|
|
109
|
-
private knownMaxInstances;
|
|
110
|
-
private capacityExhausted;
|
|
111
|
-
private initialized;
|
|
112
|
-
/**
|
|
113
|
-
* Get a container UUID for the given sandbox ID.
|
|
114
|
-
* - If this ID already has an assigned container that's still running, return it.
|
|
115
|
-
* - Otherwise assign a warm container (or start a new one).
|
|
116
|
-
*/
|
|
117
|
-
getContainer(sandboxId: string): Promise<string>;
|
|
118
|
-
/**
|
|
119
|
-
* Look up an existing container assignment without allocating.
|
|
120
|
-
* Returns the container UUID if the sandbox ID has an active assignment, null otherwise.
|
|
121
|
-
* Used by DELETE to avoid starting a container just to destroy it.
|
|
122
|
-
*/
|
|
123
|
-
lookupContainer(sandboxId: string): Promise<string | null>;
|
|
124
|
-
/**
|
|
125
|
-
* Report that a container has stopped — removes it from tracking.
|
|
126
|
-
*/
|
|
127
|
-
reportStopped(containerUUID: string): Promise<void>;
|
|
128
|
-
/**
|
|
129
|
-
* Get current pool statistics.
|
|
130
|
-
*/
|
|
131
|
-
getStats(): Promise<PoolStats>;
|
|
132
|
-
/**
|
|
133
|
-
* Update pool configuration. Idempotent — called on every request to keep
|
|
134
|
-
* config in sync with wrangler vars across deploys.
|
|
135
|
-
*/
|
|
136
|
-
configure(config: WarmPoolConfig): Promise<void>;
|
|
137
|
-
/**
|
|
138
|
-
* Shutdown all pre-warmed (unassigned) containers.
|
|
139
|
-
* Does not affect containers that are assigned to sandbox IDs.
|
|
140
|
-
*/
|
|
141
|
-
shutdownPrewarmed(): Promise<void>;
|
|
142
|
-
alarm(): Promise<void>;
|
|
143
|
-
private init;
|
|
144
|
-
private persist;
|
|
145
|
-
private scheduleRefresh;
|
|
146
|
-
private startContainer;
|
|
147
|
-
private isContainerRunning;
|
|
148
|
-
private checkContainerHealth;
|
|
149
|
-
/**
|
|
150
|
-
* Renew activity timeout on all warm containers to prevent them from sleeping.
|
|
151
|
-
*/
|
|
152
|
-
private keepWarmContainersAlive;
|
|
153
|
-
/**
|
|
154
|
-
* Scale the warm pool towards warmTarget, respecting inferred max_instances.
|
|
155
|
-
*/
|
|
156
|
-
private adjustPool;
|
|
157
|
-
private removeContainer;
|
|
158
|
-
private remainingCapacity;
|
|
159
|
-
private isMaxInstancesError;
|
|
160
|
-
private recordCapacityLimit;
|
|
161
|
-
private throwCapacityError;
|
|
162
|
-
private getSandboxStub;
|
|
163
|
-
}
|
|
164
|
-
//#endregion
|
|
165
|
-
//#region src/bridge/index.d.ts
|
|
166
|
-
/**
|
|
167
|
-
* Create a Worker export that wraps user handlers with bridge functionality.
|
|
168
|
-
*
|
|
169
|
-
* The bridge:
|
|
170
|
-
* 1. Checks that required Durable Object bindings exist (logs errors if missing).
|
|
171
|
-
* 2. Wraps `fetch()` to serve bridge API routes first, then falls through to the user handler.
|
|
172
|
-
* 3. Wraps `scheduled()` to prime the warm pool, then calls the user handler.
|
|
173
|
-
* 4. Passes through all other properties unchanged.
|
|
174
|
-
*
|
|
175
|
-
* @param worker - The user's worker handlers (fetch, scheduled, and any others).
|
|
176
|
-
* @param config - Optional configuration for binding names and route paths.
|
|
177
|
-
*/
|
|
178
|
-
declare function bridge(worker: WorkerHandlers, config?: BridgeConfig): ExportedHandler<BridgeEnv>;
|
|
179
|
-
//#endregion
|
|
180
|
-
export { type BridgeConfig, type BridgeEnv, type PoolStats, WarmPool, type WarmPoolConfig, type WorkerHandlers, bridge, resolveWorkspacePath, shellQuote };
|
|
181
|
-
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../../src/bridge/types.ts","../../src/bridge/helpers.ts","../../src/bridge/warm-pool.ts","../../src/bridge/index.ts"],"sourcesContent":[],"mappings":";;;;;;;AA6DgB,UAvCC,YAAA,CAuCD;EAEP;;;AAaT;;;;ICJgB,OAAA,CAAA,EAAU,MAAA;IAyBV;;;;AChFhB;AAOA;AAWC;AA6CD;EAA4C,cAAA,CAAA,EAAA,MAAA;EA2BH;;;;;EAiFf,WAAA,CAAA,EAAA,MAAA;;;;;;;;UFtIT,cAAA;EGgCD,KAAA,EAAA,OAAM,EH9BT,OG8BS,EAAA,GAAA,EAAA,GAAA,EAAA,GAAA,EH5Bb,gBG4Ba,CAAA,EH3BjB,QG2BiB,GH3BN,OG2BM,CH3BE,QG2BF,CAAA;EACZ,SAAA,EAAA,UAAA,EH1BM,mBG0BN,EAAA,GAAA,EAAA,GAAA,EAAA,GAAA,EHxBD,gBGwBC,CAAA,EAAA,IAAA,GHvBE,OGuBF,CAAA,IAAA,CAAA;EACC,CAAA,GAAA,EAAA,MAAA,CAAA,EAAA,OAAA;;;;;;UHZM,SAAA;;;;;;;;;;;AAAjB;;;;ACJA;AAyBgB,iBAzBA,UAAA,CAyBoB,GAAA,EAAA,MAAA,CAAA,EAAA,MAAA;;;;AChFpC;AAOA;AAmDU,iBDsBM,oBAAA,CCrBL,QAAsB,EAAA,MAAA,CAAA,EAAA,MAAA,GAAA,IAAA;;;AFbxB,UE9CQ,cAAA,CF8CR;EACG;EAAO,UAAA,CAAA,EAAA,MAAA;EAYF;;;UEpDA,SAAA;EDgDD;EAyBA,IAAA,EAAA,MAAA;;;;EChFC,KAAA,EAAA,MAAA;EAOA;EAmDP,MAAA,EA3CA,QA2CW,CA3CF,cA4CR,CAAA;EAIE;EAA+B,YAAA,EAAA,MAAA,GAAA,IAAA;;;;;;;UALlC,WAAA,CAiHiC;EAUd,OAAA,EA1HlB,sBA0HkB;EAyBZ,CAAA,GAAA,EAAA,MAAA,CAAA,EAAA,OAAA;;AA/I0B,cAA9B,QAAA,SAAiB,aAAa,CAAC,WAAD,CAAA,CAAA;;;;ECM3B;EACN,QAAA,WAAA;EACC;EACQ,QAAA,kBAAA;EAAhB;EAAe,QAAA,iBAAA;;;;;;;;mCDkBuB;;;;;;sCA6CG;;;;wCAYE;;;;cAS1B,QAAQ;;;;;oBAeF,iBAAiB;;;;;uBAUd;WAyBZ;;;;;;;;;;;;;;;;;;;;;;;;AAvMjB;AAWC;AA6CD;;;;;;;;;;AA+IiB,iBCzID,MAAA,CDyIC,MAAA,ECxIP,cDwIO,EAAA,MAAA,CAAA,ECvIN,YDuIM,CAAA,ECtId,eDsIc,CCtIE,SDsIF,CAAA"}
|