@mastra/daytona 0.0.1

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.
@@ -0,0 +1,224 @@
1
+ /**
2
+ * Daytona Sandbox Provider
3
+ *
4
+ * A Daytona sandbox implementation for Mastra workspaces.
5
+ * Supports command execution, environment variables, resource configuration,
6
+ * snapshots, and Daytona volumes.
7
+ *
8
+ * @see https://www.daytona.io/docs
9
+ */
10
+ import type { Sandbox, VolumeMount } from '@daytonaio/sdk';
11
+ import type { SandboxInfo, ProviderStatus, MastraSandboxOptions } from '@mastra/core/workspace';
12
+ import { MastraSandbox } from '@mastra/core/workspace';
13
+ import type { DaytonaResources } from './types.js';
14
+ /**
15
+ * Daytona sandbox provider configuration.
16
+ */
17
+ export interface DaytonaSandboxOptions extends MastraSandboxOptions {
18
+ /** Unique identifier for this sandbox instance */
19
+ id?: string;
20
+ /** API key for authentication. Falls back to DAYTONA_API_KEY env var. */
21
+ apiKey?: string;
22
+ /** API URL. Falls back to DAYTONA_API_URL env var or https://app.daytona.io/api. */
23
+ apiUrl?: string;
24
+ /** Target runner region. Falls back to DAYTONA_TARGET env var. */
25
+ target?: string;
26
+ /**
27
+ * Default execution timeout in milliseconds.
28
+ * @default 300_000 // 5 minutes
29
+ */
30
+ timeout?: number;
31
+ /**
32
+ * Sandbox runtime language.
33
+ * @default 'typescript'
34
+ */
35
+ language?: 'typescript' | 'javascript' | 'python';
36
+ /** Resource allocation for the sandbox */
37
+ resources?: DaytonaResources;
38
+ /** Environment variables to set in the sandbox */
39
+ env?: Record<string, string>;
40
+ /** Custom metadata labels */
41
+ labels?: Record<string, string>;
42
+ /** Pre-built snapshot ID to create sandbox from. Takes precedence over resources/image. */
43
+ snapshot?: string;
44
+ /**
45
+ * Docker image to use for sandbox creation. When set, triggers image-based creation.
46
+ * Can optionally be combined with `resources` for custom resource allocation.
47
+ * Has no effect when `snapshot` is set.
48
+ */
49
+ image?: string;
50
+ /**
51
+ * Whether the sandbox should be ephemeral. If true, autoDeleteInterval will be set to 0
52
+ * (delete immediately on stop).
53
+ * @default false
54
+ */
55
+ ephemeral?: boolean;
56
+ /**
57
+ * Auto-stop interval in minutes (0 = disabled).
58
+ * @default 15
59
+ */
60
+ autoStopInterval?: number;
61
+ /**
62
+ * Auto-archive interval in minutes (0 = maximum interval, which is 7 days).
63
+ * @default 7 days
64
+ */
65
+ autoArchiveInterval?: number;
66
+ /**
67
+ * Daytona volumes to attach at creation.
68
+ * Volumes are configured at sandbox creation time, not mounted dynamically.
69
+ */
70
+ volumes?: Array<VolumeMount>;
71
+ /** Sandbox display name */
72
+ name?: string;
73
+ /** OS user to use for the sandbox */
74
+ user?: string;
75
+ /** Whether the sandbox port preview is public */
76
+ public?: boolean;
77
+ /**
78
+ * Auto-delete interval in minutes (negative = disabled, 0 = delete immediately on stop).
79
+ * @default disabled
80
+ */
81
+ autoDeleteInterval?: number;
82
+ /** Whether to block all network access for the sandbox */
83
+ networkBlockAll?: boolean;
84
+ /** Comma-separated list of allowed CIDR network addresses for the sandbox */
85
+ networkAllowList?: string;
86
+ }
87
+ /**
88
+ * Daytona sandbox provider for Mastra workspaces.
89
+ *
90
+ * Features:
91
+ * - Isolated cloud sandbox via Daytona SDK
92
+ * - Multi-runtime support (TypeScript, JavaScript, Python)
93
+ * - Resource configuration (CPU, memory, disk)
94
+ * - Volume attachment at creation time
95
+ * - Automatic sandbox timeout handling with retry
96
+ *
97
+ * @example Basic usage
98
+ * ```typescript
99
+ * import { Workspace } from '@mastra/core/workspace';
100
+ * import { DaytonaSandbox } from '@mastra/daytona';
101
+ *
102
+ * const sandbox = new DaytonaSandbox({
103
+ * timeout: 60000,
104
+ * language: 'typescript',
105
+ * });
106
+ *
107
+ * const workspace = new Workspace({ sandbox });
108
+ * const result = await workspace.executeCode('console.log("Hello!")');
109
+ * ```
110
+ *
111
+ * @example With resources and volumes
112
+ * ```typescript
113
+ * const sandbox = new DaytonaSandbox({
114
+ * resources: { cpu: 2, memory: 4, disk: 6 },
115
+ * volumes: [{ volumeId: 'vol-123', mountPath: '/data' }],
116
+ * env: { NODE_ENV: 'production' },
117
+ * });
118
+ * ```
119
+ */
120
+ export declare class DaytonaSandbox extends MastraSandbox {
121
+ readonly id: string;
122
+ readonly name = "DaytonaSandbox";
123
+ readonly provider = "daytona";
124
+ status: ProviderStatus;
125
+ private _daytona;
126
+ private _sandbox;
127
+ private _createdAt;
128
+ private _isRetrying;
129
+ private _workingDir;
130
+ private readonly timeout;
131
+ private readonly language;
132
+ private readonly resources?;
133
+ private readonly env;
134
+ private readonly labels;
135
+ private readonly snapshotId?;
136
+ private readonly image?;
137
+ private readonly ephemeral;
138
+ private readonly autoStopInterval?;
139
+ private readonly autoArchiveInterval?;
140
+ private readonly autoDeleteInterval?;
141
+ private readonly volumeConfigs;
142
+ private readonly sandboxName?;
143
+ private readonly sandboxUser?;
144
+ private readonly sandboxPublic?;
145
+ private readonly networkBlockAll?;
146
+ private readonly networkAllowList?;
147
+ private readonly connectionOpts;
148
+ constructor(options?: DaytonaSandboxOptions);
149
+ private generateId;
150
+ /**
151
+ * Get the underlying Daytona Sandbox instance for direct access to Daytona APIs.
152
+ *
153
+ * Use this when you need to access Daytona features not exposed through the
154
+ * WorkspaceSandbox interface (e.g., filesystem API, git operations, LSP).
155
+ *
156
+ * @throws {SandboxNotReadyError} If the sandbox has not been started
157
+ *
158
+ * @example Direct file operations
159
+ * ```typescript
160
+ * const daytonaSandbox = sandbox.instance;
161
+ * await daytonaSandbox.fs.uploadFile(Buffer.from('Hello'), '/tmp/test.txt');
162
+ * ```
163
+ */
164
+ get instance(): Sandbox;
165
+ /**
166
+ * Start the Daytona sandbox.
167
+ * Reconnects to an existing sandbox with the same logical ID if one exists,
168
+ * otherwise creates a new sandbox instance.
169
+ */
170
+ start(): Promise<void>;
171
+ /**
172
+ * Stop the Daytona sandbox.
173
+ * Stops the sandbox instance and releases the reference.
174
+ */
175
+ stop(): Promise<void>;
176
+ /**
177
+ * Destroy the Daytona sandbox and clean up all resources.
178
+ * Deletes the sandbox and clears all state.
179
+ */
180
+ destroy(): Promise<void>;
181
+ /**
182
+ * Check if the sandbox is ready for operations.
183
+ */
184
+ isReady(): Promise<boolean>;
185
+ /**
186
+ * Get information about the current state of the sandbox.
187
+ */
188
+ getInfo(): Promise<SandboxInfo>;
189
+ /**
190
+ * Get instructions describing this Daytona sandbox.
191
+ * Used by agents to understand the execution environment.
192
+ */
193
+ getInstructions(): string;
194
+ /**
195
+ * Detect the actual working directory inside the sandbox via `pwd`.
196
+ * Stores the result for use in `getInstructions()`.
197
+ */
198
+ private detectWorkingDir;
199
+ /**
200
+ * Try to find and reconnect to an existing Daytona sandbox with the same
201
+ * logical ID (via the mastra-sandbox-id label). Returns the sandbox if
202
+ * found and usable, or null if a fresh sandbox should be created.
203
+ */
204
+ private findExistingSandbox;
205
+ /**
206
+ * Check if an error indicates the sandbox is dead/gone.
207
+ * Uses DaytonaNotFoundError from the SDK when available,
208
+ * with string fallback for edge cases.
209
+ *
210
+ * String patterns observed in @daytonaio/sdk@0.143.0 error messages.
211
+ * Update if SDK error messages change in future versions.
212
+ */
213
+ private isSandboxDeadError;
214
+ /**
215
+ * Handle sandbox timeout by clearing the instance and resetting state.
216
+ */
217
+ private handleSandboxTimeout;
218
+ /**
219
+ * Execute a function, retrying once if the sandbox is found to be dead.
220
+ * Used by DaytonaProcessManager to handle stale sandboxes transparently.
221
+ */
222
+ retryOnDead<T>(fn: () => Promise<T>): Promise<T>;
223
+ }
224
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/sandbox/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Daytona Process Manager
3
+ *
4
+ * Implements SandboxProcessManager for Daytona cloud sandboxes.
5
+ * Wraps the Daytona SDK's session API (createSession, executeSessionCommand,
6
+ * getSessionCommandLogs, deleteSession) for background process management.
7
+ *
8
+ * Each spawn() creates a dedicated session with a single command.
9
+ * The user command is wrapped in a subshell `(command)` so that:
10
+ * - `exit N` exits the subshell, not the session shell
11
+ * - Heredocs are contained within the subshell
12
+ * - The session command finishes cleanly
13
+ */
14
+ import { ProcessHandle, SandboxProcessManager } from '@mastra/core/workspace';
15
+ import type { ProcessInfo, SpawnProcessOptions } from '@mastra/core/workspace';
16
+ import type { DaytonaSandbox } from './index.js';
17
+ export interface DaytonaProcessManagerOptions {
18
+ env?: Record<string, string | undefined>;
19
+ /** Default timeout in milliseconds for commands that don't specify one. */
20
+ defaultTimeout?: number;
21
+ }
22
+ /**
23
+ * Daytona implementation of SandboxProcessManager.
24
+ * Uses the Daytona SDK's session API with one session per spawned process.
25
+ */
26
+ export declare class DaytonaProcessManager extends SandboxProcessManager<DaytonaSandbox> {
27
+ private _nextPid;
28
+ private readonly _defaultTimeout?;
29
+ constructor(opts?: DaytonaProcessManagerOptions);
30
+ spawn(command: string, options?: SpawnProcessOptions): Promise<ProcessHandle>;
31
+ list(): Promise<ProcessInfo[]>;
32
+ get(pid: number): Promise<ProcessHandle | undefined>;
33
+ }
34
+ //# sourceMappingURL=process-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"process-manager.d.ts","sourceRoot":"","sources":["../../src/sandbox/process-manager.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,EAAE,aAAa,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAC9E,OAAO,KAAK,EAAiB,WAAW,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAE9F,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AA2J9C,MAAM,WAAW,4BAA4B;IAC3C,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IACzC,2EAA2E;IAC3E,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;;GAGG;AACH,qBAAa,qBAAsB,SAAQ,qBAAqB,CAAC,cAAc,CAAC;IAC9E,OAAO,CAAC,QAAQ,CAAK;IACrB,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAS;gBAE9B,IAAI,GAAE,4BAAiC;IAK7C,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,mBAAwB,GAAG,OAAO,CAAC,aAAa,CAAC;IAkDjF,IAAI,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;IAa9B,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,SAAS,CAAC;CAG3D"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Daytona Sandbox Types
3
+ */
4
+ /**
5
+ * Resource allocation for Daytona sandboxes.
6
+ */
7
+ export interface DaytonaResources {
8
+ /** CPU cores */
9
+ cpu?: number;
10
+ /** Memory in GiB */
11
+ memory?: number;
12
+ /** Disk in GiB */
13
+ disk?: number;
14
+ }
15
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/sandbox/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,gBAAgB;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,oBAAoB;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,kBAAkB;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Returns a shallow copy of the object with all undefined values removed.
3
+ */
4
+ export declare function compact<T extends object>(obj: T): T;
5
+ //# sourceMappingURL=compact.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compact.d.ts","sourceRoot":"","sources":["../../src/utils/compact.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,wBAAgB,OAAO,CAAC,CAAC,SAAS,MAAM,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,CAEnD"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Shell-quote a single argument for safe use in a command string.
3
+ *
4
+ * Arguments containing only safe characters are returned as-is.
5
+ * All others are wrapped in single quotes with embedded single quotes escaped.
6
+ */
7
+ export declare function shellQuote(arg: string): string;
8
+ //# sourceMappingURL=shell-quote.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shell-quote.d.ts","sourceRoot":"","sources":["../../src/utils/shell-quote.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAK9C"}
package/package.json ADDED
@@ -0,0 +1,68 @@
1
+ {
2
+ "name": "@mastra/daytona",
3
+ "version": "0.0.1",
4
+ "description": "Daytona cloud sandbox provider for Mastra workspaces",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "import": {
11
+ "types": "./dist/index.d.ts",
12
+ "default": "./dist/index.js"
13
+ },
14
+ "require": {
15
+ "types": "./dist/index.d.ts",
16
+ "default": "./dist/index.cjs"
17
+ }
18
+ },
19
+ "./package.json": "./package.json"
20
+ },
21
+ "license": "Apache-2.0",
22
+ "dependencies": {
23
+ "@daytonaio/sdk": "^0.143.0"
24
+ },
25
+ "devDependencies": {
26
+ "@types/node": "22.19.7",
27
+ "@vitest/coverage-v8": "4.0.18",
28
+ "@vitest/ui": "4.0.18",
29
+ "dotenv": "^17.2.3",
30
+ "eslint": "^9.37.0",
31
+ "tsup": "^8.5.1",
32
+ "typescript": "^5.9.3",
33
+ "vitest": "4.0.18",
34
+ "@internal/lint": "0.0.63",
35
+ "@internal/workspace-test-utils": "0.0.7",
36
+ "@internal/types-builder": "0.0.38",
37
+ "@mastra/core": "1.8.0"
38
+ },
39
+ "peerDependencies": {
40
+ "@mastra/core": ">=1.3.0-0 <2.0.0-0"
41
+ },
42
+ "files": [
43
+ "dist",
44
+ "CHANGELOG.md"
45
+ ],
46
+ "homepage": "https://mastra.ai",
47
+ "repository": {
48
+ "type": "git",
49
+ "url": "git+https://github.com/mastra-ai/mastra.git",
50
+ "directory": "workspaces/daytona"
51
+ },
52
+ "bugs": {
53
+ "url": "https://github.com/mastra-ai/mastra/issues"
54
+ },
55
+ "engines": {
56
+ "node": ">=22.13.0"
57
+ },
58
+ "scripts": {
59
+ "build": "tsup --silent --config tsup.config.ts",
60
+ "build:lib": "pnpm build",
61
+ "build:watch": "pnpm build --watch",
62
+ "test:unit": "vitest run --exclude '**/*.integration.test.ts'",
63
+ "test:watch": "vitest watch",
64
+ "test": "vitest run ./src/**/*.integration.test.ts",
65
+ "test:cloud": "pnpm test",
66
+ "lint": "eslint ."
67
+ }
68
+ }