@cloudflare/sandbox 0.5.6 → 0.6.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/Dockerfile +54 -56
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/package.json +11 -6
- package/.turbo/turbo-build.log +0 -23
- package/CHANGELOG.md +0 -463
- package/src/clients/base-client.ts +0 -356
- package/src/clients/command-client.ts +0 -133
- package/src/clients/file-client.ts +0 -300
- package/src/clients/git-client.ts +0 -98
- package/src/clients/index.ts +0 -64
- package/src/clients/interpreter-client.ts +0 -339
- package/src/clients/port-client.ts +0 -105
- package/src/clients/process-client.ts +0 -198
- package/src/clients/sandbox-client.ts +0 -39
- package/src/clients/types.ts +0 -88
- package/src/clients/utility-client.ts +0 -156
- package/src/errors/adapter.ts +0 -238
- package/src/errors/classes.ts +0 -594
- package/src/errors/index.ts +0 -109
- package/src/file-stream.ts +0 -175
- package/src/index.ts +0 -121
- package/src/interpreter.ts +0 -168
- package/src/openai/index.ts +0 -465
- package/src/request-handler.ts +0 -184
- package/src/sandbox.ts +0 -1937
- package/src/security.ts +0 -119
- package/src/sse-parser.ts +0 -147
- package/src/storage-mount/credential-detection.ts +0 -41
- package/src/storage-mount/errors.ts +0 -51
- package/src/storage-mount/index.ts +0 -17
- package/src/storage-mount/provider-detection.ts +0 -93
- package/src/storage-mount/types.ts +0 -17
- package/src/version.ts +0 -6
- package/tests/base-client.test.ts +0 -582
- package/tests/command-client.test.ts +0 -444
- package/tests/file-client.test.ts +0 -831
- package/tests/file-stream.test.ts +0 -310
- package/tests/get-sandbox.test.ts +0 -172
- package/tests/git-client.test.ts +0 -455
- package/tests/openai-shell-editor.test.ts +0 -434
- package/tests/port-client.test.ts +0 -283
- package/tests/process-client.test.ts +0 -649
- package/tests/request-handler.test.ts +0 -292
- package/tests/sandbox.test.ts +0 -890
- package/tests/sse-parser.test.ts +0 -291
- package/tests/storage-mount/credential-detection.test.ts +0 -119
- package/tests/storage-mount/provider-detection.test.ts +0 -77
- package/tests/utility-client.test.ts +0 -339
- package/tests/version.test.ts +0 -16
- package/tests/wrangler.jsonc +0 -35
- package/tsconfig.json +0 -11
- package/tsdown.config.ts +0 -13
- package/vitest.config.ts +0 -31
|
@@ -1,300 +0,0 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
DeleteFileResult,
|
|
3
|
-
FileExistsResult,
|
|
4
|
-
ListFilesOptions,
|
|
5
|
-
ListFilesResult,
|
|
6
|
-
MkdirResult,
|
|
7
|
-
MoveFileResult,
|
|
8
|
-
ReadFileResult,
|
|
9
|
-
RenameFileResult,
|
|
10
|
-
WriteFileResult
|
|
11
|
-
} from '@repo/shared';
|
|
12
|
-
import { BaseHttpClient } from './base-client';
|
|
13
|
-
import type { HttpClientOptions, SessionRequest } from './types';
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* Request interface for creating directories
|
|
17
|
-
*/
|
|
18
|
-
export interface MkdirRequest extends SessionRequest {
|
|
19
|
-
path: string;
|
|
20
|
-
recursive?: boolean;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Request interface for writing files
|
|
25
|
-
*/
|
|
26
|
-
export interface WriteFileRequest extends SessionRequest {
|
|
27
|
-
path: string;
|
|
28
|
-
content: string;
|
|
29
|
-
encoding?: string;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Request interface for reading files
|
|
34
|
-
*/
|
|
35
|
-
export interface ReadFileRequest extends SessionRequest {
|
|
36
|
-
path: string;
|
|
37
|
-
encoding?: string;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* Request interface for file operations (delete, rename, move)
|
|
42
|
-
*/
|
|
43
|
-
export interface FileOperationRequest extends SessionRequest {
|
|
44
|
-
path: string;
|
|
45
|
-
newPath?: string; // For rename/move operations
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* Client for file system operations
|
|
50
|
-
*/
|
|
51
|
-
export class FileClient extends BaseHttpClient {
|
|
52
|
-
/**
|
|
53
|
-
* Create a directory
|
|
54
|
-
* @param path - Directory path to create
|
|
55
|
-
* @param sessionId - The session ID for this operation
|
|
56
|
-
* @param options - Optional settings (recursive)
|
|
57
|
-
*/
|
|
58
|
-
async mkdir(
|
|
59
|
-
path: string,
|
|
60
|
-
sessionId: string,
|
|
61
|
-
options?: { recursive?: boolean }
|
|
62
|
-
): Promise<MkdirResult> {
|
|
63
|
-
try {
|
|
64
|
-
const data = {
|
|
65
|
-
path,
|
|
66
|
-
sessionId,
|
|
67
|
-
recursive: options?.recursive ?? false
|
|
68
|
-
};
|
|
69
|
-
|
|
70
|
-
const response = await this.post<MkdirResult>('/api/mkdir', data);
|
|
71
|
-
|
|
72
|
-
this.logSuccess(
|
|
73
|
-
'Directory created',
|
|
74
|
-
`${path} (recursive: ${data.recursive})`
|
|
75
|
-
);
|
|
76
|
-
return response;
|
|
77
|
-
} catch (error) {
|
|
78
|
-
this.logError('mkdir', error);
|
|
79
|
-
throw error;
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
/**
|
|
84
|
-
* Write content to a file
|
|
85
|
-
* @param path - File path to write to
|
|
86
|
-
* @param content - Content to write
|
|
87
|
-
* @param sessionId - The session ID for this operation
|
|
88
|
-
* @param options - Optional settings (encoding)
|
|
89
|
-
*/
|
|
90
|
-
async writeFile(
|
|
91
|
-
path: string,
|
|
92
|
-
content: string,
|
|
93
|
-
sessionId: string,
|
|
94
|
-
options?: { encoding?: string }
|
|
95
|
-
): Promise<WriteFileResult> {
|
|
96
|
-
try {
|
|
97
|
-
const data = {
|
|
98
|
-
path,
|
|
99
|
-
content,
|
|
100
|
-
sessionId,
|
|
101
|
-
encoding: options?.encoding
|
|
102
|
-
};
|
|
103
|
-
|
|
104
|
-
const response = await this.post<WriteFileResult>('/api/write', data);
|
|
105
|
-
|
|
106
|
-
this.logSuccess('File written', `${path} (${content.length} chars)`);
|
|
107
|
-
return response;
|
|
108
|
-
} catch (error) {
|
|
109
|
-
this.logError('writeFile', error);
|
|
110
|
-
throw error;
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
/**
|
|
115
|
-
* Read content from a file
|
|
116
|
-
* @param path - File path to read from
|
|
117
|
-
* @param sessionId - The session ID for this operation
|
|
118
|
-
* @param options - Optional settings (encoding)
|
|
119
|
-
*/
|
|
120
|
-
async readFile(
|
|
121
|
-
path: string,
|
|
122
|
-
sessionId: string,
|
|
123
|
-
options?: { encoding?: string }
|
|
124
|
-
): Promise<ReadFileResult> {
|
|
125
|
-
try {
|
|
126
|
-
const data = {
|
|
127
|
-
path,
|
|
128
|
-
sessionId,
|
|
129
|
-
encoding: options?.encoding
|
|
130
|
-
};
|
|
131
|
-
|
|
132
|
-
const response = await this.post<ReadFileResult>('/api/read', data);
|
|
133
|
-
|
|
134
|
-
this.logSuccess(
|
|
135
|
-
'File read',
|
|
136
|
-
`${path} (${response.content.length} chars)`
|
|
137
|
-
);
|
|
138
|
-
return response;
|
|
139
|
-
} catch (error) {
|
|
140
|
-
this.logError('readFile', error);
|
|
141
|
-
throw error;
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
/**
|
|
146
|
-
* Stream a file using Server-Sent Events
|
|
147
|
-
* Returns a ReadableStream of SSE events containing metadata, chunks, and completion
|
|
148
|
-
* @param path - File path to stream
|
|
149
|
-
* @param sessionId - The session ID for this operation
|
|
150
|
-
*/
|
|
151
|
-
async readFileStream(
|
|
152
|
-
path: string,
|
|
153
|
-
sessionId: string
|
|
154
|
-
): Promise<ReadableStream<Uint8Array>> {
|
|
155
|
-
try {
|
|
156
|
-
const data = {
|
|
157
|
-
path,
|
|
158
|
-
sessionId
|
|
159
|
-
};
|
|
160
|
-
|
|
161
|
-
const response = await this.doFetch('/api/read/stream', {
|
|
162
|
-
method: 'POST',
|
|
163
|
-
headers: {
|
|
164
|
-
'Content-Type': 'application/json'
|
|
165
|
-
},
|
|
166
|
-
body: JSON.stringify(data)
|
|
167
|
-
});
|
|
168
|
-
|
|
169
|
-
const stream = await this.handleStreamResponse(response);
|
|
170
|
-
this.logSuccess('File stream started', path);
|
|
171
|
-
return stream;
|
|
172
|
-
} catch (error) {
|
|
173
|
-
this.logError('readFileStream', error);
|
|
174
|
-
throw error;
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
/**
|
|
179
|
-
* Delete a file
|
|
180
|
-
* @param path - File path to delete
|
|
181
|
-
* @param sessionId - The session ID for this operation
|
|
182
|
-
*/
|
|
183
|
-
async deleteFile(path: string, sessionId: string): Promise<DeleteFileResult> {
|
|
184
|
-
try {
|
|
185
|
-
const data = { path, sessionId };
|
|
186
|
-
|
|
187
|
-
const response = await this.post<DeleteFileResult>('/api/delete', data);
|
|
188
|
-
|
|
189
|
-
this.logSuccess('File deleted', path);
|
|
190
|
-
return response;
|
|
191
|
-
} catch (error) {
|
|
192
|
-
this.logError('deleteFile', error);
|
|
193
|
-
throw error;
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
/**
|
|
198
|
-
* Rename a file
|
|
199
|
-
* @param path - Current file path
|
|
200
|
-
* @param newPath - New file path
|
|
201
|
-
* @param sessionId - The session ID for this operation
|
|
202
|
-
*/
|
|
203
|
-
async renameFile(
|
|
204
|
-
path: string,
|
|
205
|
-
newPath: string,
|
|
206
|
-
sessionId: string
|
|
207
|
-
): Promise<RenameFileResult> {
|
|
208
|
-
try {
|
|
209
|
-
const data = { oldPath: path, newPath, sessionId };
|
|
210
|
-
|
|
211
|
-
const response = await this.post<RenameFileResult>('/api/rename', data);
|
|
212
|
-
|
|
213
|
-
this.logSuccess('File renamed', `${path} -> ${newPath}`);
|
|
214
|
-
return response;
|
|
215
|
-
} catch (error) {
|
|
216
|
-
this.logError('renameFile', error);
|
|
217
|
-
throw error;
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
/**
|
|
222
|
-
* Move a file
|
|
223
|
-
* @param path - Current file path
|
|
224
|
-
* @param newPath - Destination file path
|
|
225
|
-
* @param sessionId - The session ID for this operation
|
|
226
|
-
*/
|
|
227
|
-
async moveFile(
|
|
228
|
-
path: string,
|
|
229
|
-
newPath: string,
|
|
230
|
-
sessionId: string
|
|
231
|
-
): Promise<MoveFileResult> {
|
|
232
|
-
try {
|
|
233
|
-
const data = { sourcePath: path, destinationPath: newPath, sessionId };
|
|
234
|
-
|
|
235
|
-
const response = await this.post<MoveFileResult>('/api/move', data);
|
|
236
|
-
|
|
237
|
-
this.logSuccess('File moved', `${path} -> ${newPath}`);
|
|
238
|
-
return response;
|
|
239
|
-
} catch (error) {
|
|
240
|
-
this.logError('moveFile', error);
|
|
241
|
-
throw error;
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
/**
|
|
246
|
-
* List files in a directory
|
|
247
|
-
* @param path - Directory path to list
|
|
248
|
-
* @param sessionId - The session ID for this operation
|
|
249
|
-
* @param options - Optional settings (recursive, includeHidden)
|
|
250
|
-
*/
|
|
251
|
-
async listFiles(
|
|
252
|
-
path: string,
|
|
253
|
-
sessionId: string,
|
|
254
|
-
options?: ListFilesOptions
|
|
255
|
-
): Promise<ListFilesResult> {
|
|
256
|
-
try {
|
|
257
|
-
const data = {
|
|
258
|
-
path,
|
|
259
|
-
sessionId,
|
|
260
|
-
options: options || {}
|
|
261
|
-
};
|
|
262
|
-
|
|
263
|
-
const response = await this.post<ListFilesResult>(
|
|
264
|
-
'/api/list-files',
|
|
265
|
-
data
|
|
266
|
-
);
|
|
267
|
-
|
|
268
|
-
this.logSuccess('Files listed', `${path} (${response.count} files)`);
|
|
269
|
-
return response;
|
|
270
|
-
} catch (error) {
|
|
271
|
-
this.logError('listFiles', error);
|
|
272
|
-
throw error;
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
/**
|
|
277
|
-
* Check if a file or directory exists
|
|
278
|
-
* @param path - Path to check
|
|
279
|
-
* @param sessionId - The session ID for this operation
|
|
280
|
-
*/
|
|
281
|
-
async exists(path: string, sessionId: string): Promise<FileExistsResult> {
|
|
282
|
-
try {
|
|
283
|
-
const data = {
|
|
284
|
-
path,
|
|
285
|
-
sessionId
|
|
286
|
-
};
|
|
287
|
-
|
|
288
|
-
const response = await this.post<FileExistsResult>('/api/exists', data);
|
|
289
|
-
|
|
290
|
-
this.logSuccess(
|
|
291
|
-
'Path existence checked',
|
|
292
|
-
`${path} (exists: ${response.exists})`
|
|
293
|
-
);
|
|
294
|
-
return response;
|
|
295
|
-
} catch (error) {
|
|
296
|
-
this.logError('exists', error);
|
|
297
|
-
throw error;
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
}
|
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
import type { GitCheckoutResult } from '@repo/shared';
|
|
2
|
-
import { GitLogger } from '@repo/shared';
|
|
3
|
-
import { BaseHttpClient } from './base-client';
|
|
4
|
-
import type { HttpClientOptions, SessionRequest } from './types';
|
|
5
|
-
|
|
6
|
-
// Re-export for convenience
|
|
7
|
-
export type { GitCheckoutResult };
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Request interface for Git checkout operations
|
|
11
|
-
*/
|
|
12
|
-
export interface GitCheckoutRequest extends SessionRequest {
|
|
13
|
-
repoUrl: string;
|
|
14
|
-
branch?: string;
|
|
15
|
-
targetDir?: string;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Client for Git repository operations
|
|
20
|
-
*/
|
|
21
|
-
export class GitClient extends BaseHttpClient {
|
|
22
|
-
constructor(options: HttpClientOptions = {}) {
|
|
23
|
-
super(options);
|
|
24
|
-
// Wrap logger with GitLogger to auto-redact credentials
|
|
25
|
-
this.logger = new GitLogger(this.logger);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Clone a Git repository
|
|
30
|
-
* @param repoUrl - URL of the Git repository to clone
|
|
31
|
-
* @param sessionId - The session ID for this operation
|
|
32
|
-
* @param options - Optional settings (branch, targetDir)
|
|
33
|
-
*/
|
|
34
|
-
async checkout(
|
|
35
|
-
repoUrl: string,
|
|
36
|
-
sessionId: string,
|
|
37
|
-
options?: {
|
|
38
|
-
branch?: string;
|
|
39
|
-
targetDir?: string;
|
|
40
|
-
}
|
|
41
|
-
): Promise<GitCheckoutResult> {
|
|
42
|
-
try {
|
|
43
|
-
// Determine target directory - use provided path or generate from repo name
|
|
44
|
-
let targetDir = options?.targetDir;
|
|
45
|
-
if (!targetDir) {
|
|
46
|
-
const repoName = this.extractRepoName(repoUrl);
|
|
47
|
-
// Ensure absolute path in /workspace
|
|
48
|
-
targetDir = `/workspace/${repoName}`;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
const data: GitCheckoutRequest = {
|
|
52
|
-
repoUrl,
|
|
53
|
-
sessionId,
|
|
54
|
-
targetDir
|
|
55
|
-
};
|
|
56
|
-
|
|
57
|
-
// Only include branch if explicitly specified
|
|
58
|
-
// This allows Git to use the repository's default branch
|
|
59
|
-
if (options?.branch) {
|
|
60
|
-
data.branch = options.branch;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
const response = await this.post<GitCheckoutResult>(
|
|
64
|
-
'/api/git/checkout',
|
|
65
|
-
data
|
|
66
|
-
);
|
|
67
|
-
|
|
68
|
-
this.logSuccess(
|
|
69
|
-
'Repository cloned',
|
|
70
|
-
`${repoUrl} (branch: ${response.branch}) -> ${response.targetDir}`
|
|
71
|
-
);
|
|
72
|
-
|
|
73
|
-
return response;
|
|
74
|
-
} catch (error) {
|
|
75
|
-
this.logError('checkout', error);
|
|
76
|
-
throw error;
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
/**
|
|
81
|
-
* Extract repository name from URL for default directory name
|
|
82
|
-
*/
|
|
83
|
-
private extractRepoName(repoUrl: string): string {
|
|
84
|
-
try {
|
|
85
|
-
const url = new URL(repoUrl);
|
|
86
|
-
const pathParts = url.pathname.split('/');
|
|
87
|
-
const repoName = pathParts[pathParts.length - 1];
|
|
88
|
-
|
|
89
|
-
// Remove .git extension if present
|
|
90
|
-
return repoName.replace(/\.git$/, '');
|
|
91
|
-
} catch {
|
|
92
|
-
// Fallback for invalid URLs
|
|
93
|
-
const parts = repoUrl.split('/');
|
|
94
|
-
const repoName = parts[parts.length - 1];
|
|
95
|
-
return repoName.replace(/\.git$/, '') || 'repo';
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
}
|
package/src/clients/index.ts
DELETED
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
// Main client exports
|
|
2
|
-
|
|
3
|
-
// Command client types
|
|
4
|
-
export type { ExecuteRequest, ExecuteResponse } from './command-client';
|
|
5
|
-
|
|
6
|
-
// Domain-specific clients
|
|
7
|
-
export { CommandClient } from './command-client';
|
|
8
|
-
// File client types
|
|
9
|
-
export type {
|
|
10
|
-
FileOperationRequest,
|
|
11
|
-
MkdirRequest,
|
|
12
|
-
ReadFileRequest,
|
|
13
|
-
WriteFileRequest
|
|
14
|
-
} from './file-client';
|
|
15
|
-
export { FileClient } from './file-client';
|
|
16
|
-
// Git client types
|
|
17
|
-
export type { GitCheckoutRequest, GitCheckoutResult } from './git-client';
|
|
18
|
-
export { GitClient } from './git-client';
|
|
19
|
-
export {
|
|
20
|
-
type ExecutionCallbacks,
|
|
21
|
-
InterpreterClient
|
|
22
|
-
} from './interpreter-client';
|
|
23
|
-
// Port client types
|
|
24
|
-
export type {
|
|
25
|
-
ExposePortRequest,
|
|
26
|
-
PortCloseResult,
|
|
27
|
-
PortExposeResult,
|
|
28
|
-
PortListResult,
|
|
29
|
-
UnexposePortRequest
|
|
30
|
-
} from './port-client';
|
|
31
|
-
export { PortClient } from './port-client';
|
|
32
|
-
// Process client types
|
|
33
|
-
export type {
|
|
34
|
-
ProcessCleanupResult,
|
|
35
|
-
ProcessInfoResult,
|
|
36
|
-
ProcessKillResult,
|
|
37
|
-
ProcessListResult,
|
|
38
|
-
ProcessLogsResult,
|
|
39
|
-
ProcessStartResult,
|
|
40
|
-
StartProcessRequest
|
|
41
|
-
} from './process-client';
|
|
42
|
-
export { ProcessClient } from './process-client';
|
|
43
|
-
export { SandboxClient } from './sandbox-client';
|
|
44
|
-
// Types and interfaces
|
|
45
|
-
export type {
|
|
46
|
-
BaseApiResponse,
|
|
47
|
-
ContainerStub,
|
|
48
|
-
ErrorResponse,
|
|
49
|
-
HttpClientOptions,
|
|
50
|
-
RequestConfig,
|
|
51
|
-
ResponseHandler,
|
|
52
|
-
SessionRequest
|
|
53
|
-
} from './types';
|
|
54
|
-
// Utility client types
|
|
55
|
-
export type {
|
|
56
|
-
CommandsResponse,
|
|
57
|
-
CreateSessionRequest,
|
|
58
|
-
CreateSessionResponse,
|
|
59
|
-
DeleteSessionRequest,
|
|
60
|
-
DeleteSessionResponse,
|
|
61
|
-
PingResponse,
|
|
62
|
-
VersionResponse
|
|
63
|
-
} from './utility-client';
|
|
64
|
-
export { UtilityClient } from './utility-client';
|