UNPKG

e2b

Version:

E2B SDK that give agents cloud environments

1,400 lines (1,378 loc) 65.3 kB
var __defProp = Object.defineProperty; var __defProps = Object.defineProperties; var __getOwnPropDescs = Object.getOwnPropertyDescriptors; var __getOwnPropSymbols = Object.getOwnPropertySymbols; var __hasOwnProp = Object.prototype.hasOwnProperty; var __propIsEnum = Object.prototype.propertyIsEnumerable; var __knownSymbol = (name, symbol) => (symbol = Symbol[name]) ? symbol : Symbol.for("Symbol." + name); var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __spreadValues = (a, b) => { for (var prop in b || (b = {})) if (__hasOwnProp.call(b, prop)) __defNormalProp(a, prop, b[prop]); if (__getOwnPropSymbols) for (var prop of __getOwnPropSymbols(b)) { if (__propIsEnum.call(b, prop)) __defNormalProp(a, prop, b[prop]); } return a; }; var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b)); var __async = (__this, __arguments, generator) => { return new Promise((resolve, reject) => { var fulfilled = (value) => { try { step(generator.next(value)); } catch (e) { reject(e); } }; var rejected = (value) => { try { step(generator.throw(value)); } catch (e) { reject(e); } }; var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected); step((generator = generator.apply(__this, __arguments)).next()); }); }; var __await = function(promise, isYieldStar) { this[0] = promise; this[1] = isYieldStar; }; var __asyncGenerator = (__this, __arguments, generator) => { var resume = (k, v, yes, no) => { try { var x = generator[k](v), isAwait = (v = x.value) instanceof __await, done = x.done; Promise.resolve(isAwait ? v[0] : v).then((y) => isAwait ? resume(k === "return" ? k : "next", v[1] ? { done: y.done, value: y.value } : y, yes, no) : yes({ value: y, done })).catch((e) => resume("throw", e, yes, no)); } catch (e) { no(e); } }, method = (k) => it[k] = (x) => new Promise((yes, no) => resume(k, x, yes, no)), it = {}; return generator = generator.apply(__this, __arguments), it[__knownSymbol("asyncIterator")] = () => it, method("next"), method("throw"), method("return"), it; }; var __forAwait = (obj, it, method) => (it = obj[__knownSymbol("asyncIterator")]) ? it.call(obj) : (obj = obj[__knownSymbol("iterator")](), it = {}, method = (key, fn) => (fn = obj[key]) && (it[key] = (arg) => new Promise((yes, no, done) => (arg = fn.call(obj, arg), done = arg.done, Promise.resolve(arg.value).then((value) => yes({ value, done }), no)))), method("next"), method("return"), it); // src/api/index.ts import createClient from "openapi-fetch"; // src/api/metadata.ts import platform from "platform"; // package.json var version = "1.2.2"; // src/api/metadata.ts function getRuntime() { var _a2, _b, _c; if (globalThis.Bun) { return { runtime: "bun", version: globalThis.Bun.version }; } if (globalThis.Deno) { return { runtime: "deno", version: globalThis.Deno.version.deno }; } if (((_b = (_a2 = globalThis.process) == null ? void 0 : _a2.release) == null ? void 0 : _b.name) === "node") { return { runtime: "node", version: platform.version || "unknown" }; } if (typeof EdgeRuntime === "string") { return { runtime: "vercel-edge", version: "unknown" }; } if (((_c = globalThis.navigator) == null ? void 0 : _c.userAgent) === "Cloudflare-Workers") { return { runtime: "cloudflare-worker", version: "unknown" }; } if (typeof window !== "undefined") { return { runtime: "browser", version: platform.version || "unknown" }; } return { runtime: "unknown", version: "unknown" }; } var { runtime, version: runtimeVersion } = getRuntime(); var _a; var defaultHeaders = { browser: typeof window !== "undefined" && platform.name || "unknown", lang: "js", lang_version: runtimeVersion, package_version: version, publisher: "e2b", sdk_runtime: runtime, system: ((_a = platform.os) == null ? void 0 : _a.family) || "unknown" }; function getEnvVar(name) { if (runtime === "deno") { return Deno.env.get(name); } if (typeof process === "undefined") { return ""; } return process.env[name]; } // src/errors.ts function formatSandboxTimeoutError(message) { return new TimeoutError( `${message}: This error is likely due to sandbox timeout. You can modify the sandbox timeout by passing 'timeoutMs' when starting the sandbox or calling '.setTimeout' on the sandbox with the desired timeout.` ); } var SandboxError = class extends Error { constructor(message) { super(message); this.name = "SandboxError"; } }; var TimeoutError = class extends SandboxError { constructor(message) { super(message); this.name = "TimeoutError"; } }; var InvalidArgumentError = class extends SandboxError { constructor(message) { super(message); this.name = "InvalidArgumentError"; } }; var NotEnoughSpaceError = class extends SandboxError { constructor(message) { super(message); this.name = "NotEnoughSpaceError"; } }; var NotFoundError = class extends SandboxError { constructor(message) { super(message); this.name = "NotFoundError"; } }; var AuthenticationError = class extends SandboxError { constructor(message) { super(message); this.name = "AuthenticationError"; } }; var TemplateError = class extends SandboxError { constructor(message) { super(message); this.name = "TemplateError"; } }; var RateLimitError = class extends SandboxError { constructor(message) { super(message); this.name = "RateLimitError"; } }; // src/logs.ts function formatLog(log) { return JSON.parse(JSON.stringify(log)); } function createRpcLogger(logger) { function logEach(stream) { return __asyncGenerator(this, null, function* () { var _a2; try { for (var iter = __forAwait(stream), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) { const m = temp.value; (_a2 = logger.debug) == null ? void 0 : _a2.call(logger, "Response stream:", formatLog(m)); yield m; } } catch (temp) { error = [temp]; } finally { try { more && (temp = iter.return) && (yield new __await(temp.call(iter))); } finally { if (error) throw error[0]; } } }); } return (next) => (req) => __async(this, null, function* () { var _a2, _b; (_a2 = logger.info) == null ? void 0 : _a2.call(logger, `Request: POST ${req.url}`); const res = yield next(req); if (res.stream) { return __spreadProps(__spreadValues({}, res), { message: logEach(res.message) }); } else { (_b = logger.info) == null ? void 0 : _b.call(logger, "Response:", formatLog(res.message)); } return res; }); } function createApiLogger(logger) { return { onRequest(req) { return __async(this, null, function* () { var _a3; (_a3 = logger.info) == null ? void 0 : _a3.call(logger, `Request ${req.method} ${req.url}`); return req; }); }, onResponse(res) { return __async(this, null, function* () { var _a3, _b; if (res.status >= 400) { (_a3 = logger.error) == null ? void 0 : _a3.call(logger, "Response:", res.status, res.statusText); } else { (_b = logger.info) == null ? void 0 : _b.call(logger, "Response:", res.status, res.statusText); } return res; }); } }; } // src/api/index.ts function handleApiError(response) { var _a2, _b; if (!response.error) { return; } if (response.response.status === 429) { return new RateLimitError("Rate limit exceeded, please try again later."); } const message = (_b = (_a2 = response.error) == null ? void 0 : _a2.message) != null ? _b : response.error; return new SandboxError(`${response.response.status}: ${message}`); } var ApiClient = class { constructor(config, opts = { requireAccessToken: false, requireApiKey: true }) { if (!(opts == null ? void 0 : opts.requireApiKey) && !config.apiKey) { throw new AuthenticationError( "API key is required, please visit the Team tab at https://e2b.dev/dashboard to get your API key. You can either set the environment variable `E2B_API_KEY` or you can pass it directly to the sandbox like Sandbox.create({ apiKey: 'e2b_...' })" ); } if ((opts == null ? void 0 : opts.requireAccessToken) && !config.accessToken) { throw new AuthenticationError( "Access token is required, please visit the Personal tab at https://e2b.dev/dashboard to get your access token. You can set the environment variable `E2B_ACCESS_TOKEN` or pass the `accessToken` in options." ); } this.api = createClient({ baseUrl: config.apiUrl, // keepalive: true, // TODO: Return keepalive headers: __spreadValues(__spreadValues(__spreadValues(__spreadValues({}, defaultHeaders), config.apiKey && { "X-API-KEY": config.apiKey }), config.accessToken && { Authorization: `Bearer ${config.accessToken}` }), config.headers) }); if (config.logger) { this.api.use(createApiLogger(config.logger)); } } }; // src/connectionConfig.ts var REQUEST_TIMEOUT_MS = 3e4; var KEEPALIVE_PING_INTERVAL_SEC = 50; var KEEPALIVE_PING_HEADER = "Keepalive-Ping-Interval"; var ConnectionConfig = class _ConnectionConfig { constructor(opts) { var _a2; this.apiKey = (opts == null ? void 0 : opts.apiKey) || _ConnectionConfig.apiKey; this.debug = (opts == null ? void 0 : opts.debug) || _ConnectionConfig.debug; this.domain = (opts == null ? void 0 : opts.domain) || _ConnectionConfig.domain; this.accessToken = (opts == null ? void 0 : opts.accessToken) || _ConnectionConfig.accessToken; this.requestTimeoutMs = (_a2 = opts == null ? void 0 : opts.requestTimeoutMs) != null ? _a2 : REQUEST_TIMEOUT_MS; this.logger = opts == null ? void 0 : opts.logger; this.headers = opts == null ? void 0 : opts.headers; this.apiUrl = this.debug ? "http://localhost:3000" : `https://api.${this.domain}`; } static get domain() { return getEnvVar("E2B_DOMAIN") || "e2b.app"; } static get debug() { return (getEnvVar("E2B_DEBUG") || "false").toLowerCase() === "true"; } static get apiKey() { return getEnvVar("E2B_API_KEY"); } static get accessToken() { return getEnvVar("E2B_ACCESS_TOKEN"); } getSignal(requestTimeoutMs) { const timeout = requestTimeoutMs != null ? requestTimeoutMs : this.requestTimeoutMs; return timeout ? AbortSignal.timeout(timeout) : void 0; } }; var defaultUsername = "user"; // src/sandbox/filesystem/index.ts import { createClient as createClient3, ConnectError as ConnectError3, Code as Code3 } from "@connectrpc/connect"; // src/envd/api.ts import createClient2 from "openapi-fetch"; import { Code, ConnectError } from "@connectrpc/connect"; function handleEnvdApiError(res) { return __async(this, null, function* () { var _a2; if (!res.error) { return; } const message = typeof res.error == "string" ? res.error : ((_a2 = res.error) == null ? void 0 : _a2.message) || (yield res.response.text()); switch (res.response.status) { case 400: return new InvalidArgumentError(message); case 401: return new AuthenticationError(message); case 404: return new NotFoundError(message); case 429: return new SandboxError( `${res.response.status}: ${message}: The requests are being rate limited.` ); case 502: return formatSandboxTimeoutError(message); case 507: return new NotEnoughSpaceError(message); default: return new SandboxError(`${res.response.status}: ${message}`); } }); } function handleProcessStartEvent(events) { return __async(this, null, function* () { var _a2; let startEvent; try { startEvent = (yield events[Symbol.asyncIterator]().next()).value; } catch (err) { if (err instanceof ConnectError) { if (err.code === Code.Unavailable) { throw new NotFoundError("Sandbox is probably not running anymore"); } } throw err; } if (((_a2 = startEvent.event) == null ? void 0 : _a2.event.case) !== "start") { throw new Error("Expected start event"); } return startEvent.event.event.value.pid; }); } function handleWatchDirStartEvent(events) { return __async(this, null, function* () { var _a2; let startEvent; try { startEvent = (yield events[Symbol.asyncIterator]().next()).value; } catch (err) { if (err instanceof ConnectError) { if (err.code === Code.Unavailable) { throw new NotFoundError("Sandbox is probably not running anymore"); } } throw err; } if (((_a2 = startEvent.event) == null ? void 0 : _a2.case) !== "start") { throw new Error("Expected start event"); } return startEvent.event.value; }); } var EnvdApiClient = class { constructor(config, metadata) { this.api = createClient2({ baseUrl: config.apiUrl // keepalive: true, // TODO: Return keepalive }); this.version = metadata.version; if (config.logger) { this.api.use(createApiLogger(config.logger)); } } }; // src/envd/rpc.ts import { Code as Code2, ConnectError as ConnectError2 } from "@connectrpc/connect"; function handleRpcError(err) { if (err instanceof ConnectError2) { switch (err.code) { case Code2.InvalidArgument: return new InvalidArgumentError(err.message); case Code2.Unauthenticated: return new AuthenticationError(err.message); case Code2.NotFound: return new NotFoundError(err.message); case Code2.Unavailable: return formatSandboxTimeoutError(err.message); case Code2.Canceled: return new TimeoutError( `${err.message}: This error is likely due to exceeding 'requestTimeoutMs'. You can pass the request timeout value as an option when making the request.` ); case Code2.DeadlineExceeded: return new TimeoutError( `${err.message}: This error is likely due to exceeding 'timeoutMs' \u2014 the total time a long running request (like command execution or directory watch) can be active. It can be modified by passing 'timeoutMs' when making the request. Use '0' to disable the timeout.` ); default: return new SandboxError(`${err.code}: ${err.message}`); } } return err; } function encode64(value) { switch (runtime) { case "deno": return btoa(value); case "node": return Buffer.from(value).toString("base64"); case "bun": return Buffer.from(value).toString("base64"); default: return btoa(value); } } function authenticationHeader(username) { const value = `${username || defaultUsername}:`; const encoded = encode64(value); return { "Authorization": `Basic ${encoded}` }; } // src/envd/filesystem/filesystem_pb.ts import { enumDesc, fileDesc, messageDesc, serviceDesc } from "@bufbuild/protobuf/codegenv1"; var file_filesystem_filesystem = /* @__PURE__ */ fileDesc("ChtmaWxlc3lzdGVtL2ZpbGVzeXN0ZW0ucHJvdG8SCmZpbGVzeXN0ZW0iMgoLTW92ZVJlcXVlc3QSDgoGc291cmNlGAEgASgJEhMKC2Rlc3RpbmF0aW9uGAIgASgJIjQKDE1vdmVSZXNwb25zZRIkCgVlbnRyeRgBIAEoCzIVLmZpbGVzeXN0ZW0uRW50cnlJbmZvIh4KDk1ha2VEaXJSZXF1ZXN0EgwKBHBhdGgYASABKAkiNwoPTWFrZURpclJlc3BvbnNlEiQKBWVudHJ5GAEgASgLMhUuZmlsZXN5c3RlbS5FbnRyeUluZm8iHQoNUmVtb3ZlUmVxdWVzdBIMCgRwYXRoGAEgASgJIhAKDlJlbW92ZVJlc3BvbnNlIhsKC1N0YXRSZXF1ZXN0EgwKBHBhdGgYASABKAkiNAoMU3RhdFJlc3BvbnNlEiQKBWVudHJ5GAEgASgLMhUuZmlsZXN5c3RlbS5FbnRyeUluZm8iSwoJRW50cnlJbmZvEgwKBG5hbWUYASABKAkSIgoEdHlwZRgCIAEoDjIULmZpbGVzeXN0ZW0uRmlsZVR5cGUSDAoEcGF0aBgDIAEoCSIeCg5MaXN0RGlyUmVxdWVzdBIMCgRwYXRoGAEgASgJIjkKD0xpc3REaXJSZXNwb25zZRImCgdlbnRyaWVzGAEgAygLMhUuZmlsZXN5c3RlbS5FbnRyeUluZm8iMgoPV2F0Y2hEaXJSZXF1ZXN0EgwKBHBhdGgYASABKAkSEQoJcmVjdXJzaXZlGAIgASgIIkQKD0ZpbGVzeXN0ZW1FdmVudBIMCgRuYW1lGAEgASgJEiMKBHR5cGUYAiABKA4yFS5maWxlc3lzdGVtLkV2ZW50VHlwZSLgAQoQV2F0Y2hEaXJSZXNwb25zZRI4CgVzdGFydBgBIAEoCzInLmZpbGVzeXN0ZW0uV2F0Y2hEaXJSZXNwb25zZS5TdGFydEV2ZW50SAASMQoKZmlsZXN5c3RlbRgCIAEoCzIbLmZpbGVzeXN0ZW0uRmlsZXN5c3RlbUV2ZW50SAASOwoJa2VlcGFsaXZlGAMgASgLMiYuZmlsZXN5c3RlbS5XYXRjaERpclJlc3BvbnNlLktlZXBBbGl2ZUgAGgwKClN0YXJ0RXZlbnQaCwoJS2VlcEFsaXZlQgcKBWV2ZW50IjcKFENyZWF0ZVdhdGNoZXJSZXF1ZXN0EgwKBHBhdGgYASABKAkSEQoJcmVjdXJzaXZlGAIgASgIIisKFUNyZWF0ZVdhdGNoZXJSZXNwb25zZRISCgp3YXRjaGVyX2lkGAEgASgJIi0KF0dldFdhdGNoZXJFdmVudHNSZXF1ZXN0EhIKCndhdGNoZXJfaWQYASABKAkiRwoYR2V0V2F0Y2hlckV2ZW50c1Jlc3BvbnNlEisKBmV2ZW50cxgBIAMoCzIbLmZpbGVzeXN0ZW0uRmlsZXN5c3RlbUV2ZW50IioKFFJlbW92ZVdhdGNoZXJSZXF1ZXN0EhIKCndhdGNoZXJfaWQYASABKAkiFwoVUmVtb3ZlV2F0Y2hlclJlc3BvbnNlKlIKCEZpbGVUeXBlEhkKFUZJTEVfVFlQRV9VTlNQRUNJRklFRBAAEhIKDkZJTEVfVFlQRV9GSUxFEAESFwoTRklMRV9UWVBFX0RJUkVDVE9SWRACKpgBCglFdmVudFR5cGUSGgoWRVZFTlRfVFlQRV9VTlNQRUNJRklFRBAAEhUKEUVWRU5UX1RZUEVfQ1JFQVRFEAESFAoQRVZFTlRfVFlQRV9XUklURRACEhUKEUVWRU5UX1RZUEVfUkVNT1ZFEAMSFQoRRVZFTlRfVFlQRV9SRU5BTUUQBBIUChBFVkVOVF9UWVBFX0NITU9EEAUynwUKCkZpbGVzeXN0ZW0SOQoEU3RhdBIXLmZpbGVzeXN0ZW0uU3RhdFJlcXVlc3QaGC5maWxlc3lzdGVtLlN0YXRSZXNwb25zZRJCCgdNYWtlRGlyEhouZmlsZXN5c3RlbS5NYWtlRGlyUmVxdWVzdBobLmZpbGVzeXN0ZW0uTWFrZURpclJlc3BvbnNlEjkKBE1vdmUSFy5maWxlc3lzdGVtLk1vdmVSZXF1ZXN0GhguZmlsZXN5c3RlbS5Nb3ZlUmVzcG9uc2USQgoHTGlzdERpchIaLmZpbGVzeXN0ZW0uTGlzdERpclJlcXVlc3QaGy5maWxlc3lzdGVtLkxpc3REaXJSZXNwb25zZRI/CgZSZW1vdmUSGS5maWxlc3lzdGVtLlJlbW92ZVJlcXVlc3QaGi5maWxlc3lzdGVtLlJlbW92ZVJlc3BvbnNlEkcKCFdhdGNoRGlyEhsuZmlsZXN5c3RlbS5XYXRjaERpclJlcXVlc3QaHC5maWxlc3lzdGVtLldhdGNoRGlyUmVzcG9uc2UwARJUCg1DcmVhdGVXYXRjaGVyEiAuZmlsZXN5c3RlbS5DcmVhdGVXYXRjaGVyUmVxdWVzdBohLmZpbGVzeXN0ZW0uQ3JlYXRlV2F0Y2hlclJlc3BvbnNlEl0KEEdldFdhdGNoZXJFdmVudHMSIy5maWxlc3lzdGVtLkdldFdhdGNoZXJFdmVudHNSZXF1ZXN0GiQuZmlsZXN5c3RlbS5HZXRXYXRjaGVyRXZlbnRzUmVzcG9uc2USVAoNUmVtb3ZlV2F0Y2hlchIgLmZpbGVzeXN0ZW0uUmVtb3ZlV2F0Y2hlclJlcXVlc3QaIS5maWxlc3lzdGVtLlJlbW92ZVdhdGNoZXJSZXNwb25zZUJpCg5jb20uZmlsZXN5c3RlbUIPRmlsZXN5c3RlbVByb3RvUAGiAgNGWFiqAgpGaWxlc3lzdGVtygIKRmlsZXN5c3RlbeICFkZpbGVzeXN0ZW1cR1BCTWV0YWRhdGHqAgpGaWxlc3lzdGVtYgZwcm90bzM"); var Filesystem = /* @__PURE__ */ serviceDesc(file_filesystem_filesystem, 0); // src/sandbox/filesystem/watchHandle.ts var FilesystemEventType = /* @__PURE__ */ ((FilesystemEventType2) => { FilesystemEventType2["CHMOD"] = "chmod"; FilesystemEventType2["CREATE"] = "create"; FilesystemEventType2["REMOVE"] = "remove"; FilesystemEventType2["RENAME"] = "rename"; FilesystemEventType2["WRITE"] = "write"; return FilesystemEventType2; })(FilesystemEventType || {}); function mapEventType(type) { switch (type) { case 5 /* CHMOD */: return "chmod" /* CHMOD */; case 1 /* CREATE */: return "create" /* CREATE */; case 3 /* REMOVE */: return "remove" /* REMOVE */; case 4 /* RENAME */: return "rename" /* RENAME */; case 2 /* WRITE */: return "write" /* WRITE */; } } var WatchHandle = class { constructor(handleStop, events, onEvent, onExit) { this.handleStop = handleStop; this.events = events; this.onEvent = onEvent; this.onExit = onExit; this.handleEvents(); } /** * Stop watching the directory. */ stop() { return __async(this, null, function* () { this.handleStop(); }); } iterateEvents() { return __asyncGenerator(this, null, function* () { try { try { for (var iter = __forAwait(this.events), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) { const event = temp.value; switch (event.event.case) { case "filesystem": yield event.event; break; } } } catch (temp) { error = [temp]; } finally { try { more && (temp = iter.return) && (yield new __await(temp.call(iter))); } finally { if (error) throw error[0]; } } } catch (err) { throw handleRpcError(err); } }); } handleEvents() { return __async(this, null, function* () { var _a2, _b, _c; try { try { for (var iter = __forAwait(this.iterateEvents()), more, temp, error; more = !(temp = yield iter.next()).done; more = false) { const event = temp.value; const eventType = mapEventType(event.value.type); if (eventType === void 0) { continue; } (_a2 = this.onEvent) == null ? void 0 : _a2.call(this, { name: event.value.name, type: eventType }); } } catch (temp) { error = [temp]; } finally { try { more && (temp = iter.return) && (yield temp.call(iter)); } finally { if (error) throw error[0]; } } (_b = this.onExit) == null ? void 0 : _b.call(this); } catch (err) { (_c = this.onExit) == null ? void 0 : _c.call(this, err); } }); } }; // src/sandbox/filesystem/index.ts import { compareVersions } from "compare-versions"; // src/envd/versions.ts var ENVD_VERSION_RECURSIVE_WATCH = "0.1.4"; // src/sandbox/filesystem/index.ts var FileType2 = /* @__PURE__ */ ((FileType3) => { FileType3["FILE"] = "file"; FileType3["DIR"] = "dir"; return FileType3; })(FileType2 || {}); function mapFileType(fileType) { switch (fileType) { case 2 /* DIRECTORY */: return "dir" /* DIR */; case 1 /* FILE */: return "file" /* FILE */; } } var Filesystem2 = class { constructor(transport, envdApi, connectionConfig) { this.envdApi = envdApi; this.connectionConfig = connectionConfig; this.defaultWatchTimeout = 6e4; // 60 seconds this.defaultWatchRecursive = false; this.rpc = createClient3(Filesystem, transport); } read(path, opts) { return __async(this, null, function* () { var _a2; const format = (_a2 = opts == null ? void 0 : opts.format) != null ? _a2 : "text"; const res = yield this.envdApi.api.GET("/files", { params: { query: { path, username: (opts == null ? void 0 : opts.user) || defaultUsername } }, parseAs: format === "bytes" ? "arrayBuffer" : format, signal: this.connectionConfig.getSignal(opts == null ? void 0 : opts.requestTimeoutMs) }); const err = yield handleEnvdApiError(res); if (err) { throw err; } if (format === "bytes") { return new Uint8Array(res.data); } if (res.response.headers.get("content-length") === "0") { return ""; } return res.data; }); } write(pathOrFiles, dataOrOpts, opts) { return __async(this, null, function* () { if (typeof pathOrFiles !== "string" && !Array.isArray(pathOrFiles)) { throw new Error("Path or files are required"); } if (typeof pathOrFiles === "string" && Array.isArray(dataOrOpts)) { throw new Error( "Cannot specify both path and array of files. You have to specify either path and data for a single file or an array for multiple files." ); } const { path, writeOpts, writeFiles } = typeof pathOrFiles === "string" ? { path: pathOrFiles, writeOpts: opts, writeFiles: [ { data: dataOrOpts } ] } : { path: void 0, writeOpts: dataOrOpts, writeFiles: pathOrFiles }; if (writeFiles.length === 0) return []; const blobs = yield Promise.all( writeFiles.map((f) => new Response(f.data).blob()) ); const res = yield this.envdApi.api.POST("/files", { params: { query: { path, username: (writeOpts == null ? void 0 : writeOpts.user) || defaultUsername } }, bodySerializer() { return blobs.reduce((fd, blob, i) => { fd.append("file", blob, writeFiles[i].path); return fd; }, new FormData()); }, body: {}, headers: { "Content-Type": "multipart/form-data", "Bun-Content-Type": "temporary-fix" // https://github.com/oven-sh/bun/issues/14988 } }); const err = yield handleEnvdApiError(res); if (err) { throw err; } const files = res.data; if (!files) { throw new Error("Expected to receive information about written file"); } return files.length === 1 && path ? files[0] : files; }); } /** * List entries in a directory. * * @param path path to the directory. * @param opts connection options. * * @returns list of entries in the sandbox filesystem directory. */ list(path, opts) { return __async(this, null, function* () { try { const res = yield this.rpc.listDir( { path }, { headers: authenticationHeader(opts == null ? void 0 : opts.user), signal: this.connectionConfig.getSignal(opts == null ? void 0 : opts.requestTimeoutMs) } ); const entries = []; for (const e of res.entries) { const type = mapFileType(e.type); if (type) { entries.push({ name: e.name, type, path: e.path }); } } return entries; } catch (err) { throw handleRpcError(err); } }); } /** * Create a new directory and all directories along the way if needed on the specified path. * * @param path path to a new directory. For example '/dirA/dirB' when creating 'dirB'. * @param opts connection options. * * @returns `true` if the directory was created, `false` if it already exists. */ makeDir(path, opts) { return __async(this, null, function* () { try { yield this.rpc.makeDir( { path }, { headers: authenticationHeader(opts == null ? void 0 : opts.user), signal: this.connectionConfig.getSignal(opts == null ? void 0 : opts.requestTimeoutMs) } ); return true; } catch (err) { if (err instanceof ConnectError3) { if (err.code === Code3.AlreadyExists) { return false; } } throw handleRpcError(err); } }); } /** * Rename a file or directory. * * @param oldPath path to the file or directory to rename. * @param newPath new path for the file or directory. * @param opts connection options. * * @returns information about renamed file or directory. */ rename(oldPath, newPath, opts) { return __async(this, null, function* () { try { const res = yield this.rpc.move( { source: oldPath, destination: newPath }, { headers: authenticationHeader(opts == null ? void 0 : opts.user), signal: this.connectionConfig.getSignal(opts == null ? void 0 : opts.requestTimeoutMs) } ); const entry = res.entry; if (!entry) { throw new Error("Expected to receive information about moved object"); } return { name: entry.name, type: mapFileType(entry.type), path: entry.path }; } catch (err) { throw handleRpcError(err); } }); } /** * Remove a file or directory. * * @param path path to a file or directory. * @param opts connection options. */ remove(path, opts) { return __async(this, null, function* () { try { yield this.rpc.remove( { path }, { headers: authenticationHeader(opts == null ? void 0 : opts.user), signal: this.connectionConfig.getSignal(opts == null ? void 0 : opts.requestTimeoutMs) } ); } catch (err) { throw handleRpcError(err); } }); } /** * Check if a file or a directory exists. * * @param path path to a file or a directory * @param opts connection options. * * @returns `true` if the file or directory exists, `false` otherwise */ exists(path, opts) { return __async(this, null, function* () { try { yield this.rpc.stat( { path }, { headers: authenticationHeader(opts == null ? void 0 : opts.user), signal: this.connectionConfig.getSignal(opts == null ? void 0 : opts.requestTimeoutMs) } ); return true; } catch (err) { if (err instanceof ConnectError3) { if (err.code === Code3.NotFound) { return false; } } throw handleRpcError(err); } }); } /** * Start watching a directory for filesystem events. * * @param path path to directory to watch. * @param onEvent callback to call when an event in the directory occurs. * @param opts connection options. * * @returns `WatchHandle` object for stopping watching directory. */ watchDir(path, onEvent, opts) { return __async(this, null, function* () { var _a2, _b, _c; if ((opts == null ? void 0 : opts.recursive) && this.envdApi.version && compareVersions(this.envdApi.version, ENVD_VERSION_RECURSIVE_WATCH) < 0) { throw new TemplateError( "You need to update the template to use recursive watching. You can do this by running `e2b template build` in the directory with the template." ); } const requestTimeoutMs = (_a2 = opts == null ? void 0 : opts.requestTimeoutMs) != null ? _a2 : this.connectionConfig.requestTimeoutMs; const controller = new AbortController(); const reqTimeout = requestTimeoutMs ? setTimeout(() => { controller.abort(); }, requestTimeoutMs) : void 0; const events = this.rpc.watchDir( { path, recursive: (_b = opts == null ? void 0 : opts.recursive) != null ? _b : this.defaultWatchRecursive }, { headers: __spreadProps(__spreadValues({}, authenticationHeader(opts == null ? void 0 : opts.user)), { [KEEPALIVE_PING_HEADER]: KEEPALIVE_PING_INTERVAL_SEC.toString() }), signal: controller.signal, timeoutMs: (_c = opts == null ? void 0 : opts.timeoutMs) != null ? _c : this.defaultWatchTimeout } ); try { yield handleWatchDirStartEvent(events); clearTimeout(reqTimeout); return new WatchHandle( () => controller.abort(), events, onEvent, opts == null ? void 0 : opts.onExit ); } catch (err) { throw handleRpcError(err); } }); } }; // src/sandbox/commands/commandHandle.ts var CommandExitError = class extends SandboxError { constructor(result) { super(result.error); this.result = result; this.name = "CommandExitError"; } /** * Command execution exit code. * `0` if the command finished successfully. */ get exitCode() { return this.result.exitCode; } /** * Error message from command execution. */ get error() { return this.result.error; } /** * Command execution stdout output. */ get stdout() { return this.result.stdout; } /** * Command execution stderr output. */ get stderr() { return this.result.stderr; } }; var CommandHandle = class { /** * @hidden * @internal * @access protected */ constructor(pid, handleDisconnect, handleKill, events, onStdout, onStderr, onPty) { this.pid = pid; this.handleDisconnect = handleDisconnect; this.handleKill = handleKill; this.events = events; this.onStdout = onStdout; this.onStderr = onStderr; this.onPty = onPty; this._stdout = ""; this._stderr = ""; this._wait = this.handleEvents(); } /** * Command execution exit code. * `0` if the command finished successfully. * * It is `undefined` if the command is still running. */ get exitCode() { var _a2; return (_a2 = this.result) == null ? void 0 : _a2.exitCode; } /** * Error message from command execution. */ get error() { var _a2; return (_a2 = this.result) == null ? void 0 : _a2.error; } /** * Command execution stderr output. */ get stderr() { return this._stderr; } /** * Command execution stdout output. */ get stdout() { return this._stdout; } /** * Wait for the command to finish and return the result. * If the command exits with a non-zero exit code, it throws a `CommandExitError`. * * @returns `CommandResult` result of command execution. */ wait() { return __async(this, null, function* () { yield this._wait; if (this.iterationError) { throw this.iterationError; } if (!this.result) { throw new SandboxError("Process exited without a result"); } if (this.result.exitCode !== 0) { throw new CommandExitError(this.result); } return this.result; }); } /** * Disconnect from the command. * * The command is not killed, but SDK stops receiving events from the command. * You can reconnect to the command using {@link Commands.connect}. */ disconnect() { return __async(this, null, function* () { this.handleDisconnect(); }); } /** * Kill the command. * It uses `SIGKILL` signal to kill the command. * * @returns `true` if the command was killed successfully, `false` if the command was not found. */ kill() { return __async(this, null, function* () { return yield this.handleKill(); }); } iterateEvents() { return __asyncGenerator(this, null, function* () { var _a2; try { for (var iter = __forAwait(this.events), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) { const event = temp.value; const e = (_a2 = event == null ? void 0 : event.event) == null ? void 0 : _a2.event; let out; switch (e == null ? void 0 : e.case) { case "data": switch (e.value.output.case) { case "stdout": out = new TextDecoder().decode(e.value.output.value); this._stdout += out; yield [out, null, null]; break; case "stderr": out = new TextDecoder().decode(e.value.output.value); this._stderr += out; yield [null, out, null]; break; case "pty": yield [null, null, e.value.output.value]; break; } break; case "end": this.result = { exitCode: e.value.exitCode, error: e.value.error, stdout: this.stdout, stderr: this.stderr }; break; } } } catch (temp) { error = [temp]; } finally { try { more && (temp = iter.return) && (yield new __await(temp.call(iter))); } finally { if (error) throw error[0]; } } }); } handleEvents() { return __async(this, null, function* () { var _a2, _b, _c; try { try { for (var iter = __forAwait(this.iterateEvents()), more, temp, error; more = !(temp = yield iter.next()).done; more = false) { const [stdout, stderr, pty] = temp.value; if (stdout !== null) { (_a2 = this.onStdout) == null ? void 0 : _a2.call(this, stdout); } else if (stderr !== null) { (_b = this.onStderr) == null ? void 0 : _b.call(this, stderr); } else if (pty) { (_c = this.onPty) == null ? void 0 : _c.call(this, pty); } } } catch (temp) { error = [temp]; } finally { try { more && (temp = iter.return) && (yield temp.call(iter)); } finally { if (error) throw error[0]; } } } catch (e) { this.iterationError = handleRpcError(e); } }); } }; // src/sandbox/index.ts import { createConnectTransport } from "@connectrpc/connect-web"; // src/sandbox/commands/index.ts import { Code as Code5, ConnectError as ConnectError5, createClient as createClient5 } from "@connectrpc/connect"; // src/envd/process/process_pb.ts import { enumDesc as enumDesc2, fileDesc as fileDesc2, messageDesc as messageDesc2, serviceDesc as serviceDesc2 } from "@bufbuild/protobuf/codegenv1"; var file_process_process = /* @__PURE__ */ fileDesc2("ChVwcm9jZXNzL3Byb2Nlc3MucHJvdG8SB3Byb2Nlc3MiSgoDUFRZEh8KBHNpemUYASABKAsyES5wcm9jZXNzLlBUWS5TaXplGiIKBFNpemUSDAoEY29scxgBIAEoDRIMCgRyb3dzGAIgASgNIqEBCg1Qcm9jZXNzQ29uZmlnEgsKA2NtZBgBIAEoCRIMCgRhcmdzGAIgAygJEi4KBGVudnMYAyADKAsyIC5wcm9jZXNzLlByb2Nlc3NDb25maWcuRW52c0VudHJ5EhAKA2N3ZBgEIAEoCUgAiAEBGisKCUVudnNFbnRyeRILCgNrZXkYASABKAkSDQoFdmFsdWUYAiABKAk6AjgBQgYKBF9jd2QiDQoLTGlzdFJlcXVlc3QiXAoLUHJvY2Vzc0luZm8SJgoGY29uZmlnGAEgASgLMhYucHJvY2Vzcy5Qcm9jZXNzQ29uZmlnEgsKA3BpZBgCIAEoDRIQCgN0YWcYAyABKAlIAIgBAUIGCgRfdGFnIjcKDExpc3RSZXNwb25zZRInCglwcm9jZXNzZXMYASADKAsyFC5wcm9jZXNzLlByb2Nlc3NJbmZvInkKDFN0YXJ0UmVxdWVzdBInCgdwcm9jZXNzGAEgASgLMhYucHJvY2Vzcy5Qcm9jZXNzQ29uZmlnEh4KA3B0eRgCIAEoCzIMLnByb2Nlc3MuUFRZSACIAQESEAoDdGFnGAMgASgJSAGIAQFCBgoEX3B0eUIGCgRfdGFnImIKDVVwZGF0ZVJlcXVlc3QSKQoHcHJvY2VzcxgBIAEoCzIYLnByb2Nlc3MuUHJvY2Vzc1NlbGVjdG9yEh4KA3B0eRgCIAEoCzIMLnByb2Nlc3MuUFRZSACIAQFCBgoEX3B0eSIQCg5VcGRhdGVSZXNwb25zZSKvAwoMUHJvY2Vzc0V2ZW50EjEKBXN0YXJ0GAEgASgLMiAucHJvY2Vzcy5Qcm9jZXNzRXZlbnQuU3RhcnRFdmVudEgAEi8KBGRhdGEYAiABKAsyHy5wcm9jZXNzLlByb2Nlc3NFdmVudC5EYXRhRXZlbnRIABItCgNlbmQYAyABKAsyHi5wcm9jZXNzLlByb2Nlc3NFdmVudC5FbmRFdmVudEgAEjQKCWtlZXBhbGl2ZRgEIAEoCzIfLnByb2Nlc3MuUHJvY2Vzc0V2ZW50LktlZXBBbGl2ZUgAGhkKClN0YXJ0RXZlbnQSCwoDcGlkGAEgASgNGkgKCURhdGFFdmVudBIQCgZzdGRvdXQYASABKAxIABIQCgZzdGRlcnIYAiABKAxIABINCgNwdHkYAyABKAxIAEIICgZvdXRwdXQaWwoIRW5kRXZlbnQSEQoJZXhpdF9jb2RlGAEgASgREg4KBmV4aXRlZBgCIAEoCBIOCgZzdGF0dXMYAyABKAkSEgoFZXJyb3IYBCABKAlIAIgBAUIICgZfZXJyb3IaCwoJS2VlcEFsaXZlQgcKBWV2ZW50IjUKDVN0YXJ0UmVzcG9uc2USJAoFZXZlbnQYASABKAsyFS5wcm9jZXNzLlByb2Nlc3NFdmVudCI3Cg9Db25uZWN0UmVzcG9uc2USJAoFZXZlbnQYASABKAsyFS5wcm9jZXNzLlByb2Nlc3NFdmVudCJjChBTZW5kSW5wdXRSZXF1ZXN0EikKB3Byb2Nlc3MYASABKAsyGC5wcm9jZXNzLlByb2Nlc3NTZWxlY3RvchIkCgVpbnB1dBgCIAEoCzIVLnByb2Nlc3MuUHJvY2Vzc0lucHV0IhMKEVNlbmRJbnB1dFJlc3BvbnNlIjcKDFByb2Nlc3NJbnB1dBIPCgVzdGRpbhgBIAEoDEgAEg0KA3B0eRgCIAEoDEgAQgcKBWlucHV0IsICChJTdHJlYW1JbnB1dFJlcXVlc3QSNwoFc3RhcnQYASABKAsyJi5wcm9jZXNzLlN0cmVhbUlucHV0UmVxdWVzdC5TdGFydEV2ZW50SAASNQoEZGF0YRgCIAEoCzIlLnByb2Nlc3MuU3RyZWFtSW5wdXRSZXF1ZXN0LkRhdGFFdmVudEgAEjoKCWtlZXBhbGl2ZRgDIAEoCzIlLnByb2Nlc3MuU3RyZWFtSW5wdXRSZXF1ZXN0LktlZXBBbGl2ZUgAGjcKClN0YXJ0RXZlbnQSKQoHcHJvY2VzcxgBIAEoCzIYLnByb2Nlc3MuUHJvY2Vzc1NlbGVjdG9yGjEKCURhdGFFdmVudBIkCgVpbnB1dBgCIAEoCzIVLnByb2Nlc3MuUHJvY2Vzc0lucHV0GgsKCUtlZXBBbGl2ZUIHCgVldmVudCIVChNTdHJlYW1JbnB1dFJlc3BvbnNlIl8KEVNlbmRTaWduYWxSZXF1ZXN0EikKB3Byb2Nlc3MYASABKAsyGC5wcm9jZXNzLlByb2Nlc3NTZWxlY3RvchIfCgZzaWduYWwYAiABKA4yDy5wcm9jZXNzLlNpZ25hbCIUChJTZW5kU2lnbmFsUmVzcG9uc2UiOwoOQ29ubmVjdFJlcXVlc3QSKQoHcHJvY2VzcxgBIAEoCzIYLnByb2Nlc3MuUHJvY2Vzc1NlbGVjdG9yIjsKD1Byb2Nlc3NTZWxlY3RvchINCgNwaWQYASABKA1IABINCgN0YWcYAiABKAlIAEIKCghzZWxlY3RvcipICgZTaWduYWwSFgoSU0lHTkFMX1VOU1BFQ0lGSUVEEAASEgoOU0lHTkFMX1NJR1RFUk0QDxISCg5TSUdOQUxfU0lHS0lMTBAJMsoDCgdQcm9jZXNzEjMKBExpc3QSFC5wcm9jZXNzLkxpc3RSZXF1ZXN0GhUucHJvY2Vzcy5MaXN0UmVzcG9uc2USPgoHQ29ubmVjdBIXLnByb2Nlc3MuQ29ubmVjdFJlcXVlc3QaGC5wcm9jZXNzLkNvbm5lY3RSZXNwb25zZTABEjgKBVN0YXJ0EhUucHJvY2Vzcy5TdGFydFJlcXVlc3QaFi5wcm9jZXNzLlN0YXJ0UmVzcG9uc2UwARI5CgZVcGRhdGUSFi5wcm9jZXNzLlVwZGF0ZVJlcXVlc3QaFy5wcm9jZXNzLlVwZGF0ZVJlc3BvbnNlEkoKC1N0cmVhbUlucHV0EhsucHJvY2Vzcy5TdHJlYW1JbnB1dFJlcXVlc3QaHC5wcm9jZXNzLlN0cmVhbUlucHV0UmVzcG9uc2UoARJCCglTZW5kSW5wdXQSGS5wcm9jZXNzLlNlbmRJbnB1dFJlcXVlc3QaGi5wcm9jZXNzLlNlbmRJbnB1dFJlc3BvbnNlEkUKClNlbmRTaWduYWwSGi5wcm9jZXNzLlNlbmRTaWduYWxSZXF1ZXN0GhsucHJvY2Vzcy5TZW5kU2lnbmFsUmVzcG9uc2VCVwoLY29tLnByb2Nlc3NCDFByb2Nlc3NQcm90b1ABogIDUFhYqgIHUHJvY2Vzc8oCB1Byb2Nlc3PiAhNQcm9jZXNzXEdQQk1ldGFkYXRh6gIHUHJvY2Vzc2IGcHJvdG8z"); var Process = /* @__PURE__ */ serviceDesc2(file_process_process, 0); // src/sandbox/commands/pty.ts import { Code as Code4, ConnectError as ConnectError4, createClient as createClient4 } from "@connectrpc/connect"; var Pty = class { constructor(transport, connectionConfig) { this.transport = transport; this.connectionConfig = connectionConfig; this.rpc = createClient4(Process, this.transport); } /** * Create a new PTY (pseudo-terminal). * * @param opts options for creating the PTY. * * @returns handle to interact with the PTY. */ create(opts) { return __async(this, null, function* () { var _a2, _b, _c; const requestTimeoutMs = (_a2 = opts == null ? void 0 : opts.requestTimeoutMs) != null ? _a2 : this.connectionConfig.requestTimeoutMs; const envs = (_b = opts == null ? void 0 : opts.envs) != null ? _b : {}; envs.TERM = "xterm-256color"; const controller = new AbortController(); const reqTimeout = setTimeout(() => { controller.abort(); }, requestTimeoutMs); const events = this.rpc.start( { process: { cmd: "/bin/bash", args: ["-i", "-l"], envs, cwd: opts == null ? void 0 : opts.cwd }, pty: { size: { cols: opts.cols, rows: opts.rows } } }, { headers: __spreadProps(__spreadValues({}, authenticationHeader(opts == null ? void 0 : opts.user)), { [KEEPALIVE_PING_HEADER]: KEEPALIVE_PING_INTERVAL_SEC.toString() }), signal: controller.signal, timeoutMs: (_c = opts == null ? void 0 : opts.timeoutMs) != null ? _c : 6e4 } ); try { const pid = yield handleProcessStartEvent(events); clearTimeout(reqTimeout); return new CommandHandle( pid, () => controller.abort(), () => this.kill(pid), events, void 0, void 0, opts.onData ); } catch (err) { throw handleRpcError(err); } }); } /** * Send input to a PTY. * * @param pid process ID of the PTY. * @param data input data to send to the PTY. * @param opts connection options. */ sendInput(pid, data, opts) { return __async(this, null, function* () { try { yield this.rpc.sendInput( { input: { input: { case: "pty", value: data } }, process: { selector: { case: "pid", value: pid } } }, { signal: this.connectionConfig.getSignal(opts == null ? void 0 : opts.requestTimeoutMs) } ); } catch (err) { throw handleRpcError(err); } }); } /** * Resize PTY. * Call this when the terminal window is resized and the number of columns and rows has changed. * * @param pid process ID of the PTY. * @param size new size of the PTY. * @param opts connection options. */ resize(pid, size, opts) { return __async(this, null, function* () { try { yield this.rpc.update( { process: { selector: { case: "pid", value: pid } }, pty: { size } }, { signal: this.connectionConfig.getSignal(opts == null ? void 0 : opts.requestTimeoutMs) } ); } catch (err) { throw handleRpcError(err); } }); } /** * Kill a running PTY specified by process ID. * It uses `SIGKILL` signal to kill the PTY. * * @param pid process ID of the PTY. * @param opts connection options. * * @returns `true` if the PTY was killed, `false` if the PTY was not found. */ kill(pid, opts) { return __async(this, null, function* () { try { yield this.rpc.sendSignal( { process: { selector: { case: "pid", value: pid } }, signal: 9 /* SIGKILL */ }, { signal: this.connectionConfig.getSignal(opts == null ? void 0 : opts.requestTimeoutMs) } ); return true; } catch (err) { if (err instanceof ConnectError4) { if (err.code === Code4.NotFound) { return false; } } throw handleRpcError(err); } }); } }; // src/sandbox/commands/index.ts var Commands = class { // 60 seconds constructor(transport, connectionConfig) { this.connectionConfig = connectionConfig; this.defaultProcessConnectionTimeout = 6e4; this.rpc = createClient5(Process, transport); } /** * List all running commands and PTY sessions. * * @param opts connection options. * * @returns list of running commands and PTY sessions. */ list(opts) { return __async(this, null, function* () { try { const res = yield this.rpc.list( {}, { signal: this.connectionConfig.getSignal(opts == null ? void 0 : opts.requestTimeoutMs) } ); return res.processes.map((p) => __spreadValues(__spreadProps(__spreadValues({ pid: p.pid }, p.tag && { tag: p.tag }), { args: p.config.args, envs: p.config.envs, cmd: p.config.cmd }), p.config.cwd && { cwd: p.config.cwd })); } catch (err) { throw handleRpcError(err); } }); } /** * Send data to command stdin. * * @param pid process ID of the command. You can get the list of running commands using {@link Commands.list}. * @param data data to send to the command. * @param opts connection options. */ sendStdin(pid, data, opts) { return __async(this, null, function* () { try { yield this.rpc.sendInput( { process: { selector: { case: "pid", value: pid } }, input: { input: { case: "stdin", value: new TextEncoder().encode(data) } } }, { signal: this.connectionConfig.getSignal(opts == null ? void 0 : opts.requestTimeoutMs) } ); } catch (err) { throw handleRpcError(err); } }); } /** * Kill a running command specified by its process ID. * It uses `SIGKILL` signal to kill the command. * * @param pid process ID of the command. You can get the list of running commands using {@link Commands.list}. * @param opts connection options. * * @returns `true` if the command was killed, `false` if the command was not found. */ kill(pid, opts) { return __async(this, null, function* () { try { yield this.rpc.sendSignal( { process: { selector: { case: "pid", value: pid } }, signal: 9 /* SIGKILL */ }, { signal: this.connectionConfig.getSignal(opts == null ? void 0 : opts.requestTimeoutMs) } ); return true; } catch (err) { if (err instanceof ConnectError5) { if (err.code === Code5.NotFound) { return false; } } throw handleRpcError(err); } }); } /** * Connect to a running command. * You can use {@link CommandHandle.wait} to wait for the command to finish and get execution results. * * @param pid process ID of the command to connect to. You can get the list of running commands using {@link Commands.list}. * @param opts connection options. * * @returns `CommandHandle` handle to interact with the running command. */ connect(pid, opts) { return __async(this, null, function* () { var _a2, _b; const requestTimeoutMs = (_a2 = opts == null ? void 0 : opts.requestTimeoutMs) != null ? _a2 : this.connectionConfig.requestTimeoutMs; const controller = new AbortController(); const reqTimeout = requestTimeoutMs ? setTimeout(() => { controller.abort(); }, requestTimeoutMs) : void 0; const events = this.rpc.connect( { process: { selector: { case: "pid", value: pid } } }, { signal: controller.signal, headers: { [KEEPALIVE_PING_HEADER]: KEEPALIVE_PING_INTERVAL_SEC.toString() }, timeoutMs: (_b = opts == null ? void 0 : opts.timeoutMs) != null ? _b : this.defaultProcessConnectionTimeout } ); try { const pid2 = yield handleProcessStartEvent(events); clearTimeout(reqTimeout); return new CommandHandle( pid2, () => controller.abort(), () => this.kill(pid2), events, opts == null ? void 0 : opts.onStdout, opts == null ? void 0 : opts.onStderr, void 0 );