withruntime 0.8.3 → 0.9.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.
- package/COMPATIBILITY.md +145 -0
- package/E2B.md +23 -13
- package/README.md +8 -5
- package/README.src.md +8 -5
- package/compatibility-lock.json +281 -0
- package/dist/ai-harness/index.js +2 -2
- package/dist/api-defaults.d.ts +17 -0
- package/dist/api-defaults.js +22 -0
- package/dist/blaxel/preview.d.ts +1 -1
- package/dist/blaxel/preview.js +1 -1
- package/dist/blaxel/process.d.ts +1 -1
- package/dist/blaxel/process.js +11 -2
- package/dist/cli-words.d.ts +27 -0
- package/dist/cli-words.js +135 -0
- package/dist/cli.js +162 -31
- package/dist/client.d.ts +4 -1
- package/dist/client.js +8 -2
- package/dist/cloudflare/index.d.ts +294 -0
- package/dist/cloudflare/index.js +554 -0
- package/dist/cloudflare/worker.d.ts +415 -0
- package/dist/cloudflare/worker.js +297 -0
- package/dist/codesandbox/guest-service.d.ts +31 -0
- package/dist/codesandbox/guest-service.js +453 -0
- package/dist/codesandbox/index.d.ts +386 -0
- package/dist/codesandbox/index.js +1313 -0
- package/dist/compat/core.d.ts +39 -0
- package/dist/compat/core.js +199 -0
- package/dist/compat/files.d.ts +26 -0
- package/dist/compat/files.js +115 -0
- package/dist/compat/shell.d.ts +4 -0
- package/dist/compat/shell.js +165 -0
- package/dist/daytona/context.js +2 -1
- package/dist/daytona/process.d.ts +1 -1
- package/dist/daytona/process.js +27 -4
- package/dist/e2b/code-interpreter.d.ts +4 -5
- package/dist/e2b/code-interpreter.js +54 -56
- package/dist/e2b/commands.d.ts +5 -4
- package/dist/e2b/commands.js +37 -29
- package/dist/e2b/errors.js +1 -1
- package/dist/e2b/filesystem.d.ts +8 -6
- package/dist/e2b/filesystem.js +127 -28
- package/dist/e2b/sandbox.d.ts +4 -3
- package/dist/e2b/sandbox.js +10 -10
- package/dist/errors.d.ts +8 -0
- package/dist/errors.js +15 -2
- package/dist/freestyle/index.d.ts +301 -0
- package/dist/freestyle/index.js +310 -0
- package/dist/index.d.ts +1 -0
- package/dist/mcp.js +2 -2
- package/dist/modal/index.d.ts +205 -0
- package/dist/modal/index.js +485 -0
- package/dist/network-cli.js +1 -1
- package/dist/openai-agents/index.js +9 -26
- package/dist/products/audit.d.ts +3 -0
- package/dist/products/index.d.ts +2 -0
- package/dist/products/index.js +2 -0
- package/dist/products/interpreter.d.ts +11 -4
- package/dist/products/interpreter.js +33 -9
- package/dist/products/jobs.d.ts +1 -1
- package/dist/products/jobs.js +5 -4
- package/dist/products/limits.d.ts +10 -0
- package/dist/products/previews.d.ts +10 -2
- package/dist/products/previews.js +3 -2
- package/dist/products/tailscale.d.ts +57 -0
- package/dist/products/tailscale.js +17 -0
- package/dist/products/watch.d.ts +25 -4
- package/dist/products/watch.js +75 -14
- package/dist/runloop/index.d.ts +340 -0
- package/dist/runloop/index.js +438 -0
- package/dist/runloop/pagination.d.ts +46 -0
- package/dist/runloop/pagination.js +82 -0
- package/dist/runloop/snapshots.d.ts +52 -0
- package/dist/runloop/snapshots.js +244 -0
- package/dist/sandbox.d.ts +40 -9
- package/dist/sandbox.js +273 -76
- package/dist/snapshots.d.ts +11 -1
- package/dist/snapshots.js +11 -1
- package/dist/sprites/index.d.ts +251 -0
- package/dist/sprites/index.js +552 -0
- package/dist/tar.d.ts +8 -1
- package/dist/tar.js +185 -35
- package/dist/tools/index.js +2 -1
- package/dist/transport.d.ts +20 -2
- package/dist/transport.js +48 -11
- package/dist/types.d.ts +52 -3
- package/dist/vercel/command.js +12 -1
- package/dist/vercel/errors.d.ts +2 -2
- package/dist/vercel/errors.js +12 -1
- package/dist/vercel/filesystem.d.ts +21 -18
- package/dist/vercel/filesystem.js +95 -48
- package/dist/vercel/sandbox.js +5 -5
- package/package.json +45 -3
|
@@ -5,7 +5,10 @@ export interface FsContext {
|
|
|
5
5
|
readonly name: string;
|
|
6
6
|
files(): Promise<Files>;
|
|
7
7
|
/** Runs argv without a shell; resolves with the exit code and output. */
|
|
8
|
-
run(argv: string[]
|
|
8
|
+
run(argv: string[], options?: {
|
|
9
|
+
stdin?: Uint8Array;
|
|
10
|
+
signal?: AbortSignal;
|
|
11
|
+
}): Promise<{
|
|
9
12
|
exitCode: number | null;
|
|
10
13
|
stdout: string;
|
|
11
14
|
stderr: string;
|
|
@@ -28,8 +31,8 @@ export declare class Stats {
|
|
|
28
31
|
readonly ctimeMs: number;
|
|
29
32
|
readonly birthtime: Date;
|
|
30
33
|
readonly birthtimeMs: number;
|
|
31
|
-
readonly uid
|
|
32
|
-
readonly gid
|
|
34
|
+
readonly uid: number;
|
|
35
|
+
readonly gid: number;
|
|
33
36
|
readonly dev = 0;
|
|
34
37
|
readonly ino = 0;
|
|
35
38
|
readonly nlink = 1;
|
|
@@ -86,7 +89,7 @@ export declare class FileSystem {
|
|
|
86
89
|
mkdir(path: string, options?: {
|
|
87
90
|
recursive?: boolean;
|
|
88
91
|
signal?: AbortSignal;
|
|
89
|
-
} | number): Promise<
|
|
92
|
+
} | number): Promise<void>;
|
|
90
93
|
readdir(path: string, options?: {
|
|
91
94
|
signal?: AbortSignal;
|
|
92
95
|
withFileTypes?: false;
|
|
@@ -95,14 +98,14 @@ export declare class FileSystem {
|
|
|
95
98
|
signal?: AbortSignal;
|
|
96
99
|
withFileTypes: true;
|
|
97
100
|
}): Promise<Dirent[]>;
|
|
98
|
-
lstat(path: string,
|
|
101
|
+
lstat(path: string, options?: {
|
|
99
102
|
signal?: AbortSignal;
|
|
100
103
|
}): Promise<Stats>;
|
|
101
104
|
/** Follows symbolic links. */
|
|
102
105
|
stat(path: string, options?: {
|
|
103
106
|
signal?: AbortSignal;
|
|
104
107
|
}): Promise<Stats>;
|
|
105
|
-
unlink(path: string,
|
|
108
|
+
unlink(path: string, options?: {
|
|
106
109
|
signal?: AbortSignal;
|
|
107
110
|
}): Promise<void>;
|
|
108
111
|
rm(path: string, options?: {
|
|
@@ -110,40 +113,40 @@ export declare class FileSystem {
|
|
|
110
113
|
force?: boolean;
|
|
111
114
|
signal?: AbortSignal;
|
|
112
115
|
}): Promise<void>;
|
|
113
|
-
rmdir(path: string,
|
|
116
|
+
rmdir(path: string, options?: {
|
|
114
117
|
signal?: AbortSignal;
|
|
115
118
|
}): Promise<void>;
|
|
116
|
-
rename(oldPath: string, newPath: string,
|
|
119
|
+
rename(oldPath: string, newPath: string, options?: {
|
|
117
120
|
signal?: AbortSignal;
|
|
118
121
|
}): Promise<void>;
|
|
119
|
-
copyFile(src: string, dest: string,
|
|
122
|
+
copyFile(src: string, dest: string, options?: {
|
|
120
123
|
signal?: AbortSignal;
|
|
121
124
|
}): Promise<void>;
|
|
122
|
-
access(path: string,
|
|
125
|
+
access(path: string, options?: {
|
|
123
126
|
signal?: AbortSignal;
|
|
124
127
|
}): Promise<void>;
|
|
125
|
-
exists(path: string,
|
|
128
|
+
exists(path: string, options?: {
|
|
126
129
|
signal?: AbortSignal;
|
|
127
130
|
}): Promise<boolean>;
|
|
128
|
-
chmod(path: string, mode: number | string,
|
|
131
|
+
chmod(path: string, mode: number | string, options?: {
|
|
129
132
|
signal?: AbortSignal;
|
|
130
133
|
}): Promise<void>;
|
|
131
|
-
chown(path: string, uid: number, gid: number,
|
|
134
|
+
chown(path: string, uid: number, gid: number, options?: {
|
|
132
135
|
signal?: AbortSignal;
|
|
133
136
|
}): Promise<void>;
|
|
134
|
-
symlink(target: string, path: string,
|
|
137
|
+
symlink(target: string, path: string, options?: {
|
|
135
138
|
signal?: AbortSignal;
|
|
136
139
|
}): Promise<void>;
|
|
137
|
-
readlink(path: string,
|
|
140
|
+
readlink(path: string, options?: {
|
|
138
141
|
signal?: AbortSignal;
|
|
139
142
|
}): Promise<string>;
|
|
140
|
-
realpath(path: string,
|
|
143
|
+
realpath(path: string, options?: {
|
|
141
144
|
signal?: AbortSignal;
|
|
142
145
|
}): Promise<string>;
|
|
143
|
-
truncate(path: string, len?: number,
|
|
146
|
+
truncate(path: string, len?: number, options?: {
|
|
144
147
|
signal?: AbortSignal;
|
|
145
148
|
}): Promise<void>;
|
|
146
|
-
mkdtemp(prefix: string,
|
|
149
|
+
mkdtemp(prefix: string, options?: {
|
|
147
150
|
signal?: AbortSignal;
|
|
148
151
|
}): Promise<string>;
|
|
149
152
|
}
|
|
@@ -13,8 +13,8 @@ export class Stats {
|
|
|
13
13
|
ctimeMs;
|
|
14
14
|
birthtime;
|
|
15
15
|
birthtimeMs;
|
|
16
|
-
uid
|
|
17
|
-
gid
|
|
16
|
+
uid;
|
|
17
|
+
gid;
|
|
18
18
|
dev = 0;
|
|
19
19
|
ino = 0;
|
|
20
20
|
nlink = 1;
|
|
@@ -24,6 +24,8 @@ export class Stats {
|
|
|
24
24
|
#type;
|
|
25
25
|
constructor(entry) {
|
|
26
26
|
this.#type = entry.type;
|
|
27
|
+
this.uid = entry.uid ?? 0;
|
|
28
|
+
this.gid = entry.gid ?? 0;
|
|
27
29
|
this.size = entry.size;
|
|
28
30
|
const typeBits = entry.type === "directory" ? 0o040000 : entry.type === "symlink" ? 0o120000 : 0o100000;
|
|
29
31
|
this.mode = typeBits | ((parseInt(entry.mode, 8) || 0) & 0o7777);
|
|
@@ -61,7 +63,8 @@ export class Dirent {
|
|
|
61
63
|
#type;
|
|
62
64
|
constructor(entry, parent) {
|
|
63
65
|
this.name = entry.name;
|
|
64
|
-
this.parentPath =
|
|
66
|
+
this.parentPath = parent;
|
|
67
|
+
this.path = entry.path;
|
|
65
68
|
this.#type = entry.type;
|
|
66
69
|
}
|
|
67
70
|
isFile() {
|
|
@@ -111,18 +114,27 @@ export class FileSystem {
|
|
|
111
114
|
}
|
|
112
115
|
}
|
|
113
116
|
/** Runs a coreutils command; a failure is a Node-style error. */
|
|
114
|
-
async #run(syscall, path, argv) {
|
|
115
|
-
|
|
117
|
+
async #run(syscall, path, argv, options) {
|
|
118
|
+
options?.signal?.throwIfAborted();
|
|
119
|
+
const result = await this.#call(syscall, path, () => this.#ctx.run(argv, options));
|
|
116
120
|
if (result.exitCode === 0)
|
|
117
121
|
return result.stdout;
|
|
118
122
|
if (/No such file or directory/.test(result.stderr))
|
|
119
123
|
throw fsError("ENOENT", syscall, path);
|
|
124
|
+
if (syscall === "unlink" || syscall === "rm")
|
|
125
|
+
throw fsError("EACCES", syscall, path);
|
|
126
|
+
if (syscall === "rmdir" && /not empty/i.test(result.stderr))
|
|
127
|
+
throw fsError("ENOTEMPTY", syscall, path);
|
|
128
|
+
if (syscall === "readlink")
|
|
129
|
+
throw fsError("EINVAL", syscall, path);
|
|
120
130
|
if (/File exists/.test(result.stderr))
|
|
121
131
|
throw fsError("EEXIST", syscall, path);
|
|
122
132
|
if (/Is a directory/.test(result.stderr))
|
|
123
133
|
throw fsError("EISDIR", syscall, path);
|
|
124
134
|
if (/Not a directory/.test(result.stderr))
|
|
125
135
|
throw fsError("ENOTDIR", syscall, path);
|
|
136
|
+
if (/Permission denied/.test(result.stderr))
|
|
137
|
+
throw fsError("EACCES", syscall, path);
|
|
126
138
|
throw Object.assign(new Error(`${syscall} '${path}' failed: ${result.stderr.trim()}`), {
|
|
127
139
|
code: "EIO",
|
|
128
140
|
syscall,
|
|
@@ -131,6 +143,8 @@ export class FileSystem {
|
|
|
131
143
|
}
|
|
132
144
|
async readFile(path, options) {
|
|
133
145
|
const target = this.#ctx.resolve(path);
|
|
146
|
+
if (options && typeof options === "object")
|
|
147
|
+
options.signal?.throwIfAborted();
|
|
134
148
|
const files = await this.#ctx.files();
|
|
135
149
|
const bytes = await this.#call("open", target, () => files.read(target, typeof options === "object" && options?.signal ? { signal: options.signal } : {}));
|
|
136
150
|
const encoding = encodingOf(options);
|
|
@@ -139,37 +153,64 @@ export class FileSystem {
|
|
|
139
153
|
}
|
|
140
154
|
async writeFile(path, data, options) {
|
|
141
155
|
const target = this.#ctx.resolve(path);
|
|
156
|
+
if (options && typeof options === "object")
|
|
157
|
+
options.signal?.throwIfAborted();
|
|
142
158
|
const files = await this.#ctx.files();
|
|
143
|
-
await this.#call("open", target, () => files.write(target, bytesOf(data, encodingOf(options))));
|
|
159
|
+
await this.#call("open", target, () => files.write(target, bytesOf(data, encodingOf(options)), typeof options === "object" && options.signal ? { signal: options.signal } : {}));
|
|
144
160
|
}
|
|
145
161
|
async appendFile(path, data, options) {
|
|
146
162
|
const target = this.#ctx.resolve(path);
|
|
163
|
+
// Never read-modify-write: another caller may be appending too. The
|
|
164
|
+
// shell opens with O_APPEND and cat streams bytes without Python. Exec
|
|
165
|
+
// stdin is limited to 1 MiB; larger input uses the chunked files API.
|
|
166
|
+
const bytes = bytesOf(data, encodingOf(options));
|
|
167
|
+
const signal = typeof options === "object" ? options.signal : undefined;
|
|
168
|
+
signal?.throwIfAborted();
|
|
169
|
+
if (bytes.byteLength <= 1_048_576) {
|
|
170
|
+
await this.#run("open", target, ["sh", "-c", 'cat >> "$1"', "runtime-append", target], {
|
|
171
|
+
stdin: bytes,
|
|
172
|
+
...(signal ? { signal } : {}),
|
|
173
|
+
});
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
if (options && typeof options === "object")
|
|
177
|
+
options.signal?.throwIfAborted();
|
|
147
178
|
const files = await this.#ctx.files();
|
|
148
|
-
const
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
}
|
|
153
|
-
|
|
179
|
+
const staging = `/workspace/.runtime/append/${crypto.randomUUID()}`;
|
|
180
|
+
try {
|
|
181
|
+
await this.#call("open", target, () => files.write(staging, bytes, { mode: 0o600, ...(signal ? { signal } : {}) }));
|
|
182
|
+
await this.#run("open", target, ["sh", "-c", 'cat "$1" >> "$2"', "runtime-append", staging, target], signal ? { signal } : undefined);
|
|
183
|
+
}
|
|
184
|
+
finally {
|
|
185
|
+
// A cleanup failure must not invite retrying a successful append.
|
|
186
|
+
await files.remove(staging).catch(() => undefined);
|
|
187
|
+
}
|
|
154
188
|
}
|
|
155
189
|
async mkdir(path, options) {
|
|
156
190
|
const target = this.#ctx.resolve(path);
|
|
157
191
|
const recursive = typeof options === "object" && options.recursive === true;
|
|
158
|
-
await this.#run("mkdir", target, recursive ? ["mkdir", "-p", target] : ["mkdir", target]);
|
|
159
|
-
return recursive ? target : undefined;
|
|
192
|
+
await this.#run("mkdir", target, recursive ? ["mkdir", "-p", "--", target] : ["mkdir", "--", target], typeof options === "object" ? options : {});
|
|
160
193
|
}
|
|
161
194
|
async readdir(path, options = {}) {
|
|
162
195
|
const target = this.#ctx.resolve(path);
|
|
196
|
+
if (options && typeof options === "object")
|
|
197
|
+
options.signal?.throwIfAborted();
|
|
163
198
|
const files = await this.#ctx.files();
|
|
164
|
-
const entries = await this.#call("scandir", target, () => files.list(target, {
|
|
199
|
+
const entries = await this.#call("scandir", target, () => files.list(target, {
|
|
200
|
+
depth: 1,
|
|
201
|
+
hidden: options.withFileTypes === true,
|
|
202
|
+
...(options.signal ? { signal: options.signal } : {}),
|
|
203
|
+
}));
|
|
165
204
|
return options.withFileTypes
|
|
166
205
|
? entries.map((entry) => new Dirent(entry, target))
|
|
167
|
-
: entries.map((entry) => entry.name);
|
|
206
|
+
: entries.filter((entry) => !entry.name.startsWith(".")).map((entry) => entry.name);
|
|
168
207
|
}
|
|
169
|
-
async lstat(path,
|
|
208
|
+
async lstat(path, options = {}) {
|
|
170
209
|
const target = this.#ctx.resolve(path);
|
|
210
|
+
if (options && typeof options === "object")
|
|
211
|
+
options.signal?.throwIfAborted();
|
|
171
212
|
const files = await this.#ctx.files();
|
|
172
|
-
const found = await this.#call("lstat", target, () => files.stat(target));
|
|
213
|
+
const found = await this.#call("lstat", target, () => files.stat(target, options));
|
|
173
214
|
if (!found.exists)
|
|
174
215
|
throw fsError("ENOENT", "lstat", target);
|
|
175
216
|
return new Stats(found);
|
|
@@ -180,69 +221,75 @@ export class FileSystem {
|
|
|
180
221
|
const first = await this.lstat(target, options);
|
|
181
222
|
if (!first.isSymbolicLink())
|
|
182
223
|
return first;
|
|
183
|
-
return this.lstat(await this.realpath(target), options);
|
|
224
|
+
return this.lstat(await this.realpath(target, options), options);
|
|
184
225
|
}
|
|
185
|
-
async unlink(path,
|
|
226
|
+
async unlink(path, options = {}) {
|
|
186
227
|
const target = this.#ctx.resolve(path);
|
|
187
|
-
await this.#run("unlink", target, ["rm", "--", target]);
|
|
228
|
+
await this.#run("unlink", target, ["rm", "--", target], options);
|
|
188
229
|
}
|
|
189
230
|
async rm(path, options = {}) {
|
|
190
231
|
const target = this.#ctx.resolve(path);
|
|
191
232
|
const flags = `${options.recursive ? "r" : ""}${options.force ? "f" : ""}`;
|
|
192
|
-
await this.#run("rm", target, flags ? ["rm", `-${flags}`, "--", target] : ["rm", "--", target]);
|
|
233
|
+
await this.#run("rm", target, flags ? ["rm", `-${flags}`, "--", target] : ["rm", "--", target], options);
|
|
193
234
|
}
|
|
194
|
-
async rmdir(path,
|
|
235
|
+
async rmdir(path, options = {}) {
|
|
195
236
|
const target = this.#ctx.resolve(path);
|
|
196
|
-
await this.#run("rmdir", target, ["rmdir", "--", target]);
|
|
237
|
+
await this.#run("rmdir", target, ["rmdir", "--", target], options);
|
|
197
238
|
}
|
|
198
|
-
async rename(oldPath, newPath,
|
|
239
|
+
async rename(oldPath, newPath, options = {}) {
|
|
199
240
|
const from = this.#ctx.resolve(oldPath);
|
|
200
241
|
const to = this.#ctx.resolve(newPath);
|
|
242
|
+
if (options && typeof options === "object")
|
|
243
|
+
options.signal?.throwIfAborted();
|
|
201
244
|
const files = await this.#ctx.files();
|
|
202
|
-
await this.#call("rename", from, () => files.rename(from, to, { overwrite: true }));
|
|
245
|
+
await this.#call("rename", from, () => files.rename(from, to, { overwrite: true, ...options }));
|
|
203
246
|
}
|
|
204
|
-
async copyFile(src, dest,
|
|
247
|
+
async copyFile(src, dest, options = {}) {
|
|
205
248
|
const from = this.#ctx.resolve(src);
|
|
206
249
|
const to = this.#ctx.resolve(dest);
|
|
207
|
-
await this.#run("copyfile", from, ["cp", "--", from, to]);
|
|
250
|
+
await this.#run("copyfile", from, ["cp", "--", from, to], options);
|
|
208
251
|
}
|
|
209
|
-
async access(path,
|
|
252
|
+
async access(path, options = {}) {
|
|
210
253
|
const target = this.#ctx.resolve(path);
|
|
211
|
-
if (!(await this.exists(target)))
|
|
254
|
+
if (!(await this.exists(target, options)))
|
|
212
255
|
throw fsError("ENOENT", "access", target);
|
|
213
256
|
}
|
|
214
|
-
async exists(path,
|
|
257
|
+
async exists(path, options = {}) {
|
|
215
258
|
const target = this.#ctx.resolve(path);
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
259
|
+
if (options && typeof options === "object")
|
|
260
|
+
options.signal?.throwIfAborted();
|
|
261
|
+
// The native stat is lstat: a dangling link exists there. Vercel's public
|
|
262
|
+
// exists/access follow the target, matching test -e in its published SDK.
|
|
263
|
+
const result = await this.#call("access", target, () => this.#ctx.run(["test", "-e", target], options));
|
|
264
|
+
return result.exitCode === 0;
|
|
265
|
+
}
|
|
266
|
+
async chmod(path, mode, options = {}) {
|
|
220
267
|
const target = this.#ctx.resolve(path);
|
|
221
268
|
const octal = typeof mode === "number" ? mode.toString(8) : mode;
|
|
222
|
-
await this.#run("chmod", target, ["chmod", octal, "--", target]);
|
|
269
|
+
await this.#run("chmod", target, ["chmod", octal, "--", target], options);
|
|
223
270
|
}
|
|
224
|
-
async chown(path, uid, gid,
|
|
271
|
+
async chown(path, uid, gid, options = {}) {
|
|
225
272
|
const target = this.#ctx.resolve(path);
|
|
226
|
-
await this.#run("chown", target, ["sudo", "chown", `${uid}:${gid}`, "--", target]);
|
|
273
|
+
await this.#run("chown", target, ["sudo", "chown", `${uid}:${gid}`, "--", target], options);
|
|
227
274
|
}
|
|
228
|
-
async symlink(target, path,
|
|
275
|
+
async symlink(target, path, options = {}) {
|
|
229
276
|
const link = this.#ctx.resolve(path);
|
|
230
|
-
await this.#run("symlink", link, ["ln", "-s", "--", target, link]);
|
|
277
|
+
await this.#run("symlink", link, ["ln", "-s", "--", target, link], options);
|
|
231
278
|
}
|
|
232
|
-
async readlink(path,
|
|
279
|
+
async readlink(path, options = {}) {
|
|
233
280
|
const target = this.#ctx.resolve(path);
|
|
234
|
-
return (await this.#run("readlink", target, ["readlink", "--", target])).replace(/\n$/, "");
|
|
281
|
+
return (await this.#run("readlink", target, ["readlink", "--", target], options)).replace(/\n$/, "");
|
|
235
282
|
}
|
|
236
|
-
async realpath(path,
|
|
283
|
+
async realpath(path, options = {}) {
|
|
237
284
|
const target = this.#ctx.resolve(path);
|
|
238
|
-
return (await this.#run("realpath", target, ["realpath", "-e", "--", target])).replace(/\n$/, "");
|
|
285
|
+
return (await this.#run("realpath", target, ["realpath", "-e", "--", target], options)).replace(/\n$/, "");
|
|
239
286
|
}
|
|
240
|
-
async truncate(path, len = 0,
|
|
287
|
+
async truncate(path, len = 0, options = {}) {
|
|
241
288
|
const target = this.#ctx.resolve(path);
|
|
242
|
-
await this.#run("open", target, ["truncate", "-s", String(len), "--", target]);
|
|
289
|
+
await this.#run("open", target, ["truncate", "-s", String(len), "--", target], options);
|
|
243
290
|
}
|
|
244
|
-
async mkdtemp(prefix,
|
|
291
|
+
async mkdtemp(prefix, options = {}) {
|
|
245
292
|
const base = this.#ctx.resolve(prefix);
|
|
246
|
-
return (await this.#run("mkdtemp", base, ["mktemp", "-d", `${base}XXXXXX`])).replace(/\n$/, "");
|
|
293
|
+
return (await this.#run("mkdtemp", base, ["mktemp", "-d", `${base}XXXXXX`], options)).replace(/\n$/, "");
|
|
247
294
|
}
|
|
248
295
|
}
|
package/dist/vercel/sandbox.js
CHANGED
|
@@ -111,15 +111,15 @@ function statusOf(state) {
|
|
|
111
111
|
/** Runtime's `/workspace` stands for Vercel's `/vercel/sandbox`: relative
|
|
112
112
|
* paths resolve against it, and paths under /vercel/sandbox are rewritten. */
|
|
113
113
|
export function toRuntimePath(path, cwd) {
|
|
114
|
-
const base = cwd === undefined ? HOME : toVercelPath(cwd);
|
|
115
|
-
const absolute = path.startsWith("/") ? path : `${base}/${path.replace(
|
|
114
|
+
const base = cwd === undefined ? HOME : toVercelPath(cwd).replace(/\/+$/, "");
|
|
115
|
+
const absolute = path.startsWith("/") ? path : `${base}/${path.replace(/^(?:\.(?:\/+|$))+/, "")}`;
|
|
116
116
|
const normal = absolute.replace(/\/+$/, "") || "/";
|
|
117
117
|
if (normal === HOME || normal.startsWith(`${HOME}/`))
|
|
118
118
|
return RUNTIME_HOME + normal.slice(HOME.length);
|
|
119
119
|
return normal;
|
|
120
120
|
}
|
|
121
121
|
function toVercelPath(path) {
|
|
122
|
-
return path.startsWith("/") ? path : `${HOME}/${path.replace(
|
|
122
|
+
return path.startsWith("/") ? path : `${HOME}/${path.replace(/^(?:\.(?:\/+|$))+/, "")}`;
|
|
123
123
|
}
|
|
124
124
|
/** A sandbox with Vercel's methods. `sandbox.withruntime` is the Runtime
|
|
125
125
|
* sandbox underneath, for anything Vercel has no name for. */
|
|
@@ -143,9 +143,9 @@ export class Sandbox {
|
|
|
143
143
|
this.fs = new FileSystem({
|
|
144
144
|
name: this.name,
|
|
145
145
|
files: async () => (await this.#live()).files,
|
|
146
|
-
run: async (argv) => {
|
|
146
|
+
run: async (argv, options) => {
|
|
147
147
|
const live = await this.#live();
|
|
148
|
-
return live.exec(argv);
|
|
148
|
+
return live.exec(argv, options);
|
|
149
149
|
},
|
|
150
150
|
resolve: (path, cwd) => toRuntimePath(path, cwd),
|
|
151
151
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "withruntime",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"mcpName": "com.withruntime/runtime",
|
|
6
6
|
"type": "module",
|
|
@@ -59,6 +59,41 @@
|
|
|
59
59
|
"types": "./dist/ai-harness/index.d.ts",
|
|
60
60
|
"import": "./dist/ai-harness/index.js",
|
|
61
61
|
"default": "./dist/ai-harness/index.js"
|
|
62
|
+
},
|
|
63
|
+
"./runloop": {
|
|
64
|
+
"types": "./dist/runloop/index.d.ts",
|
|
65
|
+
"import": "./dist/runloop/index.js",
|
|
66
|
+
"default": "./dist/runloop/index.js"
|
|
67
|
+
},
|
|
68
|
+
"./codesandbox": {
|
|
69
|
+
"types": "./dist/codesandbox/index.d.ts",
|
|
70
|
+
"import": "./dist/codesandbox/index.js",
|
|
71
|
+
"default": "./dist/codesandbox/index.js"
|
|
72
|
+
},
|
|
73
|
+
"./sprites": {
|
|
74
|
+
"types": "./dist/sprites/index.d.ts",
|
|
75
|
+
"import": "./dist/sprites/index.js",
|
|
76
|
+
"default": "./dist/sprites/index.js"
|
|
77
|
+
},
|
|
78
|
+
"./freestyle": {
|
|
79
|
+
"types": "./dist/freestyle/index.d.ts",
|
|
80
|
+
"import": "./dist/freestyle/index.js",
|
|
81
|
+
"default": "./dist/freestyle/index.js"
|
|
82
|
+
},
|
|
83
|
+
"./modal": {
|
|
84
|
+
"types": "./dist/modal/index.d.ts",
|
|
85
|
+
"import": "./dist/modal/index.js",
|
|
86
|
+
"default": "./dist/modal/index.js"
|
|
87
|
+
},
|
|
88
|
+
"./cloudflare": {
|
|
89
|
+
"workerd": {
|
|
90
|
+
"types": "./dist/cloudflare/worker.d.ts",
|
|
91
|
+
"import": "./dist/cloudflare/worker.js",
|
|
92
|
+
"default": "./dist/cloudflare/worker.js"
|
|
93
|
+
},
|
|
94
|
+
"types": "./dist/cloudflare/index.d.ts",
|
|
95
|
+
"import": "./dist/cloudflare/index.js",
|
|
96
|
+
"default": "./dist/cloudflare/index.js"
|
|
62
97
|
}
|
|
63
98
|
},
|
|
64
99
|
"bin": {
|
|
@@ -72,7 +107,9 @@
|
|
|
72
107
|
"DAYTONA.md",
|
|
73
108
|
"VERCEL.md",
|
|
74
109
|
"BLAXEL.md",
|
|
75
|
-
"LICENSE"
|
|
110
|
+
"LICENSE",
|
|
111
|
+
"COMPATIBILITY.md",
|
|
112
|
+
"compatibility-lock.json"
|
|
76
113
|
],
|
|
77
114
|
"engines": {
|
|
78
115
|
"node": ">=22.12"
|
|
@@ -86,12 +123,17 @@
|
|
|
86
123
|
"test:java": "bun ../../sdks/java/scripts/check.ts",
|
|
87
124
|
"test:ruby": "bun ../../sdks/ruby/scripts/check.ts",
|
|
88
125
|
"test:python": "bun scripts/test-python.ts",
|
|
89
|
-
"test:go": "bun scripts/test-go.ts"
|
|
126
|
+
"test:go": "bun scripts/test-go.ts",
|
|
127
|
+
"compat:upstream": "bun scripts/check-upstream.ts",
|
|
128
|
+
"test:compat": "bun test tests/e2b tests/daytona tests/vercel tests/blaxel tests/compat tests/drop-in-isolation.test.ts tests/drop-in-paths.test.ts tests/process-input.test.ts tests/watch-reentrant.test.ts tests/upstream-check.test.ts tests/process-output.test.ts tests/prepare-compatibility.test.ts",
|
|
129
|
+
"compat:prepare": "bun scripts/prepare-compatibility.ts",
|
|
130
|
+
"compat:oracle": "bun oracle/check.mjs"
|
|
90
131
|
},
|
|
91
132
|
"devDependencies": {
|
|
92
133
|
"@ai-sdk/harness": "1.0.124",
|
|
93
134
|
"@anthropic-ai/claude-agent-sdk": "0.3.277",
|
|
94
135
|
"@anthropic-ai/sdk": "0.128.0",
|
|
136
|
+
"@cloudflare/workers-types": "5.20260929.1",
|
|
95
137
|
"@google/genai": "2.24.0",
|
|
96
138
|
"@mastra/core": "1.71.0",
|
|
97
139
|
"@mistralai/mistralai": "2.7.0",
|