ppio-sandbox 1.0.1 → 1.0.2

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.
@@ -48,7 +48,7 @@ import createClient from "openapi-fetch";
48
48
  import platform from "platform";
49
49
 
50
50
  // package.json
51
- var version = "1.0.1";
51
+ var version = "1.0.2";
52
52
 
53
53
  // src/core/api/metadata.ts
54
54
  function getRuntime() {
@@ -1752,6 +1752,39 @@ var SandboxApi = class {
1752
1752
  }
1753
1753
  return true;
1754
1754
  }
1755
+ static async connectSandbox(sandboxId, opts) {
1756
+ var _a2, _b;
1757
+ const timeoutMs = (_a2 = opts == null ? void 0 : opts.timeoutMs) != null ? _a2 : DEFAULT_SANDBOX_TIMEOUT_MS;
1758
+ const config = new ConnectionConfig(opts);
1759
+ const client = new ApiClient(config);
1760
+ const res = await client.api.POST("/sandboxes/{sandboxID}/connect", {
1761
+ params: {
1762
+ path: {
1763
+ sandboxID: sandboxId
1764
+ }
1765
+ },
1766
+ body: {
1767
+ timeout: timeoutToSeconds(timeoutMs)
1768
+ },
1769
+ signal: config.getSignal(opts == null ? void 0 : opts.requestTimeoutMs)
1770
+ });
1771
+ if (((_b = res.error) == null ? void 0 : _b.code) === 404) {
1772
+ throw new NotFoundError(`Sandbox ${sandboxId} not found`);
1773
+ }
1774
+ const err = handleApiError(res);
1775
+ if (err) {
1776
+ throw err;
1777
+ }
1778
+ if (!res.data) {
1779
+ throw new Error("Sandbox not found");
1780
+ }
1781
+ return {
1782
+ sandboxId: `${res.data.sandboxID}-${res.data.clientID}`,
1783
+ envdVersion: res.data.envdVersion,
1784
+ envdAccessToken: res.data.envdAccessToken,
1785
+ sandboxDomain: void 0
1786
+ };
1787
+ }
1755
1788
  };
1756
1789
  var SandboxPaginator = class {
1757
1790
  constructor(opts) {
@@ -1956,23 +1989,10 @@ var Sandbox = class extends SandboxApi {
1956
1989
  * ```
1957
1990
  */
1958
1991
  static async connect(sandboxId, opts) {
1959
- try {
1960
- await SandboxApi.setTimeout(
1961
- sandboxId,
1962
- (opts == null ? void 0 : opts.timeoutMs) || DEFAULT_SANDBOX_TIMEOUT_MS,
1963
- opts
1964
- );
1965
- } catch (e) {
1966
- if (e instanceof SandboxError) {
1967
- await SandboxApi.resumeSandbox(sandboxId, opts);
1968
- } else {
1969
- throw e;
1970
- }
1971
- }
1972
- const info = await SandboxApi.getFullInfo(sandboxId, opts);
1992
+ const info = await SandboxApi.connectSandbox(sandboxId, opts);
1973
1993
  const config = new ConnectionConfig(opts);
1974
1994
  return new this(__spreadValues({
1975
- sandboxId,
1995
+ sandboxId: info.sandboxId,
1976
1996
  sandboxDomain: info.sandboxDomain,
1977
1997
  envdAccessToken: info.envdAccessToken,
1978
1998
  envdVersion: info.envdVersion
@@ -1998,15 +2018,7 @@ var Sandbox = class extends SandboxApi {
1998
2018
  * ```
1999
2019
  */
2000
2020
  async connect(opts) {
2001
- try {
2002
- await SandboxApi.setTimeout(
2003
- this.sandboxId,
2004
- (opts == null ? void 0 : opts.timeoutMs) || DEFAULT_SANDBOX_TIMEOUT_MS,
2005
- opts
2006
- );
2007
- } catch (e) {
2008
- await SandboxApi.resumeSandbox(this.sandboxId, opts);
2009
- }
2021
+ await SandboxApi.connectSandbox(this.sandboxId, opts);
2010
2022
  return this;
2011
2023
  }
2012
2024
  /**
@@ -2248,4 +2260,4 @@ export {
2248
2260
  Sandbox,
2249
2261
  core_default
2250
2262
  };
2251
- //# sourceMappingURL=chunk-7OUSMPTE.mjs.map
2263
+ //# sourceMappingURL=chunk-DTP6KHRO.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/core/api/index.ts","../src/core/api/metadata.ts","../package.json","../src/core/errors.ts","../src/core/logs.ts","../src/core/connectionConfig.ts","../src/core/utils.ts","../src/core/sandbox/signature.ts","../src/core/sandbox/filesystem/index.ts","../src/core/envd/api.ts","../src/core/envd/rpc.ts","../src/core/envd/filesystem/filesystem_pb.ts","../src/core/sandbox/filesystem/watchHandle.ts","../src/core/envd/versions.ts","../src/core/sandbox/commands/commandHandle.ts","../src/core/sandbox/index.ts","../src/core/sandbox/commands/index.ts","../src/core/envd/process/process_pb.ts","../src/core/sandbox/commands/pty.ts","../src/core/sandbox/sandboxApi.ts","../src/core/index.ts"],"sourcesContent":["import createClient, { FetchResponse } from 'openapi-fetch'\n\nimport type { components, paths } from './schema.gen'\nimport { defaultHeaders } from './metadata'\nimport { ConnectionConfig } from '../connectionConfig'\nimport { AuthenticationError, RateLimitError, SandboxError } from '../errors'\nimport { createApiLogger } from '../logs'\n\nexport function handleApiError(\n response: FetchResponse<any, any, any>\n): Error | undefined {\n if (!response.error) {\n return\n }\n\n if (response.response.status === 429) {\n const message = 'Rate limit exceeded, please try again later'\n const content = response.error?.message ?? response.error\n\n if (content) {\n return new RateLimitError(`${message} - ${content}`)\n }\n return new RateLimitError(message)\n }\n\n const message = response.error?.message ?? response.error\n return new SandboxError(`${response.response.status}: ${message}`)\n}\n\n/**\n * Client for interacting with the PPIO agent sandbox API.\n */\nclass ApiClient {\n readonly api: ReturnType<typeof createClient<paths>>\n\n constructor(\n config: ConnectionConfig,\n opts: {\n requireAccessToken?: boolean\n requireApiKey?: boolean\n } = { requireAccessToken: false, requireApiKey: false }\n ) {\n if (opts?.requireApiKey && !config.apiKey) {\n throw new AuthenticationError(\n 'API key is required, please visit the Key Management page at https://ppio.com/settings/key-management to get your API key. ' +\n 'You can either set the environment variable `PPIO_API_KEY` ' +\n \"or you can pass it directly to the sandbox like Sandbox.create({ apiKey: 'sk_...' })\"\n )\n }\n\n if (opts?.requireAccessToken && !config.accessToken) {\n throw new AuthenticationError(\n 'Access token is required, please visit the Key Management page at https://ppio.com/settings/key-management to get your access token, which is same as the API key. ' +\n 'You can set the environment variable `PPIO_ACCESS_TOKEN` or pass the `accessToken` in options.'\n )\n }\n\n this.api = createClient<paths>({\n baseUrl: config.apiUrl,\n // keepalive: true, // TODO: Return keepalive\n headers: {\n ...defaultHeaders,\n ...(config.apiKey && { 'X-API-KEY': config.apiKey }),\n ...(config.accessToken && {\n Authorization: `Bearer ${config.accessToken}`,\n }),\n ...config.headers,\n },\n querySerializer: {\n array: {\n style: 'form',\n explode: false,\n },\n },\n })\n\n if (config.logger) {\n this.api.use(createApiLogger(config.logger))\n }\n }\n}\n\nexport type { components, paths }\nexport { ApiClient }\n","import platform from 'platform'\n\nimport { version } from '../../../package.json'\n\nexport { version }\n\ndeclare let window: any\n\ntype Runtime = 'node' | 'browser' | 'deno' | 'bun' | 'vercel-edge' | 'cloudflare-worker' | 'unknown'\n\nfunction getRuntime(): { runtime: Runtime; version: string } {\n // @ts-ignore\n if ((globalThis as any).Bun) {\n // @ts-ignore\n return { runtime: 'bun', version: globalThis.Bun.version }\n }\n\n // @ts-ignore\n if ((globalThis as any).Deno) {\n // @ts-ignore\n return { runtime: 'deno', version: globalThis.Deno.version.deno }\n }\n\n if ((globalThis as any).process?.release?.name === 'node') {\n return { runtime: 'node', version: platform.version || 'unknown' }\n }\n\n // @ts-ignore\n if (typeof EdgeRuntime === 'string') {\n return { runtime: 'vercel-edge', version: 'unknown' }\n }\n\n if ((globalThis as any).navigator?.userAgent === 'Cloudflare-Workers') {\n return { runtime: 'cloudflare-worker', version: 'unknown' }\n }\n\n if (typeof window !== 'undefined') {\n return { runtime: 'browser', version: platform.version || 'unknown' }\n }\n\n return { runtime: 'unknown', version: 'unknown' }\n}\n\nexport const { runtime, version: runtimeVersion } = getRuntime()\n\nexport const defaultHeaders = {\n browser: (typeof window !== 'undefined' && platform.name) || 'unknown',\n lang: 'js',\n lang_version: runtimeVersion,\n package_version: version,\n publisher: 'PPIO',\n sdk_runtime: runtime,\n system: platform.os?.family || 'unknown',\n}\n\nexport function getEnvVar(name: string) {\n if (runtime === 'deno') {\n // @ts-ignore\n return Deno.env.get(name)\n }\n\n if (typeof process === 'undefined') {\n return ''\n }\n\n return process.env[name]\n}\n","{\n \"name\": \"ppio-sandbox\",\n \"version\": \"1.0.2\",\n \"description\": \"PPIO Sandbox SDK for JavaScript/TypeScript - A comprehensive SDK for code execution, desktop automation, and cloud computing environments\",\n \"main\": \"dist/index.js\",\n \"types\": \"dist/index.d.ts\",\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"import\": \"./dist/index.mjs\",\n \"require\": \"./dist/index.js\"\n },\n \"./code-interpreter\": {\n \"types\": \"./dist/code-interpreter.d.ts\",\n \"import\": \"./dist/code-interpreter.mjs\",\n \"require\": \"./dist/code-interpreter.js\"\n },\n \"./desktop\": {\n \"types\": \"./dist/desktop.d.ts\",\n \"import\": \"./dist/desktop.mjs\",\n \"require\": \"./dist/desktop.js\"\n }\n },\n \"files\": [\n \"dist/**/*\",\n \"README.md\"\n ],\n \"publishConfig\": {\n \"access\": \"public\"\n },\n \"scripts\": {\n \"check-deps\": \"knip\",\n \"update-deps\": \"ncu -u && pnpm i\",\n \"build\": \"tsc --noEmit && tsup\",\n \"dev\": \"tsup --watch\",\n \"lint:fix\": \"eslint src/**/*.ts --fix\",\n \"lint\": \"eslint src/**/*.ts tests/**/*.ts\",\n \"format\": \"prettier --write src/**/*.ts\",\n \"clean\": \"rimraf dist\",\n \"prepublishOnly\": \"pnpm build\",\n \"test:core\": \"vitest run ./src/core/ --reporter verbose --run\",\n \"test:code-interpreter\": \"vitest run ./src/code-interpreter/ --reporter verbose --run\",\n \"test:desktop\": \"vitest run ./src/desktop/ --reporter verbose --run\",\n \"generate:api\": \"python ./spec/remove_extra_tags.py sandboxes templates auth && openapi-typescript ./spec/openapi_generated.yml -x api_key --array-length --alphabetize --output src/core/api/schema.gen.ts\",\n \"generate:envd-api\": \"openapi-typescript ./spec/envd/envd.yaml -x api_key --array-length --alphabetize --output src/core/envd/schema.gen.ts\"\n },\n \"keywords\": [\n \"ppio\",\n \"ai-agent\",\n \"sandbox\",\n \"sdk\",\n \"typescript\",\n \"javascript\",\n \"code-interpreter\",\n \"desktop-automation\",\n \"cloud-computing\",\n \"remote-execution\",\n \"api-client\"\n ],\n \"author\": {\n \"name\": \"PPIO\",\n \"url\": \"https://ppio.com\"\n },\n \"engines\": {\n \"node\": \">=16.0.0\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"@types/platform\": \"^1.3.6\",\n \"@types/react\": \"^19.1.12\",\n \"@typescript-eslint/eslint-plugin\": \"^6.0.0\",\n \"@typescript-eslint/parser\": \"^6.0.0\",\n \"eslint\": \"^8.0.0\",\n \"eslint-config-prettier\": \"^9.0.0\",\n \"eslint-plugin-prettier\": \"^5.0.0\",\n \"knip\": \"^5.43.6\",\n \"prettier\": \"^3.0.0\",\n \"react\": \"^18.3.1\",\n \"rimraf\": \"^5.0.0\",\n \"ts-jest\": \"^29.1.0\",\n \"ts-node\": \"^10.9.0\",\n \"typescript\": \"^5.0.0\",\n \"vitest\": \"^3.1.1\",\n \"tsup\": \"^8.4.0\",\n \"openapi-typescript\": \"^7.6.1\"\n },\n \"dependencies\": {\n \"@bufbuild/protobuf\": \"^2.6.2\",\n \"@connectrpc/connect\": \"2.0.0-rc.3\",\n \"@connectrpc/connect-web\": \"2.0.0-rc.3\",\n \"compare-versions\": \"^6.1.0\",\n \"openapi-fetch\": \"^0.9.7\",\n \"platform\": \"^1.3.6\"\n },\n \"bugs\": {\n \"url\": \"https://ppio.com/about?index=2\"\n },\n \"homepage\": \"https://ppio.com/ai-computing/sandbox\"\n}\n","// This is the message for the sandbox timeout error when the response code is 502/Unavailable\nexport function formatSandboxTimeoutError(message: string) {\n return new TimeoutError(\n `${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.`\n )\n}\n\n/**\n * Base class for all sandbox errors.\n *\n * Thrown when general sandbox errors occur.\n */\nexport class SandboxError extends Error {\n constructor(message: any) {\n super(message)\n this.name = 'SandboxError'\n }\n}\n\n/**\n * Thrown when a timeout error occurs.\n *\n * The [unavailable] error type is caused by sandbox timeout.\n *\n * The [canceled] error type is caused by exceeding request timeout.\n *\n * The [deadline_exceeded] error type is caused by exceeding the timeout for command execution, watch, etc.\n *\n * The [unknown] error type is sometimes caused by the sandbox timeout when the request is not processed correctly.\n */\nexport class TimeoutError extends SandboxError {\n constructor(message: string) {\n super(message)\n this.name = 'TimeoutError'\n }\n}\n\n/**\n * Thrown when an invalid argument is provided.\n */\nexport class InvalidArgumentError extends SandboxError {\n constructor(message: string) {\n super(message)\n this.name = 'InvalidArgumentError'\n }\n}\n\n/**\n * Thrown when there is not enough disk space.\n */\nexport class NotEnoughSpaceError extends SandboxError {\n constructor(message: string) {\n super(message)\n this.name = 'NotEnoughSpaceError'\n }\n}\n\n/**\n * Thrown when a resource is not found.\n */\nexport class NotFoundError extends SandboxError {\n constructor(message: string) {\n super(message)\n this.name = 'NotFoundError'\n }\n}\n\n/**\n * Thrown when authentication fails.\n */\nexport class AuthenticationError extends SandboxError {\n constructor(message: any) {\n super(message)\n this.name = 'AuthenticationError'\n }\n}\n\n/**\n * Thrown when the template uses old envd version. It isn't compatible with the new SDK.\n */\nexport class TemplateError extends SandboxError {\n constructor(message: string) {\n super(message)\n this.name = 'TemplateError'\n }\n}\n\n/**\n * Thrown when the API rate limit is exceeded.\n */\nexport class RateLimitError extends SandboxError {\n constructor(message: any) {\n super(message)\n this.name = 'RateLimitError'\n }\n}\n","import type { Interceptor } from '@connectrpc/connect'\nimport type { Middleware } from 'openapi-fetch'\n\n/**\n * Logger interface compatible with {@link console} used for logging Sandbox messages.\n */\nexport interface Logger {\n /**\n * Debug level logging method.\n */\n debug?: (...args: any[]) => void\n /**\n * Info level logging method.\n */\n info?: (...args: any[]) => void\n /**\n * Warn level logging method.\n */\n warn?: (...args: any[]) => void\n /**\n * Error level logging method.\n */\n error?: (...args: any[]) => void\n}\n\nfunction formatLog(log: any) {\n return JSON.parse(JSON.stringify(log))\n}\n\nexport function createRpcLogger(logger: Logger): Interceptor {\n async function* logEach(stream: AsyncIterable<any>) {\n for await (const m of stream) {\n logger.debug?.('Response stream:', formatLog(m))\n yield m\n }\n }\n\n return (next) => async (req) => {\n logger.info?.(`Request: POST ${req.url}`)\n\n const res = await next(req)\n if (res.stream) {\n return {\n ...res,\n message: logEach(res.message),\n }\n } else {\n logger.info?.('Response:', formatLog(res.message))\n }\n\n return res\n }\n}\n\nexport function createApiLogger(logger: Logger): Middleware {\n return {\n async onRequest(req) {\n logger.info?.(`Request ${req.method} ${req.url}`)\n\n return req\n },\n async onResponse(res) {\n if (res.status >= 400) {\n logger.error?.('Response:', res.status, res.statusText)\n } else {\n logger.info?.('Response:', res.status, res.statusText)\n }\n\n return res\n },\n }\n}\n","import { Logger } from './logs'\nimport { getEnvVar, version } from './api/metadata'\n\nexport const REQUEST_TIMEOUT_MS = 60_000 // 60 seconds\nexport const DEFAULT_SANDBOX_TIMEOUT_MS = 300_000 // 300 seconds\nexport const KEEPALIVE_PING_INTERVAL_SEC = 50 // 50 seconds\n\nexport const KEEPALIVE_PING_HEADER = 'Keepalive-Ping-Interval'\n\n/**\n * Connection options for requests to the API.\n */\nexport interface ConnectionOpts {\n /**\n * PPIO API key to use for authentication.\n *\n * @default PPIO_API_KEY // environment variable\n */\n apiKey?: string\n /**\n * PPIO access token to use for authentication.\n *\n * @default PPIO_ACCESS_TOKEN // environment variable\n */\n accessToken?: string\n /**\n * Domain to use for the API.\n *\n * @default PPIO_DOMAIN // environment variable or `ppio.com`\n */\n domain?: string\n /**\n * If true the SDK starts in the debug mode and connects to the local envd API server.\n * @internal\n * @default PPIO_DEBUG // environment variable or `false`\n */\n debug?: boolean\n /**\n * Timeout for requests to the API in **milliseconds**.\n *\n * @default 60_000 // 60 seconds\n */\n requestTimeoutMs?: number\n /**\n * Logger to use for logging messages. It can accept any object that implements `Logger` interface—for example, {@link console}.\n */\n logger?: Logger\n\n /**\n * Additional headers to send with the request.\n */\n headers?: Record<string, string>\n}\n\n/**\n * Configuration for connecting to the API.\n */\nexport class ConnectionConfig {\n readonly debug: boolean\n readonly domain: string\n readonly apiUrl: string\n readonly logger?: Logger\n\n readonly requestTimeoutMs: number\n\n readonly apiKey?: string\n readonly accessToken?: string\n\n readonly headers?: Record<string, string>\n\n constructor(opts?: ConnectionOpts) {\n this.apiKey = opts?.apiKey || ConnectionConfig.apiKey\n this.debug = opts?.debug || ConnectionConfig.debug\n this.domain = opts?.domain || ConnectionConfig.domain\n this.accessToken = opts?.accessToken || ConnectionConfig.accessToken\n this.requestTimeoutMs = opts?.requestTimeoutMs ?? REQUEST_TIMEOUT_MS\n this.logger = opts?.logger\n this.headers = opts?.headers || {}\n this.headers['User-Agent'] = `ppio-sandbox-sdk-js/${version}`\n\n this.apiUrl = this.debug\n ? 'http://localhost:3000'\n : `https://api.${this.domain}`\n }\n\n private static get domain() {\n return getEnvVar('PPIO_DOMAIN') || 'sandbox.ppio.cn'\n }\n\n private static get debug() {\n return (getEnvVar('PPIO_DEBUG') || 'false').toLowerCase() === 'true'\n }\n\n private static get apiKey() {\n return getEnvVar('PPIO_API_KEY')\n }\n\n private static get accessToken() {\n return getEnvVar('PPIO_ACCESS_TOKEN')\n }\n\n getSignal(requestTimeoutMs?: number) {\n const timeout = requestTimeoutMs ?? this.requestTimeoutMs\n\n return timeout ? AbortSignal.timeout(timeout) : undefined\n }\n}\n\n/**\n * User used for the operation in the sandbox.\n */\nexport type Username = 'root' | 'user'\n\nexport const defaultUsername: Username = 'user'\n","export async function sha256(data: string): Promise<string> {\n // Use WebCrypto API if available\n if (typeof crypto !== 'undefined') {\n const encoder = new TextEncoder()\n const dataBuffer = encoder.encode(data)\n const hashBuffer = await crypto.subtle.digest('SHA-256', dataBuffer)\n const hashArray = new Uint8Array(hashBuffer)\n return btoa(String.fromCharCode(...hashArray))\n }\n\n // Use Node.js crypto if WebCrypto is not available\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const { createHash } = require('node:crypto')\n const hash = createHash('sha256').update(data, 'utf8').digest()\n return hash.toString('base64')\n}\n\nexport function timeoutToSeconds(timeout: number): number {\n return Math.ceil(timeout / 1000)\n}\n","import { sha256 } from '../utils'\n\n/**\n * Get the URL signature for the specified path, operation and user.\n *\n * @param path Path to the file in the sandbox.\n *\n * @param operation File system operation. Can be either `read` or `write`.\n *\n * @param user Sandbox user.\n *\n * @param expirationInSeconds Optional signature expiration time in seconds.\n */\n\ninterface SignatureOpts {\n path: string\n operation: 'read' | 'write'\n user: string\n expirationInSeconds?: number\n envdAccessToken?: string\n}\n\nexport async function getSignature({\n path,\n operation,\n user,\n expirationInSeconds,\n envdAccessToken,\n}: SignatureOpts): Promise<{ signature: string; expiration: number | null }> {\n if (!envdAccessToken) {\n throw new Error(\n 'Access token is not set and signature cannot be generated!'\n )\n }\n\n // expiration is unix timestamp\n const signatureExpiration = expirationInSeconds\n ? Math.floor(Date.now() / 1000) + expirationInSeconds\n : null\n let signatureRaw: string\n\n if (signatureExpiration === null) {\n signatureRaw = `${path}:${operation}:${user}:${envdAccessToken}`\n } else {\n signatureRaw = `${path}:${operation}:${user}:${envdAccessToken}:${signatureExpiration.toString()}`\n }\n\n const hashBase64 = await sha256(signatureRaw)\n const signature = 'v1_' + hashBase64.replace(/=+$/, '')\n\n return {\n signature: signature,\n expiration: signatureExpiration,\n }\n}\n","import {\n createClient,\n Transport,\n Client,\n ConnectError,\n Code,\n} from '@connectrpc/connect'\nimport {\n ConnectionConfig,\n ConnectionOpts,\n defaultUsername,\n KEEPALIVE_PING_HEADER,\n KEEPALIVE_PING_INTERVAL_SEC,\n Username,\n} from '../../connectionConfig'\n\nimport { handleEnvdApiError, handleWatchDirStartEvent } from '../../envd/api'\nimport { authenticationHeader, handleRpcError } from '../../envd/rpc'\n\nimport { EnvdApiClient } from '../../envd/api'\nimport {\n FileType as FsFileType,\n Filesystem as FilesystemService,\n} from '../../envd/filesystem/filesystem_pb'\n\nimport { FilesystemEvent, WatchHandle } from './watchHandle'\n\nimport { compareVersions } from 'compare-versions'\nimport { InvalidArgumentError, TemplateError } from '../../errors'\nimport { ENVD_VERSION_RECURSIVE_WATCH } from '../../envd/versions'\nimport type { Timestamp } from '@bufbuild/protobuf/wkt'\n\n/**\n * Sandbox filesystem object information.\n */\nexport interface WriteInfo {\n /**\n * Name of the filesystem object.\n */\n name: string\n /**\n * Type of the filesystem object.\n */\n type?: FileType\n /**\n * Path to the filesystem object.\n */\n path: string\n}\n\nexport interface EntryInfo extends WriteInfo {\n /**\n * Size of the filesystem object in bytes.\n */\n size: number\n\n /**\n * File mode and permission bits.\n */\n mode: number\n\n /**\n * String representation of file permissions (e.g. 'rwxr-xr-x').\n */\n permissions: string\n\n /**\n * Owner of the filesystem object.\n */\n owner: string\n\n /**\n * Group owner of the filesystem object.\n */\n group: string\n\n /**\n * Last modification time of the filesystem object.\n */\n modifiedTime?: Date\n\n /**\n * If the filesystem object is a symlink, this is the target of the symlink.\n */\n symlinkTarget?: string\n}\n\n/**\n * Sandbox filesystem object type.\n */\nexport enum FileType {\n /**\n * Filesystem object is a file.\n */\n FILE = 'file',\n /**\n * Filesystem object is a directory.\n */\n DIR = 'dir',\n}\n\nexport type WriteEntry = {\n path: string\n data: string | ArrayBuffer | Blob | ReadableStream\n}\n\nfunction mapFileType(fileType: FsFileType) {\n switch (fileType) {\n case FsFileType.DIRECTORY:\n return FileType.DIR\n case FsFileType.FILE:\n return FileType.FILE\n }\n}\n\nfunction mapModifiedTime(modifiedTime: Timestamp | undefined) {\n if (!modifiedTime) return undefined\n\n return new Date(\n Number(modifiedTime.seconds) * 1000 +\n Math.floor(modifiedTime.nanos / 1_000_000)\n )\n}\n\n/**\n * Options for the sandbox filesystem operations.\n */\nexport interface FilesystemRequestOpts\n extends Partial<Pick<ConnectionOpts, 'requestTimeoutMs'>> {\n /**\n * User to use for the operation in the sandbox.\n * This affects the resolution of relative paths and ownership of the created filesystem objects.\n */\n user?: Username\n}\n\nexport interface FilesystemListOpts extends FilesystemRequestOpts {\n /**\n * Depth of the directory to list.\n */\n depth?: number\n}\n\n/**\n * Options for watching a directory.\n */\nexport interface WatchOpts extends FilesystemRequestOpts {\n /**\n * Timeout for the watch operation in **milliseconds**.\n * You can pass `0` to disable the timeout.\n *\n * @default 60_000 // 60 seconds\n */\n timeoutMs?: number\n /**\n * Callback to call when the watch operation stops.\n */\n onExit?: (err?: Error) => void | Promise<void>\n /**\n * Watch the directory recursively\n */\n recursive?: boolean\n}\n\n/**\n * Module for interacting with the sandbox filesystem.\n */\nexport class Filesystem {\n private readonly rpc: Client<typeof FilesystemService>\n\n private readonly defaultWatchTimeout = 60_000 // 60 seconds\n private readonly defaultWatchRecursive = false\n\n constructor(\n transport: Transport,\n private readonly envdApi: EnvdApiClient,\n private readonly connectionConfig: ConnectionConfig\n ) {\n this.rpc = createClient(FilesystemService, transport)\n }\n\n /**\n * Read file content as a `string`.\n *\n * You can pass `text`, `bytes`, `blob`, or `stream` to `opts.format` to change the return type.\n *\n * @param path path to the file.\n * @param opts connection options.\n * @param [opts.format] format of the file content—`text` by default.\n *\n * @returns file content as string\n */\n async read(\n path: string,\n opts?: FilesystemRequestOpts & { format?: 'text' }\n ): Promise<string>\n /**\n * Read file content as a `Uint8Array`.\n *\n * You can pass `text`, `bytes`, `blob`, or `stream` to `opts.format` to change the return type.\n *\n * @param path path to the file.\n * @param opts connection options.\n * @param [opts.format] format of the file content—`bytes`.\n *\n * @returns file content as `Uint8Array`\n */\n async read(\n path: string,\n opts?: FilesystemRequestOpts & { format: 'bytes' }\n ): Promise<Uint8Array>\n /**\n * Read file content as a `Blob`.\n *\n * You can pass `text`, `bytes`, `blob`, or `stream` to `opts.format` to change the return type.\n *\n * @param path path to the file.\n * @param opts connection options.\n * @param [opts.format] format of the file content—`blob`.\n *\n * @returns file content as `Blob`\n */\n async read(\n path: string,\n opts?: FilesystemRequestOpts & { format: 'blob' }\n ): Promise<Blob>\n /**\n * Read file content as a `ReadableStream`.\n *\n * You can pass `text`, `bytes`, `blob`, or `stream` to `opts.format` to change the return type.\n *\n * @param path path to the file.\n * @param opts connection options.\n * @param [opts.format] format of the file content—`stream`.\n *\n * @returns file content as `ReadableStream`\n */\n async read(\n path: string,\n opts?: FilesystemRequestOpts & { format: 'stream' }\n ): Promise<ReadableStream<Uint8Array>>\n async read(\n path: string,\n opts?: FilesystemRequestOpts & {\n format?: 'text' | 'stream' | 'bytes' | 'blob'\n }\n ): Promise<unknown> {\n const format = opts?.format ?? 'text'\n\n const res = await this.envdApi.api.GET('/files', {\n params: {\n query: {\n path,\n username: opts?.user || defaultUsername,\n },\n },\n parseAs: format === 'bytes' ? 'arrayBuffer' : format,\n signal: this.connectionConfig.getSignal(opts?.requestTimeoutMs),\n })\n\n const err = await handleEnvdApiError(res)\n if (err) {\n throw err\n }\n\n if (format === 'bytes') {\n return new Uint8Array(res.data as ArrayBuffer)\n }\n\n // When the file is empty, res.data is parsed as `{}`. This is a workaround to return an empty string.\n if (res.response.headers.get('content-length') === '0') {\n return ''\n }\n\n return res.data\n }\n\n /**\n * Write content to a file.\n *\n *\n * Writing to a file that doesn't exist creates the file.\n *\n * Writing to a file that already exists overwrites the file.\n *\n * Writing to a file at path that doesn't exist creates the necessary directories.\n *\n * @param path path to file.\n * @param data data to write to the file. Data can be a string, `ArrayBuffer`, `Blob`, or `ReadableStream`.\n * @param opts connection options.\n *\n * @returns information about the written file\n */\n async write(\n path: string,\n data: string | ArrayBuffer | Blob | ReadableStream,\n opts?: FilesystemRequestOpts\n ): Promise<WriteInfo>\n async write(\n files: WriteEntry[],\n opts?: FilesystemRequestOpts\n ): Promise<WriteInfo[]>\n async write(\n pathOrFiles: string | WriteEntry[],\n dataOrOpts?:\n | string\n | ArrayBuffer\n | Blob\n | ReadableStream\n | FilesystemRequestOpts,\n opts?: FilesystemRequestOpts\n ): Promise<WriteInfo | WriteInfo[]> {\n if (typeof pathOrFiles !== 'string' && !Array.isArray(pathOrFiles)) {\n throw new Error('Path or files are required')\n }\n\n if (typeof pathOrFiles === 'string' && Array.isArray(dataOrOpts)) {\n throw new Error(\n '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.'\n )\n }\n\n const { path, writeOpts, writeFiles } =\n typeof pathOrFiles === 'string'\n ? {\n path: pathOrFiles,\n writeOpts: opts as FilesystemRequestOpts,\n writeFiles: [\n {\n data: dataOrOpts as\n | string\n | ArrayBuffer\n | Blob\n | ReadableStream,\n },\n ],\n }\n : {\n path: undefined,\n writeOpts: dataOrOpts as FilesystemRequestOpts,\n writeFiles: pathOrFiles as WriteEntry[],\n }\n\n if (writeFiles.length === 0) return [] as WriteInfo[]\n\n const blobs = await Promise.all(\n writeFiles.map((f) => new Response(f.data).blob())\n )\n\n const res = await this.envdApi.api.POST('/files', {\n params: {\n query: {\n path,\n username: writeOpts?.user || defaultUsername,\n },\n },\n bodySerializer() {\n return blobs.reduce((fd, blob, i) => {\n // Important: RFC 7578, Section 4.2 requires that if a filename is provided,\n // the directory path information must not be used.\n // BUT in our case we need to use the directory path information with a custom\n // muktipart part name getter in envd.\n fd.append('file', blob, writeFiles[i].path)\n\n return fd\n }, new FormData())\n },\n body: {},\n headers: {\n 'Content-Type': 'multipart/form-data',\n 'Bun-Content-Type': 'temporary-fix', // https://github.com/oven-sh/bun/issues/14988\n },\n })\n\n const err = await handleEnvdApiError(res)\n if (err) {\n throw err\n }\n\n const files = res.data as WriteInfo[]\n if (!files) {\n throw new Error('Expected to receive information about written file')\n }\n\n return files.length === 1 && path ? files[0] : files\n }\n\n /**\n * List entries in a directory.\n *\n * @param path path to the directory.\n * @param opts connection options.\n *\n * @returns list of entries in the sandbox filesystem directory.\n */\n async list(path: string, opts?: FilesystemListOpts): Promise<EntryInfo[]> {\n if (typeof opts?.depth === 'number' && opts.depth < 1) {\n throw new InvalidArgumentError('depth should be at least one')\n }\n\n try {\n const res = await this.rpc.listDir(\n {\n path,\n depth: opts?.depth ?? 1,\n },\n {\n headers: authenticationHeader(opts?.user),\n signal: this.connectionConfig.getSignal(opts?.requestTimeoutMs),\n }\n )\n\n const entries: EntryInfo[] = []\n\n for (const e of res.entries) {\n const type = mapFileType(e.type)\n\n if (type) {\n entries.push({\n name: e.name,\n type,\n path: e.path,\n size: Number(e.size),\n mode: e.mode,\n permissions: e.permissions,\n owner: e.owner,\n group: e.group,\n modifiedTime: mapModifiedTime(e.modifiedTime),\n symlinkTarget: e.symlinkTarget,\n })\n }\n }\n\n return entries\n } catch (err) {\n throw handleRpcError(err)\n }\n }\n\n /**\n * Create a new directory and all directories along the way if needed on the specified path.\n *\n * @param path path to a new directory. For example '/dirA/dirB' when creating 'dirB'.\n * @param opts connection options.\n *\n * @returns `true` if the directory was created, `false` if it already exists.\n */\n async makeDir(path: string, opts?: FilesystemRequestOpts): Promise<boolean> {\n try {\n await this.rpc.makeDir(\n { path },\n {\n headers: authenticationHeader(opts?.user),\n signal: this.connectionConfig.getSignal(opts?.requestTimeoutMs),\n }\n )\n\n return true\n } catch (err) {\n if (err instanceof ConnectError) {\n if (err.code === Code.AlreadyExists) {\n return false\n }\n }\n\n throw handleRpcError(err)\n }\n }\n\n /**\n * Rename a file or directory.\n *\n * @param oldPath path to the file or directory to rename.\n * @param newPath new path for the file or directory.\n * @param opts connection options.\n *\n * @returns information about renamed file or directory.\n */\n async rename(\n oldPath: string,\n newPath: string,\n opts?: FilesystemRequestOpts\n ): Promise<EntryInfo> {\n try {\n const res = await this.rpc.move(\n {\n source: oldPath,\n destination: newPath,\n },\n {\n headers: authenticationHeader(opts?.user),\n signal: this.connectionConfig.getSignal(opts?.requestTimeoutMs),\n }\n )\n\n const entry = res.entry\n if (!entry) {\n throw new Error('Expected to receive information about moved object')\n }\n\n return {\n name: entry.name,\n type: mapFileType(entry.type),\n path: entry.path,\n size: Number(entry.size),\n mode: entry.mode,\n permissions: entry.permissions,\n owner: entry.owner,\n group: entry.group,\n modifiedTime: mapModifiedTime(entry.modifiedTime),\n symlinkTarget: entry.symlinkTarget,\n }\n } catch (err) {\n throw handleRpcError(err)\n }\n }\n\n /**\n * Remove a file or directory.\n *\n * @param path path to a file or directory.\n * @param opts connection options.\n */\n async remove(path: string, opts?: FilesystemRequestOpts): Promise<void> {\n try {\n await this.rpc.remove(\n { path },\n {\n headers: authenticationHeader(opts?.user),\n signal: this.connectionConfig.getSignal(opts?.requestTimeoutMs),\n }\n )\n } catch (err) {\n throw handleRpcError(err)\n }\n }\n\n /**\n * Check if a file or a directory exists.\n *\n * @param path path to a file or a directory\n * @param opts connection options.\n *\n * @returns `true` if the file or directory exists, `false` otherwise\n */\n async exists(path: string, opts?: FilesystemRequestOpts): Promise<boolean> {\n try {\n await this.rpc.stat(\n { path },\n {\n headers: authenticationHeader(opts?.user),\n signal: this.connectionConfig.getSignal(opts?.requestTimeoutMs),\n }\n )\n\n return true\n } catch (err) {\n if (err instanceof ConnectError) {\n if (err.code === Code.NotFound) {\n return false\n }\n }\n\n throw handleRpcError(err)\n }\n }\n\n /**\n * Get information about a file or directory.\n *\n * @param path path to a file or directory.\n * @param opts connection options.\n *\n * @returns information about the file or directory like name, type, and path.\n */\n async getInfo(\n path: string,\n opts?: FilesystemRequestOpts\n ): Promise<EntryInfo> {\n try {\n const res = await this.rpc.stat(\n { path },\n { headers: authenticationHeader(opts?.user) }\n )\n\n if (!res.entry) {\n throw new Error(\n 'Expected to receive information about the file or directory'\n )\n }\n\n return {\n name: res.entry.name,\n type: mapFileType(res.entry.type),\n path: res.entry.path,\n size: Number(res.entry.size),\n mode: res.entry.mode,\n permissions: res.entry.permissions,\n owner: res.entry.owner,\n group: res.entry.group,\n modifiedTime: mapModifiedTime(res.entry.modifiedTime),\n symlinkTarget: res.entry.symlinkTarget,\n }\n } catch (err) {\n throw handleRpcError(err)\n }\n }\n\n /**\n * Start watching a directory for filesystem events.\n *\n * @param path path to directory to watch.\n * @param onEvent callback to call when an event in the directory occurs.\n * @param opts connection options.\n *\n * @returns `WatchHandle` object for stopping watching directory.\n */\n async watchDir(\n path: string,\n onEvent: (event: FilesystemEvent) => void | Promise<void>,\n opts?: WatchOpts & {\n onExit?: (err?: Error) => void | Promise<void>\n }\n ): Promise<WatchHandle> {\n if (\n opts?.recursive &&\n this.envdApi.version &&\n compareVersions(this.envdApi.version, ENVD_VERSION_RECURSIVE_WATCH) < 0\n ) {\n throw new TemplateError(\n 'You need to update the template to use recursive watching. ' +\n 'You can do this by running `ppio-sandbox-cli template build` in the directory with the template.'\n )\n }\n\n const requestTimeoutMs =\n opts?.requestTimeoutMs ?? this.connectionConfig.requestTimeoutMs\n\n const controller = new AbortController()\n\n const reqTimeout = requestTimeoutMs\n ? setTimeout(() => {\n controller.abort()\n }, requestTimeoutMs)\n : undefined\n\n const events = this.rpc.watchDir(\n {\n path,\n recursive: opts?.recursive ?? this.defaultWatchRecursive,\n },\n {\n headers: {\n ...authenticationHeader(opts?.user),\n [KEEPALIVE_PING_HEADER]: KEEPALIVE_PING_INTERVAL_SEC.toString(),\n },\n signal: controller.signal,\n timeoutMs: opts?.timeoutMs ?? this.defaultWatchTimeout,\n }\n )\n\n try {\n await handleWatchDirStartEvent(events)\n\n clearTimeout(reqTimeout)\n\n return new WatchHandle(\n () => controller.abort(),\n events,\n onEvent,\n opts?.onExit\n )\n } catch (err) {\n throw handleRpcError(err)\n }\n }\n}\n","import createClient, { FetchResponse } from 'openapi-fetch'\n\nimport type { components, paths } from './schema.gen'\nimport { ConnectionConfig } from '../connectionConfig'\nimport { createApiLogger } from '../logs'\nimport {\n SandboxError,\n InvalidArgumentError,\n NotFoundError,\n NotEnoughSpaceError,\n formatSandboxTimeoutError,\n AuthenticationError,\n} from '../errors'\nimport { StartResponse, ConnectResponse } from './process/process_pb'\nimport { Code, ConnectError } from '@connectrpc/connect'\nimport { WatchDirResponse } from './filesystem/filesystem_pb'\n\nexport async function handleEnvdApiError<A, B, C extends `${string}/${string}`>(\n res: FetchResponse<A, B, C>\n) {\n if (!res.error) {\n return\n }\n\n const message: string =\n typeof res.error == 'string'\n ? res.error\n : res.error?.message || (await res.response.text())\n\n switch (res.response.status) {\n case 400:\n return new InvalidArgumentError(message)\n case 401:\n return new AuthenticationError(message)\n case 404:\n return new NotFoundError(message)\n case 429:\n return new SandboxError(\n `${res.response.status}: ${message}: The requests are being rate limited.`\n )\n case 502:\n return formatSandboxTimeoutError(message)\n case 507:\n return new NotEnoughSpaceError(message)\n default:\n return new SandboxError(`${res.response.status}: ${message}`)\n }\n}\n\nexport async function handleProcessStartEvent(\n events: AsyncIterable<StartResponse | ConnectResponse>\n) {\n let startEvent: StartResponse | ConnectResponse\n\n try {\n startEvent = (await events[Symbol.asyncIterator]().next()).value\n } catch (err) {\n if (err instanceof ConnectError) {\n if (err.code === Code.Unavailable) {\n throw new NotFoundError('Sandbox is probably not running anymore')\n }\n }\n\n throw err\n }\n if (startEvent.event?.event.case !== 'start') {\n throw new Error('Expected start event')\n }\n\n return startEvent.event.event.value.pid\n}\n\nexport async function handleWatchDirStartEvent(\n events: AsyncIterable<WatchDirResponse>\n) {\n let startEvent: WatchDirResponse\n\n try {\n startEvent = (await events[Symbol.asyncIterator]().next()).value\n } catch (err) {\n if (err instanceof ConnectError) {\n if (err.code === Code.Unavailable) {\n throw new NotFoundError('Sandbox is probably not running anymore')\n }\n }\n\n throw err\n }\n if (startEvent.event?.case !== 'start') {\n throw new Error('Expected start event')\n }\n\n return startEvent.event.value\n}\n\nclass EnvdApiClient {\n readonly api: ReturnType<typeof createClient<paths>>\n readonly version: string | undefined\n\n constructor(\n config: Pick<ConnectionConfig, 'apiUrl' | 'logger' | 'accessToken'> & { fetch?: (request: Request) => ReturnType<typeof fetch>, headers?: Record<string, string> },\n metadata: {\n version?: string\n },\n ) {\n this.api = createClient({\n baseUrl: config.apiUrl,\n fetch: config?.fetch,\n headers: config?.headers,\n // keepalive: true, // TODO: Return keepalive\n })\n this.version = metadata.version\n\n if (config.logger) {\n this.api.use(createApiLogger(config.logger))\n }\n }\n}\n\nexport type { components, paths }\nexport { EnvdApiClient }\n","import { Code, ConnectError } from '@connectrpc/connect'\nimport { runtime } from '../api/metadata'\nimport { defaultUsername } from '../connectionConfig'\n\nimport { SandboxError, TimeoutError, formatSandboxTimeoutError, InvalidArgumentError, NotFoundError, AuthenticationError } from '../errors'\n\n\nexport function handleRpcError(err: unknown): Error {\n if (err instanceof ConnectError) {\n switch (err.code) {\n case Code.InvalidArgument:\n return new InvalidArgumentError(err.message)\n case Code.Unauthenticated:\n return new AuthenticationError(err.message)\n case Code.NotFound:\n return new NotFoundError(err.message)\n case Code.Unavailable:\n return formatSandboxTimeoutError(err.message)\n case Code.Canceled:\n return new TimeoutError(\n `${err.message}: This error is likely due to exceeding 'requestTimeoutMs'. You can pass the request timeout value as an option when making the request.`\n )\n case Code.DeadlineExceeded:\n return new TimeoutError(\n `${err.message}: This error is likely due to exceeding 'timeoutMs' — 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.`\n )\n default:\n return new SandboxError(`${err.code}: ${err.message}`)\n }\n }\n\n return err as Error\n}\n\nfunction encode64(value: string): string {\n switch (runtime) {\n case 'deno':\n return btoa(value)\n case 'node':\n return Buffer.from(value).toString('base64')\n case 'bun':\n return Buffer.from(value).toString('base64')\n default:\n return btoa(value)\n }\n}\n\nexport function authenticationHeader(username?: string): Record<string, string> {\n const value = `${username || defaultUsername}:`\n\n const encoded = encode64(value)\n\n return { 'Authorization': `Basic ${encoded}` }\n}\n","// @generated by protoc-gen-es v2.6.2 with parameter \"target=ts\"\n// @generated from file filesystem/filesystem.proto (package filesystem, syntax proto3)\n/* eslint-disable */\n\nimport type { GenEnum, GenFile, GenMessage, GenService } from \"@bufbuild/protobuf/codegenv2\";\nimport { enumDesc, fileDesc, messageDesc, serviceDesc } from \"@bufbuild/protobuf/codegenv2\";\nimport type { Timestamp } from \"@bufbuild/protobuf/wkt\";\nimport { file_google_protobuf_timestamp } from \"@bufbuild/protobuf/wkt\";\nimport type { Message } from \"@bufbuild/protobuf\";\n\n/**\n * Describes the file filesystem/filesystem.proto.\n */\nexport const file_filesystem_filesystem: GenFile = /*@__PURE__*/\n fileDesc(\"ChtmaWxlc3lzdGVtL2ZpbGVzeXN0ZW0ucHJvdG8SCmZpbGVzeXN0ZW0iMgoLTW92ZVJlcXVlc3QSDgoGc291cmNlGAEgASgJEhMKC2Rlc3RpbmF0aW9uGAIgASgJIjQKDE1vdmVSZXNwb25zZRIkCgVlbnRyeRgBIAEoCzIVLmZpbGVzeXN0ZW0uRW50cnlJbmZvIh4KDk1ha2VEaXJSZXF1ZXN0EgwKBHBhdGgYASABKAkiNwoPTWFrZURpclJlc3BvbnNlEiQKBWVudHJ5GAEgASgLMhUuZmlsZXN5c3RlbS5FbnRyeUluZm8iHQoNUmVtb3ZlUmVxdWVzdBIMCgRwYXRoGAEgASgJIhAKDlJlbW92ZVJlc3BvbnNlIhsKC1N0YXRSZXF1ZXN0EgwKBHBhdGgYASABKAkiNAoMU3RhdFJlc3BvbnNlEiQKBWVudHJ5GAEgASgLMhUuZmlsZXN5c3RlbS5FbnRyeUluZm8i/QEKCUVudHJ5SW5mbxIMCgRuYW1lGAEgASgJEiIKBHR5cGUYAiABKA4yFC5maWxlc3lzdGVtLkZpbGVUeXBlEgwKBHBhdGgYAyABKAkSDAoEc2l6ZRgEIAEoAxIMCgRtb2RlGAUgASgNEhMKC3Blcm1pc3Npb25zGAYgASgJEg0KBW93bmVyGAcgASgJEg0KBWdyb3VwGAggASgJEjEKDW1vZGlmaWVkX3RpbWUYCSABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wEhsKDnN5bWxpbmtfdGFyZ2V0GAogASgJSACIAQFCEQoPX3N5bWxpbmtfdGFyZ2V0Ii0KDkxpc3REaXJSZXF1ZXN0EgwKBHBhdGgYASABKAkSDQoFZGVwdGgYAiABKA0iOQoPTGlzdERpclJlc3BvbnNlEiYKB2VudHJpZXMYASADKAsyFS5maWxlc3lzdGVtLkVudHJ5SW5mbyIyCg9XYXRjaERpclJlcXVlc3QSDAoEcGF0aBgBIAEoCRIRCglyZWN1cnNpdmUYAiABKAgiRAoPRmlsZXN5c3RlbUV2ZW50EgwKBG5hbWUYASABKAkSIwoEdHlwZRgCIAEoDjIVLmZpbGVzeXN0ZW0uRXZlbnRUeXBlIuABChBXYXRjaERpclJlc3BvbnNlEjgKBXN0YXJ0GAEgASgLMicuZmlsZXN5c3RlbS5XYXRjaERpclJlc3BvbnNlLlN0YXJ0RXZlbnRIABIxCgpmaWxlc3lzdGVtGAIgASgLMhsuZmlsZXN5c3RlbS5GaWxlc3lzdGVtRXZlbnRIABI7CglrZWVwYWxpdmUYAyABKAsyJi5maWxlc3lzdGVtLldhdGNoRGlyUmVzcG9uc2UuS2VlcEFsaXZlSAAaDAoKU3RhcnRFdmVudBoLCglLZWVwQWxpdmVCBwoFZXZlbnQiNwoUQ3JlYXRlV2F0Y2hlclJlcXVlc3QSDAoEcGF0aBgBIAEoCRIRCglyZWN1cnNpdmUYAiABKAgiKwoVQ3JlYXRlV2F0Y2hlclJlc3BvbnNlEhIKCndhdGNoZXJfaWQYASABKAkiLQoXR2V0V2F0Y2hlckV2ZW50c1JlcXVlc3QSEgoKd2F0Y2hlcl9pZBgBIAEoCSJHChhHZXRXYXRjaGVyRXZlbnRzUmVzcG9uc2USKwoGZXZlbnRzGAEgAygLMhsuZmlsZXN5c3RlbS5GaWxlc3lzdGVtRXZlbnQiKgoUUmVtb3ZlV2F0Y2hlclJlcXVlc3QSEgoKd2F0Y2hlcl9pZBgBIAEoCSIXChVSZW1vdmVXYXRjaGVyUmVzcG9uc2UqUgoIRmlsZVR5cGUSGQoVRklMRV9UWVBFX1VOU1BFQ0lGSUVEEAASEgoORklMRV9UWVBFX0ZJTEUQARIXChNGSUxFX1RZUEVfRElSRUNUT1JZEAIqmAEKCUV2ZW50VHlwZRIaChZFVkVOVF9UWVBFX1VOU1BFQ0lGSUVEEAASFQoRRVZFTlRfVFlQRV9DUkVBVEUQARIUChBFVkVOVF9UWVBFX1dSSVRFEAISFQoRRVZFTlRfVFlQRV9SRU1PVkUQAxIVChFFVkVOVF9UWVBFX1JFTkFNRRAEEhQKEEVWRU5UX1RZUEVfQ0hNT0QQBTKfBQoKRmlsZXN5c3RlbRI5CgRTdGF0EhcuZmlsZXN5c3RlbS5TdGF0UmVxdWVzdBoYLmZpbGVzeXN0ZW0uU3RhdFJlc3BvbnNlEkIKB01ha2VEaXISGi5maWxlc3lzdGVtLk1ha2VEaXJSZXF1ZXN0GhsuZmlsZXN5c3RlbS5NYWtlRGlyUmVzcG9uc2USOQoETW92ZRIXLmZpbGVzeXN0ZW0uTW92ZVJlcXVlc3QaGC5maWxlc3lzdGVtLk1vdmVSZXNwb25zZRJCCgdMaXN0RGlyEhouZmlsZXN5c3RlbS5MaXN0RGlyUmVxdWVzdBobLmZpbGVzeXN0ZW0uTGlzdERpclJlc3BvbnNlEj8KBlJlbW92ZRIZLmZpbGVzeXN0ZW0uUmVtb3ZlUmVxdWVzdBoaLmZpbGVzeXN0ZW0uUmVtb3ZlUmVzcG9uc2USRwoIV2F0Y2hEaXISGy5maWxlc3lzdGVtLldhdGNoRGlyUmVxdWVzdBocLmZpbGVzeXN0ZW0uV2F0Y2hEaXJSZXNwb25zZTABElQKDUNyZWF0ZVdhdGNoZXISIC5maWxlc3lzdGVtLkNyZWF0ZVdhdGNoZXJSZXF1ZXN0GiEuZmlsZXN5c3RlbS5DcmVhdGVXYXRjaGVyUmVzcG9uc2USXQoQR2V0V2F0Y2hlckV2ZW50cxIjLmZpbGVzeXN0ZW0uR2V0V2F0Y2hlckV2ZW50c1JlcXVlc3QaJC5maWxlc3lzdGVtLkdldFdhdGNoZXJFdmVudHNSZXNwb25zZRJUCg1SZW1vdmVXYXRjaGVyEiAuZmlsZXN5c3RlbS5SZW1vdmVXYXRjaGVyUmVxdWVzdBohLmZpbGVzeXN0ZW0uUmVtb3ZlV2F0Y2hlclJlc3BvbnNlQmkKDmNvbS5maWxlc3lzdGVtQg9GaWxlc3lzdGVtUHJvdG9QAaICA0ZYWKoCCkZpbGVzeXN0ZW3KAgpGaWxlc3lzdGVt4gIWRmlsZXN5c3RlbVxHUEJNZXRhZGF0YeoCCkZpbGVzeXN0ZW1iBnByb3RvMw\", [file_google_protobuf_timestamp]);\n\n/**\n * @generated from message filesystem.MoveRequest\n */\nexport type MoveRequest = Message<\"filesystem.MoveRequest\"> & {\n /**\n * @generated from field: string source = 1;\n */\n source: string;\n\n /**\n * @generated from field: string destination = 2;\n */\n destination: string;\n};\n\n/**\n * Describes the message filesystem.MoveRequest.\n * Use `create(MoveRequestSchema)` to create a new message.\n */\nexport const MoveRequestSchema: GenMessage<MoveRequest> = /*@__PURE__*/\n messageDesc(file_filesystem_filesystem, 0);\n\n/**\n * @generated from message filesystem.MoveResponse\n */\nexport type MoveResponse = Message<\"filesystem.MoveResponse\"> & {\n /**\n * @generated from field: filesystem.EntryInfo entry = 1;\n */\n entry?: EntryInfo;\n};\n\n/**\n * Describes the message filesystem.MoveResponse.\n * Use `create(MoveResponseSchema)` to create a new message.\n */\nexport const MoveResponseSchema: GenMessage<MoveResponse> = /*@__PURE__*/\n messageDesc(file_filesystem_filesystem, 1);\n\n/**\n * @generated from message filesystem.MakeDirRequest\n */\nexport type MakeDirRequest = Message<\"filesystem.MakeDirRequest\"> & {\n /**\n * @generated from field: string path = 1;\n */\n path: string;\n};\n\n/**\n * Describes the message filesystem.MakeDirRequest.\n * Use `create(MakeDirRequestSchema)` to create a new message.\n */\nexport const MakeDirRequestSchema: GenMessage<MakeDirRequest> = /*@__PURE__*/\n messageDesc(file_filesystem_filesystem, 2);\n\n/**\n * @generated from message filesystem.MakeDirResponse\n */\nexport type MakeDirResponse = Message<\"filesystem.MakeDirResponse\"> & {\n /**\n * @generated from field: filesystem.EntryInfo entry = 1;\n */\n entry?: EntryInfo;\n};\n\n/**\n * Describes the message filesystem.MakeDirResponse.\n * Use `create(MakeDirResponseSchema)` to create a new message.\n */\nexport const MakeDirResponseSchema: GenMessage<MakeDirResponse> = /*@__PURE__*/\n messageDesc(file_filesystem_filesystem, 3);\n\n/**\n * @generated from message filesystem.RemoveRequest\n */\nexport type RemoveRequest = Message<\"filesystem.RemoveRequest\"> & {\n /**\n * @generated from field: string path = 1;\n */\n path: string;\n};\n\n/**\n * Describes the message filesystem.RemoveRequest.\n * Use `create(RemoveRequestSchema)` to create a new message.\n */\nexport const RemoveRequestSchema: GenMessage<RemoveRequest> = /*@__PURE__*/\n messageDesc(file_filesystem_filesystem, 4);\n\n/**\n * @generated from message filesystem.RemoveResponse\n */\nexport type RemoveResponse = Message<\"filesystem.RemoveResponse\"> & {\n};\n\n/**\n * Describes the message filesystem.RemoveResponse.\n * Use `create(RemoveResponseSchema)` to create a new message.\n */\nexport const RemoveResponseSchema: GenMessage<RemoveResponse> = /*@__PURE__*/\n messageDesc(file_filesystem_filesystem, 5);\n\n/**\n * @generated from message filesystem.StatRequest\n */\nexport type StatRequest = Message<\"filesystem.StatRequest\"> & {\n /**\n * @generated from field: string path = 1;\n */\n path: string;\n};\n\n/**\n * Describes the message filesystem.StatRequest.\n * Use `create(StatRequestSchema)` to create a new message.\n */\nexport const StatRequestSchema: GenMessage<StatRequest> = /*@__PURE__*/\n messageDesc(file_filesystem_filesystem, 6);\n\n/**\n * @generated from message filesystem.StatResponse\n */\nexport type StatResponse = Message<\"filesystem.StatResponse\"> & {\n /**\n * @generated from field: filesystem.EntryInfo entry = 1;\n */\n entry?: EntryInfo;\n};\n\n/**\n * Describes the message filesystem.StatResponse.\n * Use `create(StatResponseSchema)` to create a new message.\n */\nexport const StatResponseSchema: GenMessage<StatResponse> = /*@__PURE__*/\n messageDesc(file_filesystem_filesystem, 7);\n\n/**\n * @generated from message filesystem.EntryInfo\n */\nexport type EntryInfo = Message<\"filesystem.EntryInfo\"> & {\n /**\n * @generated from field: string name = 1;\n */\n name: string;\n\n /**\n * @generated from field: filesystem.FileType type = 2;\n */\n type: FileType;\n\n /**\n * @generated from field: string path = 3;\n */\n path: string;\n\n /**\n * @generated from field: int64 size = 4;\n */\n size: bigint;\n\n /**\n * @generated from field: uint32 mode = 5;\n */\n mode: number;\n\n /**\n * @generated from field: string permissions = 6;\n */\n permissions: string;\n\n /**\n * @generated from field: string owner = 7;\n */\n owner: string;\n\n /**\n * @generated from field: string group = 8;\n */\n group: string;\n\n /**\n * @generated from field: google.protobuf.Timestamp modified_time = 9;\n */\n modifiedTime?: Timestamp;\n\n /**\n * If the entry is a symlink, this field contains the target of the symlink.\n *\n * @generated from field: optional string symlink_target = 10;\n */\n symlinkTarget?: string;\n};\n\n/**\n * Describes the message filesystem.EntryInfo.\n * Use `create(EntryInfoSchema)` to create a new message.\n */\nexport const EntryInfoSchema: GenMessage<EntryInfo> = /*@__PURE__*/\n messageDesc(file_filesystem_filesystem, 8);\n\n/**\n * @generated from message filesystem.ListDirRequest\n */\nexport type ListDirRequest = Message<\"filesystem.ListDirRequest\"> & {\n /**\n * @generated from field: string path = 1;\n */\n path: string;\n\n /**\n * @generated from field: uint32 depth = 2;\n */\n depth: number;\n};\n\n/**\n * Describes the message filesystem.ListDirRequest.\n * Use `create(ListDirRequestSchema)` to create a new message.\n */\nexport const ListDirRequestSchema: GenMessage<ListDirRequest> = /*@__PURE__*/\n messageDesc(file_filesystem_filesystem, 9);\n\n/**\n * @generated from message filesystem.ListDirResponse\n */\nexport type ListDirResponse = Message<\"filesystem.ListDirResponse\"> & {\n /**\n * @generated from field: repeated filesystem.EntryInfo entries = 1;\n */\n entries: EntryInfo[];\n};\n\n/**\n * Describes the message filesystem.ListDirResponse.\n * Use `create(ListDirResponseSchema)` to create a new message.\n */\nexport const ListDirResponseSchema: GenMessage<ListDirResponse> = /*@__PURE__*/\n messageDesc(file_filesystem_filesystem, 10);\n\n/**\n * @generated from message filesystem.WatchDirRequest\n */\nexport type WatchDirRequest = Message<\"filesystem.WatchDirRequest\"> & {\n /**\n * @generated from field: string path = 1;\n */\n path: string;\n\n /**\n * @generated from field: bool recursive = 2;\n */\n recursive: boolean;\n};\n\n/**\n * Describes the message filesystem.WatchDirRequest.\n * Use `create(WatchDirRequestSchema)` to create a new message.\n */\nexport const WatchDirRequestSchema: GenMessage<WatchDirRequest> = /*@__PURE__*/\n messageDesc(file_filesystem_filesystem, 11);\n\n/**\n * @generated from message filesystem.FilesystemEvent\n */\nexport type FilesystemEvent = Message<\"filesystem.FilesystemEvent\"> & {\n /**\n * @generated from field: string name = 1;\n */\n name: string;\n\n /**\n * @generated from field: filesystem.EventType type = 2;\n */\n type: EventType;\n};\n\n/**\n * Describes the message filesystem.FilesystemEvent.\n * Use `create(FilesystemEventSchema)` to create a new message.\n */\nexport const FilesystemEventSchema: GenMessage<FilesystemEvent> = /*@__PURE__*/\n messageDesc(file_filesystem_filesystem, 12);\n\n/**\n * @generated from message filesystem.WatchDirResponse\n */\nexport type WatchDirResponse = Message<\"filesystem.WatchDirResponse\"> & {\n /**\n * @generated from oneof filesystem.WatchDirResponse.event\n */\n event: {\n /**\n * @generated from field: filesystem.WatchDirResponse.StartEvent start = 1;\n */\n value: WatchDirResponse_StartEvent;\n case: \"start\";\n } | {\n /**\n * @generated from field: filesystem.FilesystemEvent filesystem = 2;\n */\n value: FilesystemEvent;\n case: \"filesystem\";\n } | {\n /**\n * @generated from field: filesystem.WatchDirResponse.KeepAlive keepalive = 3;\n */\n value: WatchDirResponse_KeepAlive;\n case: \"keepalive\";\n } | { case: undefined; value?: undefined };\n};\n\n/**\n * Describes the message filesystem.WatchDirResponse.\n * Use `create(WatchDirResponseSchema)` to create a new message.\n */\nexport const WatchDirResponseSchema: GenMessage<WatchDirResponse> = /*@__PURE__*/\n messageDesc(file_filesystem_filesystem, 13);\n\n/**\n * @generated from message filesystem.WatchDirResponse.StartEvent\n */\nexport type WatchDirResponse_StartEvent = Message<\"filesystem.WatchDirResponse.StartEvent\"> & {\n};\n\n/**\n * Describes the message filesystem.WatchDirResponse.StartEvent.\n * Use `create(WatchDirResponse_StartEventSchema)` to create a new message.\n */\nexport const WatchDirResponse_StartEventSchema: GenMessage<WatchDirResponse_StartEvent> = /*@__PURE__*/\n messageDesc(file_filesystem_filesystem, 13, 0);\n\n/**\n * @generated from message filesystem.WatchDirResponse.KeepAlive\n */\nexport type WatchDirResponse_KeepAlive = Message<\"filesystem.WatchDirResponse.KeepAlive\"> & {\n};\n\n/**\n * Describes the message filesystem.WatchDirResponse.KeepAlive.\n * Use `create(WatchDirResponse_KeepAliveSchema)` to create a new message.\n */\nexport const WatchDirResponse_KeepAliveSchema: GenMessage<WatchDirResponse_KeepAlive> = /*@__PURE__*/\n messageDesc(file_filesystem_filesystem, 13, 1);\n\n/**\n * @generated from message filesystem.CreateWatcherRequest\n */\nexport type CreateWatcherRequest = Message<\"filesystem.CreateWatcherRequest\"> & {\n /**\n * @generated from field: string path = 1;\n */\n path: string;\n\n /**\n * @generated from field: bool recursive = 2;\n */\n recursive: boolean;\n};\n\n/**\n * Describes the message filesystem.CreateWatcherRequest.\n * Use `create(CreateWatcherRequestSchema)` to create a new message.\n */\nexport const CreateWatcherRequestSchema: GenMessage<CreateWatcherRequest> = /*@__PURE__*/\n messageDesc(file_filesystem_filesystem, 14);\n\n/**\n * @generated from message filesystem.CreateWatcherResponse\n */\nexport type CreateWatcherResponse = Message<\"filesystem.CreateWatcherResponse\"> & {\n /**\n * @generated from field: string watcher_id = 1;\n */\n watcherId: string;\n};\n\n/**\n * Describes the message filesystem.CreateWatcherResponse.\n * Use `create(CreateWatcherResponseSchema)` to create a new message.\n */\nexport const CreateWatcherResponseSchema: GenMessage<CreateWatcherResponse> = /*@__PURE__*/\n messageDesc(file_filesystem_filesystem, 15);\n\n/**\n * @generated from message filesystem.GetWatcherEventsRequest\n */\nexport type GetWatcherEventsRequest = Message<\"filesystem.GetWatcherEventsRequest\"> & {\n /**\n * @generated from field: string watcher_id = 1;\n */\n watcherId: string;\n};\n\n/**\n * Describes the message filesystem.GetWatcherEventsRequest.\n * Use `create(GetWatcherEventsRequestSchema)` to create a new message.\n */\nexport const GetWatcherEventsRequestSchema: GenMessage<GetWatcherEventsRequest> = /*@__PURE__*/\n messageDesc(file_filesystem_filesystem, 16);\n\n/**\n * @generated from message filesystem.GetWatcherEventsResponse\n */\nexport type GetWatcherEventsResponse = Message<\"filesystem.GetWatcherEventsResponse\"> & {\n /**\n * @generated from field: repeated filesystem.FilesystemEvent events = 1;\n */\n events: FilesystemEvent[];\n};\n\n/**\n * Describes the message filesystem.GetWatcherEventsResponse.\n * Use `create(GetWatcherEventsResponseSchema)` to create a new message.\n */\nexport const GetWatcherEventsResponseSchema: GenMessage<GetWatcherEventsResponse> = /*@__PURE__*/\n messageDesc(file_filesystem_filesystem, 17);\n\n/**\n * @generated from message filesystem.RemoveWatcherRequest\n */\nexport type RemoveWatcherRequest = Message<\"filesystem.RemoveWatcherRequest\"> & {\n /**\n * @generated from field: string watcher_id = 1;\n */\n watcherId: string;\n};\n\n/**\n * Describes the message filesystem.RemoveWatcherRequest.\n * Use `create(RemoveWatcherRequestSchema)` to create a new message.\n */\nexport const RemoveWatcherRequestSchema: GenMessage<RemoveWatcherRequest> = /*@__PURE__*/\n messageDesc(file_filesystem_filesystem, 18);\n\n/**\n * @generated from message filesystem.RemoveWatcherResponse\n */\nexport type RemoveWatcherResponse = Message<\"filesystem.RemoveWatcherResponse\"> & {\n};\n\n/**\n * Describes the message filesystem.RemoveWatcherResponse.\n * Use `create(RemoveWatcherResponseSchema)` to create a new message.\n */\nexport const RemoveWatcherResponseSchema: GenMessage<RemoveWatcherResponse> = /*@__PURE__*/\n messageDesc(file_filesystem_filesystem, 19);\n\n/**\n * @generated from enum filesystem.FileType\n */\nexport enum FileType {\n /**\n * @generated from enum value: FILE_TYPE_UNSPECIFIED = 0;\n */\n UNSPECIFIED = 0,\n\n /**\n * @generated from enum value: FILE_TYPE_FILE = 1;\n */\n FILE = 1,\n\n /**\n * @generated from enum value: FILE_TYPE_DIRECTORY = 2;\n */\n DIRECTORY = 2,\n}\n\n/**\n * Describes the enum filesystem.FileType.\n */\nexport const FileTypeSchema: GenEnum<FileType> = /*@__PURE__*/\n enumDesc(file_filesystem_filesystem, 0);\n\n/**\n * @generated from enum filesystem.EventType\n */\nexport enum EventType {\n /**\n * @generated from enum value: EVENT_TYPE_UNSPECIFIED = 0;\n */\n UNSPECIFIED = 0,\n\n /**\n * @generated from enum value: EVENT_TYPE_CREATE = 1;\n */\n CREATE = 1,\n\n /**\n * @generated from enum value: EVENT_TYPE_WRITE = 2;\n */\n WRITE = 2,\n\n /**\n * @generated from enum value: EVENT_TYPE_REMOVE = 3;\n */\n REMOVE = 3,\n\n /**\n * @generated from enum value: EVENT_TYPE_RENAME = 4;\n */\n RENAME = 4,\n\n /**\n * @generated from enum value: EVENT_TYPE_CHMOD = 5;\n */\n CHMOD = 5,\n}\n\n/**\n * Describes the enum filesystem.EventType.\n */\nexport const EventTypeSchema: GenEnum<EventType> = /*@__PURE__*/\n enumDesc(file_filesystem_filesystem, 1);\n\n/**\n * @generated from service filesystem.Filesystem\n */\nexport const Filesystem: GenService<{\n /**\n * @generated from rpc filesystem.Filesystem.Stat\n */\n stat: {\n methodKind: \"unary\";\n input: typeof StatRequestSchema;\n output: typeof StatResponseSchema;\n },\n /**\n * @generated from rpc filesystem.Filesystem.MakeDir\n */\n makeDir: {\n methodKind: \"unary\";\n input: typeof MakeDirRequestSchema;\n output: typeof MakeDirResponseSchema;\n },\n /**\n * @generated from rpc filesystem.Filesystem.Move\n */\n move: {\n methodKind: \"unary\";\n input: typeof MoveRequestSchema;\n output: typeof MoveResponseSchema;\n },\n /**\n * @generated from rpc filesystem.Filesystem.ListDir\n */\n listDir: {\n methodKind: \"unary\";\n input: typeof ListDirRequestSchema;\n output: typeof ListDirResponseSchema;\n },\n /**\n * @generated from rpc filesystem.Filesystem.Remove\n */\n remove: {\n methodKind: \"unary\";\n input: typeof RemoveRequestSchema;\n output: typeof RemoveResponseSchema;\n },\n /**\n * @generated from rpc filesystem.Filesystem.WatchDir\n */\n watchDir: {\n methodKind: \"server_streaming\";\n input: typeof WatchDirRequestSchema;\n output: typeof WatchDirResponseSchema;\n },\n /**\n * Non-streaming versions of WatchDir\n *\n * @generated from rpc filesystem.Filesystem.CreateWatcher\n */\n createWatcher: {\n methodKind: \"unary\";\n input: typeof CreateWatcherRequestSchema;\n output: typeof CreateWatcherResponseSchema;\n },\n /**\n * @generated from rpc filesystem.Filesystem.GetWatcherEvents\n */\n getWatcherEvents: {\n methodKind: \"unary\";\n input: typeof GetWatcherEventsRequestSchema;\n output: typeof GetWatcherEventsResponseSchema;\n },\n /**\n * @generated from rpc filesystem.Filesystem.RemoveWatcher\n */\n removeWatcher: {\n methodKind: \"unary\";\n input: typeof RemoveWatcherRequestSchema;\n output: typeof RemoveWatcherResponseSchema;\n },\n}> = /*@__PURE__*/\n serviceDesc(file_filesystem_filesystem, 0);\n\n","import { handleRpcError } from '../../envd/rpc'\nimport {\n EventType,\n WatchDirResponse,\n} from '../../envd/filesystem/filesystem_pb'\n\n/**\n * Sandbox filesystem event types.\n */\nexport enum FilesystemEventType {\n /**\n * Filesystem object permissions were changed.\n */\n CHMOD = 'chmod',\n /**\n * Filesystem object was created.\n */\n CREATE = 'create',\n /**\n * Filesystem object was removed.\n */\n REMOVE = 'remove',\n /**\n * Filesystem object was renamed.\n */\n RENAME = 'rename',\n /**\n * Filesystem object was written to.\n */\n WRITE = 'write',\n}\n\nfunction mapEventType(type: EventType) {\n switch (type) {\n case EventType.CHMOD:\n return FilesystemEventType.CHMOD\n case EventType.CREATE:\n return FilesystemEventType.CREATE\n case EventType.REMOVE:\n return FilesystemEventType.REMOVE\n case EventType.RENAME:\n return FilesystemEventType.RENAME\n case EventType.WRITE:\n return FilesystemEventType.WRITE\n }\n}\n\n/**\n * Information about a filesystem event.\n */\nexport interface FilesystemEvent {\n /**\n * Relative path to the filesystem object.\n */\n name: string\n /**\n * Filesystem operation event type.\n */\n type: FilesystemEventType\n}\n\n/**\n * Handle for watching a directory in the sandbox filesystem.\n *\n * Use {@link WatchHandle.stop} to stop watching the directory.\n */\nexport class WatchHandle {\n constructor(\n private readonly handleStop: () => void,\n private readonly events: AsyncIterable<WatchDirResponse>,\n private readonly onEvent?: (event: FilesystemEvent) => void | Promise<void>,\n private readonly onExit?: (err?: Error) => void | Promise<void>\n ) {\n this.handleEvents()\n }\n\n /**\n * Stop watching the directory.\n */\n async stop() {\n this.handleStop()\n }\n\n private async *iterateEvents() {\n try {\n for await (const event of this.events) {\n switch (event.event.case) {\n case 'filesystem':\n yield event.event\n break\n }\n }\n } catch (err) {\n throw handleRpcError(err)\n }\n }\n\n private async handleEvents() {\n try {\n for await (const event of this.iterateEvents()) {\n const eventType = mapEventType(event.value.type)\n if (eventType === undefined) {\n continue\n }\n\n this.onEvent?.({\n name: event.value.name,\n type: eventType,\n })\n }\n this.onExit?.()\n } catch (err) {\n this.onExit?.(err as Error)\n }\n }\n}\n","export const ENVD_VERSION_RECURSIVE_WATCH = '0.1.4'","import { handleRpcError } from '../../envd/rpc'\nimport { SandboxError } from '../../errors'\nimport { ConnectResponse, StartResponse } from '../../envd/process/process_pb'\n\ndeclare const __brand: unique symbol\ntype Brand<B> = { [__brand]: B }\nexport type Branded<T, B> = T & Brand<B>\n\nexport type Stdout = Branded<string, 'stdout'>\nexport type Stderr = Branded<string, 'stderr'>\nexport type PtyOutput = Branded<Uint8Array, 'pty'>\n\n/**\n * Command execution result.\n */\nexport interface CommandResult {\n /**\n * Command execution exit code.\n * `0` if the command finished successfully.\n */\n exitCode: number\n /**\n * Error message from command execution if it failed.\n */\n error?: string\n /**\n * Command stdout output.\n */\n stdout: string\n /**\n * Command stderr output.\n */\n stderr: string\n}\n\n/**\n * Error thrown when a command exits with a non-zero exit code.\n */\nexport class CommandExitError extends SandboxError implements CommandResult {\n constructor(private readonly result: CommandResult) {\n super(result.error)\n this.name = 'CommandExitError'\n }\n\n /**\n * Command execution exit code.\n * `0` if the command finished successfully.\n */\n get exitCode() {\n return this.result.exitCode\n }\n\n /**\n * Error message from command execution.\n */\n get error() {\n return this.result.error\n }\n\n /**\n * Command execution stdout output.\n */\n get stdout() {\n return this.result.stdout\n }\n\n /**\n * Command execution stderr output.\n */\n get stderr() {\n return this.result.stderr\n }\n}\n\n/**\n * Command execution handle.\n *\n * It provides methods for waiting for the command to finish, retrieving stdout/stderr, and killing the command.\n *\n * @property {number} pid process ID of the command.\n */\nexport class CommandHandle\n implements\n Omit<CommandResult, 'exitCode' | 'error'>,\n Partial<Pick<CommandResult, 'exitCode' | 'error'>>\n{\n private _stdout = ''\n private _stderr = ''\n\n private result?: CommandResult\n private iterationError?: Error\n\n private readonly _wait: Promise<void>\n\n /**\n * @hidden\n * @internal\n * @access protected\n */\n constructor(\n readonly pid: number,\n private readonly handleDisconnect: () => void,\n private readonly handleKill: () => Promise<boolean>,\n private readonly events: AsyncIterable<ConnectResponse | StartResponse>,\n private readonly onStdout?: (stdout: string) => void | Promise<void>,\n private readonly onStderr?: (stderr: string) => void | Promise<void>,\n private readonly onPty?: (pty: Uint8Array) => void | Promise<void>\n ) {\n this._wait = this.handleEvents()\n }\n\n /**\n * Command execution exit code.\n * `0` if the command finished successfully.\n * \n * It is `undefined` if the command is still running.\n */\n get exitCode() {\n return this.result?.exitCode\n }\n\n /**\n * Error message from command execution.\n */\n get error() {\n return this.result?.error\n }\n\n /**\n * Command execution stderr output.\n */\n get stderr() {\n return this._stderr\n }\n\n /**\n * Command execution stdout output.\n */\n get stdout() {\n return this._stdout\n }\n\n /**\n * Wait for the command to finish and return the result.\n * If the command exits with a non-zero exit code, it throws a `CommandExitError`.\n * \n * @returns `CommandResult` result of command execution.\n */\n async wait() {\n await this._wait\n\n if (this.iterationError) {\n throw this.iterationError\n }\n\n if (!this.result) {\n throw new SandboxError('Process exited without a result')\n }\n\n if (this.result.exitCode !== 0) {\n throw new CommandExitError(this.result)\n }\n\n return this.result\n }\n\n /**\n * Disconnect from the command.\n * \n * The command is not killed, but SDK stops receiving events from the command.\n * You can reconnect to the command using {@link Commands.connect}.\n */\n async disconnect() {\n this.handleDisconnect()\n }\n\n /**\n * Kill the command.\n * It uses `SIGKILL` signal to kill the command.\n * \n * @returns `true` if the command was killed successfully, `false` if the command was not found.\n */\n async kill() {\n return await this.handleKill()\n }\n\n private async *iterateEvents(): AsyncGenerator<\n [Stdout, null, null] | [null, Stderr, null] | [null, null, PtyOutput]\n > {\n for await (const event of this.events) {\n const e = event?.event?.event\n let out: string | undefined\n\n switch (e?.case) {\n case 'data':\n switch (e.value.output.case) {\n case 'stdout':\n out = new TextDecoder().decode(e.value.output.value)\n this._stdout += out\n yield [out as Stdout, null, null]\n break\n case 'stderr':\n out = new TextDecoder().decode(e.value.output.value)\n this._stderr += out\n yield [null, out as Stderr, null]\n break\n case 'pty':\n yield [null, null, e.value.output.value as PtyOutput]\n break\n }\n break\n case 'end':\n this.result = {\n exitCode: e.value.exitCode,\n error: e.value.error,\n stdout: this.stdout,\n stderr: this.stderr,\n }\n break\n }\n // TODO: Handle empty events like in python SDK\n }\n }\n\n private async handleEvents() {\n try {\n for await (const [stdout, stderr, pty] of this.iterateEvents()) {\n if (stdout !== null) {\n this.onStdout?.(stdout)\n } else if (stderr !== null) {\n this.onStderr?.(stderr)\n } else if (pty) {\n this.onPty?.(pty)\n }\n }\n } catch (e) {\n this.iterationError = handleRpcError(e)\n }\n }\n}\n","import { createConnectTransport } from '@connectrpc/connect-web'\n\nimport {\n ConnectionConfig,\n ConnectionOpts,\n DEFAULT_SANDBOX_TIMEOUT_MS,\n defaultUsername,\n Username,\n} from '../connectionConfig'\nimport { EnvdApiClient, handleEnvdApiError } from '../envd/api'\nimport { createRpcLogger } from '../logs'\nimport { Commands, Pty } from './commands'\nimport { Filesystem } from './filesystem'\nimport {\n SandboxOpts,\n SandboxConnectOpts,\n SandboxMetricsOpts,\n SandboxApi,\n SandboxListOpts,\n SandboxPaginator,\n SandboxBetaCreateOpts,\n} from './sandboxApi'\nimport { getSignature } from './signature'\nimport { compareVersions } from 'compare-versions'\nimport { SandboxError } from '../errors'\n\n/**\n * Options for sandbox upload/download URL generation.\n */\nexport interface SandboxUrlOpts {\n /**\n * Use signature expiration for the URL.\n * Optional parameter to set the expiration time for the signature in seconds.\n */\n useSignatureExpiration?: number\n\n /**\n * User that will be used to access the file.\n */\n user?: Username\n}\n\n/**\n * PPIO agent sandbox is a secure and isolated cloud environment.\n *\n * The sandbox allows you to:\n * - Access Linux OS\n * - Create, list, and delete files and directories\n * - Run commands\n * - Run isolated code\n * - Access the internet\n *\n * Check docs [here](https://ppio.com/docs/sandbox/overview).\n *\n * Use {@link Sandbox.create} to create a new sandbox.\n *\n * @example\n * ```ts\n * import { Sandbox } from '@ppio-sandbox/core'\n *\n * const sandbox = await Sandbox.create()\n * ```\n */\nexport class Sandbox extends SandboxApi {\n protected static readonly defaultTemplate: string = 'base'\n protected static readonly defaultSandboxTimeoutMs = DEFAULT_SANDBOX_TIMEOUT_MS\n\n /**\n * Module for interacting with the sandbox filesystem\n */\n readonly files: Filesystem\n /**\n * Module for running commands in the sandbox\n */\n readonly commands: Commands\n /**\n * Module for interacting with the sandbox pseudo-terminals\n */\n readonly pty: Pty\n\n /**\n * Unique identifier of the sandbox.\n */\n readonly sandboxId: string\n\n /**\n * Domain where the sandbox is hosted.\n */\n readonly sandboxDomain: string\n\n protected readonly envdPort = 49983\n\n protected readonly connectionConfig: ConnectionConfig\n protected readonly envdAccessToken?: string\n private readonly envdApiUrl: string\n private readonly envdApi: EnvdApiClient\n\n /**\n * Use {@link Sandbox.create} to create a new Sandbox instead.\n *\n * @hidden\n * @hide\n * @internal\n * @access protected\n */\n constructor(\n opts: SandboxConnectOpts & {\n sandboxId: string\n sandboxDomain?: string\n envdVersion?: string\n envdAccessToken?: string\n }\n ) {\n super()\n\n this.connectionConfig = new ConnectionConfig(opts)\n\n this.sandboxId = opts.sandboxId\n this.sandboxDomain = opts.sandboxDomain ?? this.connectionConfig.domain\n\n this.envdAccessToken = opts.envdAccessToken\n this.envdApiUrl = `${\n this.connectionConfig.debug ? 'http' : 'https'\n }://${this.getHost(this.envdPort)}`\n\n const rpcTransport = createConnectTransport({\n baseUrl: this.envdApiUrl,\n useBinaryFormat: false,\n interceptors: opts?.logger ? [createRpcLogger(opts.logger)] : undefined,\n fetch: (url, options) => {\n // Patch fetch to always use redirect: \"follow\"\n // connect-web doesn't allow to configure redirect option - https://github.com/connectrpc/connect-es/pull/1082\n // connect-web package uses redirect: \"error\" which is not supported in edge runtimes\n\n const headers = new Headers(this.connectionConfig.headers)\n new Headers(options?.headers).forEach((value, key) =>\n headers.append(key, value)\n )\n\n if (this.envdAccessToken) {\n headers.append('X-Access-Token', this.envdAccessToken)\n }\n\n options = {\n ...(options ?? {}),\n headers: headers,\n redirect: 'follow',\n }\n\n return fetch(url, options)\n },\n })\n\n this.envdApi = new EnvdApiClient(\n {\n apiUrl: this.envdApiUrl,\n logger: opts?.logger,\n accessToken: this.envdAccessToken,\n headers: this.envdAccessToken\n ? { 'X-Access-Token': this.envdAccessToken }\n : {},\n },\n {\n version: opts?.envdVersion,\n }\n )\n this.files = new Filesystem(\n rpcTransport,\n this.envdApi,\n this.connectionConfig\n )\n this.commands = new Commands(rpcTransport, this.connectionConfig)\n this.pty = new Pty(rpcTransport, this.connectionConfig)\n }\n\n /**\n * List all sandboxes.\n *\n * @param opts connection options.\n *\n * @returns paginator for listing sandboxes.\n */\n static list(opts?: SandboxListOpts): SandboxPaginator {\n return new SandboxPaginator(opts)\n }\n\n /**\n * Create a new sandbox from the default `base` sandbox template.\n *\n * @param opts connection options.\n *\n * @returns sandbox instance for the new sandbox.\n *\n * @example\n * ```ts\n * const sandbox = await Sandbox.create()\n * ```\n * @constructs {@link Sandbox}\n */\n static async create<S extends typeof Sandbox>(\n this: S,\n opts?: SandboxOpts\n ): Promise<InstanceType<S>>\n\n /**\n * Create a new sandbox from the specified sandbox template.\n *\n * @param template sandbox template name or ID.\n * @param opts connection options.\n *\n * @returns sandbox instance for the new sandbox.\n *\n * @example\n * ```ts\n * const sandbox = await Sandbox.create('<template-name-or-id>')\n * ```\n * @constructs {@link Sandbox}\n */\n static async create<S extends typeof Sandbox>(\n this: S,\n template: string,\n opts?: SandboxOpts\n ): Promise<InstanceType<S>>\n static async create<S extends typeof Sandbox>(\n this: S,\n templateOrOpts?: SandboxOpts | string,\n opts?: SandboxOpts\n ): Promise<InstanceType<S>> {\n const { template, sandboxOpts } =\n typeof templateOrOpts === 'string'\n ? { template: templateOrOpts, sandboxOpts: opts }\n : { template: this.defaultTemplate, sandboxOpts: templateOrOpts }\n\n const config = new ConnectionConfig(sandboxOpts)\n if (config.debug) {\n return new this({\n sandboxId: 'debug_sandbox_id',\n ...config,\n }) as InstanceType<S>\n }\n\n const sandbox = await SandboxApi.createSandbox(\n template,\n sandboxOpts?.timeoutMs ?? this.defaultSandboxTimeoutMs,\n sandboxOpts\n )\n\n return new this({ ...sandbox, ...config }) as InstanceType<S>\n }\n\n /**\n * @beta This feature is in beta and may change in the future.\n *\n * Create a new sandbox from the default `base` sandbox template.\n *\n * @param opts connection options.\n *\n * @returns sandbox instance for the new sandbox.\n *\n * @example\n * ```ts\n * const sandbox = await Sandbox.betaCreate()\n * ```\n * @constructs {@link Sandbox}\n */\n static async betaCreate<S extends typeof Sandbox>(\n this: S,\n opts?: SandboxBetaCreateOpts\n ): Promise<InstanceType<S>>\n\n /**\n * @beta This feature is in beta and may change in the future.\n *\n * Create a new sandbox from the specified sandbox template.\n *\n * @param template sandbox template name or ID.\n * @param opts connection options.\n *\n * @returns sandbox instance for the new sandbox.\n *\n * @example\n * ```ts\n * const sandbox = await Sandbox.betaCreate('<template-name-or-id>')\n * ```\n * @constructs {@link Sandbox}\n */\n static async betaCreate<S extends typeof Sandbox>(\n this: S,\n template: string,\n opts?: SandboxBetaCreateOpts\n ): Promise<InstanceType<S>>\n static async betaCreate<S extends typeof Sandbox>(\n this: S,\n templateOrOpts?: SandboxBetaCreateOpts | string,\n opts?: SandboxBetaCreateOpts\n ): Promise<InstanceType<S>> {\n const { template, sandboxOpts } =\n typeof templateOrOpts === 'string'\n ? { template: templateOrOpts, sandboxOpts: opts }\n : { template: this.defaultTemplate, sandboxOpts: templateOrOpts }\n\n const config = new ConnectionConfig(sandboxOpts)\n if (config.debug) {\n return new this({\n sandboxId: 'debug_sandbox_id',\n ...config,\n }) as InstanceType<S>\n }\n\n const sandbox = await SandboxApi.createSandbox(\n template,\n sandboxOpts?.timeoutMs ?? this.defaultSandboxTimeoutMs,\n sandboxOpts\n )\n\n return new this({ ...sandbox, ...config }) as InstanceType<S>\n }\n\n /**\n * Connect to a sandbox. If the sandbox is paused, it will be automatically resumed.\n * Sandbox must be either running or be paused.\n *\n * With sandbox ID you can connect to the same sandbox from different places or environments (serverless functions, etc).\n *\n * @param sandboxId sandbox ID.\n * @param opts connection options.\n *\n * @returns A running sandbox instance\n *\n * @example\n * ```ts\n * const sandbox = await Sandbox.create()\n * const sandboxId = sandbox.sandboxId\n *\n * // Connect to the same sandbox.\n * const sameSandbox = await Sandbox.connect(sandboxId)\n * ```\n */\n static async connect<S extends typeof Sandbox>(\n this: S,\n sandboxId: string,\n opts?: SandboxConnectOpts\n ): Promise<InstanceType<S>> {\n const info = await SandboxApi.connectSandbox(sandboxId, opts)\n\n const config = new ConnectionConfig(opts)\n\n return new this({\n sandboxId: info.sandboxId,\n sandboxDomain: info.sandboxDomain,\n envdAccessToken: info.envdAccessToken,\n envdVersion: info.envdVersion,\n ...config,\n }) as InstanceType<S>\n }\n\n /**\n * Connect to a sandbox. If the sandbox is paused, it will be automatically resumed.\n * Sandbox must be either running or be paused.\n *\n * With sandbox ID you can connect to the same sandbox from different places or environments (serverless functions, etc).\n *\n * @param opts connection options.\n *\n * @returns A running sandbox instance\n *\n * @example\n * ```ts\n * const sandbox = await Sandbox.create()\n * await sandbox.betaPause()\n *\n * // Connect to the same sandbox.\n * const sameSandbox = await sandbox.connect()\n * ```\n */\n async connect(opts?: SandboxBetaCreateOpts): Promise<this> {\n await SandboxApi.connectSandbox(this.sandboxId, opts)\n\n return this\n }\n\n /**\n * Get the host address for the specified sandbox port.\n * You can then use this address to connect to the sandbox port from outside the sandbox via HTTP or WebSocket.\n *\n * @param port number of the port in the sandbox.\n *\n * @returns host address of the sandbox port.\n *\n * @example\n * ```ts\n * const sandbox = await Sandbox.create()\n * // Start an HTTP server\n * await sandbox.commands.exec('python3 -m http.server 3000')\n * // Get the hostname of the HTTP server\n * const serverURL = sandbox.getHost(3000)\n * ```\n */\n getHost(port: number) {\n if (this.connectionConfig.debug) {\n return `localhost:${port}`\n }\n\n return `${port}-${this.sandboxId}.${this.sandboxDomain}`\n }\n\n /**\n * Check if the sandbox is running.\n *\n * @returns `true` if the sandbox is running, `false` otherwise.\n *\n * @example\n * ```ts\n * const sandbox = await Sandbox.create()\n * await sandbox.isRunning() // Returns true\n *\n * await sandbox.kill()\n * await sandbox.isRunning() // Returns false\n * ```\n */\n async isRunning(\n opts?: Pick<ConnectionOpts, 'requestTimeoutMs'>\n ): Promise<boolean> {\n const signal = this.connectionConfig.getSignal(opts?.requestTimeoutMs)\n\n const res = await this.envdApi.api.GET('/health', {\n signal,\n })\n\n if (res.response.status == 502) {\n return false\n }\n\n const err = await handleEnvdApiError(res)\n if (err) {\n throw err\n }\n\n return true\n }\n\n /**\n * Set the timeout of the sandbox.\n * After the timeout expires the sandbox will be automatically killed.\n *\n * This method can extend or reduce the sandbox timeout set when creating the sandbox or from the last call to `.setTimeout`.\n * Maximum time a sandbox can be kept alive is 24 hours (86_400_000 milliseconds) for Pro users and 1 hour (3_600_000 milliseconds) for Hobby users.\n *\n * @param timeoutMs timeout in **milliseconds**.\n * @param opts connection options.\n */\n async setTimeout(\n timeoutMs: number,\n opts?: Pick<SandboxOpts, 'requestTimeoutMs'>\n ) {\n if (this.connectionConfig.debug) {\n // Skip timeout in debug mode\n return\n }\n\n await SandboxApi.setTimeout(this.sandboxId, timeoutMs, {\n ...this.connectionConfig,\n ...opts,\n })\n }\n\n /**\n * Kill the sandbox.\n *\n * @param opts connection options.\n */\n async kill(opts?: Pick<SandboxOpts, 'requestTimeoutMs'>) {\n if (this.connectionConfig.debug) {\n // Skip killing in debug mode\n return\n }\n\n await SandboxApi.kill(this.sandboxId, { ...this.connectionConfig, ...opts })\n }\n\n /**\n * @beta This feature is in beta and may change in the future.\n *\n * Pause a sandbox by its ID.\n *\n * @param opts connection options.\n *\n * @returns sandbox ID that can be used to resume the sandbox.\n */\n async betaPause(opts?: ConnectionOpts): Promise<boolean> {\n return await SandboxApi.betaPause(this.sandboxId, opts)\n }\n\n /**\n * Get the URL to upload a file to the sandbox.\n *\n * You have to send a POST request to this URL with the file as multipart/form-data.\n *\n * @param path path to the file in the sandbox.\n *\n * @param opts download url options.\n *\n * @returns URL for uploading file.\n */\n async uploadUrl(path?: string, opts?: SandboxUrlOpts) {\n opts = opts ?? {}\n\n const useSignature = !!this.envdAccessToken\n\n if (!useSignature && opts.useSignatureExpiration != undefined) {\n throw new Error(\n 'Signature expiration can be used only when sandbox is created as secured.'\n )\n }\n\n const username = opts.user ?? defaultUsername\n const filePath = path ?? ''\n const fileUrl = this.fileUrl(filePath, username)\n\n if (useSignature) {\n const url = new URL(fileUrl)\n const sig = await getSignature({\n path: filePath,\n operation: 'write',\n user: username,\n expirationInSeconds: opts.useSignatureExpiration,\n envdAccessToken: this.envdAccessToken,\n })\n\n url.searchParams.set('signature', sig.signature)\n if (sig.expiration) {\n url.searchParams.set('signature_expiration', sig.expiration.toString())\n }\n\n return url.toString()\n }\n\n return fileUrl\n }\n\n /**\n * Get the URL to download a file from the sandbox.\n *\n * @param path path to the file in the sandbox.\n *\n * @param opts download url options.\n *\n * @returns URL for downloading file.\n */\n async downloadUrl(path: string, opts?: SandboxUrlOpts) {\n opts = opts ?? {}\n\n const useSignature = !!this.envdAccessToken\n\n if (!useSignature && opts.useSignatureExpiration != undefined) {\n throw new Error(\n 'Signature expiration can be used only when sandbox is created as secured.'\n )\n }\n\n const username = opts.user ?? defaultUsername\n const fileUrl = this.fileUrl(path, username)\n\n if (useSignature) {\n const url = new URL(fileUrl)\n const sig = await getSignature({\n path,\n operation: 'read',\n user: username,\n expirationInSeconds: opts.useSignatureExpiration,\n envdAccessToken: this.envdAccessToken,\n })\n\n url.searchParams.set('signature', sig.signature)\n if (sig.expiration) {\n url.searchParams.set('signature_expiration', sig.expiration.toString())\n }\n\n return url.toString()\n }\n\n return fileUrl\n }\n\n /**\n * Get sandbox information like sandbox ID, template, metadata, started at/end at date.\n *\n * @param opts connection options.\n *\n * @returns information about the sandbox\n */\n async getInfo(opts?: Pick<SandboxOpts, 'requestTimeoutMs'>) {\n return await SandboxApi.getInfo(this.sandboxId, {\n ...this.connectionConfig,\n ...opts,\n })\n }\n\n /**\n * Get the metrics of the sandbox.\n *\n * @param opts connection options.\n *\n * @returns List of sandbox metrics containing CPU, memory and disk usage information.\n */\n async getMetrics(opts?: SandboxMetricsOpts) {\n if (this.envdApi.version) {\n if (compareVersions(this.envdApi.version, '0.1.5') < 0) {\n throw new SandboxError(\n 'You need to update the template to use the new SDK. ' +\n 'You can do this by running `ppio-sandbox-cli template build` in the directory with the template.'\n )\n }\n\n if (compareVersions(this.envdApi.version, '0.2.4') < 0) {\n this.connectionConfig.logger?.warn?.(\n 'Disk metrics are not supported in this version of the sandbox, please rebuild the template to get disk metrics.'\n )\n }\n }\n\n return await SandboxApi.getMetrics(this.sandboxId, {\n ...this.connectionConfig,\n ...opts,\n })\n }\n\n private fileUrl(path?: string, username?: string) {\n const url = new URL('/files', this.envdApiUrl)\n\n url.searchParams.set('username', username ?? defaultUsername)\n if (path) {\n url.searchParams.set('path', path)\n }\n\n return url.toString()\n }\n}\n","import {\n Code,\n ConnectError,\n createClient,\n Client,\n Transport,\n} from '@connectrpc/connect'\n\nimport {\n Signal,\n Process as ProcessService,\n} from '../../envd/process/process_pb'\nimport {\n ConnectionConfig,\n Username,\n ConnectionOpts,\n KEEPALIVE_PING_INTERVAL_SEC,\n KEEPALIVE_PING_HEADER,\n} from '../../connectionConfig'\nimport { authenticationHeader, handleRpcError } from '../../envd/rpc'\nimport { CommandResult, CommandHandle } from './commandHandle'\nimport { handleProcessStartEvent } from '../../envd/api'\nexport { Pty } from './pty'\n\n/**\n * Options for sending a command request.\n */\nexport interface CommandRequestOpts\n extends Partial<Pick<ConnectionOpts, 'requestTimeoutMs'>> {}\n\n/**\n * Options for starting a new command.\n */\nexport interface CommandStartOpts extends CommandRequestOpts {\n /**\n * If true, starts command in the background and the method returns immediately.\n * You can use {@link CommandHandle.wait} to wait for the command to finish.\n */\n background?: boolean\n /**\n * Working directory for the command.\n *\n * @default // home directory of the user used to start the command\n */\n cwd?: string\n /**\n * User to run the command as.\n *\n * @default `user`\n */\n user?: Username\n /**\n * Environment variables used for the command.\n *\n * This overrides the default environment variables from `Sandbox` constructor.\n *\n * @default `{}`\n */\n envs?: Record<string, string>\n /**\n * Callback for command stdout output.\n */\n onStdout?: (data: string) => void | Promise<void>\n /**\n * Callback for command stderr output.\n */\n onStderr?: (data: string) => void | Promise<void>\n /**\n * Timeout for the command in **milliseconds**.\n *\n * @default 60_000 // 60 seconds\n */\n timeoutMs?: number\n}\n\n/**\n * Options for connecting to a command.\n */\nexport type CommandConnectOpts = Pick<\n CommandStartOpts,\n 'onStderr' | 'onStdout' | 'timeoutMs'\n> &\n CommandRequestOpts\n\n/**\n * Information about a command, PTY session or start command running in the sandbox as process.\n */\nexport interface ProcessInfo {\n /**\n * Process ID.\n */\n pid: number\n /**\n * Custom tag used for identifying special commands like start command in the custom template.\n */\n tag?: string\n /**\n * Command that was executed.\n */\n cmd: string\n /**\n * Command arguments.\n */\n args: string[]\n /**\n * Environment variables used for the command.\n */\n envs: Record<string, string>\n /**\n * Executed command working directory.\n */\n cwd?: string\n}\n\n/**\n * Module for starting and interacting with commands in the sandbox.\n */\nexport class Commands {\n protected readonly rpc: Client<typeof ProcessService>\n\n private readonly defaultProcessConnectionTimeout = 60_000 // 60 seconds\n\n constructor(\n transport: Transport,\n private readonly connectionConfig: ConnectionConfig\n ) {\n this.rpc = createClient(ProcessService, transport)\n }\n\n /**\n * List all running commands and PTY sessions.\n *\n * @param opts connection options.\n *\n * @returns list of running commands and PTY sessions.\n */\n async list(opts?: CommandRequestOpts): Promise<ProcessInfo[]> {\n try {\n const res = await this.rpc.list(\n {},\n {\n signal: this.connectionConfig.getSignal(opts?.requestTimeoutMs),\n }\n )\n\n return res.processes.map((p) => ({\n pid: p.pid,\n ...(p.tag && { tag: p.tag }),\n args: p.config!.args,\n envs: p.config!.envs,\n cmd: p.config!.cmd,\n ...(p.config!.cwd && { cwd: p.config!.cwd }),\n }))\n } catch (err) {\n throw handleRpcError(err)\n }\n }\n\n /**\n * Send data to command stdin.\n *\n * @param pid process ID of the command. You can get the list of running commands using {@link Commands.list}.\n * @param data data to send to the command.\n * @param opts connection options.\n */\n async sendStdin(\n pid: number,\n data: string,\n opts?: CommandRequestOpts\n ): Promise<void> {\n try {\n await this.rpc.sendInput(\n {\n process: {\n selector: {\n case: 'pid',\n value: pid,\n },\n },\n input: {\n input: {\n case: 'stdin',\n value: new TextEncoder().encode(data),\n },\n },\n },\n {\n signal: this.connectionConfig.getSignal(opts?.requestTimeoutMs),\n }\n )\n } catch (err) {\n throw handleRpcError(err)\n }\n }\n\n /**\n * Kill a running command specified by its process ID.\n * It uses `SIGKILL` signal to kill the command.\n *\n * @param pid process ID of the command. You can get the list of running commands using {@link Commands.list}.\n * @param opts connection options.\n *\n * @returns `true` if the command was killed, `false` if the command was not found.\n */\n async kill(pid: number, opts?: CommandRequestOpts): Promise<boolean> {\n try {\n await this.rpc.sendSignal(\n {\n process: {\n selector: {\n case: 'pid',\n value: pid,\n },\n },\n signal: Signal.SIGKILL,\n },\n {\n signal: this.connectionConfig.getSignal(opts?.requestTimeoutMs),\n }\n )\n\n return true\n } catch (err) {\n if (err instanceof ConnectError) {\n if (err.code === Code.NotFound) {\n return false\n }\n }\n\n throw handleRpcError(err)\n }\n }\n\n /**\n * Connect to a running command.\n * You can use {@link CommandHandle.wait} to wait for the command to finish and get execution results.\n *\n * @param pid process ID of the command to connect to. You can get the list of running commands using {@link Commands.list}.\n * @param opts connection options.\n *\n * @returns `CommandHandle` handle to interact with the running command.\n */\n async connect(\n pid: number,\n opts?: CommandConnectOpts\n ): Promise<CommandHandle> {\n const requestTimeoutMs =\n opts?.requestTimeoutMs ?? this.connectionConfig.requestTimeoutMs\n\n const controller = new AbortController()\n\n const reqTimeout = requestTimeoutMs\n ? setTimeout(() => {\n controller.abort()\n }, requestTimeoutMs)\n : undefined\n\n const events = this.rpc.connect(\n {\n process: {\n selector: {\n case: 'pid',\n value: pid,\n },\n },\n },\n {\n signal: controller.signal,\n headers: {\n [KEEPALIVE_PING_HEADER]: KEEPALIVE_PING_INTERVAL_SEC.toString(),\n },\n timeoutMs: opts?.timeoutMs ?? this.defaultProcessConnectionTimeout,\n }\n )\n\n try {\n const pid = await handleProcessStartEvent(events)\n\n clearTimeout(reqTimeout)\n\n return new CommandHandle(\n pid,\n () => controller.abort(),\n () => this.kill(pid),\n events,\n opts?.onStdout,\n opts?.onStderr,\n undefined\n )\n } catch (err) {\n throw handleRpcError(err)\n }\n }\n\n /**\n * Start a new command and wait until it finishes executing.\n *\n * @param cmd command to execute.\n * @param opts options for starting the command.\n *\n * @returns `CommandResult` result of the command execution.\n */\n async run(\n cmd: string,\n opts?: CommandStartOpts & { background?: false }\n ): Promise<CommandResult>\n\n /**\n * Start a new command in the background.\n * You can use {@link CommandHandle.wait} to wait for the command to finish and get its result.\n *\n * @param cmd command to execute.\n * @param opts options for starting the command\n *\n * @returns `CommandHandle` handle to interact with the running command.\n */\n async run(\n cmd: string,\n opts: CommandStartOpts & { background: true }\n ): Promise<CommandHandle>\n\n // NOTE - The following overload seems redundant, but it's required to make the type inference work correctly.\n\n /**\n * Start a new command.\n *\n * @param cmd command to execute.\n * @param opts options for starting the command.\n * - `opts.background: true` - runs in background, returns `CommandHandle`\n * - `opts.background: false | undefined` - waits for completion, returns `CommandResult`\n *\n * @returns Either a `CommandHandle` or a `CommandResult` (depending on `opts.background`).\n */\n async run(\n cmd: string,\n opts?: CommandStartOpts & { background?: boolean }\n ): Promise<CommandHandle | CommandResult>\n async run(\n cmd: string,\n opts?: CommandStartOpts & { background?: boolean }\n ): Promise<CommandHandle | CommandResult> {\n const proc = await this.start(cmd, opts)\n\n return opts?.background ? proc : proc.wait()\n }\n\n private async start(\n cmd: string,\n opts?: CommandStartOpts\n ): Promise<CommandHandle> {\n const requestTimeoutMs =\n opts?.requestTimeoutMs ?? this.connectionConfig.requestTimeoutMs\n\n const controller = new AbortController()\n\n const reqTimeout = requestTimeoutMs\n ? setTimeout(() => {\n controller.abort()\n }, requestTimeoutMs)\n : undefined\n\n const events = this.rpc.start(\n {\n process: {\n cmd: '/bin/bash',\n cwd: opts?.cwd,\n envs: opts?.envs,\n args: ['-l', '-c', cmd],\n },\n },\n {\n headers: {\n ...authenticationHeader(opts?.user),\n [KEEPALIVE_PING_HEADER]: KEEPALIVE_PING_INTERVAL_SEC.toString(),\n },\n signal: controller.signal,\n timeoutMs: opts?.timeoutMs ?? this.defaultProcessConnectionTimeout,\n }\n )\n\n try {\n const pid = await handleProcessStartEvent(events)\n\n clearTimeout(reqTimeout)\n\n return new CommandHandle(\n pid,\n () => controller.abort(),\n () => this.kill(pid),\n events,\n opts?.onStdout,\n opts?.onStderr,\n undefined\n )\n } catch (err) {\n throw handleRpcError(err)\n }\n }\n}\n","// @generated by protoc-gen-es v2.6.2 with parameter \"target=ts\"\n// @generated from file process/process.proto (package process, syntax proto3)\n/* eslint-disable */\n\nimport type { GenEnum, GenFile, GenMessage, GenService } from \"@bufbuild/protobuf/codegenv2\";\nimport { enumDesc, fileDesc, messageDesc, serviceDesc } from \"@bufbuild/protobuf/codegenv2\";\nimport type { Message } from \"@bufbuild/protobuf\";\n\n/**\n * Describes the file process/process.proto.\n */\nexport const file_process_process: GenFile = /*@__PURE__*/\n fileDesc(\"ChVwcm9jZXNzL3Byb2Nlc3MucHJvdG8SB3Byb2Nlc3MiSgoDUFRZEh8KBHNpemUYASABKAsyES5wcm9jZXNzLlBUWS5TaXplGiIKBFNpemUSDAoEY29scxgBIAEoDRIMCgRyb3dzGAIgASgNIqEBCg1Qcm9jZXNzQ29uZmlnEgsKA2NtZBgBIAEoCRIMCgRhcmdzGAIgAygJEi4KBGVudnMYAyADKAsyIC5wcm9jZXNzLlByb2Nlc3NDb25maWcuRW52c0VudHJ5EhAKA2N3ZBgEIAEoCUgAiAEBGisKCUVudnNFbnRyeRILCgNrZXkYASABKAkSDQoFdmFsdWUYAiABKAk6AjgBQgYKBF9jd2QiDQoLTGlzdFJlcXVlc3QiXAoLUHJvY2Vzc0luZm8SJgoGY29uZmlnGAEgASgLMhYucHJvY2Vzcy5Qcm9jZXNzQ29uZmlnEgsKA3BpZBgCIAEoDRIQCgN0YWcYAyABKAlIAIgBAUIGCgRfdGFnIjcKDExpc3RSZXNwb25zZRInCglwcm9jZXNzZXMYASADKAsyFC5wcm9jZXNzLlByb2Nlc3NJbmZvInkKDFN0YXJ0UmVxdWVzdBInCgdwcm9jZXNzGAEgASgLMhYucHJvY2Vzcy5Qcm9jZXNzQ29uZmlnEh4KA3B0eRgCIAEoCzIMLnByb2Nlc3MuUFRZSACIAQESEAoDdGFnGAMgASgJSAGIAQFCBgoEX3B0eUIGCgRfdGFnImIKDVVwZGF0ZVJlcXVlc3QSKQoHcHJvY2VzcxgBIAEoCzIYLnByb2Nlc3MuUHJvY2Vzc1NlbGVjdG9yEh4KA3B0eRgCIAEoCzIMLnByb2Nlc3MuUFRZSACIAQFCBgoEX3B0eSIQCg5VcGRhdGVSZXNwb25zZSKvAwoMUHJvY2Vzc0V2ZW50EjEKBXN0YXJ0GAEgASgLMiAucHJvY2Vzcy5Qcm9jZXNzRXZlbnQuU3RhcnRFdmVudEgAEi8KBGRhdGEYAiABKAsyHy5wcm9jZXNzLlByb2Nlc3NFdmVudC5EYXRhRXZlbnRIABItCgNlbmQYAyABKAsyHi5wcm9jZXNzLlByb2Nlc3NFdmVudC5FbmRFdmVudEgAEjQKCWtlZXBhbGl2ZRgEIAEoCzIfLnByb2Nlc3MuUHJvY2Vzc0V2ZW50LktlZXBBbGl2ZUgAGhkKClN0YXJ0RXZlbnQSCwoDcGlkGAEgASgNGkgKCURhdGFFdmVudBIQCgZzdGRvdXQYASABKAxIABIQCgZzdGRlcnIYAiABKAxIABINCgNwdHkYAyABKAxIAEIICgZvdXRwdXQaWwoIRW5kRXZlbnQSEQoJZXhpdF9jb2RlGAEgASgREg4KBmV4aXRlZBgCIAEoCBIOCgZzdGF0dXMYAyABKAkSEgoFZXJyb3IYBCABKAlIAIgBAUIICgZfZXJyb3IaCwoJS2VlcEFsaXZlQgcKBWV2ZW50IjUKDVN0YXJ0UmVzcG9uc2USJAoFZXZlbnQYASABKAsyFS5wcm9jZXNzLlByb2Nlc3NFdmVudCI3Cg9Db25uZWN0UmVzcG9uc2USJAoFZXZlbnQYASABKAsyFS5wcm9jZXNzLlByb2Nlc3NFdmVudCJjChBTZW5kSW5wdXRSZXF1ZXN0EikKB3Byb2Nlc3MYASABKAsyGC5wcm9jZXNzLlByb2Nlc3NTZWxlY3RvchIkCgVpbnB1dBgCIAEoCzIVLnByb2Nlc3MuUHJvY2Vzc0lucHV0IhMKEVNlbmRJbnB1dFJlc3BvbnNlIjcKDFByb2Nlc3NJbnB1dBIPCgVzdGRpbhgBIAEoDEgAEg0KA3B0eRgCIAEoDEgAQgcKBWlucHV0IsICChJTdHJlYW1JbnB1dFJlcXVlc3QSNwoFc3RhcnQYASABKAsyJi5wcm9jZXNzLlN0cmVhbUlucHV0UmVxdWVzdC5TdGFydEV2ZW50SAASNQoEZGF0YRgCIAEoCzIlLnByb2Nlc3MuU3RyZWFtSW5wdXRSZXF1ZXN0LkRhdGFFdmVudEgAEjoKCWtlZXBhbGl2ZRgDIAEoCzIlLnByb2Nlc3MuU3RyZWFtSW5wdXRSZXF1ZXN0LktlZXBBbGl2ZUgAGjcKClN0YXJ0RXZlbnQSKQoHcHJvY2VzcxgBIAEoCzIYLnByb2Nlc3MuUHJvY2Vzc1NlbGVjdG9yGjEKCURhdGFFdmVudBIkCgVpbnB1dBgCIAEoCzIVLnByb2Nlc3MuUHJvY2Vzc0lucHV0GgsKCUtlZXBBbGl2ZUIHCgVldmVudCIVChNTdHJlYW1JbnB1dFJlc3BvbnNlIl8KEVNlbmRTaWduYWxSZXF1ZXN0EikKB3Byb2Nlc3MYASABKAsyGC5wcm9jZXNzLlByb2Nlc3NTZWxlY3RvchIfCgZzaWduYWwYAiABKA4yDy5wcm9jZXNzLlNpZ25hbCIUChJTZW5kU2lnbmFsUmVzcG9uc2UiOwoOQ29ubmVjdFJlcXVlc3QSKQoHcHJvY2VzcxgBIAEoCzIYLnByb2Nlc3MuUHJvY2Vzc1NlbGVjdG9yIjsKD1Byb2Nlc3NTZWxlY3RvchINCgNwaWQYASABKA1IABINCgN0YWcYAiABKAlIAEIKCghzZWxlY3RvcipICgZTaWduYWwSFgoSU0lHTkFMX1VOU1BFQ0lGSUVEEAASEgoOU0lHTkFMX1NJR1RFUk0QDxISCg5TSUdOQUxfU0lHS0lMTBAJMsoDCgdQcm9jZXNzEjMKBExpc3QSFC5wcm9jZXNzLkxpc3RSZXF1ZXN0GhUucHJvY2Vzcy5MaXN0UmVzcG9uc2USPgoHQ29ubmVjdBIXLnByb2Nlc3MuQ29ubmVjdFJlcXVlc3QaGC5wcm9jZXNzLkNvbm5lY3RSZXNwb25zZTABEjgKBVN0YXJ0EhUucHJvY2Vzcy5TdGFydFJlcXVlc3QaFi5wcm9jZXNzLlN0YXJ0UmVzcG9uc2UwARI5CgZVcGRhdGUSFi5wcm9jZXNzLlVwZGF0ZVJlcXVlc3QaFy5wcm9jZXNzLlVwZGF0ZVJlc3BvbnNlEkoKC1N0cmVhbUlucHV0EhsucHJvY2Vzcy5TdHJlYW1JbnB1dFJlcXVlc3QaHC5wcm9jZXNzLlN0cmVhbUlucHV0UmVzcG9uc2UoARJCCglTZW5kSW5wdXQSGS5wcm9jZXNzLlNlbmRJbnB1dFJlcXVlc3QaGi5wcm9jZXNzLlNlbmRJbnB1dFJlc3BvbnNlEkUKClNlbmRTaWduYWwSGi5wcm9jZXNzLlNlbmRTaWduYWxSZXF1ZXN0GhsucHJvY2Vzcy5TZW5kU2lnbmFsUmVzcG9uc2VCVwoLY29tLnByb2Nlc3NCDFByb2Nlc3NQcm90b1ABogIDUFhYqgIHUHJvY2Vzc8oCB1Byb2Nlc3PiAhNQcm9jZXNzXEdQQk1ldGFkYXRh6gIHUHJvY2Vzc2IGcHJvdG8z\");\n\n/**\n * @generated from message process.PTY\n */\nexport type PTY = Message<\"process.PTY\"> & {\n /**\n * @generated from field: process.PTY.Size size = 1;\n */\n size?: PTY_Size;\n};\n\n/**\n * Describes the message process.PTY.\n * Use `create(PTYSchema)` to create a new message.\n */\nexport const PTYSchema: GenMessage<PTY> = /*@__PURE__*/\n messageDesc(file_process_process, 0);\n\n/**\n * @generated from message process.PTY.Size\n */\nexport type PTY_Size = Message<\"process.PTY.Size\"> & {\n /**\n * @generated from field: uint32 cols = 1;\n */\n cols: number;\n\n /**\n * @generated from field: uint32 rows = 2;\n */\n rows: number;\n};\n\n/**\n * Describes the message process.PTY.Size.\n * Use `create(PTY_SizeSchema)` to create a new message.\n */\nexport const PTY_SizeSchema: GenMessage<PTY_Size> = /*@__PURE__*/\n messageDesc(file_process_process, 0, 0);\n\n/**\n * @generated from message process.ProcessConfig\n */\nexport type ProcessConfig = Message<\"process.ProcessConfig\"> & {\n /**\n * @generated from field: string cmd = 1;\n */\n cmd: string;\n\n /**\n * @generated from field: repeated string args = 2;\n */\n args: string[];\n\n /**\n * @generated from field: map<string, string> envs = 3;\n */\n envs: { [key: string]: string };\n\n /**\n * @generated from field: optional string cwd = 4;\n */\n cwd?: string;\n};\n\n/**\n * Describes the message process.ProcessConfig.\n * Use `create(ProcessConfigSchema)` to create a new message.\n */\nexport const ProcessConfigSchema: GenMessage<ProcessConfig> = /*@__PURE__*/\n messageDesc(file_process_process, 1);\n\n/**\n * @generated from message process.ListRequest\n */\nexport type ListRequest = Message<\"process.ListRequest\"> & {\n};\n\n/**\n * Describes the message process.ListRequest.\n * Use `create(ListRequestSchema)` to create a new message.\n */\nexport const ListRequestSchema: GenMessage<ListRequest> = /*@__PURE__*/\n messageDesc(file_process_process, 2);\n\n/**\n * @generated from message process.ProcessInfo\n */\nexport type ProcessInfo = Message<\"process.ProcessInfo\"> & {\n /**\n * @generated from field: process.ProcessConfig config = 1;\n */\n config?: ProcessConfig;\n\n /**\n * @generated from field: uint32 pid = 2;\n */\n pid: number;\n\n /**\n * @generated from field: optional string tag = 3;\n */\n tag?: string;\n};\n\n/**\n * Describes the message process.ProcessInfo.\n * Use `create(ProcessInfoSchema)` to create a new message.\n */\nexport const ProcessInfoSchema: GenMessage<ProcessInfo> = /*@__PURE__*/\n messageDesc(file_process_process, 3);\n\n/**\n * @generated from message process.ListResponse\n */\nexport type ListResponse = Message<\"process.ListResponse\"> & {\n /**\n * @generated from field: repeated process.ProcessInfo processes = 1;\n */\n processes: ProcessInfo[];\n};\n\n/**\n * Describes the message process.ListResponse.\n * Use `create(ListResponseSchema)` to create a new message.\n */\nexport const ListResponseSchema: GenMessage<ListResponse> = /*@__PURE__*/\n messageDesc(file_process_process, 4);\n\n/**\n * @generated from message process.StartRequest\n */\nexport type StartRequest = Message<\"process.StartRequest\"> & {\n /**\n * @generated from field: process.ProcessConfig process = 1;\n */\n process?: ProcessConfig;\n\n /**\n * @generated from field: optional process.PTY pty = 2;\n */\n pty?: PTY;\n\n /**\n * @generated from field: optional string tag = 3;\n */\n tag?: string;\n};\n\n/**\n * Describes the message process.StartRequest.\n * Use `create(StartRequestSchema)` to create a new message.\n */\nexport const StartRequestSchema: GenMessage<StartRequest> = /*@__PURE__*/\n messageDesc(file_process_process, 5);\n\n/**\n * @generated from message process.UpdateRequest\n */\nexport type UpdateRequest = Message<\"process.UpdateRequest\"> & {\n /**\n * @generated from field: process.ProcessSelector process = 1;\n */\n process?: ProcessSelector;\n\n /**\n * @generated from field: optional process.PTY pty = 2;\n */\n pty?: PTY;\n};\n\n/**\n * Describes the message process.UpdateRequest.\n * Use `create(UpdateRequestSchema)` to create a new message.\n */\nexport const UpdateRequestSchema: GenMessage<UpdateRequest> = /*@__PURE__*/\n messageDesc(file_process_process, 6);\n\n/**\n * @generated from message process.UpdateResponse\n */\nexport type UpdateResponse = Message<\"process.UpdateResponse\"> & {\n};\n\n/**\n * Describes the message process.UpdateResponse.\n * Use `create(UpdateResponseSchema)` to create a new message.\n */\nexport const UpdateResponseSchema: GenMessage<UpdateResponse> = /*@__PURE__*/\n messageDesc(file_process_process, 7);\n\n/**\n * @generated from message process.ProcessEvent\n */\nexport type ProcessEvent = Message<\"process.ProcessEvent\"> & {\n /**\n * @generated from oneof process.ProcessEvent.event\n */\n event: {\n /**\n * @generated from field: process.ProcessEvent.StartEvent start = 1;\n */\n value: ProcessEvent_StartEvent;\n case: \"start\";\n } | {\n /**\n * @generated from field: process.ProcessEvent.DataEvent data = 2;\n */\n value: ProcessEvent_DataEvent;\n case: \"data\";\n } | {\n /**\n * @generated from field: process.ProcessEvent.EndEvent end = 3;\n */\n value: ProcessEvent_EndEvent;\n case: \"end\";\n } | {\n /**\n * @generated from field: process.ProcessEvent.KeepAlive keepalive = 4;\n */\n value: ProcessEvent_KeepAlive;\n case: \"keepalive\";\n } | { case: undefined; value?: undefined };\n};\n\n/**\n * Describes the message process.ProcessEvent.\n * Use `create(ProcessEventSchema)` to create a new message.\n */\nexport const ProcessEventSchema: GenMessage<ProcessEvent> = /*@__PURE__*/\n messageDesc(file_process_process, 8);\n\n/**\n * @generated from message process.ProcessEvent.StartEvent\n */\nexport type ProcessEvent_StartEvent = Message<\"process.ProcessEvent.StartEvent\"> & {\n /**\n * @generated from field: uint32 pid = 1;\n */\n pid: number;\n};\n\n/**\n * Describes the message process.ProcessEvent.StartEvent.\n * Use `create(ProcessEvent_StartEventSchema)` to create a new message.\n */\nexport const ProcessEvent_StartEventSchema: GenMessage<ProcessEvent_StartEvent> = /*@__PURE__*/\n messageDesc(file_process_process, 8, 0);\n\n/**\n * @generated from message process.ProcessEvent.DataEvent\n */\nexport type ProcessEvent_DataEvent = Message<\"process.ProcessEvent.DataEvent\"> & {\n /**\n * @generated from oneof process.ProcessEvent.DataEvent.output\n */\n output: {\n /**\n * @generated from field: bytes stdout = 1;\n */\n value: Uint8Array;\n case: \"stdout\";\n } | {\n /**\n * @generated from field: bytes stderr = 2;\n */\n value: Uint8Array;\n case: \"stderr\";\n } | {\n /**\n * @generated from field: bytes pty = 3;\n */\n value: Uint8Array;\n case: \"pty\";\n } | { case: undefined; value?: undefined };\n};\n\n/**\n * Describes the message process.ProcessEvent.DataEvent.\n * Use `create(ProcessEvent_DataEventSchema)` to create a new message.\n */\nexport const ProcessEvent_DataEventSchema: GenMessage<ProcessEvent_DataEvent> = /*@__PURE__*/\n messageDesc(file_process_process, 8, 1);\n\n/**\n * @generated from message process.ProcessEvent.EndEvent\n */\nexport type ProcessEvent_EndEvent = Message<\"process.ProcessEvent.EndEvent\"> & {\n /**\n * @generated from field: sint32 exit_code = 1;\n */\n exitCode: number;\n\n /**\n * @generated from field: bool exited = 2;\n */\n exited: boolean;\n\n /**\n * @generated from field: string status = 3;\n */\n status: string;\n\n /**\n * @generated from field: optional string error = 4;\n */\n error?: string;\n};\n\n/**\n * Describes the message process.ProcessEvent.EndEvent.\n * Use `create(ProcessEvent_EndEventSchema)` to create a new message.\n */\nexport const ProcessEvent_EndEventSchema: GenMessage<ProcessEvent_EndEvent> = /*@__PURE__*/\n messageDesc(file_process_process, 8, 2);\n\n/**\n * @generated from message process.ProcessEvent.KeepAlive\n */\nexport type ProcessEvent_KeepAlive = Message<\"process.ProcessEvent.KeepAlive\"> & {\n};\n\n/**\n * Describes the message process.ProcessEvent.KeepAlive.\n * Use `create(ProcessEvent_KeepAliveSchema)` to create a new message.\n */\nexport const ProcessEvent_KeepAliveSchema: GenMessage<ProcessEvent_KeepAlive> = /*@__PURE__*/\n messageDesc(file_process_process, 8, 3);\n\n/**\n * @generated from message process.StartResponse\n */\nexport type StartResponse = Message<\"process.StartResponse\"> & {\n /**\n * @generated from field: process.ProcessEvent event = 1;\n */\n event?: ProcessEvent;\n};\n\n/**\n * Describes the message process.StartResponse.\n * Use `create(StartResponseSchema)` to create a new message.\n */\nexport const StartResponseSchema: GenMessage<StartResponse> = /*@__PURE__*/\n messageDesc(file_process_process, 9);\n\n/**\n * @generated from message process.ConnectResponse\n */\nexport type ConnectResponse = Message<\"process.ConnectResponse\"> & {\n /**\n * @generated from field: process.ProcessEvent event = 1;\n */\n event?: ProcessEvent;\n};\n\n/**\n * Describes the message process.ConnectResponse.\n * Use `create(ConnectResponseSchema)` to create a new message.\n */\nexport const ConnectResponseSchema: GenMessage<ConnectResponse> = /*@__PURE__*/\n messageDesc(file_process_process, 10);\n\n/**\n * @generated from message process.SendInputRequest\n */\nexport type SendInputRequest = Message<\"process.SendInputRequest\"> & {\n /**\n * @generated from field: process.ProcessSelector process = 1;\n */\n process?: ProcessSelector;\n\n /**\n * @generated from field: process.ProcessInput input = 2;\n */\n input?: ProcessInput;\n};\n\n/**\n * Describes the message process.SendInputRequest.\n * Use `create(SendInputRequestSchema)` to create a new message.\n */\nexport const SendInputRequestSchema: GenMessage<SendInputRequest> = /*@__PURE__*/\n messageDesc(file_process_process, 11);\n\n/**\n * @generated from message process.SendInputResponse\n */\nexport type SendInputResponse = Message<\"process.SendInputResponse\"> & {\n};\n\n/**\n * Describes the message process.SendInputResponse.\n * Use `create(SendInputResponseSchema)` to create a new message.\n */\nexport const SendInputResponseSchema: GenMessage<SendInputResponse> = /*@__PURE__*/\n messageDesc(file_process_process, 12);\n\n/**\n * @generated from message process.ProcessInput\n */\nexport type ProcessInput = Message<\"process.ProcessInput\"> & {\n /**\n * @generated from oneof process.ProcessInput.input\n */\n input: {\n /**\n * @generated from field: bytes stdin = 1;\n */\n value: Uint8Array;\n case: \"stdin\";\n } | {\n /**\n * @generated from field: bytes pty = 2;\n */\n value: Uint8Array;\n case: \"pty\";\n } | { case: undefined; value?: undefined };\n};\n\n/**\n * Describes the message process.ProcessInput.\n * Use `create(ProcessInputSchema)` to create a new message.\n */\nexport const ProcessInputSchema: GenMessage<ProcessInput> = /*@__PURE__*/\n messageDesc(file_process_process, 13);\n\n/**\n * @generated from message process.StreamInputRequest\n */\nexport type StreamInputRequest = Message<\"process.StreamInputRequest\"> & {\n /**\n * @generated from oneof process.StreamInputRequest.event\n */\n event: {\n /**\n * @generated from field: process.StreamInputRequest.StartEvent start = 1;\n */\n value: StreamInputRequest_StartEvent;\n case: \"start\";\n } | {\n /**\n * @generated from field: process.StreamInputRequest.DataEvent data = 2;\n */\n value: StreamInputRequest_DataEvent;\n case: \"data\";\n } | {\n /**\n * @generated from field: process.StreamInputRequest.KeepAlive keepalive = 3;\n */\n value: StreamInputRequest_KeepAlive;\n case: \"keepalive\";\n } | { case: undefined; value?: undefined };\n};\n\n/**\n * Describes the message process.StreamInputRequest.\n * Use `create(StreamInputRequestSchema)` to create a new message.\n */\nexport const StreamInputRequestSchema: GenMessage<StreamInputRequest> = /*@__PURE__*/\n messageDesc(file_process_process, 14);\n\n/**\n * @generated from message process.StreamInputRequest.StartEvent\n */\nexport type StreamInputRequest_StartEvent = Message<\"process.StreamInputRequest.StartEvent\"> & {\n /**\n * @generated from field: process.ProcessSelector process = 1;\n */\n process?: ProcessSelector;\n};\n\n/**\n * Describes the message process.StreamInputRequest.StartEvent.\n * Use `create(StreamInputRequest_StartEventSchema)` to create a new message.\n */\nexport const StreamInputRequest_StartEventSchema: GenMessage<StreamInputRequest_StartEvent> = /*@__PURE__*/\n messageDesc(file_process_process, 14, 0);\n\n/**\n * @generated from message process.StreamInputRequest.DataEvent\n */\nexport type StreamInputRequest_DataEvent = Message<\"process.StreamInputRequest.DataEvent\"> & {\n /**\n * @generated from field: process.ProcessInput input = 2;\n */\n input?: ProcessInput;\n};\n\n/**\n * Describes the message process.StreamInputRequest.DataEvent.\n * Use `create(StreamInputRequest_DataEventSchema)` to create a new message.\n */\nexport const StreamInputRequest_DataEventSchema: GenMessage<StreamInputRequest_DataEvent> = /*@__PURE__*/\n messageDesc(file_process_process, 14, 1);\n\n/**\n * @generated from message process.StreamInputRequest.KeepAlive\n */\nexport type StreamInputRequest_KeepAlive = Message<\"process.StreamInputRequest.KeepAlive\"> & {\n};\n\n/**\n * Describes the message process.StreamInputRequest.KeepAlive.\n * Use `create(StreamInputRequest_KeepAliveSchema)` to create a new message.\n */\nexport const StreamInputRequest_KeepAliveSchema: GenMessage<StreamInputRequest_KeepAlive> = /*@__PURE__*/\n messageDesc(file_process_process, 14, 2);\n\n/**\n * @generated from message process.StreamInputResponse\n */\nexport type StreamInputResponse = Message<\"process.StreamInputResponse\"> & {\n};\n\n/**\n * Describes the message process.StreamInputResponse.\n * Use `create(StreamInputResponseSchema)` to create a new message.\n */\nexport const StreamInputResponseSchema: GenMessage<StreamInputResponse> = /*@__PURE__*/\n messageDesc(file_process_process, 15);\n\n/**\n * @generated from message process.SendSignalRequest\n */\nexport type SendSignalRequest = Message<\"process.SendSignalRequest\"> & {\n /**\n * @generated from field: process.ProcessSelector process = 1;\n */\n process?: ProcessSelector;\n\n /**\n * @generated from field: process.Signal signal = 2;\n */\n signal: Signal;\n};\n\n/**\n * Describes the message process.SendSignalRequest.\n * Use `create(SendSignalRequestSchema)` to create a new message.\n */\nexport const SendSignalRequestSchema: GenMessage<SendSignalRequest> = /*@__PURE__*/\n messageDesc(file_process_process, 16);\n\n/**\n * @generated from message process.SendSignalResponse\n */\nexport type SendSignalResponse = Message<\"process.SendSignalResponse\"> & {\n};\n\n/**\n * Describes the message process.SendSignalResponse.\n * Use `create(SendSignalResponseSchema)` to create a new message.\n */\nexport const SendSignalResponseSchema: GenMessage<SendSignalResponse> = /*@__PURE__*/\n messageDesc(file_process_process, 17);\n\n/**\n * @generated from message process.ConnectRequest\n */\nexport type ConnectRequest = Message<\"process.ConnectRequest\"> & {\n /**\n * @generated from field: process.ProcessSelector process = 1;\n */\n process?: ProcessSelector;\n};\n\n/**\n * Describes the message process.ConnectRequest.\n * Use `create(ConnectRequestSchema)` to create a new message.\n */\nexport const ConnectRequestSchema: GenMessage<ConnectRequest> = /*@__PURE__*/\n messageDesc(file_process_process, 18);\n\n/**\n * @generated from message process.ProcessSelector\n */\nexport type ProcessSelector = Message<\"process.ProcessSelector\"> & {\n /**\n * @generated from oneof process.ProcessSelector.selector\n */\n selector: {\n /**\n * @generated from field: uint32 pid = 1;\n */\n value: number;\n case: \"pid\";\n } | {\n /**\n * @generated from field: string tag = 2;\n */\n value: string;\n case: \"tag\";\n } | { case: undefined; value?: undefined };\n};\n\n/**\n * Describes the message process.ProcessSelector.\n * Use `create(ProcessSelectorSchema)` to create a new message.\n */\nexport const ProcessSelectorSchema: GenMessage<ProcessSelector> = /*@__PURE__*/\n messageDesc(file_process_process, 19);\n\n/**\n * @generated from enum process.Signal\n */\nexport enum Signal {\n /**\n * @generated from enum value: SIGNAL_UNSPECIFIED = 0;\n */\n UNSPECIFIED = 0,\n\n /**\n * @generated from enum value: SIGNAL_SIGTERM = 15;\n */\n SIGTERM = 15,\n\n /**\n * @generated from enum value: SIGNAL_SIGKILL = 9;\n */\n SIGKILL = 9,\n}\n\n/**\n * Describes the enum process.Signal.\n */\nexport const SignalSchema: GenEnum<Signal> = /*@__PURE__*/\n enumDesc(file_process_process, 0);\n\n/**\n * @generated from service process.Process\n */\nexport const Process: GenService<{\n /**\n * @generated from rpc process.Process.List\n */\n list: {\n methodKind: \"unary\";\n input: typeof ListRequestSchema;\n output: typeof ListResponseSchema;\n },\n /**\n * @generated from rpc process.Process.Connect\n */\n connect: {\n methodKind: \"server_streaming\";\n input: typeof ConnectRequestSchema;\n output: typeof ConnectResponseSchema;\n },\n /**\n * @generated from rpc process.Process.Start\n */\n start: {\n methodKind: \"server_streaming\";\n input: typeof StartRequestSchema;\n output: typeof StartResponseSchema;\n },\n /**\n * @generated from rpc process.Process.Update\n */\n update: {\n methodKind: \"unary\";\n input: typeof UpdateRequestSchema;\n output: typeof UpdateResponseSchema;\n },\n /**\n * Client input stream ensures ordering of messages\n *\n * @generated from rpc process.Process.StreamInput\n */\n streamInput: {\n methodKind: \"client_streaming\";\n input: typeof StreamInputRequestSchema;\n output: typeof StreamInputResponseSchema;\n },\n /**\n * @generated from rpc process.Process.SendInput\n */\n sendInput: {\n methodKind: \"unary\";\n input: typeof SendInputRequestSchema;\n output: typeof SendInputResponseSchema;\n },\n /**\n * @generated from rpc process.Process.SendSignal\n */\n sendSignal: {\n methodKind: \"unary\";\n input: typeof SendSignalRequestSchema;\n output: typeof SendSignalResponseSchema;\n },\n}> = /*@__PURE__*/\n serviceDesc(file_process_process, 0);\n\n","import {\n Code,\n ConnectError,\n createClient,\n Client,\n Transport,\n} from '@connectrpc/connect'\n\nimport { Signal, Process as ProcessService } from '../../envd/process/process_pb'\nimport {\n ConnectionConfig,\n ConnectionOpts,\n Username,\n KEEPALIVE_PING_HEADER,\n KEEPALIVE_PING_INTERVAL_SEC,\n} from '../../connectionConfig'\nimport { CommandHandle } from './commandHandle'\nimport { authenticationHeader, handleRpcError } from '../../envd/rpc'\nimport { handleProcessStartEvent } from '../../envd/api'\n\nexport interface PtyCreateOpts\n extends Pick<ConnectionOpts, 'requestTimeoutMs'> {\n /**\n * Number of columns for the PTY.\n */\n cols: number\n /**\n * Number of rows for the PTY.\n */\n rows: number\n /**\n * Callback to handle PTY data.\n */\n onData: (data: Uint8Array) => void | Promise<void>\n /**\n * Timeout for the PTY in **milliseconds**.\n * \n * @default 60_000 // 60 seconds\n */\n timeoutMs?: number\n /**\n * User to use for the PTY.\n * \n * @default `user`\n */\n user?: Username\n /**\n * Environment variables for the PTY.\n * \n * @default {}\n */\n envs?: Record<string, string>\n /**\n * Working directory for the PTY.\n * \n * @default // home directory of the user used to start the PTY\n */\n cwd?: string\n}\n\n/**\n * Module for interacting with PTYs (pseudo-terminals) in the sandbox.\n */\nexport class Pty {\n private readonly rpc: Client<typeof ProcessService>\n\n constructor(\n private readonly transport: Transport,\n private readonly connectionConfig: ConnectionConfig\n ) {\n this.rpc = createClient(ProcessService, this.transport)\n }\n\n /**\n * Create a new PTY (pseudo-terminal).\n *\n * @param opts options for creating the PTY.\n * \n * @returns handle to interact with the PTY.\n */\n async create(opts: PtyCreateOpts) {\n const requestTimeoutMs =\n opts?.requestTimeoutMs ?? this.connectionConfig.requestTimeoutMs\n const envs = opts?.envs ?? {}\n envs.TERM = 'xterm-256color'\n const controller = new AbortController()\n\n const reqTimeout = setTimeout(() => {\n controller.abort()\n }, requestTimeoutMs)\n\n const events = this.rpc.start(\n {\n process: {\n cmd: '/bin/bash',\n args: ['-i', '-l'],\n envs: envs,\n cwd: opts?.cwd,\n },\n pty: {\n size: {\n cols: opts.cols,\n rows: opts.rows,\n },\n },\n },\n {\n headers: {\n ...authenticationHeader(opts?.user),\n [KEEPALIVE_PING_HEADER]: KEEPALIVE_PING_INTERVAL_SEC.toString(),\n },\n signal: controller.signal,\n timeoutMs: opts?.timeoutMs ?? 60_000,\n }\n )\n\n try {\n const pid = await handleProcessStartEvent(events)\n\n clearTimeout(reqTimeout)\n\n return new CommandHandle(\n pid,\n () => controller.abort(),\n () => this.kill(pid),\n events,\n undefined,\n undefined,\n opts.onData\n )\n } catch (err) {\n throw handleRpcError(err)\n }\n }\n\n /**\n * Send input to a PTY.\n *\n * @param pid process ID of the PTY.\n * @param data input data to send to the PTY.\n * @param opts connection options.\n */\n async sendInput(\n pid: number,\n data: Uint8Array,\n opts?: Pick<ConnectionOpts, 'requestTimeoutMs'>\n ): Promise<void> {\n try {\n await this.rpc.sendInput(\n {\n input: {\n input: {\n case: 'pty',\n value: data,\n },\n },\n process: {\n selector: {\n case: 'pid',\n value: pid,\n },\n },\n },\n {\n signal: this.connectionConfig.getSignal(opts?.requestTimeoutMs),\n }\n )\n } catch (err) {\n throw handleRpcError(err)\n }\n }\n\n /**\n * Resize PTY.\n * Call this when the terminal window is resized and the number of columns and rows has changed.\n *\n * @param pid process ID of the PTY.\n * @param size new size of the PTY.\n * @param opts connection options.\n */\n async resize(\n pid: number,\n size: {\n cols: number\n rows: number\n },\n opts?: Pick<ConnectionOpts, 'requestTimeoutMs'>\n ): Promise<void> {\n try {\n await this.rpc.update(\n {\n process: {\n selector: {\n case: 'pid',\n value: pid,\n },\n },\n pty: {\n size,\n },\n },\n {\n signal: this.connectionConfig.getSignal(opts?.requestTimeoutMs),\n }\n )\n } catch (err) {\n throw handleRpcError(err)\n }\n }\n\n /**\n * Kill a running PTY specified by process ID.\n * It uses `SIGKILL` signal to kill the PTY.\n *\n * @param pid process ID of the PTY.\n * @param opts connection options.\n * \n * @returns `true` if the PTY was killed, `false` if the PTY was not found.\n */\n async kill(\n pid: number,\n opts?: Pick<ConnectionOpts, 'requestTimeoutMs'>\n ): Promise<boolean> {\n try {\n await this.rpc.sendSignal(\n {\n process: {\n selector: {\n case: 'pid',\n value: pid,\n },\n },\n signal: Signal.SIGKILL,\n },\n {\n signal: this.connectionConfig.getSignal(opts?.requestTimeoutMs),\n }\n )\n\n return true\n } catch (err) {\n if (err instanceof ConnectError) {\n if (err.code === Code.NotFound) {\n return false\n }\n }\n\n throw handleRpcError(err)\n }\n }\n}\n","import { ApiClient, components, handleApiError } from '../api'\nimport {\n ConnectionConfig,\n ConnectionOpts,\n DEFAULT_SANDBOX_TIMEOUT_MS,\n} from '../connectionConfig'\nimport { compareVersions } from 'compare-versions'\nimport { NotFoundError, TemplateError } from '../errors'\nimport { timeoutToSeconds } from '../utils'\n\n/**\n * Options for request to the Sandbox API.\n */\nexport interface SandboxApiOpts\n extends Partial<\n Pick<\n ConnectionOpts,\n 'apiKey' | 'headers' | 'debug' | 'domain' | 'requestTimeoutMs'\n >\n > {}\n\n/**\n * Options for creating a new Sandbox.\n */\nexport interface SandboxOpts extends ConnectionOpts {\n /**\n * Custom metadata for the sandbox.\n *\n * @default {}\n */\n metadata?: Record<string, string>\n\n /**\n * Custom environment variables for the sandbox.\n *\n * Used when executing commands and code in the sandbox.\n * Can be overridden with the `envs` argument when executing commands or code.\n *\n * @default {}\n */\n envs?: Record<string, string>\n\n /**\n * Timeout for the sandbox in **milliseconds**.\n * Maximum time a sandbox can be kept alive is 24 hours (86_400_000 milliseconds) for Pro users and 1 hour (3_600_000 milliseconds) for Hobby users.\n *\n * @default 300_000 // 5 minutes\n */\n timeoutMs?: number\n\n /**\n * Secure all traffic coming to the sandbox controller with auth token\n *\n * @default true\n */\n secure?: boolean\n\n /**\n * Allow sandbox to access the internet\n *\n * @default true\n */\n // allowInternetAccess?: boolean\n}\n\nexport type SandboxBetaCreateOpts = SandboxOpts & {\n /**\n * Automatically pause the sandbox after the timeout expires.\n * @default false\n */\n autoPause?: boolean\n}\n\n/**\n * Options for connecting to a Sandbox.\n */\nexport type SandboxConnectOpts = Omit<SandboxOpts, 'metadata' | 'envs'>\n\n/**\n * State of the sandbox.\n */\nexport type SandboxState = 'running' | 'paused'\n\nexport interface SandboxListOpts extends SandboxApiOpts {\n /**\n * Filter the list of sandboxes, e.g. by metadata `metadata:{\"key\": \"value\"}`, if there are multiple filters they are combined with AND.\n *\n */\n query?: {\n metadata?: Record<string, string>\n /**\n * Filter the list of sandboxes by state.\n * @default ['running', 'paused']\n */\n state?: Array<SandboxState>\n }\n\n /**\n * Number of sandboxes to return per page.\n *\n * @default 100\n */\n limit?: number\n\n /**\n * Token to the next page.\n */\n nextToken?: string\n}\n\nexport interface SandboxMetricsOpts extends SandboxApiOpts {\n /**\n * Start time for the metrics, defaults to the start of the sandbox\n */\n start?: string | Date\n /**\n * End time for the metrics, defaults to the current time\n */\n end?: string | Date\n}\n\n/**\n * Information about a sandbox.\n */\nexport interface SandboxInfo {\n /**\n * Sandbox ID.\n */\n sandboxId: string\n\n /**\n * Template ID.\n */\n templateId: string\n\n /**\n * Template name.\n */\n name?: string\n\n /**\n * Saved sandbox metadata.\n */\n metadata: Record<string, string>\n\n /**\n * Sandbox start time.\n */\n startedAt: Date\n\n /**\n * Sandbox expiration date.\n */\n endAt: Date\n\n /**\n * Sandbox state.\n *\n * @string can be `running` or `paused`\n */\n state: SandboxState\n\n /**\n * Sandbox CPU count.\n */\n cpuCount: number\n\n /**\n * Sandbox Memory size in MiB.\n */\n memoryMB: number\n\n /**\n * Envd version.\n */\n envdVersion: string | undefined\n}\n\n/**\n * Sandbox resource usage metrics.\n */\nexport interface SandboxMetrics {\n /**\n * Timestamp of the metrics.\n */\n timestamp: Date\n\n /**\n * CPU usage in percentage.\n */\n cpuUsedPct: number\n\n /**\n * Number of CPU cores.\n */\n cpuCount: number\n\n /**\n * Memory usage in bytes.\n */\n memUsed: number\n\n /**\n * Total memory available in bytes.\n */\n memTotal: number\n\n /**\n * Used disk space in bytes.\n */\n diskUsed: number\n\n /**\n * Total disk space available in bytes.\n */\n diskTotal: number\n}\n\nexport class SandboxApi {\n protected constructor() {}\n\n /**\n * Kill the sandbox specified by sandbox ID.\n *\n * @param sandboxId sandbox ID.\n * @param opts connection options.\n *\n * @returns `true` if the sandbox was found and killed, `false` otherwise.\n */\n static async kill(\n sandboxId: string,\n opts?: SandboxApiOpts\n ): Promise<boolean> {\n const config = new ConnectionConfig(opts)\n const client = new ApiClient(config)\n\n const res = await client.api.DELETE('/sandboxes/{sandboxID}', {\n params: {\n path: {\n sandboxID: sandboxId,\n },\n },\n signal: config.getSignal(opts?.requestTimeoutMs),\n })\n\n if (res.error?.code === 404) {\n return false\n }\n\n const err = handleApiError(res)\n if (err) {\n throw err\n }\n\n return true\n }\n\n /**\n * Get sandbox information like sandbox ID, template, metadata, started at/end at date.\n *\n * @param sandboxId sandbox ID.\n * @param opts connection options.\n *\n * @returns sandbox information.\n */\n static async getInfo(\n sandboxId: string,\n opts?: SandboxApiOpts\n ): Promise<SandboxInfo> {\n const fullInfo = await this.getFullInfo(sandboxId, opts)\n delete fullInfo.envdAccessToken\n delete fullInfo.sandboxDomain\n\n return fullInfo\n }\n\n /**\n * Get the metrics of the sandbox.\n *\n * @param sandboxId sandbox ID.\n * @param opts sandbox metrics options.\n *\n * @returns List of sandbox metrics containing CPU, memory and disk usage information.\n */\n static async getMetrics(\n sandboxId: string,\n opts?: SandboxMetricsOpts\n ): Promise<SandboxMetrics[]> {\n const config = new ConnectionConfig(opts)\n const client = new ApiClient(config)\n\n const res = await client.api.GET('/sandboxes/{sandboxID}/metrics', {\n params: {\n path: {\n sandboxID: sandboxId,\n start: opts?.start,\n end: opts?.end,\n },\n },\n signal: config.getSignal(opts?.requestTimeoutMs),\n })\n\n const err = handleApiError(res)\n if (err) {\n throw err\n }\n\n return (\n res.data?.map((metric: components['schemas']['SandboxMetric']) => ({\n timestamp: new Date(metric.timestamp),\n cpuUsedPct: metric.cpuUsedPct,\n cpuCount: metric.cpuCount,\n memUsed: metric.memUsedMiB * 1024 * 1024,\n memTotal: metric.memTotalMiB * 1024 * 1024,\n // diskUsed: metric.diskUsed,\n diskUsed: -1,\n // diskTotal: metric.diskTotal,\n diskTotal: -1,\n })) ?? []\n )\n }\n\n /**\n * Set the timeout of the specified sandbox.\n * After the timeout expires the sandbox will be automatically killed.\n *\n * This method can extend or reduce the sandbox timeout set when creating the sandbox or from the last call to {@link Sandbox.setTimeout}.\n *\n * Maximum time a sandbox can be kept alive is 24 hours (86_400_000 milliseconds) for Pro users and 1 hour (3_600_000 milliseconds) for Hobby users.\n *\n * @param sandboxId sandbox ID.\n * @param timeoutMs timeout in **milliseconds**.\n * @param opts connection options.\n */\n static async setTimeout(\n sandboxId: string,\n timeoutMs: number,\n opts?: SandboxApiOpts\n ): Promise<void> {\n const config = new ConnectionConfig(opts)\n const client = new ApiClient(config)\n\n const res = await client.api.POST('/sandboxes/{sandboxID}/timeout', {\n params: {\n path: {\n sandboxID: sandboxId,\n },\n },\n body: {\n timeout: timeoutToSeconds(timeoutMs),\n },\n signal: config.getSignal(opts?.requestTimeoutMs),\n })\n\n const err = handleApiError(res)\n if (err) {\n throw err\n }\n }\n\n static async getFullInfo(sandboxId: string, opts?: SandboxApiOpts) {\n const config = new ConnectionConfig(opts)\n const client = new ApiClient(config)\n\n const res = await client.api.GET('/sandboxes/{sandboxID}', {\n params: {\n path: {\n sandboxID: sandboxId,\n },\n },\n signal: config.getSignal(opts?.requestTimeoutMs),\n })\n\n const err = handleApiError(res)\n if (err) {\n throw err\n }\n\n if (!res.data) {\n throw new Error('Sandbox not found')\n }\n\n return {\n sandboxId: `${res.data.sandboxID}-${res.data.clientID}`,\n templateId: res.data.templateID,\n ...(res.data.alias && { name: res.data.alias }),\n metadata: res.data.metadata ?? {},\n envdVersion: res.data.envdVersion,\n envdAccessToken: res.data.envdAccessToken,\n startedAt: new Date(res.data.startedAt),\n endAt: new Date(res.data.endAt),\n state: res.data.state,\n cpuCount: res.data.cpuCount,\n memoryMB: res.data.memoryMB,\n // sandboxDomain: res.data.domain || undefined,\n sandboxDomain: undefined,\n }\n }\n\n /**\n * Pause the sandbox specified by sandbox ID.\n *\n * @param sandboxId sandbox ID.\n * @param opts connection options.\n *\n * @returns `true` if the sandbox got paused, `false` if the sandbox was already paused.\n */\n static async betaPause(\n sandboxId: string,\n opts?: SandboxApiOpts\n ): Promise<boolean> {\n const config = new ConnectionConfig(opts)\n const client = new ApiClient(config)\n\n const res = await client.api.POST('/sandboxes/{sandboxID}/pause', {\n params: {\n path: {\n sandboxID: sandboxId,\n },\n },\n signal: config.getSignal(opts?.requestTimeoutMs),\n })\n\n if (res.error?.code === 404) {\n throw new NotFoundError(`Sandbox ${sandboxId} not found`)\n }\n\n if (res.error?.code === 409) {\n // Sandbox is already paused\n return false\n }\n\n const err = handleApiError(res)\n if (err) {\n throw err\n }\n\n return true\n }\n\n protected static async createSandbox(\n template: string,\n timeoutMs: number,\n opts?: SandboxBetaCreateOpts\n ): Promise<{\n sandboxId: string\n sandboxDomain?: string\n envdVersion: string\n envdAccessToken?: string\n }> {\n const config = new ConnectionConfig(opts)\n const client = new ApiClient(config)\n\n const res = await client.api.POST('/sandboxes', {\n body: {\n autoPause: opts?.autoPause ?? false,\n templateID: template,\n metadata: opts?.metadata,\n envVars: opts?.envs,\n timeout: timeoutToSeconds(timeoutMs),\n secure: opts?.secure ?? false,\n // allow_internet_access: opts?.allowInternetAccess ?? true,\n allow_internet_access: true,\n },\n signal: config.getSignal(opts?.requestTimeoutMs),\n })\n\n const err = handleApiError(res)\n if (err) {\n throw err\n }\n\n if (compareVersions(res.data!.envdVersion, '0.1.0') < 0) {\n await this.kill(res.data!.sandboxID, opts)\n throw new TemplateError(\n 'You need to update the template to use the new SDK. ' +\n 'You can do this by running `ppio-sandbox-cli template build` in the directory with the template.'\n )\n }\n\n return {\n sandboxId: `${res.data!.sandboxID}-${res.data!.clientID}`,\n // sandboxDomain: res.data!.domain || undefined,\n sandboxDomain: undefined,\n envdVersion: res.data!.envdVersion,\n envdAccessToken: res.data!.envdAccessToken,\n }\n }\n\n protected static async resumeSandbox(\n sandboxId: string,\n opts?: SandboxConnectOpts\n ): Promise<boolean> {\n const timeoutMs = opts?.timeoutMs ?? DEFAULT_SANDBOX_TIMEOUT_MS\n\n const config = new ConnectionConfig(opts)\n const client = new ApiClient(config)\n\n const res = await client.api.POST('/sandboxes/{sandboxID}/resume', {\n params: {\n path: {\n sandboxID: sandboxId,\n },\n },\n body: {\n autoPause: false,\n timeout: timeoutToSeconds(timeoutMs),\n },\n signal: config.getSignal(opts?.requestTimeoutMs),\n })\n\n if (res.error?.code === 404) {\n throw new NotFoundError(`Paused sandbox ${sandboxId} not found`)\n }\n\n if (res.error?.code === 409) {\n // Sandbox is already running\n return false\n }\n\n const err = handleApiError(res)\n if (err) {\n throw err\n }\n\n return true\n }\n\n protected static async connectSandbox(\n sandboxId: string,\n opts?: SandboxConnectOpts\n ) {\n const timeoutMs = opts?.timeoutMs ?? DEFAULT_SANDBOX_TIMEOUT_MS\n\n const config = new ConnectionConfig(opts)\n const client = new ApiClient(config)\n\n const res = await client.api.POST('/sandboxes/{sandboxID}/connect', {\n params: {\n path: {\n sandboxID: sandboxId,\n },\n },\n body: {\n timeout: timeoutToSeconds(timeoutMs),\n },\n signal: config.getSignal(opts?.requestTimeoutMs),\n })\n\n if (res.error?.code === 404) {\n throw new NotFoundError(`Sandbox ${sandboxId} not found`)\n }\n\n const err = handleApiError(res)\n if (err) {\n throw err\n }\n\n if (!res.data) {\n throw new Error('Sandbox not found')\n }\n\n return {\n sandboxId: `${res.data.sandboxID}-${res.data.clientID}`,\n envdVersion: res.data.envdVersion,\n envdAccessToken: res.data.envdAccessToken,\n sandboxDomain: undefined,\n }\n }\n}\n\n/**\n * Paginator for listing sandboxes.\n *\n * @example\n * ```ts\n * const paginator = Sandbox.list()\n *\n * while (paginator.hasNext) {\n * const sandboxes = await paginator.nextItems()\n * console.log(sandboxes)\n * }\n * ```\n */\nexport class SandboxPaginator {\n private _hasNext: boolean\n private _nextToken?: string\n\n private readonly config: ConnectionConfig\n private client: ApiClient\n\n private query: SandboxListOpts['query']\n private readonly limit?: number\n\n constructor(opts?: SandboxListOpts) {\n this.config = new ConnectionConfig(opts)\n this.client = new ApiClient(this.config)\n\n this._hasNext = true\n this._nextToken = opts?.nextToken\n\n this.query = opts?.query\n this.limit = opts?.limit\n }\n\n /**\n * Returns True if there are more items to fetch.\n */\n get hasNext(): boolean {\n return this._hasNext\n }\n\n /**\n * Returns the next token to use for pagination.\n */\n get nextToken(): string | undefined {\n return this._nextToken\n }\n\n /**\n * Get the next page of sandboxes.\n *\n * @throws Error if there are no more items to fetch. Call this method only if `hasNext` is `true`.\n *\n * @returns List of sandboxes\n */\n async nextItems(): Promise<SandboxInfo[]> {\n if (!this.hasNext) {\n throw new Error('No more items to fetch')\n }\n\n let metadata = undefined\n if (this.query?.metadata) {\n const encodedPairs: Record<string, string> = Object.fromEntries(\n Object.entries(this.query.metadata).map(([key, value]) => [\n encodeURIComponent(key),\n encodeURIComponent(value),\n ])\n )\n\n metadata = new URLSearchParams(encodedPairs).toString()\n }\n\n const res = await this.client.api.GET('/v2/sandboxes', {\n params: {\n query: {\n metadata,\n state: this.query?.state,\n limit: this.limit,\n nextToken: this.nextToken,\n },\n },\n // requestTimeoutMs is already passed here via the connectionConfig.\n signal: this.config.getSignal(),\n })\n\n const err = handleApiError(res)\n if (err) {\n throw err\n }\n\n this._nextToken = res.response.headers.get('x-next-token') || undefined\n this._hasNext = !!this._nextToken\n\n return (res.data ?? []).map(\n (sandbox: components['schemas']['ListedSandbox']) => ({\n sandboxId: `${sandbox.sandboxID}-${sandbox.clientID}`,\n templateId: sandbox.templateID,\n ...(sandbox.alias && { name: sandbox.alias }),\n metadata: sandbox.metadata ?? {},\n startedAt: new Date(sandbox.startedAt),\n endAt: new Date(sandbox.endAt),\n state: sandbox.state,\n cpuCount: sandbox.cpuCount,\n memoryMB: sandbox.memoryMB,\n // envdVersion: sandbox.envdVersion,\n envdVersion: undefined,\n })\n )\n }\n}\n","export { ApiClient } from './api'\nexport type { components, paths } from './api'\n\nexport { ConnectionConfig } from './connectionConfig'\nexport type { ConnectionOpts, Username } from './connectionConfig'\nexport {\n AuthenticationError,\n InvalidArgumentError,\n NotEnoughSpaceError,\n NotFoundError,\n SandboxError,\n TemplateError,\n TimeoutError,\n RateLimitError,\n} from './errors'\nexport type { Logger } from './logs'\n\nexport { getSignature } from './sandbox/signature'\n\nexport { FileType } from './sandbox/filesystem'\nexport type { WriteInfo, EntryInfo, Filesystem } from './sandbox/filesystem'\nexport { FilesystemEventType } from './sandbox/filesystem/watchHandle'\nexport type {\n FilesystemEvent,\n WatchHandle,\n} from './sandbox/filesystem/watchHandle'\n\nexport { CommandExitError } from './sandbox/commands/commandHandle'\nexport type {\n CommandResult,\n Stdout,\n Stderr,\n PtyOutput,\n CommandHandle,\n} from './sandbox/commands/commandHandle'\nexport type {\n SandboxInfo,\n SandboxMetrics,\n SandboxOpts,\n SandboxApiOpts,\n SandboxConnectOpts,\n SandboxBetaCreateOpts,\n SandboxMetricsOpts,\n SandboxState,\n SandboxListOpts,\n SandboxPaginator,\n} from './sandbox/sandboxApi'\n\nexport type {\n ProcessInfo,\n CommandRequestOpts,\n CommandConnectOpts,\n CommandStartOpts,\n Commands,\n Pty,\n} from './sandbox/commands'\n\nexport { Sandbox }\nimport { Sandbox } from './sandbox'\nexport default Sandbox\n"],"mappings":"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","names":["_a","_a","_a","message","_a","createClient","ConnectError","Code","createClient","_a","createClient","Code","ConnectError","ConnectError","Code","FilesystemEventType","_a","FileType","Filesystem","createClient","_a","ConnectError","Code","_a","Code","ConnectError","createClient","enumDesc","fileDesc","messageDesc","serviceDesc","serviceDesc","Code","ConnectError","createClient","createClient","_a","ConnectError","Code","createClient","ConnectError","Code","_a","pid","compareVersions","_a","compareVersions","compareVersions","_a","Filesystem","compareVersions"]}
@@ -1,5 +1,5 @@
1
- import { S as Sandbox$1 } from './index-D9GCzBVP.mjs';
2
- export { A as ApiClient, b as AuthenticationError, H as CommandConnectOpts, l as CommandExitError, q as CommandHandle, G as CommandRequestOpts, m as CommandResult, J as CommandStartOpts, K as Commands, C as ConnectionConfig, a as ConnectionOpts, E as EntryInfo, F as FileType, h as Filesystem, j as FilesystemEvent, i as FilesystemEventType, I as InvalidArgumentError, L as Logger, N as NotEnoughSpaceError, d as NotFoundError, D as ProcessInfo, M as Pty, P as PtyOutput, R as RateLimitError, u as SandboxApiOpts, w as SandboxBetaCreateOpts, v as SandboxConnectOpts, e as SandboxError, r as SandboxInfo, z as SandboxListOpts, s as SandboxMetrics, x as SandboxMetricsOpts, t as SandboxOpts, B as SandboxPaginator, y as SandboxState, o as Stderr, n as Stdout, T as TemplateError, f as TimeoutError, U as Username, k as WatchHandle, W as WriteInfo, c as components, g as getSignature, p as paths } from './index-D9GCzBVP.mjs';
1
+ import { S as Sandbox$1 } from './index-DVtYWWe-.mjs';
2
+ export { A as ApiClient, b as AuthenticationError, H as CommandConnectOpts, l as CommandExitError, q as CommandHandle, G as CommandRequestOpts, m as CommandResult, J as CommandStartOpts, K as Commands, C as ConnectionConfig, a as ConnectionOpts, E as EntryInfo, F as FileType, h as Filesystem, j as FilesystemEvent, i as FilesystemEventType, I as InvalidArgumentError, L as Logger, N as NotEnoughSpaceError, d as NotFoundError, D as ProcessInfo, M as Pty, P as PtyOutput, R as RateLimitError, u as SandboxApiOpts, w as SandboxBetaCreateOpts, v as SandboxConnectOpts, e as SandboxError, r as SandboxInfo, z as SandboxListOpts, s as SandboxMetrics, x as SandboxMetricsOpts, t as SandboxOpts, B as SandboxPaginator, y as SandboxState, o as Stderr, n as Stdout, T as TemplateError, f as TimeoutError, U as Username, k as WatchHandle, W as WriteInfo, c as components, g as getSignature, p as paths } from './index-DVtYWWe-.mjs';
3
3
  import 'openapi-fetch';
4
4
  import '@connectrpc/connect';
5
5
  import '@bufbuild/protobuf/codegenv2';
@@ -1,5 +1,5 @@
1
- import { S as Sandbox$1 } from './index-D9GCzBVP.js';
2
- export { A as ApiClient, b as AuthenticationError, H as CommandConnectOpts, l as CommandExitError, q as CommandHandle, G as CommandRequestOpts, m as CommandResult, J as CommandStartOpts, K as Commands, C as ConnectionConfig, a as ConnectionOpts, E as EntryInfo, F as FileType, h as Filesystem, j as FilesystemEvent, i as FilesystemEventType, I as InvalidArgumentError, L as Logger, N as NotEnoughSpaceError, d as NotFoundError, D as ProcessInfo, M as Pty, P as PtyOutput, R as RateLimitError, u as SandboxApiOpts, w as SandboxBetaCreateOpts, v as SandboxConnectOpts, e as SandboxError, r as SandboxInfo, z as SandboxListOpts, s as SandboxMetrics, x as SandboxMetricsOpts, t as SandboxOpts, B as SandboxPaginator, y as SandboxState, o as Stderr, n as Stdout, T as TemplateError, f as TimeoutError, U as Username, k as WatchHandle, W as WriteInfo, c as components, g as getSignature, p as paths } from './index-D9GCzBVP.js';
1
+ import { S as Sandbox$1 } from './index-DVtYWWe-.js';
2
+ export { A as ApiClient, b as AuthenticationError, H as CommandConnectOpts, l as CommandExitError, q as CommandHandle, G as CommandRequestOpts, m as CommandResult, J as CommandStartOpts, K as Commands, C as ConnectionConfig, a as ConnectionOpts, E as EntryInfo, F as FileType, h as Filesystem, j as FilesystemEvent, i as FilesystemEventType, I as InvalidArgumentError, L as Logger, N as NotEnoughSpaceError, d as NotFoundError, D as ProcessInfo, M as Pty, P as PtyOutput, R as RateLimitError, u as SandboxApiOpts, w as SandboxBetaCreateOpts, v as SandboxConnectOpts, e as SandboxError, r as SandboxInfo, z as SandboxListOpts, s as SandboxMetrics, x as SandboxMetricsOpts, t as SandboxOpts, B as SandboxPaginator, y as SandboxState, o as Stderr, n as Stdout, T as TemplateError, f as TimeoutError, U as Username, k as WatchHandle, W as WriteInfo, c as components, g as getSignature, p as paths } from './index-DVtYWWe-.js';
3
3
  import 'openapi-fetch';
4
4
  import '@connectrpc/connect';
5
5
  import '@bufbuild/protobuf/codegenv2';