@computesdk/daytona 1.5.7 → 1.5.8

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
@@ -144,29 +144,24 @@ var daytona = (0, import_computesdk.createProvider)({
144
144
  );
145
145
  }
146
146
  },
147
- runCommand: async (sandbox, command, args = [], options) => {
147
+ runCommand: async (sandbox, command, args = []) => {
148
148
  const startTime = Date.now();
149
149
  try {
150
- const { command: finalCommand, args: finalArgs, isBackground } = (0, import_computesdk.createBackgroundCommand)(command, args, options);
151
- const quotedArgs = finalArgs.map((arg) => {
150
+ const quotedArgs = args.map((arg) => {
152
151
  if (arg.includes(" ") || arg.includes('"') || arg.includes("'") || arg.includes("$") || arg.includes("`")) {
153
152
  return `"${arg.replace(/"/g, '\\"')}"`;
154
153
  }
155
154
  return arg;
156
155
  });
157
- const fullCommand = quotedArgs.length > 0 ? `${finalCommand} ${quotedArgs.join(" ")}` : finalCommand;
156
+ const fullCommand = quotedArgs.length > 0 ? `${command} ${quotedArgs.join(" ")}` : command;
158
157
  const response = await sandbox.process.executeCommand(fullCommand);
159
158
  return {
160
159
  stdout: response.result || "",
161
160
  stderr: "",
162
- // Daytona doesn't separate stderr in the response
163
161
  exitCode: response.exitCode || 0,
164
162
  executionTime: Date.now() - startTime,
165
163
  sandboxId: sandbox.id,
166
- provider: "daytona",
167
- isBackground,
168
- // For background commands, we can't get a real PID, but we can indicate it's running
169
- ...isBackground && { pid: -1 }
164
+ provider: "daytona"
170
165
  };
171
166
  } catch (error) {
172
167
  throw new Error(
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * Daytona Provider - Factory-based Implementation\n * \n * Code execution only provider using the factory pattern.\n * Reduces ~300 lines of boilerplate to ~80 lines of core logic.\n */\n\nimport { Daytona, Sandbox as DaytonaSandbox } from '@daytonaio/sdk';\nimport { createProvider, createBackgroundCommand } from 'computesdk';\nimport type { Runtime, ExecutionResult, SandboxInfo, CreateSandboxOptions, FileEntry, RunCommandOptions } from 'computesdk';\n\n/**\n * Daytona-specific configuration options\n */\nexport interface DaytonaConfig {\n /** Daytona API key - if not provided, will fallback to DAYTONA_API_KEY environment variable */\n apiKey?: string;\n /** Default runtime environment */\n runtime?: Runtime;\n /** Execution timeout in milliseconds */\n timeout?: number;\n}\n\n/**\n * Create a Daytona provider instance using the factory pattern\n */\nexport const daytona = createProvider<DaytonaSandbox, DaytonaConfig>({\n name: 'daytona',\n methods: {\n sandbox: {\n // Collection operations (compute.sandbox.*)\n create: async (config: DaytonaConfig, options?: CreateSandboxOptions) => {\n // Validate API key\n const apiKey = config.apiKey || (typeof process !== 'undefined' && process.env?.DAYTONA_API_KEY) || '';\n\n if (!apiKey) {\n throw new Error(\n `Missing Daytona API key. Provide 'apiKey' in config or set DAYTONA_API_KEY environment variable. Get your API key from https://daytona.io/`\n );\n }\n\n const runtime = options?.runtime || config.runtime || 'node';\n\n try {\n // Initialize Daytona client\n const daytona = new Daytona({ apiKey: apiKey });\n\n let session: DaytonaSandbox;\n let sandboxId: string;\n\n if (options?.sandboxId) {\n // Reconnect to existing Daytona sandbox\n session = await daytona.get(options.sandboxId);\n sandboxId = options.sandboxId;\n } else {\n // Create new Daytona sandbox\n session = await daytona.create({\n language: runtime === 'python' ? 'python' : 'javascript',\n });\n sandboxId = session.id;\n }\n\n return {\n sandbox: session,\n sandboxId\n };\n } catch (error) {\n if (error instanceof Error) {\n if (error.message.includes('unauthorized') || error.message.includes('API key')) {\n throw new Error(\n `Daytona authentication failed. Please check your DAYTONA_API_KEY environment variable. Get your API key from https://daytona.io/`\n );\n }\n if (error.message.includes('quota') || error.message.includes('limit')) {\n throw new Error(\n `Daytona quota exceeded. Please check your usage at https://daytona.io/`\n );\n }\n }\n throw new Error(\n `Failed to create Daytona sandbox: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n getById: async (config: DaytonaConfig, sandboxId: string) => {\n const apiKey = config.apiKey || process.env.DAYTONA_API_KEY!;\n\n try {\n const daytona = new Daytona({ apiKey: apiKey });\n const session = await daytona.get(sandboxId);\n\n return {\n sandbox: session,\n sandboxId\n };\n } catch (error) {\n // Sandbox doesn't exist or can't be accessed\n return null;\n }\n },\n\n list: async (config: DaytonaConfig) => {\n const apiKey = config.apiKey || process.env.DAYTONA_API_KEY!;\n\n try {\n const daytona = new Daytona({ apiKey: apiKey });\n const sandboxes = await daytona.list();\n\n return sandboxes.map((session: any) => ({\n sandbox: session,\n sandboxId: session.id\n }));\n } catch (error) {\n // Return empty array if listing fails\n return [];\n }\n },\n\n destroy: async (config: DaytonaConfig, sandboxId: string) => {\n const apiKey = config.apiKey || process.env.DAYTONA_API_KEY!;\n\n try {\n const daytona = new Daytona({ apiKey: apiKey });\n // Note: Daytona SDK expects a Sandbox object, but we only have the ID\n // This is a limitation of the current Daytona SDK design\n // For now, we'll skip the delete operation\n const sandbox = await daytona.get(sandboxId);\n await sandbox.delete();\n } catch (error) {\n // Sandbox might already be destroyed or doesn't exist\n // This is acceptable for destroy operations\n }\n },\n\n // Instance operations (sandbox.*)\n runCode: async (sandbox: DaytonaSandbox, code: string, runtime?: Runtime): Promise<ExecutionResult> => {\n const startTime = Date.now();\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 direct command execution like Vercel for consistency\n let response;\n \n // Use base64 encoding for both runtimes for reliability and consistency\n const encoded = Buffer.from(code).toString('base64');\n \n if (effectiveRuntime === 'python') {\n response = await sandbox.process.executeCommand(`echo \"${encoded}\" | base64 -d | python3`);\n } else {\n response = await sandbox.process.executeCommand(`echo \"${encoded}\" | base64 -d | node`);\n }\n\n // Daytona always returns exitCode: 0, so we need to detect errors from output\n const output = response.result || '';\n const hasError = output.includes('Error:') || \n output.includes('error TS') || \n output.includes('SyntaxError:') ||\n output.includes('TypeError:') ||\n output.includes('ReferenceError:') ||\n output.includes('Traceback (most recent call last)');\n\n // Check for syntax errors and throw them (similar to Vercel behavior)\n if (hasError && (output.includes('SyntaxError:') || \n output.includes('invalid syntax') ||\n output.includes('Unexpected token') ||\n output.includes('Unexpected identifier') ||\n output.includes('error TS1434'))) {\n throw new Error(`Syntax error: ${output.trim()}`);\n }\n\n const actualExitCode = hasError ? 1 : (response.exitCode || 0);\n\n return {\n stdout: hasError ? '' : output,\n stderr: hasError ? output : '',\n exitCode: actualExitCode,\n executionTime: Date.now() - startTime,\n sandboxId: sandbox.id,\n provider: 'daytona'\n };\n } catch (error) {\n // Re-throw syntax errors\n if (error instanceof Error && error.message.includes('Syntax error')) {\n throw error;\n }\n throw new Error(\n `Daytona execution failed: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n runCommand: async (sandbox: DaytonaSandbox, command: string, args: string[] = [], options?: RunCommandOptions): Promise<ExecutionResult> => {\n const startTime = Date.now();\n\n try {\n // Handle background command execution\n const { command: finalCommand, args: finalArgs, isBackground } = createBackgroundCommand(command, args, options);\n\n // Construct full command with arguments, properly quoting each arg\n const quotedArgs = finalArgs.map(arg => {\n // Quote arguments that contain spaces or special characters\n if (arg.includes(' ') || arg.includes('\"') || arg.includes(\"'\") || arg.includes('$') || arg.includes('`')) {\n // Escape any double quotes in the argument and wrap in double quotes\n return `\"${arg.replace(/\"/g, '\\\\\"')}\"`;\n }\n return arg;\n });\n const fullCommand = quotedArgs.length > 0 ? `${finalCommand} ${quotedArgs.join(' ')}` : finalCommand;\n\n // Execute command using Daytona's process.executeCommand method\n const response = await sandbox.process.executeCommand(fullCommand);\n\n return {\n stdout: response.result || '',\n stderr: '', // Daytona doesn't separate stderr in the response\n exitCode: response.exitCode || 0,\n executionTime: Date.now() - startTime,\n sandboxId: sandbox.id,\n provider: 'daytona',\n isBackground,\n // For background commands, we can't get a real PID, but we can indicate it's running\n ...(isBackground && { pid: -1 })\n };\n } catch (error) {\n throw new Error(\n `Daytona command execution failed: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n getInfo: async (sandbox: DaytonaSandbox): Promise<SandboxInfo> => {\n return {\n id: sandbox.id,\n provider: 'daytona',\n runtime: 'python', // Daytona default\n status: 'running',\n createdAt: new Date(),\n timeout: 300000,\n metadata: {\n daytonaSandboxId: sandbox.id\n }\n };\n },\n\n getUrl: async (sandbox: DaytonaSandbox, options: { port: number; protocol?: string }): Promise<string> => {\n try {\n // Use Daytona's built-in getPreviewLink method\n const previewInfo = await sandbox.getPreviewLink(options.port);\n let url = previewInfo.url;\n \n // If a specific protocol is requested, replace the URL's protocol\n if (options.protocol) {\n const urlObj = new URL(url);\n urlObj.protocol = options.protocol + ':';\n url = urlObj.toString();\n }\n \n return url;\n } catch (error) {\n throw new Error(\n `Failed to get Daytona preview URL for port ${options.port}: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n // Filesystem operations via terminal commands\n filesystem: {\n readFile: async (sandbox: DaytonaSandbox, path: string): Promise<string> => {\n try {\n const response = await sandbox.process.executeCommand(`cat \"${path}\"`);\n if (response.exitCode !== 0) {\n throw new Error(`File not found or cannot be read: ${path}`);\n }\n return response.result || '';\n } catch (error) {\n throw new Error(`Failed to read file ${path}: ${error instanceof Error ? error.message : String(error)}`);\n }\n },\n\n writeFile: async (sandbox: DaytonaSandbox, path: string, content: string): Promise<void> => {\n try {\n // Use base64 encoding to safely handle special characters, newlines, and binary content\n const encoded = Buffer.from(content).toString('base64');\n const response = await sandbox.process.executeCommand(`echo \"${encoded}\" | base64 -d > \"${path}\"`);\n if (response.exitCode !== 0) {\n throw new Error(`Failed to write to file: ${path}`);\n }\n } catch (error) {\n throw new Error(`Failed to write file ${path}: ${error instanceof Error ? error.message : String(error)}`);\n }\n },\n\n mkdir: async (sandbox: DaytonaSandbox, path: string): Promise<void> => {\n try {\n const response = await sandbox.process.executeCommand(`mkdir -p \"${path}\"`);\n if (response.exitCode !== 0) {\n throw new Error(`Failed to create directory: ${path}`);\n }\n } catch (error) {\n throw new Error(`Failed to create directory ${path}: ${error instanceof Error ? error.message : String(error)}`);\n }\n },\n\n readdir: async (sandbox: DaytonaSandbox, path: string): Promise<FileEntry[]> => {\n try {\n const response = await sandbox.process.executeCommand(`ls -la \"${path}\"`);\n if (response.exitCode !== 0) {\n throw new Error(`Directory not found or cannot be read: ${path}`);\n }\n\n // Parse ls -la output into FileEntry objects\n const lines = response.result.split('\\n').filter(line => line.trim());\n const entries: FileEntry[] = [];\n\n for (const line of lines) {\n // Skip total line and current/parent directory entries\n if (line.startsWith('total ') || line.endsWith(' .') || line.endsWith(' ..')) {\n continue;\n }\n\n // Parse ls -la format: permissions links owner group size date time name\n const parts = line.trim().split(/\\s+/);\n if (parts.length >= 9) {\n const permissions = parts[0];\n const name = parts.slice(8).join(' '); // Handle filenames with spaces\n const isDirectory = permissions.startsWith('d');\n const size = parseInt(parts[4]) || 0;\n\n entries.push({\n name,\n path: `${path}/${name}`.replace(/\\/+/g, '/'), // Clean up double slashes\n isDirectory,\n size,\n lastModified: new Date() // ls -la date parsing is complex, use current time\n });\n }\n }\n\n return entries;\n } catch (error) {\n throw new Error(`Failed to read directory ${path}: ${error instanceof Error ? error.message : String(error)}`);\n }\n },\n\n exists: async (sandbox: DaytonaSandbox, path: string): Promise<boolean> => {\n try {\n const response = await sandbox.process.executeCommand(`test -e \"${path}\"`);\n return response.exitCode === 0;\n } catch (error) {\n // If command execution fails, assume file doesn't exist\n return false;\n }\n },\n\n remove: async (sandbox: DaytonaSandbox, path: string): Promise<void> => {\n try {\n const response = await sandbox.process.executeCommand(`rm -rf \"${path}\"`);\n if (response.exitCode !== 0) {\n throw new Error(`Failed to remove: ${path}`);\n }\n } catch (error) {\n throw new Error(`Failed to remove ${path}: ${error instanceof Error ? error.message : String(error)}`);\n }\n }\n },\n\n // Provider-specific typed getInstance method\n getInstance: (sandbox: DaytonaSandbox): DaytonaSandbox => {\n return sandbox;\n },\n\n // Terminal operations not implemented - Daytona session API needs verification\n\n }\n }\n});\n"],"mappings":"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","names":["daytona"]}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * Daytona Provider - Factory-based Implementation\n * \n * Code execution only provider using the factory pattern.\n * Reduces ~300 lines of boilerplate to ~80 lines of core logic.\n */\n\nimport { Daytona, Sandbox as DaytonaSandbox } from '@daytonaio/sdk';\nimport { createProvider } from 'computesdk';\nimport type { Runtime, ExecutionResult, SandboxInfo, CreateSandboxOptions, FileEntry } from 'computesdk';\n\n/**\n * Daytona-specific configuration options\n */\nexport interface DaytonaConfig {\n /** Daytona API key - if not provided, will fallback to DAYTONA_API_KEY environment variable */\n apiKey?: string;\n /** Default runtime environment */\n runtime?: Runtime;\n /** Execution timeout in milliseconds */\n timeout?: number;\n}\n\n/**\n * Create a Daytona provider instance using the factory pattern\n */\nexport const daytona = createProvider<DaytonaSandbox, DaytonaConfig>({\n name: 'daytona',\n methods: {\n sandbox: {\n // Collection operations (compute.sandbox.*)\n create: async (config: DaytonaConfig, options?: CreateSandboxOptions) => {\n // Validate API key\n const apiKey = config.apiKey || (typeof process !== 'undefined' && process.env?.DAYTONA_API_KEY) || '';\n\n if (!apiKey) {\n throw new Error(\n `Missing Daytona API key. Provide 'apiKey' in config or set DAYTONA_API_KEY environment variable. Get your API key from https://daytona.io/`\n );\n }\n\n const runtime = options?.runtime || config.runtime || 'node';\n\n try {\n // Initialize Daytona client\n const daytona = new Daytona({ apiKey: apiKey });\n\n let session: DaytonaSandbox;\n let sandboxId: string;\n\n if (options?.sandboxId) {\n // Reconnect to existing Daytona sandbox\n session = await daytona.get(options.sandboxId);\n sandboxId = options.sandboxId;\n } else {\n // Create new Daytona sandbox\n session = await daytona.create({\n language: runtime === 'python' ? 'python' : 'javascript',\n });\n sandboxId = session.id;\n }\n\n return {\n sandbox: session,\n sandboxId\n };\n } catch (error) {\n if (error instanceof Error) {\n if (error.message.includes('unauthorized') || error.message.includes('API key')) {\n throw new Error(\n `Daytona authentication failed. Please check your DAYTONA_API_KEY environment variable. Get your API key from https://daytona.io/`\n );\n }\n if (error.message.includes('quota') || error.message.includes('limit')) {\n throw new Error(\n `Daytona quota exceeded. Please check your usage at https://daytona.io/`\n );\n }\n }\n throw new Error(\n `Failed to create Daytona sandbox: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n getById: async (config: DaytonaConfig, sandboxId: string) => {\n const apiKey = config.apiKey || process.env.DAYTONA_API_KEY!;\n\n try {\n const daytona = new Daytona({ apiKey: apiKey });\n const session = await daytona.get(sandboxId);\n\n return {\n sandbox: session,\n sandboxId\n };\n } catch (error) {\n // Sandbox doesn't exist or can't be accessed\n return null;\n }\n },\n\n list: async (config: DaytonaConfig) => {\n const apiKey = config.apiKey || process.env.DAYTONA_API_KEY!;\n\n try {\n const daytona = new Daytona({ apiKey: apiKey });\n const sandboxes = await daytona.list();\n\n return sandboxes.map((session: any) => ({\n sandbox: session,\n sandboxId: session.id\n }));\n } catch (error) {\n // Return empty array if listing fails\n return [];\n }\n },\n\n destroy: async (config: DaytonaConfig, sandboxId: string) => {\n const apiKey = config.apiKey || process.env.DAYTONA_API_KEY!;\n\n try {\n const daytona = new Daytona({ apiKey: apiKey });\n // Note: Daytona SDK expects a Sandbox object, but we only have the ID\n // This is a limitation of the current Daytona SDK design\n // For now, we'll skip the delete operation\n const sandbox = await daytona.get(sandboxId);\n await sandbox.delete();\n } catch (error) {\n // Sandbox might already be destroyed or doesn't exist\n // This is acceptable for destroy operations\n }\n },\n\n // Instance operations (sandbox.*)\n runCode: async (sandbox: DaytonaSandbox, code: string, runtime?: Runtime): Promise<ExecutionResult> => {\n const startTime = Date.now();\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 direct command execution like Vercel for consistency\n let response;\n \n // Use base64 encoding for both runtimes for reliability and consistency\n const encoded = Buffer.from(code).toString('base64');\n \n if (effectiveRuntime === 'python') {\n response = await sandbox.process.executeCommand(`echo \"${encoded}\" | base64 -d | python3`);\n } else {\n response = await sandbox.process.executeCommand(`echo \"${encoded}\" | base64 -d | node`);\n }\n\n // Daytona always returns exitCode: 0, so we need to detect errors from output\n const output = response.result || '';\n const hasError = output.includes('Error:') || \n output.includes('error TS') || \n output.includes('SyntaxError:') ||\n output.includes('TypeError:') ||\n output.includes('ReferenceError:') ||\n output.includes('Traceback (most recent call last)');\n\n // Check for syntax errors and throw them (similar to Vercel behavior)\n if (hasError && (output.includes('SyntaxError:') || \n output.includes('invalid syntax') ||\n output.includes('Unexpected token') ||\n output.includes('Unexpected identifier') ||\n output.includes('error TS1434'))) {\n throw new Error(`Syntax error: ${output.trim()}`);\n }\n\n const actualExitCode = hasError ? 1 : (response.exitCode || 0);\n\n return {\n stdout: hasError ? '' : output,\n stderr: hasError ? output : '',\n exitCode: actualExitCode,\n executionTime: Date.now() - startTime,\n sandboxId: sandbox.id,\n provider: 'daytona'\n };\n } catch (error) {\n // Re-throw syntax errors\n if (error instanceof Error && error.message.includes('Syntax error')) {\n throw error;\n }\n throw new Error(\n `Daytona execution failed: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n runCommand: async (sandbox: DaytonaSandbox, command: string, args: string[] = []): Promise<ExecutionResult> => {\n const startTime = Date.now();\n\n try {\n // Construct full command with arguments, properly quoting each arg\n const quotedArgs = args.map((arg: string) => {\n if (arg.includes(' ') || arg.includes('\"') || arg.includes(\"'\") || arg.includes('$') || arg.includes('`')) {\n return `\"${arg.replace(/\"/g, '\\\\\"')}\"`;\n }\n return arg;\n });\n const fullCommand = quotedArgs.length > 0 ? `${command} ${quotedArgs.join(' ')}` : command;\n\n // Execute command using Daytona's process.executeCommand method\n const response = await sandbox.process.executeCommand(fullCommand);\n\n return {\n stdout: response.result || '',\n stderr: '',\n exitCode: response.exitCode || 0,\n executionTime: Date.now() - startTime,\n sandboxId: sandbox.id,\n provider: 'daytona'\n };\n } catch (error) {\n throw new Error(\n `Daytona command execution failed: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n getInfo: async (sandbox: DaytonaSandbox): Promise<SandboxInfo> => {\n return {\n id: sandbox.id,\n provider: 'daytona',\n runtime: 'python', // Daytona default\n status: 'running',\n createdAt: new Date(),\n timeout: 300000,\n metadata: {\n daytonaSandboxId: sandbox.id\n }\n };\n },\n\n getUrl: async (sandbox: DaytonaSandbox, options: { port: number; protocol?: string }): Promise<string> => {\n try {\n // Use Daytona's built-in getPreviewLink method\n const previewInfo = await sandbox.getPreviewLink(options.port);\n let url = previewInfo.url;\n \n // If a specific protocol is requested, replace the URL's protocol\n if (options.protocol) {\n const urlObj = new URL(url);\n urlObj.protocol = options.protocol + ':';\n url = urlObj.toString();\n }\n \n return url;\n } catch (error) {\n throw new Error(\n `Failed to get Daytona preview URL for port ${options.port}: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n // Filesystem operations via terminal commands\n filesystem: {\n readFile: async (sandbox: DaytonaSandbox, path: string): Promise<string> => {\n try {\n const response = await sandbox.process.executeCommand(`cat \"${path}\"`);\n if (response.exitCode !== 0) {\n throw new Error(`File not found or cannot be read: ${path}`);\n }\n return response.result || '';\n } catch (error) {\n throw new Error(`Failed to read file ${path}: ${error instanceof Error ? error.message : String(error)}`);\n }\n },\n\n writeFile: async (sandbox: DaytonaSandbox, path: string, content: string): Promise<void> => {\n try {\n // Use base64 encoding to safely handle special characters, newlines, and binary content\n const encoded = Buffer.from(content).toString('base64');\n const response = await sandbox.process.executeCommand(`echo \"${encoded}\" | base64 -d > \"${path}\"`);\n if (response.exitCode !== 0) {\n throw new Error(`Failed to write to file: ${path}`);\n }\n } catch (error) {\n throw new Error(`Failed to write file ${path}: ${error instanceof Error ? error.message : String(error)}`);\n }\n },\n\n mkdir: async (sandbox: DaytonaSandbox, path: string): Promise<void> => {\n try {\n const response = await sandbox.process.executeCommand(`mkdir -p \"${path}\"`);\n if (response.exitCode !== 0) {\n throw new Error(`Failed to create directory: ${path}`);\n }\n } catch (error) {\n throw new Error(`Failed to create directory ${path}: ${error instanceof Error ? error.message : String(error)}`);\n }\n },\n\n readdir: async (sandbox: DaytonaSandbox, path: string): Promise<FileEntry[]> => {\n try {\n const response = await sandbox.process.executeCommand(`ls -la \"${path}\"`);\n if (response.exitCode !== 0) {\n throw new Error(`Directory not found or cannot be read: ${path}`);\n }\n\n // Parse ls -la output into FileEntry objects\n const lines = response.result.split('\\n').filter(line => line.trim());\n const entries: FileEntry[] = [];\n\n for (const line of lines) {\n // Skip total line and current/parent directory entries\n if (line.startsWith('total ') || line.endsWith(' .') || line.endsWith(' ..')) {\n continue;\n }\n\n // Parse ls -la format: permissions links owner group size date time name\n const parts = line.trim().split(/\\s+/);\n if (parts.length >= 9) {\n const permissions = parts[0];\n const name = parts.slice(8).join(' '); // Handle filenames with spaces\n const isDirectory = permissions.startsWith('d');\n const size = parseInt(parts[4]) || 0;\n\n entries.push({\n name,\n path: `${path}/${name}`.replace(/\\/+/g, '/'), // Clean up double slashes\n isDirectory,\n size,\n lastModified: new Date() // ls -la date parsing is complex, use current time\n });\n }\n }\n\n return entries;\n } catch (error) {\n throw new Error(`Failed to read directory ${path}: ${error instanceof Error ? error.message : String(error)}`);\n }\n },\n\n exists: async (sandbox: DaytonaSandbox, path: string): Promise<boolean> => {\n try {\n const response = await sandbox.process.executeCommand(`test -e \"${path}\"`);\n return response.exitCode === 0;\n } catch (error) {\n // If command execution fails, assume file doesn't exist\n return false;\n }\n },\n\n remove: async (sandbox: DaytonaSandbox, path: string): Promise<void> => {\n try {\n const response = await sandbox.process.executeCommand(`rm -rf \"${path}\"`);\n if (response.exitCode !== 0) {\n throw new Error(`Failed to remove: ${path}`);\n }\n } catch (error) {\n throw new Error(`Failed to remove ${path}: ${error instanceof Error ? error.message : String(error)}`);\n }\n }\n },\n\n // Provider-specific typed getInstance method\n getInstance: (sandbox: DaytonaSandbox): DaytonaSandbox => {\n return sandbox;\n },\n\n // Terminal operations not implemented - Daytona session API needs verification\n\n }\n }\n});\n"],"mappings":"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","names":["daytona"]}
package/dist/index.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  // src/index.ts
2
2
  import { Daytona } from "@daytonaio/sdk";
3
- import { createProvider, createBackgroundCommand } from "computesdk";
3
+ import { createProvider } from "computesdk";
4
4
  var daytona = createProvider({
5
5
  name: "daytona",
6
6
  methods: {
@@ -120,29 +120,24 @@ var daytona = createProvider({
120
120
  );
121
121
  }
122
122
  },
123
- runCommand: async (sandbox, command, args = [], options) => {
123
+ runCommand: async (sandbox, command, args = []) => {
124
124
  const startTime = Date.now();
125
125
  try {
126
- const { command: finalCommand, args: finalArgs, isBackground } = createBackgroundCommand(command, args, options);
127
- const quotedArgs = finalArgs.map((arg) => {
126
+ const quotedArgs = args.map((arg) => {
128
127
  if (arg.includes(" ") || arg.includes('"') || arg.includes("'") || arg.includes("$") || arg.includes("`")) {
129
128
  return `"${arg.replace(/"/g, '\\"')}"`;
130
129
  }
131
130
  return arg;
132
131
  });
133
- const fullCommand = quotedArgs.length > 0 ? `${finalCommand} ${quotedArgs.join(" ")}` : finalCommand;
132
+ const fullCommand = quotedArgs.length > 0 ? `${command} ${quotedArgs.join(" ")}` : command;
134
133
  const response = await sandbox.process.executeCommand(fullCommand);
135
134
  return {
136
135
  stdout: response.result || "",
137
136
  stderr: "",
138
- // Daytona doesn't separate stderr in the response
139
137
  exitCode: response.exitCode || 0,
140
138
  executionTime: Date.now() - startTime,
141
139
  sandboxId: sandbox.id,
142
- provider: "daytona",
143
- isBackground,
144
- // For background commands, we can't get a real PID, but we can indicate it's running
145
- ...isBackground && { pid: -1 }
140
+ provider: "daytona"
146
141
  };
147
142
  } catch (error) {
148
143
  throw new Error(
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * Daytona Provider - Factory-based Implementation\n * \n * Code execution only provider using the factory pattern.\n * Reduces ~300 lines of boilerplate to ~80 lines of core logic.\n */\n\nimport { Daytona, Sandbox as DaytonaSandbox } from '@daytonaio/sdk';\nimport { createProvider, createBackgroundCommand } from 'computesdk';\nimport type { Runtime, ExecutionResult, SandboxInfo, CreateSandboxOptions, FileEntry, RunCommandOptions } from 'computesdk';\n\n/**\n * Daytona-specific configuration options\n */\nexport interface DaytonaConfig {\n /** Daytona API key - if not provided, will fallback to DAYTONA_API_KEY environment variable */\n apiKey?: string;\n /** Default runtime environment */\n runtime?: Runtime;\n /** Execution timeout in milliseconds */\n timeout?: number;\n}\n\n/**\n * Create a Daytona provider instance using the factory pattern\n */\nexport const daytona = createProvider<DaytonaSandbox, DaytonaConfig>({\n name: 'daytona',\n methods: {\n sandbox: {\n // Collection operations (compute.sandbox.*)\n create: async (config: DaytonaConfig, options?: CreateSandboxOptions) => {\n // Validate API key\n const apiKey = config.apiKey || (typeof process !== 'undefined' && process.env?.DAYTONA_API_KEY) || '';\n\n if (!apiKey) {\n throw new Error(\n `Missing Daytona API key. Provide 'apiKey' in config or set DAYTONA_API_KEY environment variable. Get your API key from https://daytona.io/`\n );\n }\n\n const runtime = options?.runtime || config.runtime || 'node';\n\n try {\n // Initialize Daytona client\n const daytona = new Daytona({ apiKey: apiKey });\n\n let session: DaytonaSandbox;\n let sandboxId: string;\n\n if (options?.sandboxId) {\n // Reconnect to existing Daytona sandbox\n session = await daytona.get(options.sandboxId);\n sandboxId = options.sandboxId;\n } else {\n // Create new Daytona sandbox\n session = await daytona.create({\n language: runtime === 'python' ? 'python' : 'javascript',\n });\n sandboxId = session.id;\n }\n\n return {\n sandbox: session,\n sandboxId\n };\n } catch (error) {\n if (error instanceof Error) {\n if (error.message.includes('unauthorized') || error.message.includes('API key')) {\n throw new Error(\n `Daytona authentication failed. Please check your DAYTONA_API_KEY environment variable. Get your API key from https://daytona.io/`\n );\n }\n if (error.message.includes('quota') || error.message.includes('limit')) {\n throw new Error(\n `Daytona quota exceeded. Please check your usage at https://daytona.io/`\n );\n }\n }\n throw new Error(\n `Failed to create Daytona sandbox: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n getById: async (config: DaytonaConfig, sandboxId: string) => {\n const apiKey = config.apiKey || process.env.DAYTONA_API_KEY!;\n\n try {\n const daytona = new Daytona({ apiKey: apiKey });\n const session = await daytona.get(sandboxId);\n\n return {\n sandbox: session,\n sandboxId\n };\n } catch (error) {\n // Sandbox doesn't exist or can't be accessed\n return null;\n }\n },\n\n list: async (config: DaytonaConfig) => {\n const apiKey = config.apiKey || process.env.DAYTONA_API_KEY!;\n\n try {\n const daytona = new Daytona({ apiKey: apiKey });\n const sandboxes = await daytona.list();\n\n return sandboxes.map((session: any) => ({\n sandbox: session,\n sandboxId: session.id\n }));\n } catch (error) {\n // Return empty array if listing fails\n return [];\n }\n },\n\n destroy: async (config: DaytonaConfig, sandboxId: string) => {\n const apiKey = config.apiKey || process.env.DAYTONA_API_KEY!;\n\n try {\n const daytona = new Daytona({ apiKey: apiKey });\n // Note: Daytona SDK expects a Sandbox object, but we only have the ID\n // This is a limitation of the current Daytona SDK design\n // For now, we'll skip the delete operation\n const sandbox = await daytona.get(sandboxId);\n await sandbox.delete();\n } catch (error) {\n // Sandbox might already be destroyed or doesn't exist\n // This is acceptable for destroy operations\n }\n },\n\n // Instance operations (sandbox.*)\n runCode: async (sandbox: DaytonaSandbox, code: string, runtime?: Runtime): Promise<ExecutionResult> => {\n const startTime = Date.now();\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 direct command execution like Vercel for consistency\n let response;\n \n // Use base64 encoding for both runtimes for reliability and consistency\n const encoded = Buffer.from(code).toString('base64');\n \n if (effectiveRuntime === 'python') {\n response = await sandbox.process.executeCommand(`echo \"${encoded}\" | base64 -d | python3`);\n } else {\n response = await sandbox.process.executeCommand(`echo \"${encoded}\" | base64 -d | node`);\n }\n\n // Daytona always returns exitCode: 0, so we need to detect errors from output\n const output = response.result || '';\n const hasError = output.includes('Error:') || \n output.includes('error TS') || \n output.includes('SyntaxError:') ||\n output.includes('TypeError:') ||\n output.includes('ReferenceError:') ||\n output.includes('Traceback (most recent call last)');\n\n // Check for syntax errors and throw them (similar to Vercel behavior)\n if (hasError && (output.includes('SyntaxError:') || \n output.includes('invalid syntax') ||\n output.includes('Unexpected token') ||\n output.includes('Unexpected identifier') ||\n output.includes('error TS1434'))) {\n throw new Error(`Syntax error: ${output.trim()}`);\n }\n\n const actualExitCode = hasError ? 1 : (response.exitCode || 0);\n\n return {\n stdout: hasError ? '' : output,\n stderr: hasError ? output : '',\n exitCode: actualExitCode,\n executionTime: Date.now() - startTime,\n sandboxId: sandbox.id,\n provider: 'daytona'\n };\n } catch (error) {\n // Re-throw syntax errors\n if (error instanceof Error && error.message.includes('Syntax error')) {\n throw error;\n }\n throw new Error(\n `Daytona execution failed: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n runCommand: async (sandbox: DaytonaSandbox, command: string, args: string[] = [], options?: RunCommandOptions): Promise<ExecutionResult> => {\n const startTime = Date.now();\n\n try {\n // Handle background command execution\n const { command: finalCommand, args: finalArgs, isBackground } = createBackgroundCommand(command, args, options);\n\n // Construct full command with arguments, properly quoting each arg\n const quotedArgs = finalArgs.map(arg => {\n // Quote arguments that contain spaces or special characters\n if (arg.includes(' ') || arg.includes('\"') || arg.includes(\"'\") || arg.includes('$') || arg.includes('`')) {\n // Escape any double quotes in the argument and wrap in double quotes\n return `\"${arg.replace(/\"/g, '\\\\\"')}\"`;\n }\n return arg;\n });\n const fullCommand = quotedArgs.length > 0 ? `${finalCommand} ${quotedArgs.join(' ')}` : finalCommand;\n\n // Execute command using Daytona's process.executeCommand method\n const response = await sandbox.process.executeCommand(fullCommand);\n\n return {\n stdout: response.result || '',\n stderr: '', // Daytona doesn't separate stderr in the response\n exitCode: response.exitCode || 0,\n executionTime: Date.now() - startTime,\n sandboxId: sandbox.id,\n provider: 'daytona',\n isBackground,\n // For background commands, we can't get a real PID, but we can indicate it's running\n ...(isBackground && { pid: -1 })\n };\n } catch (error) {\n throw new Error(\n `Daytona command execution failed: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n getInfo: async (sandbox: DaytonaSandbox): Promise<SandboxInfo> => {\n return {\n id: sandbox.id,\n provider: 'daytona',\n runtime: 'python', // Daytona default\n status: 'running',\n createdAt: new Date(),\n timeout: 300000,\n metadata: {\n daytonaSandboxId: sandbox.id\n }\n };\n },\n\n getUrl: async (sandbox: DaytonaSandbox, options: { port: number; protocol?: string }): Promise<string> => {\n try {\n // Use Daytona's built-in getPreviewLink method\n const previewInfo = await sandbox.getPreviewLink(options.port);\n let url = previewInfo.url;\n \n // If a specific protocol is requested, replace the URL's protocol\n if (options.protocol) {\n const urlObj = new URL(url);\n urlObj.protocol = options.protocol + ':';\n url = urlObj.toString();\n }\n \n return url;\n } catch (error) {\n throw new Error(\n `Failed to get Daytona preview URL for port ${options.port}: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n // Filesystem operations via terminal commands\n filesystem: {\n readFile: async (sandbox: DaytonaSandbox, path: string): Promise<string> => {\n try {\n const response = await sandbox.process.executeCommand(`cat \"${path}\"`);\n if (response.exitCode !== 0) {\n throw new Error(`File not found or cannot be read: ${path}`);\n }\n return response.result || '';\n } catch (error) {\n throw new Error(`Failed to read file ${path}: ${error instanceof Error ? error.message : String(error)}`);\n }\n },\n\n writeFile: async (sandbox: DaytonaSandbox, path: string, content: string): Promise<void> => {\n try {\n // Use base64 encoding to safely handle special characters, newlines, and binary content\n const encoded = Buffer.from(content).toString('base64');\n const response = await sandbox.process.executeCommand(`echo \"${encoded}\" | base64 -d > \"${path}\"`);\n if (response.exitCode !== 0) {\n throw new Error(`Failed to write to file: ${path}`);\n }\n } catch (error) {\n throw new Error(`Failed to write file ${path}: ${error instanceof Error ? error.message : String(error)}`);\n }\n },\n\n mkdir: async (sandbox: DaytonaSandbox, path: string): Promise<void> => {\n try {\n const response = await sandbox.process.executeCommand(`mkdir -p \"${path}\"`);\n if (response.exitCode !== 0) {\n throw new Error(`Failed to create directory: ${path}`);\n }\n } catch (error) {\n throw new Error(`Failed to create directory ${path}: ${error instanceof Error ? error.message : String(error)}`);\n }\n },\n\n readdir: async (sandbox: DaytonaSandbox, path: string): Promise<FileEntry[]> => {\n try {\n const response = await sandbox.process.executeCommand(`ls -la \"${path}\"`);\n if (response.exitCode !== 0) {\n throw new Error(`Directory not found or cannot be read: ${path}`);\n }\n\n // Parse ls -la output into FileEntry objects\n const lines = response.result.split('\\n').filter(line => line.trim());\n const entries: FileEntry[] = [];\n\n for (const line of lines) {\n // Skip total line and current/parent directory entries\n if (line.startsWith('total ') || line.endsWith(' .') || line.endsWith(' ..')) {\n continue;\n }\n\n // Parse ls -la format: permissions links owner group size date time name\n const parts = line.trim().split(/\\s+/);\n if (parts.length >= 9) {\n const permissions = parts[0];\n const name = parts.slice(8).join(' '); // Handle filenames with spaces\n const isDirectory = permissions.startsWith('d');\n const size = parseInt(parts[4]) || 0;\n\n entries.push({\n name,\n path: `${path}/${name}`.replace(/\\/+/g, '/'), // Clean up double slashes\n isDirectory,\n size,\n lastModified: new Date() // ls -la date parsing is complex, use current time\n });\n }\n }\n\n return entries;\n } catch (error) {\n throw new Error(`Failed to read directory ${path}: ${error instanceof Error ? error.message : String(error)}`);\n }\n },\n\n exists: async (sandbox: DaytonaSandbox, path: string): Promise<boolean> => {\n try {\n const response = await sandbox.process.executeCommand(`test -e \"${path}\"`);\n return response.exitCode === 0;\n } catch (error) {\n // If command execution fails, assume file doesn't exist\n return false;\n }\n },\n\n remove: async (sandbox: DaytonaSandbox, path: string): Promise<void> => {\n try {\n const response = await sandbox.process.executeCommand(`rm -rf \"${path}\"`);\n if (response.exitCode !== 0) {\n throw new Error(`Failed to remove: ${path}`);\n }\n } catch (error) {\n throw new Error(`Failed to remove ${path}: ${error instanceof Error ? error.message : String(error)}`);\n }\n }\n },\n\n // Provider-specific typed getInstance method\n getInstance: (sandbox: DaytonaSandbox): DaytonaSandbox => {\n return sandbox;\n },\n\n // Terminal operations not implemented - Daytona session API needs verification\n\n }\n }\n});\n"],"mappings":"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","names":["daytona"]}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * Daytona Provider - Factory-based Implementation\n * \n * Code execution only provider using the factory pattern.\n * Reduces ~300 lines of boilerplate to ~80 lines of core logic.\n */\n\nimport { Daytona, Sandbox as DaytonaSandbox } from '@daytonaio/sdk';\nimport { createProvider } from 'computesdk';\nimport type { Runtime, ExecutionResult, SandboxInfo, CreateSandboxOptions, FileEntry } from 'computesdk';\n\n/**\n * Daytona-specific configuration options\n */\nexport interface DaytonaConfig {\n /** Daytona API key - if not provided, will fallback to DAYTONA_API_KEY environment variable */\n apiKey?: string;\n /** Default runtime environment */\n runtime?: Runtime;\n /** Execution timeout in milliseconds */\n timeout?: number;\n}\n\n/**\n * Create a Daytona provider instance using the factory pattern\n */\nexport const daytona = createProvider<DaytonaSandbox, DaytonaConfig>({\n name: 'daytona',\n methods: {\n sandbox: {\n // Collection operations (compute.sandbox.*)\n create: async (config: DaytonaConfig, options?: CreateSandboxOptions) => {\n // Validate API key\n const apiKey = config.apiKey || (typeof process !== 'undefined' && process.env?.DAYTONA_API_KEY) || '';\n\n if (!apiKey) {\n throw new Error(\n `Missing Daytona API key. Provide 'apiKey' in config or set DAYTONA_API_KEY environment variable. Get your API key from https://daytona.io/`\n );\n }\n\n const runtime = options?.runtime || config.runtime || 'node';\n\n try {\n // Initialize Daytona client\n const daytona = new Daytona({ apiKey: apiKey });\n\n let session: DaytonaSandbox;\n let sandboxId: string;\n\n if (options?.sandboxId) {\n // Reconnect to existing Daytona sandbox\n session = await daytona.get(options.sandboxId);\n sandboxId = options.sandboxId;\n } else {\n // Create new Daytona sandbox\n session = await daytona.create({\n language: runtime === 'python' ? 'python' : 'javascript',\n });\n sandboxId = session.id;\n }\n\n return {\n sandbox: session,\n sandboxId\n };\n } catch (error) {\n if (error instanceof Error) {\n if (error.message.includes('unauthorized') || error.message.includes('API key')) {\n throw new Error(\n `Daytona authentication failed. Please check your DAYTONA_API_KEY environment variable. Get your API key from https://daytona.io/`\n );\n }\n if (error.message.includes('quota') || error.message.includes('limit')) {\n throw new Error(\n `Daytona quota exceeded. Please check your usage at https://daytona.io/`\n );\n }\n }\n throw new Error(\n `Failed to create Daytona sandbox: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n getById: async (config: DaytonaConfig, sandboxId: string) => {\n const apiKey = config.apiKey || process.env.DAYTONA_API_KEY!;\n\n try {\n const daytona = new Daytona({ apiKey: apiKey });\n const session = await daytona.get(sandboxId);\n\n return {\n sandbox: session,\n sandboxId\n };\n } catch (error) {\n // Sandbox doesn't exist or can't be accessed\n return null;\n }\n },\n\n list: async (config: DaytonaConfig) => {\n const apiKey = config.apiKey || process.env.DAYTONA_API_KEY!;\n\n try {\n const daytona = new Daytona({ apiKey: apiKey });\n const sandboxes = await daytona.list();\n\n return sandboxes.map((session: any) => ({\n sandbox: session,\n sandboxId: session.id\n }));\n } catch (error) {\n // Return empty array if listing fails\n return [];\n }\n },\n\n destroy: async (config: DaytonaConfig, sandboxId: string) => {\n const apiKey = config.apiKey || process.env.DAYTONA_API_KEY!;\n\n try {\n const daytona = new Daytona({ apiKey: apiKey });\n // Note: Daytona SDK expects a Sandbox object, but we only have the ID\n // This is a limitation of the current Daytona SDK design\n // For now, we'll skip the delete operation\n const sandbox = await daytona.get(sandboxId);\n await sandbox.delete();\n } catch (error) {\n // Sandbox might already be destroyed or doesn't exist\n // This is acceptable for destroy operations\n }\n },\n\n // Instance operations (sandbox.*)\n runCode: async (sandbox: DaytonaSandbox, code: string, runtime?: Runtime): Promise<ExecutionResult> => {\n const startTime = Date.now();\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 direct command execution like Vercel for consistency\n let response;\n \n // Use base64 encoding for both runtimes for reliability and consistency\n const encoded = Buffer.from(code).toString('base64');\n \n if (effectiveRuntime === 'python') {\n response = await sandbox.process.executeCommand(`echo \"${encoded}\" | base64 -d | python3`);\n } else {\n response = await sandbox.process.executeCommand(`echo \"${encoded}\" | base64 -d | node`);\n }\n\n // Daytona always returns exitCode: 0, so we need to detect errors from output\n const output = response.result || '';\n const hasError = output.includes('Error:') || \n output.includes('error TS') || \n output.includes('SyntaxError:') ||\n output.includes('TypeError:') ||\n output.includes('ReferenceError:') ||\n output.includes('Traceback (most recent call last)');\n\n // Check for syntax errors and throw them (similar to Vercel behavior)\n if (hasError && (output.includes('SyntaxError:') || \n output.includes('invalid syntax') ||\n output.includes('Unexpected token') ||\n output.includes('Unexpected identifier') ||\n output.includes('error TS1434'))) {\n throw new Error(`Syntax error: ${output.trim()}`);\n }\n\n const actualExitCode = hasError ? 1 : (response.exitCode || 0);\n\n return {\n stdout: hasError ? '' : output,\n stderr: hasError ? output : '',\n exitCode: actualExitCode,\n executionTime: Date.now() - startTime,\n sandboxId: sandbox.id,\n provider: 'daytona'\n };\n } catch (error) {\n // Re-throw syntax errors\n if (error instanceof Error && error.message.includes('Syntax error')) {\n throw error;\n }\n throw new Error(\n `Daytona execution failed: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n runCommand: async (sandbox: DaytonaSandbox, command: string, args: string[] = []): Promise<ExecutionResult> => {\n const startTime = Date.now();\n\n try {\n // Construct full command with arguments, properly quoting each arg\n const quotedArgs = args.map((arg: string) => {\n if (arg.includes(' ') || arg.includes('\"') || arg.includes(\"'\") || arg.includes('$') || arg.includes('`')) {\n return `\"${arg.replace(/\"/g, '\\\\\"')}\"`;\n }\n return arg;\n });\n const fullCommand = quotedArgs.length > 0 ? `${command} ${quotedArgs.join(' ')}` : command;\n\n // Execute command using Daytona's process.executeCommand method\n const response = await sandbox.process.executeCommand(fullCommand);\n\n return {\n stdout: response.result || '',\n stderr: '',\n exitCode: response.exitCode || 0,\n executionTime: Date.now() - startTime,\n sandboxId: sandbox.id,\n provider: 'daytona'\n };\n } catch (error) {\n throw new Error(\n `Daytona command execution failed: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n getInfo: async (sandbox: DaytonaSandbox): Promise<SandboxInfo> => {\n return {\n id: sandbox.id,\n provider: 'daytona',\n runtime: 'python', // Daytona default\n status: 'running',\n createdAt: new Date(),\n timeout: 300000,\n metadata: {\n daytonaSandboxId: sandbox.id\n }\n };\n },\n\n getUrl: async (sandbox: DaytonaSandbox, options: { port: number; protocol?: string }): Promise<string> => {\n try {\n // Use Daytona's built-in getPreviewLink method\n const previewInfo = await sandbox.getPreviewLink(options.port);\n let url = previewInfo.url;\n \n // If a specific protocol is requested, replace the URL's protocol\n if (options.protocol) {\n const urlObj = new URL(url);\n urlObj.protocol = options.protocol + ':';\n url = urlObj.toString();\n }\n \n return url;\n } catch (error) {\n throw new Error(\n `Failed to get Daytona preview URL for port ${options.port}: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n // Filesystem operations via terminal commands\n filesystem: {\n readFile: async (sandbox: DaytonaSandbox, path: string): Promise<string> => {\n try {\n const response = await sandbox.process.executeCommand(`cat \"${path}\"`);\n if (response.exitCode !== 0) {\n throw new Error(`File not found or cannot be read: ${path}`);\n }\n return response.result || '';\n } catch (error) {\n throw new Error(`Failed to read file ${path}: ${error instanceof Error ? error.message : String(error)}`);\n }\n },\n\n writeFile: async (sandbox: DaytonaSandbox, path: string, content: string): Promise<void> => {\n try {\n // Use base64 encoding to safely handle special characters, newlines, and binary content\n const encoded = Buffer.from(content).toString('base64');\n const response = await sandbox.process.executeCommand(`echo \"${encoded}\" | base64 -d > \"${path}\"`);\n if (response.exitCode !== 0) {\n throw new Error(`Failed to write to file: ${path}`);\n }\n } catch (error) {\n throw new Error(`Failed to write file ${path}: ${error instanceof Error ? error.message : String(error)}`);\n }\n },\n\n mkdir: async (sandbox: DaytonaSandbox, path: string): Promise<void> => {\n try {\n const response = await sandbox.process.executeCommand(`mkdir -p \"${path}\"`);\n if (response.exitCode !== 0) {\n throw new Error(`Failed to create directory: ${path}`);\n }\n } catch (error) {\n throw new Error(`Failed to create directory ${path}: ${error instanceof Error ? error.message : String(error)}`);\n }\n },\n\n readdir: async (sandbox: DaytonaSandbox, path: string): Promise<FileEntry[]> => {\n try {\n const response = await sandbox.process.executeCommand(`ls -la \"${path}\"`);\n if (response.exitCode !== 0) {\n throw new Error(`Directory not found or cannot be read: ${path}`);\n }\n\n // Parse ls -la output into FileEntry objects\n const lines = response.result.split('\\n').filter(line => line.trim());\n const entries: FileEntry[] = [];\n\n for (const line of lines) {\n // Skip total line and current/parent directory entries\n if (line.startsWith('total ') || line.endsWith(' .') || line.endsWith(' ..')) {\n continue;\n }\n\n // Parse ls -la format: permissions links owner group size date time name\n const parts = line.trim().split(/\\s+/);\n if (parts.length >= 9) {\n const permissions = parts[0];\n const name = parts.slice(8).join(' '); // Handle filenames with spaces\n const isDirectory = permissions.startsWith('d');\n const size = parseInt(parts[4]) || 0;\n\n entries.push({\n name,\n path: `${path}/${name}`.replace(/\\/+/g, '/'), // Clean up double slashes\n isDirectory,\n size,\n lastModified: new Date() // ls -la date parsing is complex, use current time\n });\n }\n }\n\n return entries;\n } catch (error) {\n throw new Error(`Failed to read directory ${path}: ${error instanceof Error ? error.message : String(error)}`);\n }\n },\n\n exists: async (sandbox: DaytonaSandbox, path: string): Promise<boolean> => {\n try {\n const response = await sandbox.process.executeCommand(`test -e \"${path}\"`);\n return response.exitCode === 0;\n } catch (error) {\n // If command execution fails, assume file doesn't exist\n return false;\n }\n },\n\n remove: async (sandbox: DaytonaSandbox, path: string): Promise<void> => {\n try {\n const response = await sandbox.process.executeCommand(`rm -rf \"${path}\"`);\n if (response.exitCode !== 0) {\n throw new Error(`Failed to remove: ${path}`);\n }\n } catch (error) {\n throw new Error(`Failed to remove ${path}: ${error instanceof Error ? error.message : String(error)}`);\n }\n }\n },\n\n // Provider-specific typed getInstance method\n getInstance: (sandbox: DaytonaSandbox): DaytonaSandbox => {\n return sandbox;\n },\n\n // Terminal operations not implemented - Daytona session API needs verification\n\n }\n }\n});\n"],"mappings":"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","names":["daytona"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@computesdk/daytona",
3
- "version": "1.5.7",
3
+ "version": "1.5.8",
4
4
  "description": "Daytona provider for ComputeSDK",
5
5
  "author": "Garrison",
6
6
  "license": "MIT",
@@ -19,7 +19,7 @@
19
19
  ],
20
20
  "dependencies": {
21
21
  "@daytonaio/sdk": "^0.25.0",
22
- "computesdk": "1.8.7"
22
+ "computesdk": "1.8.8"
23
23
  },
24
24
  "keywords": [
25
25
  "daytona",