@computesdk/runloop 1.0.0 → 1.1.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 CHANGED
@@ -60,8 +60,14 @@ var runloop = (0, import_computesdk.createProvider)({
60
60
  }
61
61
  }
62
62
  const dbx = await client.devboxes.createAndAwaitRunning(devboxParams);
63
+ const runloopSandbox = {
64
+ ...dbx,
65
+ // Spread all DevboxView properties
66
+ client
67
+ // Add client for method access
68
+ };
63
69
  return {
64
- sandbox: dbx,
70
+ sandbox: runloopSandbox,
65
71
  sandboxId: dbx.id
66
72
  };
67
73
  } catch (error) {
@@ -112,12 +118,70 @@ var runloop = (0, import_computesdk.createProvider)({
112
118
  }
113
119
  },
114
120
  // Instance operations (map to individual Sandbox methods)
115
- runCode: async (_sandbox, _code) => {
116
- throw new Error("Please use runCommand instead");
121
+ runCode: async (sandbox, code, runtime) => {
122
+ const startTime = Date.now();
123
+ const devbox = sandbox;
124
+ const client = sandbox.client;
125
+ 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
+ const encoded = Buffer.from(code).toString("base64");
129
+ let command;
130
+ if (effectiveRuntime === "python") {
131
+ command = `echo "${encoded}" | base64 -d | python3`;
132
+ } else {
133
+ command = `echo "${encoded}" | base64 -d | node`;
134
+ }
135
+ const execution = await client.devboxes.executeAsync(devbox.id, {
136
+ command
137
+ });
138
+ const executionResult = await client.devboxes.executions.awaitCompleted(
139
+ devbox.id,
140
+ execution.execution_id
141
+ );
142
+ if (executionResult.exit_status !== 0 && executionResult.stderr) {
143
+ if (executionResult.stderr.includes("SyntaxError") || executionResult.stderr.includes("invalid syntax") || executionResult.stderr.includes("Unexpected token") || executionResult.stderr.includes("Unexpected identifier")) {
144
+ throw new Error(`Syntax error: ${executionResult.stderr.trim()}`);
145
+ }
146
+ }
147
+ return {
148
+ stdout: executionResult.stdout || "",
149
+ stderr: executionResult.stderr || "",
150
+ exitCode: executionResult.exit_status || 0,
151
+ executionTime: Date.now() - startTime,
152
+ sandboxId: devbox.id || "runloop-unknown",
153
+ provider: "runloop"
154
+ };
155
+ } catch (error) {
156
+ if (error instanceof Error && error.message === "exit status 1") {
157
+ const actualStderr = error?.result?.stderr || "";
158
+ const isSyntaxError = actualStderr.includes("SyntaxError");
159
+ if (isSyntaxError) {
160
+ const syntaxErrorLine = actualStderr.split("\n").find((line) => line.includes("SyntaxError")) || "SyntaxError: Invalid syntax in code";
161
+ throw new Error(`Syntax error: ${syntaxErrorLine}`);
162
+ } else {
163
+ return {
164
+ stdout: "",
165
+ stderr: actualStderr || "Error: Runtime error occurred during execution",
166
+ exitCode: 1,
167
+ executionTime: Date.now() - startTime,
168
+ sandboxId: devbox.id || "runloop-unknown",
169
+ provider: "runloop"
170
+ };
171
+ }
172
+ }
173
+ if (error instanceof Error && error.message.includes("Syntax error")) {
174
+ throw error;
175
+ }
176
+ throw new Error(
177
+ `Runloop execution failed: ${error instanceof Error ? error.message : String(error)}`
178
+ );
179
+ }
117
180
  },
118
181
  runCommand: async (sandbox, command, args = []) => {
119
182
  const startTime = Date.now();
120
- const { devbox, client } = sandbox;
183
+ const devbox = sandbox;
184
+ const client = sandbox.client;
121
185
  try {
122
186
  const execution = await client.devboxes.executeAsync(devbox.id, {
123
187
  command: `${command} ${args.join(" ")}`
@@ -161,7 +225,8 @@ var runloop = (0, import_computesdk.createProvider)({
161
225
  };
162
226
  },
163
227
  getUrl: async (sandbox, options) => {
164
- const { devbox, client } = sandbox;
228
+ const devbox = sandbox;
229
+ const client = sandbox.client;
165
230
  try {
166
231
  const tunnel = await client.devboxes.createTunnel(devbox.id, {
167
232
  port: options.port
@@ -175,26 +240,26 @@ var runloop = (0, import_computesdk.createProvider)({
175
240
  },
176
241
  // Optional filesystem methods - using Runloop's file operations
177
242
  filesystem: {
178
- readFile: async (sandbox, path) => {
179
- const { devbox, client } = sandbox;
243
+ readFile: async (sandbox, path, runCommand) => {
180
244
  try {
181
- const result = await client.devboxes.readFileContents(devbox.id, {
182
- path
183
- });
184
- return result.content || "";
245
+ const result = await runCommand(sandbox, "cat", [path]);
246
+ if (result.exitCode !== 0) {
247
+ throw new Error(`File not found or unreadable: ${result.stderr}`);
248
+ }
249
+ return result.stdout;
185
250
  } catch (error) {
186
251
  throw new Error(
187
252
  `Failed to read file ${path}: ${error instanceof Error ? error.message : String(error)}`
188
253
  );
189
254
  }
190
255
  },
191
- writeFile: async (sandbox, path, content) => {
192
- const { devbox, client } = sandbox;
256
+ writeFile: async (sandbox, path, content, runCommand) => {
193
257
  try {
194
- await client.devboxes.writeFileContents(devbox.id, {
195
- path,
196
- content
197
- });
258
+ const encoded = Buffer.from(content).toString("base64");
259
+ const result = await runCommand(sandbox, "sh", ["-c", `echo "${encoded}" | base64 -d > "${path}"`]);
260
+ if (result.exitCode !== 0) {
261
+ throw new Error(`Command failed: ${result.stderr}`);
262
+ }
198
263
  } catch (error) {
199
264
  throw new Error(
200
265
  `Failed to write file ${path}: ${error instanceof Error ? error.message : String(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 return {\n sandbox: dbx, \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): Promise<ExecutionResult> => {\n throw new Error(\"Please use runCommand instead\");\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, client } = sandbox;\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, client } = sandbox;\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): Promise<string> => {\n const { devbox, client } = sandbox;\n\n try {\n const result = await client.devboxes.readFileContents(devbox.id, {\n path: path,\n });\n return result.content || \"\";\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 ): Promise<void> => {\n const { devbox, client } = sandbox;\n\n try {\n await client.devboxes.writeFileContents(devbox.id, {\n path: path,\n content: content,\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 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":[]}
package/dist/index.mjs CHANGED
@@ -36,8 +36,14 @@ var runloop = createProvider({
36
36
  }
37
37
  }
38
38
  const dbx = await client.devboxes.createAndAwaitRunning(devboxParams);
39
+ const runloopSandbox = {
40
+ ...dbx,
41
+ // Spread all DevboxView properties
42
+ client
43
+ // Add client for method access
44
+ };
39
45
  return {
40
- sandbox: dbx,
46
+ sandbox: runloopSandbox,
41
47
  sandboxId: dbx.id
42
48
  };
43
49
  } catch (error) {
@@ -88,12 +94,70 @@ var runloop = createProvider({
88
94
  }
89
95
  },
90
96
  // Instance operations (map to individual Sandbox methods)
91
- runCode: async (_sandbox, _code) => {
92
- throw new Error("Please use runCommand instead");
97
+ runCode: async (sandbox, code, runtime) => {
98
+ const startTime = Date.now();
99
+ const devbox = sandbox;
100
+ const client = sandbox.client;
101
+ 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
+ const encoded = Buffer.from(code).toString("base64");
105
+ let command;
106
+ if (effectiveRuntime === "python") {
107
+ command = `echo "${encoded}" | base64 -d | python3`;
108
+ } else {
109
+ command = `echo "${encoded}" | base64 -d | node`;
110
+ }
111
+ const execution = await client.devboxes.executeAsync(devbox.id, {
112
+ command
113
+ });
114
+ const executionResult = await client.devboxes.executions.awaitCompleted(
115
+ devbox.id,
116
+ execution.execution_id
117
+ );
118
+ if (executionResult.exit_status !== 0 && executionResult.stderr) {
119
+ if (executionResult.stderr.includes("SyntaxError") || executionResult.stderr.includes("invalid syntax") || executionResult.stderr.includes("Unexpected token") || executionResult.stderr.includes("Unexpected identifier")) {
120
+ throw new Error(`Syntax error: ${executionResult.stderr.trim()}`);
121
+ }
122
+ }
123
+ return {
124
+ stdout: executionResult.stdout || "",
125
+ stderr: executionResult.stderr || "",
126
+ exitCode: executionResult.exit_status || 0,
127
+ executionTime: Date.now() - startTime,
128
+ sandboxId: devbox.id || "runloop-unknown",
129
+ provider: "runloop"
130
+ };
131
+ } catch (error) {
132
+ if (error instanceof Error && error.message === "exit status 1") {
133
+ const actualStderr = error?.result?.stderr || "";
134
+ const isSyntaxError = actualStderr.includes("SyntaxError");
135
+ if (isSyntaxError) {
136
+ const syntaxErrorLine = actualStderr.split("\n").find((line) => line.includes("SyntaxError")) || "SyntaxError: Invalid syntax in code";
137
+ throw new Error(`Syntax error: ${syntaxErrorLine}`);
138
+ } else {
139
+ return {
140
+ stdout: "",
141
+ stderr: actualStderr || "Error: Runtime error occurred during execution",
142
+ exitCode: 1,
143
+ executionTime: Date.now() - startTime,
144
+ sandboxId: devbox.id || "runloop-unknown",
145
+ provider: "runloop"
146
+ };
147
+ }
148
+ }
149
+ if (error instanceof Error && error.message.includes("Syntax error")) {
150
+ throw error;
151
+ }
152
+ throw new Error(
153
+ `Runloop execution failed: ${error instanceof Error ? error.message : String(error)}`
154
+ );
155
+ }
93
156
  },
94
157
  runCommand: async (sandbox, command, args = []) => {
95
158
  const startTime = Date.now();
96
- const { devbox, client } = sandbox;
159
+ const devbox = sandbox;
160
+ const client = sandbox.client;
97
161
  try {
98
162
  const execution = await client.devboxes.executeAsync(devbox.id, {
99
163
  command: `${command} ${args.join(" ")}`
@@ -137,7 +201,8 @@ var runloop = createProvider({
137
201
  };
138
202
  },
139
203
  getUrl: async (sandbox, options) => {
140
- const { devbox, client } = sandbox;
204
+ const devbox = sandbox;
205
+ const client = sandbox.client;
141
206
  try {
142
207
  const tunnel = await client.devboxes.createTunnel(devbox.id, {
143
208
  port: options.port
@@ -151,26 +216,26 @@ var runloop = createProvider({
151
216
  },
152
217
  // Optional filesystem methods - using Runloop's file operations
153
218
  filesystem: {
154
- readFile: async (sandbox, path) => {
155
- const { devbox, client } = sandbox;
219
+ readFile: async (sandbox, path, runCommand) => {
156
220
  try {
157
- const result = await client.devboxes.readFileContents(devbox.id, {
158
- path
159
- });
160
- return result.content || "";
221
+ const result = await runCommand(sandbox, "cat", [path]);
222
+ if (result.exitCode !== 0) {
223
+ throw new Error(`File not found or unreadable: ${result.stderr}`);
224
+ }
225
+ return result.stdout;
161
226
  } catch (error) {
162
227
  throw new Error(
163
228
  `Failed to read file ${path}: ${error instanceof Error ? error.message : String(error)}`
164
229
  );
165
230
  }
166
231
  },
167
- writeFile: async (sandbox, path, content) => {
168
- const { devbox, client } = sandbox;
232
+ writeFile: async (sandbox, path, content, runCommand) => {
169
233
  try {
170
- await client.devboxes.writeFileContents(devbox.id, {
171
- path,
172
- content
173
- });
234
+ const encoded = Buffer.from(content).toString("base64");
235
+ const result = await runCommand(sandbox, "sh", ["-c", `echo "${encoded}" | base64 -d > "${path}"`]);
236
+ if (result.exitCode !== 0) {
237
+ throw new Error(`Command failed: ${result.stderr}`);
238
+ }
174
239
  } catch (error) {
175
240
  throw new Error(
176
241
  `Failed to write file ${path}: ${error instanceof Error ? error.message : String(error)}`
@@ -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 return {\n sandbox: dbx, \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): Promise<ExecutionResult> => {\n throw new Error(\"Please use runCommand instead\");\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, client } = sandbox;\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, client } = sandbox;\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): Promise<string> => {\n const { devbox, client } = sandbox;\n\n try {\n const result = await client.devboxes.readFileContents(devbox.id, {\n path: path,\n });\n return result.content || \"\";\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 ): Promise<void> => {\n const { devbox, client } = sandbox;\n\n try {\n await client.devboxes.writeFileContents(devbox.id, {\n path: path,\n content: content,\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 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":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@computesdk/runloop",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "Runloop provider for ComputeSDK",
5
5
  "author": "Runloop",
6
6
  "license": "MIT",