@capsule-run/sdk 0.6.4 → 0.7.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/README.md +16 -10
- package/dist/task.d.ts +8 -2
- package/dist/task.d.ts.map +1 -1
- package/dist/task.js +17 -1
- package/dist/task.js.map +1 -1
- package/package.json +1 -1
- package/src/task.ts +28 -3
package/README.md
CHANGED
|
@@ -173,7 +173,7 @@ Every task returns a structured JSON envelope containing both the result and exe
|
|
|
173
173
|
| `ram` | Memory limit | `string` | unlimited | `"512MB"`, `"2GB"` |
|
|
174
174
|
| `timeout` | Maximum execution time | `string` or `number` | unlimited | `"30s"`, `"5m"` |
|
|
175
175
|
| `maxRetries` | Retry attempts on failure | `number` | `0` | `3` |
|
|
176
|
-
| `allowedFiles` | Folders accessible in the sandbox | `string[]` | `[]` | `["./data"
|
|
176
|
+
| `allowedFiles` | Folders accessible in the sandbox (with optional access mode) | `(string \| AllowedFile)[]` | `[]` | `["./data"]`, `[{ path: "./data", mode: "ro" }]` |
|
|
177
177
|
| `allowedHosts` | Domains accessible in the sandbox | `string[]` | `["*"]` | `["api.openai.com", "*.anthropic.com"]` |
|
|
178
178
|
| `envVariables` | Environment variables accessible in the sandbox | `string[]` | `[]` | `["API_KEY"]` |
|
|
179
179
|
|
|
@@ -206,25 +206,31 @@ Task-level options always override these defaults.
|
|
|
206
206
|
|
|
207
207
|
Tasks can read and write files within directories specified in `allowedFiles`. Any attempt to access files outside these directories is not possible.
|
|
208
208
|
|
|
209
|
+
> `allowedFiles` supports directory paths only, not individual files.
|
|
210
|
+
|
|
211
|
+
Each entry can be a plain path (read-write by default) or an `AllowedFile` object with an explicit `mode`: `"read-only"` (or `"ro"`) or `"read-write"` (or `"rw"`).
|
|
212
|
+
|
|
209
213
|
Common Node.js built-ins are available. Use the standard `fs` module:
|
|
210
214
|
|
|
211
215
|
```typescript
|
|
212
216
|
import { task } from "@capsule-run/sdk";
|
|
213
217
|
import fs from "fs/promises";
|
|
214
218
|
|
|
215
|
-
export const
|
|
216
|
-
name: "
|
|
217
|
-
allowedFiles: [
|
|
219
|
+
export const main = task({
|
|
220
|
+
name: "main",
|
|
221
|
+
allowedFiles: [
|
|
222
|
+
{ path: "./data", mode: "read-only" },
|
|
223
|
+
{ path: "./output", mode: "read-write" },
|
|
224
|
+
]
|
|
218
225
|
}, async () => {
|
|
219
|
-
await fs.
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
export const main = task({ name: "main", allowedFiles: ["./data"] }, async () => {
|
|
223
|
-
await restrictedWriter();
|
|
224
|
-
return await fs.readFile("./data/input.txt", "utf8");
|
|
226
|
+
const content = await fs.readFile("./data/input.txt", "utf8");
|
|
227
|
+
await fs.writeFile("./output/result.txt", content);
|
|
228
|
+
return content;
|
|
225
229
|
});
|
|
226
230
|
```
|
|
227
231
|
|
|
232
|
+
Plain strings are still accepted: `allowedFiles: ["./output"]` defaults to read-write.
|
|
233
|
+
|
|
228
234
|
### Network Access
|
|
229
235
|
|
|
230
236
|
Tasks can make HTTP requests to domains specified in `allowedHosts`. By default, all outbound requests are allowed (`[\"*\"]`). Restrict access by providing a whitelist of domains.
|
package/dist/task.d.ts
CHANGED
|
@@ -4,6 +4,12 @@
|
|
|
4
4
|
* Provides the `task` wrapper function for defining Capsule tasks
|
|
5
5
|
* in an idiomatic TypeScript way.
|
|
6
6
|
*/
|
|
7
|
+
export interface AllowedFile {
|
|
8
|
+
/** Path to the directory, e.g., "./data" */
|
|
9
|
+
path: string;
|
|
10
|
+
/** Access mode: "read-only" / "ro" or "read-write" / "rw" (default) */
|
|
11
|
+
mode?: "read-only" | "read-write" | "ro" | "rw";
|
|
12
|
+
}
|
|
7
13
|
export interface TaskOptions {
|
|
8
14
|
/** Task name (required) */
|
|
9
15
|
name: string;
|
|
@@ -19,8 +25,8 @@ export interface TaskOptions {
|
|
|
19
25
|
timeout?: string | number;
|
|
20
26
|
/** Maximum number of retries */
|
|
21
27
|
maxRetries?: number;
|
|
22
|
-
/** Files/folders accessible in the sandbox, e.g., ["./data"] */
|
|
23
|
-
allowedFiles?: string[];
|
|
28
|
+
/** Files/folders accessible in the sandbox, e.g., ["./data"] or [{ path: "./data", mode: "ro" }] */
|
|
29
|
+
allowedFiles?: (string | AllowedFile)[];
|
|
24
30
|
/** Allowed hosts for HTTP requests */
|
|
25
31
|
allowedHosts?: string[];
|
|
26
32
|
/** Environment variables available from your .env file for the task */
|
package/dist/task.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"task.d.ts","sourceRoot":"","sources":["../src/task.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,MAAM,WAAW,WAAW;IAC1B,2BAA2B;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,gDAAgD;IAChD,OAAO,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,MAAM,CAAC;IAC7C,sCAAsC;IACtC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC1B,gCAAgC;IAChC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,
|
|
1
|
+
{"version":3,"file":"task.d.ts","sourceRoot":"","sources":["../src/task.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,MAAM,WAAW,WAAW;IAC1B,4CAA4C;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,uEAAuE;IACvE,IAAI,CAAC,EAAE,WAAW,GAAG,YAAY,GAAG,IAAI,GAAG,IAAI,CAAC;CACjD;AAED,MAAM,WAAW,WAAW;IAC1B,2BAA2B;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,gDAAgD;IAChD,OAAO,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,MAAM,CAAC;IAC7C,sCAAsC;IACtC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC1B,gCAAgC;IAChC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,oGAAoG;IACpG,YAAY,CAAC,EAAE,CAAC,MAAM,GAAG,WAAW,CAAC,EAAE,CAAC;IACxC,sCAAsC;IACtC,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,uEAAuE;IACvE,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB;AAED,UAAU,UAAU,CAAC,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,CAAC,CAAC;IACV,KAAK,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IACtD,SAAS,EAAE,aAAa,CAAC;CAC1B;AAED,UAAU,aAAa;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;CACzB;AAID,KAAK,cAAc,CAAC,CAAC,IAAI,CAAC,SAAS,OAAO,CAAC,MAAM,CAAC,CAAC,GAC/C,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,GACtB,UAAU,CAAC,CAAC,CAAC,CAAC;AAiElB,wBAAgB,IAAI,CAAC,KAAK,SAAS,GAAG,EAAE,EAAE,OAAO,EAC/C,OAAO,EAAE,WAAW,EACpB,EAAE,EAAE,CAAC,GAAG,IAAI,EAAE,KAAK,KAAK,OAAO,GAC9B,CAAC,GAAG,IAAI,EAAE,KAAK,KAAK,cAAc,CAAC,OAAO,CAAC,CA+D7C"}
|
package/dist/task.js
CHANGED
|
@@ -50,6 +50,22 @@ function normalizeTimeout(timeout) {
|
|
|
50
50
|
}
|
|
51
51
|
return timeout;
|
|
52
52
|
}
|
|
53
|
+
function normalizeAllowedFile(entry) {
|
|
54
|
+
if (typeof entry === "string")
|
|
55
|
+
return entry;
|
|
56
|
+
switch (entry.mode) {
|
|
57
|
+
case undefined:
|
|
58
|
+
case "rw":
|
|
59
|
+
case "read-write":
|
|
60
|
+
return entry.path;
|
|
61
|
+
case "ro":
|
|
62
|
+
case "read-only":
|
|
63
|
+
return `${entry.path}:ro`;
|
|
64
|
+
default:
|
|
65
|
+
throw new Error(`Invalid allowed_files mode '${entry.mode}' for path '${entry.path}'. ` +
|
|
66
|
+
`Use 'read-only' or 'read-write'.`);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
53
69
|
export function task(options, fn) {
|
|
54
70
|
const taskName = options.name;
|
|
55
71
|
let compute = options.compute?.toString().toUpperCase() ?? "MEDIUM";
|
|
@@ -60,7 +76,7 @@ export function task(options, fn) {
|
|
|
60
76
|
ram: options.ram,
|
|
61
77
|
timeout: normalizeTimeout(options.timeout),
|
|
62
78
|
maxRetries: options.maxRetries,
|
|
63
|
-
allowedFiles: options.allowedFiles,
|
|
79
|
+
allowedFiles: options.allowedFiles?.map(normalizeAllowedFile),
|
|
64
80
|
allowedHosts,
|
|
65
81
|
envVariables: options.envVariables,
|
|
66
82
|
};
|
package/dist/task.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"task.js","sourceRoot":"","sources":["../src/task.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,YAAY,EAAmB,MAAM,UAAU,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"task.js","sourceRoot":"","sources":["../src/task.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/src/task.ts
CHANGED
|
@@ -8,6 +8,13 @@
|
|
|
8
8
|
import { registerTask, type TaskConfig } from "./app.js";
|
|
9
9
|
import { isWasmMode, callHost } from "./hostApi.js";
|
|
10
10
|
|
|
11
|
+
export interface AllowedFile {
|
|
12
|
+
/** Path to the directory, e.g., "./data" */
|
|
13
|
+
path: string;
|
|
14
|
+
/** Access mode: "read-only" / "ro" or "read-write" / "rw" (default) */
|
|
15
|
+
mode?: "read-only" | "read-write" | "ro" | "rw";
|
|
16
|
+
}
|
|
17
|
+
|
|
11
18
|
export interface TaskOptions {
|
|
12
19
|
/** Task name (required) */
|
|
13
20
|
name: string;
|
|
@@ -23,8 +30,8 @@ export interface TaskOptions {
|
|
|
23
30
|
timeout?: string | number;
|
|
24
31
|
/** Maximum number of retries */
|
|
25
32
|
maxRetries?: number;
|
|
26
|
-
/** Files/folders accessible in the sandbox, e.g., ["./data"] */
|
|
27
|
-
allowedFiles?: string[];
|
|
33
|
+
/** Files/folders accessible in the sandbox, e.g., ["./data"] or [{ path: "./data", mode: "ro" }] */
|
|
34
|
+
allowedFiles?: (string | AllowedFile)[];
|
|
28
35
|
/** Allowed hosts for HTTP requests */
|
|
29
36
|
allowedHosts?: string[];
|
|
30
37
|
/** Environment variables available from your .env file for the task */
|
|
@@ -96,6 +103,24 @@ function normalizeTimeout(timeout?: string | number): string | undefined {
|
|
|
96
103
|
return timeout;
|
|
97
104
|
}
|
|
98
105
|
|
|
106
|
+
function normalizeAllowedFile(entry: string | AllowedFile): string {
|
|
107
|
+
if (typeof entry === "string") return entry;
|
|
108
|
+
switch (entry.mode) {
|
|
109
|
+
case undefined:
|
|
110
|
+
case "rw":
|
|
111
|
+
case "read-write":
|
|
112
|
+
return entry.path;
|
|
113
|
+
case "ro":
|
|
114
|
+
case "read-only":
|
|
115
|
+
return `${entry.path}:ro`;
|
|
116
|
+
default:
|
|
117
|
+
throw new Error(
|
|
118
|
+
`Invalid allowed_files mode '${(entry as any).mode}' for path '${entry.path}'. ` +
|
|
119
|
+
`Use 'read-only' or 'read-write'.`
|
|
120
|
+
);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
99
124
|
export function task<TArgs extends any[], TReturn>(
|
|
100
125
|
options: TaskOptions,
|
|
101
126
|
fn: (...args: TArgs) => TReturn
|
|
@@ -110,7 +135,7 @@ export function task<TArgs extends any[], TReturn>(
|
|
|
110
135
|
ram: options.ram,
|
|
111
136
|
timeout: normalizeTimeout(options.timeout),
|
|
112
137
|
maxRetries: options.maxRetries,
|
|
113
|
-
allowedFiles: options.allowedFiles,
|
|
138
|
+
allowedFiles: options.allowedFiles?.map(normalizeAllowedFile),
|
|
114
139
|
allowedHosts,
|
|
115
140
|
envVariables: options.envVariables,
|
|
116
141
|
};
|