@opencoredev/sandbox-sdk 0.1.1 → 1.0.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (158) hide show
  1. package/CHANGELOG.md +34 -7
  2. package/README.md +350 -23
  3. package/dist/ai.d.ts +5 -0
  4. package/dist/ai.js +1 -0
  5. package/dist/chunk-59t3rqja.js +2 -0
  6. package/dist/chunk-cwx6cc31.js +2 -0
  7. package/dist/chunk-exv1kf89.js +60 -0
  8. package/dist/chunk-gc8zdxyb.js +2 -0
  9. package/dist/chunk-hjzhc3qg.js +40 -0
  10. package/dist/chunk-md6fmprc.js +1 -0
  11. package/dist/chunk-t5vr9nd8.js +8 -0
  12. package/dist/chunk-v6y7eqxw.js +27 -0
  13. package/dist/chunk-yed8mvs7.js +2 -0
  14. package/dist/chunk-yrsb6hws.js +5 -0
  15. package/dist/chunk-z9rjzn28.js +2 -0
  16. package/dist/errors.d.ts +60 -0
  17. package/dist/files.d.ts +57 -0
  18. package/dist/git.d.ts +28 -0
  19. package/dist/handle.d.ts +4 -0
  20. package/dist/index.d.ts +17 -0
  21. package/dist/index.js +1 -0
  22. package/dist/keys.d.ts +5 -0
  23. package/dist/logs.d.ts +8 -0
  24. package/dist/mastra.d.ts +43 -0
  25. package/dist/mastra.js +1 -0
  26. package/dist/memory.d.ts +34 -0
  27. package/dist/memory.js +11 -0
  28. package/dist/openai.d.ts +39 -0
  29. package/dist/openai.js +1 -0
  30. package/dist/peer.d.ts +5 -0
  31. package/dist/processes.d.ts +71 -0
  32. package/dist/provider.d.ts +138 -0
  33. package/dist/provider.js +0 -0
  34. package/dist/providers/agentos/errors.d.ts +4 -0
  35. package/dist/providers/agentos/index.d.ts +11 -0
  36. package/dist/providers/agentos/index.js +2 -0
  37. package/dist/providers/boat/index.d.ts +23 -0
  38. package/dist/providers/boat/index.js +1 -0
  39. package/dist/providers/boat-api/errors.d.ts +6 -0
  40. package/dist/providers/boat-api/exec.d.ts +11 -0
  41. package/dist/providers/boat-api/index.d.ts +22 -0
  42. package/dist/providers/boxd/errors.d.ts +3 -0
  43. package/dist/providers/boxd/execute.d.ts +3 -0
  44. package/dist/providers/boxd/guest.d.ts +14 -0
  45. package/dist/providers/boxd/index.d.ts +23 -0
  46. package/dist/providers/boxd/index.js +85 -0
  47. package/dist/providers/boxd/transfers.d.ts +19 -0
  48. package/dist/providers/daytona/buffered.d.ts +3 -0
  49. package/dist/providers/daytona/errors.d.ts +3 -0
  50. package/dist/providers/daytona/exec.d.ts +14 -0
  51. package/dist/providers/daytona/index.d.ts +24 -0
  52. package/dist/providers/daytona/index.js +88 -0
  53. package/dist/providers/e2b/errors.d.ts +3 -0
  54. package/dist/providers/e2b/index.d.ts +15 -0
  55. package/dist/providers/e2b/index.js +1 -0
  56. package/dist/providers/freestyle/deadline.d.ts +4 -0
  57. package/dist/providers/freestyle/errors.d.ts +16 -0
  58. package/dist/providers/freestyle/execute.d.ts +12 -0
  59. package/dist/providers/freestyle/index.d.ts +14 -0
  60. package/dist/providers/freestyle/index.js +133 -0
  61. package/dist/providers/freestyle/wire.d.ts +10 -0
  62. package/dist/providers/local/docker.d.ts +32 -0
  63. package/dist/providers/local/index.d.ts +17 -0
  64. package/dist/providers/local/index.js +2 -0
  65. package/dist/providers/railway/errors.d.ts +4 -0
  66. package/dist/providers/railway/index.d.ts +24 -0
  67. package/dist/providers/railway/index.js +1 -0
  68. package/dist/providers/sandboxer/index.d.ts +33 -0
  69. package/dist/providers/sandboxer/index.js +1 -0
  70. package/dist/providers/superserve/bootstrap.d.ts +11 -0
  71. package/dist/providers/superserve/errors.d.ts +3 -0
  72. package/dist/providers/superserve/execute.d.ts +13 -0
  73. package/dist/providers/superserve/index.d.ts +23 -0
  74. package/dist/providers/superserve/index.js +126 -0
  75. package/dist/providers/tenki/deadline.d.ts +2 -0
  76. package/dist/providers/tenki/errors.d.ts +10 -0
  77. package/dist/providers/tenki/exec.d.ts +4 -0
  78. package/dist/providers/tenki/files.d.ts +3 -0
  79. package/dist/providers/tenki/index.d.ts +28 -0
  80. package/dist/providers/tenki/index.js +172 -0
  81. package/dist/providers/tenki/ready.d.ts +7 -0
  82. package/dist/providers/tenki/stream.d.ts +3 -0
  83. package/dist/providers/upstash/buffered.d.ts +3 -0
  84. package/dist/providers/upstash/errors.d.ts +3 -0
  85. package/dist/providers/upstash/exec.d.ts +18 -0
  86. package/dist/providers/upstash/files.d.ts +15 -0
  87. package/dist/providers/upstash/index.d.ts +38 -0
  88. package/dist/providers/upstash/index.js +111 -0
  89. package/dist/providers/vercel/errors.d.ts +3 -0
  90. package/dist/providers/vercel/index.d.ts +14 -0
  91. package/dist/providers/vercel/index.js +1 -0
  92. package/dist/providers/vercel/provider.d.ts +10 -0
  93. package/dist/providers/vercel/transport.d.ts +40 -0
  94. package/dist/run.d.ts +41 -0
  95. package/dist/testing.d.ts +17 -0
  96. package/dist/testing.js +6 -0
  97. package/dist/tool-security.d.ts +9 -0
  98. package/dist/tools.d.ts +117 -0
  99. package/dist/tools.js +1 -0
  100. package/dist/types.d.ts +189 -0
  101. package/package.json +170 -92
  102. package/dist/agentos-DFJ4TFaY.mjs +0 -389
  103. package/dist/agentos-DFJ4TFaY.mjs.map +0 -1
  104. package/dist/ai/harness.d.mts +0 -16
  105. package/dist/ai/harness.mjs +0 -69
  106. package/dist/ai/harness.mjs.map +0 -1
  107. package/dist/ai/index.d.mts +0 -54
  108. package/dist/ai/index.mjs +0 -4
  109. package/dist/ai-DhfwIZdL.mjs +0 -243
  110. package/dist/ai-DhfwIZdL.mjs.map +0 -1
  111. package/dist/capabilities-CEowrzRM.mjs +0 -99
  112. package/dist/capabilities-CEowrzRM.mjs.map +0 -1
  113. package/dist/capabilities-COKpwoFH.mjs +0 -28
  114. package/dist/capabilities-COKpwoFH.mjs.map +0 -1
  115. package/dist/capabilities-DftdOpIu.d.mts +0 -13
  116. package/dist/errors-Ch9PHKTd.mjs +0 -61
  117. package/dist/errors-Ch9PHKTd.mjs.map +0 -1
  118. package/dist/eve/index.d.mts +0 -19
  119. package/dist/eve/index.mjs +0 -155
  120. package/dist/eve/index.mjs.map +0 -1
  121. package/dist/index-Bk6GmoEt.d.mts +0 -25
  122. package/dist/index-BufLdrbp.d.mts +0 -31
  123. package/dist/index.d.mts +0 -5
  124. package/dist/index.mjs +0 -38
  125. package/dist/index.mjs.map +0 -1
  126. package/dist/mastra/index.d.mts +0 -118
  127. package/dist/mastra/index.mjs +0 -662
  128. package/dist/mastra/index.mjs.map +0 -1
  129. package/dist/metadata.d.mts +0 -34
  130. package/dist/metadata.mjs +0 -103
  131. package/dist/metadata.mjs.map +0 -1
  132. package/dist/provider-BzzkIVmv.d.mts +0 -91
  133. package/dist/provider-utils-BjOSWNsh.mjs +0 -201
  134. package/dist/provider-utils-BjOSWNsh.mjs.map +0 -1
  135. package/dist/providers/agentos/index.d.mts +0 -7
  136. package/dist/providers/agentos/index.mjs +0 -8
  137. package/dist/providers/daytona/index.d.mts +0 -21
  138. package/dist/providers/daytona/index.mjs +0 -205
  139. package/dist/providers/daytona/index.mjs.map +0 -1
  140. package/dist/providers/e2b/index.d.mts +0 -17
  141. package/dist/providers/e2b/index.mjs +0 -168
  142. package/dist/providers/e2b/index.mjs.map +0 -1
  143. package/dist/providers/local/index.d.mts +0 -22
  144. package/dist/providers/local/index.mjs +0 -21
  145. package/dist/providers/local/index.mjs.map +0 -1
  146. package/dist/providers/upstash/index.d.mts +0 -17
  147. package/dist/providers/upstash/index.mjs +0 -210
  148. package/dist/providers/upstash/index.mjs.map +0 -1
  149. package/dist/providers/vercel/index.d.mts +0 -28
  150. package/dist/providers/vercel/index.mjs +0 -185
  151. package/dist/providers/vercel/index.mjs.map +0 -1
  152. package/dist/sandbox-Dco6z9aB.d.mts +0 -26
  153. package/dist/sandbox-rIOcbhtM.mjs +0 -112
  154. package/dist/sandbox-rIOcbhtM.mjs.map +0 -1
  155. package/dist/testing/index.d.mts +0 -27
  156. package/dist/testing/index.mjs +0 -173
  157. package/dist/testing/index.mjs.map +0 -1
  158. package/dist/types-DEi_dfRR.d.mts +0 -103
@@ -1,662 +0,0 @@
1
- import { n as isSandboxError, t as SandboxError } from "../errors-Ch9PHKTd.mjs";
2
- import { DirectoryNotEmptyError, DirectoryNotFoundError, FileExistsError, FileNotFoundError, IsDirectoryError, MastraFilesystem, MastraSandbox, NotDirectoryError, PermissionError, ProcessHandle, SandboxNotReadyError, SandboxProcessManager, StaleFileError, Workspace, WorkspaceReadOnlyError } from "@mastra/core/workspace";
3
-
4
- //#region src/mastra/index.ts
5
- /** Create a Mastra sandbox backed by any managed Sandbox SDK provider. */
6
- function createMastraSandbox(options) {
7
- return new SandboxSDKMastraSandbox(options);
8
- }
9
- /**
10
- * Create a Mastra workspace whose filesystem and commands share one Sandbox SDK
11
- * session. The workspace owns and destroys the session.
12
- */
13
- function createMastraWorkspace(options) {
14
- const sandbox = createMastraSandbox(options);
15
- const filesystem = new SandboxSDKMastraFilesystem({
16
- ...options.filesystem,
17
- sandbox
18
- });
19
- return new Workspace({
20
- ...options.workspace,
21
- filesystem,
22
- sandbox
23
- });
24
- }
25
- /** Mastra WorkspaceSandbox implementation for Sandbox SDK providers. */
26
- var SandboxSDKMastraSandbox = class extends MastraSandbox {
27
- id;
28
- name;
29
- provider;
30
- cwd;
31
- processes;
32
- status = "pending";
33
- managed;
34
- identity;
35
- env;
36
- ports;
37
- instructions;
38
- onFirstCreate;
39
- createdAt = /* @__PURE__ */ new Date();
40
- session;
41
- constructor(options) {
42
- const processes = new SandboxSDKProcessManager({ env: options.env });
43
- super({
44
- ...options,
45
- name: "Sandbox SDK",
46
- processes
47
- });
48
- this.managed = requireManaged(options.provider);
49
- this.id = options.id ?? `mastra-${options.provider.id}-${crypto.randomUUID()}`;
50
- this.name = `Sandbox SDK (${options.provider.id})`;
51
- this.provider = options.provider.id;
52
- this.cwd = normalizeCwd(options.cwd ?? "/workspace");
53
- this.env = options.env ?? {};
54
- this.ports = options.ports ?? [];
55
- this.identity = options.identity;
56
- this.instructions = options.instructions;
57
- this.onFirstCreate = options.onFirstCreate;
58
- this.processes = processes;
59
- }
60
- /** The live normalized Sandbox SDK session. */
61
- get sandboxSdk() {
62
- if (!this.session) throw new SandboxNotReadyError(this.id);
63
- return this.session.sandbox;
64
- }
65
- async start() {
66
- if (this.session) {
67
- await this.session.resume();
68
- return;
69
- }
70
- this.session = await this.managed.create({
71
- sessionId: this.id,
72
- identity: this.identity,
73
- cwd: this.cwd,
74
- env: this.env,
75
- ports: this.ports,
76
- onFirstCreate: this.onFirstCreate
77
- });
78
- }
79
- async stop() {
80
- if (!this.session) return;
81
- await this.killTrackedProcesses();
82
- await this.session.stop();
83
- }
84
- async destroy() {
85
- if (!this.session) return;
86
- await this.killTrackedProcesses();
87
- const session = this.session;
88
- this.session = void 0;
89
- await session.destroy();
90
- }
91
- async getPortUrl(port, protocol) {
92
- await this.ensureRunning();
93
- return this.session.getPortUrl({
94
- port,
95
- protocol
96
- });
97
- }
98
- getInfo() {
99
- return {
100
- id: this.id,
101
- name: this.name,
102
- provider: this.provider,
103
- status: this.status,
104
- createdAt: this.createdAt,
105
- metadata: {
106
- sandboxId: this.session?.sandbox.id,
107
- sandboxProvider: this.provider,
108
- cwd: this.cwd,
109
- capabilities: this.session?.sandbox.capabilities
110
- }
111
- };
112
- }
113
- getInstructions(options) {
114
- const defaultInstructions = `Commands run in an isolated ${this.provider} sandbox. The default working directory is ${this.cwd}.`;
115
- if (this.instructions === void 0) return defaultInstructions;
116
- if (typeof this.instructions === "string") return this.instructions;
117
- return this.instructions({
118
- defaultInstructions,
119
- requestContext: options?.requestContext
120
- });
121
- }
122
- /** @deprecated Use `status === "running"` instead. */
123
- isReady() {
124
- return this.status === "running" && this.session !== void 0;
125
- }
126
- async killTrackedProcesses() {
127
- const processes = await this.processes.list().catch(() => []);
128
- await Promise.all(processes.filter((process) => process.running).map((process) => this.processes.kill(process.pid).catch(() => false)));
129
- }
130
- };
131
- /** Mastra background-process bridge for normalized Sandbox SDK processes. */
132
- var SandboxSDKProcessManager = class extends SandboxProcessManager {
133
- async spawn(command, options = {}) {
134
- const env = Object.fromEntries(Object.entries({
135
- ...this.env,
136
- ...options.env
137
- }).filter((entry) => entry[1] !== void 0));
138
- const handle = new SandboxSDKProcessHandle(await this.sandbox.sandboxSdk.processes.start(parseSimpleCommand(command) ?? command, {
139
- cwd: options.cwd,
140
- env,
141
- timeout: options.timeout,
142
- signal: options.abortSignal
143
- }), options);
144
- this._tracked.set(handle.pid, handle);
145
- return handle;
146
- }
147
- async list() {
148
- return Promise.all([...this._tracked.values()].map(async (handle) => {
149
- const adapter = handle;
150
- return {
151
- pid: handle.pid,
152
- command: handle.command,
153
- running: await adapter.isRunning(),
154
- ...handle.exitCode === void 0 ? {} : { exitCode: handle.exitCode }
155
- };
156
- }));
157
- }
158
- };
159
- var SandboxSDKProcessHandle = class extends ProcessHandle {
160
- pid;
161
- process;
162
- startedAt = performance.now();
163
- completed;
164
- currentExitCode;
165
- killed = false;
166
- timedOut = false;
167
- timeoutId;
168
- constructor(process, options) {
169
- super(options);
170
- this.process = process;
171
- this.pid = process.id;
172
- if (options.timeout !== void 0 && options.timeout > 0) this.timeoutId = setTimeout(() => {
173
- this.timedOut = true;
174
- this.kill();
175
- }, options.timeout);
176
- this.completed = this.collect();
177
- }
178
- get exitCode() {
179
- return this.currentExitCode;
180
- }
181
- async wait() {
182
- return this.completed;
183
- }
184
- async kill() {
185
- if (this.currentExitCode !== void 0) return false;
186
- this.killed = true;
187
- await this.process.kill();
188
- return true;
189
- }
190
- async sendStdin(data) {
191
- if (this.currentExitCode !== void 0) throw new Error(`Process ${this.pid} has already exited with code ${this.currentExitCode}`);
192
- await this.process.write(data);
193
- }
194
- async isRunning() {
195
- if (this.currentExitCode !== void 0) return false;
196
- const status = await this.process.status();
197
- return status === "starting" || status === "running";
198
- }
199
- async collect() {
200
- const output = this.pumpOutput();
201
- try {
202
- const result = await this.process.wait();
203
- this.currentExitCode = this.timedOut ? 124 : result.exitCode;
204
- await output;
205
- } catch (error) {
206
- await output.catch(() => void 0);
207
- if (isSandboxError(error) && error.code === "timeout") this.timedOut = true;
208
- this.currentExitCode = this.timedOut ? 124 : 1;
209
- this.emitStderr(error instanceof Error ? error.message : String(error));
210
- } finally {
211
- if (this.timeoutId) clearTimeout(this.timeoutId);
212
- }
213
- return {
214
- success: this.currentExitCode === 0,
215
- exitCode: this.currentExitCode,
216
- stdout: this.stdout,
217
- stderr: this.stderr,
218
- executionTimeMs: Math.round(performance.now() - this.startedAt),
219
- ...this.killed ? { killed: true } : {},
220
- ...this.timedOut ? { timedOut: true } : {}
221
- };
222
- }
223
- async pumpOutput() {
224
- const decoders = {
225
- stdout: new TextDecoder(),
226
- stderr: new TextDecoder()
227
- };
228
- try {
229
- for await (const event of this.process.output()) {
230
- const data = typeof event.data === "string" ? event.data : decoders[event.stream].decode(event.data, { stream: true });
231
- if (data) if (event.stream === "stdout") this.emitStdout(data);
232
- else this.emitStderr(data);
233
- }
234
- } finally {
235
- const stdout = decoders.stdout.decode();
236
- const stderr = decoders.stderr.decode();
237
- if (stdout) this.emitStdout(stdout);
238
- if (stderr) this.emitStderr(stderr);
239
- }
240
- }
241
- };
242
- /** Mastra WorkspaceFilesystem implementation sharing a Mastra sandbox session. */
243
- var SandboxSDKMastraFilesystem = class extends MastraFilesystem {
244
- id;
245
- name = "Sandbox SDK Filesystem";
246
- provider = "sandbox-sdk";
247
- readOnly;
248
- basePath;
249
- status = "pending";
250
- sandbox;
251
- instructions;
252
- constructor(options) {
253
- super({
254
- ...options,
255
- name: "Sandbox SDK Filesystem"
256
- });
257
- this.sandbox = options.sandbox;
258
- this.id = `${options.sandbox.id}-filesystem`;
259
- this.basePath = options.sandbox.cwd;
260
- this.readOnly = options.readOnly ?? false;
261
- this.instructions = options.instructions;
262
- }
263
- async init() {}
264
- async destroy() {}
265
- getInfo() {
266
- return {
267
- id: this.id,
268
- name: this.name,
269
- provider: this.provider,
270
- status: this.status,
271
- readOnly: this.readOnly,
272
- metadata: {
273
- sandboxId: this.sandbox.id,
274
- sandboxProvider: this.sandbox.provider,
275
- basePath: this.basePath
276
- }
277
- };
278
- }
279
- getInstructions(options) {
280
- const defaultInstructions = `Files are stored in the same ${this.sandbox.provider} sandbox used for commands. Filesystem path / maps to ${this.basePath} inside the sandbox.`;
281
- if (this.instructions === void 0) return defaultInstructions;
282
- if (typeof this.instructions === "string") return this.instructions;
283
- return this.instructions({
284
- defaultInstructions,
285
- requestContext: options?.requestContext
286
- });
287
- }
288
- async realpath(path) {
289
- await this.ready();
290
- const virtual = toVirtualPath(this.basePath, path);
291
- const result = await this.sandbox.sandboxSdk.run({
292
- command: "realpath",
293
- args: ["-m", toSandboxPath(this.basePath, virtual)]
294
- });
295
- if (!result.success) return virtual;
296
- const resolved = result.stdout.trim();
297
- if (!isWithin(this.basePath, resolved)) throw new PermissionError(path, "realpath");
298
- return fromSandboxPath(this.basePath, resolved);
299
- }
300
- async readFile(path, options) {
301
- await this.ready();
302
- if ((await this.stat(path)).type === "directory") throw new IsDirectoryError(path);
303
- try {
304
- const content = Buffer.from(await this.sandbox.sandboxSdk.files.read(toSandboxPath(this.basePath, path)));
305
- return options?.encoding ? content.toString(options.encoding) : content;
306
- } catch (error) {
307
- throw mapFileError(path, "read", error);
308
- }
309
- }
310
- async writeFile(path, content, options) {
311
- await this.ready();
312
- this.assertWritable("writeFile");
313
- const target = toSandboxPath(this.basePath, path);
314
- const exists = await this.exists(path);
315
- if (exists && options?.overwrite === false) throw new FileExistsError(path);
316
- if (exists) {
317
- const current = await this.stat(path);
318
- if (current.type === "directory") throw new IsDirectoryError(path);
319
- if (options?.expectedMtime && current.modifiedAt.getTime() !== options.expectedMtime.getTime()) throw new StaleFileError(path, options.expectedMtime, current.modifiedAt);
320
- }
321
- await this.ensureParent(path, options?.recursive !== false);
322
- try {
323
- await this.sandbox.sandboxSdk.files.write(target, toBytes(content));
324
- } catch (error) {
325
- throw mapFileError(path, "write", error);
326
- }
327
- }
328
- async appendFile(path, content) {
329
- await this.ready();
330
- this.assertWritable("appendFile");
331
- const current = await this.exists(path) ? Buffer.from(await this.readFile(path)) : Buffer.alloc(0);
332
- const added = Buffer.from(toBytes(content));
333
- const combined = new Uint8Array(current.byteLength + added.byteLength);
334
- combined.set(current);
335
- combined.set(added, current.byteLength);
336
- await this.writeFile(path, combined);
337
- }
338
- async deleteFile(path, options) {
339
- await this.ready();
340
- this.assertWritable("deleteFile");
341
- if (!await this.exists(path)) {
342
- if (options?.force) return;
343
- throw new FileNotFoundError(path);
344
- }
345
- if ((await this.stat(path)).type === "directory") throw new IsDirectoryError(path);
346
- try {
347
- await this.sandbox.sandboxSdk.files.remove(toSandboxPath(this.basePath, path));
348
- } catch (error) {
349
- throw mapFileError(path, "delete", error);
350
- }
351
- }
352
- async copyFile(src, dest, options) {
353
- await this.ready();
354
- this.assertWritable("copyFile");
355
- if (!await this.exists(src)) throw new FileNotFoundError(src);
356
- if (await this.exists(dest) && options?.overwrite === false) throw new FileExistsError(dest);
357
- if ((await this.stat(src)).type === "directory") {
358
- if (!options?.recursive) throw new IsDirectoryError(src);
359
- await this.mkdir(dest, { recursive: true });
360
- for (const entry of await this.readdir(src)) await this.copyFile(joinVirtual(src, entry.name), joinVirtual(dest, entry.name), options);
361
- return;
362
- }
363
- await this.writeFile(dest, await this.readFile(src), {
364
- recursive: true,
365
- overwrite: options?.overwrite
366
- });
367
- }
368
- async moveFile(src, dest, options) {
369
- this.assertWritable("moveFile");
370
- const source = await this.stat(src);
371
- await this.copyFile(src, dest, {
372
- ...options,
373
- recursive: source.type === "directory" ? true : options?.recursive
374
- });
375
- if (source.type === "directory") await this.rmdir(src, { recursive: true });
376
- else await this.deleteFile(src);
377
- }
378
- async mkdir(path, options) {
379
- await this.ready();
380
- this.assertWritable("mkdir");
381
- if (await this.exists(path)) {
382
- if ((await this.stat(path)).type !== "directory") throw new FileExistsError(path);
383
- return;
384
- }
385
- if (options?.recursive === false) await this.requireParent(path);
386
- try {
387
- await this.sandbox.sandboxSdk.files.mkdir(toSandboxPath(this.basePath, path));
388
- } catch (error) {
389
- throw mapFileError(path, "mkdir", error);
390
- }
391
- }
392
- async rmdir(path, options) {
393
- await this.ready();
394
- this.assertWritable("rmdir");
395
- if (!await this.exists(path)) {
396
- if (options?.force) return;
397
- throw new DirectoryNotFoundError(path);
398
- }
399
- if ((await this.stat(path)).type !== "directory") throw new NotDirectoryError(path);
400
- if (!options?.recursive && (await this.readdir(path)).length > 0) throw new DirectoryNotEmptyError(path);
401
- try {
402
- await this.sandbox.sandboxSdk.files.remove(toSandboxPath(this.basePath, path));
403
- } catch (error) {
404
- throw mapFileError(path, "rmdir", error);
405
- }
406
- }
407
- async readdir(path, options) {
408
- await this.ready();
409
- if (!await this.exists(path)) throw new DirectoryNotFoundError(path);
410
- if ((await this.stat(path)).type !== "directory") throw new NotDirectoryError(path);
411
- const extensions = options?.extension ? new Set((Array.isArray(options.extension) ? options.extension : [options.extension]).map((extension$1) => extension$1.startsWith(".") ? extension$1 : `.${extension$1}`)) : void 0;
412
- return this.listDirectory(path, options?.recursive ? options.maxDepth ?? 100 : 0, extensions);
413
- }
414
- async exists(path) {
415
- await this.ready();
416
- return this.sandbox.sandboxSdk.files.exists(toSandboxPath(this.basePath, path));
417
- }
418
- async stat(path) {
419
- await this.ready();
420
- const virtual = toVirtualPath(this.basePath, path);
421
- const target = toSandboxPath(this.basePath, virtual);
422
- if (virtual === "/") return directoryStat("", "/");
423
- if (!await this.sandbox.sandboxSdk.files.exists(target)) throw new FileNotFoundError(path);
424
- const native = await this.nativeStat(target);
425
- if (native) return {
426
- name: basename(virtual),
427
- path: virtual,
428
- type: native.type,
429
- size: native.size,
430
- createdAt: native.createdAt,
431
- modifiedAt: native.modifiedAt
432
- };
433
- const entry = await this.findEntry(target);
434
- if (!entry) throw new FileNotFoundError(path);
435
- const timestamp = /* @__PURE__ */ new Date(0);
436
- return {
437
- name: entry.name,
438
- path: virtual,
439
- type: entry.type === "directory" ? "directory" : "file",
440
- size: entry.size ?? 0,
441
- createdAt: timestamp,
442
- modifiedAt: timestamp
443
- };
444
- }
445
- async ready() {
446
- await this.ensureReady();
447
- await this.sandbox.ensureRunning();
448
- }
449
- assertWritable(operation) {
450
- if (this.readOnly) throw new WorkspaceReadOnlyError(operation);
451
- }
452
- async ensureParent(path, recursive) {
453
- const parent = dirname(toVirtualPath(this.basePath, path));
454
- if (parent === "/") return;
455
- if (recursive) await this.mkdir(parent, { recursive: true });
456
- else await this.requireParent(path);
457
- }
458
- async requireParent(path) {
459
- const parent = dirname(toVirtualPath(this.basePath, path));
460
- if (!await this.exists(parent)) throw new DirectoryNotFoundError(parent);
461
- if ((await this.stat(parent)).type !== "directory") throw new NotDirectoryError(parent);
462
- }
463
- async listDirectory(path, depth, extensions) {
464
- const entries = await this.sandbox.sandboxSdk.files.list(toSandboxPath(this.basePath, path));
465
- const result = [];
466
- for (const entry of entries) {
467
- const type = entry.type === "directory" ? "directory" : "file";
468
- if (type === "file" && extensions && !extensions.has(extension(entry.name))) continue;
469
- result.push({
470
- name: entry.name,
471
- type,
472
- ...entry.size === void 0 ? {} : { size: entry.size },
473
- ...entry.type === "symlink" ? { isSymlink: true } : {}
474
- });
475
- if (depth > 0 && type === "directory") {
476
- const childPath = joinVirtual(path, entry.name);
477
- const children = await this.listDirectory(childPath, depth - 1, extensions);
478
- result.push(...children.map((child) => ({
479
- ...child,
480
- name: `${entry.name}/${child.name}`
481
- })));
482
- }
483
- }
484
- return result;
485
- }
486
- async findEntry(target) {
487
- const parent = dirname(target);
488
- return (await this.sandbox.sandboxSdk.files.list(parent)).find((entry) => entry.path === target);
489
- }
490
- async nativeStat(target) {
491
- try {
492
- const result = await this.sandbox.sandboxSdk.run({
493
- command: "stat",
494
- args: [
495
- "-c",
496
- "%F|%s|%W|%Y",
497
- target
498
- ]
499
- });
500
- if (!result.success) return void 0;
501
- const [kind, sizeValue, createdValue, modifiedValue] = result.stdout.trim().split("|");
502
- if (!kind || !sizeValue || !createdValue || !modifiedValue) return;
503
- const modified = Number(modifiedValue) * 1e3;
504
- const createdSeconds = Number(createdValue);
505
- return {
506
- type: kind.includes("directory") ? "directory" : "file",
507
- size: Number(sizeValue),
508
- createdAt: /* @__PURE__ */ new Date((createdSeconds > 0 ? createdSeconds : Number(modifiedValue)) * 1e3),
509
- modifiedAt: new Date(modified)
510
- };
511
- } catch {
512
- return;
513
- }
514
- }
515
- };
516
- function requireManaged(provider) {
517
- if (!provider.managed) throw new SandboxError({
518
- code: "unsupported",
519
- provider: provider.id,
520
- operation: "mastra.createSandbox",
521
- message: `Provider ${provider.id} does not implement managed sandbox sessions`
522
- });
523
- return provider.managed;
524
- }
525
- function normalizeCwd(value) {
526
- if (!value.startsWith("/") || value.includes("\0")) throw new SandboxError({
527
- code: "invalid_input",
528
- provider: "mastra",
529
- operation: "cwd",
530
- message: "cwd must be an absolute path"
531
- });
532
- return value.replace(/\/$/, "") || "/";
533
- }
534
- function toVirtualPath(cwd, value) {
535
- assertPath(value);
536
- if (value === cwd) return "/";
537
- if (value.startsWith(`${cwd}/`)) return `/${value.slice(cwd.length + 1)}`;
538
- return (value.startsWith("/") ? value : `/${value}`).replace(/\/{2,}/g, "/").replace(/\/$/, "") || "/";
539
- }
540
- function toSandboxPath(cwd, value) {
541
- const virtual = toVirtualPath(cwd, value);
542
- return virtual === "/" ? cwd : `${cwd}${virtual}`;
543
- }
544
- function fromSandboxPath(cwd, value) {
545
- if (value === cwd) return "/";
546
- if (!value.startsWith(`${cwd}/`)) throw new PermissionError(value, "access");
547
- return `/${value.slice(cwd.length + 1)}`;
548
- }
549
- function assertPath(value) {
550
- if (!value || value.includes("\0") || value.split("/").includes("..")) throw new PermissionError(value, "access");
551
- }
552
- function isWithin(root, path) {
553
- return path === root || path.startsWith(`${root}/`);
554
- }
555
- function toBytes(content) {
556
- return typeof content === "string" ? new TextEncoder().encode(content) : new Uint8Array(content);
557
- }
558
- function basename(path) {
559
- return path.split("/").filter(Boolean).at(-1) ?? "";
560
- }
561
- function dirname(path) {
562
- const parts = path.split("/").filter(Boolean);
563
- parts.pop();
564
- return `/${parts.join("/")}`.replace(/\/$/, "") || "/";
565
- }
566
- function joinVirtual(parent, child) {
567
- return `${parent.replace(/\/$/, "")}/${child}`.replace(/\/{2,}/g, "/");
568
- }
569
- function extension(path) {
570
- const name = basename(path);
571
- const index = name.lastIndexOf(".");
572
- return index <= 0 ? "" : name.slice(index);
573
- }
574
- /**
575
- * Preserve argument boundaries for ordinary commands. Commands that use shell
576
- * syntax deliberately fall back to the provider's shell-string execution path.
577
- */
578
- function parseSimpleCommand(value) {
579
- const parts = [];
580
- let current = "";
581
- let tokenStarted = false;
582
- let quote;
583
- const finish = () => {
584
- if (!tokenStarted) return;
585
- parts.push(current);
586
- current = "";
587
- tokenStarted = false;
588
- };
589
- for (let index = 0; index < value.length; index++) {
590
- const character = value[index];
591
- if (quote === "single") {
592
- if (character === "'") quote = void 0;
593
- else current += character;
594
- tokenStarted = true;
595
- continue;
596
- }
597
- if (quote === "double") {
598
- if (character === "\"") quote = void 0;
599
- else if (character === "\\") {
600
- const next = value[++index];
601
- if (next === void 0) return void 0;
602
- current += next;
603
- } else if (character === "$" || character === "`") return;
604
- else current += character;
605
- tokenStarted = true;
606
- continue;
607
- }
608
- if (/\s/.test(character)) {
609
- finish();
610
- continue;
611
- }
612
- if (character === "'") {
613
- quote = "single";
614
- tokenStarted = true;
615
- continue;
616
- }
617
- if (character === "\"") {
618
- quote = "double";
619
- tokenStarted = true;
620
- continue;
621
- }
622
- if (character === "\\") {
623
- const next = value[++index];
624
- if (next === void 0) return void 0;
625
- current += next;
626
- tokenStarted = true;
627
- continue;
628
- }
629
- if ("|&;<>()$`*?[]{}~#\n\r".includes(character)) return void 0;
630
- current += character;
631
- tokenStarted = true;
632
- }
633
- if (quote) return void 0;
634
- finish();
635
- const [command, ...args] = parts;
636
- return command ? {
637
- command,
638
- args
639
- } : void 0;
640
- }
641
- function directoryStat(name, path) {
642
- const timestamp = /* @__PURE__ */ new Date(0);
643
- return {
644
- name,
645
- path,
646
- type: "directory",
647
- size: 0,
648
- createdAt: timestamp,
649
- modifiedAt: timestamp
650
- };
651
- }
652
- function mapFileError(path, operation, error) {
653
- if (!isSandboxError(error)) return error instanceof Error ? error : new Error(String(error));
654
- if (error.code === "not_found") return new FileNotFoundError(path);
655
- if (error.code === "permission") return new PermissionError(path, operation);
656
- if (error.code === "conflict") return new FileExistsError(path);
657
- return error;
658
- }
659
-
660
- //#endregion
661
- export { SandboxSDKMastraFilesystem, SandboxSDKMastraSandbox, SandboxSDKProcessManager, createMastraSandbox, createMastraWorkspace };
662
- //# sourceMappingURL=index.mjs.map