@computesdk/runloop 1.2.7 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +7 -15
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +7 -15
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -122,9 +122,9 @@ var runloop = (0, import_computesdk.createProvider)({
|
|
|
122
122
|
const startTime = Date.now();
|
|
123
123
|
const devbox = sandbox;
|
|
124
124
|
const client = sandbox.client;
|
|
125
|
+
const effectiveRuntime = runtime || // Strong Python indicators
|
|
126
|
+
(code.includes("print(") || code.includes("import ") || code.includes("def ") || code.includes("sys.") || code.includes("json.") || code.includes("__") || code.includes('f"') || code.includes("f'") || code.includes("raise ") ? "python" : "node");
|
|
125
127
|
try {
|
|
126
|
-
const effectiveRuntime = runtime || // Strong Python indicators
|
|
127
|
-
(code.includes("print(") || code.includes("import ") || code.includes("def ") || code.includes("sys.") || code.includes("json.") || code.includes("__") || code.includes('f"') || code.includes("f'") || code.includes("raise ") ? "python" : "node");
|
|
128
128
|
const encoded = Buffer.from(code).toString("base64");
|
|
129
129
|
let command;
|
|
130
130
|
if (effectiveRuntime === "python") {
|
|
@@ -145,12 +145,9 @@ var runloop = (0, import_computesdk.createProvider)({
|
|
|
145
145
|
}
|
|
146
146
|
}
|
|
147
147
|
return {
|
|
148
|
-
|
|
149
|
-
stderr: executionResult.stderr || "",
|
|
148
|
+
output: (executionResult.stdout || "") + (executionResult.stderr || ""),
|
|
150
149
|
exitCode: executionResult.exit_status || 0,
|
|
151
|
-
|
|
152
|
-
sandboxId: devbox.id || "runloop-unknown",
|
|
153
|
-
provider: "runloop"
|
|
150
|
+
language: effectiveRuntime
|
|
154
151
|
};
|
|
155
152
|
} catch (error) {
|
|
156
153
|
if (error instanceof Error && error.message === "exit status 1") {
|
|
@@ -161,12 +158,9 @@ var runloop = (0, import_computesdk.createProvider)({
|
|
|
161
158
|
throw new Error(`Syntax error: ${syntaxErrorLine}`);
|
|
162
159
|
} else {
|
|
163
160
|
return {
|
|
164
|
-
|
|
165
|
-
stderr: actualStderr || "Error: Runtime error occurred during execution",
|
|
161
|
+
output: actualStderr || "Error: Runtime error occurred during execution",
|
|
166
162
|
exitCode: 1,
|
|
167
|
-
|
|
168
|
-
sandboxId: devbox.id || "runloop-unknown",
|
|
169
|
-
provider: "runloop"
|
|
163
|
+
language: effectiveRuntime
|
|
170
164
|
};
|
|
171
165
|
}
|
|
172
166
|
}
|
|
@@ -194,9 +188,7 @@ var runloop = (0, import_computesdk.createProvider)({
|
|
|
194
188
|
stdout: executionResult.stdout || "",
|
|
195
189
|
stderr: executionResult.stderr || "",
|
|
196
190
|
exitCode: executionResult.exit_status || 0,
|
|
197
|
-
|
|
198
|
-
sandboxId: devbox.id || "runloop-unknown",
|
|
199
|
-
provider: "runloop"
|
|
191
|
+
durationMs: Date.now() - startTime
|
|
200
192
|
};
|
|
201
193
|
} catch (error) {
|
|
202
194
|
if (error instanceof Error && error.message.includes("Syntax error")) {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * Runloop Provider - Factory-based Implementation\n *\n * Full-featured provider with filesystem support using the factory pattern.\n * Reduces ~400 lines of boilerplate to ~100 lines of core logic.\n */\n\nimport { Runloop } from \"@runloop/api-client\";\nimport { createProvider } from \"computesdk\";\nimport type {\n ExecutionResult,\n SandboxInfo,\n CreateSandboxOptions,\n FileEntry,\n CreateSnapshotOptions,\n ListSnapshotsOptions,\n Runtime,\n SandboxStatus,\n Sandbox,\n} from \"computesdk\";\n\n// Define Runloop-specific types\ntype RunloopSnapshot = Runloop.DevboxSnapshotView;\ntype RunloopTemplate = Runloop.BlueprintView;\n\n/**\n * Runloop-specific configuration options\n */\nexport interface RunloopConfig {\n /** Runloop API key - if not provided, will fallback to RUNLOOP_API_KEY environment variable */\n apiKey?: string;\n /** Execution timeout in milliseconds */\n timeout?: number;\n}\n\n/**\n * Runloop-specific blueprint creation options\n */\nexport interface CreateBlueprintTemplateOptions {\n /** Name of the blueprint template */\n name: string;\n /** Custom Dockerfile content */\n dockerfile?: string;\n /** System setup commands to run during blueprint creation */\n systemSetupCommands?: string[];\n /** Launch commands to run when starting a devbox from this blueprint */\n launchCommands?: string[];\n /** File mounts as key-value pairs (path -> content) */\n fileMounts?: Record<string, string>;\n /** Code repository mounts */\n codeMounts?: Array<{\n repoName: string;\n repoOwner: string;\n token?: string;\n installCommand?: string;\n }>;\n /** Resource size for devboxes created from this blueprint */\n resourceSize?:\n | \"X_SMALL\"\n | \"SMALL\"\n | \"MEDIUM\"\n | \"LARGE\"\n | \"X_LARGE\"\n | \"XX_LARGE\"\n | \"CUSTOM_SIZE\";\n /** CPU architecture */\n architecture?: \"x86_64\" | \"arm64\";\n /** Custom CPU cores (requires CUSTOM_SIZE) */\n customCpuCores?: number;\n /** Custom memory in GB (requires CUSTOM_SIZE) */\n customMemoryGb?: number;\n /** Custom disk size (requires CUSTOM_SIZE) */\n customDiskSize?: number;\n /** Available ports for the devbox */\n availablePorts?: number[];\n /** Action to take when devbox is idle */\n afterIdle?: { action: string; timeSeconds: number };\n /** Keep alive time in seconds */\n keepAliveTimeSeconds?: number;\n}\n\n/**\n * Create a Runloop provider instance using the factory pattern\n */\nexport const runloop = createProvider<\n Runloop.DevboxView, // TSandbox\n RunloopConfig, // TConfig\n RunloopTemplate, // TTemplate \n RunloopSnapshot // TSnapshot\n>({\n name: \"runloop\",\n methods: {\n sandbox: {\n // Collection operations (map to compute.sandbox.*)\n create: async (config: RunloopConfig, options?: CreateSandboxOptions) => {\n // Validate API key\n const apiKey =\n config.apiKey ||\n (typeof process !== \"undefined\" && process.env?.RUNLOOP_API_KEY) ||\n \"\";\n\n if (!apiKey) {\n throw new Error(\n `Missing Runloop API key. Provide 'apiKey' in config or set RUNLOOP_API_KEY environment variable. Get your API key from https://runloop.ai/`\n );\n }\n\n const timeout = config.timeout;\n\n try {\n const client = new Runloop({\n bearerToken: apiKey,\n });\n\n let devboxParams: Runloop.DevboxCreateParams = {\n launch_parameters: {\n keep_alive_time_seconds: timeout || options?.timeout || 300000,\n },\n name: options?.sandboxId,\n metadata: options?.metadata,\n environment_variables: options?.envs,\n };\n\n // Use blueprint if specified\n if (options?.templateId) {\n const templateId = options?.templateId;\n // Check template prefix to determine parameter type\n if (templateId?.startsWith(\"bpt_\")) {\n devboxParams.blueprint_id = templateId;\n } else if (templateId?.startsWith(\"snp_\")) {\n devboxParams.snapshot_id = templateId;\n } else {\n // empty\n }\n }\n\n const dbx = await client.devboxes.createAndAwaitRunning(devboxParams);\n\n // Create a RunloopSandbox object that contains both devbox and client\n const runloopSandbox = {\n ...dbx, // Spread all DevboxView properties\n client: client // Add client for method access\n };\n\n return {\n sandbox: runloopSandbox, \n sandboxId: dbx.id,\n };\n } catch (error) {\n throw new Error(\n `Failed to create Runloop devbox: ${\n error instanceof Error ? error.message : String(error)\n }`\n );\n }\n },\n\n getById: async (config: RunloopConfig, sandboxId: string) => {\n const apiKey = config.apiKey || process.env.RUNLOOP_API_KEY!;\n\n try {\n const client = new Runloop({\n bearerToken: apiKey,\n });\n\n const devbox = await client.devboxes.retrieve(sandboxId);\n\n return {\n sandbox: devbox,\n sandboxId,\n };\n } catch (error) {\n // Devbox doesn't exist or can't be accessed\n return null;\n }\n },\n\n list: async (config: RunloopConfig) => {\n const apiKey = config.apiKey || process.env.RUNLOOP_API_KEY!;\n\n try {\n const client = new Runloop({\n bearerToken: apiKey,\n });\n\n const response = await client.devboxes.list();\n const devboxes = response.devboxes || [];\n\n return devboxes.map((devbox) => ({\n sandbox: devbox,\n sandboxId: devbox.id,\n }));\n } catch (error) {\n // Return empty array if listing fails\n return [];\n }\n },\n\n destroy: async (config: RunloopConfig, sandboxId: string) => {\n const apiKey = config.apiKey || process.env.RUNLOOP_API_KEY!;\n\n try {\n const client = new Runloop({\n bearerToken: apiKey,\n });\n\n await client.devboxes.shutdown(sandboxId);\n } catch (error) {\n // Devbox might already be destroyed or doesn't exist\n // This is acceptable for destroy operations\n }\n },\n\n // Instance operations (map to individual Sandbox methods)\n runCode: async (sandbox: any, code: string, runtime?: Runtime): Promise<ExecutionResult> => {\n const startTime = Date.now();\n const devbox = sandbox;\n const client = sandbox.client;\n\n try {\n // Auto-detect runtime if not specified\n const effectiveRuntime = runtime || (\n // Strong Python indicators\n code.includes('print(') ||\n code.includes('import ') ||\n code.includes('def ') ||\n code.includes('sys.') ||\n code.includes('json.') ||\n code.includes('__') ||\n code.includes('f\"') ||\n code.includes(\"f'\") ||\n code.includes('raise ')\n ? 'python'\n // Default to Node.js for all other cases (including ambiguous)\n : 'node'\n );\n\n // Use base64 encoding for both runtimes for reliability and consistency\n const encoded = Buffer.from(code).toString('base64');\n\n let command;\n if (effectiveRuntime === 'python') {\n command = `echo \"${encoded}\" | base64 -d | python3`;\n } else {\n command = `echo \"${encoded}\" | base64 -d | node`;\n }\n\n // Execute code using Runloop's executeAsync\n const execution = await client.devboxes.executeAsync(devbox.id, {\n command: command,\n });\n\n const executionResult = await client.devboxes.executions.awaitCompleted(\n devbox.id,\n execution.execution_id\n );\n\n // Check for syntax errors and throw them (similar to Vercel behavior)\n if (executionResult.exit_status !== 0 && executionResult.stderr) {\n // Check for common syntax error patterns\n if (executionResult.stderr.includes('SyntaxError') ||\n executionResult.stderr.includes('invalid syntax') ||\n executionResult.stderr.includes('Unexpected token') ||\n executionResult.stderr.includes('Unexpected identifier')) {\n throw new Error(`Syntax error: ${executionResult.stderr.trim()}`);\n }\n }\n\n return {\n stdout: executionResult.stdout || \"\",\n stderr: executionResult.stderr || \"\",\n exitCode: executionResult.exit_status || 0,\n executionTime: Date.now() - startTime,\n sandboxId: devbox.id || \"runloop-unknown\",\n provider: \"runloop\",\n };\n } catch (error) {\n // Handle Runloop execution errors\n if (error instanceof Error && error.message === 'exit status 1') {\n const actualStderr = (error as any)?.result?.stderr || '';\n const isSyntaxError = actualStderr.includes('SyntaxError');\n\n if (isSyntaxError) {\n // For syntax errors, throw\n const syntaxErrorLine = actualStderr.split('\\n').find((line: string) => line.includes('SyntaxError')) || 'SyntaxError: Invalid syntax in code';\n throw new Error(`Syntax error: ${syntaxErrorLine}`);\n } else {\n // For runtime errors, return a result instead of throwing\n return {\n stdout: '',\n stderr: actualStderr || 'Error: Runtime error occurred during execution',\n exitCode: 1,\n executionTime: Date.now() - startTime,\n sandboxId: devbox.id || 'runloop-unknown',\n provider: 'runloop'\n };\n }\n }\n\n // Re-throw syntax errors\n if (error instanceof Error && error.message.includes('Syntax error')) {\n throw error;\n }\n throw new Error(\n `Runloop execution failed: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n runCommand: async (\n sandbox: any,\n command: string,\n args: string[] = []\n ): Promise<ExecutionResult> => {\n const startTime = Date.now();\n const devbox = sandbox;\n const client = sandbox.client;\n\n try {\n // Execute code using Runloop's executeAsync\n // Runloop supports all runtimes\n\n const execution = await client.devboxes.executeAsync(devbox.id, {\n command: `${command} ${args.join(\" \")}`,\n });\n\n const executionResult =\n await client.devboxes.executions.awaitCompleted(\n devbox.id,\n execution.execution_id\n );\n\n return {\n stdout: executionResult.stdout || \"\",\n stderr: executionResult.stderr || \"\",\n exitCode: executionResult.exit_status || 0,\n executionTime: Date.now() - startTime,\n sandboxId: devbox.id || \"runloop-unknown\",\n provider: \"runloop\",\n };\n } catch (error) {\n // Re-throw syntax errors\n if (\n error instanceof Error &&\n error.message.includes(\"Syntax error\")\n ) {\n throw error;\n }\n throw new Error(\n `Runloop execution failed: ${\n error instanceof Error ? error.message : String(error)\n }`\n );\n }\n },\n\n getInfo: async (sandbox): Promise<SandboxInfo> => {\n const devbox = sandbox;\n\n return {\n id: devbox.id || \"runloop-unknown\",\n provider: \"runloop\",\n runtime: \"node\" as Runtime, // Runloop supports multiple runtimes, defaulting to node\n status: devbox.status as SandboxStatus,\n createdAt: new Date(devbox.create_time_ms || Date.now()),\n timeout: devbox.launch_parameters.keep_alive_time_seconds || 300000,\n metadata: {\n runloopDevboxId: devbox.id,\n templateId: devbox.blueprint_id || devbox.snapshot_id,\n ...devbox.metadata,\n },\n };\n },\n\n getUrl: async (\n sandbox: any,\n options: { port: number }\n ): Promise<string> => {\n const devbox = sandbox;\n const client = sandbox.client;\n\n try {\n const tunnel = await client.devboxes.createTunnel(devbox.id, {\n port: options.port,\n });\n\n return tunnel.url;\n } catch (error) {\n throw new Error(\n `Failed to get Runloop URL for port ${options.port}: ${\n error instanceof Error ? error.message : String(error)\n }`\n );\n }\n },\n\n // Optional filesystem methods - using Runloop's file operations\n filesystem: {\n readFile: async (sandbox: any, path: string, runCommand: any): Promise<string> => {\n try {\n const result = await runCommand(sandbox, 'cat', [path]);\n if (result.exitCode !== 0) {\n throw new Error(`File not found or unreadable: ${result.stderr}`);\n }\n return result.stdout;\n } catch (error) {\n throw new Error(\n `Failed to read file ${path}: ${\n error instanceof Error ? error.message : String(error)\n }`\n );\n }\n },\n\n writeFile: async (\n sandbox: any,\n path: string,\n content: string,\n runCommand: any\n ): Promise<void> => {\n try {\n // Use command-based approach for file writing since API writeFileContents may have issues\n const encoded = Buffer.from(content).toString('base64');\n const result = await runCommand(sandbox, 'sh', ['-c', `echo \"${encoded}\" | base64 -d > \"${path}\"`]);\n \n if (result.exitCode !== 0) {\n throw new Error(`Command failed: ${result.stderr}`);\n }\n } catch (error) {\n throw new Error(\n `Failed to write file ${path}: ${\n error instanceof Error ? error.message : String(error)\n }`\n );\n }\n },\n\n mkdir: async (\n sandbox: any,\n path: string,\n runCommand: any\n ): Promise<void> => {\n const result = await runCommand(sandbox, \"mkdir\", [\"-p\", path]);\n if (result.exitCode !== 0) {\n throw new Error(\n `Failed to create directory ${path}: ${result.stderr}`\n );\n }\n },\n\n readdir: async (\n sandbox: any,\n path: string,\n runCommand: any\n ): Promise<FileEntry[]> => {\n const result = await runCommand(sandbox, \"ls\", [\"-la\", path]);\n\n if (result.exitCode !== 0) {\n throw new Error(\n `Failed to list directory ${path}: ${result.stderr}`\n );\n }\n\n const lines = (result.stdout || \"\")\n .split(\"\\n\")\n .filter((line: string) => line.trim() && !line.startsWith(\"total\"));\n\n return lines.map((line: string) => {\n const parts = line.trim().split(/\\s+/);\n const name = parts[parts.length - 1];\n const isDirectory = line.startsWith(\"d\");\n\n return {\n name,\n path: `${path}/${name}`,\n isDirectory,\n size: parseInt(parts[4]) || 0,\n lastModified: new Date(),\n };\n });\n },\n\n exists: async (\n sandbox: any,\n path: string,\n runCommand: any\n ): Promise<boolean> => {\n const result = await runCommand(sandbox, \"test\", [\"-e\", path]);\n return result.exitCode === 0;\n },\n\n remove: async (\n sandbox: any,\n path: string,\n runCommand: any\n ): Promise<void> => {\n const result = await runCommand(sandbox, \"rm\", [\"-rf\", path]);\n if (result.exitCode !== 0) {\n throw new Error(`Failed to remove ${path}: ${result.stderr}`);\n }\n },\n },\n \n // Provider-specific typed getInstance method\n getInstance: (sandbox): Runloop.DevboxView => {\n return sandbox;\n },\n },\n\n // Template management methods using the new factory pattern\n template: {\n create: async (\n config: RunloopConfig,\n options: CreateBlueprintTemplateOptions | Runloop.BlueprintCreateParams\n ) => {\n const apiKey = config.apiKey || process.env.RUNLOOP_API_KEY!;\n\n if (!apiKey) {\n throw new Error(\n \"Missing Runloop API key for blueprint template creation\"\n );\n }\n\n try {\n const client = new Runloop({\n bearerToken: apiKey,\n });\n\n const blueprint = await client.blueprints.create(options);\n return blueprint;\n } catch (error) {\n throw new Error(\n `Failed to create blueprint template: ${\n error instanceof Error ? error.message : String(error)\n }`\n );\n }\n },\n\n list: async (config: RunloopConfig, options?: { limit?: number }) => {\n const apiKey = config.apiKey || process.env.RUNLOOP_API_KEY!;\n\n if (!apiKey) {\n throw new Error(\n \"Missing Runloop API key for listing blueprint templates\"\n );\n }\n\n try {\n const client = new Runloop({\n bearerToken: apiKey,\n });\n\n const listParams: any = {};\n if (options?.limit) {\n listParams.limit = options.limit;\n }\n\n const response = await client.blueprints.list(listParams);\n return response.blueprints || [];\n } catch (error) {\n throw new Error(\n `Failed to list blueprint templates: ${\n error instanceof Error ? error.message : String(error)\n }`\n );\n }\n },\n\n delete: async (config: RunloopConfig, blueprintId: string) => {\n const apiKey = config.apiKey || process.env.RUNLOOP_API_KEY!;\n\n if (!apiKey) {\n throw new Error(\n \"Missing Runloop API key for blueprint template deletion\"\n );\n }\n\n try {\n const client = new Runloop({\n bearerToken: apiKey,\n });\n\n await client.blueprints.delete(blueprintId);\n } catch (error) {\n throw new Error(\n `Failed to delete blueprint template ${blueprintId}: ${\n error instanceof Error ? error.message : String(error)\n }`\n );\n }\n },\n },\n\n // Snapshot management methods using the new factory pattern\n snapshot: {\n create: async (\n config: RunloopConfig,\n sandboxId: string,\n options?: CreateSnapshotOptions\n ) => {\n const apiKey = config.apiKey || process.env.RUNLOOP_API_KEY!;\n\n if (!apiKey) {\n throw new Error(\"Missing Runloop API key for snapshot creation\");\n }\n\n try {\n const client = new Runloop({\n bearerToken: apiKey,\n });\n\n const snapshotParams: any = {};\n if (options?.name) {\n snapshotParams.name = options.name;\n }\n if (options?.metadata) {\n snapshotParams.metadata = options.metadata;\n }\n\n const snapshot = await client.devboxes.snapshotDisk(\n sandboxId,\n snapshotParams\n );\n return snapshot;\n } catch (error) {\n throw new Error(\n `Failed to create snapshot for sandbox ${sandboxId}: ${\n error instanceof Error ? error.message : String(error)\n }`\n );\n }\n },\n\n list: async (\n config: RunloopConfig,\n options?: ListSnapshotsOptions\n ) => {\n const apiKey = config.apiKey || process.env.RUNLOOP_API_KEY!;\n\n if (!apiKey) {\n throw new Error(\"Missing Runloop API key for listing snapshots\");\n }\n\n try {\n const client = new Runloop({\n bearerToken: apiKey,\n });\n\n const listParams: any = {};\n if (options?.limit) {\n listParams.limit = options.limit;\n }\n\n const response = await client.devboxes.listDiskSnapshots(listParams);\n return response.snapshots || [];\n } catch (error) {\n throw new Error(\n `Failed to list snapshots: ${\n error instanceof Error ? error.message : String(error)\n }`\n );\n }\n },\n\n delete: async (config: RunloopConfig, snapshotId: string) => {\n const apiKey = config.apiKey || process.env.RUNLOOP_API_KEY!;\n\n if (!apiKey) {\n throw new Error(\"Missing Runloop API key for snapshot deletion\");\n }\n\n try {\n const client = new Runloop({\n bearerToken: apiKey,\n });\n\n await client.devboxes.deleteDiskSnapshot(snapshotId);\n } catch (error) {\n throw new Error(\n `Failed to delete snapshot ${snapshotId}: ${\n error instanceof Error ? error.message : String(error)\n }`\n );\n }\n },\n },\n },\n});"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAOA,wBAAwB;AACxB,wBAA+B;AA4ExB,IAAM,cAAU,kCAKrB;AAAA,EACA,MAAM;AAAA,EACN,SAAS;AAAA,IACP,SAAS;AAAA;AAAA,MAEP,QAAQ,OAAO,QAAuB,YAAmC;AAEvE,cAAM,SACJ,OAAO,UACN,OAAO,YAAY,eAAe,QAAQ,KAAK,mBAChD;AAEF,YAAI,CAAC,QAAQ;AACX,gBAAM,IAAI;AAAA,YACR;AAAA,UACF;AAAA,QACF;AAEA,cAAM,UAAU,OAAO;AAEvB,YAAI;AACF,gBAAM,SAAS,IAAI,0BAAQ;AAAA,YACzB,aAAa;AAAA,UACf,CAAC;AAED,cAAI,eAA2C;AAAA,YAC7C,mBAAmB;AAAA,cACjB,yBAAyB,WAAW,SAAS,WAAW;AAAA,YAC1D;AAAA,YACA,MAAM,SAAS;AAAA,YACf,UAAU,SAAS;AAAA,YACnB,uBAAuB,SAAS;AAAA,UAClC;AAGA,cAAI,SAAS,YAAY;AACvB,kBAAM,aAAa,SAAS;AAE5B,gBAAI,YAAY,WAAW,MAAM,GAAG;AAClC,2BAAa,eAAe;AAAA,YAC9B,WAAW,YAAY,WAAW,MAAM,GAAG;AACzC,2BAAa,cAAc;AAAA,YAC7B,OAAO;AAAA,YAEP;AAAA,UACF;AAEA,gBAAM,MAAM,MAAM,OAAO,SAAS,sBAAsB,YAAY;AAGpE,gBAAM,iBAAiB;AAAA,YACrB,GAAG;AAAA;AAAA,YACH;AAAA;AAAA,UACF;AAEA,iBAAO;AAAA,YACL,SAAS;AAAA,YACT,WAAW,IAAI;AAAA,UACjB;AAAA,QACF,SAAS,OAAO;AACd,gBAAM,IAAI;AAAA,YACR,oCACE,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CACvD;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,MAEA,SAAS,OAAO,QAAuB,cAAsB;AAC3D,cAAM,SAAS,OAAO,UAAU,QAAQ,IAAI;AAE5C,YAAI;AACF,gBAAM,SAAS,IAAI,0BAAQ;AAAA,YACzB,aAAa;AAAA,UACf,CAAC;AAED,gBAAM,SAAS,MAAM,OAAO,SAAS,SAAS,SAAS;AAEvD,iBAAO;AAAA,YACL,SAAS;AAAA,YACT;AAAA,UACF;AAAA,QACF,SAAS,OAAO;AAEd,iBAAO;AAAA,QACT;AAAA,MACF;AAAA,MAEA,MAAM,OAAO,WAA0B;AACrC,cAAM,SAAS,OAAO,UAAU,QAAQ,IAAI;AAE5C,YAAI;AACF,gBAAM,SAAS,IAAI,0BAAQ;AAAA,YACzB,aAAa;AAAA,UACf,CAAC;AAED,gBAAM,WAAW,MAAM,OAAO,SAAS,KAAK;AAC5C,gBAAM,WAAW,SAAS,YAAY,CAAC;AAEvC,iBAAO,SAAS,IAAI,CAAC,YAAY;AAAA,YAC/B,SAAS;AAAA,YACT,WAAW,OAAO;AAAA,UACpB,EAAE;AAAA,QACJ,SAAS,OAAO;AAEd,iBAAO,CAAC;AAAA,QACV;AAAA,MACF;AAAA,MAEA,SAAS,OAAO,QAAuB,cAAsB;AAC3D,cAAM,SAAS,OAAO,UAAU,QAAQ,IAAI;AAE5C,YAAI;AACF,gBAAM,SAAS,IAAI,0BAAQ;AAAA,YACzB,aAAa;AAAA,UACf,CAAC;AAED,gBAAM,OAAO,SAAS,SAAS,SAAS;AAAA,QAC1C,SAAS,OAAO;AAAA,QAGhB;AAAA,MACF;AAAA;AAAA,MAGA,SAAS,OAAO,SAAc,MAAc,YAAgD;AAC1F,cAAM,YAAY,KAAK,IAAI;AAC3B,cAAM,SAAS;AACf,cAAM,SAAS,QAAQ;AAEvB,YAAI;AAEF,gBAAM,mBAAmB;AAAA,WAEvB,KAAK,SAAS,QAAQ,KACpB,KAAK,SAAS,SAAS,KACvB,KAAK,SAAS,MAAM,KACpB,KAAK,SAAS,MAAM,KACpB,KAAK,SAAS,OAAO,KACrB,KAAK,SAAS,IAAI,KAClB,KAAK,SAAS,IAAI,KAClB,KAAK,SAAS,IAAI,KAClB,KAAK,SAAS,QAAQ,IACpB,WAEA;AAIN,gBAAM,UAAU,OAAO,KAAK,IAAI,EAAE,SAAS,QAAQ;AAEnD,cAAI;AACJ,cAAI,qBAAqB,UAAU;AACjC,sBAAU,SAAS,OAAO;AAAA,UAC5B,OAAO;AACL,sBAAU,SAAS,OAAO;AAAA,UAC5B;AAGA,gBAAM,YAAY,MAAM,OAAO,SAAS,aAAa,OAAO,IAAI;AAAA,YAC9D;AAAA,UACF,CAAC;AAED,gBAAM,kBAAkB,MAAM,OAAO,SAAS,WAAW;AAAA,YACvD,OAAO;AAAA,YACP,UAAU;AAAA,UACZ;AAGA,cAAI,gBAAgB,gBAAgB,KAAK,gBAAgB,QAAQ;AAE/D,gBAAI,gBAAgB,OAAO,SAAS,aAAa,KAC/C,gBAAgB,OAAO,SAAS,gBAAgB,KAChD,gBAAgB,OAAO,SAAS,kBAAkB,KAClD,gBAAgB,OAAO,SAAS,uBAAuB,GAAG;AAC1D,oBAAM,IAAI,MAAM,iBAAiB,gBAAgB,OAAO,KAAK,CAAC,EAAE;AAAA,YAClE;AAAA,UACF;AAEA,iBAAO;AAAA,YACL,QAAQ,gBAAgB,UAAU;AAAA,YAClC,QAAQ,gBAAgB,UAAU;AAAA,YAClC,UAAU,gBAAgB,eAAe;AAAA,YACzC,eAAe,KAAK,IAAI,IAAI;AAAA,YAC5B,WAAW,OAAO,MAAM;AAAA,YACxB,UAAU;AAAA,UACZ;AAAA,QACF,SAAS,OAAO;AAEd,cAAI,iBAAiB,SAAS,MAAM,YAAY,iBAAiB;AAC/D,kBAAM,eAAgB,OAAe,QAAQ,UAAU;AACvD,kBAAM,gBAAgB,aAAa,SAAS,aAAa;AAEzD,gBAAI,eAAe;AAEjB,oBAAM,kBAAkB,aAAa,MAAM,IAAI,EAAE,KAAK,CAAC,SAAiB,KAAK,SAAS,aAAa,CAAC,KAAK;AACzG,oBAAM,IAAI,MAAM,iBAAiB,eAAe,EAAE;AAAA,YACpD,OAAO;AAEL,qBAAO;AAAA,gBACL,QAAQ;AAAA,gBACR,QAAQ,gBAAgB;AAAA,gBACxB,UAAU;AAAA,gBACV,eAAe,KAAK,IAAI,IAAI;AAAA,gBAC5B,WAAW,OAAO,MAAM;AAAA,gBACxB,UAAU;AAAA,cACZ;AAAA,YACF;AAAA,UACF;AAGA,cAAI,iBAAiB,SAAS,MAAM,QAAQ,SAAS,cAAc,GAAG;AACpE,kBAAM;AAAA,UACR;AACA,gBAAM,IAAI;AAAA,YACR,6BAA6B,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,UACrF;AAAA,QACF;AAAA,MACF;AAAA,MAEA,YAAY,OACV,SACA,SACA,OAAiB,CAAC,MACW;AAC7B,cAAM,YAAY,KAAK,IAAI;AAC3B,cAAM,SAAS;AACf,cAAM,SAAS,QAAQ;AAEvB,YAAI;AAIF,gBAAM,YAAY,MAAM,OAAO,SAAS,aAAa,OAAO,IAAI;AAAA,YAC9D,SAAS,GAAG,OAAO,IAAI,KAAK,KAAK,GAAG,CAAC;AAAA,UACvC,CAAC;AAED,gBAAM,kBACJ,MAAM,OAAO,SAAS,WAAW;AAAA,YAC/B,OAAO;AAAA,YACP,UAAU;AAAA,UACZ;AAEF,iBAAO;AAAA,YACL,QAAQ,gBAAgB,UAAU;AAAA,YAClC,QAAQ,gBAAgB,UAAU;AAAA,YAClC,UAAU,gBAAgB,eAAe;AAAA,YACzC,eAAe,KAAK,IAAI,IAAI;AAAA,YAC5B,WAAW,OAAO,MAAM;AAAA,YACxB,UAAU;AAAA,UACZ;AAAA,QACF,SAAS,OAAO;AAEd,cACE,iBAAiB,SACjB,MAAM,QAAQ,SAAS,cAAc,GACrC;AACA,kBAAM;AAAA,UACR;AACA,gBAAM,IAAI;AAAA,YACR,6BACE,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CACvD;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,MAEA,SAAS,OAAO,YAAkC;AAChD,cAAM,SAAS;AAEf,eAAO;AAAA,UACL,IAAI,OAAO,MAAM;AAAA,UACjB,UAAU;AAAA,UACV,SAAS;AAAA;AAAA,UACT,QAAQ,OAAO;AAAA,UACf,WAAW,IAAI,KAAK,OAAO,kBAAkB,KAAK,IAAI,CAAC;AAAA,UACvD,SAAS,OAAO,kBAAkB,2BAA2B;AAAA,UAC7D,UAAU;AAAA,YACR,iBAAiB,OAAO;AAAA,YACxB,YAAY,OAAO,gBAAgB,OAAO;AAAA,YAC1C,GAAG,OAAO;AAAA,UACZ;AAAA,QACF;AAAA,MACF;AAAA,MAEA,QAAQ,OACN,SACA,YACoB;AACpB,cAAM,SAAS;AACf,cAAM,SAAS,QAAQ;AAEvB,YAAI;AACF,gBAAM,SAAS,MAAM,OAAO,SAAS,aAAa,OAAO,IAAI;AAAA,YAC3D,MAAM,QAAQ;AAAA,UAChB,CAAC;AAED,iBAAO,OAAO;AAAA,QAChB,SAAS,OAAO;AACd,gBAAM,IAAI;AAAA,YACR,sCAAsC,QAAQ,IAAI,KAChD,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CACvD;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA;AAAA,MAGA,YAAY;AAAA,QACV,UAAU,OAAO,SAAc,MAAc,eAAqC;AAChF,cAAI;AACF,kBAAM,SAAS,MAAM,WAAW,SAAS,OAAO,CAAC,IAAI,CAAC;AACtD,gBAAI,OAAO,aAAa,GAAG;AACzB,oBAAM,IAAI,MAAM,iCAAiC,OAAO,MAAM,EAAE;AAAA,YAClE;AACA,mBAAO,OAAO;AAAA,UAChB,SAAS,OAAO;AACd,kBAAM,IAAI;AAAA,cACR,uBAAuB,IAAI,KACzB,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CACvD;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,QAEA,WAAW,OACT,SACA,MACA,SACA,eACkB;AAClB,cAAI;AAEF,kBAAM,UAAU,OAAO,KAAK,OAAO,EAAE,SAAS,QAAQ;AACtD,kBAAM,SAAS,MAAM,WAAW,SAAS,MAAM,CAAC,MAAM,SAAS,OAAO,oBAAoB,IAAI,GAAG,CAAC;AAElG,gBAAI,OAAO,aAAa,GAAG;AACzB,oBAAM,IAAI,MAAM,mBAAmB,OAAO,MAAM,EAAE;AAAA,YACpD;AAAA,UACF,SAAS,OAAO;AACd,kBAAM,IAAI;AAAA,cACR,wBAAwB,IAAI,KAC1B,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CACvD;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,QAEA,OAAO,OACL,SACA,MACA,eACkB;AAClB,gBAAM,SAAS,MAAM,WAAW,SAAS,SAAS,CAAC,MAAM,IAAI,CAAC;AAC9D,cAAI,OAAO,aAAa,GAAG;AACzB,kBAAM,IAAI;AAAA,cACR,8BAA8B,IAAI,KAAK,OAAO,MAAM;AAAA,YACtD;AAAA,UACF;AAAA,QACF;AAAA,QAEA,SAAS,OACP,SACA,MACA,eACyB;AACzB,gBAAM,SAAS,MAAM,WAAW,SAAS,MAAM,CAAC,OAAO,IAAI,CAAC;AAE5D,cAAI,OAAO,aAAa,GAAG;AACzB,kBAAM,IAAI;AAAA,cACR,4BAA4B,IAAI,KAAK,OAAO,MAAM;AAAA,YACpD;AAAA,UACF;AAEA,gBAAM,SAAS,OAAO,UAAU,IAC7B,MAAM,IAAI,EACV,OAAO,CAAC,SAAiB,KAAK,KAAK,KAAK,CAAC,KAAK,WAAW,OAAO,CAAC;AAEpE,iBAAO,MAAM,IAAI,CAAC,SAAiB;AACjC,kBAAM,QAAQ,KAAK,KAAK,EAAE,MAAM,KAAK;AACrC,kBAAM,OAAO,MAAM,MAAM,SAAS,CAAC;AACnC,kBAAM,cAAc,KAAK,WAAW,GAAG;AAEvC,mBAAO;AAAA,cACL;AAAA,cACA,MAAM,GAAG,IAAI,IAAI,IAAI;AAAA,cACrB;AAAA,cACA,MAAM,SAAS,MAAM,CAAC,CAAC,KAAK;AAAA,cAC5B,cAAc,oBAAI,KAAK;AAAA,YACzB;AAAA,UACF,CAAC;AAAA,QACH;AAAA,QAEA,QAAQ,OACN,SACA,MACA,eACqB;AACrB,gBAAM,SAAS,MAAM,WAAW,SAAS,QAAQ,CAAC,MAAM,IAAI,CAAC;AAC7D,iBAAO,OAAO,aAAa;AAAA,QAC7B;AAAA,QAEA,QAAQ,OACN,SACA,MACA,eACkB;AAClB,gBAAM,SAAS,MAAM,WAAW,SAAS,MAAM,CAAC,OAAO,IAAI,CAAC;AAC5D,cAAI,OAAO,aAAa,GAAG;AACzB,kBAAM,IAAI,MAAM,oBAAoB,IAAI,KAAK,OAAO,MAAM,EAAE;AAAA,UAC9D;AAAA,QACF;AAAA,MACF;AAAA;AAAA,MAGA,aAAa,CAAC,YAAgC;AAC5C,eAAO;AAAA,MACT;AAAA,IACF;AAAA;AAAA,IAGA,UAAU;AAAA,MACR,QAAQ,OACN,QACA,YACG;AACH,cAAM,SAAS,OAAO,UAAU,QAAQ,IAAI;AAE5C,YAAI,CAAC,QAAQ;AACX,gBAAM,IAAI;AAAA,YACR;AAAA,UACF;AAAA,QACF;AAEA,YAAI;AACF,gBAAM,SAAS,IAAI,0BAAQ;AAAA,YACzB,aAAa;AAAA,UACf,CAAC;AAED,gBAAM,YAAY,MAAM,OAAO,WAAW,OAAO,OAAO;AACxD,iBAAO;AAAA,QACT,SAAS,OAAO;AACd,gBAAM,IAAI;AAAA,YACR,wCACE,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CACvD;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,MAEA,MAAM,OAAO,QAAuB,YAAiC;AACnE,cAAM,SAAS,OAAO,UAAU,QAAQ,IAAI;AAE5C,YAAI,CAAC,QAAQ;AACX,gBAAM,IAAI;AAAA,YACR;AAAA,UACF;AAAA,QACF;AAEA,YAAI;AACF,gBAAM,SAAS,IAAI,0BAAQ;AAAA,YACzB,aAAa;AAAA,UACf,CAAC;AAED,gBAAM,aAAkB,CAAC;AACzB,cAAI,SAAS,OAAO;AAClB,uBAAW,QAAQ,QAAQ;AAAA,UAC7B;AAEA,gBAAM,WAAW,MAAM,OAAO,WAAW,KAAK,UAAU;AACxD,iBAAO,SAAS,cAAc,CAAC;AAAA,QACjC,SAAS,OAAO;AACd,gBAAM,IAAI;AAAA,YACR,uCACE,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CACvD;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,MAEA,QAAQ,OAAO,QAAuB,gBAAwB;AAC5D,cAAM,SAAS,OAAO,UAAU,QAAQ,IAAI;AAE5C,YAAI,CAAC,QAAQ;AACX,gBAAM,IAAI;AAAA,YACR;AAAA,UACF;AAAA,QACF;AAEA,YAAI;AACF,gBAAM,SAAS,IAAI,0BAAQ;AAAA,YACzB,aAAa;AAAA,UACf,CAAC;AAED,gBAAM,OAAO,WAAW,OAAO,WAAW;AAAA,QAC5C,SAAS,OAAO;AACd,gBAAM,IAAI;AAAA,YACR,uCAAuC,WAAW,KAChD,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CACvD;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA;AAAA,IAGA,UAAU;AAAA,MACR,QAAQ,OACN,QACA,WACA,YACG;AACH,cAAM,SAAS,OAAO,UAAU,QAAQ,IAAI;AAE5C,YAAI,CAAC,QAAQ;AACX,gBAAM,IAAI,MAAM,+CAA+C;AAAA,QACjE;AAEA,YAAI;AACF,gBAAM,SAAS,IAAI,0BAAQ;AAAA,YACzB,aAAa;AAAA,UACf,CAAC;AAED,gBAAM,iBAAsB,CAAC;AAC7B,cAAI,SAAS,MAAM;AACjB,2BAAe,OAAO,QAAQ;AAAA,UAChC;AACA,cAAI,SAAS,UAAU;AACrB,2BAAe,WAAW,QAAQ;AAAA,UACpC;AAEA,gBAAM,WAAW,MAAM,OAAO,SAAS;AAAA,YACrC;AAAA,YACA;AAAA,UACF;AACA,iBAAO;AAAA,QACT,SAAS,OAAO;AACd,gBAAM,IAAI;AAAA,YACR,yCAAyC,SAAS,KAChD,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CACvD;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,MAEA,MAAM,OACJ,QACA,YACG;AACH,cAAM,SAAS,OAAO,UAAU,QAAQ,IAAI;AAE5C,YAAI,CAAC,QAAQ;AACX,gBAAM,IAAI,MAAM,+CAA+C;AAAA,QACjE;AAEA,YAAI;AACF,gBAAM,SAAS,IAAI,0BAAQ;AAAA,YACzB,aAAa;AAAA,UACf,CAAC;AAED,gBAAM,aAAkB,CAAC;AACzB,cAAI,SAAS,OAAO;AAClB,uBAAW,QAAQ,QAAQ;AAAA,UAC7B;AAEA,gBAAM,WAAW,MAAM,OAAO,SAAS,kBAAkB,UAAU;AACnE,iBAAO,SAAS,aAAa,CAAC;AAAA,QAChC,SAAS,OAAO;AACd,gBAAM,IAAI;AAAA,YACR,6BACE,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CACvD;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,MAEA,QAAQ,OAAO,QAAuB,eAAuB;AAC3D,cAAM,SAAS,OAAO,UAAU,QAAQ,IAAI;AAE5C,YAAI,CAAC,QAAQ;AACX,gBAAM,IAAI,MAAM,+CAA+C;AAAA,QACjE;AAEA,YAAI;AACF,gBAAM,SAAS,IAAI,0BAAQ;AAAA,YACzB,aAAa;AAAA,UACf,CAAC;AAED,gBAAM,OAAO,SAAS,mBAAmB,UAAU;AAAA,QACrD,SAAS,OAAO;AACd,gBAAM,IAAI;AAAA,YACR,6BAA6B,UAAU,KACrC,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CACvD;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF,CAAC;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * Runloop Provider - Factory-based Implementation\n *\n * Full-featured provider with filesystem support using the factory pattern.\n * Reduces ~400 lines of boilerplate to ~100 lines of core logic.\n */\n\nimport { Runloop } from \"@runloop/api-client\";\nimport { createProvider } from \"computesdk\";\nimport type {\n CodeResult,\n CommandResult,\n SandboxInfo,\n CreateSandboxOptions,\n FileEntry,\n CreateSnapshotOptions,\n ListSnapshotsOptions,\n Runtime,\n SandboxStatus,\n Sandbox,\n} from \"computesdk\";\n\n// Define Runloop-specific types\ntype RunloopSnapshot = Runloop.DevboxSnapshotView;\ntype RunloopTemplate = Runloop.BlueprintView;\n\n/**\n * Runloop-specific configuration options\n */\nexport interface RunloopConfig {\n /** Runloop API key - if not provided, will fallback to RUNLOOP_API_KEY environment variable */\n apiKey?: string;\n /** Execution timeout in milliseconds */\n timeout?: number;\n}\n\n/**\n * Runloop-specific blueprint creation options\n */\nexport interface CreateBlueprintTemplateOptions {\n /** Name of the blueprint template */\n name: string;\n /** Custom Dockerfile content */\n dockerfile?: string;\n /** System setup commands to run during blueprint creation */\n systemSetupCommands?: string[];\n /** Launch commands to run when starting a devbox from this blueprint */\n launchCommands?: string[];\n /** File mounts as key-value pairs (path -> content) */\n fileMounts?: Record<string, string>;\n /** Code repository mounts */\n codeMounts?: Array<{\n repoName: string;\n repoOwner: string;\n token?: string;\n installCommand?: string;\n }>;\n /** Resource size for devboxes created from this blueprint */\n resourceSize?:\n | \"X_SMALL\"\n | \"SMALL\"\n | \"MEDIUM\"\n | \"LARGE\"\n | \"X_LARGE\"\n | \"XX_LARGE\"\n | \"CUSTOM_SIZE\";\n /** CPU architecture */\n architecture?: \"x86_64\" | \"arm64\";\n /** Custom CPU cores (requires CUSTOM_SIZE) */\n customCpuCores?: number;\n /** Custom memory in GB (requires CUSTOM_SIZE) */\n customMemoryGb?: number;\n /** Custom disk size (requires CUSTOM_SIZE) */\n customDiskSize?: number;\n /** Available ports for the devbox */\n availablePorts?: number[];\n /** Action to take when devbox is idle */\n afterIdle?: { action: string; timeSeconds: number };\n /** Keep alive time in seconds */\n keepAliveTimeSeconds?: number;\n}\n\n/**\n * Create a Runloop provider instance using the factory pattern\n */\nexport const runloop = createProvider<\n Runloop.DevboxView, // TSandbox\n RunloopConfig, // TConfig\n RunloopTemplate, // TTemplate \n RunloopSnapshot // TSnapshot\n>({\n name: \"runloop\",\n methods: {\n sandbox: {\n // Collection operations (map to compute.sandbox.*)\n create: async (config: RunloopConfig, options?: CreateSandboxOptions) => {\n // Validate API key\n const apiKey =\n config.apiKey ||\n (typeof process !== \"undefined\" && process.env?.RUNLOOP_API_KEY) ||\n \"\";\n\n if (!apiKey) {\n throw new Error(\n `Missing Runloop API key. Provide 'apiKey' in config or set RUNLOOP_API_KEY environment variable. Get your API key from https://runloop.ai/`\n );\n }\n\n const timeout = config.timeout;\n\n try {\n const client = new Runloop({\n bearerToken: apiKey,\n });\n\n let devboxParams: Runloop.DevboxCreateParams = {\n launch_parameters: {\n keep_alive_time_seconds: timeout || options?.timeout || 300000,\n },\n name: options?.sandboxId,\n metadata: options?.metadata,\n environment_variables: options?.envs,\n };\n\n // Use blueprint if specified\n if (options?.templateId) {\n const templateId = options?.templateId;\n // Check template prefix to determine parameter type\n if (templateId?.startsWith(\"bpt_\")) {\n devboxParams.blueprint_id = templateId;\n } else if (templateId?.startsWith(\"snp_\")) {\n devboxParams.snapshot_id = templateId;\n } else {\n // empty\n }\n }\n\n const dbx = await client.devboxes.createAndAwaitRunning(devboxParams);\n\n // Create a RunloopSandbox object that contains both devbox and client\n const runloopSandbox = {\n ...dbx, // Spread all DevboxView properties\n client: client // Add client for method access\n };\n\n return {\n sandbox: runloopSandbox, \n sandboxId: dbx.id,\n };\n } catch (error) {\n throw new Error(\n `Failed to create Runloop devbox: ${\n error instanceof Error ? error.message : String(error)\n }`\n );\n }\n },\n\n getById: async (config: RunloopConfig, sandboxId: string) => {\n const apiKey = config.apiKey || process.env.RUNLOOP_API_KEY!;\n\n try {\n const client = new Runloop({\n bearerToken: apiKey,\n });\n\n const devbox = await client.devboxes.retrieve(sandboxId);\n\n return {\n sandbox: devbox,\n sandboxId,\n };\n } catch (error) {\n // Devbox doesn't exist or can't be accessed\n return null;\n }\n },\n\n list: async (config: RunloopConfig) => {\n const apiKey = config.apiKey || process.env.RUNLOOP_API_KEY!;\n\n try {\n const client = new Runloop({\n bearerToken: apiKey,\n });\n\n const response = await client.devboxes.list();\n const devboxes = response.devboxes || [];\n\n return devboxes.map((devbox) => ({\n sandbox: devbox,\n sandboxId: devbox.id,\n }));\n } catch (error) {\n // Return empty array if listing fails\n return [];\n }\n },\n\n destroy: async (config: RunloopConfig, sandboxId: string) => {\n const apiKey = config.apiKey || process.env.RUNLOOP_API_KEY!;\n\n try {\n const client = new Runloop({\n bearerToken: apiKey,\n });\n\n await client.devboxes.shutdown(sandboxId);\n } catch (error) {\n // Devbox might already be destroyed or doesn't exist\n // This is acceptable for destroy operations\n }\n },\n\n // Instance operations (map to individual Sandbox methods)\n runCode: async (sandbox: any, code: string, runtime?: Runtime): Promise<CodeResult> => {\n const startTime = Date.now();\n const devbox = sandbox;\n const client = sandbox.client;\n\n // Auto-detect runtime if not specified\n const effectiveRuntime: Runtime = runtime || (\n // Strong Python indicators\n code.includes('print(') ||\n code.includes('import ') ||\n code.includes('def ') ||\n code.includes('sys.') ||\n code.includes('json.') ||\n code.includes('__') ||\n code.includes('f\"') ||\n code.includes(\"f'\") ||\n code.includes('raise ')\n ? 'python'\n // Default to Node.js for all other cases (including ambiguous)\n : 'node'\n ) as Runtime;\n\n try {\n\n // Use base64 encoding for both runtimes for reliability and consistency\n const encoded = Buffer.from(code).toString('base64');\n\n let command;\n if (effectiveRuntime === 'python') {\n command = `echo \"${encoded}\" | base64 -d | python3`;\n } else {\n command = `echo \"${encoded}\" | base64 -d | node`;\n }\n\n // Execute code using Runloop's executeAsync\n const execution = await client.devboxes.executeAsync(devbox.id, {\n command: command,\n });\n\n const executionResult = await client.devboxes.executions.awaitCompleted(\n devbox.id,\n execution.execution_id\n );\n\n // Check for syntax errors and throw them (similar to Vercel behavior)\n if (executionResult.exit_status !== 0 && executionResult.stderr) {\n // Check for common syntax error patterns\n if (executionResult.stderr.includes('SyntaxError') ||\n executionResult.stderr.includes('invalid syntax') ||\n executionResult.stderr.includes('Unexpected token') ||\n executionResult.stderr.includes('Unexpected identifier')) {\n throw new Error(`Syntax error: ${executionResult.stderr.trim()}`);\n }\n }\n\n return {\n output: (executionResult.stdout || \"\") + (executionResult.stderr || \"\"),\n exitCode: executionResult.exit_status || 0,\n language: effectiveRuntime,\n };\n } catch (error) {\n // Handle Runloop execution errors\n if (error instanceof Error && error.message === 'exit status 1') {\n const actualStderr = (error as any)?.result?.stderr || '';\n const isSyntaxError = actualStderr.includes('SyntaxError');\n\n if (isSyntaxError) {\n // For syntax errors, throw\n const syntaxErrorLine = actualStderr.split('\\n').find((line: string) => line.includes('SyntaxError')) || 'SyntaxError: Invalid syntax in code';\n throw new Error(`Syntax error: ${syntaxErrorLine}`);\n } else {\n // For runtime errors, return a result instead of throwing\n return {\n output: actualStderr || 'Error: Runtime error occurred during execution',\n exitCode: 1,\n language: effectiveRuntime,\n };\n }\n }\n\n // Re-throw syntax errors\n if (error instanceof Error && error.message.includes('Syntax error')) {\n throw error;\n }\n throw new Error(\n `Runloop execution failed: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n runCommand: async (\n sandbox: any,\n command: string,\n args: string[] = []\n ): Promise<CommandResult> => {\n const startTime = Date.now();\n const devbox = sandbox;\n const client = sandbox.client;\n\n try {\n // Execute code using Runloop's executeAsync\n // Runloop supports all runtimes\n\n const execution = await client.devboxes.executeAsync(devbox.id, {\n command: `${command} ${args.join(\" \")}`,\n });\n\n const executionResult =\n await client.devboxes.executions.awaitCompleted(\n devbox.id,\n execution.execution_id\n );\n\n return {\n stdout: executionResult.stdout || \"\",\n stderr: executionResult.stderr || \"\",\n exitCode: executionResult.exit_status || 0,\n durationMs: Date.now() - startTime,\n };\n } catch (error) {\n // Re-throw syntax errors\n if (\n error instanceof Error &&\n error.message.includes(\"Syntax error\")\n ) {\n throw error;\n }\n throw new Error(\n `Runloop execution failed: ${\n error instanceof Error ? error.message : String(error)\n }`\n );\n }\n },\n\n getInfo: async (sandbox): Promise<SandboxInfo> => {\n const devbox = sandbox;\n\n return {\n id: devbox.id || \"runloop-unknown\",\n provider: \"runloop\",\n runtime: \"node\" as Runtime, // Runloop supports multiple runtimes, defaulting to node\n status: devbox.status as SandboxStatus,\n createdAt: new Date(devbox.create_time_ms || Date.now()),\n timeout: devbox.launch_parameters.keep_alive_time_seconds || 300000,\n metadata: {\n runloopDevboxId: devbox.id,\n templateId: devbox.blueprint_id || devbox.snapshot_id,\n ...devbox.metadata,\n },\n };\n },\n\n getUrl: async (\n sandbox: any,\n options: { port: number }\n ): Promise<string> => {\n const devbox = sandbox;\n const client = sandbox.client;\n\n try {\n const tunnel = await client.devboxes.createTunnel(devbox.id, {\n port: options.port,\n });\n\n return tunnel.url;\n } catch (error) {\n throw new Error(\n `Failed to get Runloop URL for port ${options.port}: ${\n error instanceof Error ? error.message : String(error)\n }`\n );\n }\n },\n\n // Optional filesystem methods - using Runloop's file operations\n filesystem: {\n readFile: async (sandbox: any, path: string, runCommand: any): Promise<string> => {\n try {\n const result = await runCommand(sandbox, 'cat', [path]);\n if (result.exitCode !== 0) {\n throw new Error(`File not found or unreadable: ${result.stderr}`);\n }\n return result.stdout;\n } catch (error) {\n throw new Error(\n `Failed to read file ${path}: ${\n error instanceof Error ? error.message : String(error)\n }`\n );\n }\n },\n\n writeFile: async (\n sandbox: any,\n path: string,\n content: string,\n runCommand: any\n ): Promise<void> => {\n try {\n // Use command-based approach for file writing since API writeFileContents may have issues\n const encoded = Buffer.from(content).toString('base64');\n const result = await runCommand(sandbox, 'sh', ['-c', `echo \"${encoded}\" | base64 -d > \"${path}\"`]);\n \n if (result.exitCode !== 0) {\n throw new Error(`Command failed: ${result.stderr}`);\n }\n } catch (error) {\n throw new Error(\n `Failed to write file ${path}: ${\n error instanceof Error ? error.message : String(error)\n }`\n );\n }\n },\n\n mkdir: async (\n sandbox: any,\n path: string,\n runCommand: any\n ): Promise<void> => {\n const result = await runCommand(sandbox, \"mkdir\", [\"-p\", path]);\n if (result.exitCode !== 0) {\n throw new Error(\n `Failed to create directory ${path}: ${result.stderr}`\n );\n }\n },\n\n readdir: async (\n sandbox: any,\n path: string,\n runCommand: any\n ): Promise<FileEntry[]> => {\n const result = await runCommand(sandbox, \"ls\", [\"-la\", path]);\n\n if (result.exitCode !== 0) {\n throw new Error(\n `Failed to list directory ${path}: ${result.stderr}`\n );\n }\n\n const lines = (result.stdout || \"\")\n .split(\"\\n\")\n .filter((line: string) => line.trim() && !line.startsWith(\"total\"));\n\n return lines.map((line: string) => {\n const parts = line.trim().split(/\\s+/);\n const name = parts[parts.length - 1];\n const isDirectory = line.startsWith(\"d\");\n\n return {\n name,\n path: `${path}/${name}`,\n isDirectory,\n size: parseInt(parts[4]) || 0,\n lastModified: new Date(),\n };\n });\n },\n\n exists: async (\n sandbox: any,\n path: string,\n runCommand: any\n ): Promise<boolean> => {\n const result = await runCommand(sandbox, \"test\", [\"-e\", path]);\n return result.exitCode === 0;\n },\n\n remove: async (\n sandbox: any,\n path: string,\n runCommand: any\n ): Promise<void> => {\n const result = await runCommand(sandbox, \"rm\", [\"-rf\", path]);\n if (result.exitCode !== 0) {\n throw new Error(`Failed to remove ${path}: ${result.stderr}`);\n }\n },\n },\n \n // Provider-specific typed getInstance method\n getInstance: (sandbox): Runloop.DevboxView => {\n return sandbox;\n },\n },\n\n // Template management methods using the new factory pattern\n template: {\n create: async (\n config: RunloopConfig,\n options: CreateBlueprintTemplateOptions | Runloop.BlueprintCreateParams\n ) => {\n const apiKey = config.apiKey || process.env.RUNLOOP_API_KEY!;\n\n if (!apiKey) {\n throw new Error(\n \"Missing Runloop API key for blueprint template creation\"\n );\n }\n\n try {\n const client = new Runloop({\n bearerToken: apiKey,\n });\n\n const blueprint = await client.blueprints.create(options);\n return blueprint;\n } catch (error) {\n throw new Error(\n `Failed to create blueprint template: ${\n error instanceof Error ? error.message : String(error)\n }`\n );\n }\n },\n\n list: async (config: RunloopConfig, options?: { limit?: number }) => {\n const apiKey = config.apiKey || process.env.RUNLOOP_API_KEY!;\n\n if (!apiKey) {\n throw new Error(\n \"Missing Runloop API key for listing blueprint templates\"\n );\n }\n\n try {\n const client = new Runloop({\n bearerToken: apiKey,\n });\n\n const listParams: any = {};\n if (options?.limit) {\n listParams.limit = options.limit;\n }\n\n const response = await client.blueprints.list(listParams);\n return response.blueprints || [];\n } catch (error) {\n throw new Error(\n `Failed to list blueprint templates: ${\n error instanceof Error ? error.message : String(error)\n }`\n );\n }\n },\n\n delete: async (config: RunloopConfig, blueprintId: string) => {\n const apiKey = config.apiKey || process.env.RUNLOOP_API_KEY!;\n\n if (!apiKey) {\n throw new Error(\n \"Missing Runloop API key for blueprint template deletion\"\n );\n }\n\n try {\n const client = new Runloop({\n bearerToken: apiKey,\n });\n\n await client.blueprints.delete(blueprintId);\n } catch (error) {\n throw new Error(\n `Failed to delete blueprint template ${blueprintId}: ${\n error instanceof Error ? error.message : String(error)\n }`\n );\n }\n },\n },\n\n // Snapshot management methods using the new factory pattern\n snapshot: {\n create: async (\n config: RunloopConfig,\n sandboxId: string,\n options?: CreateSnapshotOptions\n ) => {\n const apiKey = config.apiKey || process.env.RUNLOOP_API_KEY!;\n\n if (!apiKey) {\n throw new Error(\"Missing Runloop API key for snapshot creation\");\n }\n\n try {\n const client = new Runloop({\n bearerToken: apiKey,\n });\n\n const snapshotParams: any = {};\n if (options?.name) {\n snapshotParams.name = options.name;\n }\n if (options?.metadata) {\n snapshotParams.metadata = options.metadata;\n }\n\n const snapshot = await client.devboxes.snapshotDisk(\n sandboxId,\n snapshotParams\n );\n return snapshot;\n } catch (error) {\n throw new Error(\n `Failed to create snapshot for sandbox ${sandboxId}: ${\n error instanceof Error ? error.message : String(error)\n }`\n );\n }\n },\n\n list: async (\n config: RunloopConfig,\n options?: ListSnapshotsOptions\n ) => {\n const apiKey = config.apiKey || process.env.RUNLOOP_API_KEY!;\n\n if (!apiKey) {\n throw new Error(\"Missing Runloop API key for listing snapshots\");\n }\n\n try {\n const client = new Runloop({\n bearerToken: apiKey,\n });\n\n const listParams: any = {};\n if (options?.limit) {\n listParams.limit = options.limit;\n }\n\n const response = await client.devboxes.listDiskSnapshots(listParams);\n return response.snapshots || [];\n } catch (error) {\n throw new Error(\n `Failed to list snapshots: ${\n error instanceof Error ? error.message : String(error)\n }`\n );\n }\n },\n\n delete: async (config: RunloopConfig, snapshotId: string) => {\n const apiKey = config.apiKey || process.env.RUNLOOP_API_KEY!;\n\n if (!apiKey) {\n throw new Error(\"Missing Runloop API key for snapshot deletion\");\n }\n\n try {\n const client = new Runloop({\n bearerToken: apiKey,\n });\n\n await client.devboxes.deleteDiskSnapshot(snapshotId);\n } catch (error) {\n throw new Error(\n `Failed to delete snapshot ${snapshotId}: ${\n error instanceof Error ? error.message : String(error)\n }`\n );\n }\n },\n },\n },\n});"],"mappings":"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","names":[]}
|
package/dist/index.mjs
CHANGED
|
@@ -98,9 +98,9 @@ var runloop = createProvider({
|
|
|
98
98
|
const startTime = Date.now();
|
|
99
99
|
const devbox = sandbox;
|
|
100
100
|
const client = sandbox.client;
|
|
101
|
+
const effectiveRuntime = runtime || // Strong Python indicators
|
|
102
|
+
(code.includes("print(") || code.includes("import ") || code.includes("def ") || code.includes("sys.") || code.includes("json.") || code.includes("__") || code.includes('f"') || code.includes("f'") || code.includes("raise ") ? "python" : "node");
|
|
101
103
|
try {
|
|
102
|
-
const effectiveRuntime = runtime || // Strong Python indicators
|
|
103
|
-
(code.includes("print(") || code.includes("import ") || code.includes("def ") || code.includes("sys.") || code.includes("json.") || code.includes("__") || code.includes('f"') || code.includes("f'") || code.includes("raise ") ? "python" : "node");
|
|
104
104
|
const encoded = Buffer.from(code).toString("base64");
|
|
105
105
|
let command;
|
|
106
106
|
if (effectiveRuntime === "python") {
|
|
@@ -121,12 +121,9 @@ var runloop = createProvider({
|
|
|
121
121
|
}
|
|
122
122
|
}
|
|
123
123
|
return {
|
|
124
|
-
|
|
125
|
-
stderr: executionResult.stderr || "",
|
|
124
|
+
output: (executionResult.stdout || "") + (executionResult.stderr || ""),
|
|
126
125
|
exitCode: executionResult.exit_status || 0,
|
|
127
|
-
|
|
128
|
-
sandboxId: devbox.id || "runloop-unknown",
|
|
129
|
-
provider: "runloop"
|
|
126
|
+
language: effectiveRuntime
|
|
130
127
|
};
|
|
131
128
|
} catch (error) {
|
|
132
129
|
if (error instanceof Error && error.message === "exit status 1") {
|
|
@@ -137,12 +134,9 @@ var runloop = createProvider({
|
|
|
137
134
|
throw new Error(`Syntax error: ${syntaxErrorLine}`);
|
|
138
135
|
} else {
|
|
139
136
|
return {
|
|
140
|
-
|
|
141
|
-
stderr: actualStderr || "Error: Runtime error occurred during execution",
|
|
137
|
+
output: actualStderr || "Error: Runtime error occurred during execution",
|
|
142
138
|
exitCode: 1,
|
|
143
|
-
|
|
144
|
-
sandboxId: devbox.id || "runloop-unknown",
|
|
145
|
-
provider: "runloop"
|
|
139
|
+
language: effectiveRuntime
|
|
146
140
|
};
|
|
147
141
|
}
|
|
148
142
|
}
|
|
@@ -170,9 +164,7 @@ var runloop = createProvider({
|
|
|
170
164
|
stdout: executionResult.stdout || "",
|
|
171
165
|
stderr: executionResult.stderr || "",
|
|
172
166
|
exitCode: executionResult.exit_status || 0,
|
|
173
|
-
|
|
174
|
-
sandboxId: devbox.id || "runloop-unknown",
|
|
175
|
-
provider: "runloop"
|
|
167
|
+
durationMs: Date.now() - startTime
|
|
176
168
|
};
|
|
177
169
|
} catch (error) {
|
|
178
170
|
if (error instanceof Error && error.message.includes("Syntax error")) {
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * Runloop Provider - Factory-based Implementation\n *\n * Full-featured provider with filesystem support using the factory pattern.\n * Reduces ~400 lines of boilerplate to ~100 lines of core logic.\n */\n\nimport { Runloop } from \"@runloop/api-client\";\nimport { createProvider } from \"computesdk\";\nimport type {\n ExecutionResult,\n SandboxInfo,\n CreateSandboxOptions,\n FileEntry,\n CreateSnapshotOptions,\n ListSnapshotsOptions,\n Runtime,\n SandboxStatus,\n Sandbox,\n} from \"computesdk\";\n\n// Define Runloop-specific types\ntype RunloopSnapshot = Runloop.DevboxSnapshotView;\ntype RunloopTemplate = Runloop.BlueprintView;\n\n/**\n * Runloop-specific configuration options\n */\nexport interface RunloopConfig {\n /** Runloop API key - if not provided, will fallback to RUNLOOP_API_KEY environment variable */\n apiKey?: string;\n /** Execution timeout in milliseconds */\n timeout?: number;\n}\n\n/**\n * Runloop-specific blueprint creation options\n */\nexport interface CreateBlueprintTemplateOptions {\n /** Name of the blueprint template */\n name: string;\n /** Custom Dockerfile content */\n dockerfile?: string;\n /** System setup commands to run during blueprint creation */\n systemSetupCommands?: string[];\n /** Launch commands to run when starting a devbox from this blueprint */\n launchCommands?: string[];\n /** File mounts as key-value pairs (path -> content) */\n fileMounts?: Record<string, string>;\n /** Code repository mounts */\n codeMounts?: Array<{\n repoName: string;\n repoOwner: string;\n token?: string;\n installCommand?: string;\n }>;\n /** Resource size for devboxes created from this blueprint */\n resourceSize?:\n | \"X_SMALL\"\n | \"SMALL\"\n | \"MEDIUM\"\n | \"LARGE\"\n | \"X_LARGE\"\n | \"XX_LARGE\"\n | \"CUSTOM_SIZE\";\n /** CPU architecture */\n architecture?: \"x86_64\" | \"arm64\";\n /** Custom CPU cores (requires CUSTOM_SIZE) */\n customCpuCores?: number;\n /** Custom memory in GB (requires CUSTOM_SIZE) */\n customMemoryGb?: number;\n /** Custom disk size (requires CUSTOM_SIZE) */\n customDiskSize?: number;\n /** Available ports for the devbox */\n availablePorts?: number[];\n /** Action to take when devbox is idle */\n afterIdle?: { action: string; timeSeconds: number };\n /** Keep alive time in seconds */\n keepAliveTimeSeconds?: number;\n}\n\n/**\n * Create a Runloop provider instance using the factory pattern\n */\nexport const runloop = createProvider<\n Runloop.DevboxView, // TSandbox\n RunloopConfig, // TConfig\n RunloopTemplate, // TTemplate \n RunloopSnapshot // TSnapshot\n>({\n name: \"runloop\",\n methods: {\n sandbox: {\n // Collection operations (map to compute.sandbox.*)\n create: async (config: RunloopConfig, options?: CreateSandboxOptions) => {\n // Validate API key\n const apiKey =\n config.apiKey ||\n (typeof process !== \"undefined\" && process.env?.RUNLOOP_API_KEY) ||\n \"\";\n\n if (!apiKey) {\n throw new Error(\n `Missing Runloop API key. Provide 'apiKey' in config or set RUNLOOP_API_KEY environment variable. Get your API key from https://runloop.ai/`\n );\n }\n\n const timeout = config.timeout;\n\n try {\n const client = new Runloop({\n bearerToken: apiKey,\n });\n\n let devboxParams: Runloop.DevboxCreateParams = {\n launch_parameters: {\n keep_alive_time_seconds: timeout || options?.timeout || 300000,\n },\n name: options?.sandboxId,\n metadata: options?.metadata,\n environment_variables: options?.envs,\n };\n\n // Use blueprint if specified\n if (options?.templateId) {\n const templateId = options?.templateId;\n // Check template prefix to determine parameter type\n if (templateId?.startsWith(\"bpt_\")) {\n devboxParams.blueprint_id = templateId;\n } else if (templateId?.startsWith(\"snp_\")) {\n devboxParams.snapshot_id = templateId;\n } else {\n // empty\n }\n }\n\n const dbx = await client.devboxes.createAndAwaitRunning(devboxParams);\n\n // Create a RunloopSandbox object that contains both devbox and client\n const runloopSandbox = {\n ...dbx, // Spread all DevboxView properties\n client: client // Add client for method access\n };\n\n return {\n sandbox: runloopSandbox, \n sandboxId: dbx.id,\n };\n } catch (error) {\n throw new Error(\n `Failed to create Runloop devbox: ${\n error instanceof Error ? error.message : String(error)\n }`\n );\n }\n },\n\n getById: async (config: RunloopConfig, sandboxId: string) => {\n const apiKey = config.apiKey || process.env.RUNLOOP_API_KEY!;\n\n try {\n const client = new Runloop({\n bearerToken: apiKey,\n });\n\n const devbox = await client.devboxes.retrieve(sandboxId);\n\n return {\n sandbox: devbox,\n sandboxId,\n };\n } catch (error) {\n // Devbox doesn't exist or can't be accessed\n return null;\n }\n },\n\n list: async (config: RunloopConfig) => {\n const apiKey = config.apiKey || process.env.RUNLOOP_API_KEY!;\n\n try {\n const client = new Runloop({\n bearerToken: apiKey,\n });\n\n const response = await client.devboxes.list();\n const devboxes = response.devboxes || [];\n\n return devboxes.map((devbox) => ({\n sandbox: devbox,\n sandboxId: devbox.id,\n }));\n } catch (error) {\n // Return empty array if listing fails\n return [];\n }\n },\n\n destroy: async (config: RunloopConfig, sandboxId: string) => {\n const apiKey = config.apiKey || process.env.RUNLOOP_API_KEY!;\n\n try {\n const client = new Runloop({\n bearerToken: apiKey,\n });\n\n await client.devboxes.shutdown(sandboxId);\n } catch (error) {\n // Devbox might already be destroyed or doesn't exist\n // This is acceptable for destroy operations\n }\n },\n\n // Instance operations (map to individual Sandbox methods)\n runCode: async (sandbox: any, code: string, runtime?: Runtime): Promise<ExecutionResult> => {\n const startTime = Date.now();\n const devbox = sandbox;\n const client = sandbox.client;\n\n try {\n // Auto-detect runtime if not specified\n const effectiveRuntime = runtime || (\n // Strong Python indicators\n code.includes('print(') ||\n code.includes('import ') ||\n code.includes('def ') ||\n code.includes('sys.') ||\n code.includes('json.') ||\n code.includes('__') ||\n code.includes('f\"') ||\n code.includes(\"f'\") ||\n code.includes('raise ')\n ? 'python'\n // Default to Node.js for all other cases (including ambiguous)\n : 'node'\n );\n\n // Use base64 encoding for both runtimes for reliability and consistency\n const encoded = Buffer.from(code).toString('base64');\n\n let command;\n if (effectiveRuntime === 'python') {\n command = `echo \"${encoded}\" | base64 -d | python3`;\n } else {\n command = `echo \"${encoded}\" | base64 -d | node`;\n }\n\n // Execute code using Runloop's executeAsync\n const execution = await client.devboxes.executeAsync(devbox.id, {\n command: command,\n });\n\n const executionResult = await client.devboxes.executions.awaitCompleted(\n devbox.id,\n execution.execution_id\n );\n\n // Check for syntax errors and throw them (similar to Vercel behavior)\n if (executionResult.exit_status !== 0 && executionResult.stderr) {\n // Check for common syntax error patterns\n if (executionResult.stderr.includes('SyntaxError') ||\n executionResult.stderr.includes('invalid syntax') ||\n executionResult.stderr.includes('Unexpected token') ||\n executionResult.stderr.includes('Unexpected identifier')) {\n throw new Error(`Syntax error: ${executionResult.stderr.trim()}`);\n }\n }\n\n return {\n stdout: executionResult.stdout || \"\",\n stderr: executionResult.stderr || \"\",\n exitCode: executionResult.exit_status || 0,\n executionTime: Date.now() - startTime,\n sandboxId: devbox.id || \"runloop-unknown\",\n provider: \"runloop\",\n };\n } catch (error) {\n // Handle Runloop execution errors\n if (error instanceof Error && error.message === 'exit status 1') {\n const actualStderr = (error as any)?.result?.stderr || '';\n const isSyntaxError = actualStderr.includes('SyntaxError');\n\n if (isSyntaxError) {\n // For syntax errors, throw\n const syntaxErrorLine = actualStderr.split('\\n').find((line: string) => line.includes('SyntaxError')) || 'SyntaxError: Invalid syntax in code';\n throw new Error(`Syntax error: ${syntaxErrorLine}`);\n } else {\n // For runtime errors, return a result instead of throwing\n return {\n stdout: '',\n stderr: actualStderr || 'Error: Runtime error occurred during execution',\n exitCode: 1,\n executionTime: Date.now() - startTime,\n sandboxId: devbox.id || 'runloop-unknown',\n provider: 'runloop'\n };\n }\n }\n\n // Re-throw syntax errors\n if (error instanceof Error && error.message.includes('Syntax error')) {\n throw error;\n }\n throw new Error(\n `Runloop execution failed: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n runCommand: async (\n sandbox: any,\n command: string,\n args: string[] = []\n ): Promise<ExecutionResult> => {\n const startTime = Date.now();\n const devbox = sandbox;\n const client = sandbox.client;\n\n try {\n // Execute code using Runloop's executeAsync\n // Runloop supports all runtimes\n\n const execution = await client.devboxes.executeAsync(devbox.id, {\n command: `${command} ${args.join(\" \")}`,\n });\n\n const executionResult =\n await client.devboxes.executions.awaitCompleted(\n devbox.id,\n execution.execution_id\n );\n\n return {\n stdout: executionResult.stdout || \"\",\n stderr: executionResult.stderr || \"\",\n exitCode: executionResult.exit_status || 0,\n executionTime: Date.now() - startTime,\n sandboxId: devbox.id || \"runloop-unknown\",\n provider: \"runloop\",\n };\n } catch (error) {\n // Re-throw syntax errors\n if (\n error instanceof Error &&\n error.message.includes(\"Syntax error\")\n ) {\n throw error;\n }\n throw new Error(\n `Runloop execution failed: ${\n error instanceof Error ? error.message : String(error)\n }`\n );\n }\n },\n\n getInfo: async (sandbox): Promise<SandboxInfo> => {\n const devbox = sandbox;\n\n return {\n id: devbox.id || \"runloop-unknown\",\n provider: \"runloop\",\n runtime: \"node\" as Runtime, // Runloop supports multiple runtimes, defaulting to node\n status: devbox.status as SandboxStatus,\n createdAt: new Date(devbox.create_time_ms || Date.now()),\n timeout: devbox.launch_parameters.keep_alive_time_seconds || 300000,\n metadata: {\n runloopDevboxId: devbox.id,\n templateId: devbox.blueprint_id || devbox.snapshot_id,\n ...devbox.metadata,\n },\n };\n },\n\n getUrl: async (\n sandbox: any,\n options: { port: number }\n ): Promise<string> => {\n const devbox = sandbox;\n const client = sandbox.client;\n\n try {\n const tunnel = await client.devboxes.createTunnel(devbox.id, {\n port: options.port,\n });\n\n return tunnel.url;\n } catch (error) {\n throw new Error(\n `Failed to get Runloop URL for port ${options.port}: ${\n error instanceof Error ? error.message : String(error)\n }`\n );\n }\n },\n\n // Optional filesystem methods - using Runloop's file operations\n filesystem: {\n readFile: async (sandbox: any, path: string, runCommand: any): Promise<string> => {\n try {\n const result = await runCommand(sandbox, 'cat', [path]);\n if (result.exitCode !== 0) {\n throw new Error(`File not found or unreadable: ${result.stderr}`);\n }\n return result.stdout;\n } catch (error) {\n throw new Error(\n `Failed to read file ${path}: ${\n error instanceof Error ? error.message : String(error)\n }`\n );\n }\n },\n\n writeFile: async (\n sandbox: any,\n path: string,\n content: string,\n runCommand: any\n ): Promise<void> => {\n try {\n // Use command-based approach for file writing since API writeFileContents may have issues\n const encoded = Buffer.from(content).toString('base64');\n const result = await runCommand(sandbox, 'sh', ['-c', `echo \"${encoded}\" | base64 -d > \"${path}\"`]);\n \n if (result.exitCode !== 0) {\n throw new Error(`Command failed: ${result.stderr}`);\n }\n } catch (error) {\n throw new Error(\n `Failed to write file ${path}: ${\n error instanceof Error ? error.message : String(error)\n }`\n );\n }\n },\n\n mkdir: async (\n sandbox: any,\n path: string,\n runCommand: any\n ): Promise<void> => {\n const result = await runCommand(sandbox, \"mkdir\", [\"-p\", path]);\n if (result.exitCode !== 0) {\n throw new Error(\n `Failed to create directory ${path}: ${result.stderr}`\n );\n }\n },\n\n readdir: async (\n sandbox: any,\n path: string,\n runCommand: any\n ): Promise<FileEntry[]> => {\n const result = await runCommand(sandbox, \"ls\", [\"-la\", path]);\n\n if (result.exitCode !== 0) {\n throw new Error(\n `Failed to list directory ${path}: ${result.stderr}`\n );\n }\n\n const lines = (result.stdout || \"\")\n .split(\"\\n\")\n .filter((line: string) => line.trim() && !line.startsWith(\"total\"));\n\n return lines.map((line: string) => {\n const parts = line.trim().split(/\\s+/);\n const name = parts[parts.length - 1];\n const isDirectory = line.startsWith(\"d\");\n\n return {\n name,\n path: `${path}/${name}`,\n isDirectory,\n size: parseInt(parts[4]) || 0,\n lastModified: new Date(),\n };\n });\n },\n\n exists: async (\n sandbox: any,\n path: string,\n runCommand: any\n ): Promise<boolean> => {\n const result = await runCommand(sandbox, \"test\", [\"-e\", path]);\n return result.exitCode === 0;\n },\n\n remove: async (\n sandbox: any,\n path: string,\n runCommand: any\n ): Promise<void> => {\n const result = await runCommand(sandbox, \"rm\", [\"-rf\", path]);\n if (result.exitCode !== 0) {\n throw new Error(`Failed to remove ${path}: ${result.stderr}`);\n }\n },\n },\n \n // Provider-specific typed getInstance method\n getInstance: (sandbox): Runloop.DevboxView => {\n return sandbox;\n },\n },\n\n // Template management methods using the new factory pattern\n template: {\n create: async (\n config: RunloopConfig,\n options: CreateBlueprintTemplateOptions | Runloop.BlueprintCreateParams\n ) => {\n const apiKey = config.apiKey || process.env.RUNLOOP_API_KEY!;\n\n if (!apiKey) {\n throw new Error(\n \"Missing Runloop API key for blueprint template creation\"\n );\n }\n\n try {\n const client = new Runloop({\n bearerToken: apiKey,\n });\n\n const blueprint = await client.blueprints.create(options);\n return blueprint;\n } catch (error) {\n throw new Error(\n `Failed to create blueprint template: ${\n error instanceof Error ? error.message : String(error)\n }`\n );\n }\n },\n\n list: async (config: RunloopConfig, options?: { limit?: number }) => {\n const apiKey = config.apiKey || process.env.RUNLOOP_API_KEY!;\n\n if (!apiKey) {\n throw new Error(\n \"Missing Runloop API key for listing blueprint templates\"\n );\n }\n\n try {\n const client = new Runloop({\n bearerToken: apiKey,\n });\n\n const listParams: any = {};\n if (options?.limit) {\n listParams.limit = options.limit;\n }\n\n const response = await client.blueprints.list(listParams);\n return response.blueprints || [];\n } catch (error) {\n throw new Error(\n `Failed to list blueprint templates: ${\n error instanceof Error ? error.message : String(error)\n }`\n );\n }\n },\n\n delete: async (config: RunloopConfig, blueprintId: string) => {\n const apiKey = config.apiKey || process.env.RUNLOOP_API_KEY!;\n\n if (!apiKey) {\n throw new Error(\n \"Missing Runloop API key for blueprint template deletion\"\n );\n }\n\n try {\n const client = new Runloop({\n bearerToken: apiKey,\n });\n\n await client.blueprints.delete(blueprintId);\n } catch (error) {\n throw new Error(\n `Failed to delete blueprint template ${blueprintId}: ${\n error instanceof Error ? error.message : String(error)\n }`\n );\n }\n },\n },\n\n // Snapshot management methods using the new factory pattern\n snapshot: {\n create: async (\n config: RunloopConfig,\n sandboxId: string,\n options?: CreateSnapshotOptions\n ) => {\n const apiKey = config.apiKey || process.env.RUNLOOP_API_KEY!;\n\n if (!apiKey) {\n throw new Error(\"Missing Runloop API key for snapshot creation\");\n }\n\n try {\n const client = new Runloop({\n bearerToken: apiKey,\n });\n\n const snapshotParams: any = {};\n if (options?.name) {\n snapshotParams.name = options.name;\n }\n if (options?.metadata) {\n snapshotParams.metadata = options.metadata;\n }\n\n const snapshot = await client.devboxes.snapshotDisk(\n sandboxId,\n snapshotParams\n );\n return snapshot;\n } catch (error) {\n throw new Error(\n `Failed to create snapshot for sandbox ${sandboxId}: ${\n error instanceof Error ? error.message : String(error)\n }`\n );\n }\n },\n\n list: async (\n config: RunloopConfig,\n options?: ListSnapshotsOptions\n ) => {\n const apiKey = config.apiKey || process.env.RUNLOOP_API_KEY!;\n\n if (!apiKey) {\n throw new Error(\"Missing Runloop API key for listing snapshots\");\n }\n\n try {\n const client = new Runloop({\n bearerToken: apiKey,\n });\n\n const listParams: any = {};\n if (options?.limit) {\n listParams.limit = options.limit;\n }\n\n const response = await client.devboxes.listDiskSnapshots(listParams);\n return response.snapshots || [];\n } catch (error) {\n throw new Error(\n `Failed to list snapshots: ${\n error instanceof Error ? error.message : String(error)\n }`\n );\n }\n },\n\n delete: async (config: RunloopConfig, snapshotId: string) => {\n const apiKey = config.apiKey || process.env.RUNLOOP_API_KEY!;\n\n if (!apiKey) {\n throw new Error(\"Missing Runloop API key for snapshot deletion\");\n }\n\n try {\n const client = new Runloop({\n bearerToken: apiKey,\n });\n\n await client.devboxes.deleteDiskSnapshot(snapshotId);\n } catch (error) {\n throw new Error(\n `Failed to delete snapshot ${snapshotId}: ${\n error instanceof Error ? error.message : String(error)\n }`\n );\n }\n },\n },\n },\n});"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * Runloop Provider - Factory-based Implementation\n *\n * Full-featured provider with filesystem support using the factory pattern.\n * Reduces ~400 lines of boilerplate to ~100 lines of core logic.\n */\n\nimport { Runloop } from \"@runloop/api-client\";\nimport { createProvider } from \"computesdk\";\nimport type {\n CodeResult,\n CommandResult,\n SandboxInfo,\n CreateSandboxOptions,\n FileEntry,\n CreateSnapshotOptions,\n ListSnapshotsOptions,\n Runtime,\n SandboxStatus,\n Sandbox,\n} from \"computesdk\";\n\n// Define Runloop-specific types\ntype RunloopSnapshot = Runloop.DevboxSnapshotView;\ntype RunloopTemplate = Runloop.BlueprintView;\n\n/**\n * Runloop-specific configuration options\n */\nexport interface RunloopConfig {\n /** Runloop API key - if not provided, will fallback to RUNLOOP_API_KEY environment variable */\n apiKey?: string;\n /** Execution timeout in milliseconds */\n timeout?: number;\n}\n\n/**\n * Runloop-specific blueprint creation options\n */\nexport interface CreateBlueprintTemplateOptions {\n /** Name of the blueprint template */\n name: string;\n /** Custom Dockerfile content */\n dockerfile?: string;\n /** System setup commands to run during blueprint creation */\n systemSetupCommands?: string[];\n /** Launch commands to run when starting a devbox from this blueprint */\n launchCommands?: string[];\n /** File mounts as key-value pairs (path -> content) */\n fileMounts?: Record<string, string>;\n /** Code repository mounts */\n codeMounts?: Array<{\n repoName: string;\n repoOwner: string;\n token?: string;\n installCommand?: string;\n }>;\n /** Resource size for devboxes created from this blueprint */\n resourceSize?:\n | \"X_SMALL\"\n | \"SMALL\"\n | \"MEDIUM\"\n | \"LARGE\"\n | \"X_LARGE\"\n | \"XX_LARGE\"\n | \"CUSTOM_SIZE\";\n /** CPU architecture */\n architecture?: \"x86_64\" | \"arm64\";\n /** Custom CPU cores (requires CUSTOM_SIZE) */\n customCpuCores?: number;\n /** Custom memory in GB (requires CUSTOM_SIZE) */\n customMemoryGb?: number;\n /** Custom disk size (requires CUSTOM_SIZE) */\n customDiskSize?: number;\n /** Available ports for the devbox */\n availablePorts?: number[];\n /** Action to take when devbox is idle */\n afterIdle?: { action: string; timeSeconds: number };\n /** Keep alive time in seconds */\n keepAliveTimeSeconds?: number;\n}\n\n/**\n * Create a Runloop provider instance using the factory pattern\n */\nexport const runloop = createProvider<\n Runloop.DevboxView, // TSandbox\n RunloopConfig, // TConfig\n RunloopTemplate, // TTemplate \n RunloopSnapshot // TSnapshot\n>({\n name: \"runloop\",\n methods: {\n sandbox: {\n // Collection operations (map to compute.sandbox.*)\n create: async (config: RunloopConfig, options?: CreateSandboxOptions) => {\n // Validate API key\n const apiKey =\n config.apiKey ||\n (typeof process !== \"undefined\" && process.env?.RUNLOOP_API_KEY) ||\n \"\";\n\n if (!apiKey) {\n throw new Error(\n `Missing Runloop API key. Provide 'apiKey' in config or set RUNLOOP_API_KEY environment variable. Get your API key from https://runloop.ai/`\n );\n }\n\n const timeout = config.timeout;\n\n try {\n const client = new Runloop({\n bearerToken: apiKey,\n });\n\n let devboxParams: Runloop.DevboxCreateParams = {\n launch_parameters: {\n keep_alive_time_seconds: timeout || options?.timeout || 300000,\n },\n name: options?.sandboxId,\n metadata: options?.metadata,\n environment_variables: options?.envs,\n };\n\n // Use blueprint if specified\n if (options?.templateId) {\n const templateId = options?.templateId;\n // Check template prefix to determine parameter type\n if (templateId?.startsWith(\"bpt_\")) {\n devboxParams.blueprint_id = templateId;\n } else if (templateId?.startsWith(\"snp_\")) {\n devboxParams.snapshot_id = templateId;\n } else {\n // empty\n }\n }\n\n const dbx = await client.devboxes.createAndAwaitRunning(devboxParams);\n\n // Create a RunloopSandbox object that contains both devbox and client\n const runloopSandbox = {\n ...dbx, // Spread all DevboxView properties\n client: client // Add client for method access\n };\n\n return {\n sandbox: runloopSandbox, \n sandboxId: dbx.id,\n };\n } catch (error) {\n throw new Error(\n `Failed to create Runloop devbox: ${\n error instanceof Error ? error.message : String(error)\n }`\n );\n }\n },\n\n getById: async (config: RunloopConfig, sandboxId: string) => {\n const apiKey = config.apiKey || process.env.RUNLOOP_API_KEY!;\n\n try {\n const client = new Runloop({\n bearerToken: apiKey,\n });\n\n const devbox = await client.devboxes.retrieve(sandboxId);\n\n return {\n sandbox: devbox,\n sandboxId,\n };\n } catch (error) {\n // Devbox doesn't exist or can't be accessed\n return null;\n }\n },\n\n list: async (config: RunloopConfig) => {\n const apiKey = config.apiKey || process.env.RUNLOOP_API_KEY!;\n\n try {\n const client = new Runloop({\n bearerToken: apiKey,\n });\n\n const response = await client.devboxes.list();\n const devboxes = response.devboxes || [];\n\n return devboxes.map((devbox) => ({\n sandbox: devbox,\n sandboxId: devbox.id,\n }));\n } catch (error) {\n // Return empty array if listing fails\n return [];\n }\n },\n\n destroy: async (config: RunloopConfig, sandboxId: string) => {\n const apiKey = config.apiKey || process.env.RUNLOOP_API_KEY!;\n\n try {\n const client = new Runloop({\n bearerToken: apiKey,\n });\n\n await client.devboxes.shutdown(sandboxId);\n } catch (error) {\n // Devbox might already be destroyed or doesn't exist\n // This is acceptable for destroy operations\n }\n },\n\n // Instance operations (map to individual Sandbox methods)\n runCode: async (sandbox: any, code: string, runtime?: Runtime): Promise<CodeResult> => {\n const startTime = Date.now();\n const devbox = sandbox;\n const client = sandbox.client;\n\n // Auto-detect runtime if not specified\n const effectiveRuntime: Runtime = runtime || (\n // Strong Python indicators\n code.includes('print(') ||\n code.includes('import ') ||\n code.includes('def ') ||\n code.includes('sys.') ||\n code.includes('json.') ||\n code.includes('__') ||\n code.includes('f\"') ||\n code.includes(\"f'\") ||\n code.includes('raise ')\n ? 'python'\n // Default to Node.js for all other cases (including ambiguous)\n : 'node'\n ) as Runtime;\n\n try {\n\n // Use base64 encoding for both runtimes for reliability and consistency\n const encoded = Buffer.from(code).toString('base64');\n\n let command;\n if (effectiveRuntime === 'python') {\n command = `echo \"${encoded}\" | base64 -d | python3`;\n } else {\n command = `echo \"${encoded}\" | base64 -d | node`;\n }\n\n // Execute code using Runloop's executeAsync\n const execution = await client.devboxes.executeAsync(devbox.id, {\n command: command,\n });\n\n const executionResult = await client.devboxes.executions.awaitCompleted(\n devbox.id,\n execution.execution_id\n );\n\n // Check for syntax errors and throw them (similar to Vercel behavior)\n if (executionResult.exit_status !== 0 && executionResult.stderr) {\n // Check for common syntax error patterns\n if (executionResult.stderr.includes('SyntaxError') ||\n executionResult.stderr.includes('invalid syntax') ||\n executionResult.stderr.includes('Unexpected token') ||\n executionResult.stderr.includes('Unexpected identifier')) {\n throw new Error(`Syntax error: ${executionResult.stderr.trim()}`);\n }\n }\n\n return {\n output: (executionResult.stdout || \"\") + (executionResult.stderr || \"\"),\n exitCode: executionResult.exit_status || 0,\n language: effectiveRuntime,\n };\n } catch (error) {\n // Handle Runloop execution errors\n if (error instanceof Error && error.message === 'exit status 1') {\n const actualStderr = (error as any)?.result?.stderr || '';\n const isSyntaxError = actualStderr.includes('SyntaxError');\n\n if (isSyntaxError) {\n // For syntax errors, throw\n const syntaxErrorLine = actualStderr.split('\\n').find((line: string) => line.includes('SyntaxError')) || 'SyntaxError: Invalid syntax in code';\n throw new Error(`Syntax error: ${syntaxErrorLine}`);\n } else {\n // For runtime errors, return a result instead of throwing\n return {\n output: actualStderr || 'Error: Runtime error occurred during execution',\n exitCode: 1,\n language: effectiveRuntime,\n };\n }\n }\n\n // Re-throw syntax errors\n if (error instanceof Error && error.message.includes('Syntax error')) {\n throw error;\n }\n throw new Error(\n `Runloop execution failed: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n runCommand: async (\n sandbox: any,\n command: string,\n args: string[] = []\n ): Promise<CommandResult> => {\n const startTime = Date.now();\n const devbox = sandbox;\n const client = sandbox.client;\n\n try {\n // Execute code using Runloop's executeAsync\n // Runloop supports all runtimes\n\n const execution = await client.devboxes.executeAsync(devbox.id, {\n command: `${command} ${args.join(\" \")}`,\n });\n\n const executionResult =\n await client.devboxes.executions.awaitCompleted(\n devbox.id,\n execution.execution_id\n );\n\n return {\n stdout: executionResult.stdout || \"\",\n stderr: executionResult.stderr || \"\",\n exitCode: executionResult.exit_status || 0,\n durationMs: Date.now() - startTime,\n };\n } catch (error) {\n // Re-throw syntax errors\n if (\n error instanceof Error &&\n error.message.includes(\"Syntax error\")\n ) {\n throw error;\n }\n throw new Error(\n `Runloop execution failed: ${\n error instanceof Error ? error.message : String(error)\n }`\n );\n }\n },\n\n getInfo: async (sandbox): Promise<SandboxInfo> => {\n const devbox = sandbox;\n\n return {\n id: devbox.id || \"runloop-unknown\",\n provider: \"runloop\",\n runtime: \"node\" as Runtime, // Runloop supports multiple runtimes, defaulting to node\n status: devbox.status as SandboxStatus,\n createdAt: new Date(devbox.create_time_ms || Date.now()),\n timeout: devbox.launch_parameters.keep_alive_time_seconds || 300000,\n metadata: {\n runloopDevboxId: devbox.id,\n templateId: devbox.blueprint_id || devbox.snapshot_id,\n ...devbox.metadata,\n },\n };\n },\n\n getUrl: async (\n sandbox: any,\n options: { port: number }\n ): Promise<string> => {\n const devbox = sandbox;\n const client = sandbox.client;\n\n try {\n const tunnel = await client.devboxes.createTunnel(devbox.id, {\n port: options.port,\n });\n\n return tunnel.url;\n } catch (error) {\n throw new Error(\n `Failed to get Runloop URL for port ${options.port}: ${\n error instanceof Error ? error.message : String(error)\n }`\n );\n }\n },\n\n // Optional filesystem methods - using Runloop's file operations\n filesystem: {\n readFile: async (sandbox: any, path: string, runCommand: any): Promise<string> => {\n try {\n const result = await runCommand(sandbox, 'cat', [path]);\n if (result.exitCode !== 0) {\n throw new Error(`File not found or unreadable: ${result.stderr}`);\n }\n return result.stdout;\n } catch (error) {\n throw new Error(\n `Failed to read file ${path}: ${\n error instanceof Error ? error.message : String(error)\n }`\n );\n }\n },\n\n writeFile: async (\n sandbox: any,\n path: string,\n content: string,\n runCommand: any\n ): Promise<void> => {\n try {\n // Use command-based approach for file writing since API writeFileContents may have issues\n const encoded = Buffer.from(content).toString('base64');\n const result = await runCommand(sandbox, 'sh', ['-c', `echo \"${encoded}\" | base64 -d > \"${path}\"`]);\n \n if (result.exitCode !== 0) {\n throw new Error(`Command failed: ${result.stderr}`);\n }\n } catch (error) {\n throw new Error(\n `Failed to write file ${path}: ${\n error instanceof Error ? error.message : String(error)\n }`\n );\n }\n },\n\n mkdir: async (\n sandbox: any,\n path: string,\n runCommand: any\n ): Promise<void> => {\n const result = await runCommand(sandbox, \"mkdir\", [\"-p\", path]);\n if (result.exitCode !== 0) {\n throw new Error(\n `Failed to create directory ${path}: ${result.stderr}`\n );\n }\n },\n\n readdir: async (\n sandbox: any,\n path: string,\n runCommand: any\n ): Promise<FileEntry[]> => {\n const result = await runCommand(sandbox, \"ls\", [\"-la\", path]);\n\n if (result.exitCode !== 0) {\n throw new Error(\n `Failed to list directory ${path}: ${result.stderr}`\n );\n }\n\n const lines = (result.stdout || \"\")\n .split(\"\\n\")\n .filter((line: string) => line.trim() && !line.startsWith(\"total\"));\n\n return lines.map((line: string) => {\n const parts = line.trim().split(/\\s+/);\n const name = parts[parts.length - 1];\n const isDirectory = line.startsWith(\"d\");\n\n return {\n name,\n path: `${path}/${name}`,\n isDirectory,\n size: parseInt(parts[4]) || 0,\n lastModified: new Date(),\n };\n });\n },\n\n exists: async (\n sandbox: any,\n path: string,\n runCommand: any\n ): Promise<boolean> => {\n const result = await runCommand(sandbox, \"test\", [\"-e\", path]);\n return result.exitCode === 0;\n },\n\n remove: async (\n sandbox: any,\n path: string,\n runCommand: any\n ): Promise<void> => {\n const result = await runCommand(sandbox, \"rm\", [\"-rf\", path]);\n if (result.exitCode !== 0) {\n throw new Error(`Failed to remove ${path}: ${result.stderr}`);\n }\n },\n },\n \n // Provider-specific typed getInstance method\n getInstance: (sandbox): Runloop.DevboxView => {\n return sandbox;\n },\n },\n\n // Template management methods using the new factory pattern\n template: {\n create: async (\n config: RunloopConfig,\n options: CreateBlueprintTemplateOptions | Runloop.BlueprintCreateParams\n ) => {\n const apiKey = config.apiKey || process.env.RUNLOOP_API_KEY!;\n\n if (!apiKey) {\n throw new Error(\n \"Missing Runloop API key for blueprint template creation\"\n );\n }\n\n try {\n const client = new Runloop({\n bearerToken: apiKey,\n });\n\n const blueprint = await client.blueprints.create(options);\n return blueprint;\n } catch (error) {\n throw new Error(\n `Failed to create blueprint template: ${\n error instanceof Error ? error.message : String(error)\n }`\n );\n }\n },\n\n list: async (config: RunloopConfig, options?: { limit?: number }) => {\n const apiKey = config.apiKey || process.env.RUNLOOP_API_KEY!;\n\n if (!apiKey) {\n throw new Error(\n \"Missing Runloop API key for listing blueprint templates\"\n );\n }\n\n try {\n const client = new Runloop({\n bearerToken: apiKey,\n });\n\n const listParams: any = {};\n if (options?.limit) {\n listParams.limit = options.limit;\n }\n\n const response = await client.blueprints.list(listParams);\n return response.blueprints || [];\n } catch (error) {\n throw new Error(\n `Failed to list blueprint templates: ${\n error instanceof Error ? error.message : String(error)\n }`\n );\n }\n },\n\n delete: async (config: RunloopConfig, blueprintId: string) => {\n const apiKey = config.apiKey || process.env.RUNLOOP_API_KEY!;\n\n if (!apiKey) {\n throw new Error(\n \"Missing Runloop API key for blueprint template deletion\"\n );\n }\n\n try {\n const client = new Runloop({\n bearerToken: apiKey,\n });\n\n await client.blueprints.delete(blueprintId);\n } catch (error) {\n throw new Error(\n `Failed to delete blueprint template ${blueprintId}: ${\n error instanceof Error ? error.message : String(error)\n }`\n );\n }\n },\n },\n\n // Snapshot management methods using the new factory pattern\n snapshot: {\n create: async (\n config: RunloopConfig,\n sandboxId: string,\n options?: CreateSnapshotOptions\n ) => {\n const apiKey = config.apiKey || process.env.RUNLOOP_API_KEY!;\n\n if (!apiKey) {\n throw new Error(\"Missing Runloop API key for snapshot creation\");\n }\n\n try {\n const client = new Runloop({\n bearerToken: apiKey,\n });\n\n const snapshotParams: any = {};\n if (options?.name) {\n snapshotParams.name = options.name;\n }\n if (options?.metadata) {\n snapshotParams.metadata = options.metadata;\n }\n\n const snapshot = await client.devboxes.snapshotDisk(\n sandboxId,\n snapshotParams\n );\n return snapshot;\n } catch (error) {\n throw new Error(\n `Failed to create snapshot for sandbox ${sandboxId}: ${\n error instanceof Error ? error.message : String(error)\n }`\n );\n }\n },\n\n list: async (\n config: RunloopConfig,\n options?: ListSnapshotsOptions\n ) => {\n const apiKey = config.apiKey || process.env.RUNLOOP_API_KEY!;\n\n if (!apiKey) {\n throw new Error(\"Missing Runloop API key for listing snapshots\");\n }\n\n try {\n const client = new Runloop({\n bearerToken: apiKey,\n });\n\n const listParams: any = {};\n if (options?.limit) {\n listParams.limit = options.limit;\n }\n\n const response = await client.devboxes.listDiskSnapshots(listParams);\n return response.snapshots || [];\n } catch (error) {\n throw new Error(\n `Failed to list snapshots: ${\n error instanceof Error ? error.message : String(error)\n }`\n );\n }\n },\n\n delete: async (config: RunloopConfig, snapshotId: string) => {\n const apiKey = config.apiKey || process.env.RUNLOOP_API_KEY!;\n\n if (!apiKey) {\n throw new Error(\"Missing Runloop API key for snapshot deletion\");\n }\n\n try {\n const client = new Runloop({\n bearerToken: apiKey,\n });\n\n await client.devboxes.deleteDiskSnapshot(snapshotId);\n } catch (error) {\n throw new Error(\n `Failed to delete snapshot ${snapshotId}: ${\n error instanceof Error ? error.message : String(error)\n }`\n );\n }\n },\n },\n },\n});"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@computesdk/runloop",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "Runloop provider for ComputeSDK",
|
|
5
5
|
"author": "Runloop",
|
|
6
6
|
"license": "MIT",
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
],
|
|
20
20
|
"dependencies": {
|
|
21
21
|
"@runloop/api-client": "^0.44.0",
|
|
22
|
-
"computesdk": "1.
|
|
22
|
+
"computesdk": "1.9.0"
|
|
23
23
|
},
|
|
24
24
|
"keywords": [
|
|
25
25
|
"runloop",
|