@computesdk/codesandbox 1.5.6 → 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/README.md CHANGED
@@ -17,20 +17,16 @@ npm install @computesdk/codesandbox
17
17
  export CSB_API_KEY=your_api_key_here
18
18
  ```
19
19
 
20
- ## Usage
20
+ ## Quick Start
21
21
 
22
- ### With ComputeSDK
22
+ ### Gateway Mode (Recommended)
23
23
 
24
- ```typescript
25
- import { createCompute } from 'computesdk';
26
- import { codesandbox } from '@computesdk/codesandbox';
24
+ Use the gateway for zero-config auto-detection:
27
25
 
28
- // Set as default provider
29
- const compute = createCompute({
30
- provider: codesandbox({ apiKey: process.env.CSB_API_KEY })
31
- });
26
+ ```typescript
27
+ import { compute } from 'computesdk';
32
28
 
33
- // Create sandbox
29
+ // Auto-detects CodeSandbox from CSB_API_KEY environment variable
34
30
  const sandbox = await compute.sandbox.create();
35
31
 
36
32
  // Execute JavaScript/Node.js code
@@ -66,24 +62,28 @@ console.log(pythonResult.stdout);
66
62
  // }
67
63
  // Running in: CodeSandbox
68
64
 
69
- // Clean up
70
- await compute.sandbox.destroy(sandbox.sandboxId);
65
+ await sandbox.destroy();
71
66
  ```
72
67
 
73
- ### Direct Usage
68
+ ### Direct Mode
69
+
70
+ For direct SDK usage without the gateway:
74
71
 
75
72
  ```typescript
76
73
  import { codesandbox } from '@computesdk/codesandbox';
77
74
 
78
- // Create provider
79
- const provider = codesandbox({
80
- apiKey: 'your_api_key',
75
+ const compute = codesandbox({
76
+ apiKey: process.env.CSB_API_KEY,
81
77
  templateId: 'universal', // Optional: specify template
82
78
  timeout: 600000 // 10 minutes
83
79
  });
84
80
 
85
- // Use with compute singleton
86
- const sandbox = await compute.sandbox.create({ provider });
81
+ const sandbox = await compute.sandbox.create();
82
+
83
+ const result = await sandbox.runCode('console.log("Hello from CodeSandbox!");');
84
+ console.log(result.stdout);
85
+
86
+ await sandbox.destroy();
87
87
  ```
88
88
 
89
89
  ## Configuration
package/dist/index.d.mts CHANGED
@@ -1,5 +1,5 @@
1
- import * as computesdk from 'computesdk';
2
- import { Runtime } from 'computesdk';
1
+ import * as _computesdk_provider from '@computesdk/provider';
2
+ import { Runtime } from '@computesdk/provider';
3
3
  import { Sandbox } from '@codesandbox/sdk';
4
4
 
5
5
  /**
@@ -18,6 +18,6 @@ interface CodesandboxConfig {
18
18
  /**
19
19
  * Create a Codesandbox provider instance using the factory pattern
20
20
  */
21
- declare const codesandbox: (config: CodesandboxConfig & computesdk.BaseProviderConfig) => computesdk.Provider<Sandbox, any, any>;
21
+ declare const codesandbox: (config: CodesandboxConfig & _computesdk_provider.BaseProviderConfig) => _computesdk_provider.Provider<Sandbox, any, any>;
22
22
 
23
23
  export { type CodesandboxConfig, codesandbox };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import * as computesdk from 'computesdk';
2
- import { Runtime } from 'computesdk';
1
+ import * as _computesdk_provider from '@computesdk/provider';
2
+ import { Runtime } from '@computesdk/provider';
3
3
  import { Sandbox } from '@codesandbox/sdk';
4
4
 
5
5
  /**
@@ -18,6 +18,6 @@ interface CodesandboxConfig {
18
18
  /**
19
19
  * Create a Codesandbox provider instance using the factory pattern
20
20
  */
21
- declare const codesandbox: (config: CodesandboxConfig & computesdk.BaseProviderConfig) => computesdk.Provider<Sandbox, any, any>;
21
+ declare const codesandbox: (config: CodesandboxConfig & _computesdk_provider.BaseProviderConfig) => _computesdk_provider.Provider<Sandbox, any, any>;
22
22
 
23
23
  export { type CodesandboxConfig, codesandbox };
package/dist/index.js CHANGED
@@ -24,8 +24,8 @@ __export(index_exports, {
24
24
  });
25
25
  module.exports = __toCommonJS(index_exports);
26
26
  var import_sdk = require("@codesandbox/sdk");
27
- var import_computesdk = require("computesdk");
28
- var codesandbox = (0, import_computesdk.createProvider)({
27
+ var import_provider = require("@computesdk/provider");
28
+ var codesandbox = (0, import_provider.defineProvider)({
29
29
  name: "codesandbox",
30
30
  methods: {
31
31
  sandbox: {
@@ -208,10 +208,9 @@ var codesandbox = (0, import_computesdk.createProvider)({
208
208
  const entries = await client.fs.readdir(path);
209
209
  return entries.map((entry) => ({
210
210
  name: entry.name,
211
- path: `${path}/${entry.name}`.replace(/\/+/g, "/"),
212
- isDirectory: entry.isDirectory || false,
211
+ type: entry.isDirectory ? "directory" : "file",
213
212
  size: entry.size || 0,
214
- lastModified: entry.lastModified ? new Date(entry.lastModified) : /* @__PURE__ */ new Date()
213
+ modified: entry.lastModified ? new Date(entry.lastModified) : /* @__PURE__ */ new Date()
215
214
  }));
216
215
  },
217
216
  exists: async (sandbox, path) => {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * Codesandbox Provider - Factory-based Implementation\n * \n * Full-featured provider with filesystem support using the factory pattern.\n */\n\nimport { CodeSandbox } from '@codesandbox/sdk';\nimport type { Sandbox as CodesandboxSandbox } from '@codesandbox/sdk';\nimport { createProvider } from 'computesdk';\nimport type { Runtime, CodeResult, CommandResult, SandboxInfo, CreateSandboxOptions, FileEntry } from 'computesdk';\n\n/**\n * Codesandbox-specific configuration options\n */\nexport interface CodesandboxConfig {\n /** CodeSandbox API key - if not provided, will fallback to CSB_API_KEY environment variable */\n apiKey?: string;\n /** Template to use for new sandboxes */\n templateId?: string;\n /** Default runtime environment */\n runtime?: Runtime;\n /** Execution timeout in milliseconds */\n timeout?: number;\n}\n\n/**\n * Create a Codesandbox provider instance using the factory pattern\n */\nexport const codesandbox = createProvider<CodesandboxSandbox, CodesandboxConfig>({\n name: 'codesandbox',\n methods: {\n sandbox: {\n // Collection operations (compute.sandbox.*)\n create: async (config: CodesandboxConfig, options?: CreateSandboxOptions) => {\n // Validate API key\n const apiKey = config.apiKey || (typeof process !== 'undefined' && process.env?.CSB_API_KEY) || '';\n\n if (!apiKey) {\n throw new Error(\n `Missing CodeSandbox API key. Provide 'apiKey' in config or set CSB_API_KEY environment variable. Get your API key from https://codesandbox.io/t/api`\n );\n }\n\n const sdk = new CodeSandbox(apiKey);\n\n try {\n let sandbox: CodesandboxSandbox;\n let sandboxId: string;\n\n if (options?.sandboxId) {\n // Resume existing CodeSandbox using sdk.sandboxes.resume()\n sandbox = await sdk.sandboxes.resume(options.sandboxId);\n sandboxId = options.sandboxId;\n } else {\n // Create new CodeSandbox using sdk.sandboxes.create()\n const createOptions: any = {};\n \n if (config.templateId) {\n createOptions.id = config.templateId;\n }\n\n sandbox = await sdk.sandboxes.create(createOptions);\n sandboxId = sandbox.id;\n }\n\n return {\n sandbox,\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 `CodeSandbox authentication failed. Please check your CSB_API_KEY environment variable. Get your API key from https://codesandbox.io/t/api`\n );\n }\n if (error.message.includes('quota') || error.message.includes('limit')) {\n throw new Error(\n `CodeSandbox quota exceeded. Please check your usage at https://codesandbox.io/dashboard`\n );\n }\n }\n throw new Error(\n `Failed to create CodeSandbox sandbox: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n getById: async (config: CodesandboxConfig, sandboxId: string) => {\n const apiKey = config.apiKey || (typeof process !== 'undefined' && process.env?.CSB_API_KEY) || '';\n\n if (!apiKey) {\n throw new Error(\n `Missing CodeSandbox API key. Provide 'apiKey' in config or set CSB_API_KEY environment variable.`\n );\n }\n\n const sdk = new CodeSandbox(apiKey);\n\n try {\n // Resume existing sandbox using sdk.sandboxes.resume()\n const sandbox = await sdk.sandboxes.resume(sandboxId);\n\n return {\n sandbox,\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: CodesandboxConfig) => {\n throw new Error(\n `CodeSandbox provider does not support listing sandboxes. CodeSandbox SDK does not provide a native list API. Consider using the CodeSandbox dashboard or implement your own tracking system.`\n );\n },\n\n destroy: async (config: CodesandboxConfig, sandboxId: string) => {\n const apiKey = config.apiKey || (typeof process !== 'undefined' && process.env?.CSB_API_KEY) || '';\n\n if (!apiKey) {\n throw new Error(\n `Missing CodeSandbox API key. Provide 'apiKey' in config or set CSB_API_KEY environment variable.`\n );\n }\n\n const sdk = new CodeSandbox(apiKey);\n\n try {\n // Shutdown the sandbox using sdk.sandboxes.shutdown() to clean it up\n await sdk.sandboxes.shutdown(sandboxId);\n } catch (error) {\n // Sandbox might already be shutdown or doesn't exist\n // This is acceptable for destroy operations\n }\n },\n\n // Instance operations (sandbox.*)\n runCode: async (sandbox: CodesandboxSandbox, code: string, runtime?: Runtime): Promise<CodeResult> => {\n const startTime = Date.now();\n\n try {\n // Connect to the sandbox client using sandbox.connect()\n const client = await sandbox.connect();\n\n // Auto-detect runtime if not specified\n const effectiveRuntime = runtime || (\n // Strong Python indicators\n code.includes('print(') || \n code.includes('import ') ||\n code.includes('def ') ||\n code.includes('sys.') ||\n code.includes('json.') ||\n code.includes('__') ||\n code.includes('f\"') ||\n code.includes(\"f'\") ||\n code.includes('raise ')\n ? 'python'\n // Default to Node.js for all other cases (including ambiguous)\n : 'node'\n );\n\n // Use base64 encoding for reliability and consistency\n const encoded = Buffer.from(code).toString('base64');\n let command: string;\n\n if (effectiveRuntime === 'python') {\n // Execute Python code using client.commands.run()\n command = `echo \"${encoded}\" | base64 -d | python3`;\n } else {\n // Execute Node.js code using client.commands.run()\n command = `echo \"${encoded}\" | base64 -d | node`;\n }\n\n // Execute the command using CodeSandbox client.commands.run()\n // This returns the full output as a string\n const output = await client.commands.run(command);\n\n // Check for syntax errors in the output and throw them (similar to other providers)\n if (output.includes('SyntaxError') ||\n output.includes('invalid syntax') ||\n output.includes('Unexpected token') ||\n output.includes('Unexpected identifier')) {\n throw new Error(`Syntax error: ${output.trim()}`);\n }\n\n return {\n output: output,\n exitCode: 0,\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 `CodeSandbox execution failed: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n runCommand: async (sandbox: CodesandboxSandbox, command: string, args: string[] = []): Promise<CommandResult> => {\n const startTime = Date.now();\n\n try {\n // Connect to the sandbox client using sandbox.connect()\n const client = await sandbox.connect();\n\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 CodeSandbox client.commands.run()\n const output = await client.commands.run(fullCommand);\n\n return {\n stdout: output,\n stderr: '',\n exitCode: 0,\n durationMs: Date.now() - startTime\n };\n } catch (error) {\n return {\n stdout: '',\n stderr: error instanceof Error ? error.message : String(error),\n exitCode: 127,\n durationMs: Date.now() - startTime\n };\n }\n },\n\n getInfo: async (sandbox: CodesandboxSandbox): Promise<SandboxInfo> => {\n return {\n id: sandbox.id,\n provider: 'codesandbox',\n runtime: 'node', // CodeSandbox default\n status: 'running',\n createdAt: new Date(),\n timeout: 300000,\n metadata: {\n cluster: sandbox.cluster,\n bootupType: sandbox.bootupType,\n isUpToDate: sandbox.isUpToDate\n }\n };\n },\n\n getUrl: async (sandbox: CodesandboxSandbox, options: { port: number; protocol?: string }): Promise<string> => {\n const protocol = options.protocol || 'https';\n // CodeSandbox provides URLs in the format: https://{sandbox-id}.{cluster}.csb.app:{port}\n // Use the actual CodeSandbox URL format\n return `${protocol}://${sandbox.id}.${sandbox.cluster}.csb.app:${options.port}`;\n },\n\n // Filesystem operations using CodeSandbox client.fs API\n filesystem: {\n readFile: async (sandbox: CodesandboxSandbox, path: string): Promise<string> => {\n // Connect to the sandbox client and use client.fs.readTextFile()\n const client = await sandbox.connect();\n return await client.fs.readTextFile(path);\n },\n\n writeFile: async (sandbox: CodesandboxSandbox, path: string, content: string): Promise<void> => {\n // Connect to the sandbox client and use client.fs.writeTextFile()\n const client = await sandbox.connect();\n await client.fs.writeTextFile(path, content);\n },\n\n mkdir: async (sandbox: CodesandboxSandbox, path: string): Promise<void> => {\n // CodeSandbox doesn't have a direct mkdir API, use commands to create directory\n const client = await sandbox.connect();\n await client.commands.run(`mkdir -p \"${path}\"`);\n },\n\n readdir: async (sandbox: CodesandboxSandbox, path: string): Promise<FileEntry[]> => {\n // Connect to the sandbox client and use client.fs.readdir()\n const client = await sandbox.connect();\n const entries = await client.fs.readdir(path);\n\n return entries.map((entry: any) => ({\n name: entry.name,\n path: `${path}/${entry.name}`.replace(/\\/+/g, '/'),\n isDirectory: entry.isDirectory || false,\n size: entry.size || 0,\n lastModified: entry.lastModified ? new Date(entry.lastModified) : new Date()\n }));\n },\n\n exists: async (sandbox: CodesandboxSandbox, path: string): Promise<boolean> => {\n // CodeSandbox doesn't have a direct exists API, use ls command to check\n const client = await sandbox.connect();\n try {\n await client.commands.run(`ls \"${path}\"`);\n return true;\n } catch {\n return false;\n }\n },\n\n remove: async (sandbox: CodesandboxSandbox, path: string): Promise<void> => {\n // Connect to the sandbox client and use client.fs.remove()\n const client = await sandbox.connect();\n await client.fs.remove(path);\n }\n },\n\n // Provider-specific typed getInstance method\n getInstance: (sandbox: CodesandboxSandbox): CodesandboxSandbox => {\n return sandbox;\n },\n\n }\n }\n});\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * Codesandbox Provider - Factory-based Implementation\n * \n * Full-featured provider with filesystem support using the factory pattern.\n */\n\nimport { CodeSandbox } from '@codesandbox/sdk';\nimport type { Sandbox as CodesandboxSandbox } from '@codesandbox/sdk';\nimport { defineProvider } from '@computesdk/provider';\n\nimport type { Runtime, CodeResult, CommandResult, SandboxInfo, CreateSandboxOptions, FileEntry, RunCommandOptions } from '@computesdk/provider';\n\n/**\n * Codesandbox-specific configuration options\n */\nexport interface CodesandboxConfig {\n /** CodeSandbox API key - if not provided, will fallback to CSB_API_KEY environment variable */\n apiKey?: string;\n /** Template to use for new sandboxes */\n templateId?: string;\n /** Default runtime environment */\n runtime?: Runtime;\n /** Execution timeout in milliseconds */\n timeout?: number;\n}\n\n/**\n * Create a Codesandbox provider instance using the factory pattern\n */\nexport const codesandbox = defineProvider<CodesandboxSandbox, CodesandboxConfig>({\n name: 'codesandbox',\n methods: {\n sandbox: {\n // Collection operations (compute.sandbox.*)\n create: async (config: CodesandboxConfig, options?: CreateSandboxOptions) => {\n // Validate API key\n const apiKey = config.apiKey || (typeof process !== 'undefined' && process.env?.CSB_API_KEY) || '';\n\n if (!apiKey) {\n throw new Error(\n `Missing CodeSandbox API key. Provide 'apiKey' in config or set CSB_API_KEY environment variable. Get your API key from https://codesandbox.io/t/api`\n );\n }\n\n const sdk = new CodeSandbox(apiKey);\n\n try {\n let sandbox: CodesandboxSandbox;\n let sandboxId: string;\n\n if (options?.sandboxId) {\n // Resume existing CodeSandbox using sdk.sandboxes.resume()\n sandbox = await sdk.sandboxes.resume(options.sandboxId);\n sandboxId = options.sandboxId;\n } else {\n // Create new CodeSandbox using sdk.sandboxes.create()\n const createOptions: any = {};\n \n if (config.templateId) {\n createOptions.id = config.templateId;\n }\n\n sandbox = await sdk.sandboxes.create(createOptions);\n sandboxId = sandbox.id;\n }\n\n return {\n sandbox,\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 `CodeSandbox authentication failed. Please check your CSB_API_KEY environment variable. Get your API key from https://codesandbox.io/t/api`\n );\n }\n if (error.message.includes('quota') || error.message.includes('limit')) {\n throw new Error(\n `CodeSandbox quota exceeded. Please check your usage at https://codesandbox.io/dashboard`\n );\n }\n }\n throw new Error(\n `Failed to create CodeSandbox sandbox: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n getById: async (config: CodesandboxConfig, sandboxId: string) => {\n const apiKey = config.apiKey || (typeof process !== 'undefined' && process.env?.CSB_API_KEY) || '';\n\n if (!apiKey) {\n throw new Error(\n `Missing CodeSandbox API key. Provide 'apiKey' in config or set CSB_API_KEY environment variable.`\n );\n }\n\n const sdk = new CodeSandbox(apiKey);\n\n try {\n // Resume existing sandbox using sdk.sandboxes.resume()\n const sandbox = await sdk.sandboxes.resume(sandboxId);\n\n return {\n sandbox,\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: CodesandboxConfig) => {\n throw new Error(\n `CodeSandbox provider does not support listing sandboxes. CodeSandbox SDK does not provide a native list API. Consider using the CodeSandbox dashboard or implement your own tracking system.`\n );\n },\n\n destroy: async (config: CodesandboxConfig, sandboxId: string) => {\n const apiKey = config.apiKey || (typeof process !== 'undefined' && process.env?.CSB_API_KEY) || '';\n\n if (!apiKey) {\n throw new Error(\n `Missing CodeSandbox API key. Provide 'apiKey' in config or set CSB_API_KEY environment variable.`\n );\n }\n\n const sdk = new CodeSandbox(apiKey);\n\n try {\n // Shutdown the sandbox using sdk.sandboxes.shutdown() to clean it up\n await sdk.sandboxes.shutdown(sandboxId);\n } catch (error) {\n // Sandbox might already be shutdown or doesn't exist\n // This is acceptable for destroy operations\n }\n },\n\n // Instance operations (sandbox.*)\n runCode: async (sandbox: CodesandboxSandbox, code: string, runtime?: Runtime): Promise<CodeResult> => {\n const startTime = Date.now();\n\n try {\n // Connect to the sandbox client using sandbox.connect()\n const client = await sandbox.connect();\n\n // Auto-detect runtime if not specified\n const effectiveRuntime = runtime || (\n // Strong Python indicators\n code.includes('print(') || \n code.includes('import ') ||\n code.includes('def ') ||\n code.includes('sys.') ||\n code.includes('json.') ||\n code.includes('__') ||\n code.includes('f\"') ||\n code.includes(\"f'\") ||\n code.includes('raise ')\n ? 'python'\n // Default to Node.js for all other cases (including ambiguous)\n : 'node'\n );\n\n // Use base64 encoding for reliability and consistency\n const encoded = Buffer.from(code).toString('base64');\n let command: string;\n\n if (effectiveRuntime === 'python') {\n // Execute Python code using client.commands.run()\n command = `echo \"${encoded}\" | base64 -d | python3`;\n } else {\n // Execute Node.js code using client.commands.run()\n command = `echo \"${encoded}\" | base64 -d | node`;\n }\n\n // Execute the command using CodeSandbox client.commands.run()\n // This returns the full output as a string\n const output = await client.commands.run(command);\n\n // Check for syntax errors in the output and throw them (similar to other providers)\n if (output.includes('SyntaxError') ||\n output.includes('invalid syntax') ||\n output.includes('Unexpected token') ||\n output.includes('Unexpected identifier')) {\n throw new Error(`Syntax error: ${output.trim()}`);\n }\n\n return {\n output: output,\n exitCode: 0,\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 `CodeSandbox execution failed: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n runCommand: async (sandbox: CodesandboxSandbox, command: string, args: string[] = []): Promise<CommandResult> => {\n const startTime = Date.now();\n\n try {\n // Connect to the sandbox client using sandbox.connect()\n const client = await sandbox.connect();\n\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 CodeSandbox client.commands.run()\n const output = await client.commands.run(fullCommand);\n\n return {\n stdout: output,\n stderr: '',\n exitCode: 0,\n durationMs: Date.now() - startTime\n };\n } catch (error) {\n return {\n stdout: '',\n stderr: error instanceof Error ? error.message : String(error),\n exitCode: 127,\n durationMs: Date.now() - startTime\n };\n }\n },\n\n getInfo: async (sandbox: CodesandboxSandbox): Promise<SandboxInfo> => {\n return {\n id: sandbox.id,\n provider: 'codesandbox',\n runtime: 'node', // CodeSandbox default\n status: 'running',\n createdAt: new Date(),\n timeout: 300000,\n metadata: {\n cluster: sandbox.cluster,\n bootupType: sandbox.bootupType,\n isUpToDate: sandbox.isUpToDate\n }\n };\n },\n\n getUrl: async (sandbox: CodesandboxSandbox, options: { port: number; protocol?: string }): Promise<string> => {\n const protocol = options.protocol || 'https';\n // CodeSandbox provides URLs in the format: https://{sandbox-id}.{cluster}.csb.app:{port}\n // Use the actual CodeSandbox URL format\n return `${protocol}://${sandbox.id}.${sandbox.cluster}.csb.app:${options.port}`;\n },\n\n // Filesystem operations using CodeSandbox client.fs API\n filesystem: {\n readFile: async (sandbox: CodesandboxSandbox, path: string): Promise<string> => {\n // Connect to the sandbox client and use client.fs.readTextFile()\n const client = await sandbox.connect();\n return await client.fs.readTextFile(path);\n },\n\n writeFile: async (sandbox: CodesandboxSandbox, path: string, content: string): Promise<void> => {\n // Connect to the sandbox client and use client.fs.writeTextFile()\n const client = await sandbox.connect();\n await client.fs.writeTextFile(path, content);\n },\n\n mkdir: async (sandbox: CodesandboxSandbox, path: string): Promise<void> => {\n // CodeSandbox doesn't have a direct mkdir API, use commands to create directory\n const client = await sandbox.connect();\n await client.commands.run(`mkdir -p \"${path}\"`);\n },\n\n readdir: async (sandbox: CodesandboxSandbox, path: string): Promise<FileEntry[]> => {\n // Connect to the sandbox client and use client.fs.readdir()\n const client = await sandbox.connect();\n const entries = await client.fs.readdir(path);\n\n return entries.map((entry: any) => ({\n name: entry.name,\n type: entry.isDirectory ? 'directory' as const : 'file' as const,\n size: entry.size || 0,\n modified: entry.lastModified ? new Date(entry.lastModified) : new Date()\n }));\n },\n\n exists: async (sandbox: CodesandboxSandbox, path: string): Promise<boolean> => {\n // CodeSandbox doesn't have a direct exists API, use ls command to check\n const client = await sandbox.connect();\n try {\n await client.commands.run(`ls \"${path}\"`);\n return true;\n } catch {\n return false;\n }\n },\n\n remove: async (sandbox: CodesandboxSandbox, path: string): Promise<void> => {\n // Connect to the sandbox client and use client.fs.remove()\n const client = await sandbox.connect();\n await client.fs.remove(path);\n }\n },\n\n // Provider-specific typed getInstance method\n getInstance: (sandbox: CodesandboxSandbox): CodesandboxSandbox => {\n return sandbox;\n },\n\n }\n }\n});\n"],"mappings":"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","names":[]}
package/dist/index.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  // src/index.ts
2
2
  import { CodeSandbox } from "@codesandbox/sdk";
3
- import { createProvider } from "computesdk";
4
- var codesandbox = createProvider({
3
+ import { defineProvider } from "@computesdk/provider";
4
+ var codesandbox = defineProvider({
5
5
  name: "codesandbox",
6
6
  methods: {
7
7
  sandbox: {
@@ -184,10 +184,9 @@ var codesandbox = createProvider({
184
184
  const entries = await client.fs.readdir(path);
185
185
  return entries.map((entry) => ({
186
186
  name: entry.name,
187
- path: `${path}/${entry.name}`.replace(/\/+/g, "/"),
188
- isDirectory: entry.isDirectory || false,
187
+ type: entry.isDirectory ? "directory" : "file",
189
188
  size: entry.size || 0,
190
- lastModified: entry.lastModified ? new Date(entry.lastModified) : /* @__PURE__ */ new Date()
189
+ modified: entry.lastModified ? new Date(entry.lastModified) : /* @__PURE__ */ new Date()
191
190
  }));
192
191
  },
193
192
  exists: async (sandbox, path) => {
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * Codesandbox Provider - Factory-based Implementation\n * \n * Full-featured provider with filesystem support using the factory pattern.\n */\n\nimport { CodeSandbox } from '@codesandbox/sdk';\nimport type { Sandbox as CodesandboxSandbox } from '@codesandbox/sdk';\nimport { createProvider } from 'computesdk';\nimport type { Runtime, CodeResult, CommandResult, SandboxInfo, CreateSandboxOptions, FileEntry } from 'computesdk';\n\n/**\n * Codesandbox-specific configuration options\n */\nexport interface CodesandboxConfig {\n /** CodeSandbox API key - if not provided, will fallback to CSB_API_KEY environment variable */\n apiKey?: string;\n /** Template to use for new sandboxes */\n templateId?: string;\n /** Default runtime environment */\n runtime?: Runtime;\n /** Execution timeout in milliseconds */\n timeout?: number;\n}\n\n/**\n * Create a Codesandbox provider instance using the factory pattern\n */\nexport const codesandbox = createProvider<CodesandboxSandbox, CodesandboxConfig>({\n name: 'codesandbox',\n methods: {\n sandbox: {\n // Collection operations (compute.sandbox.*)\n create: async (config: CodesandboxConfig, options?: CreateSandboxOptions) => {\n // Validate API key\n const apiKey = config.apiKey || (typeof process !== 'undefined' && process.env?.CSB_API_KEY) || '';\n\n if (!apiKey) {\n throw new Error(\n `Missing CodeSandbox API key. Provide 'apiKey' in config or set CSB_API_KEY environment variable. Get your API key from https://codesandbox.io/t/api`\n );\n }\n\n const sdk = new CodeSandbox(apiKey);\n\n try {\n let sandbox: CodesandboxSandbox;\n let sandboxId: string;\n\n if (options?.sandboxId) {\n // Resume existing CodeSandbox using sdk.sandboxes.resume()\n sandbox = await sdk.sandboxes.resume(options.sandboxId);\n sandboxId = options.sandboxId;\n } else {\n // Create new CodeSandbox using sdk.sandboxes.create()\n const createOptions: any = {};\n \n if (config.templateId) {\n createOptions.id = config.templateId;\n }\n\n sandbox = await sdk.sandboxes.create(createOptions);\n sandboxId = sandbox.id;\n }\n\n return {\n sandbox,\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 `CodeSandbox authentication failed. Please check your CSB_API_KEY environment variable. Get your API key from https://codesandbox.io/t/api`\n );\n }\n if (error.message.includes('quota') || error.message.includes('limit')) {\n throw new Error(\n `CodeSandbox quota exceeded. Please check your usage at https://codesandbox.io/dashboard`\n );\n }\n }\n throw new Error(\n `Failed to create CodeSandbox sandbox: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n getById: async (config: CodesandboxConfig, sandboxId: string) => {\n const apiKey = config.apiKey || (typeof process !== 'undefined' && process.env?.CSB_API_KEY) || '';\n\n if (!apiKey) {\n throw new Error(\n `Missing CodeSandbox API key. Provide 'apiKey' in config or set CSB_API_KEY environment variable.`\n );\n }\n\n const sdk = new CodeSandbox(apiKey);\n\n try {\n // Resume existing sandbox using sdk.sandboxes.resume()\n const sandbox = await sdk.sandboxes.resume(sandboxId);\n\n return {\n sandbox,\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: CodesandboxConfig) => {\n throw new Error(\n `CodeSandbox provider does not support listing sandboxes. CodeSandbox SDK does not provide a native list API. Consider using the CodeSandbox dashboard or implement your own tracking system.`\n );\n },\n\n destroy: async (config: CodesandboxConfig, sandboxId: string) => {\n const apiKey = config.apiKey || (typeof process !== 'undefined' && process.env?.CSB_API_KEY) || '';\n\n if (!apiKey) {\n throw new Error(\n `Missing CodeSandbox API key. Provide 'apiKey' in config or set CSB_API_KEY environment variable.`\n );\n }\n\n const sdk = new CodeSandbox(apiKey);\n\n try {\n // Shutdown the sandbox using sdk.sandboxes.shutdown() to clean it up\n await sdk.sandboxes.shutdown(sandboxId);\n } catch (error) {\n // Sandbox might already be shutdown or doesn't exist\n // This is acceptable for destroy operations\n }\n },\n\n // Instance operations (sandbox.*)\n runCode: async (sandbox: CodesandboxSandbox, code: string, runtime?: Runtime): Promise<CodeResult> => {\n const startTime = Date.now();\n\n try {\n // Connect to the sandbox client using sandbox.connect()\n const client = await sandbox.connect();\n\n // Auto-detect runtime if not specified\n const effectiveRuntime = runtime || (\n // Strong Python indicators\n code.includes('print(') || \n code.includes('import ') ||\n code.includes('def ') ||\n code.includes('sys.') ||\n code.includes('json.') ||\n code.includes('__') ||\n code.includes('f\"') ||\n code.includes(\"f'\") ||\n code.includes('raise ')\n ? 'python'\n // Default to Node.js for all other cases (including ambiguous)\n : 'node'\n );\n\n // Use base64 encoding for reliability and consistency\n const encoded = Buffer.from(code).toString('base64');\n let command: string;\n\n if (effectiveRuntime === 'python') {\n // Execute Python code using client.commands.run()\n command = `echo \"${encoded}\" | base64 -d | python3`;\n } else {\n // Execute Node.js code using client.commands.run()\n command = `echo \"${encoded}\" | base64 -d | node`;\n }\n\n // Execute the command using CodeSandbox client.commands.run()\n // This returns the full output as a string\n const output = await client.commands.run(command);\n\n // Check for syntax errors in the output and throw them (similar to other providers)\n if (output.includes('SyntaxError') ||\n output.includes('invalid syntax') ||\n output.includes('Unexpected token') ||\n output.includes('Unexpected identifier')) {\n throw new Error(`Syntax error: ${output.trim()}`);\n }\n\n return {\n output: output,\n exitCode: 0,\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 `CodeSandbox execution failed: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n runCommand: async (sandbox: CodesandboxSandbox, command: string, args: string[] = []): Promise<CommandResult> => {\n const startTime = Date.now();\n\n try {\n // Connect to the sandbox client using sandbox.connect()\n const client = await sandbox.connect();\n\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 CodeSandbox client.commands.run()\n const output = await client.commands.run(fullCommand);\n\n return {\n stdout: output,\n stderr: '',\n exitCode: 0,\n durationMs: Date.now() - startTime\n };\n } catch (error) {\n return {\n stdout: '',\n stderr: error instanceof Error ? error.message : String(error),\n exitCode: 127,\n durationMs: Date.now() - startTime\n };\n }\n },\n\n getInfo: async (sandbox: CodesandboxSandbox): Promise<SandboxInfo> => {\n return {\n id: sandbox.id,\n provider: 'codesandbox',\n runtime: 'node', // CodeSandbox default\n status: 'running',\n createdAt: new Date(),\n timeout: 300000,\n metadata: {\n cluster: sandbox.cluster,\n bootupType: sandbox.bootupType,\n isUpToDate: sandbox.isUpToDate\n }\n };\n },\n\n getUrl: async (sandbox: CodesandboxSandbox, options: { port: number; protocol?: string }): Promise<string> => {\n const protocol = options.protocol || 'https';\n // CodeSandbox provides URLs in the format: https://{sandbox-id}.{cluster}.csb.app:{port}\n // Use the actual CodeSandbox URL format\n return `${protocol}://${sandbox.id}.${sandbox.cluster}.csb.app:${options.port}`;\n },\n\n // Filesystem operations using CodeSandbox client.fs API\n filesystem: {\n readFile: async (sandbox: CodesandboxSandbox, path: string): Promise<string> => {\n // Connect to the sandbox client and use client.fs.readTextFile()\n const client = await sandbox.connect();\n return await client.fs.readTextFile(path);\n },\n\n writeFile: async (sandbox: CodesandboxSandbox, path: string, content: string): Promise<void> => {\n // Connect to the sandbox client and use client.fs.writeTextFile()\n const client = await sandbox.connect();\n await client.fs.writeTextFile(path, content);\n },\n\n mkdir: async (sandbox: CodesandboxSandbox, path: string): Promise<void> => {\n // CodeSandbox doesn't have a direct mkdir API, use commands to create directory\n const client = await sandbox.connect();\n await client.commands.run(`mkdir -p \"${path}\"`);\n },\n\n readdir: async (sandbox: CodesandboxSandbox, path: string): Promise<FileEntry[]> => {\n // Connect to the sandbox client and use client.fs.readdir()\n const client = await sandbox.connect();\n const entries = await client.fs.readdir(path);\n\n return entries.map((entry: any) => ({\n name: entry.name,\n path: `${path}/${entry.name}`.replace(/\\/+/g, '/'),\n isDirectory: entry.isDirectory || false,\n size: entry.size || 0,\n lastModified: entry.lastModified ? new Date(entry.lastModified) : new Date()\n }));\n },\n\n exists: async (sandbox: CodesandboxSandbox, path: string): Promise<boolean> => {\n // CodeSandbox doesn't have a direct exists API, use ls command to check\n const client = await sandbox.connect();\n try {\n await client.commands.run(`ls \"${path}\"`);\n return true;\n } catch {\n return false;\n }\n },\n\n remove: async (sandbox: CodesandboxSandbox, path: string): Promise<void> => {\n // Connect to the sandbox client and use client.fs.remove()\n const client = await sandbox.connect();\n await client.fs.remove(path);\n }\n },\n\n // Provider-specific typed getInstance method\n getInstance: (sandbox: CodesandboxSandbox): CodesandboxSandbox => {\n return sandbox;\n },\n\n }\n }\n});\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * Codesandbox Provider - Factory-based Implementation\n * \n * Full-featured provider with filesystem support using the factory pattern.\n */\n\nimport { CodeSandbox } from '@codesandbox/sdk';\nimport type { Sandbox as CodesandboxSandbox } from '@codesandbox/sdk';\nimport { defineProvider } from '@computesdk/provider';\n\nimport type { Runtime, CodeResult, CommandResult, SandboxInfo, CreateSandboxOptions, FileEntry, RunCommandOptions } from '@computesdk/provider';\n\n/**\n * Codesandbox-specific configuration options\n */\nexport interface CodesandboxConfig {\n /** CodeSandbox API key - if not provided, will fallback to CSB_API_KEY environment variable */\n apiKey?: string;\n /** Template to use for new sandboxes */\n templateId?: string;\n /** Default runtime environment */\n runtime?: Runtime;\n /** Execution timeout in milliseconds */\n timeout?: number;\n}\n\n/**\n * Create a Codesandbox provider instance using the factory pattern\n */\nexport const codesandbox = defineProvider<CodesandboxSandbox, CodesandboxConfig>({\n name: 'codesandbox',\n methods: {\n sandbox: {\n // Collection operations (compute.sandbox.*)\n create: async (config: CodesandboxConfig, options?: CreateSandboxOptions) => {\n // Validate API key\n const apiKey = config.apiKey || (typeof process !== 'undefined' && process.env?.CSB_API_KEY) || '';\n\n if (!apiKey) {\n throw new Error(\n `Missing CodeSandbox API key. Provide 'apiKey' in config or set CSB_API_KEY environment variable. Get your API key from https://codesandbox.io/t/api`\n );\n }\n\n const sdk = new CodeSandbox(apiKey);\n\n try {\n let sandbox: CodesandboxSandbox;\n let sandboxId: string;\n\n if (options?.sandboxId) {\n // Resume existing CodeSandbox using sdk.sandboxes.resume()\n sandbox = await sdk.sandboxes.resume(options.sandboxId);\n sandboxId = options.sandboxId;\n } else {\n // Create new CodeSandbox using sdk.sandboxes.create()\n const createOptions: any = {};\n \n if (config.templateId) {\n createOptions.id = config.templateId;\n }\n\n sandbox = await sdk.sandboxes.create(createOptions);\n sandboxId = sandbox.id;\n }\n\n return {\n sandbox,\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 `CodeSandbox authentication failed. Please check your CSB_API_KEY environment variable. Get your API key from https://codesandbox.io/t/api`\n );\n }\n if (error.message.includes('quota') || error.message.includes('limit')) {\n throw new Error(\n `CodeSandbox quota exceeded. Please check your usage at https://codesandbox.io/dashboard`\n );\n }\n }\n throw new Error(\n `Failed to create CodeSandbox sandbox: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n getById: async (config: CodesandboxConfig, sandboxId: string) => {\n const apiKey = config.apiKey || (typeof process !== 'undefined' && process.env?.CSB_API_KEY) || '';\n\n if (!apiKey) {\n throw new Error(\n `Missing CodeSandbox API key. Provide 'apiKey' in config or set CSB_API_KEY environment variable.`\n );\n }\n\n const sdk = new CodeSandbox(apiKey);\n\n try {\n // Resume existing sandbox using sdk.sandboxes.resume()\n const sandbox = await sdk.sandboxes.resume(sandboxId);\n\n return {\n sandbox,\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: CodesandboxConfig) => {\n throw new Error(\n `CodeSandbox provider does not support listing sandboxes. CodeSandbox SDK does not provide a native list API. Consider using the CodeSandbox dashboard or implement your own tracking system.`\n );\n },\n\n destroy: async (config: CodesandboxConfig, sandboxId: string) => {\n const apiKey = config.apiKey || (typeof process !== 'undefined' && process.env?.CSB_API_KEY) || '';\n\n if (!apiKey) {\n throw new Error(\n `Missing CodeSandbox API key. Provide 'apiKey' in config or set CSB_API_KEY environment variable.`\n );\n }\n\n const sdk = new CodeSandbox(apiKey);\n\n try {\n // Shutdown the sandbox using sdk.sandboxes.shutdown() to clean it up\n await sdk.sandboxes.shutdown(sandboxId);\n } catch (error) {\n // Sandbox might already be shutdown or doesn't exist\n // This is acceptable for destroy operations\n }\n },\n\n // Instance operations (sandbox.*)\n runCode: async (sandbox: CodesandboxSandbox, code: string, runtime?: Runtime): Promise<CodeResult> => {\n const startTime = Date.now();\n\n try {\n // Connect to the sandbox client using sandbox.connect()\n const client = await sandbox.connect();\n\n // Auto-detect runtime if not specified\n const effectiveRuntime = runtime || (\n // Strong Python indicators\n code.includes('print(') || \n code.includes('import ') ||\n code.includes('def ') ||\n code.includes('sys.') ||\n code.includes('json.') ||\n code.includes('__') ||\n code.includes('f\"') ||\n code.includes(\"f'\") ||\n code.includes('raise ')\n ? 'python'\n // Default to Node.js for all other cases (including ambiguous)\n : 'node'\n );\n\n // Use base64 encoding for reliability and consistency\n const encoded = Buffer.from(code).toString('base64');\n let command: string;\n\n if (effectiveRuntime === 'python') {\n // Execute Python code using client.commands.run()\n command = `echo \"${encoded}\" | base64 -d | python3`;\n } else {\n // Execute Node.js code using client.commands.run()\n command = `echo \"${encoded}\" | base64 -d | node`;\n }\n\n // Execute the command using CodeSandbox client.commands.run()\n // This returns the full output as a string\n const output = await client.commands.run(command);\n\n // Check for syntax errors in the output and throw them (similar to other providers)\n if (output.includes('SyntaxError') ||\n output.includes('invalid syntax') ||\n output.includes('Unexpected token') ||\n output.includes('Unexpected identifier')) {\n throw new Error(`Syntax error: ${output.trim()}`);\n }\n\n return {\n output: output,\n exitCode: 0,\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 `CodeSandbox execution failed: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n runCommand: async (sandbox: CodesandboxSandbox, command: string, args: string[] = []): Promise<CommandResult> => {\n const startTime = Date.now();\n\n try {\n // Connect to the sandbox client using sandbox.connect()\n const client = await sandbox.connect();\n\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 CodeSandbox client.commands.run()\n const output = await client.commands.run(fullCommand);\n\n return {\n stdout: output,\n stderr: '',\n exitCode: 0,\n durationMs: Date.now() - startTime\n };\n } catch (error) {\n return {\n stdout: '',\n stderr: error instanceof Error ? error.message : String(error),\n exitCode: 127,\n durationMs: Date.now() - startTime\n };\n }\n },\n\n getInfo: async (sandbox: CodesandboxSandbox): Promise<SandboxInfo> => {\n return {\n id: sandbox.id,\n provider: 'codesandbox',\n runtime: 'node', // CodeSandbox default\n status: 'running',\n createdAt: new Date(),\n timeout: 300000,\n metadata: {\n cluster: sandbox.cluster,\n bootupType: sandbox.bootupType,\n isUpToDate: sandbox.isUpToDate\n }\n };\n },\n\n getUrl: async (sandbox: CodesandboxSandbox, options: { port: number; protocol?: string }): Promise<string> => {\n const protocol = options.protocol || 'https';\n // CodeSandbox provides URLs in the format: https://{sandbox-id}.{cluster}.csb.app:{port}\n // Use the actual CodeSandbox URL format\n return `${protocol}://${sandbox.id}.${sandbox.cluster}.csb.app:${options.port}`;\n },\n\n // Filesystem operations using CodeSandbox client.fs API\n filesystem: {\n readFile: async (sandbox: CodesandboxSandbox, path: string): Promise<string> => {\n // Connect to the sandbox client and use client.fs.readTextFile()\n const client = await sandbox.connect();\n return await client.fs.readTextFile(path);\n },\n\n writeFile: async (sandbox: CodesandboxSandbox, path: string, content: string): Promise<void> => {\n // Connect to the sandbox client and use client.fs.writeTextFile()\n const client = await sandbox.connect();\n await client.fs.writeTextFile(path, content);\n },\n\n mkdir: async (sandbox: CodesandboxSandbox, path: string): Promise<void> => {\n // CodeSandbox doesn't have a direct mkdir API, use commands to create directory\n const client = await sandbox.connect();\n await client.commands.run(`mkdir -p \"${path}\"`);\n },\n\n readdir: async (sandbox: CodesandboxSandbox, path: string): Promise<FileEntry[]> => {\n // Connect to the sandbox client and use client.fs.readdir()\n const client = await sandbox.connect();\n const entries = await client.fs.readdir(path);\n\n return entries.map((entry: any) => ({\n name: entry.name,\n type: entry.isDirectory ? 'directory' as const : 'file' as const,\n size: entry.size || 0,\n modified: entry.lastModified ? new Date(entry.lastModified) : new Date()\n }));\n },\n\n exists: async (sandbox: CodesandboxSandbox, path: string): Promise<boolean> => {\n // CodeSandbox doesn't have a direct exists API, use ls command to check\n const client = await sandbox.connect();\n try {\n await client.commands.run(`ls \"${path}\"`);\n return true;\n } catch {\n return false;\n }\n },\n\n remove: async (sandbox: CodesandboxSandbox, path: string): Promise<void> => {\n // Connect to the sandbox client and use client.fs.remove()\n const client = await sandbox.connect();\n await client.fs.remove(path);\n }\n },\n\n // Provider-specific typed getInstance method\n getInstance: (sandbox: CodesandboxSandbox): CodesandboxSandbox => {\n return sandbox;\n },\n\n }\n }\n});\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@computesdk/codesandbox",
3
- "version": "1.5.6",
3
+ "version": "1.5.8",
4
4
  "description": "CodeSandbox provider for ComputeSDK - fast browser-compatible sandboxes with npm and Python support",
5
5
  "author": "Garrison",
6
6
  "license": "MIT",
@@ -19,7 +19,8 @@
19
19
  ],
20
20
  "dependencies": {
21
21
  "@codesandbox/sdk": "^2.0.7",
22
- "computesdk": "1.10.0"
22
+ "@computesdk/provider": "1.0.2",
23
+ "computesdk": "1.10.2"
23
24
  },
24
25
  "keywords": [
25
26
  "computesdk",