@cloudflare/sandbox 0.7.11 → 0.7.13
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/Dockerfile +14 -0
- package/dist/{contexts-C5xSPEYL.d.ts → contexts-CeQR115r.d.ts} +2 -1
- package/dist/contexts-CeQR115r.d.ts.map +1 -0
- package/dist/{errors-8W0q5Gll.js → errors-CaSfB5Bm.js} +3 -1
- package/dist/errors-CaSfB5Bm.js.map +1 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +197 -39
- package/dist/index.js.map +1 -1
- package/dist/openai/index.d.ts +1 -1
- package/dist/opencode/index.d.ts +2 -2
- package/dist/opencode/index.js +1 -1
- package/dist/{sandbox-BYNjxjyr.d.ts → sandbox-B2OybvGn.d.ts} +44 -1
- package/dist/{sandbox-BYNjxjyr.d.ts.map → sandbox-B2OybvGn.d.ts.map} +1 -1
- package/package.json +1 -1
- package/dist/contexts-C5xSPEYL.d.ts.map +0 -1
- package/dist/errors-8W0q5Gll.js.map +0 -1
package/Dockerfile
CHANGED
|
@@ -199,6 +199,12 @@ ENTRYPOINT ["/container-server/sandbox"]
|
|
|
199
199
|
# ============================================================================
|
|
200
200
|
FROM runtime-base AS opencode
|
|
201
201
|
|
|
202
|
+
RUN --mount=type=secret,id=wrangler_ca \
|
|
203
|
+
if [ -f /run/secrets/wrangler_ca ] && [ -s /run/secrets/wrangler_ca ]; then \
|
|
204
|
+
cp /run/secrets/wrangler_ca /usr/local/share/ca-certificates/wrangler-dev-ca.crt && \
|
|
205
|
+
update-ca-certificates; \
|
|
206
|
+
fi
|
|
207
|
+
|
|
202
208
|
# Install OpenCode CLI via npm (avoids GitHub API rate limits)
|
|
203
209
|
RUN npm i -g opencode-ai \
|
|
204
210
|
&& opencode --version
|
|
@@ -218,6 +224,14 @@ ENTRYPOINT ["/container-server/sandbox"]
|
|
|
218
224
|
# ============================================================================
|
|
219
225
|
FROM golang:1.24-bookworm AS go-builder
|
|
220
226
|
|
|
227
|
+
RUN mkdir -p /usr/local/share/ca-certificates
|
|
228
|
+
RUN --mount=type=secret,id=wrangler_ca \
|
|
229
|
+
if [ -f /run/secrets/wrangler_ca ] && [ -s /run/secrets/wrangler_ca ]; then \
|
|
230
|
+
cp /run/secrets/wrangler_ca /usr/local/share/ca-certificates/wrangler-dev-ca.crt && \
|
|
231
|
+
apt-get update && apt-get install -y --no-install-recommends ca-certificates && \
|
|
232
|
+
update-ca-certificates; \
|
|
233
|
+
fi
|
|
234
|
+
|
|
221
235
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
222
236
|
gcc libx11-dev libxtst-dev libxinerama-dev libpng-dev \
|
|
223
237
|
&& rm -rf /var/lib/apt/lists/*
|
|
@@ -26,6 +26,7 @@ declare const ErrorCode: {
|
|
|
26
26
|
readonly PROCESS_PERMISSION_DENIED: "PROCESS_PERMISSION_DENIED";
|
|
27
27
|
readonly PROCESS_ERROR: "PROCESS_ERROR";
|
|
28
28
|
readonly SESSION_ALREADY_EXISTS: "SESSION_ALREADY_EXISTS";
|
|
29
|
+
readonly SESSION_DESTROYED: "SESSION_DESTROYED";
|
|
29
30
|
readonly PORT_ALREADY_EXPOSED: "PORT_ALREADY_EXPOSED";
|
|
30
31
|
readonly PORT_IN_USE: "PORT_IN_USE";
|
|
31
32
|
readonly PORT_NOT_EXPOSED: "PORT_NOT_EXPOSED";
|
|
@@ -223,4 +224,4 @@ interface DesktopCoordinateErrorContext {
|
|
|
223
224
|
}
|
|
224
225
|
//#endregion
|
|
225
226
|
export { DesktopCoordinateErrorContext as a, OpencodeStartupContext as c, ErrorResponse as d, OperationType as f, BackupRestoreContext as i, ProcessExitedBeforeReadyContext as l, BackupExpiredContext as n, DesktopErrorContext as o, ErrorCode as p, BackupNotFoundContext as r, InvalidBackupConfigContext as s, BackupCreateContext as t, ProcessReadyTimeoutContext as u };
|
|
226
|
-
//# sourceMappingURL=contexts-
|
|
227
|
+
//# sourceMappingURL=contexts-CeQR115r.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contexts-CeQR115r.d.ts","names":["ErrorCode","ErrorCode","Operation","OperationType","ErrorResponse","TContext","Record","ServiceError","ServiceResult","T","OperationType","FileNotFoundContext","FileExistsContext","FileTooLargeContext","FileSystemContext","CommandNotFoundContext","CommandErrorContext","ProcessNotFoundContext","ProcessErrorContext","SessionAlreadyExistsContext","SessionDestroyedContext","ProcessReadyTimeoutContext","ProcessExitedBeforeReadyContext","PortAlreadyExposedContext","PortNotExposedContext","InvalidPortContext","PortErrorContext","GitRepositoryNotFoundContext","GitAuthFailedContext","GitBranchNotFoundContext","GitErrorContext","InterpreterNotReadyContext","ContextNotFoundContext","CodeExecutionContext","ValidationFailedContext","Array","BucketMountContext","MissingCredentialsContext","InvalidMountConfigContext","BackupCreateContext","BackupRestoreContext","BackupNotFoundContext","BackupExpiredContext","InvalidBackupConfigContext","OpencodeStartupContext","InternalErrorContext","DesktopErrorContext","DesktopCoordinateErrorContext"],"sources":["../../shared/dist/errors/codes.d.ts","../../shared/dist/errors/types.d.ts","../../shared/dist/errors/contexts.d.ts"],"sourcesContent":["/**\n * Centralized error code registry\n * Each code maps to a specific error type with consistent semantics\n */\nexport declare const ErrorCode: {\n readonly FILE_NOT_FOUND: \"FILE_NOT_FOUND\";\n readonly PERMISSION_DENIED: \"PERMISSION_DENIED\";\n readonly FILE_EXISTS: \"FILE_EXISTS\";\n readonly IS_DIRECTORY: \"IS_DIRECTORY\";\n readonly NOT_DIRECTORY: \"NOT_DIRECTORY\";\n readonly FILE_TOO_LARGE: \"FILE_TOO_LARGE\";\n readonly NO_SPACE: \"NO_SPACE\";\n readonly TOO_MANY_FILES: \"TOO_MANY_FILES\";\n readonly RESOURCE_BUSY: \"RESOURCE_BUSY\";\n readonly READ_ONLY: \"READ_ONLY\";\n readonly NAME_TOO_LONG: \"NAME_TOO_LONG\";\n readonly TOO_MANY_LINKS: \"TOO_MANY_LINKS\";\n readonly FILESYSTEM_ERROR: \"FILESYSTEM_ERROR\";\n readonly COMMAND_NOT_FOUND: \"COMMAND_NOT_FOUND\";\n readonly COMMAND_PERMISSION_DENIED: \"COMMAND_PERMISSION_DENIED\";\n readonly INVALID_COMMAND: \"INVALID_COMMAND\";\n readonly COMMAND_EXECUTION_ERROR: \"COMMAND_EXECUTION_ERROR\";\n readonly STREAM_START_ERROR: \"STREAM_START_ERROR\";\n readonly PROCESS_NOT_FOUND: \"PROCESS_NOT_FOUND\";\n readonly PROCESS_PERMISSION_DENIED: \"PROCESS_PERMISSION_DENIED\";\n readonly PROCESS_ERROR: \"PROCESS_ERROR\";\n readonly SESSION_ALREADY_EXISTS: \"SESSION_ALREADY_EXISTS\";\n readonly SESSION_DESTROYED: \"SESSION_DESTROYED\";\n readonly PORT_ALREADY_EXPOSED: \"PORT_ALREADY_EXPOSED\";\n readonly PORT_IN_USE: \"PORT_IN_USE\";\n readonly PORT_NOT_EXPOSED: \"PORT_NOT_EXPOSED\";\n readonly INVALID_PORT_NUMBER: \"INVALID_PORT_NUMBER\";\n readonly INVALID_PORT: \"INVALID_PORT\";\n readonly SERVICE_NOT_RESPONDING: \"SERVICE_NOT_RESPONDING\";\n readonly PORT_OPERATION_ERROR: \"PORT_OPERATION_ERROR\";\n readonly CUSTOM_DOMAIN_REQUIRED: \"CUSTOM_DOMAIN_REQUIRED\";\n readonly GIT_REPOSITORY_NOT_FOUND: \"GIT_REPOSITORY_NOT_FOUND\";\n readonly GIT_BRANCH_NOT_FOUND: \"GIT_BRANCH_NOT_FOUND\";\n readonly GIT_AUTH_FAILED: \"GIT_AUTH_FAILED\";\n readonly GIT_NETWORK_ERROR: \"GIT_NETWORK_ERROR\";\n readonly INVALID_GIT_URL: \"INVALID_GIT_URL\";\n readonly GIT_CLONE_FAILED: \"GIT_CLONE_FAILED\";\n readonly GIT_CHECKOUT_FAILED: \"GIT_CHECKOUT_FAILED\";\n readonly GIT_OPERATION_FAILED: \"GIT_OPERATION_FAILED\";\n readonly BUCKET_MOUNT_ERROR: \"BUCKET_MOUNT_ERROR\";\n readonly S3FS_MOUNT_ERROR: \"S3FS_MOUNT_ERROR\";\n readonly MISSING_CREDENTIALS: \"MISSING_CREDENTIALS\";\n readonly INVALID_MOUNT_CONFIG: \"INVALID_MOUNT_CONFIG\";\n readonly BACKUP_CREATE_FAILED: \"BACKUP_CREATE_FAILED\";\n readonly BACKUP_RESTORE_FAILED: \"BACKUP_RESTORE_FAILED\";\n readonly BACKUP_NOT_FOUND: \"BACKUP_NOT_FOUND\";\n readonly BACKUP_EXPIRED: \"BACKUP_EXPIRED\";\n readonly INVALID_BACKUP_CONFIG: \"INVALID_BACKUP_CONFIG\";\n readonly INTERPRETER_NOT_READY: \"INTERPRETER_NOT_READY\";\n readonly CONTEXT_NOT_FOUND: \"CONTEXT_NOT_FOUND\";\n readonly CODE_EXECUTION_ERROR: \"CODE_EXECUTION_ERROR\";\n readonly PYTHON_NOT_AVAILABLE: \"PYTHON_NOT_AVAILABLE\";\n readonly JAVASCRIPT_NOT_AVAILABLE: \"JAVASCRIPT_NOT_AVAILABLE\";\n readonly OPENCODE_STARTUP_FAILED: \"OPENCODE_STARTUP_FAILED\";\n readonly PROCESS_READY_TIMEOUT: \"PROCESS_READY_TIMEOUT\";\n readonly PROCESS_EXITED_BEFORE_READY: \"PROCESS_EXITED_BEFORE_READY\";\n readonly DESKTOP_NOT_STARTED: \"DESKTOP_NOT_STARTED\";\n readonly DESKTOP_START_FAILED: \"DESKTOP_START_FAILED\";\n readonly DESKTOP_UNAVAILABLE: \"DESKTOP_UNAVAILABLE\";\n readonly DESKTOP_PROCESS_CRASHED: \"DESKTOP_PROCESS_CRASHED\";\n readonly DESKTOP_INVALID_OPTIONS: \"DESKTOP_INVALID_OPTIONS\";\n readonly DESKTOP_INVALID_COORDINATES: \"DESKTOP_INVALID_COORDINATES\";\n readonly WATCH_NOT_FOUND: \"WATCH_NOT_FOUND\";\n readonly WATCH_START_ERROR: \"WATCH_START_ERROR\";\n readonly WATCH_STOP_ERROR: \"WATCH_STOP_ERROR\";\n readonly VALIDATION_FAILED: \"VALIDATION_FAILED\";\n readonly INVALID_JSON_RESPONSE: \"INVALID_JSON_RESPONSE\";\n readonly UNKNOWN_ERROR: \"UNKNOWN_ERROR\";\n readonly INTERNAL_ERROR: \"INTERNAL_ERROR\";\n};\nexport type ErrorCode = (typeof ErrorCode)[keyof typeof ErrorCode];\n//# sourceMappingURL=codes.d.ts.map","import type { ErrorCode } from './codes';\n/**\n * Standard operation types\n */\nexport declare const Operation: {\n readonly FILE_READ: \"file.read\";\n readonly FILE_WRITE: \"file.write\";\n readonly FILE_DELETE: \"file.delete\";\n readonly FILE_MOVE: \"file.move\";\n readonly FILE_RENAME: \"file.rename\";\n readonly FILE_STAT: \"file.stat\";\n readonly DIRECTORY_CREATE: \"directory.create\";\n readonly DIRECTORY_LIST: \"directory.list\";\n readonly COMMAND_EXECUTE: \"command.execute\";\n readonly COMMAND_STREAM: \"command.stream\";\n readonly PROCESS_START: \"process.start\";\n readonly PROCESS_KILL: \"process.kill\";\n readonly PROCESS_LIST: \"process.list\";\n readonly PROCESS_GET: \"process.get\";\n readonly PROCESS_LOGS: \"process.logs\";\n readonly PORT_EXPOSE: \"port.expose\";\n readonly PORT_UNEXPOSE: \"port.unexpose\";\n readonly PORT_LIST: \"port.list\";\n readonly PORT_PROXY: \"port.proxy\";\n readonly GIT_CLONE: \"git.clone\";\n readonly GIT_CHECKOUT: \"git.checkout\";\n readonly GIT_OPERATION: \"git.operation\";\n readonly BACKUP_CREATE: \"backup.create\";\n readonly BACKUP_RESTORE: \"backup.restore\";\n readonly BACKUP_UNMOUNT: \"backup.unmount\";\n readonly DESKTOP_START: \"desktop.start\";\n readonly DESKTOP_STOP: \"desktop.stop\";\n readonly DESKTOP_SCREENSHOT: \"desktop.screenshot\";\n readonly DESKTOP_MOUSE: \"desktop.mouse\";\n readonly DESKTOP_KEYBOARD: \"desktop.keyboard\";\n readonly DESKTOP_STATUS: \"desktop.status\";\n readonly CODE_EXECUTE: \"code.execute\";\n readonly CODE_CONTEXT_CREATE: \"code.context.create\";\n readonly CODE_CONTEXT_DELETE: \"code.context.delete\";\n};\nexport type OperationType = (typeof Operation)[keyof typeof Operation];\n/**\n * Standard error response format with generic context type\n * TContext allows type-safe access to error-specific context\n */\nexport interface ErrorResponse<TContext = Record<string, unknown>> {\n /**\n * Error type code (machine-readable)\n */\n code: ErrorCode;\n /**\n * Human-readable error message\n */\n message: string;\n /**\n * Operation that was attempted (useful for debugging and logging)\n */\n operation?: OperationType;\n /**\n * Structured error context with relevant details\n * Type varies based on error code\n */\n context: TContext;\n /**\n * HTTP status code (for client SDK)\n */\n httpStatus: number;\n /**\n * Timestamp when error occurred\n */\n timestamp: string;\n /**\n * Actionable suggestion for fixing the error\n */\n suggestion?: string;\n /**\n * Link to documentation\n */\n documentation?: string;\n}\n/**\n * Container ServiceError (lightweight, enriched by handlers)\n */\nexport interface ServiceError {\n message: string;\n code: ErrorCode;\n details?: Record<string, unknown>;\n}\n/**\n * ServiceResult type for container services\n */\nexport type ServiceResult<T> = {\n success: true;\n data: T;\n} | {\n success: false;\n error: ServiceError;\n};\n//# sourceMappingURL=types.d.ts.map","import type { OperationType } from './types';\n/**\n * File system error contexts\n */\nexport interface FileNotFoundContext {\n path: string;\n operation: OperationType;\n}\nexport interface FileExistsContext {\n path: string;\n operation: OperationType;\n}\nexport interface FileTooLargeContext {\n path: string;\n operation: OperationType;\n maxSize: number;\n actualSize: number;\n}\nexport interface FileSystemContext {\n path: string;\n operation: OperationType;\n stderr?: string;\n exitCode?: number;\n}\n/**\n * Command error contexts\n */\nexport interface CommandNotFoundContext {\n command: string;\n}\nexport interface CommandErrorContext {\n command: string;\n exitCode?: number;\n stdout?: string;\n stderr?: string;\n}\n/**\n * Process error contexts\n */\nexport interface ProcessNotFoundContext {\n processId: string;\n}\nexport interface ProcessErrorContext {\n processId: string;\n pid?: number;\n exitCode?: number;\n stderr?: string;\n}\nexport interface SessionAlreadyExistsContext {\n sessionId: string;\n}\nexport interface SessionDestroyedContext {\n sessionId: string;\n}\n/**\n * Process readiness error contexts\n */\nexport interface ProcessReadyTimeoutContext {\n processId: string;\n command: string;\n condition: string;\n timeout: number;\n}\nexport interface ProcessExitedBeforeReadyContext {\n processId: string;\n command: string;\n condition: string;\n exitCode: number;\n}\n/**\n * Port error contexts\n */\nexport interface PortAlreadyExposedContext {\n port: number;\n portName?: string;\n}\nexport interface PortNotExposedContext {\n port: number;\n}\nexport interface InvalidPortContext {\n port: number;\n reason: string;\n}\nexport interface PortErrorContext {\n port: number;\n portName?: string;\n stderr?: string;\n}\n/**\n * Git error contexts\n */\nexport interface GitRepositoryNotFoundContext {\n repository: string;\n}\nexport interface GitAuthFailedContext {\n repository: string;\n}\nexport interface GitBranchNotFoundContext {\n branch: string;\n repository?: string;\n}\nexport interface GitErrorContext {\n repository?: string;\n branch?: string;\n targetDir?: string;\n stderr?: string;\n exitCode?: number;\n}\n/**\n * Code interpreter error contexts\n */\nexport interface InterpreterNotReadyContext {\n retryAfter?: number;\n progress?: number;\n}\nexport interface ContextNotFoundContext {\n contextId: string;\n}\nexport interface CodeExecutionContext {\n contextId?: string;\n ename?: string;\n evalue?: string;\n traceback?: string[];\n}\n/**\n * Validation error contexts\n */\nexport interface ValidationFailedContext {\n validationErrors: Array<{\n field: string;\n message: string;\n code?: string;\n }>;\n}\n/**\n * Bucket mounting error contexts\n */\nexport interface BucketMountContext {\n bucket: string;\n mountPath: string;\n endpoint: string;\n stderr?: string;\n exitCode?: number;\n}\nexport interface MissingCredentialsContext {\n bucket: string;\n endpoint: string;\n}\nexport interface InvalidMountConfigContext {\n bucket?: string;\n mountPath?: string;\n endpoint?: string;\n reason?: string;\n}\n/**\n * Backup error contexts\n */\nexport interface BackupCreateContext {\n dir: string;\n backupId?: string;\n stderr?: string;\n exitCode?: number;\n}\nexport interface BackupRestoreContext {\n dir: string;\n backupId: string;\n stderr?: string;\n exitCode?: number;\n}\nexport interface BackupNotFoundContext {\n backupId: string;\n}\nexport interface BackupExpiredContext {\n backupId: string;\n expiredAt?: string;\n}\nexport interface InvalidBackupConfigContext {\n reason: string;\n}\n/**\n * OpenCode error contexts\n */\nexport interface OpencodeStartupContext {\n port: number;\n stderr?: string;\n command?: string;\n}\n/**\n * Generic error contexts\n */\nexport interface InternalErrorContext {\n originalError?: string;\n stack?: string;\n [key: string]: unknown;\n}\n/**\n * Desktop error contexts\n */\nexport interface DesktopErrorContext {\n process?: string;\n stderr?: string;\n crashedProcess?: string;\n reason?: string;\n}\nexport interface DesktopCoordinateErrorContext {\n x: number;\n y: number;\n displayWidth: number;\n displayHeight: number;\n}\n//# sourceMappingURL=contexts.d.ts.map"],"mappings":";;AAIA;AAuEA;;cAvEqBA;;ECAAE,SAAAA,iBAmCpB,EAAA,mBAAA;EACWC,SAAAA,WAAa,EAAA,aAAWD;EAKnBE,SAAAA,YAAa,EAAAC,cAAA;EAAYC,SAAAA,aAAAA,EAAAA,eAAAA;EAIhCL,SAAAA,cAAAA,EAAAA,gBAAAA;EAQME,SAAAA,QAAAA,EAAAA,UAAAA;EAKHE,SAAAA,cAAAA,EAAAA,gBAAAA;EAAQ,SAAA,aAAA,EAAA,eAAA;;;;ECLJgB,SAAAA,gBAAAA,EAAAA,kBAA0B;EAM1BC,SAAAA,iBAAAA,EAAAA,mBAA+B;EA8F/BiB,SAAAA,yBAAmB,EAAA,2BAAA;EAMnBC,SAAAA,eAAoB,EAAA,iBAAA;EAMpBC,SAAAA,uBAAqB,EAAA,yBAAA;EAGrBC,SAAAA,kBAAoB,EAAA,oBAAA;EAIpBC,SAAAA,iBAAAA,EAAAA,mBAA0B;EAM1BC,SAAAA,yBAAsB,EAAA,2BAAA;EAgBtBE,SAAAA,aAAmB,EAAA,eAAA;EAMnBC,SAAAA,sBAAAA,EAA6B,wBAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KFjIlC/C,SAAAA,WAAoBA,wBAAwBA;;;AAvExD;AAuEA;;cCvEqBE;;EAAAA,SAAAA,UAmCpB,EAAA,YAAA;EACWC,SAAAA,WAAa,EAAA,aAAWD;EAKnBE,SAAAA,SAAa,EAAA,WAAAC;EAAYC,SAAAA,WAAAA,EAAAA,aAAAA;EAIhCL,SAAAA,SAAAA,EAAAA,WAAAA;EAQME,SAAAA,gBAAAA,EAAAA,kBAAAA;EAKHE,SAAAA,cAAAA,EAAAA,gBAAAA;EAAQ,SAAA,eAAA,EAAA,iBAAA;;;;ECLJgB,SAAAA,YAAAA,EAAAA,cAA0B;EAM1BC,SAAAA,WAAAA,EAAAA,aAA+B;EA8F/BiB,SAAAA,YAAAA,EAAmB,cAAA;EAMnBC,SAAAA,WAAAA,EAAAA,aAAoB;EAMpBC,SAAAA,aAAAA,EAAqB,eAAA;EAGrBC,SAAAA,SAAAA,EAAAA,WAAoB;EAIpBC,SAAAA,UAAAA,EAAAA,YAA0B;EAM1BC,SAAAA,SAAAA,EAAAA,WAAsB;EAgBtBE,SAAAA,YAAAA,EAAmB,cAAA;EAMnBC,SAAAA,aAAAA,EAAAA,eAA6B;;;;;;;;;;;;;;KDpKlC5C,aAAAA,WAAwBD,wBAAwBA;;;;;UAK3CE,yBAAyBE;;;;QAIhCL;;;;;;;;cAQME;;;;;WAKHE;;;;;;;;;;;;;;;;;;;;;;;;UCLIgB,0BAAAA;;;;;;UAMAC,+BAAAA;;;;;;;;;UA8FAiB,mBAAAA;;;;;;UAMAC,oBAAAA;;;;;;UAMAC,qBAAAA;;;UAGAC,oBAAAA;;;;UAIAC,0BAAAA;;;;;;UAMAC,sBAAAA;;;;;;;;UAgBAE,mBAAAA;;;;;;UAMAC,6BAAAA"}
|
|
@@ -26,6 +26,7 @@ const ErrorCode = {
|
|
|
26
26
|
PROCESS_PERMISSION_DENIED: "PROCESS_PERMISSION_DENIED",
|
|
27
27
|
PROCESS_ERROR: "PROCESS_ERROR",
|
|
28
28
|
SESSION_ALREADY_EXISTS: "SESSION_ALREADY_EXISTS",
|
|
29
|
+
SESSION_DESTROYED: "SESSION_DESTROYED",
|
|
29
30
|
PORT_ALREADY_EXPOSED: "PORT_ALREADY_EXPOSED",
|
|
30
31
|
PORT_IN_USE: "PORT_IN_USE",
|
|
31
32
|
PORT_NOT_EXPOSED: "PORT_NOT_EXPOSED",
|
|
@@ -111,6 +112,7 @@ const ERROR_STATUS_MAP = {
|
|
|
111
112
|
[ErrorCode.PORT_IN_USE]: 409,
|
|
112
113
|
[ErrorCode.RESOURCE_BUSY]: 409,
|
|
113
114
|
[ErrorCode.SESSION_ALREADY_EXISTS]: 409,
|
|
115
|
+
[ErrorCode.SESSION_DESTROYED]: 410,
|
|
114
116
|
[ErrorCode.FILE_TOO_LARGE]: 413,
|
|
115
117
|
[ErrorCode.SERVICE_NOT_RESPONDING]: 502,
|
|
116
118
|
[ErrorCode.GIT_NETWORK_ERROR]: 502,
|
|
@@ -153,4 +155,4 @@ const ERROR_STATUS_MAP = {
|
|
|
153
155
|
|
|
154
156
|
//#endregion
|
|
155
157
|
export { ErrorCode as t };
|
|
156
|
-
//# sourceMappingURL=errors-
|
|
158
|
+
//# sourceMappingURL=errors-CaSfB5Bm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors-CaSfB5Bm.js","names":[],"sources":["../../shared/dist/errors/codes.js","../../shared/dist/errors/status-map.js"],"sourcesContent":["/**\n * Centralized error code registry\n * Each code maps to a specific error type with consistent semantics\n */\nexport const ErrorCode = {\n // File System Errors (404)\n FILE_NOT_FOUND: 'FILE_NOT_FOUND',\n // Permission Errors (403)\n PERMISSION_DENIED: 'PERMISSION_DENIED',\n // File System Errors (409)\n FILE_EXISTS: 'FILE_EXISTS',\n // File System Errors (400)\n IS_DIRECTORY: 'IS_DIRECTORY',\n NOT_DIRECTORY: 'NOT_DIRECTORY',\n // File Too Large Errors (413)\n FILE_TOO_LARGE: 'FILE_TOO_LARGE',\n // File System Errors (500)\n NO_SPACE: 'NO_SPACE',\n TOO_MANY_FILES: 'TOO_MANY_FILES',\n RESOURCE_BUSY: 'RESOURCE_BUSY',\n READ_ONLY: 'READ_ONLY',\n NAME_TOO_LONG: 'NAME_TOO_LONG',\n TOO_MANY_LINKS: 'TOO_MANY_LINKS',\n FILESYSTEM_ERROR: 'FILESYSTEM_ERROR',\n // Command Errors (404)\n COMMAND_NOT_FOUND: 'COMMAND_NOT_FOUND',\n // Command Errors (403/400)\n COMMAND_PERMISSION_DENIED: 'COMMAND_PERMISSION_DENIED',\n INVALID_COMMAND: 'INVALID_COMMAND',\n // Command Errors (500)\n COMMAND_EXECUTION_ERROR: 'COMMAND_EXECUTION_ERROR',\n STREAM_START_ERROR: 'STREAM_START_ERROR',\n // Process Errors (404)\n PROCESS_NOT_FOUND: 'PROCESS_NOT_FOUND',\n // Process Errors (403/500)\n PROCESS_PERMISSION_DENIED: 'PROCESS_PERMISSION_DENIED',\n PROCESS_ERROR: 'PROCESS_ERROR',\n // Session Errors (409)\n SESSION_ALREADY_EXISTS: 'SESSION_ALREADY_EXISTS',\n // Session Errors (410)\n SESSION_DESTROYED: 'SESSION_DESTROYED',\n // Port Errors (409)\n PORT_ALREADY_EXPOSED: 'PORT_ALREADY_EXPOSED',\n PORT_IN_USE: 'PORT_IN_USE',\n // Port Errors (404)\n PORT_NOT_EXPOSED: 'PORT_NOT_EXPOSED',\n // Port Errors (400)\n INVALID_PORT_NUMBER: 'INVALID_PORT_NUMBER',\n INVALID_PORT: 'INVALID_PORT',\n // Port Errors (502/500)\n SERVICE_NOT_RESPONDING: 'SERVICE_NOT_RESPONDING',\n PORT_OPERATION_ERROR: 'PORT_OPERATION_ERROR',\n // Port Errors (400)\n CUSTOM_DOMAIN_REQUIRED: 'CUSTOM_DOMAIN_REQUIRED',\n // Git Errors (404)\n GIT_REPOSITORY_NOT_FOUND: 'GIT_REPOSITORY_NOT_FOUND',\n GIT_BRANCH_NOT_FOUND: 'GIT_BRANCH_NOT_FOUND',\n // Git Errors (401)\n GIT_AUTH_FAILED: 'GIT_AUTH_FAILED',\n // Git Errors (502)\n GIT_NETWORK_ERROR: 'GIT_NETWORK_ERROR',\n // Git Errors (400)\n INVALID_GIT_URL: 'INVALID_GIT_URL',\n // Git Errors (500)\n GIT_CLONE_FAILED: 'GIT_CLONE_FAILED',\n GIT_CHECKOUT_FAILED: 'GIT_CHECKOUT_FAILED',\n GIT_OPERATION_FAILED: 'GIT_OPERATION_FAILED',\n // Bucket mounting errors\n BUCKET_MOUNT_ERROR: 'BUCKET_MOUNT_ERROR',\n S3FS_MOUNT_ERROR: 'S3FS_MOUNT_ERROR',\n MISSING_CREDENTIALS: 'MISSING_CREDENTIALS',\n INVALID_MOUNT_CONFIG: 'INVALID_MOUNT_CONFIG',\n // Backup Errors (500)\n BACKUP_CREATE_FAILED: 'BACKUP_CREATE_FAILED',\n BACKUP_RESTORE_FAILED: 'BACKUP_RESTORE_FAILED',\n // Backup Errors (404)\n BACKUP_NOT_FOUND: 'BACKUP_NOT_FOUND',\n // Backup Errors (400)\n BACKUP_EXPIRED: 'BACKUP_EXPIRED',\n INVALID_BACKUP_CONFIG: 'INVALID_BACKUP_CONFIG',\n // Code Interpreter Errors (503)\n INTERPRETER_NOT_READY: 'INTERPRETER_NOT_READY',\n // Code Interpreter Errors (404)\n CONTEXT_NOT_FOUND: 'CONTEXT_NOT_FOUND',\n // Code Interpreter Errors (500)\n CODE_EXECUTION_ERROR: 'CODE_EXECUTION_ERROR',\n // Code Interpreter Errors (501) - Feature not available in image variant\n PYTHON_NOT_AVAILABLE: 'PYTHON_NOT_AVAILABLE',\n JAVASCRIPT_NOT_AVAILABLE: 'JAVASCRIPT_NOT_AVAILABLE',\n // OpenCode Errors (503)\n OPENCODE_STARTUP_FAILED: 'OPENCODE_STARTUP_FAILED',\n // Process Readiness Errors (408/500)\n PROCESS_READY_TIMEOUT: 'PROCESS_READY_TIMEOUT',\n PROCESS_EXITED_BEFORE_READY: 'PROCESS_EXITED_BEFORE_READY',\n // Desktop Errors (409)\n DESKTOP_NOT_STARTED: 'DESKTOP_NOT_STARTED',\n // Desktop Errors (500)\n DESKTOP_START_FAILED: 'DESKTOP_START_FAILED',\n // Desktop Errors (503)\n DESKTOP_UNAVAILABLE: 'DESKTOP_UNAVAILABLE',\n // Desktop Errors (500)\n DESKTOP_PROCESS_CRASHED: 'DESKTOP_PROCESS_CRASHED',\n // Desktop Errors (400)\n DESKTOP_INVALID_OPTIONS: 'DESKTOP_INVALID_OPTIONS',\n DESKTOP_INVALID_COORDINATES: 'DESKTOP_INVALID_COORDINATES',\n // File Watch Errors (404)\n WATCH_NOT_FOUND: 'WATCH_NOT_FOUND',\n // File Watch Errors (500)\n WATCH_START_ERROR: 'WATCH_START_ERROR',\n WATCH_STOP_ERROR: 'WATCH_STOP_ERROR',\n // Validation Errors (400)\n VALIDATION_FAILED: 'VALIDATION_FAILED',\n // Generic Errors (400/500)\n INVALID_JSON_RESPONSE: 'INVALID_JSON_RESPONSE',\n UNKNOWN_ERROR: 'UNKNOWN_ERROR',\n INTERNAL_ERROR: 'INTERNAL_ERROR'\n};\n","import { ErrorCode } from './codes';\n/**\n * Maps error codes to HTTP status codes\n * Centralized mapping ensures consistency across SDK\n */\nexport const ERROR_STATUS_MAP = {\n // 404 Not Found\n [ErrorCode.FILE_NOT_FOUND]: 404,\n [ErrorCode.COMMAND_NOT_FOUND]: 404,\n [ErrorCode.PROCESS_NOT_FOUND]: 404,\n [ErrorCode.PORT_NOT_EXPOSED]: 404,\n [ErrorCode.GIT_REPOSITORY_NOT_FOUND]: 404,\n [ErrorCode.GIT_BRANCH_NOT_FOUND]: 404,\n [ErrorCode.CONTEXT_NOT_FOUND]: 404,\n [ErrorCode.WATCH_NOT_FOUND]: 404,\n // 400 Bad Request\n [ErrorCode.IS_DIRECTORY]: 400,\n [ErrorCode.NOT_DIRECTORY]: 400,\n [ErrorCode.INVALID_COMMAND]: 400,\n [ErrorCode.INVALID_PORT_NUMBER]: 400,\n [ErrorCode.INVALID_PORT]: 400,\n [ErrorCode.INVALID_GIT_URL]: 400,\n [ErrorCode.CUSTOM_DOMAIN_REQUIRED]: 400,\n [ErrorCode.INVALID_JSON_RESPONSE]: 400,\n [ErrorCode.NAME_TOO_LONG]: 400,\n [ErrorCode.VALIDATION_FAILED]: 400,\n [ErrorCode.MISSING_CREDENTIALS]: 400,\n [ErrorCode.INVALID_MOUNT_CONFIG]: 400,\n // 401 Unauthorized\n [ErrorCode.GIT_AUTH_FAILED]: 401,\n // 403 Forbidden\n [ErrorCode.PERMISSION_DENIED]: 403,\n [ErrorCode.COMMAND_PERMISSION_DENIED]: 403,\n [ErrorCode.PROCESS_PERMISSION_DENIED]: 403,\n [ErrorCode.READ_ONLY]: 403,\n // 409 Conflict\n [ErrorCode.FILE_EXISTS]: 409,\n [ErrorCode.PORT_ALREADY_EXPOSED]: 409,\n [ErrorCode.PORT_IN_USE]: 409,\n [ErrorCode.RESOURCE_BUSY]: 409,\n [ErrorCode.SESSION_ALREADY_EXISTS]: 409,\n // 410 Gone\n [ErrorCode.SESSION_DESTROYED]: 410,\n // 413 Content Too Large\n [ErrorCode.FILE_TOO_LARGE]: 413,\n // 502 Bad Gateway\n [ErrorCode.SERVICE_NOT_RESPONDING]: 502,\n [ErrorCode.GIT_NETWORK_ERROR]: 502,\n // Backup errors\n [ErrorCode.BACKUP_NOT_FOUND]: 404,\n [ErrorCode.BACKUP_EXPIRED]: 400,\n [ErrorCode.INVALID_BACKUP_CONFIG]: 400,\n [ErrorCode.BACKUP_CREATE_FAILED]: 500,\n [ErrorCode.BACKUP_RESTORE_FAILED]: 500,\n // 501 Not Implemented (feature not available in image variant)\n [ErrorCode.PYTHON_NOT_AVAILABLE]: 501,\n [ErrorCode.JAVASCRIPT_NOT_AVAILABLE]: 501,\n // Desktop errors\n [ErrorCode.DESKTOP_NOT_STARTED]: 409,\n [ErrorCode.DESKTOP_START_FAILED]: 500,\n [ErrorCode.DESKTOP_UNAVAILABLE]: 503,\n [ErrorCode.DESKTOP_PROCESS_CRASHED]: 500,\n [ErrorCode.DESKTOP_INVALID_OPTIONS]: 400,\n [ErrorCode.DESKTOP_INVALID_COORDINATES]: 400,\n // 503 Service Unavailable\n [ErrorCode.INTERPRETER_NOT_READY]: 503,\n [ErrorCode.OPENCODE_STARTUP_FAILED]: 503,\n // 408 Request Timeout\n [ErrorCode.PROCESS_READY_TIMEOUT]: 408,\n // 500 Internal Server Error\n [ErrorCode.PROCESS_EXITED_BEFORE_READY]: 500,\n [ErrorCode.NO_SPACE]: 500,\n [ErrorCode.TOO_MANY_FILES]: 500,\n [ErrorCode.TOO_MANY_LINKS]: 500,\n [ErrorCode.FILESYSTEM_ERROR]: 500,\n [ErrorCode.COMMAND_EXECUTION_ERROR]: 500,\n [ErrorCode.STREAM_START_ERROR]: 500,\n [ErrorCode.PROCESS_ERROR]: 500,\n [ErrorCode.PORT_OPERATION_ERROR]: 500,\n [ErrorCode.GIT_CLONE_FAILED]: 500,\n [ErrorCode.GIT_CHECKOUT_FAILED]: 500,\n [ErrorCode.GIT_OPERATION_FAILED]: 500,\n [ErrorCode.CODE_EXECUTION_ERROR]: 500,\n [ErrorCode.BUCKET_MOUNT_ERROR]: 500,\n [ErrorCode.S3FS_MOUNT_ERROR]: 500,\n [ErrorCode.WATCH_START_ERROR]: 500,\n [ErrorCode.WATCH_STOP_ERROR]: 500,\n [ErrorCode.UNKNOWN_ERROR]: 500,\n [ErrorCode.INTERNAL_ERROR]: 500\n};\n/**\n * Get HTTP status code for an error code\n * Falls back to 500 for unknown errors\n */\nexport function getHttpStatus(code) {\n return ERROR_STATUS_MAP[code] || 500;\n}\n"],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { $ as DirectoryBackup, A as DesktopStopResponse, At as WaitForPortOptions, B as ExecuteResponse, Bt as CreateContextOptions, C as ClickOptions, Ct as ProcessStartResult, D as DesktopStartOptions, Dt as SessionOptions, E as DesktopClient, Et as SandboxOptions, F as ScreenshotRegion, Ft as ExecuteRequest, G as HttpClientOptions, H as BaseApiResponse, Ht as ExecutionResult, I as ScreenshotResponse, It as ExposePortRequest, J as SessionRequest, K as RequestConfig, L as ScrollDirection, Lt as StartProcessRequest, M as ScreenSizeResponse, Mt as isExecResult, N as ScreenshotBytesResponse, Nt as isProcess, O as DesktopStartResponse, Ot as StreamOptions, P as ScreenshotOptions, Pt as isProcessStatus, Q as BucketProvider, R as TypeOptions, Rt as PtyOptions, S as WriteFileRequest, St as ProcessOptions, T as Desktop, Tt as RestoreBackupResult, U as ContainerStub, Ut as RunCodeOptions, V as BackupClient, Vt as Execution, W as ErrorResponse, X as BaseExecOptions, Y as BackupOptions, Z as BucketCredentials, _ as GitClient, _t as ProcessCleanupResult, a as CreateSessionRequest, at as FileMetadata, b as MkdirRequest, bt as ProcessListResult, c as DeleteSessionResponse, ct as GitCheckoutResult, d as ProcessClient, dt as LogEvent, et as ExecEvent, f as PortClient, ft as MountBucketOptions, g as GitCheckoutRequest, gt as Process, h as InterpreterClient, ht as PortListResult, i as CommandsResponse, it as FileChunk, j as KeyInput, jt as WatchOptions, k as DesktopStatusResponse, kt as WaitForLogResult, l as PingResponse, lt as ISandbox, m as ExecutionCallbacks, mt as PortExposeResult, n as getSandbox, nt as ExecResult, o as CreateSessionResponse, ot as FileStreamEvent, p as UnexposePortRequest, pt as PortCloseResult, q as ResponseHandler, r as SandboxClient, rt as ExecutionSession, s as DeleteSessionRequest, st as FileWatchSSEEvent, t as Sandbox, tt as ExecOptions, u as UtilityClient, ut as ListFilesOptions, v as FileClient, vt as ProcessInfoResult, w as CursorPositionResponse, wt as ProcessStatus, x as ReadFileRequest, xt as ProcessLogsResult, y as FileOperationRequest, yt as ProcessKillResult, z as CommandClient, zt as CodeContext } from "./sandbox-
|
|
2
|
-
import { a as DesktopCoordinateErrorContext, d as ErrorResponse$1, f as OperationType, i as BackupRestoreContext, l as ProcessExitedBeforeReadyContext, n as BackupExpiredContext, o as DesktopErrorContext, p as ErrorCode, r as BackupNotFoundContext, s as InvalidBackupConfigContext, t as BackupCreateContext, u as ProcessReadyTimeoutContext } from "./contexts-
|
|
1
|
+
import { $ as DirectoryBackup, A as DesktopStopResponse, At as WaitForPortOptions, B as ExecuteResponse, Bt as CreateContextOptions, C as ClickOptions, Ct as ProcessStartResult, D as DesktopStartOptions, Dt as SessionOptions, E as DesktopClient, Et as SandboxOptions, F as ScreenshotRegion, Ft as ExecuteRequest, G as HttpClientOptions, H as BaseApiResponse, Ht as ExecutionResult, I as ScreenshotResponse, It as ExposePortRequest, J as SessionRequest, K as RequestConfig, L as ScrollDirection, Lt as StartProcessRequest, M as ScreenSizeResponse, Mt as isExecResult, N as ScreenshotBytesResponse, Nt as isProcess, O as DesktopStartResponse, Ot as StreamOptions, P as ScreenshotOptions, Pt as isProcessStatus, Q as BucketProvider, R as TypeOptions, Rt as PtyOptions, S as WriteFileRequest, St as ProcessOptions, T as Desktop, Tt as RestoreBackupResult, U as ContainerStub, Ut as RunCodeOptions, V as BackupClient, Vt as Execution, W as ErrorResponse, X as BaseExecOptions, Y as BackupOptions, Z as BucketCredentials, _ as GitClient, _t as ProcessCleanupResult, a as CreateSessionRequest, at as FileMetadata, b as MkdirRequest, bt as ProcessListResult, c as DeleteSessionResponse, ct as GitCheckoutResult, d as ProcessClient, dt as LogEvent, et as ExecEvent, f as PortClient, ft as MountBucketOptions, g as GitCheckoutRequest, gt as Process, h as InterpreterClient, ht as PortListResult, i as CommandsResponse, it as FileChunk, j as KeyInput, jt as WatchOptions, k as DesktopStatusResponse, kt as WaitForLogResult, l as PingResponse, lt as ISandbox, m as ExecutionCallbacks, mt as PortExposeResult, n as getSandbox, nt as ExecResult, o as CreateSessionResponse, ot as FileStreamEvent, p as UnexposePortRequest, pt as PortCloseResult, q as ResponseHandler, r as SandboxClient, rt as ExecutionSession, s as DeleteSessionRequest, st as FileWatchSSEEvent, t as Sandbox, tt as ExecOptions, u as UtilityClient, ut as ListFilesOptions, v as FileClient, vt as ProcessInfoResult, w as CursorPositionResponse, wt as ProcessStatus, x as ReadFileRequest, xt as ProcessLogsResult, y as FileOperationRequest, yt as ProcessKillResult, z as CommandClient, zt as CodeContext } from "./sandbox-B2OybvGn.js";
|
|
2
|
+
import { a as DesktopCoordinateErrorContext, d as ErrorResponse$1, f as OperationType, i as BackupRestoreContext, l as ProcessExitedBeforeReadyContext, n as BackupExpiredContext, o as DesktopErrorContext, p as ErrorCode, r as BackupNotFoundContext, s as InvalidBackupConfigContext, t as BackupCreateContext, u as ProcessReadyTimeoutContext } from "./contexts-CeQR115r.js";
|
|
3
3
|
|
|
4
4
|
//#region src/errors/classes.d.ts
|
|
5
5
|
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/errors/classes.ts","../src/file-stream.ts","../src/interpreter.ts","../src/pty/proxy.ts","../src/request-handler.ts","../src/sse-parser.ts","../src/storage-mount/errors.ts"],"sourcesContent":[],"mappings":";;;;;;;;;
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/errors/classes.ts","../src/file-stream.ts","../src/interpreter.ts","../src/pty/proxy.ts","../src/request-handler.ts","../src/sse-parser.ts","../src/storage-mount/errors.ts"],"sourcesContent":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { _ as filterEnvVars, a as isExecResult, c as parseSSEFrames, d as createNoOpLogger, f as TraceContext, g as extractRepoName, h as GitLogger, i as isWSStreamChunk, l as shellEscape, m as ResultImpl, n as isWSError, o as isProcess, p as Execution, r as isWSResponse, s as isProcessStatus, t as generateRequestId, u as createLogger, v as getEnvString, y as partitionEnvVars } from "./dist-CwUZf_TJ.js";
|
|
2
|
-
import { t as ErrorCode } from "./errors-
|
|
2
|
+
import { t as ErrorCode } from "./errors-CaSfB5Bm.js";
|
|
3
3
|
import { Container, getContainer, switchPort } from "@cloudflare/containers";
|
|
4
4
|
import { AwsClient } from "aws4fetch";
|
|
5
5
|
|
|
@@ -195,6 +195,18 @@ var SessionAlreadyExistsError = class extends SandboxError {
|
|
|
195
195
|
}
|
|
196
196
|
};
|
|
197
197
|
/**
|
|
198
|
+
* Error thrown when a session was destroyed while a command was executing
|
|
199
|
+
*/
|
|
200
|
+
var SessionDestroyedError = class extends SandboxError {
|
|
201
|
+
constructor(errorResponse) {
|
|
202
|
+
super(errorResponse);
|
|
203
|
+
this.name = "SessionDestroyedError";
|
|
204
|
+
}
|
|
205
|
+
get sessionId() {
|
|
206
|
+
return this.context.sessionId;
|
|
207
|
+
}
|
|
208
|
+
};
|
|
209
|
+
/**
|
|
198
210
|
* Error thrown when a port is already exposed
|
|
199
211
|
*/
|
|
200
212
|
var PortAlreadyExposedError = class extends SandboxError {
|
|
@@ -660,6 +672,7 @@ function createErrorFromResponse(errorResponse) {
|
|
|
660
672
|
case ErrorCode.PROCESS_PERMISSION_DENIED:
|
|
661
673
|
case ErrorCode.PROCESS_ERROR: return new ProcessError(errorResponse);
|
|
662
674
|
case ErrorCode.SESSION_ALREADY_EXISTS: return new SessionAlreadyExistsError(errorResponse);
|
|
675
|
+
case ErrorCode.SESSION_DESTROYED: return new SessionDestroyedError(errorResponse);
|
|
663
676
|
case ErrorCode.PORT_ALREADY_EXPOSED: return new PortAlreadyExposedError(errorResponse);
|
|
664
677
|
case ErrorCode.PORT_NOT_EXPOSED: return new PortNotExposedError(errorResponse);
|
|
665
678
|
case ErrorCode.INVALID_PORT_NUMBER:
|
|
@@ -703,7 +716,7 @@ function createErrorFromResponse(errorResponse) {
|
|
|
703
716
|
/**
|
|
704
717
|
* Container startup retry configuration
|
|
705
718
|
*/
|
|
706
|
-
const
|
|
719
|
+
const DEFAULT_RETRY_TIMEOUT_MS = 12e4;
|
|
707
720
|
const MIN_TIME_FOR_RETRY_MS = 15e3;
|
|
708
721
|
/**
|
|
709
722
|
* Abstract base transport with shared retry logic
|
|
@@ -714,9 +727,14 @@ const MIN_TIME_FOR_RETRY_MS = 15e3;
|
|
|
714
727
|
var BaseTransport = class {
|
|
715
728
|
config;
|
|
716
729
|
logger;
|
|
730
|
+
retryTimeoutMs;
|
|
717
731
|
constructor(config) {
|
|
718
732
|
this.config = config;
|
|
719
733
|
this.logger = config.logger ?? createNoOpLogger();
|
|
734
|
+
this.retryTimeoutMs = config.retryTimeoutMs ?? DEFAULT_RETRY_TIMEOUT_MS;
|
|
735
|
+
}
|
|
736
|
+
setRetryTimeoutMs(ms) {
|
|
737
|
+
this.retryTimeoutMs = ms;
|
|
720
738
|
}
|
|
721
739
|
/**
|
|
722
740
|
* Fetch with automatic retry for 503 (container starting)
|
|
@@ -731,7 +749,7 @@ var BaseTransport = class {
|
|
|
731
749
|
const response = await this.doFetch(path, options);
|
|
732
750
|
if (response.status === 503) {
|
|
733
751
|
const elapsed = Date.now() - startTime;
|
|
734
|
-
const remaining =
|
|
752
|
+
const remaining = this.retryTimeoutMs - elapsed;
|
|
735
753
|
if (remaining > MIN_TIME_FOR_RETRY_MS) {
|
|
736
754
|
const delay = Math.min(3e3 * 2 ** attempt, 3e4);
|
|
737
755
|
this.logger.info("Container not ready, retrying", {
|
|
@@ -1105,7 +1123,22 @@ var WebSocketTransport = class extends BaseTransport {
|
|
|
1105
1123
|
if (!firstMessageReceived) {
|
|
1106
1124
|
firstMessageReceived = true;
|
|
1107
1125
|
const pending = this.pendingRequests.get(id);
|
|
1108
|
-
if (pending)
|
|
1126
|
+
if (pending) {
|
|
1127
|
+
pending.streamController = streamController;
|
|
1128
|
+
if (pending.bufferedChunks) {
|
|
1129
|
+
try {
|
|
1130
|
+
for (const buffered of pending.bufferedChunks) streamController.enqueue(buffered);
|
|
1131
|
+
} catch (error) {
|
|
1132
|
+
this.logger.debug("Failed to flush buffered chunks, cleaning up", {
|
|
1133
|
+
id,
|
|
1134
|
+
error: error instanceof Error ? error.message : String(error)
|
|
1135
|
+
});
|
|
1136
|
+
if (pending.timeoutId) clearTimeout(pending.timeoutId);
|
|
1137
|
+
this.pendingRequests.delete(id);
|
|
1138
|
+
}
|
|
1139
|
+
pending.bufferedChunks = void 0;
|
|
1140
|
+
}
|
|
1141
|
+
}
|
|
1109
1142
|
resolveStream(stream);
|
|
1110
1143
|
}
|
|
1111
1144
|
}
|
|
@@ -1176,7 +1209,12 @@ var WebSocketTransport = class extends BaseTransport {
|
|
|
1176
1209
|
pending.onFirstChunk = void 0;
|
|
1177
1210
|
}
|
|
1178
1211
|
if (!pending.streamController) {
|
|
1179
|
-
|
|
1212
|
+
if (!pending.bufferedChunks) pending.bufferedChunks = [];
|
|
1213
|
+
const encoder$1 = new TextEncoder();
|
|
1214
|
+
let sseData$1;
|
|
1215
|
+
if (chunk.event) sseData$1 = `event: ${chunk.event}\ndata: ${chunk.data}\n\n`;
|
|
1216
|
+
else sseData$1 = `data: ${chunk.data}\n\n`;
|
|
1217
|
+
pending.bufferedChunks.push(encoder$1.encode(sseData$1));
|
|
1180
1218
|
return;
|
|
1181
1219
|
}
|
|
1182
1220
|
const encoder = new TextEncoder();
|
|
@@ -1300,10 +1338,17 @@ var BaseHttpClient = class {
|
|
|
1300
1338
|
wsUrl: options.wsUrl,
|
|
1301
1339
|
logger: this.logger,
|
|
1302
1340
|
stub: options.stub,
|
|
1303
|
-
port: options.port
|
|
1341
|
+
port: options.port,
|
|
1342
|
+
retryTimeoutMs: options.retryTimeoutMs
|
|
1304
1343
|
});
|
|
1305
1344
|
}
|
|
1306
1345
|
/**
|
|
1346
|
+
* Update the transport's 503 retry budget
|
|
1347
|
+
*/
|
|
1348
|
+
setRetryTimeoutMs(ms) {
|
|
1349
|
+
this.transport.setRetryTimeoutMs(ms);
|
|
1350
|
+
}
|
|
1351
|
+
/**
|
|
1307
1352
|
* Check if using WebSocket transport
|
|
1308
1353
|
*/
|
|
1309
1354
|
isWebSocketMode() {
|
|
@@ -2722,7 +2767,8 @@ var SandboxClient = class {
|
|
|
2722
2767
|
baseUrl: options.baseUrl,
|
|
2723
2768
|
logger: options.logger,
|
|
2724
2769
|
stub: options.stub,
|
|
2725
|
-
port: options.port
|
|
2770
|
+
port: options.port,
|
|
2771
|
+
retryTimeoutMs: options.retryTimeoutMs
|
|
2726
2772
|
});
|
|
2727
2773
|
const clientOptions = {
|
|
2728
2774
|
baseUrl: "http://localhost:3000",
|
|
@@ -2741,6 +2787,28 @@ var SandboxClient = class {
|
|
|
2741
2787
|
this.watch = new WatchClient(clientOptions);
|
|
2742
2788
|
}
|
|
2743
2789
|
/**
|
|
2790
|
+
* Update the 503 retry budget on all transports without recreating the client.
|
|
2791
|
+
*
|
|
2792
|
+
* In WebSocket mode a single shared transport is used, so one update covers
|
|
2793
|
+
* every sub-client. In HTTP mode each sub-client owns its own transport, so
|
|
2794
|
+
* all of them are updated individually.
|
|
2795
|
+
*/
|
|
2796
|
+
setRetryTimeoutMs(ms) {
|
|
2797
|
+
if (this.transport) this.transport.setRetryTimeoutMs(ms);
|
|
2798
|
+
else {
|
|
2799
|
+
this.backup.setRetryTimeoutMs(ms);
|
|
2800
|
+
this.commands.setRetryTimeoutMs(ms);
|
|
2801
|
+
this.files.setRetryTimeoutMs(ms);
|
|
2802
|
+
this.processes.setRetryTimeoutMs(ms);
|
|
2803
|
+
this.ports.setRetryTimeoutMs(ms);
|
|
2804
|
+
this.git.setRetryTimeoutMs(ms);
|
|
2805
|
+
this.interpreter.setRetryTimeoutMs(ms);
|
|
2806
|
+
this.utils.setRetryTimeoutMs(ms);
|
|
2807
|
+
this.desktop.setRetryTimeoutMs(ms);
|
|
2808
|
+
this.watch.setRetryTimeoutMs(ms);
|
|
2809
|
+
}
|
|
2810
|
+
}
|
|
2811
|
+
/**
|
|
2744
2812
|
* Get the current transport mode
|
|
2745
2813
|
*/
|
|
2746
2814
|
getTransportMode() {
|
|
@@ -3280,7 +3348,7 @@ function buildS3fsSource(bucket, prefix) {
|
|
|
3280
3348
|
* This file is auto-updated by .github/changeset-version.ts during releases
|
|
3281
3349
|
* DO NOT EDIT MANUALLY - Changes will be overwritten on the next version bump
|
|
3282
3350
|
*/
|
|
3283
|
-
const SDK_VERSION = "0.7.
|
|
3351
|
+
const SDK_VERSION = "0.7.13";
|
|
3284
3352
|
|
|
3285
3353
|
//#endregion
|
|
3286
3354
|
//#region src/sandbox.ts
|
|
@@ -3433,6 +3501,18 @@ var Sandbox = class Sandbox extends Container {
|
|
|
3433
3501
|
return fn.apply(client, args);
|
|
3434
3502
|
}
|
|
3435
3503
|
/**
|
|
3504
|
+
* Compute the transport retry budget from current container timeouts.
|
|
3505
|
+
*
|
|
3506
|
+
* The budget covers the full container startup window (instance provisioning
|
|
3507
|
+
* + port readiness) plus a 30s margin for the maximum single backoff delay
|
|
3508
|
+
* (capped at 30s in BaseTransport). The 120s floor preserves the previous
|
|
3509
|
+
* default for short timeout configurations.
|
|
3510
|
+
*/
|
|
3511
|
+
computeRetryTimeoutMs() {
|
|
3512
|
+
const startupBudgetMs = this.containerTimeouts.instanceGetTimeoutMS + this.containerTimeouts.portReadyTimeoutMS;
|
|
3513
|
+
return Math.max(12e4, startupBudgetMs + 3e4);
|
|
3514
|
+
}
|
|
3515
|
+
/**
|
|
3436
3516
|
* Create a SandboxClient with current transport settings
|
|
3437
3517
|
*/
|
|
3438
3518
|
createSandboxClient() {
|
|
@@ -3440,6 +3520,7 @@ var Sandbox = class Sandbox extends Container {
|
|
|
3440
3520
|
logger: this.logger,
|
|
3441
3521
|
port: 3e3,
|
|
3442
3522
|
stub: this,
|
|
3523
|
+
retryTimeoutMs: this.computeRetryTimeoutMs(),
|
|
3443
3524
|
...this.transport === "websocket" && {
|
|
3444
3525
|
transportMode: "websocket",
|
|
3445
3526
|
wsUrl: "ws://localhost:3000/ws"
|
|
@@ -3478,10 +3559,13 @@ var Sandbox = class Sandbox extends Container {
|
|
|
3478
3559
|
this.defaultSession = await this.ctx.storage.get("defaultSession") || null;
|
|
3479
3560
|
this.keepAliveEnabled = await this.ctx.storage.get("keepAliveEnabled") || false;
|
|
3480
3561
|
const storedTimeouts = await this.ctx.storage.get("containerTimeouts");
|
|
3481
|
-
if (storedTimeouts)
|
|
3482
|
-
|
|
3483
|
-
|
|
3484
|
-
|
|
3562
|
+
if (storedTimeouts) {
|
|
3563
|
+
this.containerTimeouts = {
|
|
3564
|
+
...this.containerTimeouts,
|
|
3565
|
+
...storedTimeouts
|
|
3566
|
+
};
|
|
3567
|
+
this.client.setRetryTimeoutMs(this.computeRetryTimeoutMs());
|
|
3568
|
+
}
|
|
3485
3569
|
});
|
|
3486
3570
|
}
|
|
3487
3571
|
async setSandboxName(name, normalizeId) {
|
|
@@ -3536,6 +3620,7 @@ var Sandbox = class Sandbox extends Container {
|
|
|
3536
3620
|
if (timeouts.waitIntervalMS !== void 0) validated.waitIntervalMS = this.validateTimeout(timeouts.waitIntervalMS, "waitIntervalMS", 100, 5e3);
|
|
3537
3621
|
this.containerTimeouts = validated;
|
|
3538
3622
|
await this.ctx.storage.put("containerTimeouts", this.containerTimeouts);
|
|
3623
|
+
this.client.setRetryTimeoutMs(this.computeRetryTimeoutMs());
|
|
3539
3624
|
this.logger.debug("Container timeouts updated", this.containerTimeouts);
|
|
3540
3625
|
}
|
|
3541
3626
|
/**
|
|
@@ -3783,22 +3868,84 @@ var Sandbox = class Sandbox extends Container {
|
|
|
3783
3868
|
}
|
|
3784
3869
|
});
|
|
3785
3870
|
} catch (e) {
|
|
3786
|
-
if (this.isNoInstanceError(e))
|
|
3787
|
-
|
|
3788
|
-
|
|
3789
|
-
|
|
3871
|
+
if (this.isNoInstanceError(e)) {
|
|
3872
|
+
const errorBody$1 = {
|
|
3873
|
+
code: ErrorCode.INTERNAL_ERROR,
|
|
3874
|
+
message: "Container is currently provisioning. This can take several minutes on first deployment.",
|
|
3875
|
+
context: { phase: "provisioning" },
|
|
3876
|
+
httpStatus: 503,
|
|
3877
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
3878
|
+
suggestion: "This is expected during first deployment. The SDK will retry automatically."
|
|
3879
|
+
};
|
|
3880
|
+
return new Response(JSON.stringify(errorBody$1), {
|
|
3881
|
+
status: 503,
|
|
3882
|
+
headers: {
|
|
3883
|
+
"Content-Type": "application/json",
|
|
3884
|
+
"Retry-After": "10"
|
|
3885
|
+
}
|
|
3886
|
+
});
|
|
3887
|
+
}
|
|
3888
|
+
if (this.isPermanentStartupError(e)) {
|
|
3889
|
+
this.logger.error("Permanent container startup error, returning 500", e instanceof Error ? e : new Error(String(e)));
|
|
3890
|
+
const errorBody$1 = {
|
|
3891
|
+
code: ErrorCode.INTERNAL_ERROR,
|
|
3892
|
+
message: "Container failed to start due to a permanent error. Check your container configuration.",
|
|
3893
|
+
context: {
|
|
3894
|
+
phase: "startup",
|
|
3895
|
+
error: e instanceof Error ? e.message : String(e)
|
|
3896
|
+
},
|
|
3897
|
+
httpStatus: 500,
|
|
3898
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
3899
|
+
suggestion: "This error will not resolve with retries. Check container logs, image name, and resource limits."
|
|
3900
|
+
};
|
|
3901
|
+
return new Response(JSON.stringify(errorBody$1), {
|
|
3902
|
+
status: 500,
|
|
3903
|
+
headers: { "Content-Type": "application/json" }
|
|
3904
|
+
});
|
|
3905
|
+
}
|
|
3790
3906
|
if (this.isTransientStartupError(e)) {
|
|
3791
3907
|
if (staleStateDetected) {
|
|
3792
3908
|
this.logger.warn("Container startup failed after stale state detection, aborting DO for recovery", { error: e instanceof Error ? e.message : String(e) });
|
|
3793
3909
|
this.ctx.abort();
|
|
3794
3910
|
} else this.logger.debug("Transient container startup error, returning 503", { error: e instanceof Error ? e.message : String(e) });
|
|
3795
|
-
|
|
3911
|
+
const errorBody$1 = {
|
|
3912
|
+
code: ErrorCode.INTERNAL_ERROR,
|
|
3913
|
+
message: "Container is starting. Please retry in a moment.",
|
|
3914
|
+
context: {
|
|
3915
|
+
phase: "startup",
|
|
3916
|
+
error: e instanceof Error ? e.message : String(e)
|
|
3917
|
+
},
|
|
3918
|
+
httpStatus: 503,
|
|
3919
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
3920
|
+
suggestion: "The container is booting. The SDK will retry automatically."
|
|
3921
|
+
};
|
|
3922
|
+
return new Response(JSON.stringify(errorBody$1), {
|
|
3796
3923
|
status: 503,
|
|
3797
|
-
headers: {
|
|
3924
|
+
headers: {
|
|
3925
|
+
"Content-Type": "application/json",
|
|
3926
|
+
"Retry-After": "3"
|
|
3927
|
+
}
|
|
3798
3928
|
});
|
|
3799
3929
|
}
|
|
3800
|
-
this.logger.
|
|
3801
|
-
|
|
3930
|
+
this.logger.warn("Unrecognized container startup error, returning 503 for retry", { error: e instanceof Error ? e.message : String(e) });
|
|
3931
|
+
const errorBody = {
|
|
3932
|
+
code: ErrorCode.INTERNAL_ERROR,
|
|
3933
|
+
message: "Container is starting. Please retry in a moment.",
|
|
3934
|
+
context: {
|
|
3935
|
+
phase: "startup",
|
|
3936
|
+
error: e instanceof Error ? e.message : String(e)
|
|
3937
|
+
},
|
|
3938
|
+
httpStatus: 503,
|
|
3939
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
3940
|
+
suggestion: "The SDK will retry automatically. If this persists, the container may need redeployment."
|
|
3941
|
+
};
|
|
3942
|
+
return new Response(JSON.stringify(errorBody), {
|
|
3943
|
+
status: 503,
|
|
3944
|
+
headers: {
|
|
3945
|
+
"Content-Type": "application/json",
|
|
3946
|
+
"Retry-After": "5"
|
|
3947
|
+
}
|
|
3948
|
+
});
|
|
3802
3949
|
}
|
|
3803
3950
|
}
|
|
3804
3951
|
return await super.containerFetch(requestOrUrl, portOrInit, portParam);
|
|
@@ -3844,6 +3991,30 @@ var Sandbox = class Sandbox extends Container {
|
|
|
3844
3991
|
].some((pattern) => msg.includes(pattern));
|
|
3845
3992
|
}
|
|
3846
3993
|
/**
|
|
3994
|
+
* Helper: Check if error is a permanent startup failure that will never recover
|
|
3995
|
+
*
|
|
3996
|
+
* These errors indicate resource exhaustion, misconfiguration, or missing images.
|
|
3997
|
+
* Retrying will never succeed, so the SDK should fail fast with HTTP 500.
|
|
3998
|
+
*
|
|
3999
|
+
* Error sources (traced from platform internals):
|
|
4000
|
+
* - Container runtime: OOM, PID limit
|
|
4001
|
+
* - Scheduling/provisioning: no matching app, no namespace configured
|
|
4002
|
+
* - workerd container-client.c++: no such image
|
|
4003
|
+
* - @cloudflare/containers: did not call start
|
|
4004
|
+
*/
|
|
4005
|
+
isPermanentStartupError(error) {
|
|
4006
|
+
if (!(error instanceof Error)) return false;
|
|
4007
|
+
const msg = error.message.toLowerCase();
|
|
4008
|
+
return [
|
|
4009
|
+
"ran out of memory",
|
|
4010
|
+
"too many subprocesses",
|
|
4011
|
+
"no application that matches",
|
|
4012
|
+
"no container application assigned",
|
|
4013
|
+
"no such image",
|
|
4014
|
+
"did not call start"
|
|
4015
|
+
].some((pattern) => msg.includes(pattern));
|
|
4016
|
+
}
|
|
4017
|
+
/**
|
|
3847
4018
|
* Helper: Parse containerFetch arguments (supports multiple signatures)
|
|
3848
4019
|
*/
|
|
3849
4020
|
parseContainerFetchArgs(requestOrUrl, portOrInit, portParam) {
|
|
@@ -4103,9 +4274,6 @@ var Sandbox = class Sandbox extends Container {
|
|
|
4103
4274
|
}
|
|
4104
4275
|
try {
|
|
4105
4276
|
const streamProcessor = async () => {
|
|
4106
|
-
const DEBOUNCE_MS = 50;
|
|
4107
|
-
let lastCheckTime = 0;
|
|
4108
|
-
let pendingCheck = false;
|
|
4109
4277
|
const checkPattern = () => {
|
|
4110
4278
|
const stdoutResult = this.matchPattern(collectedStdout, pattern);
|
|
4111
4279
|
if (stdoutResult) return stdoutResult;
|
|
@@ -4118,27 +4286,17 @@ var Sandbox = class Sandbox extends Container {
|
|
|
4118
4286
|
const data = event.data || "";
|
|
4119
4287
|
if (event.type === "stdout") collectedStdout += data;
|
|
4120
4288
|
else collectedStderr += data;
|
|
4121
|
-
|
|
4122
|
-
|
|
4123
|
-
if (now - lastCheckTime >= DEBOUNCE_MS) {
|
|
4124
|
-
lastCheckTime = now;
|
|
4125
|
-
pendingCheck = false;
|
|
4126
|
-
const result = checkPattern();
|
|
4127
|
-
if (result) return result;
|
|
4128
|
-
}
|
|
4289
|
+
const result = checkPattern();
|
|
4290
|
+
if (result) return result;
|
|
4129
4291
|
}
|
|
4130
4292
|
if (event.type === "exit") {
|
|
4131
|
-
|
|
4132
|
-
|
|
4133
|
-
if (result) return result;
|
|
4134
|
-
}
|
|
4293
|
+
const result = checkPattern();
|
|
4294
|
+
if (result) return result;
|
|
4135
4295
|
throw this.createExitedBeforeReadyError(processId, command, conditionStr, event.exitCode ?? 1);
|
|
4136
4296
|
}
|
|
4137
4297
|
}
|
|
4138
|
-
|
|
4139
|
-
|
|
4140
|
-
if (result) return result;
|
|
4141
|
-
}
|
|
4298
|
+
const finalResult = checkPattern();
|
|
4299
|
+
if (finalResult) return finalResult;
|
|
4142
4300
|
throw this.createExitedBeforeReadyError(processId, command, conditionStr, 0);
|
|
4143
4301
|
};
|
|
4144
4302
|
if (timeoutPromise) return await Promise.race([streamProcessor(), timeoutPromise]);
|