@giselles-ai/sandkit 0.1.0 → 0.1.2
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 +51 -7
- package/dist/adapters/drizzle.d.ts +2 -2
- package/dist/adapters/memory.d.ts +2 -2
- package/dist/adapters/sqlite-bun.d.ts +2 -2
- package/dist/{chunk-FSDVHEEX.js → chunk-2M2AZUOC.js} +2 -2
- package/dist/chunk-5MXHFOJH.js +50 -0
- package/dist/chunk-5MXHFOJH.js.map +1 -0
- package/dist/{chunk-7DLK7LOM.js → chunk-6GHZO3Y5.js} +2 -2
- package/dist/{chunk-VISDS5T7.js → chunk-NKTNTBOY.js} +97 -4
- package/dist/chunk-NKTNTBOY.js.map +1 -0
- package/dist/chunk-T76VM5D2.js +23 -0
- package/dist/chunk-T76VM5D2.js.map +1 -0
- package/dist/{chunk-REGOUXVI.js → chunk-UEAKE56H.js} +2 -2
- package/dist/{chunk-HVYCAAZQ.js → chunk-XN6DGLRP.js} +1 -1
- package/dist/chunk-XN6DGLRP.js.map +1 -0
- package/dist/chunk-YGUNJGP7.js +23 -0
- package/dist/chunk-YGUNJGP7.js.map +1 -0
- package/dist/index.d.ts +12 -8
- package/dist/index.js +353 -127
- package/dist/index.js.map +1 -1
- package/dist/integrations/mock.d.ts +3 -3
- package/dist/integrations/mock.js +21 -4
- package/dist/integrations/mock.js.map +1 -1
- package/dist/integrations/vercel.d.ts +3 -3
- package/dist/integrations/vercel.js +59 -17
- package/dist/integrations/vercel.js.map +1 -1
- package/dist/policies/ai-gateway.d.ts +1 -1
- package/dist/policies/ai-gateway.js +2 -2
- package/dist/policies/bun.d.ts +9 -0
- package/dist/policies/bun.js +10 -0
- package/dist/policies/bun.js.map +1 -0
- package/dist/policies/codex.d.ts +1 -1
- package/dist/policies/codex.js +2 -2
- package/dist/policies/gemini.d.ts +1 -1
- package/dist/policies/gemini.js +2 -2
- package/dist/policies/npm.d.ts +12 -0
- package/dist/policies/npm.js +10 -0
- package/dist/policies/npm.js.map +1 -0
- package/dist/{types-Cy36bS1j.d.ts → types-DNpj280o.d.ts} +2 -2
- package/dist/{types-BCgprbo8.d.ts → types-Dpr_BkF9.d.ts} +3 -0
- package/dist/{types-BEKQnjeb.d.ts → types-nu3vpBCZ.d.ts} +35 -5
- package/package.json +11 -1
- package/dist/chunk-HVYCAAZQ.js.map +0 -1
- package/dist/chunk-VISDS5T7.js.map +0 -1
- package/dist/chunk-XM4HGRXW.js +0 -37
- package/dist/chunk-XM4HGRXW.js.map +0 -1
- /package/dist/{chunk-FSDVHEEX.js.map → chunk-2M2AZUOC.js.map} +0 -0
- /package/dist/{chunk-7DLK7LOM.js.map → chunk-6GHZO3Y5.js.map} +0 -0
- /package/dist/{chunk-REGOUXVI.js.map → chunk-UEAKE56H.js.map} +0 -0
package/README.md
CHANGED
|
@@ -11,6 +11,8 @@ It keeps two paths explicit:
|
|
|
11
11
|
|
|
12
12
|
An active session is an exclusive workspace lease. While a live session is open, `runCommand()` is unavailable until you attach to that session or commit it.
|
|
13
13
|
|
|
14
|
+
Durable lock enforcement is currently in-process (`packages/sandkit` only). Concurrent durable commands for the same workspace are excluded while one is in flight in the same process.
|
|
15
|
+
|
|
14
16
|
Provider-specific behavior still matters, but the public API stays centered on workspaces, policies, and durable state.
|
|
15
17
|
|
|
16
18
|
## Problem
|
|
@@ -95,18 +97,43 @@ const result = await workspace.sandbox.runCommand({
|
|
|
95
97
|
console.log(result.stdout.trim());
|
|
96
98
|
```
|
|
97
99
|
|
|
100
|
+
`runCommand(...)` (without `detached`) resolves to `CommandResult` only after the full unit-of-work is complete: process exit, snapshot/commit, and persist.
|
|
101
|
+
|
|
102
|
+
For detached execution, pass `detached: true` and you get a `Command` object. Observe logs and then await durable completion:
|
|
103
|
+
|
|
104
|
+
```ts
|
|
105
|
+
const command = await workspace.sandbox.runCommand({
|
|
106
|
+
command: "sh",
|
|
107
|
+
args: ["-lc", "echo 'start'; sleep 1; echo 'done'"],
|
|
108
|
+
detached: true,
|
|
109
|
+
});
|
|
110
|
+
for await (const chunk of command.logs?.() ?? []) {
|
|
111
|
+
console.log(`${chunk.stream}: ${chunk.chunk}`);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
const commandResult = await command.wait();
|
|
115
|
+
```
|
|
116
|
+
|
|
98
117
|
Set `VERCEL_OIDC_TOKEN` for local runs or `VERCEL_ACCESS_TOKEN` in CI before creating a Vercel-backed sandbox.
|
|
99
118
|
|
|
100
119
|
Declare `exposedPorts` on `createWorkspace({ sandbox: ... })` only when you need a live session URL. `defaultTimeout` is the provider-level lease default; override a specific live session with `openSession({ timeoutMs })`.
|
|
101
120
|
|
|
102
121
|
## Setup bootstrap
|
|
103
122
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
123
|
+
`setup` is the shared bootstrap definition, not the materialized artifact.
|
|
124
|
+
It is optional.
|
|
125
|
+
When `setup` is provided, it is the shared bootstrap command, args, and required durable `policy`.
|
|
126
|
+
This produces adapter-scoped shared bootstrap state keyed by `adapter.id` + setup definition fingerprint.
|
|
127
|
+
Multiple Sandkit instances using the same adapter and setup definition can reuse the same shared bootstrap state.
|
|
128
|
+
|
|
129
|
+
`sandkit.bootstrap()` is an optional eager materialization step:
|
|
130
|
+
|
|
131
|
+
- it creates shared bootstrap state if missing,
|
|
132
|
+
- it leaves existing shared bootstrap state untouched,
|
|
133
|
+
- it does not run a restore path to prove an existing shared bootstrap state is still usable.
|
|
134
|
+
|
|
135
|
+
Without `bootstrap()`, shared setup is still materialized lazily on first workspace use (first `runCommand(...)` or `openSession(...)` that needs it).
|
|
136
|
+
Stale or unusable shared bootstrap artifacts are detected and rebuilt in those workspace flows, not by `bootstrap()` alone.
|
|
110
137
|
|
|
111
138
|
`setup` durability is adapter-backed. With a persistent adapter such as Bun SQLite or Drizzle, the shared bootstrap survives process restarts. With the default in-memory adapter, it does not.
|
|
112
139
|
|
|
@@ -123,6 +150,9 @@ const sandkit = createSandkit({
|
|
|
123
150
|
},
|
|
124
151
|
});
|
|
125
152
|
|
|
153
|
+
await sandkit.bootstrap();
|
|
154
|
+
|
|
155
|
+
// Optional: omit bootstrap() and let setup materialize on first workspace use.
|
|
126
156
|
const workspace = await sandkit.createWorkspace({
|
|
127
157
|
name: "bootstrapped-workspace",
|
|
128
158
|
});
|
|
@@ -135,12 +165,25 @@ If you do not pass `database`, Sandkit defaults to the in-memory adapter. That d
|
|
|
135
165
|
|
|
136
166
|
## Policies
|
|
137
167
|
|
|
168
|
+
- `npm()` allows the public npm registry host `registry.npmjs.org`
|
|
169
|
+
- `bun()` allows Bun install/distribution hosts `bun.sh` and `bun.com`
|
|
138
170
|
- `codex()` reads `CODEX_API_KEY`
|
|
139
171
|
- `gemini()` reads `GEMINI_API_KEY`
|
|
140
|
-
- `github()` reads `GITHUB_TOKEN`
|
|
172
|
+
- `github()` reads `GITHUB_TOKEN` and maps it through Vercel Sandbox firewall transforms:
|
|
173
|
+
- `Authorization: Basic <base64(x-access-token:<token>)>` on requests to `github.com`, intended for Git-over-HTTPS operations
|
|
174
|
+
- `Authorization: Bearer <token>` on requests to `api.github.com`
|
|
175
|
+
- no Authorization header for `*.githubusercontent.com`
|
|
141
176
|
- `aiGateway()` reads `AI_GATEWAY_API_KEY` from host env and allows the hostname (plus wildcard) from `AI_GATEWAY_BASE_URL`.
|
|
142
177
|
`AI_GATEWAY_BASE_URL` ports are ignored for allow-listing; only host/domain matches are used.
|
|
143
178
|
|
|
179
|
+
For JavaScript package bootstrap, prefer explicit service presets over `allowAll()`:
|
|
180
|
+
|
|
181
|
+
```ts
|
|
182
|
+
import { allowServices, bun, npm } from "@giselles-ai/sandkit";
|
|
183
|
+
|
|
184
|
+
const policy = allowServices([bun(), npm()]);
|
|
185
|
+
```
|
|
186
|
+
|
|
144
187
|
Durable default policy belongs to the workspace: use `createWorkspace({ policy: ... })` when you create it, or `workspace.setPolicy(...)` later. Pass `policy` to `runCommand(...)` for one-off overrides.
|
|
145
188
|
|
|
146
189
|
## Schema Generation
|
|
@@ -157,6 +200,7 @@ npx @giselles-ai/sandkit generate
|
|
|
157
200
|
|
|
158
201
|
## Examples
|
|
159
202
|
|
|
203
|
+
- `examples/workflow-hello-git`
|
|
160
204
|
- `examples/sandbox-openclaw`
|
|
161
205
|
- `smoke/drizzle-sample`
|
|
162
206
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { SQLWrapper } from 'drizzle-orm';
|
|
2
|
-
import { a as SandkitAdapter } from '../types-
|
|
3
|
-
import '../types-
|
|
2
|
+
import { a as SandkitAdapter } from '../types-DNpj280o.js';
|
|
3
|
+
import '../types-Dpr_BkF9.js';
|
|
4
4
|
|
|
5
5
|
interface DrizzleWorkspaceTableShape {
|
|
6
6
|
readonly id: SQLWrapper;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Database } from 'bun:sqlite';
|
|
2
|
-
import { a as SandkitAdapter } from '../types-
|
|
3
|
-
import '../types-
|
|
2
|
+
import { a as SandkitAdapter } from '../types-DNpj280o.js';
|
|
3
|
+
import '../types-Dpr_BkF9.js';
|
|
4
4
|
|
|
5
5
|
declare function createBunSqliteAdapter(db: Database): SandkitAdapter;
|
|
6
6
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
allowService
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-NKTNTBOY.js";
|
|
4
4
|
|
|
5
5
|
// src/policies/codex.ts
|
|
6
6
|
var CODEX_DOMAINS = ["api.openai.com", "*.openai.com", "openrouter.ai", "*.openrouter.ai"];
|
|
@@ -42,4 +42,4 @@ export {
|
|
|
42
42
|
codex,
|
|
43
43
|
allowCodex
|
|
44
44
|
};
|
|
45
|
-
//# sourceMappingURL=chunk-
|
|
45
|
+
//# sourceMappingURL=chunk-2M2AZUOC.js.map
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
// src/policies/github.ts
|
|
2
|
+
var GITHUB_DOMAINS = ["github.com", "api.github.com", "*.githubusercontent.com"];
|
|
3
|
+
function resolveGithubCredential(options) {
|
|
4
|
+
if (options === void 0) {
|
|
5
|
+
return { kind: "default" };
|
|
6
|
+
}
|
|
7
|
+
if (typeof options.token !== "string" || options.token.trim().length === 0) {
|
|
8
|
+
throw new Error(
|
|
9
|
+
'github(...) explicit override requires a non-empty "token". Omit the options object to use GITHUB_TOKEN.'
|
|
10
|
+
);
|
|
11
|
+
}
|
|
12
|
+
return { kind: "value", value: options.token };
|
|
13
|
+
}
|
|
14
|
+
function resolveGithubDefaultApiKey() {
|
|
15
|
+
return process.env.GITHUB_TOKEN;
|
|
16
|
+
}
|
|
17
|
+
function github(options) {
|
|
18
|
+
const credential = resolveGithubCredential(options);
|
|
19
|
+
return {
|
|
20
|
+
id: "github",
|
|
21
|
+
name: "GitHub",
|
|
22
|
+
description: "Allow requests to github.com and api.github.com through Vercel Sandbox firewall header transforms.",
|
|
23
|
+
domains: GITHUB_DOMAINS,
|
|
24
|
+
domainHeaders: {
|
|
25
|
+
"github.com": [
|
|
26
|
+
{
|
|
27
|
+
headerName: "authorization",
|
|
28
|
+
valuePrefix: "Basic ",
|
|
29
|
+
credentialPrefix: "x-access-token:",
|
|
30
|
+
valueEncoding: "base64",
|
|
31
|
+
credential
|
|
32
|
+
}
|
|
33
|
+
],
|
|
34
|
+
"api.github.com": [
|
|
35
|
+
{
|
|
36
|
+
headerName: "authorization",
|
|
37
|
+
valuePrefix: "Bearer ",
|
|
38
|
+
credential
|
|
39
|
+
}
|
|
40
|
+
],
|
|
41
|
+
"*.githubusercontent.com": []
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export {
|
|
47
|
+
resolveGithubDefaultApiKey,
|
|
48
|
+
github
|
|
49
|
+
};
|
|
50
|
+
//# sourceMappingURL=chunk-5MXHFOJH.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/policies/github.ts"],"sourcesContent":["import type { PolicyServiceDescriptor } from \"./types.ts\";\n\nconst GITHUB_DOMAINS = [\"github.com\", \"api.github.com\", \"*.githubusercontent.com\"] as const;\n\nexport interface GithubOptions {\n readonly token?: string;\n}\n\nfunction resolveGithubCredential(options?: GithubOptions) {\n if (options === undefined) {\n return { kind: \"default\" } as const;\n }\n\n if (typeof options.token !== \"string\" || options.token.trim().length === 0) {\n throw new Error(\n 'github(...) explicit override requires a non-empty \"token\". Omit the options object to use GITHUB_TOKEN.',\n );\n }\n\n return { kind: \"value\", value: options.token } as const;\n}\n\nexport function resolveGithubDefaultApiKey(): string | undefined {\n return process.env.GITHUB_TOKEN;\n}\n\nexport function github(options?: GithubOptions): PolicyServiceDescriptor {\n const credential = resolveGithubCredential(options);\n\n return {\n id: \"github\",\n name: \"GitHub\",\n description:\n \"Allow requests to github.com and api.github.com through Vercel Sandbox firewall header transforms.\",\n domains: GITHUB_DOMAINS,\n domainHeaders: {\n \"github.com\": [\n {\n headerName: \"authorization\",\n valuePrefix: \"Basic \",\n credentialPrefix: \"x-access-token:\",\n valueEncoding: \"base64\",\n credential,\n },\n ],\n \"api.github.com\": [\n {\n headerName: \"authorization\",\n valuePrefix: \"Bearer \",\n credential,\n },\n ],\n \"*.githubusercontent.com\": [],\n },\n };\n}\n"],"mappings":";AAEA,IAAM,iBAAiB,CAAC,cAAc,kBAAkB,yBAAyB;AAMjF,SAAS,wBAAwB,SAAyB;AACxD,MAAI,YAAY,QAAW;AACzB,WAAO,EAAE,MAAM,UAAU;AAAA,EAC3B;AAEA,MAAI,OAAO,QAAQ,UAAU,YAAY,QAAQ,MAAM,KAAK,EAAE,WAAW,GAAG;AAC1E,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,SAAO,EAAE,MAAM,SAAS,OAAO,QAAQ,MAAM;AAC/C;AAEO,SAAS,6BAAiD;AAC/D,SAAO,QAAQ,IAAI;AACrB;AAEO,SAAS,OAAO,SAAkD;AACvE,QAAM,aAAa,wBAAwB,OAAO;AAElD,SAAO;AAAA,IACL,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,aACE;AAAA,IACF,SAAS;AAAA,IACT,eAAe;AAAA,MACb,cAAc;AAAA,QACZ;AAAA,UACE,YAAY;AAAA,UACZ,aAAa;AAAA,UACb,kBAAkB;AAAA,UAClB,eAAe;AAAA,UACf;AAAA,QACF;AAAA,MACF;AAAA,MACA,kBAAkB;AAAA,QAChB;AAAA,UACE,YAAY;AAAA,UACZ,aAAa;AAAA,UACb;AAAA,QACF;AAAA,MACF;AAAA,MACA,2BAA2B,CAAC;AAAA,IAC9B;AAAA,EACF;AACF;","names":[]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
allowService
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-NKTNTBOY.js";
|
|
4
4
|
|
|
5
5
|
// src/policies/gemini.ts
|
|
6
6
|
var GEMINI_DOMAINS = ["ai.google.dev", "*.ai.google.dev", "generativelanguage.googleapis.com"];
|
|
@@ -41,4 +41,4 @@ export {
|
|
|
41
41
|
gemini,
|
|
42
42
|
allowGemini
|
|
43
43
|
};
|
|
44
|
-
//# sourceMappingURL=chunk-
|
|
44
|
+
//# sourceMappingURL=chunk-6GHZO3Y5.js.map
|
|
@@ -22,12 +22,18 @@ function normalizeCredentialSource(source) {
|
|
|
22
22
|
}
|
|
23
23
|
function normalizeHeaderTransform(header) {
|
|
24
24
|
const headerName = header.headerName.trim().toLowerCase();
|
|
25
|
+
const valueEncoding = header.valueEncoding ?? "plain";
|
|
25
26
|
if (!headerName) {
|
|
26
27
|
throw new Error("Policy header transform must include a header name.");
|
|
27
28
|
}
|
|
29
|
+
if (valueEncoding !== "plain" && valueEncoding !== "base64") {
|
|
30
|
+
throw new Error(`Policy header transform for "${headerName}" has unsupported valueEncoding.`);
|
|
31
|
+
}
|
|
28
32
|
return {
|
|
29
33
|
headerName,
|
|
30
34
|
valuePrefix: header.valuePrefix,
|
|
35
|
+
credentialPrefix: header.credentialPrefix,
|
|
36
|
+
valueEncoding,
|
|
31
37
|
credential: normalizeCredentialSource(header.credential)
|
|
32
38
|
};
|
|
33
39
|
}
|
|
@@ -46,12 +52,26 @@ function normalizeService(service) {
|
|
|
46
52
|
if (domains.length === 0) {
|
|
47
53
|
throw new Error(`Policy service "${id}" must declare at least one domain.`);
|
|
48
54
|
}
|
|
55
|
+
const normalizedDomainHeaders = service.domainHeaders === void 0 ? void 0 : Object.fromEntries(
|
|
56
|
+
Object.entries(service.domainHeaders).map(([domain, headers]) => [
|
|
57
|
+
domain.trim(),
|
|
58
|
+
headers.map((header) => normalizeHeaderTransform(header))
|
|
59
|
+
]).filter(([domain]) => Boolean(domain))
|
|
60
|
+
);
|
|
61
|
+
for (const domain of Object.keys(normalizedDomainHeaders ?? {})) {
|
|
62
|
+
if (!domains.includes(domain)) {
|
|
63
|
+
throw new Error(
|
|
64
|
+
`Policy service "${id}" defines domainHeaders for "${domain}" but does not declare that domain.`
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
49
68
|
return {
|
|
50
69
|
id,
|
|
51
70
|
name,
|
|
52
71
|
description: service.description?.trim() || void 0,
|
|
53
72
|
domains,
|
|
54
|
-
headers: service.headers?.map((header) => normalizeHeaderTransform(header))
|
|
73
|
+
headers: service.headers?.map((header) => normalizeHeaderTransform(header)),
|
|
74
|
+
domainHeaders: normalizedDomainHeaders
|
|
55
75
|
};
|
|
56
76
|
}
|
|
57
77
|
function normalizeServices(services) {
|
|
@@ -104,8 +124,22 @@ function redactWorkspacePolicy(policy) {
|
|
|
104
124
|
headers: service.headers?.map((header) => ({
|
|
105
125
|
headerName: header.headerName,
|
|
106
126
|
valuePrefix: header.valuePrefix,
|
|
127
|
+
credentialPrefix: header.credentialPrefix,
|
|
128
|
+
valueEncoding: header.valueEncoding,
|
|
107
129
|
credential: header.credential.kind === "value" ? { kind: "redacted" } : header.credential
|
|
108
|
-
}))
|
|
130
|
+
})),
|
|
131
|
+
domainHeaders: service.domainHeaders === void 0 ? void 0 : Object.fromEntries(
|
|
132
|
+
Object.entries(service.domainHeaders).map(([domain, headers]) => [
|
|
133
|
+
domain,
|
|
134
|
+
headers.map((header) => ({
|
|
135
|
+
headerName: header.headerName,
|
|
136
|
+
valuePrefix: header.valuePrefix,
|
|
137
|
+
credentialPrefix: header.credentialPrefix,
|
|
138
|
+
valueEncoding: header.valueEncoding,
|
|
139
|
+
credential: header.credential.kind === "value" ? { kind: "redacted" } : header.credential
|
|
140
|
+
}))
|
|
141
|
+
])
|
|
142
|
+
)
|
|
109
143
|
}))
|
|
110
144
|
};
|
|
111
145
|
}
|
|
@@ -121,6 +155,15 @@ function assertWorkspacePolicyIsDurable(policy) {
|
|
|
121
155
|
);
|
|
122
156
|
}
|
|
123
157
|
}
|
|
158
|
+
for (const headers of Object.values(service.domainHeaders ?? {})) {
|
|
159
|
+
for (const header of headers) {
|
|
160
|
+
if (header.credential.kind === "value") {
|
|
161
|
+
throw new Error(
|
|
162
|
+
`Workspace policy for service "${service.id}" contains an explicit secret and cannot be stored durably.`
|
|
163
|
+
);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
124
167
|
}
|
|
125
168
|
}
|
|
126
169
|
function parseWorkspacePolicy(value) {
|
|
@@ -158,6 +201,8 @@ function parseWorkspacePolicy(value) {
|
|
|
158
201
|
return normalizeHeaderTransform({
|
|
159
202
|
headerName: header.headerName,
|
|
160
203
|
valuePrefix: typeof header.valuePrefix === "string" ? header.valuePrefix : void 0,
|
|
204
|
+
credentialPrefix: typeof header.credentialPrefix === "string" ? header.credentialPrefix : void 0,
|
|
205
|
+
valueEncoding: header.valueEncoding === "base64" || header.valueEncoding === "plain" ? header.valueEncoding : void 0,
|
|
161
206
|
credential: {
|
|
162
207
|
kind: "default"
|
|
163
208
|
}
|
|
@@ -167,6 +212,8 @@ function parseWorkspacePolicy(value) {
|
|
|
167
212
|
return normalizeHeaderTransform({
|
|
168
213
|
headerName: header.headerName,
|
|
169
214
|
valuePrefix: typeof header.valuePrefix === "string" ? header.valuePrefix : void 0,
|
|
215
|
+
credentialPrefix: typeof header.credentialPrefix === "string" ? header.credentialPrefix : void 0,
|
|
216
|
+
valueEncoding: header.valueEncoding === "base64" || header.valueEncoding === "plain" ? header.valueEncoding : void 0,
|
|
170
217
|
credential: { kind: "redacted" }
|
|
171
218
|
});
|
|
172
219
|
}
|
|
@@ -175,12 +222,58 @@ function parseWorkspacePolicy(value) {
|
|
|
175
222
|
);
|
|
176
223
|
});
|
|
177
224
|
})();
|
|
225
|
+
const domainHeaders = service.domainHeaders === void 0 ? void 0 : (() => {
|
|
226
|
+
if (!isRecord(service.domainHeaders)) {
|
|
227
|
+
throw new Error(`service at index ${index} has invalid domain headers`);
|
|
228
|
+
}
|
|
229
|
+
return Object.fromEntries(
|
|
230
|
+
Object.entries(service.domainHeaders).map(([domain, rawHeaders]) => {
|
|
231
|
+
if (!isRecordArray(rawHeaders)) {
|
|
232
|
+
throw new Error(
|
|
233
|
+
`service at index ${index} has invalid domain headers for ${domain}`
|
|
234
|
+
);
|
|
235
|
+
}
|
|
236
|
+
return [
|
|
237
|
+
domain,
|
|
238
|
+
rawHeaders.map((header, headerIndex) => {
|
|
239
|
+
if (typeof header.headerName !== "string" || !isRecord(header.credential) || typeof header.credential.kind !== "string") {
|
|
240
|
+
throw new Error(
|
|
241
|
+
`service at index ${index} has invalid domain header transform for ${domain} at ${headerIndex}`
|
|
242
|
+
);
|
|
243
|
+
}
|
|
244
|
+
if (header.credential.kind === "default") {
|
|
245
|
+
return normalizeHeaderTransform({
|
|
246
|
+
headerName: header.headerName,
|
|
247
|
+
valuePrefix: typeof header.valuePrefix === "string" ? header.valuePrefix : void 0,
|
|
248
|
+
credentialPrefix: typeof header.credentialPrefix === "string" ? header.credentialPrefix : void 0,
|
|
249
|
+
valueEncoding: header.valueEncoding === "base64" || header.valueEncoding === "plain" ? header.valueEncoding : void 0,
|
|
250
|
+
credential: { kind: "default" }
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
if (header.credential.kind === "redacted") {
|
|
254
|
+
return normalizeHeaderTransform({
|
|
255
|
+
headerName: header.headerName,
|
|
256
|
+
valuePrefix: typeof header.valuePrefix === "string" ? header.valuePrefix : void 0,
|
|
257
|
+
credentialPrefix: typeof header.credentialPrefix === "string" ? header.credentialPrefix : void 0,
|
|
258
|
+
valueEncoding: header.valueEncoding === "base64" || header.valueEncoding === "plain" ? header.valueEncoding : void 0,
|
|
259
|
+
credential: { kind: "redacted" }
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
throw new Error(
|
|
263
|
+
`service at index ${index} contains a non-durable credential source in domain headers`
|
|
264
|
+
);
|
|
265
|
+
})
|
|
266
|
+
];
|
|
267
|
+
})
|
|
268
|
+
);
|
|
269
|
+
})();
|
|
178
270
|
return normalizeService({
|
|
179
271
|
id: service.id,
|
|
180
272
|
name: service.name,
|
|
181
273
|
description: typeof service.description === "string" ? service.description : void 0,
|
|
182
274
|
domains: service.domains,
|
|
183
|
-
headers
|
|
275
|
+
headers,
|
|
276
|
+
domainHeaders
|
|
184
277
|
});
|
|
185
278
|
});
|
|
186
279
|
return allowServices(services);
|
|
@@ -199,4 +292,4 @@ export {
|
|
|
199
292
|
assertWorkspacePolicyIsDurable,
|
|
200
293
|
parseWorkspacePolicy
|
|
201
294
|
};
|
|
202
|
-
//# sourceMappingURL=chunk-
|
|
295
|
+
//# sourceMappingURL=chunk-NKTNTBOY.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/policies/dsl.ts"],"sourcesContent":["import type { JsonValue } from \"../types.ts\";\nimport type {\n PolicyServiceCredentialSource,\n PolicyServiceDescriptor,\n PolicyServiceHeaderTransform,\n WorkspacePolicy,\n} from \"./types.ts\";\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction isStringArray(value: unknown): value is string[] {\n return Array.isArray(value) && value.every((entry) => typeof entry === \"string\");\n}\n\nfunction isRecordArray(value: unknown): value is Record<string, unknown>[] {\n return Array.isArray(value) && value.every((entry) => isRecord(entry));\n}\n\nfunction normalizeCredentialSource(\n source: PolicyServiceCredentialSource,\n): PolicyServiceCredentialSource {\n if (source.kind === \"default\") {\n return { kind: \"default\" };\n }\n\n if (source.kind === \"value\") {\n if (!source.value) {\n throw new Error(\"Policy credential value must not be empty.\");\n }\n return { kind: \"value\", value: source.value };\n }\n\n return { kind: \"redacted\" };\n}\n\nfunction normalizeHeaderTransform(\n header: PolicyServiceHeaderTransform,\n): PolicyServiceHeaderTransform {\n const headerName = header.headerName.trim().toLowerCase();\n const valueEncoding = header.valueEncoding ?? \"plain\";\n if (!headerName) {\n throw new Error(\"Policy header transform must include a header name.\");\n }\n if (valueEncoding !== \"plain\" && valueEncoding !== \"base64\") {\n throw new Error(`Policy header transform for \"${headerName}\" has unsupported valueEncoding.`);\n }\n\n return {\n headerName,\n valuePrefix: header.valuePrefix,\n credentialPrefix: header.credentialPrefix,\n valueEncoding,\n credential: normalizeCredentialSource(header.credential),\n };\n}\n\nfunction normalizeService(service: PolicyServiceDescriptor): PolicyServiceDescriptor {\n const id = service.id.trim();\n const name = service.name.trim();\n const domains = [\n ...new Set(service.domains.map((domain) => domain.trim()).filter(Boolean)),\n ].sort();\n\n if (!id) {\n throw new Error(\"Policy service id must not be empty.\");\n }\n\n if (!name) {\n throw new Error(`Policy service \"${id}\" must have a name.`);\n }\n\n if (domains.length === 0) {\n throw new Error(`Policy service \"${id}\" must declare at least one domain.`);\n }\n\n const normalizedDomainHeaders =\n service.domainHeaders === undefined\n ? undefined\n : Object.fromEntries(\n Object.entries(service.domainHeaders)\n .map(([domain, headers]) => [\n domain.trim(),\n headers.map((header) => normalizeHeaderTransform(header)),\n ])\n .filter(([domain]) => Boolean(domain)),\n );\n\n for (const domain of Object.keys(normalizedDomainHeaders ?? {})) {\n if (!domains.includes(domain)) {\n throw new Error(\n `Policy service \"${id}\" defines domainHeaders for \"${domain}\" but does not declare that domain.`,\n );\n }\n }\n\n return {\n id,\n name,\n description: service.description?.trim() || undefined,\n domains,\n headers: service.headers?.map((header) => normalizeHeaderTransform(header)),\n domainHeaders: normalizedDomainHeaders,\n };\n}\n\nfunction normalizeServices(\n services: readonly PolicyServiceDescriptor[],\n): readonly PolicyServiceDescriptor[] {\n if (services.length === 0) {\n throw new Error(\"allowServices(...) requires at least one service descriptor.\");\n }\n\n const deduped = new Map<string, PolicyServiceDescriptor>();\n for (const service of services) {\n const normalized = normalizeService(service);\n deduped.set(normalized.id, normalized);\n }\n\n return [...deduped.values()].sort((left, right) => left.id.localeCompare(right.id));\n}\n\nexport function allowAll(): WorkspacePolicy {\n return { mode: \"allow-all\" };\n}\n\nexport function denyAll(): WorkspacePolicy {\n return { mode: \"deny-all\" };\n}\n\nexport function allowService(service: PolicyServiceDescriptor): WorkspacePolicy {\n return allowServices([service]);\n}\n\nexport function allowServices(services: readonly PolicyServiceDescriptor[]): WorkspacePolicy {\n return {\n mode: \"allow-services\",\n services: normalizeServices(services),\n };\n}\n\nexport function describeWorkspacePolicy(policy: WorkspacePolicy): string {\n switch (policy.mode) {\n case \"allow-all\":\n return \"allow-all\";\n case \"deny-all\":\n return \"deny-all\";\n case \"allow-services\":\n return `allow-services:${policy.services.map((service) => service.id).join(\",\")}`;\n }\n}\n\nexport function serializeWorkspacePolicy(policy: WorkspacePolicy): JsonValue {\n return policy as unknown as JsonValue;\n}\n\nexport function redactWorkspacePolicy(policy: WorkspacePolicy): WorkspacePolicy {\n if (policy.mode !== \"allow-services\") {\n return policy;\n }\n\n return {\n mode: \"allow-services\",\n services: policy.services.map((service) => ({\n ...service,\n headers: service.headers?.map((header) => ({\n headerName: header.headerName,\n valuePrefix: header.valuePrefix,\n credentialPrefix: header.credentialPrefix,\n valueEncoding: header.valueEncoding,\n credential: header.credential.kind === \"value\" ? { kind: \"redacted\" } : header.credential,\n })),\n domainHeaders:\n service.domainHeaders === undefined\n ? undefined\n : Object.fromEntries(\n Object.entries(service.domainHeaders).map(([domain, headers]) => [\n domain,\n headers.map((header) => ({\n headerName: header.headerName,\n valuePrefix: header.valuePrefix,\n credentialPrefix: header.credentialPrefix,\n valueEncoding: header.valueEncoding,\n credential:\n header.credential.kind === \"value\" ? { kind: \"redacted\" } : header.credential,\n })),\n ]),\n ),\n })),\n };\n}\n\nexport function assertWorkspacePolicyIsDurable(policy: WorkspacePolicy): void {\n if (policy.mode !== \"allow-services\") {\n return;\n }\n\n for (const service of policy.services) {\n for (const header of service.headers ?? []) {\n if (header.credential.kind === \"value\") {\n throw new Error(\n `Workspace policy for service \"${service.id}\" contains an explicit secret and cannot be stored durably.`,\n );\n }\n }\n for (const headers of Object.values(service.domainHeaders ?? {})) {\n for (const header of headers) {\n if (header.credential.kind === \"value\") {\n throw new Error(\n `Workspace policy for service \"${service.id}\" contains an explicit secret and cannot be stored durably.`,\n );\n }\n }\n }\n }\n}\n\nexport function parseWorkspacePolicy(value: unknown): WorkspacePolicy {\n if (!isRecord(value) || typeof value.mode !== \"string\") {\n throw new Error(\"expected workspace policy object\");\n }\n\n if (value.mode === \"allow-all\") {\n return allowAll();\n }\n\n if (value.mode === \"deny-all\") {\n return denyAll();\n }\n\n if (value.mode === \"allow-services\") {\n if (!Array.isArray(value.services)) {\n throw new Error(\"allow-services policy must include a services array\");\n }\n\n const services = value.services.map((service, index) => {\n if (!isRecord(service)) {\n throw new Error(`service at index ${index} must be an object`);\n }\n\n if (\n typeof service.id !== \"string\" ||\n typeof service.name !== \"string\" ||\n !isStringArray(service.domains)\n ) {\n throw new Error(`service at index ${index} has an invalid shape`);\n }\n\n const headers =\n service.headers === undefined\n ? undefined\n : (() => {\n if (!isRecordArray(service.headers)) {\n throw new Error(`service at index ${index} has invalid headers`);\n }\n\n return service.headers.map((header, headerIndex) => {\n if (\n typeof header.headerName !== \"string\" ||\n !isRecord(header.credential) ||\n typeof header.credential.kind !== \"string\"\n ) {\n throw new Error(\n `service at index ${index} has invalid header transform at ${headerIndex}`,\n );\n }\n\n if (header.credential.kind === \"default\") {\n return normalizeHeaderTransform({\n headerName: header.headerName,\n valuePrefix:\n typeof header.valuePrefix === \"string\" ? header.valuePrefix : undefined,\n credentialPrefix:\n typeof header.credentialPrefix === \"string\"\n ? header.credentialPrefix\n : undefined,\n valueEncoding:\n header.valueEncoding === \"base64\" || header.valueEncoding === \"plain\"\n ? header.valueEncoding\n : undefined,\n credential: {\n kind: \"default\",\n },\n });\n }\n\n if (header.credential.kind === \"redacted\") {\n return normalizeHeaderTransform({\n headerName: header.headerName,\n valuePrefix:\n typeof header.valuePrefix === \"string\" ? header.valuePrefix : undefined,\n credentialPrefix:\n typeof header.credentialPrefix === \"string\"\n ? header.credentialPrefix\n : undefined,\n valueEncoding:\n header.valueEncoding === \"base64\" || header.valueEncoding === \"plain\"\n ? header.valueEncoding\n : undefined,\n credential: { kind: \"redacted\" },\n });\n }\n\n throw new Error(\n `service at index ${index} contains a non-durable credential source`,\n );\n });\n })();\n\n const domainHeaders =\n service.domainHeaders === undefined\n ? undefined\n : (() => {\n if (!isRecord(service.domainHeaders)) {\n throw new Error(`service at index ${index} has invalid domain headers`);\n }\n\n return Object.fromEntries(\n Object.entries(service.domainHeaders).map(([domain, rawHeaders]) => {\n if (!isRecordArray(rawHeaders)) {\n throw new Error(\n `service at index ${index} has invalid domain headers for ${domain}`,\n );\n }\n\n return [\n domain,\n rawHeaders.map((header, headerIndex) => {\n if (\n typeof header.headerName !== \"string\" ||\n !isRecord(header.credential) ||\n typeof header.credential.kind !== \"string\"\n ) {\n throw new Error(\n `service at index ${index} has invalid domain header transform for ${domain} at ${headerIndex}`,\n );\n }\n\n if (header.credential.kind === \"default\") {\n return normalizeHeaderTransform({\n headerName: header.headerName,\n valuePrefix:\n typeof header.valuePrefix === \"string\" ? header.valuePrefix : undefined,\n credentialPrefix:\n typeof header.credentialPrefix === \"string\"\n ? header.credentialPrefix\n : undefined,\n valueEncoding:\n header.valueEncoding === \"base64\" || header.valueEncoding === \"plain\"\n ? header.valueEncoding\n : undefined,\n credential: { kind: \"default\" },\n });\n }\n\n if (header.credential.kind === \"redacted\") {\n return normalizeHeaderTransform({\n headerName: header.headerName,\n valuePrefix:\n typeof header.valuePrefix === \"string\" ? header.valuePrefix : undefined,\n credentialPrefix:\n typeof header.credentialPrefix === \"string\"\n ? header.credentialPrefix\n : undefined,\n valueEncoding:\n header.valueEncoding === \"base64\" || header.valueEncoding === \"plain\"\n ? header.valueEncoding\n : undefined,\n credential: { kind: \"redacted\" },\n });\n }\n\n throw new Error(\n `service at index ${index} contains a non-durable credential source in domain headers`,\n );\n }),\n ];\n }),\n );\n })();\n\n return normalizeService({\n id: service.id,\n name: service.name,\n description: typeof service.description === \"string\" ? service.description : undefined,\n domains: service.domains,\n headers,\n domainHeaders,\n });\n });\n\n return allowServices(services);\n }\n\n throw new Error(`unsupported workspace policy mode \"${value.mode}\"`);\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import {
|
|
2
|
+
allowService
|
|
3
|
+
} from "./chunk-NKTNTBOY.js";
|
|
4
|
+
|
|
5
|
+
// src/policies/npm.ts
|
|
6
|
+
var NPM_DOMAINS = ["registry.npmjs.org"];
|
|
7
|
+
function npm() {
|
|
8
|
+
return {
|
|
9
|
+
id: "npm",
|
|
10
|
+
name: "npm",
|
|
11
|
+
description: "Allow outbound access to the public npm package registry.",
|
|
12
|
+
domains: NPM_DOMAINS
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
function allowNpm() {
|
|
16
|
+
return allowService(npm());
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export {
|
|
20
|
+
npm,
|
|
21
|
+
allowNpm
|
|
22
|
+
};
|
|
23
|
+
//# sourceMappingURL=chunk-T76VM5D2.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/policies/npm.ts"],"sourcesContent":["import { allowService } from \"./dsl.ts\";\nimport type { PolicyServiceDescriptor, WorkspacePolicy } from \"./types.ts\";\n\nconst NPM_DOMAINS = [\"registry.npmjs.org\"] as const;\n\n/**\n * Allow outbound access to the public npm package registry.\n *\n * Keep this preset scoped to the actual package source host instead of\n * broadening to unrelated npm web properties.\n */\nexport function npm(): PolicyServiceDescriptor {\n return {\n id: \"npm\",\n name: \"npm\",\n description: \"Allow outbound access to the public npm package registry.\",\n domains: NPM_DOMAINS,\n };\n}\n\nexport function allowNpm(): WorkspacePolicy {\n return allowService(npm());\n}\n"],"mappings":";;;;;AAGA,IAAM,cAAc,CAAC,oBAAoB;AAQlC,SAAS,MAA+B;AAC7C,SAAO;AAAA,IACL,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,aAAa;AAAA,IACb,SAAS;AAAA,EACX;AACF;AAEO,SAAS,WAA4B;AAC1C,SAAO,aAAa,IAAI,CAAC;AAC3B;","names":[]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
allowService
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-NKTNTBOY.js";
|
|
4
4
|
|
|
5
5
|
// src/policies/ai-gateway.ts
|
|
6
6
|
var DEFAULT_AI_GATEWAY_BASE_URL = "https://ai-gateway.vercel.sh/v1";
|
|
@@ -55,4 +55,4 @@ export {
|
|
|
55
55
|
aiGateway,
|
|
56
56
|
allowAiGateway
|
|
57
57
|
};
|
|
58
|
-
//# sourceMappingURL=chunk-
|
|
58
|
+
//# sourceMappingURL=chunk-UEAKE56H.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/types.ts"],"sourcesContent":["import type { SandkitAdapter, WorkspaceRecord } from \"./adapters/types.ts\";\nimport type {\n PolicySnapshotAdapter,\n PolicySnapshotRecord,\n PolicySnapshotCreateInput,\n RunAdapter,\n RunCreateInput,\n RunFinishInput,\n RunRecord,\n RunStatus,\n SetupStateAdapter,\n SetupStateRecord,\n SetupStatePutInput,\n WorkspaceMetadata,\n SharedSetup,\n SharedSetupState,\n WorkspaceStatus,\n} from \"./adapters/types.ts\";\nimport type { WorkspacePolicy } from \"./policies/types.ts\";\n\nexport type JsonPrimitive = boolean | number | string | null;\n\nexport type JsonValue =\n | JsonPrimitive\n | JsonValue[]\n | {\n [key: string]: JsonValue;\n };\n\nexport type {\n SandkitAdapter,\n WorkspaceRecord,\n RunAdapter,\n RunCreateInput,\n RunFinishInput,\n RunRecord,\n PolicySnapshotAdapter,\n PolicySnapshotRecord,\n PolicySnapshotCreateInput,\n RunStatus,\n SetupStateAdapter,\n SetupStateRecord,\n SetupStatePutInput,\n SharedSetup,\n SharedSetupState,\n};\nexport type { WorkspacePolicy };\n\nexport interface WorkspaceCreateOptions {\n id?: string;\n name?: string;\n metadata?: WorkspaceMetadata;\n policy?: WorkspacePolicy;\n sandbox?: {\n /**\n * Durable workspace default for provider port publication. This affects\n * create/restore behavior for live session/public URL flows, not the\n * durable runCommand() unit-of-work model itself.\n */\n readonly exposedPorts?: readonly number[];\n };\n status?: WorkspaceStatus;\n sandboxId?: string;\n lastResumedAt?: string;\n}\n\nexport interface CommandResult {\n exitCode: number;\n stderr: string;\n stdout: string;\n}\n\nexport interface Command {\n /**\n * Wait for durable completion of the command unit-of-work: process exit,\n * snapshot/commit, and persist outcome.\n */\n readonly wait: () => Promise<CommandResult>;\n /**\n * Ephemeral log stream for detached execution. The stream is live-only and does\n * not participate in durable state replay.\n */\n readonly logs?: () => AsyncIterable<WorkspaceSessionLog>;\n}\n\nexport interface SandboxSessionLease {\n readonly sandboxId: string;\n readonly observedAt: string;\n readonly expiresAt: string;\n}\n\nexport interface WorkspaceSandboxLease {\n readonly sandboxId: string;\n readonly observedAt: string;\n readonly expiresAt: string;\n readonly remainingMs: number;\n}\n\nexport interface WorkspaceSessionProcess {\n readonly processId: string;\n wait(): Promise<CommandResult>;\n /**\n * Accesses the same normalized log stream used by onStdout/onStderr callbacks.\n * Sandkit keeps a single internal stream, so callbacks and logs() observe\n * the same sequence and buffered historical chunks are replayed to new readers.\n */\n logs?: () => AsyncIterable<WorkspaceSessionLog>;\n}\n\nexport interface WorkspaceSessionLog {\n readonly stream: \"stdout\" | \"stderr\";\n readonly chunk: string;\n}\n\nexport interface WorkspaceSessionProcessStartInput {\n readonly command: string;\n readonly args: readonly string[];\n /**\n * Optional per-call policy override for this session process.\n */\n readonly policy?: WorkspacePolicy;\n /**\n * Callbacks consume chunks from Sandkit's normalized process log stream.\n */\n readonly onStdout?: ((chunk: string) => void) | undefined;\n /**\n * Callbacks consume chunks from Sandkit's normalized process log stream.\n */\n readonly onStderr?: ((chunk: string) => void) | undefined;\n}\n\nexport interface WorkspaceSessionRunCommandOptions {\n readonly command: string;\n readonly args?: readonly string[];\n readonly policy?: WorkspacePolicy;\n}\n\ninterface WorkspaceRunCommandBaseOptions {\n readonly command: string;\n readonly args?: readonly string[];\n readonly policy?: WorkspacePolicy;\n /**\n * Ephemeral timeout override for this durable runCommand() invocation.\n * This affects sandbox create/restore lease timing for the run only and\n * must not mutate durable workspace defaults.\n */\n readonly timeoutMs?: number;\n}\n\nexport interface WorkspaceRunCommandOptions extends WorkspaceRunCommandBaseOptions {}\n\nexport interface WorkspaceRunCommandDetachedOptions extends WorkspaceRunCommandBaseOptions {\n readonly detached: true;\n}\n\nexport type SandboxRunCommandOptions =\n | WorkspaceRunCommandOptions\n | WorkspaceRunCommandDetachedOptions;\n\nexport interface PersistedSandboxState {\n readonly kind: string;\n readonly sessionId: string;\n readonly state?: JsonValue;\n}\n\nexport interface SandboxDriver {\n readonly id: string;\n readonly provider: string;\n applyPolicy(policy: WorkspacePolicy): Promise<void>;\n /**\n * Returns lease timing observed from the current sandbox instance.\n * Some providers expose this as an interpreted timeout value.\n * Sandkit persists lease updates only from explicit session open/extend paths,\n * so callers should not treat mere reads as lease refreshes.\n */\n getSessionLease(): Promise<SandboxSessionLease>;\n runCommand(\n command: string,\n args: string[],\n options?: { readonly detached?: boolean },\n ): Promise<Command>;\n startProcess?(input: WorkspaceSessionProcessStartInput): Promise<WorkspaceSessionProcess>;\n /** Persists and restores durability state through commit() and attach/restore APIs. */\n snapshot(): Promise<PersistedSandboxState>;\n url?(port: number): Promise<string>;\n extendTimeout?(durationMs: number): Promise<void>;\n}\n\nexport interface SandboxCreateOptions {\n readonly policy: WorkspacePolicy;\n readonly exposedPorts?: readonly number[];\n readonly timeoutMs?: number;\n}\n\nexport interface SandboxDriverFactory {\n createSandbox(workspace: WorkspaceRecord, options: SandboxCreateOptions): Promise<SandboxDriver>;\n resumeSandbox(\n workspace: WorkspaceRecord,\n snapshot: PersistedSandboxState,\n options: SandboxCreateOptions,\n ): Promise<SandboxDriver>;\n isSessionUnavailableError?(error: unknown): boolean;\n}\n\nexport interface VercelSandboxOptions {\n runtime?: string;\n /**\n * Provider default sandbox lease timeout in milliseconds. Sandkit uses this\n * when creating or restoring a sandbox unless openSession({ timeoutMs })\n * supplies a live-session override.\n */\n defaultTimeout?: number;\n /**\n * Legacy alias retained for compatibility with existing call sites.\n * Prefer defaultTimeout for new code.\n */\n timeout?: number;\n}\n\nconst sandboxProviderContract = Symbol(\"sandkit.sandbox.provider\");\n\ntype SandboxProviderRecord = {\n readonly provider: string;\n readonly driverFactory: SandboxDriverFactory;\n};\n\nexport interface SandkitSandboxProvider {\n readonly [sandboxProviderContract]: SandboxProviderRecord;\n}\n\nexport function createSandboxProvider(\n provider: string,\n driverFactory: SandboxDriverFactory,\n): SandkitSandboxProvider {\n return {\n [sandboxProviderContract]: {\n provider,\n driverFactory,\n },\n };\n}\n\nexport function getSandboxDriverFactory(\n sandboxProvider: SandkitSandboxProvider,\n): SandboxDriverFactory {\n const driverFactory = sandboxProvider[sandboxProviderContract]?.driverFactory;\n if (!driverFactory) {\n throw new Error(\n \"SandkitOptions.sandbox is invalid. Pass a provider created by Sandkit integrations such as vercelSandbox(...).\",\n );\n }\n\n return driverFactory;\n}\n\nexport interface SandkitOptions {\n readonly database?: SandkitAdapter | undefined;\n readonly setup?: SharedSetup | undefined;\n readonly network?: readonly unknown[] | undefined;\n readonly sandbox: SandkitSandboxProvider;\n}\n"],"mappings":";AA2NA,IAAM,0BAA0B,uBAAO,0BAA0B;AAW1D,SAAS,sBACd,UACA,eACwB;AACxB,SAAO;AAAA,IACL,CAAC,uBAAuB,GAAG;AAAA,MACzB;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;AAEO,SAAS,wBACd,iBACsB;AACtB,QAAM,gBAAgB,gBAAgB,uBAAuB,GAAG;AAChE,MAAI,CAAC,eAAe;AAClB,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;","names":[]}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import {
|
|
2
|
+
allowService
|
|
3
|
+
} from "./chunk-NKTNTBOY.js";
|
|
4
|
+
|
|
5
|
+
// src/policies/bun.ts
|
|
6
|
+
var BUN_DOMAINS = ["bun.sh", "bun.com"];
|
|
7
|
+
function bun() {
|
|
8
|
+
return {
|
|
9
|
+
id: "bun",
|
|
10
|
+
name: "Bun",
|
|
11
|
+
description: "Allow outbound access to Bun install and distribution endpoints.",
|
|
12
|
+
domains: BUN_DOMAINS
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
function allowBun() {
|
|
16
|
+
return allowService(bun());
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export {
|
|
20
|
+
bun,
|
|
21
|
+
allowBun
|
|
22
|
+
};
|
|
23
|
+
//# sourceMappingURL=chunk-YGUNJGP7.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/policies/bun.ts"],"sourcesContent":["import { allowService } from \"./dsl.ts\";\nimport type { PolicyServiceDescriptor, WorkspacePolicy } from \"./types.ts\";\n\nconst BUN_DOMAINS = [\"bun.sh\", \"bun.com\"] as const;\n\n/**\n * Allow outbound access to Bun distribution and install endpoints.\n */\nexport function bun(): PolicyServiceDescriptor {\n return {\n id: \"bun\",\n name: \"Bun\",\n description: \"Allow outbound access to Bun install and distribution endpoints.\",\n domains: BUN_DOMAINS,\n };\n}\n\nexport function allowBun(): WorkspacePolicy {\n return allowService(bun());\n}\n"],"mappings":";;;;;AAGA,IAAM,cAAc,CAAC,UAAU,SAAS;AAKjC,SAAS,MAA+B;AAC7C,SAAO;AAAA,IACL,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,aAAa;AAAA,IACb,SAAS;AAAA,EACX;AACF;AAEO,SAAS,WAA4B;AAC1C,SAAO,aAAa,IAAI,CAAC;AAC3B;","names":[]}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
import { S as SandkitOptions, a as SandboxDriverFactory, C as CommandResult, b as
|
|
2
|
-
import { W as WorkspacePolicy, P as PolicyServiceDescriptor } from './types-
|
|
3
|
-
export { a as PolicyServiceCredentialSource } from './types-
|
|
1
|
+
import { S as SandkitOptions, a as SandboxDriverFactory, C as CommandResult, W as WorkspaceRunCommandOptions, b as WorkspaceRunCommandDetachedOptions, c as Command, d as WorkspaceSessionRunCommandOptions, e as WorkspaceSessionProcess, f as WorkspaceSessionProcessStartInput, g as WorkspaceSandboxLease, h as WorkspaceCreateOptions } from './types-nu3vpBCZ.js';
|
|
2
|
+
import { W as WorkspacePolicy, P as PolicyServiceDescriptor } from './types-Dpr_BkF9.js';
|
|
3
|
+
export { a as PolicyServiceCredentialSource } from './types-Dpr_BkF9.js';
|
|
4
4
|
export { aiGateway } from './policies/ai-gateway.js';
|
|
5
|
+
export { allowBun, bun } from './policies/bun.js';
|
|
5
6
|
export { codex } from './policies/codex.js';
|
|
6
7
|
export { gemini } from './policies/gemini.js';
|
|
7
|
-
export {
|
|
8
|
+
export { allowNpm, npm } from './policies/npm.js';
|
|
9
|
+
export { S as SharedSetup } from './types-DNpj280o.js';
|
|
8
10
|
|
|
9
11
|
interface SandkitContext {
|
|
10
12
|
readonly adapter: NonNullable<SandkitOptions["database"]>;
|
|
@@ -14,7 +16,8 @@ interface SandkitContext {
|
|
|
14
16
|
|
|
15
17
|
interface WorkspaceSandboxHandle {
|
|
16
18
|
runCommand(command: string, args: string[]): Promise<CommandResult>;
|
|
17
|
-
runCommand(input:
|
|
19
|
+
runCommand(input: WorkspaceRunCommandOptions): Promise<CommandResult>;
|
|
20
|
+
runCommand(input: WorkspaceRunCommandDetachedOptions): Promise<Command>;
|
|
18
21
|
/**
|
|
19
22
|
* Opens a live sandbox lease. timeoutMs overrides the provider's default
|
|
20
23
|
* lease timeout for this session start; it does not change runCommand()
|
|
@@ -28,7 +31,7 @@ interface WorkspaceSandboxHandle {
|
|
|
28
31
|
}
|
|
29
32
|
interface WorkspaceSessionHandle {
|
|
30
33
|
exec(command: string, args: string[]): Promise<CommandResult>;
|
|
31
|
-
exec(input:
|
|
34
|
+
exec(input: WorkspaceSessionRunCommandOptions): Promise<CommandResult>;
|
|
32
35
|
commit(): Promise<void>;
|
|
33
36
|
/**
|
|
34
37
|
* Sets a non-durable, session-scoped policy override for subsequent session
|
|
@@ -60,6 +63,7 @@ declare class Sandkit {
|
|
|
60
63
|
#private;
|
|
61
64
|
constructor(options: SandkitOptions);
|
|
62
65
|
get context(): SandkitContext;
|
|
66
|
+
bootstrap(): Promise<void>;
|
|
63
67
|
createWorkspace(input?: WorkspaceCreateOptions): Promise<PublicWorkspaceHandle>;
|
|
64
68
|
getWorkspace(id: string): Promise<PublicWorkspaceHandle>;
|
|
65
69
|
}
|
|
@@ -71,8 +75,8 @@ declare function allowService(service: PolicyServiceDescriptor): WorkspacePolicy
|
|
|
71
75
|
declare function allowServices(services: readonly PolicyServiceDescriptor[]): WorkspacePolicy;
|
|
72
76
|
|
|
73
77
|
interface GithubOptions {
|
|
74
|
-
readonly
|
|
78
|
+
readonly token?: string;
|
|
75
79
|
}
|
|
76
80
|
declare function github(options?: GithubOptions): PolicyServiceDescriptor;
|
|
77
81
|
|
|
78
|
-
export { PolicyServiceDescriptor, type PublicWorkspaceHandle, Sandkit, SandkitOptions, WorkspaceCreateOptions, type WorkspaceDescriptor, WorkspacePolicy, type WorkspaceSandboxHandle, type WorkspaceSessionHandle, type WorkspaceStatus, allowAll, allowService, allowServices, createSandkit, denyAll, github };
|
|
82
|
+
export { Command, CommandResult, PolicyServiceDescriptor, type PublicWorkspaceHandle, Sandkit, SandkitOptions, WorkspaceCreateOptions, type WorkspaceDescriptor, WorkspacePolicy, WorkspaceRunCommandDetachedOptions, WorkspaceRunCommandOptions, type WorkspaceSandboxHandle, type WorkspaceSessionHandle, WorkspaceSessionRunCommandOptions, type WorkspaceStatus, allowAll, allowService, allowServices, createSandkit, denyAll, github };
|