@cloudflare/sandbox 0.10.2 → 0.10.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/Dockerfile +51 -20
- package/README.md +0 -2
- package/dist/bridge/index.js +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/openai/index.d.ts +1 -1
- package/dist/opencode/index.d.ts +1 -1
- package/dist/opencode/index.d.ts.map +1 -1
- package/dist/{sandbox-BcEq4aUF.js → sandbox-B-MUmsli.js} +228 -89
- package/dist/sandbox-B-MUmsli.js.map +1 -0
- package/dist/{sandbox-KdzTTnWq.d.ts → sandbox-CwcSm_60.d.ts} +59 -32
- package/dist/sandbox-CwcSm_60.d.ts.map +1 -0
- package/package.json +2 -2
- package/dist/sandbox-BcEq4aUF.js.map +0 -1
- package/dist/sandbox-KdzTTnWq.d.ts.map +0 -1
|
@@ -2765,6 +2765,10 @@ function normalizeBackupExcludePattern(pattern) {
|
|
|
2765
2765
|
return normalized;
|
|
2766
2766
|
}
|
|
2767
2767
|
|
|
2768
|
+
//#endregion
|
|
2769
|
+
//#region ../shared/src/internal.ts
|
|
2770
|
+
const DISABLE_SESSION_TOKEN = "__DISABLE_SESSION__";
|
|
2771
|
+
|
|
2768
2772
|
//#endregion
|
|
2769
2773
|
//#region src/container-control/connection.ts
|
|
2770
2774
|
const DEFAULT_CONNECT_TIMEOUT_MS = 3e4;
|
|
@@ -3057,12 +3061,33 @@ const IDLE_EXPORT_THRESHOLD = 1;
|
|
|
3057
3061
|
/**
|
|
3058
3062
|
* Translate a capnweb-propagated error into a typed SandboxError.
|
|
3059
3063
|
*
|
|
3060
|
-
*
|
|
3061
|
-
*
|
|
3062
|
-
*
|
|
3064
|
+
* Two wire formats are supported for backward compatibility with older
|
|
3065
|
+
* container images:
|
|
3066
|
+
*
|
|
3067
|
+
* 1. Propagated error properties (capnweb >= 0.8.0). The container throws a
|
|
3068
|
+
* `ServiceError`-shaped object with own enumerable `code` and `details`
|
|
3069
|
+
* properties. capnweb walks `Object.keys()` and reconstructs those fields
|
|
3070
|
+
* on the SDK side.
|
|
3071
|
+
* 2. Legacy JSON-encoded message. Older containers encoded the structured
|
|
3072
|
+
* payload as a JSON string in `error.message`.
|
|
3073
|
+
*
|
|
3074
|
+
* The JSON-fallback branch can be removed once all older container images are
|
|
3075
|
+
* no longer in service.
|
|
3063
3076
|
*/
|
|
3064
3077
|
function translateRPCError(error) {
|
|
3065
3078
|
if (error instanceof Error) {
|
|
3079
|
+
const propagated = error;
|
|
3080
|
+
if (typeof propagated.code === "string" && Object.hasOwn(ErrorCode, propagated.code)) {
|
|
3081
|
+
const code = propagated.code;
|
|
3082
|
+
const context = propagated.details && typeof propagated.details === "object" ? propagated.details : {};
|
|
3083
|
+
throw createErrorFromResponse({
|
|
3084
|
+
code,
|
|
3085
|
+
message: error.message,
|
|
3086
|
+
context,
|
|
3087
|
+
httpStatus: getHttpStatus(code),
|
|
3088
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
3089
|
+
});
|
|
3090
|
+
}
|
|
3066
3091
|
let payload;
|
|
3067
3092
|
try {
|
|
3068
3093
|
payload = JSON.parse(error.message);
|
|
@@ -4838,7 +4863,7 @@ function createTunnelsHandler(host) {
|
|
|
4838
4863
|
* This file is auto-updated by .github/changeset-version.ts during releases
|
|
4839
4864
|
* DO NOT EDIT MANUALLY - Changes will be overwritten on the next version bump
|
|
4840
4865
|
*/
|
|
4841
|
-
const SDK_VERSION = "0.10.
|
|
4866
|
+
const SDK_VERSION = "0.10.3";
|
|
4842
4867
|
|
|
4843
4868
|
//#endregion
|
|
4844
4869
|
//#region src/sandbox.ts
|
|
@@ -4987,14 +5012,63 @@ function getSandbox(ns, id, options) {
|
|
|
4987
5012
|
});
|
|
4988
5013
|
}
|
|
4989
5014
|
const defaultSessionId = `sandbox-${effectiveId}`;
|
|
5015
|
+
const useDefaultSession = options?.enableDefaultSession !== false;
|
|
4990
5016
|
const enhancedMethods = {
|
|
4991
5017
|
fetch: (request) => stub.fetch(request),
|
|
5018
|
+
exec: (command, execOptions) => useDefaultSession ? stub.exec(command, execOptions) : stub.execWithSessionToken(command, DISABLE_SESSION_TOKEN, execOptions),
|
|
5019
|
+
startProcess: (command, processOptions) => useDefaultSession || processOptions?.sessionId !== void 0 ? stub.startProcess(command, processOptions) : stub.startProcess(command, {
|
|
5020
|
+
...processOptions,
|
|
5021
|
+
sessionId: DISABLE_SESSION_TOKEN
|
|
5022
|
+
}),
|
|
5023
|
+
listProcesses: (sessionId) => useDefaultSession || sessionId !== void 0 ? stub.listProcesses(sessionId) : stub.listProcesses(DISABLE_SESSION_TOKEN),
|
|
5024
|
+
getProcess: (id$1, sessionId) => useDefaultSession || sessionId !== void 0 ? stub.getProcess(id$1, sessionId) : stub.getProcess(id$1, DISABLE_SESSION_TOKEN),
|
|
5025
|
+
execStream: (command, streamOptions) => {
|
|
5026
|
+
if (useDefaultSession || streamOptions?.sessionId !== void 0) return stub.execStream(command, streamOptions);
|
|
5027
|
+
return stub.execStreamWithSessionToken(command, DISABLE_SESSION_TOKEN, streamOptions);
|
|
5028
|
+
},
|
|
5029
|
+
writeFile: (path$1, content, fileOptions = {}) => useDefaultSession || fileOptions.sessionId !== void 0 ? stub.writeFile(path$1, content, fileOptions) : stub.writeFile(path$1, content, {
|
|
5030
|
+
...fileOptions,
|
|
5031
|
+
sessionId: DISABLE_SESSION_TOKEN
|
|
5032
|
+
}),
|
|
5033
|
+
readFile: (path$1, fileOptions = {}) => {
|
|
5034
|
+
const options$1 = useDefaultSession || fileOptions.sessionId !== void 0 ? fileOptions : {
|
|
5035
|
+
...fileOptions,
|
|
5036
|
+
sessionId: DISABLE_SESSION_TOKEN
|
|
5037
|
+
};
|
|
5038
|
+
if (options$1.encoding === "none") return stub.readFile(path$1, options$1);
|
|
5039
|
+
return stub.readFile(path$1, options$1);
|
|
5040
|
+
},
|
|
5041
|
+
readFileStream: (path$1, fileOptions = {}) => useDefaultSession || fileOptions.sessionId !== void 0 ? stub.readFileStream(path$1, fileOptions) : stub.readFileStream(path$1, { sessionId: DISABLE_SESSION_TOKEN }),
|
|
5042
|
+
mkdir: (path$1, mkdirOptions = {}) => useDefaultSession || mkdirOptions.sessionId !== void 0 ? stub.mkdir(path$1, mkdirOptions) : stub.mkdir(path$1, {
|
|
5043
|
+
...mkdirOptions,
|
|
5044
|
+
sessionId: DISABLE_SESSION_TOKEN
|
|
5045
|
+
}),
|
|
5046
|
+
deleteFile: (path$1) => useDefaultSession ? stub.deleteFile(path$1) : stub.deleteFile(path$1, DISABLE_SESSION_TOKEN),
|
|
5047
|
+
renameFile: (oldPath, newPath) => useDefaultSession ? stub.renameFile(oldPath, newPath) : stub.renameFile(oldPath, newPath, DISABLE_SESSION_TOKEN),
|
|
5048
|
+
moveFile: (sourcePath, destinationPath) => useDefaultSession ? stub.moveFile(sourcePath, destinationPath) : stub.moveFile(sourcePath, destinationPath, DISABLE_SESSION_TOKEN),
|
|
5049
|
+
listFiles: (path$1, listOptions) => useDefaultSession || listOptions?.sessionId !== void 0 ? stub.listFiles(path$1, listOptions) : stub.listFiles(path$1, {
|
|
5050
|
+
...listOptions,
|
|
5051
|
+
sessionId: DISABLE_SESSION_TOKEN
|
|
5052
|
+
}),
|
|
5053
|
+
exists: (path$1, sessionId) => useDefaultSession || sessionId !== void 0 ? stub.exists(path$1, sessionId) : stub.exists(path$1, DISABLE_SESSION_TOKEN),
|
|
5054
|
+
gitCheckout: (repoUrl, gitOptions) => useDefaultSession || gitOptions?.sessionId !== void 0 ? stub.gitCheckout(repoUrl, gitOptions) : stub.gitCheckout(repoUrl, {
|
|
5055
|
+
...gitOptions,
|
|
5056
|
+
sessionId: DISABLE_SESSION_TOKEN
|
|
5057
|
+
}),
|
|
4992
5058
|
createSession: async (opts) => {
|
|
4993
5059
|
return enhanceSession(stub, await stub.createSession(opts));
|
|
4994
5060
|
},
|
|
4995
5061
|
getSession: async (sessionId) => {
|
|
4996
5062
|
return enhanceSession(stub, await stub.getSession(sessionId));
|
|
4997
5063
|
},
|
|
5064
|
+
watch: (path$1, options$1 = {}) => useDefaultSession || options$1.sessionId !== void 0 ? stub.watch(path$1, options$1) : stub.watch(path$1, {
|
|
5065
|
+
...options$1,
|
|
5066
|
+
sessionId: DISABLE_SESSION_TOKEN
|
|
5067
|
+
}),
|
|
5068
|
+
checkChanges: (path$1, options$1 = {}) => useDefaultSession || options$1.sessionId !== void 0 ? stub.checkChanges(path$1, options$1) : stub.checkChanges(path$1, {
|
|
5069
|
+
...options$1,
|
|
5070
|
+
sessionId: DISABLE_SESSION_TOKEN
|
|
5071
|
+
}),
|
|
4998
5072
|
terminal: (request, opts) => proxyTerminal(stub, defaultSessionId, request, opts),
|
|
4999
5073
|
wsConnect: connect(stub),
|
|
5000
5074
|
desktop: new Proxy({}, { get(_, method) {
|
|
@@ -5325,13 +5399,6 @@ var Sandbox = class Sandbox extends Container {
|
|
|
5325
5399
|
}
|
|
5326
5400
|
}
|
|
5327
5401
|
}
|
|
5328
|
-
/**
|
|
5329
|
-
* RPC method to configure container startup timeouts. Idempotent once
|
|
5330
|
-
* the values have been persisted: re-applying the same timeout set is a
|
|
5331
|
-
* no-op. The transport retry budget is recomputed only when at least
|
|
5332
|
-
* one timeout actually changes. Storage is written before the in-memory
|
|
5333
|
-
* mirror and derived state are updated.
|
|
5334
|
-
*/
|
|
5335
5402
|
async setContainerTimeouts(timeouts) {
|
|
5336
5403
|
const validated = { ...this.containerTimeouts };
|
|
5337
5404
|
if (timeouts.instanceGetTimeoutMS !== void 0) validated.instanceGetTimeoutMS = this.validateTimeout(timeouts.instanceGetTimeoutMS, "instanceGetTimeoutMS", 5e3, 3e5);
|
|
@@ -5344,11 +5411,6 @@ var Sandbox = class Sandbox extends Container {
|
|
|
5344
5411
|
this.client.setRetryTimeoutMs(this.computeRetryTimeoutMs());
|
|
5345
5412
|
this.logger.debug("Container timeouts updated", this.containerTimeouts);
|
|
5346
5413
|
}
|
|
5347
|
-
/**
|
|
5348
|
-
* RPC method to set the transport protocol. Idempotent once the value
|
|
5349
|
-
* has been persisted: re-applying the same transport is a no-op.
|
|
5350
|
-
* Storage is written before the in-memory state and client are updated.
|
|
5351
|
-
*/
|
|
5352
5414
|
async setTransport(transport) {
|
|
5353
5415
|
if (transport !== "http" && transport !== "websocket" && transport !== "rpc") {
|
|
5354
5416
|
this.logger.warn(`Invalid transport value: "${transport}". Must be "http", "websocket", or "rpc". Ignoring.`);
|
|
@@ -5367,19 +5429,11 @@ var Sandbox = class Sandbox extends Container {
|
|
|
5367
5429
|
this.renewActivityTimeout();
|
|
5368
5430
|
this.logger.debug("Transport updated", { transport });
|
|
5369
5431
|
}
|
|
5370
|
-
/**
|
|
5371
|
-
* Validate a timeout value is within acceptable range
|
|
5372
|
-
* Throws error if invalid - used for user-provided values
|
|
5373
|
-
*/
|
|
5374
5432
|
validateTimeout(value, name, min, max) {
|
|
5375
5433
|
if (typeof value !== "number" || Number.isNaN(value) || !Number.isFinite(value)) throw new Error(`${name} must be a valid finite number, got ${value}`);
|
|
5376
5434
|
if (value < min || value > max) throw new Error(`${name} must be between ${min}-${max}ms, got ${value}ms`);
|
|
5377
5435
|
return value;
|
|
5378
5436
|
}
|
|
5379
|
-
/**
|
|
5380
|
-
* Get default timeouts with env var fallbacks and validation
|
|
5381
|
-
* Precedence: SDK defaults < Env vars < User config
|
|
5382
|
-
*/
|
|
5383
5437
|
getDefaultTimeouts(env$1) {
|
|
5384
5438
|
const parseAndValidate = (envVar, name, min, max) => {
|
|
5385
5439
|
const defaultValue = this.DEFAULT_CONTAINER_TIMEOUTS[name];
|
|
@@ -5742,7 +5796,7 @@ var Sandbox = class Sandbox extends Container {
|
|
|
5742
5796
|
*/
|
|
5743
5797
|
async createPasswordFile(passwordFilePath, bucket, credentials) {
|
|
5744
5798
|
const content = `${bucket}:${credentials.accessKeyId}:${credentials.secretAccessKey}`;
|
|
5745
|
-
await this.writeFile(passwordFilePath, content);
|
|
5799
|
+
await this.client.files.writeFile(passwordFilePath, content, DISABLE_SESSION_TOKEN);
|
|
5746
5800
|
await this.execInternal(`chmod 0600 ${shellEscape(passwordFilePath)}`);
|
|
5747
5801
|
}
|
|
5748
5802
|
/**
|
|
@@ -5920,8 +5974,7 @@ var Sandbox = class Sandbox extends Container {
|
|
|
5920
5974
|
let restored = 0;
|
|
5921
5975
|
let skipped = 0;
|
|
5922
5976
|
let failed = 0;
|
|
5923
|
-
const
|
|
5924
|
-
const exposedSet = await this.client.ports.getExposedPorts(sessionId).then((response) => new Set(response.ports.map((p) => p.port))).catch((error) => {
|
|
5977
|
+
const exposedSet = await this.client.ports.getExposedPorts(DISABLE_SESSION_TOKEN).then((response) => new Set(response.ports.map((p) => p.port))).catch((error) => {
|
|
5925
5978
|
this.logger.warn("Failed to fetch exposed ports for restore; assuming none exposed", { error: error instanceof Error ? error.message : String(error) });
|
|
5926
5979
|
return /* @__PURE__ */ new Set();
|
|
5927
5980
|
});
|
|
@@ -5937,7 +5990,7 @@ var Sandbox = class Sandbox extends Container {
|
|
|
5937
5990
|
continue;
|
|
5938
5991
|
}
|
|
5939
5992
|
try {
|
|
5940
|
-
await this.client.ports.exposePort(port,
|
|
5993
|
+
await this.client.ports.exposePort(port, DISABLE_SESSION_TOKEN, entry.name);
|
|
5941
5994
|
restored++;
|
|
5942
5995
|
} catch (error) {
|
|
5943
5996
|
failed++;
|
|
@@ -6320,10 +6373,78 @@ var Sandbox = class Sandbox extends Container {
|
|
|
6320
6373
|
if (containerPlacementId === void 0) return;
|
|
6321
6374
|
await this.ctx.storage.put("containerPlacementId", containerPlacementId);
|
|
6322
6375
|
}
|
|
6376
|
+
async resolveExecution(explicitSessionId) {
|
|
6377
|
+
if (explicitSessionId !== void 0) {
|
|
6378
|
+
this.validateExplicitSessionId(explicitSessionId);
|
|
6379
|
+
if (explicitSessionId === DISABLE_SESSION_TOKEN) return { kind: "sessionless" };
|
|
6380
|
+
return {
|
|
6381
|
+
kind: "session",
|
|
6382
|
+
sessionId: explicitSessionId
|
|
6383
|
+
};
|
|
6384
|
+
}
|
|
6385
|
+
return {
|
|
6386
|
+
kind: "session",
|
|
6387
|
+
sessionId: await this.ensureDefaultSession()
|
|
6388
|
+
};
|
|
6389
|
+
}
|
|
6390
|
+
validateExplicitSessionId(sessionId) {
|
|
6391
|
+
if (sessionId.trim().length === 0) throw new Error("sessionId must not be empty or whitespace");
|
|
6392
|
+
}
|
|
6393
|
+
serializeExecutionContext(context) {
|
|
6394
|
+
if (context.kind === "sessionless") return DISABLE_SESSION_TOKEN;
|
|
6395
|
+
return context.sessionId;
|
|
6396
|
+
}
|
|
6397
|
+
getPublicExecutionSessionId(sessionId) {
|
|
6398
|
+
return sessionId === DISABLE_SESSION_TOKEN ? void 0 : sessionId;
|
|
6399
|
+
}
|
|
6400
|
+
/**
|
|
6401
|
+
* Resolves the session ID to annotate returned Process objects.
|
|
6402
|
+
*
|
|
6403
|
+
* Unlike `resolveExecution`, this is synchronous and never creates a
|
|
6404
|
+
* session. When the default session hasn't been established yet, it returns
|
|
6405
|
+
* `undefined` rather than triggering session creation. The resolved value is
|
|
6406
|
+
* only used to populate `Process.sessionId` on the returned object — it is
|
|
6407
|
+
* never sent to the container API.
|
|
6408
|
+
*/
|
|
6409
|
+
getProcessSessionBinding(explicitSessionId) {
|
|
6410
|
+
if (explicitSessionId !== void 0) {
|
|
6411
|
+
this.validateExplicitSessionId(explicitSessionId);
|
|
6412
|
+
if (explicitSessionId === DISABLE_SESSION_TOKEN) return;
|
|
6413
|
+
return explicitSessionId;
|
|
6414
|
+
}
|
|
6415
|
+
return this.defaultSession ?? void 0;
|
|
6416
|
+
}
|
|
6417
|
+
resolveExecutionEnv(sessionId, env$1) {
|
|
6418
|
+
if (sessionId === DISABLE_SESSION_TOKEN) {
|
|
6419
|
+
const mergedEnv = filterEnvVars({
|
|
6420
|
+
...this.envVars,
|
|
6421
|
+
...env$1 ?? {}
|
|
6422
|
+
});
|
|
6423
|
+
return Object.keys(mergedEnv).length > 0 ? mergedEnv : void 0;
|
|
6424
|
+
}
|
|
6425
|
+
if (env$1 === void 0) return;
|
|
6426
|
+
const filteredEnv = filterEnvVars(env$1);
|
|
6427
|
+
return Object.keys(filteredEnv).length > 0 ? filteredEnv : void 0;
|
|
6428
|
+
}
|
|
6429
|
+
buildExecutionRequestOptions(sessionId, options) {
|
|
6430
|
+
const env$1 = this.resolveExecutionEnv(sessionId, options?.env);
|
|
6431
|
+
if (options?.timeout === void 0 && env$1 === void 0 && options?.cwd === void 0 && options?.origin === void 0) return;
|
|
6432
|
+
return {
|
|
6433
|
+
...options?.timeout !== void 0 && { timeoutMs: options.timeout },
|
|
6434
|
+
...env$1 !== void 0 && { env: env$1 },
|
|
6435
|
+
...options?.cwd !== void 0 && { cwd: options.cwd },
|
|
6436
|
+
...options?.origin !== void 0 && { origin: options.origin }
|
|
6437
|
+
};
|
|
6438
|
+
}
|
|
6323
6439
|
async exec(command, options) {
|
|
6324
|
-
const
|
|
6440
|
+
const context = await this.resolveExecution();
|
|
6441
|
+
const session = this.serializeExecutionContext(context);
|
|
6325
6442
|
return this.execWithSession(command, session, options);
|
|
6326
6443
|
}
|
|
6444
|
+
async execWithSessionToken(command, sessionId, options) {
|
|
6445
|
+
this.validateExplicitSessionId(sessionId);
|
|
6446
|
+
return this.execWithSession(command, sessionId, options);
|
|
6447
|
+
}
|
|
6327
6448
|
/**
|
|
6328
6449
|
* Execute an infrastructure command (backup, mount, env setup, etc.)
|
|
6329
6450
|
* tagged with origin: 'internal' so logging demotes it to debug level.
|
|
@@ -6346,15 +6467,11 @@ var Sandbox = class Sandbox extends Container {
|
|
|
6346
6467
|
let result;
|
|
6347
6468
|
if (options?.stream && options?.onOutput) result = await this.executeWithStreaming(command, sessionId, options, startTime, timestamp);
|
|
6348
6469
|
else {
|
|
6349
|
-
const commandOptions =
|
|
6350
|
-
timeoutMs: options.timeout,
|
|
6351
|
-
env: options.env,
|
|
6352
|
-
cwd: options.cwd,
|
|
6353
|
-
origin: options.origin
|
|
6354
|
-
} : void 0;
|
|
6470
|
+
const commandOptions = this.buildExecutionRequestOptions(sessionId, options);
|
|
6355
6471
|
const response = await this.client.commands.execute(command, sessionId, commandOptions);
|
|
6356
6472
|
const duration = Date.now() - startTime;
|
|
6357
|
-
|
|
6473
|
+
const publicSessionId = this.getPublicExecutionSessionId(sessionId);
|
|
6474
|
+
result = this.mapExecuteResponseToExecResult(response, duration, publicSessionId);
|
|
6358
6475
|
}
|
|
6359
6476
|
execOutcome = {
|
|
6360
6477
|
exitCode: result.exitCode,
|
|
@@ -6373,7 +6490,7 @@ var Sandbox = class Sandbox extends Container {
|
|
|
6373
6490
|
command,
|
|
6374
6491
|
exitCode: execOutcome?.exitCode,
|
|
6375
6492
|
durationMs: Date.now() - startTime,
|
|
6376
|
-
sessionId,
|
|
6493
|
+
sessionId: this.getPublicExecutionSessionId(sessionId),
|
|
6377
6494
|
origin: options?.origin ?? "user",
|
|
6378
6495
|
error: execError ?? void 0,
|
|
6379
6496
|
errorMessage: execError?.message
|
|
@@ -6384,12 +6501,8 @@ var Sandbox = class Sandbox extends Container {
|
|
|
6384
6501
|
let stdout = "";
|
|
6385
6502
|
let stderr = "";
|
|
6386
6503
|
try {
|
|
6387
|
-
const
|
|
6388
|
-
|
|
6389
|
-
env: options.env,
|
|
6390
|
-
cwd: options.cwd,
|
|
6391
|
-
origin: options.origin
|
|
6392
|
-
});
|
|
6504
|
+
const commandOptions = this.buildExecutionRequestOptions(sessionId, options);
|
|
6505
|
+
const stream = await this.client.commands.executeStream(command, sessionId, commandOptions);
|
|
6393
6506
|
for await (const event of parseSSEStream(stream)) {
|
|
6394
6507
|
if (options.signal?.aborted) throw new Error("Operation was aborted");
|
|
6395
6508
|
switch (event.type) {
|
|
@@ -6411,7 +6524,7 @@ var Sandbox = class Sandbox extends Container {
|
|
|
6411
6524
|
command,
|
|
6412
6525
|
duration,
|
|
6413
6526
|
timestamp,
|
|
6414
|
-
sessionId
|
|
6527
|
+
sessionId: this.getPublicExecutionSessionId(sessionId)
|
|
6415
6528
|
};
|
|
6416
6529
|
}
|
|
6417
6530
|
case "error": throw new Error(event.data || "Command execution failed");
|
|
@@ -6687,12 +6800,16 @@ var Sandbox = class Sandbox extends Container {
|
|
|
6687
6800
|
}
|
|
6688
6801
|
async startProcess(command, options, sessionId) {
|
|
6689
6802
|
try {
|
|
6690
|
-
const
|
|
6803
|
+
const execution = await this.resolveExecution(sessionId);
|
|
6804
|
+
const session = this.serializeExecutionContext(execution);
|
|
6805
|
+
const processSession = this.getProcessSessionBinding(session);
|
|
6691
6806
|
const requestOptions = {
|
|
6807
|
+
...this.buildExecutionRequestOptions(session, {
|
|
6808
|
+
timeout: options?.timeout,
|
|
6809
|
+
env: options?.env,
|
|
6810
|
+
cwd: options?.cwd
|
|
6811
|
+
}),
|
|
6692
6812
|
...options?.processId !== void 0 && { processId: options.processId },
|
|
6693
|
-
...options?.timeout !== void 0 && { timeoutMs: options.timeout },
|
|
6694
|
-
...options?.env !== void 0 && { env: filterEnvVars(options.env) },
|
|
6695
|
-
...options?.cwd !== void 0 && { cwd: options.cwd },
|
|
6696
6813
|
...options?.encoding !== void 0 && { encoding: options.encoding },
|
|
6697
6814
|
...options?.autoCleanup !== void 0 && { autoCleanup: options.autoCleanup }
|
|
6698
6815
|
};
|
|
@@ -6705,7 +6822,7 @@ var Sandbox = class Sandbox extends Container {
|
|
|
6705
6822
|
startTime: /* @__PURE__ */ new Date(),
|
|
6706
6823
|
endTime: void 0,
|
|
6707
6824
|
exitCode: void 0
|
|
6708
|
-
},
|
|
6825
|
+
}, processSession);
|
|
6709
6826
|
if (options?.onStart) options.onStart(processObj);
|
|
6710
6827
|
if (options?.onOutput || options?.onExit) this.startProcessCallbackStream(response.processId, options).catch(() => {});
|
|
6711
6828
|
return processObj;
|
|
@@ -6733,13 +6850,14 @@ var Sandbox = class Sandbox extends Container {
|
|
|
6733
6850
|
if (options.onExit) options.onExit(event.exitCode ?? null);
|
|
6734
6851
|
return;
|
|
6735
6852
|
}
|
|
6853
|
+
throw new Error("Stream ended without completion event");
|
|
6736
6854
|
} catch (error) {
|
|
6737
6855
|
if (options.onError && error instanceof Error) options.onError(error);
|
|
6738
6856
|
this.logger.error("Background process streaming failed", error instanceof Error ? error : new Error(String(error)), { processId });
|
|
6739
6857
|
}
|
|
6740
6858
|
}
|
|
6741
6859
|
async listProcesses(sessionId) {
|
|
6742
|
-
const session =
|
|
6860
|
+
const session = this.getProcessSessionBinding(sessionId);
|
|
6743
6861
|
return (await this.client.processes.listProcesses()).processes.map((processData) => this.createProcessFromDTO({
|
|
6744
6862
|
id: processData.id,
|
|
6745
6863
|
pid: processData.pid,
|
|
@@ -6751,22 +6869,24 @@ var Sandbox = class Sandbox extends Container {
|
|
|
6751
6869
|
}, session));
|
|
6752
6870
|
}
|
|
6753
6871
|
async getProcess(id, sessionId) {
|
|
6754
|
-
const session =
|
|
6755
|
-
|
|
6756
|
-
|
|
6757
|
-
|
|
6758
|
-
|
|
6759
|
-
|
|
6760
|
-
|
|
6761
|
-
|
|
6762
|
-
|
|
6763
|
-
|
|
6764
|
-
|
|
6765
|
-
|
|
6766
|
-
|
|
6767
|
-
|
|
6768
|
-
|
|
6769
|
-
|
|
6872
|
+
const session = this.getProcessSessionBinding(sessionId);
|
|
6873
|
+
try {
|
|
6874
|
+
const response = await this.client.processes.getProcess(id);
|
|
6875
|
+
if (!response.process) return null;
|
|
6876
|
+
const processData = response.process;
|
|
6877
|
+
return this.createProcessFromDTO({
|
|
6878
|
+
id: processData.id,
|
|
6879
|
+
pid: processData.pid,
|
|
6880
|
+
command: processData.command,
|
|
6881
|
+
status: processData.status,
|
|
6882
|
+
startTime: processData.startTime,
|
|
6883
|
+
endTime: processData.endTime,
|
|
6884
|
+
exitCode: processData.exitCode
|
|
6885
|
+
}, session);
|
|
6886
|
+
} catch (error) {
|
|
6887
|
+
if (error instanceof ProcessNotFoundError) return null;
|
|
6888
|
+
throw error;
|
|
6889
|
+
}
|
|
6770
6890
|
}
|
|
6771
6891
|
async killProcess(id, signal, sessionId) {
|
|
6772
6892
|
await this.client.processes.killProcess(id);
|
|
@@ -6787,23 +6907,29 @@ var Sandbox = class Sandbox extends Container {
|
|
|
6787
6907
|
}
|
|
6788
6908
|
async execStream(command, options) {
|
|
6789
6909
|
if (options?.signal?.aborted) throw new Error("Operation was aborted");
|
|
6790
|
-
const
|
|
6791
|
-
|
|
6792
|
-
|
|
6910
|
+
const context = await this.resolveExecution(options?.sessionId);
|
|
6911
|
+
const session = this.serializeExecutionContext(context);
|
|
6912
|
+
const executionOptions = this.buildExecutionRequestOptions(session, {
|
|
6913
|
+
timeout: options?.timeout,
|
|
6793
6914
|
env: options?.env,
|
|
6794
6915
|
cwd: options?.cwd
|
|
6795
6916
|
});
|
|
6917
|
+
return this.client.commands.executeStream(command, session, executionOptions);
|
|
6918
|
+
}
|
|
6919
|
+
async execStreamWithSessionToken(command, sessionId, options) {
|
|
6920
|
+
this.validateExplicitSessionId(sessionId);
|
|
6921
|
+
return this.execStreamWithSession(command, sessionId, options);
|
|
6796
6922
|
}
|
|
6797
6923
|
/**
|
|
6798
6924
|
* Internal session-aware execStream implementation
|
|
6799
6925
|
*/
|
|
6800
6926
|
async execStreamWithSession(command, sessionId, options) {
|
|
6801
6927
|
if (options?.signal?.aborted) throw new Error("Operation was aborted");
|
|
6802
|
-
return this.client.commands.executeStream(command, sessionId, {
|
|
6803
|
-
|
|
6928
|
+
return this.client.commands.executeStream(command, sessionId, this.buildExecutionRequestOptions(sessionId, {
|
|
6929
|
+
timeout: options?.timeout,
|
|
6804
6930
|
env: options?.env,
|
|
6805
6931
|
cwd: options?.cwd
|
|
6806
|
-
});
|
|
6932
|
+
}));
|
|
6807
6933
|
}
|
|
6808
6934
|
/**
|
|
6809
6935
|
* Stream logs from a background process as a ReadableStream.
|
|
@@ -6813,7 +6939,8 @@ var Sandbox = class Sandbox extends Container {
|
|
|
6813
6939
|
return this.client.processes.streamProcessLogs(processId);
|
|
6814
6940
|
}
|
|
6815
6941
|
async gitCheckout(repoUrl, options) {
|
|
6816
|
-
const
|
|
6942
|
+
const execution = await this.resolveExecution(options?.sessionId);
|
|
6943
|
+
const session = this.serializeExecutionContext(execution);
|
|
6817
6944
|
return this.client.git.checkout(repoUrl, session, {
|
|
6818
6945
|
branch: options?.branch,
|
|
6819
6946
|
targetDir: options?.targetDir,
|
|
@@ -6822,28 +6949,34 @@ var Sandbox = class Sandbox extends Container {
|
|
|
6822
6949
|
});
|
|
6823
6950
|
}
|
|
6824
6951
|
async mkdir(path$1, options = {}) {
|
|
6825
|
-
const
|
|
6952
|
+
const execution = await this.resolveExecution(options.sessionId);
|
|
6953
|
+
const session = this.serializeExecutionContext(execution);
|
|
6826
6954
|
return this.client.files.mkdir(path$1, session, { recursive: options.recursive });
|
|
6827
6955
|
}
|
|
6828
6956
|
async writeFile(path$1, content, options = {}) {
|
|
6829
|
-
const
|
|
6957
|
+
const execution = await this.resolveExecution(options.sessionId);
|
|
6958
|
+
const session = this.serializeExecutionContext(execution);
|
|
6830
6959
|
if (content instanceof ReadableStream) return this.client.files.writeFileStream(path$1, content, session);
|
|
6831
6960
|
return this.client.files.writeFile(path$1, content, session, { encoding: options.encoding });
|
|
6832
6961
|
}
|
|
6833
6962
|
async deleteFile(path$1, sessionId) {
|
|
6834
|
-
const
|
|
6963
|
+
const execution = await this.resolveExecution(sessionId);
|
|
6964
|
+
const session = this.serializeExecutionContext(execution);
|
|
6835
6965
|
return this.client.files.deleteFile(path$1, session);
|
|
6836
6966
|
}
|
|
6837
6967
|
async renameFile(oldPath, newPath, sessionId) {
|
|
6838
|
-
const
|
|
6968
|
+
const execution = await this.resolveExecution(sessionId);
|
|
6969
|
+
const session = this.serializeExecutionContext(execution);
|
|
6839
6970
|
return this.client.files.renameFile(oldPath, newPath, session);
|
|
6840
6971
|
}
|
|
6841
6972
|
async moveFile(sourcePath, destinationPath, sessionId) {
|
|
6842
|
-
const
|
|
6973
|
+
const execution = await this.resolveExecution(sessionId);
|
|
6974
|
+
const session = this.serializeExecutionContext(execution);
|
|
6843
6975
|
return this.client.files.moveFile(sourcePath, destinationPath, session);
|
|
6844
6976
|
}
|
|
6845
6977
|
async readFile(path$1, options = {}) {
|
|
6846
|
-
const
|
|
6978
|
+
const execution = await this.resolveExecution(options.sessionId);
|
|
6979
|
+
const session = this.serializeExecutionContext(execution);
|
|
6847
6980
|
if (options.encoding === "none") return this.client.files.readFile(path$1, session, { encoding: "none" });
|
|
6848
6981
|
return this.client.files.readFile(path$1, session, { encoding: options.encoding });
|
|
6849
6982
|
}
|
|
@@ -6854,15 +6987,18 @@ var Sandbox = class Sandbox extends Container {
|
|
|
6854
6987
|
* @param options - Optional session ID
|
|
6855
6988
|
*/
|
|
6856
6989
|
async readFileStream(path$1, options = {}) {
|
|
6857
|
-
const
|
|
6990
|
+
const execution = await this.resolveExecution(options.sessionId);
|
|
6991
|
+
const session = this.serializeExecutionContext(execution);
|
|
6858
6992
|
return this.client.files.readFileStream(path$1, session);
|
|
6859
6993
|
}
|
|
6860
6994
|
async listFiles(path$1, options) {
|
|
6861
|
-
const
|
|
6995
|
+
const context = await this.resolveExecution(options?.sessionId);
|
|
6996
|
+
const session = this.serializeExecutionContext(context);
|
|
6862
6997
|
return this.client.files.listFiles(path$1, session, options);
|
|
6863
6998
|
}
|
|
6864
6999
|
async exists(path$1, sessionId) {
|
|
6865
|
-
const
|
|
7000
|
+
const execution = await this.resolveExecution(sessionId);
|
|
7001
|
+
const session = this.serializeExecutionContext(execution);
|
|
6866
7002
|
return this.client.files.exists(path$1, session);
|
|
6867
7003
|
}
|
|
6868
7004
|
/**
|
|
@@ -6913,7 +7049,8 @@ var Sandbox = class Sandbox extends Container {
|
|
|
6913
7049
|
* @param options - Watch options
|
|
6914
7050
|
*/
|
|
6915
7051
|
async watch(path$1, options = {}) {
|
|
6916
|
-
const
|
|
7052
|
+
const execution = await this.resolveExecution(options.sessionId);
|
|
7053
|
+
const sessionId = this.serializeExecutionContext(execution);
|
|
6917
7054
|
return this.client.watch.watch({
|
|
6918
7055
|
path: path$1,
|
|
6919
7056
|
recursive: options.recursive,
|
|
@@ -6933,7 +7070,8 @@ var Sandbox = class Sandbox extends Container {
|
|
|
6933
7070
|
* @param options - Change-check options
|
|
6934
7071
|
*/
|
|
6935
7072
|
async checkChanges(path$1, options = {}) {
|
|
6936
|
-
const
|
|
7073
|
+
const execution = await this.resolveExecution(options.sessionId);
|
|
7074
|
+
const sessionId = this.serializeExecutionContext(execution);
|
|
6937
7075
|
return this.client.watch.checkChanges({
|
|
6938
7076
|
path: path$1,
|
|
6939
7077
|
recursive: options.recursive,
|
|
@@ -6995,7 +7133,7 @@ var Sandbox = class Sandbox extends Container {
|
|
|
6995
7133
|
const tokens = await this.readPortTokens();
|
|
6996
7134
|
const existingPort = Object.entries(tokens).find(([p, entry]) => entry.token === token && p !== port.toString());
|
|
6997
7135
|
if (existingPort) throw new SandboxSecurityError(`Token '${token}' is already in use by port ${existingPort[0]}. Please use a different token.`);
|
|
6998
|
-
const sessionId = await this.
|
|
7136
|
+
const sessionId = this.serializeExecutionContext(await this.resolveExecution());
|
|
6999
7137
|
await this.client.ports.exposePort(port, sessionId, options?.name);
|
|
7000
7138
|
tokens[port.toString()] = {
|
|
7001
7139
|
token,
|
|
@@ -7035,7 +7173,7 @@ var Sandbox = class Sandbox extends Container {
|
|
|
7035
7173
|
delete tokens[port.toString()];
|
|
7036
7174
|
await this.ctx.storage.put("portTokens", tokens);
|
|
7037
7175
|
}
|
|
7038
|
-
const sessionId = await this.
|
|
7176
|
+
const sessionId = this.serializeExecutionContext(await this.resolveExecution());
|
|
7039
7177
|
try {
|
|
7040
7178
|
await this.client.ports.unexposePort(port, sessionId);
|
|
7041
7179
|
} catch (error) {
|
|
@@ -7056,7 +7194,7 @@ var Sandbox = class Sandbox extends Container {
|
|
|
7056
7194
|
}
|
|
7057
7195
|
}
|
|
7058
7196
|
async getExposedPorts(hostname) {
|
|
7059
|
-
const sessionId = await this.
|
|
7197
|
+
const sessionId = this.serializeExecutionContext(await this.resolveExecution());
|
|
7060
7198
|
const response = await this.client.ports.getExposedPorts(sessionId);
|
|
7061
7199
|
if (!this.sandboxName) throw new Error("Sandbox name not available. Ensure sandbox is accessed through getSandbox()");
|
|
7062
7200
|
const tokens = await this.readPortTokens();
|
|
@@ -7114,7 +7252,7 @@ var Sandbox = class Sandbox extends Container {
|
|
|
7114
7252
|
}
|
|
7115
7253
|
async isPortExposed(port) {
|
|
7116
7254
|
try {
|
|
7117
|
-
const sessionId = await this.
|
|
7255
|
+
const sessionId = this.serializeExecutionContext(await this.resolveExecution());
|
|
7118
7256
|
return (await this.client.ports.getExposedPorts(sessionId)).ports.some((exposedPort) => exposedPort.port === port);
|
|
7119
7257
|
} catch (error) {
|
|
7120
7258
|
this.logger.error("Error checking if port is exposed", error instanceof Error ? error : new Error(String(error)), { port });
|
|
@@ -7174,6 +7312,7 @@ var Sandbox = class Sandbox extends Container {
|
|
|
7174
7312
|
*/
|
|
7175
7313
|
async createSession(options) {
|
|
7176
7314
|
const sessionId = options?.id || `session-${Date.now()}`;
|
|
7315
|
+
if (sessionId === DISABLE_SESSION_TOKEN) throw new Error(`Session ID '${DISABLE_SESSION_TOKEN}' is reserved for internal use`);
|
|
7177
7316
|
const filteredEnv = filterEnvVars({
|
|
7178
7317
|
...this.envVars,
|
|
7179
7318
|
...options?.env ?? {}
|
|
@@ -8401,4 +8540,4 @@ var Sandbox = class Sandbox extends Container {
|
|
|
8401
8540
|
|
|
8402
8541
|
//#endregion
|
|
8403
8542
|
export { DesktopInvalidOptionsError as A, CommandClient as C, BackupNotFoundError as D, BackupExpiredError as E, InvalidBackupConfigError as F, ProcessExitedBeforeReadyError as I, ProcessReadyTimeoutError as L, DesktopProcessCrashedError as M, DesktopStartFailedError as N, BackupRestoreError as O, DesktopUnavailableError as P, RPCTransportError as R, DesktopClient as S, BackupCreateError as T, UtilityClient as _, BucketMountError as a, GitClient as b, MissingCredentialsError as c, parseSSEStream as d, responseToAsyncIterable as f, SandboxClient as g, streamFile as h, proxyTerminal as i, DesktopNotStartedError as j, DesktopInvalidCoordinatesError as k, S3FSMountError as l, collectFile as m, getSandbox as n, BucketUnmountError as o, CodeInterpreter as p, proxyToSandbox as r, InvalidMountConfigError as s, Sandbox as t, asyncIterableToSSEStream as u, ProcessClient as v, BackupClient as w, FileClient as x, PortClient as y, SessionTerminatedError as z };
|
|
8404
|
-
//# sourceMappingURL=sandbox-
|
|
8543
|
+
//# sourceMappingURL=sandbox-B-MUmsli.js.map
|