@computesdk/daytona 1.6.7 → 1.6.9

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/README.md CHANGED
@@ -8,43 +8,42 @@ Daytona provider for ComputeSDK - Execute code in Daytona development workspaces
8
8
  npm install @computesdk/daytona
9
9
  ```
10
10
 
11
- ## Usage
11
+ ## Quick Start
12
12
 
13
- ### With ComputeSDK
13
+ ### Gateway Mode (Recommended)
14
14
 
15
- ```typescript
16
- import { createCompute } from 'computesdk';
17
- import { daytona } from '@computesdk/daytona';
15
+ Use the gateway for zero-config auto-detection:
18
16
 
19
- // Set as default provider
20
- const compute = createCompute({
21
- provider: daytona({ apiKey: process.env.DAYTONA_API_KEY })
22
- });
17
+ ```typescript
18
+ import { compute } from 'computesdk';
23
19
 
24
- // Create sandbox
20
+ // Auto-detects Daytona from DAYTONA_API_KEY environment variable
25
21
  const sandbox = await compute.sandbox.create();
26
22
 
27
23
  // Execute code
28
24
  const result = await sandbox.runCode('print("Hello from Daytona!")');
29
25
  console.log(result.stdout); // "Hello from Daytona!"
30
26
 
31
- // Clean up
32
- await compute.sandbox.destroy(sandbox.sandboxId);
27
+ await sandbox.destroy();
33
28
  ```
34
29
 
35
- ### Direct Usage
30
+ ### Direct Mode
31
+
32
+ For direct SDK usage without the gateway:
36
33
 
37
34
  ```typescript
38
35
  import { daytona } from '@computesdk/daytona';
39
36
 
40
- // Create provider
41
- const provider = daytona({
42
- apiKey: 'your-api-key',
43
- runtime: 'python'
37
+ const compute = daytona({
38
+ apiKey: process.env.DAYTONA_API_KEY
44
39
  });
45
40
 
46
- // Use with compute singleton
47
- const sandbox = await compute.sandbox.create({ provider });
41
+ const sandbox = await compute.sandbox.create();
42
+
43
+ const result = await sandbox.runCode('print("Hello from Daytona!")');
44
+ console.log(result.stdout);
45
+
46
+ await sandbox.destroy();
48
47
  ```
49
48
 
50
49
  ## Configuration
@@ -165,7 +164,12 @@ The provider automatically detects the runtime based on code patterns:
165
164
  ## Error Handling
166
165
 
167
166
  ```typescript
167
+ import { daytona } from '@computesdk/daytona';
168
+
168
169
  try {
170
+ const compute = daytona({ apiKey: process.env.DAYTONA_API_KEY });
171
+ const sandbox = await compute.sandbox.create();
172
+
169
173
  const result = await sandbox.runCode('invalid code');
170
174
  } catch (error) {
171
175
  if (error.message.includes('Syntax error')) {
@@ -178,27 +182,16 @@ try {
178
182
  }
179
183
  ```
180
184
 
181
- ## Web Framework Integration
185
+ ## Examples
182
186
 
183
- Use with web frameworks via the request handler:
187
+ ### Data Processing
184
188
 
185
189
  ```typescript
186
- import { handleComputeRequest } from 'computesdk';
187
190
  import { daytona } from '@computesdk/daytona';
188
191
 
189
- export async function POST(request: Request) {
190
- return handleComputeRequest({
191
- request,
192
- provider: daytona({ apiKey: process.env.DAYTONA_API_KEY })
193
- });
194
- }
195
- ```
196
-
197
- ## Examples
198
-
199
- ### Data Processing
192
+ const compute = daytona({ apiKey: process.env.DAYTONA_API_KEY });
193
+ const sandbox = await compute.sandbox.create();
200
194
 
201
- ```typescript
202
195
  const result = await sandbox.runCode(`
203
196
  import json
204
197
 
@@ -215,11 +208,18 @@ print(json.dumps(result))
215
208
 
216
209
  const output = JSON.parse(result.stdout);
217
210
  console.log(output); // { sum: 15, average: 3, max: 5 }
211
+
212
+ await sandbox.destroy();
218
213
  ```
219
214
 
220
215
  ### File Processing
221
216
 
222
217
  ```typescript
218
+ import { daytona } from '@computesdk/daytona';
219
+
220
+ const compute = daytona({ apiKey: process.env.DAYTONA_API_KEY });
221
+ const sandbox = await compute.sandbox.create();
222
+
223
223
  // Create data file
224
224
  await sandbox.filesystem.writeFile('/workspace/data.json',
225
225
  JSON.stringify({ users: ['Alice', 'Bob', 'Charlie'] })
@@ -245,6 +245,8 @@ with open('/workspace/result.json', 'w') as f:
245
245
  // Read result
246
246
  const resultData = await sandbox.filesystem.readFile('/workspace/result.json');
247
247
  console.log(JSON.parse(resultData));
248
+
249
+ await sandbox.destroy();
248
250
  ```
249
251
 
250
252
  ## License
package/dist/index.js CHANGED
@@ -142,16 +142,20 @@ var daytona = (0, import_provider.defineProvider)({
142
142
  );
143
143
  }
144
144
  },
145
- runCommand: async (sandbox, command, args = []) => {
145
+ runCommand: async (sandbox, command, options) => {
146
146
  const startTime = Date.now();
147
147
  try {
148
- const quotedArgs = args.map((arg) => {
149
- if (arg.includes(" ") || arg.includes('"') || arg.includes("'") || arg.includes("$") || arg.includes("`")) {
150
- return `"${arg.replace(/"/g, '\\"')}"`;
151
- }
152
- return arg;
153
- });
154
- const fullCommand = quotedArgs.length > 0 ? `${command} ${quotedArgs.join(" ")}` : command;
148
+ let fullCommand = command;
149
+ if (options?.env && Object.keys(options.env).length > 0) {
150
+ const envPrefix = Object.entries(options.env).map(([k, v]) => `${k}="${(0, import_provider.escapeShellArg)(v)}"`).join(" ");
151
+ fullCommand = `${envPrefix} ${fullCommand}`;
152
+ }
153
+ if (options?.cwd) {
154
+ fullCommand = `cd "${(0, import_provider.escapeShellArg)(options.cwd)}" && ${fullCommand}`;
155
+ }
156
+ if (options?.background) {
157
+ fullCommand = `nohup ${fullCommand} > /dev/null 2>&1 &`;
158
+ }
155
159
  const response = await sandbox.process.executeCommand(fullCommand);
156
160
  return {
157
161
  stdout: response.result || "",
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 { defineProvider } from '@computesdk/provider';\n\nimport type { Runtime, CodeResult, CommandResult, SandboxInfo, CreateSandboxOptions, FileEntry, RunCommandOptions } from '@computesdk/provider';\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 = defineProvider<DaytonaSandbox, DaytonaConfig>({\n name: 'daytona',\n defaultMode: 'direct',\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<CodeResult> => {\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 output: output,\n exitCode: actualExitCode,\n language: effectiveRuntime\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<CommandResult> => {\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 durationMs: Date.now() - startTime\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 type: isDirectory ? 'directory' as const : 'file' as const,\n size,\n modified: 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":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAOA,iBAAmD;AACnD,sBAA+B;AAmBxB,IAAM,cAAU,gCAA8C;AAAA,EACnE,MAAM;AAAA,EACN,aAAa;AAAA,EACb,SAAS;AAAA,IACP,SAAS;AAAA;AAAA,MAEP,QAAQ,OAAO,QAAuB,YAAmC;AAEvE,cAAM,SAAS,OAAO,UAAW,OAAO,YAAY,eAAe,QAAQ,KAAK,mBAAoB;AAEpG,YAAI,CAAC,QAAQ;AACX,gBAAM,IAAI;AAAA,YACR;AAAA,UACF;AAAA,QACF;AAEA,cAAM,UAAU,SAAS,WAAW,OAAO,WAAW;AAEtD,YAAI;AAEF,gBAAMA,WAAU,IAAI,mBAAQ,EAAE,OAAe,CAAC;AAE9C,cAAI;AACJ,cAAI;AAEJ,cAAI,SAAS,WAAW;AAEtB,sBAAU,MAAMA,SAAQ,IAAI,QAAQ,SAAS;AAC7C,wBAAY,QAAQ;AAAA,UACtB,OAAO;AAEL,sBAAU,MAAMA,SAAQ,OAAO;AAAA,cAC7B,UAAU,YAAY,WAAW,WAAW;AAAA,YAC9C,CAAC;AACD,wBAAY,QAAQ;AAAA,UACtB;AAEA,iBAAO;AAAA,YACL,SAAS;AAAA,YACT;AAAA,UACF;AAAA,QACF,SAAS,OAAO;AACd,cAAI,iBAAiB,OAAO;AAC1B,gBAAI,MAAM,QAAQ,SAAS,cAAc,KAAK,MAAM,QAAQ,SAAS,SAAS,GAAG;AAC/E,oBAAM,IAAI;AAAA,gBACR;AAAA,cACF;AAAA,YACF;AACA,gBAAI,MAAM,QAAQ,SAAS,OAAO,KAAK,MAAM,QAAQ,SAAS,OAAO,GAAG;AACtE,oBAAM,IAAI;AAAA,gBACR;AAAA,cACF;AAAA,YACF;AAAA,UACF;AACA,gBAAM,IAAI;AAAA,YACR,qCAAqC,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,UAC7F;AAAA,QACF;AAAA,MACF;AAAA,MAEA,SAAS,OAAO,QAAuB,cAAsB;AAC3D,cAAM,SAAS,OAAO,UAAU,QAAQ,IAAI;AAE5C,YAAI;AACF,gBAAMA,WAAU,IAAI,mBAAQ,EAAE,OAAe,CAAC;AAC9C,gBAAM,UAAU,MAAMA,SAAQ,IAAI,SAAS;AAE3C,iBAAO;AAAA,YACL,SAAS;AAAA,YACT;AAAA,UACF;AAAA,QACF,SAAS,OAAO;AAEd,iBAAO;AAAA,QACT;AAAA,MACF;AAAA,MAEA,MAAM,OAAO,WAA0B;AACrC,cAAM,SAAS,OAAO,UAAU,QAAQ,IAAI;AAE5C,YAAI;AACF,gBAAMA,WAAU,IAAI,mBAAQ,EAAE,OAAe,CAAC;AAC9C,gBAAM,YAAY,MAAMA,SAAQ,KAAK;AAErC,iBAAO,UAAU,IAAI,CAAC,aAAkB;AAAA,YACtC,SAAS;AAAA,YACT,WAAW,QAAQ;AAAA,UACrB,EAAE;AAAA,QACJ,SAAS,OAAO;AAEd,iBAAO,CAAC;AAAA,QACV;AAAA,MACF;AAAA,MAEA,SAAS,OAAO,QAAuB,cAAsB;AAC3D,cAAM,SAAS,OAAO,UAAU,QAAQ,IAAI;AAE5C,YAAI;AACF,gBAAMA,WAAU,IAAI,mBAAQ,EAAE,OAAe,CAAC;AAI9C,gBAAM,UAAU,MAAMA,SAAQ,IAAI,SAAS;AAC3C,gBAAM,QAAQ,OAAO;AAAA,QACvB,SAAS,OAAO;AAAA,QAGhB;AAAA,MACF;AAAA;AAAA,MAGA,SAAS,OAAO,SAAyB,MAAc,YAA2C;AAChG,cAAM,YAAY,KAAK,IAAI;AAE3B,YAAI;AAEF,gBAAM,mBAAmB;AAAA,WAEvB,KAAK,SAAS,QAAQ,KACtB,KAAK,SAAS,SAAS,KACvB,KAAK,SAAS,MAAM,KACpB,KAAK,SAAS,MAAM,KACpB,KAAK,SAAS,OAAO,KACrB,KAAK,SAAS,IAAI,KAClB,KAAK,SAAS,IAAI,KAClB,KAAK,SAAS,IAAI,KAClB,KAAK,SAAS,QAAQ,IAClB,WAEA;AAIN,cAAI;AAGJ,gBAAM,UAAU,OAAO,KAAK,IAAI,EAAE,SAAS,QAAQ;AAEnD,cAAI,qBAAqB,UAAU;AACjC,uBAAW,MAAM,QAAQ,QAAQ,eAAe,SAAS,OAAO,yBAAyB;AAAA,UAC3F,OAAO;AACL,uBAAW,MAAM,QAAQ,QAAQ,eAAe,SAAS,OAAO,sBAAsB;AAAA,UACxF;AAGA,gBAAM,SAAS,SAAS,UAAU;AAClC,gBAAM,WAAW,OAAO,SAAS,QAAQ,KACzB,OAAO,SAAS,UAAU,KAC1B,OAAO,SAAS,cAAc,KAC9B,OAAO,SAAS,YAAY,KAC5B,OAAO,SAAS,iBAAiB,KACjC,OAAO,SAAS,mCAAmC;AAGnE,cAAI,aAAa,OAAO,SAAS,cAAc,KAC/B,OAAO,SAAS,gBAAgB,KAChC,OAAO,SAAS,kBAAkB,KAClC,OAAO,SAAS,uBAAuB,KACvC,OAAO,SAAS,cAAc,IAAI;AAChD,kBAAM,IAAI,MAAM,iBAAiB,OAAO,KAAK,CAAC,EAAE;AAAA,UAClD;AAEA,gBAAM,iBAAiB,WAAW,IAAK,SAAS,YAAY;AAE5D,iBAAO;AAAA,YACL;AAAA,YACA,UAAU;AAAA,YACV,UAAU;AAAA,UACZ;AAAA,QACF,SAAS,OAAO;AAEd,cAAI,iBAAiB,SAAS,MAAM,QAAQ,SAAS,cAAc,GAAG;AACpE,kBAAM;AAAA,UACR;AACA,gBAAM,IAAI;AAAA,YACR,6BAA6B,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,UACrF;AAAA,QACF;AAAA,MACF;AAAA,MAEA,YAAY,OAAO,SAAyB,SAAiB,OAAiB,CAAC,MAA8B;AAC3G,cAAM,YAAY,KAAK,IAAI;AAE3B,YAAI;AAEF,gBAAM,aAAa,KAAK,IAAI,CAAC,QAAgB;AAC3C,gBAAI,IAAI,SAAS,GAAG,KAAK,IAAI,SAAS,GAAG,KAAK,IAAI,SAAS,GAAG,KAAK,IAAI,SAAS,GAAG,KAAK,IAAI,SAAS,GAAG,GAAG;AACzG,qBAAO,IAAI,IAAI,QAAQ,MAAM,KAAK,CAAC;AAAA,YACrC;AACA,mBAAO;AAAA,UACT,CAAC;AACD,gBAAM,cAAc,WAAW,SAAS,IAAI,GAAG,OAAO,IAAI,WAAW,KAAK,GAAG,CAAC,KAAK;AAGnF,gBAAM,WAAW,MAAM,QAAQ,QAAQ,eAAe,WAAW;AAEjE,iBAAO;AAAA,YACL,QAAQ,SAAS,UAAU;AAAA,YAC3B,QAAQ;AAAA,YACR,UAAU,SAAS,YAAY;AAAA,YAC/B,YAAY,KAAK,IAAI,IAAI;AAAA,UAC3B;AAAA,QACF,SAAS,OAAO;AACd,gBAAM,IAAI;AAAA,YACR,qCAAqC,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,UAC7F;AAAA,QACF;AAAA,MACF;AAAA,MAEA,SAAS,OAAO,YAAkD;AAChE,eAAO;AAAA,UACL,IAAI,QAAQ;AAAA,UACZ,UAAU;AAAA,UACV,SAAS;AAAA;AAAA,UACT,QAAQ;AAAA,UACR,WAAW,oBAAI,KAAK;AAAA,UACpB,SAAS;AAAA,UACT,UAAU;AAAA,YACR,kBAAkB,QAAQ;AAAA,UAC5B;AAAA,QACF;AAAA,MACF;AAAA,MAEA,QAAQ,OAAO,SAAyB,YAAkE;AACxG,YAAI;AAEF,gBAAM,cAAc,MAAM,QAAQ,eAAe,QAAQ,IAAI;AAC7D,cAAI,MAAM,YAAY;AAGtB,cAAI,QAAQ,UAAU;AACpB,kBAAM,SAAS,IAAI,IAAI,GAAG;AAC1B,mBAAO,WAAW,QAAQ,WAAW;AACrC,kBAAM,OAAO,SAAS;AAAA,UACxB;AAEA,iBAAO;AAAA,QACT,SAAS,OAAO;AACd,gBAAM,IAAI;AAAA,YACR,8CAA8C,QAAQ,IAAI,KAAK,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,UACvH;AAAA,QACF;AAAA,MACF;AAAA;AAAA,MAGA,YAAY;AAAA,QACV,UAAU,OAAO,SAAyB,SAAkC;AAC1E,cAAI;AACF,kBAAM,WAAW,MAAM,QAAQ,QAAQ,eAAe,QAAQ,IAAI,GAAG;AACrE,gBAAI,SAAS,aAAa,GAAG;AAC3B,oBAAM,IAAI,MAAM,qCAAqC,IAAI,EAAE;AAAA,YAC7D;AACA,mBAAO,SAAS,UAAU;AAAA,UAC5B,SAAS,OAAO;AACd,kBAAM,IAAI,MAAM,uBAAuB,IAAI,KAAK,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC,EAAE;AAAA,UAC1G;AAAA,QACF;AAAA,QAEA,WAAW,OAAO,SAAyB,MAAc,YAAmC;AAC1F,cAAI;AAEF,kBAAM,UAAU,OAAO,KAAK,OAAO,EAAE,SAAS,QAAQ;AACtD,kBAAM,WAAW,MAAM,QAAQ,QAAQ,eAAe,SAAS,OAAO,oBAAoB,IAAI,GAAG;AACjG,gBAAI,SAAS,aAAa,GAAG;AAC3B,oBAAM,IAAI,MAAM,4BAA4B,IAAI,EAAE;AAAA,YACpD;AAAA,UACF,SAAS,OAAO;AACd,kBAAM,IAAI,MAAM,wBAAwB,IAAI,KAAK,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC,EAAE;AAAA,UAC3G;AAAA,QACF;AAAA,QAEA,OAAO,OAAO,SAAyB,SAAgC;AACrE,cAAI;AACF,kBAAM,WAAW,MAAM,QAAQ,QAAQ,eAAe,aAAa,IAAI,GAAG;AAC1E,gBAAI,SAAS,aAAa,GAAG;AAC3B,oBAAM,IAAI,MAAM,+BAA+B,IAAI,EAAE;AAAA,YACvD;AAAA,UACF,SAAS,OAAO;AACd,kBAAM,IAAI,MAAM,8BAA8B,IAAI,KAAK,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC,EAAE;AAAA,UACjH;AAAA,QACF;AAAA,QAEA,SAAS,OAAO,SAAyB,SAAuC;AAC9E,cAAI;AACF,kBAAM,WAAW,MAAM,QAAQ,QAAQ,eAAe,WAAW,IAAI,GAAG;AACxE,gBAAI,SAAS,aAAa,GAAG;AAC3B,oBAAM,IAAI,MAAM,0CAA0C,IAAI,EAAE;AAAA,YAClE;AAGA,kBAAM,QAAQ,SAAS,OAAO,MAAM,IAAI,EAAE,OAAO,UAAQ,KAAK,KAAK,CAAC;AACpE,kBAAM,UAAuB,CAAC;AAE9B,uBAAW,QAAQ,OAAO;AAExB,kBAAI,KAAK,WAAW,QAAQ,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,SAAS,KAAK,GAAG;AAC5E;AAAA,cACF;AAGA,oBAAM,QAAQ,KAAK,KAAK,EAAE,MAAM,KAAK;AACrC,kBAAI,MAAM,UAAU,GAAG;AACrB,sBAAM,cAAc,MAAM,CAAC;AAC3B,sBAAM,OAAO,MAAM,MAAM,CAAC,EAAE,KAAK,GAAG;AACpC,sBAAM,cAAc,YAAY,WAAW,GAAG;AAC9C,sBAAM,OAAO,SAAS,MAAM,CAAC,CAAC,KAAK;AAEnC,wBAAQ,KAAK;AAAA,kBACX;AAAA,kBACA,MAAM,cAAc,cAAuB;AAAA,kBAC3C;AAAA,kBACA,UAAU,oBAAI,KAAK;AAAA;AAAA,gBACrB,CAAC;AAAA,cACH;AAAA,YACF;AAEA,mBAAO;AAAA,UACT,SAAS,OAAO;AACd,kBAAM,IAAI,MAAM,4BAA4B,IAAI,KAAK,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC,EAAE;AAAA,UAC/G;AAAA,QACF;AAAA,QAEA,QAAQ,OAAO,SAAyB,SAAmC;AACzE,cAAI;AACF,kBAAM,WAAW,MAAM,QAAQ,QAAQ,eAAe,YAAY,IAAI,GAAG;AACzE,mBAAO,SAAS,aAAa;AAAA,UAC/B,SAAS,OAAO;AAEd,mBAAO;AAAA,UACT;AAAA,QACF;AAAA,QAEA,QAAQ,OAAO,SAAyB,SAAgC;AACtE,cAAI;AACF,kBAAM,WAAW,MAAM,QAAQ,QAAQ,eAAe,WAAW,IAAI,GAAG;AACxE,gBAAI,SAAS,aAAa,GAAG;AAC3B,oBAAM,IAAI,MAAM,qBAAqB,IAAI,EAAE;AAAA,YAC7C;AAAA,UACF,SAAS,OAAO;AACd,kBAAM,IAAI,MAAM,oBAAoB,IAAI,KAAK,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC,EAAE;AAAA,UACvG;AAAA,QACF;AAAA,MACF;AAAA;AAAA,MAGA,aAAa,CAAC,YAA4C;AACxD,eAAO;AAAA,MACT;AAAA;AAAA,IAIF;AAAA,EACF;AACF,CAAC;","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 { defineProvider, escapeShellArg } from '@computesdk/provider';\n\nimport type { Runtime, CodeResult, CommandResult, SandboxInfo, CreateSandboxOptions, FileEntry, RunCommandOptions } from '@computesdk/provider';\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 = defineProvider<DaytonaSandbox, DaytonaConfig>({\n name: 'daytona',\n defaultMode: 'direct',\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<CodeResult> => {\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 output: output,\n exitCode: actualExitCode,\n language: effectiveRuntime\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, options?: RunCommandOptions): Promise<CommandResult> => {\n const startTime = Date.now();\n\n try {\n // Build command with options\n let fullCommand = command;\n \n // Handle environment variables\n if (options?.env && Object.keys(options.env).length > 0) {\n const envPrefix = Object.entries(options.env)\n .map(([k, v]) => `${k}=\"${escapeShellArg(v)}\"`)\n .join(' ');\n fullCommand = `${envPrefix} ${fullCommand}`;\n }\n \n // Handle working directory\n if (options?.cwd) {\n fullCommand = `cd \"${escapeShellArg(options.cwd)}\" && ${fullCommand}`;\n }\n \n // Handle background execution\n if (options?.background) {\n fullCommand = `nohup ${fullCommand} > /dev/null 2>&1 &`;\n }\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 durationMs: Date.now() - startTime\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 type: isDirectory ? 'directory' as const : 'file' as const,\n size,\n modified: 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 { defineProvider } from "@computesdk/provider";
3
+ import { defineProvider, escapeShellArg } from "@computesdk/provider";
4
4
  var daytona = defineProvider({
5
5
  name: "daytona",
6
6
  defaultMode: "direct",
@@ -118,16 +118,20 @@ var daytona = defineProvider({
118
118
  );
119
119
  }
120
120
  },
121
- runCommand: async (sandbox, command, args = []) => {
121
+ runCommand: async (sandbox, command, options) => {
122
122
  const startTime = Date.now();
123
123
  try {
124
- const quotedArgs = args.map((arg) => {
125
- if (arg.includes(" ") || arg.includes('"') || arg.includes("'") || arg.includes("$") || arg.includes("`")) {
126
- return `"${arg.replace(/"/g, '\\"')}"`;
127
- }
128
- return arg;
129
- });
130
- const fullCommand = quotedArgs.length > 0 ? `${command} ${quotedArgs.join(" ")}` : command;
124
+ let fullCommand = command;
125
+ if (options?.env && Object.keys(options.env).length > 0) {
126
+ const envPrefix = Object.entries(options.env).map(([k, v]) => `${k}="${escapeShellArg(v)}"`).join(" ");
127
+ fullCommand = `${envPrefix} ${fullCommand}`;
128
+ }
129
+ if (options?.cwd) {
130
+ fullCommand = `cd "${escapeShellArg(options.cwd)}" && ${fullCommand}`;
131
+ }
132
+ if (options?.background) {
133
+ fullCommand = `nohup ${fullCommand} > /dev/null 2>&1 &`;
134
+ }
131
135
  const response = await sandbox.process.executeCommand(fullCommand);
132
136
  return {
133
137
  stdout: response.result || "",
@@ -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 { defineProvider } from '@computesdk/provider';\n\nimport type { Runtime, CodeResult, CommandResult, SandboxInfo, CreateSandboxOptions, FileEntry, RunCommandOptions } from '@computesdk/provider';\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 = defineProvider<DaytonaSandbox, DaytonaConfig>({\n name: 'daytona',\n defaultMode: 'direct',\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<CodeResult> => {\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 output: output,\n exitCode: actualExitCode,\n language: effectiveRuntime\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<CommandResult> => {\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 durationMs: Date.now() - startTime\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 type: isDirectory ? 'directory' as const : 'file' as const,\n size,\n modified: 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 { defineProvider, escapeShellArg } from '@computesdk/provider';\n\nimport type { Runtime, CodeResult, CommandResult, SandboxInfo, CreateSandboxOptions, FileEntry, RunCommandOptions } from '@computesdk/provider';\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 = defineProvider<DaytonaSandbox, DaytonaConfig>({\n name: 'daytona',\n defaultMode: 'direct',\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<CodeResult> => {\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 output: output,\n exitCode: actualExitCode,\n language: effectiveRuntime\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, options?: RunCommandOptions): Promise<CommandResult> => {\n const startTime = Date.now();\n\n try {\n // Build command with options\n let fullCommand = command;\n \n // Handle environment variables\n if (options?.env && Object.keys(options.env).length > 0) {\n const envPrefix = Object.entries(options.env)\n .map(([k, v]) => `${k}=\"${escapeShellArg(v)}\"`)\n .join(' ');\n fullCommand = `${envPrefix} ${fullCommand}`;\n }\n \n // Handle working directory\n if (options?.cwd) {\n fullCommand = `cd \"${escapeShellArg(options.cwd)}\" && ${fullCommand}`;\n }\n \n // Handle background execution\n if (options?.background) {\n fullCommand = `nohup ${fullCommand} > /dev/null 2>&1 &`;\n }\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 durationMs: Date.now() - startTime\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 type: isDirectory ? 'directory' as const : 'file' as const,\n size,\n modified: 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.6.7",
3
+ "version": "1.6.9",
4
4
  "description": "Daytona provider for ComputeSDK - standardized development environments with devcontainer support",
5
5
  "author": "Garrison",
6
6
  "license": "MIT",
@@ -19,8 +19,8 @@
19
19
  ],
20
20
  "dependencies": {
21
21
  "@daytonaio/sdk": "^0.25.0",
22
- "@computesdk/provider": "1.0.1",
23
- "computesdk": "1.10.1"
22
+ "@computesdk/provider": "1.0.3",
23
+ "computesdk": "1.10.2"
24
24
  },
25
25
  "keywords": [
26
26
  "computesdk",
@@ -51,7 +51,7 @@
51
51
  "tsup": "^8.0.0",
52
52
  "typescript": "^5.0.0",
53
53
  "vitest": "^1.0.0",
54
- "@computesdk/test-utils": "1.5.0"
54
+ "@computesdk/test-utils": "1.5.1"
55
55
  },
56
56
  "scripts": {
57
57
  "build": "tsup",