@giselles-ai/sandkit 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/README.md +5 -1
  2. package/dist/adapters/drizzle.d.ts +2 -2
  3. package/dist/adapters/memory.d.ts +2 -2
  4. package/dist/adapters/sqlite-bun.d.ts +2 -2
  5. package/dist/{chunk-FSDVHEEX.js → chunk-2M2AZUOC.js} +2 -2
  6. package/dist/chunk-5MXHFOJH.js +50 -0
  7. package/dist/chunk-5MXHFOJH.js.map +1 -0
  8. package/dist/{chunk-7DLK7LOM.js → chunk-6GHZO3Y5.js} +2 -2
  9. package/dist/{chunk-VISDS5T7.js → chunk-NKTNTBOY.js} +97 -4
  10. package/dist/chunk-NKTNTBOY.js.map +1 -0
  11. package/dist/{chunk-REGOUXVI.js → chunk-UEAKE56H.js} +2 -2
  12. package/dist/index.d.ts +5 -5
  13. package/dist/index.js +5 -5
  14. package/dist/integrations/mock.d.ts +3 -3
  15. package/dist/integrations/mock.js +1 -1
  16. package/dist/integrations/vercel.d.ts +3 -3
  17. package/dist/integrations/vercel.js +19 -7
  18. package/dist/integrations/vercel.js.map +1 -1
  19. package/dist/policies/ai-gateway.d.ts +1 -1
  20. package/dist/policies/ai-gateway.js +2 -2
  21. package/dist/policies/codex.d.ts +1 -1
  22. package/dist/policies/codex.js +2 -2
  23. package/dist/policies/gemini.d.ts +1 -1
  24. package/dist/policies/gemini.js +2 -2
  25. package/dist/{types-BEKQnjeb.d.ts → types-B5N9o-ew.d.ts} +2 -2
  26. package/dist/{types-Cy36bS1j.d.ts → types-BRMAvcWc.d.ts} +1 -1
  27. package/dist/{types-BCgprbo8.d.ts → types-Dpr_BkF9.d.ts} +3 -0
  28. package/package.json +1 -1
  29. package/dist/chunk-VISDS5T7.js.map +0 -1
  30. package/dist/chunk-XM4HGRXW.js +0 -37
  31. package/dist/chunk-XM4HGRXW.js.map +0 -1
  32. /package/dist/{chunk-FSDVHEEX.js.map → chunk-2M2AZUOC.js.map} +0 -0
  33. /package/dist/{chunk-7DLK7LOM.js.map → chunk-6GHZO3Y5.js.map} +0 -0
  34. /package/dist/{chunk-REGOUXVI.js.map → chunk-UEAKE56H.js.map} +0 -0
package/README.md CHANGED
@@ -137,7 +137,10 @@ If you do not pass `database`, Sandkit defaults to the in-memory adapter. That d
137
137
 
138
138
  - `codex()` reads `CODEX_API_KEY`
139
139
  - `gemini()` reads `GEMINI_API_KEY`
140
- - `github()` reads `GITHUB_TOKEN`
140
+ - `github()` reads `GITHUB_TOKEN` and maps it through Vercel Sandbox firewall transforms:
141
+ - `Authorization: Basic <base64(x-access-token:<token>)>` on requests to `github.com`, intended for Git-over-HTTPS operations
142
+ - `Authorization: Bearer <token>` on requests to `api.github.com`
143
+ - no Authorization header for `*.githubusercontent.com`
141
144
  - `aiGateway()` reads `AI_GATEWAY_API_KEY` from host env and allows the hostname (plus wildcard) from `AI_GATEWAY_BASE_URL`.
142
145
  `AI_GATEWAY_BASE_URL` ports are ignored for allow-listing; only host/domain matches are used.
143
146
 
@@ -157,6 +160,7 @@ npx @giselles-ai/sandkit generate
157
160
 
158
161
  ## Examples
159
162
 
163
+ - `examples/workflow-hello-git`
160
164
  - `examples/sandbox-openclaw`
161
165
  - `smoke/drizzle-sample`
162
166
 
@@ -1,6 +1,6 @@
1
1
  import { SQLWrapper } from 'drizzle-orm';
2
- import { a as SandkitAdapter } from '../types-Cy36bS1j.js';
3
- import '../types-BCgprbo8.js';
2
+ import { a as SandkitAdapter } from '../types-BRMAvcWc.js';
3
+ import '../types-Dpr_BkF9.js';
4
4
 
5
5
  interface DrizzleWorkspaceTableShape {
6
6
  readonly id: SQLWrapper;
@@ -1,5 +1,5 @@
1
- import { a as SandkitAdapter } from '../types-Cy36bS1j.js';
2
- import '../types-BCgprbo8.js';
1
+ import { a as SandkitAdapter } from '../types-BRMAvcWc.js';
2
+ import '../types-Dpr_BkF9.js';
3
3
 
4
4
  declare const createMemoryAdapter: () => SandkitAdapter;
5
5
 
@@ -1,6 +1,6 @@
1
1
  import { Database } from 'bun:sqlite';
2
- import { a as SandkitAdapter } from '../types-Cy36bS1j.js';
3
- import '../types-BCgprbo8.js';
2
+ import { a as SandkitAdapter } from '../types-BRMAvcWc.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-VISDS5T7.js";
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-FSDVHEEX.js.map
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-VISDS5T7.js";
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-7DLK7LOM.js.map
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-VISDS5T7.js.map
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":[]}
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  allowService
3
- } from "./chunk-VISDS5T7.js";
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-REGOUXVI.js.map
58
+ //# sourceMappingURL=chunk-UEAKE56H.js.map
package/dist/index.d.ts CHANGED
@@ -1,10 +1,10 @@
1
- import { S as SandkitOptions, a as SandboxDriverFactory, C as CommandResult, b as SandboxRunCommandOptions, W as WorkspaceSessionProcess, c as WorkspaceSessionProcessStartInput, d as WorkspaceSandboxLease, e as WorkspaceCreateOptions } from './types-BEKQnjeb.js';
2
- import { W as WorkspacePolicy, P as PolicyServiceDescriptor } from './types-BCgprbo8.js';
3
- export { a as PolicyServiceCredentialSource } from './types-BCgprbo8.js';
1
+ import { S as SandkitOptions, a as SandboxDriverFactory, C as CommandResult, b as SandboxRunCommandOptions, W as WorkspaceSessionProcess, c as WorkspaceSessionProcessStartInput, d as WorkspaceSandboxLease, e as WorkspaceCreateOptions } from './types-B5N9o-ew.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
5
  export { codex } from './policies/codex.js';
6
6
  export { gemini } from './policies/gemini.js';
7
- export { S as SharedSetup } from './types-Cy36bS1j.js';
7
+ export { S as SharedSetup } from './types-BRMAvcWc.js';
8
8
 
9
9
  interface SandkitContext {
10
10
  readonly adapter: NonNullable<SandkitOptions["database"]>;
@@ -71,7 +71,7 @@ declare function allowService(service: PolicyServiceDescriptor): WorkspacePolicy
71
71
  declare function allowServices(services: readonly PolicyServiceDescriptor[]): WorkspacePolicy;
72
72
 
73
73
  interface GithubOptions {
74
- readonly apiKey?: string;
74
+ readonly token?: string;
75
75
  }
76
76
  declare function github(options?: GithubOptions): PolicyServiceDescriptor;
77
77
 
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  github
3
- } from "./chunk-XM4HGRXW.js";
3
+ } from "./chunk-5MXHFOJH.js";
4
4
  import "./chunk-UDFWES6J.js";
5
5
  import "./chunk-BDPTYR6V.js";
6
6
  import "./chunk-RMMOQD5Y.js";
@@ -9,13 +9,13 @@ import {
9
9
  } from "./chunk-CSOBTLWV.js";
10
10
  import {
11
11
  codex
12
- } from "./chunk-FSDVHEEX.js";
12
+ } from "./chunk-2M2AZUOC.js";
13
13
  import {
14
14
  gemini
15
- } from "./chunk-7DLK7LOM.js";
15
+ } from "./chunk-6GHZO3Y5.js";
16
16
  import {
17
17
  aiGateway
18
- } from "./chunk-REGOUXVI.js";
18
+ } from "./chunk-UEAKE56H.js";
19
19
  import {
20
20
  getSandboxDriverFactory
21
21
  } from "./chunk-HVYCAAZQ.js";
@@ -30,7 +30,7 @@ import {
30
30
  parseWorkspacePolicy,
31
31
  redactWorkspacePolicy,
32
32
  serializeWorkspacePolicy
33
- } from "./chunk-VISDS5T7.js";
33
+ } from "./chunk-NKTNTBOY.js";
34
34
 
35
35
  // src/core/context.ts
36
36
  function resolveDeprecatedNetworkOption(options) {
@@ -1,6 +1,6 @@
1
- import { a as SandboxDriverFactory, f as SandboxCreateOptions, g as SandboxDriver, P as PersistedSandboxState, h as SandkitSandboxProvider } from '../types-BEKQnjeb.js';
2
- import { W as WorkspaceRecord } from '../types-Cy36bS1j.js';
3
- import '../types-BCgprbo8.js';
1
+ import { a as SandboxDriverFactory, f as SandboxCreateOptions, g as SandboxDriver, P as PersistedSandboxState, h as SandkitSandboxProvider } from '../types-B5N9o-ew.js';
2
+ import { W as WorkspaceRecord } from '../types-BRMAvcWc.js';
3
+ import '../types-Dpr_BkF9.js';
4
4
 
5
5
  declare class MockSandboxDriverFactory implements SandboxDriverFactory {
6
6
  #private;
@@ -7,7 +7,7 @@ import {
7
7
  import {
8
8
  allowAll,
9
9
  describeWorkspacePolicy
10
- } from "../chunk-VISDS5T7.js";
10
+ } from "../chunk-NKTNTBOY.js";
11
11
 
12
12
  // src/core/mock-driver.ts
13
13
  function toSnapshotState(snapshot) {
@@ -1,6 +1,6 @@
1
- import { V as VercelSandboxOptions, h as SandkitSandboxProvider } from '../types-BEKQnjeb.js';
2
- import '../types-Cy36bS1j.js';
3
- import '../types-BCgprbo8.js';
1
+ import { V as VercelSandboxOptions, h as SandkitSandboxProvider } from '../types-B5N9o-ew.js';
2
+ import '../types-BRMAvcWc.js';
3
+ import '../types-Dpr_BkF9.js';
4
4
 
5
5
  declare function vercelSandbox(options?: VercelSandboxOptions): SandkitSandboxProvider;
6
6
 
@@ -1,19 +1,19 @@
1
1
  import {
2
2
  resolveGithubDefaultApiKey
3
- } from "../chunk-XM4HGRXW.js";
3
+ } from "../chunk-5MXHFOJH.js";
4
4
  import {
5
5
  resolveCodexDefaultApiKey
6
- } from "../chunk-FSDVHEEX.js";
6
+ } from "../chunk-2M2AZUOC.js";
7
7
  import {
8
8
  resolveGeminiDefaultApiKey
9
- } from "../chunk-7DLK7LOM.js";
9
+ } from "../chunk-6GHZO3Y5.js";
10
10
  import {
11
11
  resolveAiGatewayDefaultApiKey
12
- } from "../chunk-REGOUXVI.js";
12
+ } from "../chunk-UEAKE56H.js";
13
13
  import {
14
14
  createSandboxProvider
15
15
  } from "../chunk-HVYCAAZQ.js";
16
- import "../chunk-VISDS5T7.js";
16
+ import "../chunk-NKTNTBOY.js";
17
17
 
18
18
  // src/drivers/vercel-sandbox.ts
19
19
  import { Sandbox } from "@vercel/sandbox";
@@ -66,6 +66,12 @@ function resolveCredentialValue(serviceId, header) {
66
66
  `Workspace policy for service "${serviceId}" contains a redacted credential and cannot be applied.`
67
67
  );
68
68
  }
69
+ function encodeHeaderValue(value, encoding) {
70
+ if (encoding === "base64") {
71
+ return Buffer.from(value, "utf8").toString("base64");
72
+ }
73
+ return value;
74
+ }
69
75
  function compileHeaderRules(serviceId, headers) {
70
76
  if (!headers || headers.length === 0) {
71
77
  return [];
@@ -73,7 +79,10 @@ function compileHeaderRules(serviceId, headers) {
73
79
  const resolvedHeaders = Object.fromEntries(
74
80
  headers.map((header) => [
75
81
  header.headerName,
76
- `${header.valuePrefix ?? ""}${resolveCredentialValue(serviceId, header)}`
82
+ `${header.valuePrefix ?? ""}${encodeHeaderValue(
83
+ `${header.credentialPrefix ?? ""}${resolveCredentialValue(serviceId, header)}`,
84
+ header.valueEncoding
85
+ )}`
77
86
  ])
78
87
  );
79
88
  return [
@@ -95,8 +104,11 @@ function compileVercelNetworkPolicy(policy) {
95
104
  case "allow-services": {
96
105
  const allow = {};
97
106
  for (const service of policy.services) {
98
- const rules = compileHeaderRules(service.id, service.headers);
99
107
  for (const domain of service.domains) {
108
+ const rules = compileHeaderRules(
109
+ service.id,
110
+ service.domainHeaders?.[domain] ?? service.headers
111
+ );
100
112
  const existing = allow[domain] ?? [];
101
113
  allow[domain] = [...existing, ...rules];
102
114
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/drivers/vercel-sandbox.ts","../../src/policies/default-credentials.ts","../../src/drivers/vercel-network-policy.ts","../../src/integrations/vercel.ts"],"sourcesContent":["import { Sandbox } from \"@vercel/sandbox\";\n\nimport type { WorkspacePolicy } from \"../policies/types.ts\";\nimport type {\n CommandResult,\n PersistedSandboxState,\n SandboxSessionLease,\n SandboxDriver,\n WorkspaceSessionLog,\n WorkspaceSessionProcess,\n WorkspaceSessionProcessStartInput,\n SandboxCreateOptions,\n SandboxDriverFactory,\n WorkspaceRecord,\n VercelSandboxOptions,\n} from \"../types.ts\";\nimport { compileVercelNetworkPolicy } from \"./vercel-network-policy.ts\";\n\ninterface VercelCommandFinished {\n exitCode: number;\n stdout(): Promise<string>;\n stderr(): Promise<string>;\n}\n\ninterface VercelCommandHandle {\n wait(): Promise<VercelCommandFinished>;\n readonly cmdId?: string;\n readonly logs?: () => unknown;\n}\n\ninterface VercelPersistedState {\n snapshotId?: string;\n}\n\nclass VercelSandboxDriver implements SandboxDriver {\n readonly #sandbox: Awaited<ReturnType<typeof Sandbox.get>>;\n readonly provider = \"vercel-sandbox\";\n\n constructor(sandbox: Awaited<ReturnType<typeof Sandbox.get>>) {\n this.#sandbox = sandbox;\n }\n\n get id(): string {\n return this.#sandbox.sandboxId;\n }\n\n async applyPolicy(policy: WorkspacePolicy): Promise<void> {\n await this.#sandbox.updateNetworkPolicy(compileVercelNetworkPolicy(policy));\n }\n\n async getSessionLease(): Promise<SandboxSessionLease> {\n const sandbox = this.#sandbox;\n const observedAt = new Date().toISOString();\n const timeoutMs =\n typeof sandbox.timeout === \"number\" && Number.isFinite(sandbox.timeout) && sandbox.timeout > 0\n ? sandbox.timeout\n : 60_000;\n\n return {\n sandboxId: sandbox.sandboxId,\n observedAt,\n expiresAt: new Date(Date.parse(observedAt) + timeoutMs).toISOString(),\n };\n }\n\n async runCommand(command: string, args: string[]): Promise<CommandResult> {\n const result = await this.#sandbox.runCommand(command, args);\n const finished = await this.#toCommandFinished(result);\n\n return {\n exitCode: finished.exitCode,\n stdout: await finished.stdout(),\n stderr: await finished.stderr(),\n };\n }\n\n async startProcess(input: WorkspaceSessionProcessStartInput): Promise<WorkspaceSessionProcess> {\n const started = await this.#sandbox.runCommand({\n cmd: input.command,\n args: [...input.args],\n detached: true,\n });\n if (!isVercelCommandHandle(started)) {\n throw new Error(\"Unexpected Vercel sandbox startProcess() response shape.\");\n }\n\n const processId = started.cmdId ?? `${this.#sandbox.sandboxId}-${Date.now()}`;\n const commandLogBroadcast = createCommandLogBroadcaster(\n getCommandLogIterator(started),\n input.onStdout,\n input.onStderr,\n );\n\n return {\n processId,\n wait: async (): Promise<CommandResult> => {\n const finished = await started.wait();\n return {\n exitCode: finished.exitCode,\n stdout: await finished.stdout(),\n stderr: await finished.stderr(),\n };\n },\n logs: commandLogBroadcast ? () => commandLogBroadcast() : undefined,\n };\n }\n\n async url(port: number): Promise<string> {\n try {\n return this.#sandbox.domain(port);\n } catch (error) {\n if (!(error instanceof Error) || !error.message.includes(\"No route for port\")) {\n throw error;\n }\n\n const refreshed = await Sandbox.get({ sandboxId: this.#sandbox.sandboxId });\n return refreshed.domain(port);\n }\n }\n\n async extendTimeout(durationMs: number): Promise<void> {\n const extendTimeout = (\n this.#sandbox as { extendTimeout?: (durationMs: number) => Promise<unknown> }\n ).extendTimeout;\n if (!extendTimeout) {\n throw new Error(\"This Vercel sandbox does not support extendTimeout().\");\n }\n\n await extendTimeout.call(this.#sandbox, durationMs);\n }\n\n async snapshot(): Promise<PersistedSandboxState> {\n // Vercel sandbox snapshot() restores through a new sandbox and implicitly stops the source sandbox.\n // Keep this behavior as a provider detail in the driver implementation.\n const snapshot = await this.#sandbox.snapshot();\n\n return {\n kind: \"vercel-sandbox-snapshot\",\n sessionId: this.#sandbox.sandboxId,\n state: {\n snapshotId: snapshot.snapshotId,\n },\n };\n }\n\n async #toCommandFinished(raw: unknown): Promise<VercelCommandFinished> {\n if (typeof raw !== \"object\" || raw === null) {\n throw new Error(\"Unexpected Vercel sandbox command response\");\n }\n\n const candidate = raw as { wait?: () => Promise<VercelCommandFinished> };\n if (candidate.wait) {\n return candidate.wait();\n }\n\n return raw as VercelCommandFinished;\n }\n}\n\nfunction isVercelCommandHandle(value: unknown): value is VercelCommandHandle {\n if (typeof value !== \"object\" || value === null) {\n return false;\n }\n\n const candidate = value as { wait?: unknown; cmdId?: unknown };\n if (typeof candidate.wait !== \"function\") {\n return false;\n }\n\n return candidate.cmdId === undefined || typeof candidate.cmdId === \"string\";\n}\n\nfunction isIterable<T = unknown>(value: unknown): value is Iterable<T> {\n return (\n value !== null &&\n (typeof value === \"object\" || typeof value === \"function\") &&\n typeof (value as Iterable<T>)[Symbol.iterator] === \"function\"\n );\n}\n\nfunction isAsyncIterable<T = unknown>(value: unknown): value is AsyncIterable<T> {\n return (\n value !== null &&\n (typeof value === \"object\" || typeof value === \"function\") &&\n typeof (value as AsyncIterable<T>)[Symbol.asyncIterator] === \"function\"\n );\n}\n\nfunction getCommandLogIterator(raw: VercelCommandHandle): AsyncIterable<unknown> | undefined {\n const rawLogs = raw.logs?.();\n if (rawLogs === undefined) {\n return undefined;\n }\n if (isAsyncIterable<unknown>(rawLogs)) {\n return rawLogs;\n }\n if (isIterable<unknown>(rawLogs)) {\n return toAsyncIterableFromSync(rawLogs);\n }\n return undefined;\n}\n\nfunction toAsyncIterableFromSync<T>(iterable: Iterable<T>): AsyncIterable<T> {\n return {\n async *[Symbol.asyncIterator]() {\n for (const value of iterable) {\n yield value;\n }\n },\n };\n}\n\nfunction createCommandLogBroadcaster(\n logs: AsyncIterable<unknown> | undefined,\n onStdout?: (chunk: string) => void,\n onStderr?: (chunk: string) => void,\n): (() => AsyncIterable<WorkspaceSessionLog>) | undefined {\n if (!logs) {\n return undefined;\n }\n\n const bufferedLogs: WorkspaceSessionLog[] = [];\n const waiters: Array<() => void> = [];\n let completed = false;\n let error: unknown = null;\n let pumpStarted = false;\n\n const notifyWaiters = () => {\n while (waiters.length > 0) {\n waiters.pop()?.();\n }\n };\n\n const run = async (): Promise<void> => {\n if (pumpStarted) {\n return;\n }\n pumpStarted = true;\n\n try {\n for await (const log of logs) {\n const normalized = normalizeCommandLog(log);\n if (!normalized) {\n continue;\n }\n\n bufferedLogs.push(normalized);\n if (normalized.stream === \"stderr\") {\n onStderr?.(normalized.chunk);\n } else {\n onStdout?.(normalized.chunk);\n }\n notifyWaiters();\n }\n } catch (cause) {\n error = cause;\n } finally {\n completed = true;\n notifyWaiters();\n }\n };\n\n void run().catch(() => {});\n\n const waitForWork = (): Promise<void> => {\n return new Promise<void>((resolve) => {\n waiters.push(resolve);\n });\n };\n\n const createLogIterable = (): AsyncIterable<WorkspaceSessionLog> => {\n return {\n async *[Symbol.asyncIterator]() {\n let index = 0;\n while (true) {\n if (index < bufferedLogs.length) {\n yield bufferedLogs[index++]!;\n continue;\n }\n if (error !== null) {\n throw error instanceof Error ? error : new Error(\"startProcess logs failed.\");\n }\n if (completed) {\n return;\n }\n await waitForWork();\n }\n },\n };\n };\n\n return createLogIterable;\n}\n\nexport function normalizeCommandLog(log: unknown): WorkspaceSessionLog | null {\n if (typeof log === \"string\") {\n return { stream: \"stdout\", chunk: log };\n }\n if (typeof log !== \"object\" || log === null) {\n return null;\n }\n\n const candidate = log as {\n stream?: unknown;\n output?: unknown;\n chunk?: unknown;\n text?: unknown;\n message?: unknown;\n data?: unknown;\n };\n const streamValue = candidate.stream;\n const stream = streamValue === \"stderr\" || streamValue === \"stdout\" ? streamValue : \"stdout\";\n const rawChunk =\n candidate.data ??\n candidate.output ??\n candidate.chunk ??\n candidate.text ??\n candidate.message ??\n null;\n\n if (typeof rawChunk !== \"string\") {\n return null;\n }\n\n return { stream, chunk: rawChunk };\n}\n\nclass VercelSandboxDriverFactory implements SandboxDriverFactory {\n readonly #runtime: string;\n readonly #defaultTimeout: number;\n\n constructor(options: VercelSandboxOptions = {}) {\n this.#runtime = options.runtime ?? \"node24\";\n this.#defaultTimeout = normalizeSandboxTimeout(\n options.defaultTimeout ?? options.timeout,\n \"Vercel sandbox default timeout\",\n );\n }\n\n isSessionUnavailableError(error: unknown): boolean {\n if (!(error instanceof Error)) {\n return false;\n }\n\n const message = error.message.toLowerCase();\n return (\n message.includes(\"not found\") ||\n message.includes(\"does not exist\") ||\n message.includes(\"sandbox_stopped\") ||\n message.includes(\"sandbox stopped\")\n );\n }\n\n async createSandbox(\n _workspace: WorkspaceRecord,\n options: SandboxCreateOptions,\n ): Promise<SandboxDriver> {\n const timeout = this.#defaultTimeoutForCreate(options);\n\n const sandbox = await Sandbox.create({\n runtime: this.#runtime,\n timeout,\n ports: options.exposedPorts,\n networkPolicy: compileVercelNetworkPolicy(options.policy),\n });\n\n return new VercelSandboxDriver(sandbox);\n }\n\n async resumeSandbox(\n workspace: WorkspaceRecord,\n snapshot: PersistedSandboxState,\n options: SandboxCreateOptions,\n ): Promise<SandboxDriver> {\n const timeout = this.#defaultTimeoutForCreate(options);\n const state = snapshot.state as VercelPersistedState | undefined;\n const snapshotId = state?.snapshotId;\n const fallbackSandboxId = workspace.sandboxId ?? snapshot.sessionId;\n\n const sandbox =\n snapshotId === undefined || typeof snapshotId !== \"string\"\n ? await (fallbackSandboxId === undefined\n ? (() => {\n throw new Error(\"Persisted sandbox state is missing restore information\");\n })()\n : Sandbox.get({ sandboxId: fallbackSandboxId }))\n : await Sandbox.create({\n source: {\n type: \"snapshot\",\n snapshotId,\n },\n timeout,\n ports: options.exposedPorts,\n networkPolicy: compileVercelNetworkPolicy(options.policy),\n });\n\n // Reattaching to an existing live sandbox should not mutate provider state.\n // Updating the network policy here races with commit/snapshot shutdown and can\n // fail on otherwise read-only flows like getActiveLease().\n return new VercelSandboxDriver(sandbox);\n }\n\n #defaultTimeoutForCreate(options: SandboxCreateOptions): number {\n return normalizeSandboxTimeout(options.timeoutMs ?? this.#defaultTimeout, \"runtime timeout\");\n }\n}\n\nfunction normalizeSandboxTimeout(value: unknown, label: string): number {\n if (value === undefined) {\n return 60_000;\n }\n\n if (\n typeof value !== \"number\" ||\n !Number.isInteger(value) ||\n !Number.isFinite(value) ||\n value <= 0\n ) {\n throw new Error(`${label} must be a positive integer in milliseconds.`);\n }\n\n return value;\n}\n\nexport function createVercelSandboxDriverFactory(\n options: VercelSandboxOptions = {},\n): SandboxDriverFactory {\n return new VercelSandboxDriverFactory(options);\n}\n","import { resolveAiGatewayDefaultApiKey } from \"./ai-gateway.ts\";\nimport { resolveCodexDefaultApiKey } from \"./codex.ts\";\nimport { resolveGeminiDefaultApiKey } from \"./gemini.ts\";\nimport { resolveGithubDefaultApiKey } from \"./github.ts\";\n\nexport function resolveDefaultCredentialValue(serviceId: string): string | undefined {\n switch (serviceId) {\n case \"codex\":\n return resolveCodexDefaultApiKey();\n case \"gemini\":\n return resolveGeminiDefaultApiKey();\n case \"github\":\n return resolveGithubDefaultApiKey();\n case \"aiGateway\":\n return resolveAiGatewayDefaultApiKey();\n default:\n return undefined;\n }\n}\n\nexport function describeDefaultCredentialSource(serviceId: string): string {\n switch (serviceId) {\n case \"codex\":\n return \"CODEX_API_KEY\";\n case \"gemini\":\n return \"GEMINI_API_KEY\";\n case \"github\":\n return \"GITHUB_TOKEN\";\n case \"aiGateway\":\n return \"AI_GATEWAY_API_KEY\";\n default:\n return `default credential for service \"${serviceId}\"`;\n }\n}\n","import type {\n NetworkPolicy as VercelNetworkPolicy,\n NetworkPolicyRule as VercelNetworkPolicyRule,\n} from \"@vercel/sandbox\";\n\nimport {\n describeDefaultCredentialSource,\n resolveDefaultCredentialValue,\n} from \"../policies/default-credentials.ts\";\nimport type { PolicyServiceHeaderTransform, WorkspacePolicy } from \"../policies/types.ts\";\n\nfunction resolveCredentialValue(serviceId: string, header: PolicyServiceHeaderTransform): string {\n if (header.credential.kind === \"value\") {\n return header.credential.value;\n }\n\n if (header.credential.kind === \"default\") {\n const value = resolveDefaultCredentialValue(serviceId);\n if (!value) {\n throw new Error(\n `Workspace policy for service \"${serviceId}\" requires ${describeDefaultCredentialSource(serviceId)}.`,\n );\n }\n return value;\n }\n\n throw new Error(\n `Workspace policy for service \"${serviceId}\" contains a redacted credential and cannot be applied.`,\n );\n}\n\nfunction compileHeaderRules(\n serviceId: string,\n headers: readonly PolicyServiceHeaderTransform[] | undefined,\n): VercelNetworkPolicyRule[] {\n if (!headers || headers.length === 0) {\n return [];\n }\n\n const resolvedHeaders = Object.fromEntries(\n headers.map((header) => [\n header.headerName,\n `${header.valuePrefix ?? \"\"}${resolveCredentialValue(serviceId, header)}`,\n ]),\n );\n\n return [\n {\n transform: [\n {\n headers: resolvedHeaders,\n },\n ],\n },\n ];\n}\n\nexport function compileVercelNetworkPolicy(policy: WorkspacePolicy): VercelNetworkPolicy {\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 const allow: Record<string, VercelNetworkPolicyRule[]> = {};\n\n for (const service of policy.services) {\n const rules = compileHeaderRules(service.id, service.headers);\n for (const domain of service.domains) {\n const existing = allow[domain] ?? [];\n allow[domain] = [...existing, ...rules];\n }\n }\n\n return { allow };\n }\n }\n}\n","import { createVercelSandboxDriverFactory } from \"../drivers/vercel-sandbox.ts\";\nimport { createSandboxProvider } from \"../types.ts\";\nimport type { SandkitSandboxProvider, VercelSandboxOptions } from \"../types.ts\";\n\nexport type { SandkitSandboxProvider, VercelSandboxOptions } from \"../types.ts\";\n\nexport function vercelSandbox(options: VercelSandboxOptions = {}): SandkitSandboxProvider {\n return createSandboxProvider(\"vercel\", createVercelSandboxDriverFactory(options));\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/drivers/vercel-sandbox.ts","../../src/policies/default-credentials.ts","../../src/drivers/vercel-network-policy.ts","../../src/integrations/vercel.ts"],"sourcesContent":["import { Sandbox } from \"@vercel/sandbox\";\n\nimport type { WorkspacePolicy } from \"../policies/types.ts\";\nimport type {\n CommandResult,\n PersistedSandboxState,\n SandboxSessionLease,\n SandboxDriver,\n WorkspaceSessionLog,\n WorkspaceSessionProcess,\n WorkspaceSessionProcessStartInput,\n SandboxCreateOptions,\n SandboxDriverFactory,\n WorkspaceRecord,\n VercelSandboxOptions,\n} from \"../types.ts\";\nimport { compileVercelNetworkPolicy } from \"./vercel-network-policy.ts\";\n\ninterface VercelCommandFinished {\n exitCode: number;\n stdout(): Promise<string>;\n stderr(): Promise<string>;\n}\n\ninterface VercelCommandHandle {\n wait(): Promise<VercelCommandFinished>;\n readonly cmdId?: string;\n readonly logs?: () => unknown;\n}\n\ninterface VercelPersistedState {\n snapshotId?: string;\n}\n\nclass VercelSandboxDriver implements SandboxDriver {\n readonly #sandbox: Awaited<ReturnType<typeof Sandbox.get>>;\n readonly provider = \"vercel-sandbox\";\n\n constructor(sandbox: Awaited<ReturnType<typeof Sandbox.get>>) {\n this.#sandbox = sandbox;\n }\n\n get id(): string {\n return this.#sandbox.sandboxId;\n }\n\n async applyPolicy(policy: WorkspacePolicy): Promise<void> {\n await this.#sandbox.updateNetworkPolicy(compileVercelNetworkPolicy(policy));\n }\n\n async getSessionLease(): Promise<SandboxSessionLease> {\n const sandbox = this.#sandbox;\n const observedAt = new Date().toISOString();\n const timeoutMs =\n typeof sandbox.timeout === \"number\" && Number.isFinite(sandbox.timeout) && sandbox.timeout > 0\n ? sandbox.timeout\n : 60_000;\n\n return {\n sandboxId: sandbox.sandboxId,\n observedAt,\n expiresAt: new Date(Date.parse(observedAt) + timeoutMs).toISOString(),\n };\n }\n\n async runCommand(command: string, args: string[]): Promise<CommandResult> {\n const result = await this.#sandbox.runCommand(command, args);\n const finished = await this.#toCommandFinished(result);\n\n return {\n exitCode: finished.exitCode,\n stdout: await finished.stdout(),\n stderr: await finished.stderr(),\n };\n }\n\n async startProcess(input: WorkspaceSessionProcessStartInput): Promise<WorkspaceSessionProcess> {\n const started = await this.#sandbox.runCommand({\n cmd: input.command,\n args: [...input.args],\n detached: true,\n });\n if (!isVercelCommandHandle(started)) {\n throw new Error(\"Unexpected Vercel sandbox startProcess() response shape.\");\n }\n\n const processId = started.cmdId ?? `${this.#sandbox.sandboxId}-${Date.now()}`;\n const commandLogBroadcast = createCommandLogBroadcaster(\n getCommandLogIterator(started),\n input.onStdout,\n input.onStderr,\n );\n\n return {\n processId,\n wait: async (): Promise<CommandResult> => {\n const finished = await started.wait();\n return {\n exitCode: finished.exitCode,\n stdout: await finished.stdout(),\n stderr: await finished.stderr(),\n };\n },\n logs: commandLogBroadcast ? () => commandLogBroadcast() : undefined,\n };\n }\n\n async url(port: number): Promise<string> {\n try {\n return this.#sandbox.domain(port);\n } catch (error) {\n if (!(error instanceof Error) || !error.message.includes(\"No route for port\")) {\n throw error;\n }\n\n const refreshed = await Sandbox.get({ sandboxId: this.#sandbox.sandboxId });\n return refreshed.domain(port);\n }\n }\n\n async extendTimeout(durationMs: number): Promise<void> {\n const extendTimeout = (\n this.#sandbox as { extendTimeout?: (durationMs: number) => Promise<unknown> }\n ).extendTimeout;\n if (!extendTimeout) {\n throw new Error(\"This Vercel sandbox does not support extendTimeout().\");\n }\n\n await extendTimeout.call(this.#sandbox, durationMs);\n }\n\n async snapshot(): Promise<PersistedSandboxState> {\n // Vercel sandbox snapshot() restores through a new sandbox and implicitly stops the source sandbox.\n // Keep this behavior as a provider detail in the driver implementation.\n const snapshot = await this.#sandbox.snapshot();\n\n return {\n kind: \"vercel-sandbox-snapshot\",\n sessionId: this.#sandbox.sandboxId,\n state: {\n snapshotId: snapshot.snapshotId,\n },\n };\n }\n\n async #toCommandFinished(raw: unknown): Promise<VercelCommandFinished> {\n if (typeof raw !== \"object\" || raw === null) {\n throw new Error(\"Unexpected Vercel sandbox command response\");\n }\n\n const candidate = raw as { wait?: () => Promise<VercelCommandFinished> };\n if (candidate.wait) {\n return candidate.wait();\n }\n\n return raw as VercelCommandFinished;\n }\n}\n\nfunction isVercelCommandHandle(value: unknown): value is VercelCommandHandle {\n if (typeof value !== \"object\" || value === null) {\n return false;\n }\n\n const candidate = value as { wait?: unknown; cmdId?: unknown };\n if (typeof candidate.wait !== \"function\") {\n return false;\n }\n\n return candidate.cmdId === undefined || typeof candidate.cmdId === \"string\";\n}\n\nfunction isIterable<T = unknown>(value: unknown): value is Iterable<T> {\n return (\n value !== null &&\n (typeof value === \"object\" || typeof value === \"function\") &&\n typeof (value as Iterable<T>)[Symbol.iterator] === \"function\"\n );\n}\n\nfunction isAsyncIterable<T = unknown>(value: unknown): value is AsyncIterable<T> {\n return (\n value !== null &&\n (typeof value === \"object\" || typeof value === \"function\") &&\n typeof (value as AsyncIterable<T>)[Symbol.asyncIterator] === \"function\"\n );\n}\n\nfunction getCommandLogIterator(raw: VercelCommandHandle): AsyncIterable<unknown> | undefined {\n const rawLogs = raw.logs?.();\n if (rawLogs === undefined) {\n return undefined;\n }\n if (isAsyncIterable<unknown>(rawLogs)) {\n return rawLogs;\n }\n if (isIterable<unknown>(rawLogs)) {\n return toAsyncIterableFromSync(rawLogs);\n }\n return undefined;\n}\n\nfunction toAsyncIterableFromSync<T>(iterable: Iterable<T>): AsyncIterable<T> {\n return {\n async *[Symbol.asyncIterator]() {\n for (const value of iterable) {\n yield value;\n }\n },\n };\n}\n\nfunction createCommandLogBroadcaster(\n logs: AsyncIterable<unknown> | undefined,\n onStdout?: (chunk: string) => void,\n onStderr?: (chunk: string) => void,\n): (() => AsyncIterable<WorkspaceSessionLog>) | undefined {\n if (!logs) {\n return undefined;\n }\n\n const bufferedLogs: WorkspaceSessionLog[] = [];\n const waiters: Array<() => void> = [];\n let completed = false;\n let error: unknown = null;\n let pumpStarted = false;\n\n const notifyWaiters = () => {\n while (waiters.length > 0) {\n waiters.pop()?.();\n }\n };\n\n const run = async (): Promise<void> => {\n if (pumpStarted) {\n return;\n }\n pumpStarted = true;\n\n try {\n for await (const log of logs) {\n const normalized = normalizeCommandLog(log);\n if (!normalized) {\n continue;\n }\n\n bufferedLogs.push(normalized);\n if (normalized.stream === \"stderr\") {\n onStderr?.(normalized.chunk);\n } else {\n onStdout?.(normalized.chunk);\n }\n notifyWaiters();\n }\n } catch (cause) {\n error = cause;\n } finally {\n completed = true;\n notifyWaiters();\n }\n };\n\n void run().catch(() => {});\n\n const waitForWork = (): Promise<void> => {\n return new Promise<void>((resolve) => {\n waiters.push(resolve);\n });\n };\n\n const createLogIterable = (): AsyncIterable<WorkspaceSessionLog> => {\n return {\n async *[Symbol.asyncIterator]() {\n let index = 0;\n while (true) {\n if (index < bufferedLogs.length) {\n yield bufferedLogs[index++]!;\n continue;\n }\n if (error !== null) {\n throw error instanceof Error ? error : new Error(\"startProcess logs failed.\");\n }\n if (completed) {\n return;\n }\n await waitForWork();\n }\n },\n };\n };\n\n return createLogIterable;\n}\n\nexport function normalizeCommandLog(log: unknown): WorkspaceSessionLog | null {\n if (typeof log === \"string\") {\n return { stream: \"stdout\", chunk: log };\n }\n if (typeof log !== \"object\" || log === null) {\n return null;\n }\n\n const candidate = log as {\n stream?: unknown;\n output?: unknown;\n chunk?: unknown;\n text?: unknown;\n message?: unknown;\n data?: unknown;\n };\n const streamValue = candidate.stream;\n const stream = streamValue === \"stderr\" || streamValue === \"stdout\" ? streamValue : \"stdout\";\n const rawChunk =\n candidate.data ??\n candidate.output ??\n candidate.chunk ??\n candidate.text ??\n candidate.message ??\n null;\n\n if (typeof rawChunk !== \"string\") {\n return null;\n }\n\n return { stream, chunk: rawChunk };\n}\n\nclass VercelSandboxDriverFactory implements SandboxDriverFactory {\n readonly #runtime: string;\n readonly #defaultTimeout: number;\n\n constructor(options: VercelSandboxOptions = {}) {\n this.#runtime = options.runtime ?? \"node24\";\n this.#defaultTimeout = normalizeSandboxTimeout(\n options.defaultTimeout ?? options.timeout,\n \"Vercel sandbox default timeout\",\n );\n }\n\n isSessionUnavailableError(error: unknown): boolean {\n if (!(error instanceof Error)) {\n return false;\n }\n\n const message = error.message.toLowerCase();\n return (\n message.includes(\"not found\") ||\n message.includes(\"does not exist\") ||\n message.includes(\"sandbox_stopped\") ||\n message.includes(\"sandbox stopped\")\n );\n }\n\n async createSandbox(\n _workspace: WorkspaceRecord,\n options: SandboxCreateOptions,\n ): Promise<SandboxDriver> {\n const timeout = this.#defaultTimeoutForCreate(options);\n\n const sandbox = await Sandbox.create({\n runtime: this.#runtime,\n timeout,\n ports: options.exposedPorts,\n networkPolicy: compileVercelNetworkPolicy(options.policy),\n });\n\n return new VercelSandboxDriver(sandbox);\n }\n\n async resumeSandbox(\n workspace: WorkspaceRecord,\n snapshot: PersistedSandboxState,\n options: SandboxCreateOptions,\n ): Promise<SandboxDriver> {\n const timeout = this.#defaultTimeoutForCreate(options);\n const state = snapshot.state as VercelPersistedState | undefined;\n const snapshotId = state?.snapshotId;\n const fallbackSandboxId = workspace.sandboxId ?? snapshot.sessionId;\n\n const sandbox =\n snapshotId === undefined || typeof snapshotId !== \"string\"\n ? await (fallbackSandboxId === undefined\n ? (() => {\n throw new Error(\"Persisted sandbox state is missing restore information\");\n })()\n : Sandbox.get({ sandboxId: fallbackSandboxId }))\n : await Sandbox.create({\n source: {\n type: \"snapshot\",\n snapshotId,\n },\n timeout,\n ports: options.exposedPorts,\n networkPolicy: compileVercelNetworkPolicy(options.policy),\n });\n\n // Reattaching to an existing live sandbox should not mutate provider state.\n // Updating the network policy here races with commit/snapshot shutdown and can\n // fail on otherwise read-only flows like getActiveLease().\n return new VercelSandboxDriver(sandbox);\n }\n\n #defaultTimeoutForCreate(options: SandboxCreateOptions): number {\n return normalizeSandboxTimeout(options.timeoutMs ?? this.#defaultTimeout, \"runtime timeout\");\n }\n}\n\nfunction normalizeSandboxTimeout(value: unknown, label: string): number {\n if (value === undefined) {\n return 60_000;\n }\n\n if (\n typeof value !== \"number\" ||\n !Number.isInteger(value) ||\n !Number.isFinite(value) ||\n value <= 0\n ) {\n throw new Error(`${label} must be a positive integer in milliseconds.`);\n }\n\n return value;\n}\n\nexport function createVercelSandboxDriverFactory(\n options: VercelSandboxOptions = {},\n): SandboxDriverFactory {\n return new VercelSandboxDriverFactory(options);\n}\n","import { resolveAiGatewayDefaultApiKey } from \"./ai-gateway.ts\";\nimport { resolveCodexDefaultApiKey } from \"./codex.ts\";\nimport { resolveGeminiDefaultApiKey } from \"./gemini.ts\";\nimport { resolveGithubDefaultApiKey } from \"./github.ts\";\n\nexport function resolveDefaultCredentialValue(serviceId: string): string | undefined {\n switch (serviceId) {\n case \"codex\":\n return resolveCodexDefaultApiKey();\n case \"gemini\":\n return resolveGeminiDefaultApiKey();\n case \"github\":\n return resolveGithubDefaultApiKey();\n case \"aiGateway\":\n return resolveAiGatewayDefaultApiKey();\n default:\n return undefined;\n }\n}\n\nexport function describeDefaultCredentialSource(serviceId: string): string {\n switch (serviceId) {\n case \"codex\":\n return \"CODEX_API_KEY\";\n case \"gemini\":\n return \"GEMINI_API_KEY\";\n case \"github\":\n return \"GITHUB_TOKEN\";\n case \"aiGateway\":\n return \"AI_GATEWAY_API_KEY\";\n default:\n return `default credential for service \"${serviceId}\"`;\n }\n}\n","import type {\n NetworkPolicy as VercelNetworkPolicy,\n NetworkPolicyRule as VercelNetworkPolicyRule,\n} from \"@vercel/sandbox\";\n\nimport {\n describeDefaultCredentialSource,\n resolveDefaultCredentialValue,\n} from \"../policies/default-credentials.ts\";\nimport type { PolicyServiceHeaderTransform, WorkspacePolicy } from \"../policies/types.ts\";\n\nfunction resolveCredentialValue(serviceId: string, header: PolicyServiceHeaderTransform): string {\n if (header.credential.kind === \"value\") {\n return header.credential.value;\n }\n\n if (header.credential.kind === \"default\") {\n const value = resolveDefaultCredentialValue(serviceId);\n if (!value) {\n throw new Error(\n `Workspace policy for service \"${serviceId}\" requires ${describeDefaultCredentialSource(serviceId)}.`,\n );\n }\n return value;\n }\n\n throw new Error(\n `Workspace policy for service \"${serviceId}\" contains a redacted credential and cannot be applied.`,\n );\n}\n\nfunction encodeHeaderValue(\n value: string,\n encoding: PolicyServiceHeaderTransform[\"valueEncoding\"],\n): string {\n if (encoding === \"base64\") {\n return Buffer.from(value, \"utf8\").toString(\"base64\");\n }\n\n return value;\n}\n\nfunction compileHeaderRules(\n serviceId: string,\n headers: readonly PolicyServiceHeaderTransform[] | undefined,\n): VercelNetworkPolicyRule[] {\n if (!headers || headers.length === 0) {\n return [];\n }\n\n const resolvedHeaders = Object.fromEntries(\n headers.map((header) => [\n header.headerName,\n `${header.valuePrefix ?? \"\"}${encodeHeaderValue(\n `${header.credentialPrefix ?? \"\"}${resolveCredentialValue(serviceId, header)}`,\n header.valueEncoding,\n )}`,\n ]),\n );\n\n return [\n {\n transform: [\n {\n headers: resolvedHeaders,\n },\n ],\n },\n ];\n}\n\nexport function compileVercelNetworkPolicy(policy: WorkspacePolicy): VercelNetworkPolicy {\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 const allow: Record<string, VercelNetworkPolicyRule[]> = {};\n\n for (const service of policy.services) {\n for (const domain of service.domains) {\n const rules = compileHeaderRules(\n service.id,\n service.domainHeaders?.[domain] ?? service.headers,\n );\n const existing = allow[domain] ?? [];\n allow[domain] = [...existing, ...rules];\n }\n }\n\n return { allow };\n }\n }\n}\n","import { createVercelSandboxDriverFactory } from \"../drivers/vercel-sandbox.ts\";\nimport { createSandboxProvider } from \"../types.ts\";\nimport type { SandkitSandboxProvider, VercelSandboxOptions } from \"../types.ts\";\n\nexport type { SandkitSandboxProvider, VercelSandboxOptions } from \"../types.ts\";\n\nexport function vercelSandbox(options: VercelSandboxOptions = {}): SandkitSandboxProvider {\n return createSandboxProvider(\"vercel\", createVercelSandboxDriverFactory(options));\n}\n"],"mappings":"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","names":[]}
@@ -1,4 +1,4 @@
1
- import { P as PolicyServiceDescriptor, W as WorkspacePolicy } from '../types-BCgprbo8.js';
1
+ import { P as PolicyServiceDescriptor, W as WorkspacePolicy } from '../types-Dpr_BkF9.js';
2
2
 
3
3
  interface AiGatewayOptions {
4
4
  readonly baseUrl?: string;
@@ -2,8 +2,8 @@ import {
2
2
  aiGateway,
3
3
  allowAiGateway,
4
4
  resolveAiGatewayDefaultApiKey
5
- } from "../chunk-REGOUXVI.js";
6
- import "../chunk-VISDS5T7.js";
5
+ } from "../chunk-UEAKE56H.js";
6
+ import "../chunk-NKTNTBOY.js";
7
7
  export {
8
8
  aiGateway,
9
9
  allowAiGateway,
@@ -1,4 +1,4 @@
1
- import { P as PolicyServiceDescriptor, W as WorkspacePolicy } from '../types-BCgprbo8.js';
1
+ import { P as PolicyServiceDescriptor, W as WorkspacePolicy } from '../types-Dpr_BkF9.js';
2
2
 
3
3
  interface CodexOptions {
4
4
  readonly apiKey?: string;
@@ -2,8 +2,8 @@ import {
2
2
  allowCodex,
3
3
  codex,
4
4
  resolveCodexDefaultApiKey
5
- } from "../chunk-FSDVHEEX.js";
6
- import "../chunk-VISDS5T7.js";
5
+ } from "../chunk-2M2AZUOC.js";
6
+ import "../chunk-NKTNTBOY.js";
7
7
  export {
8
8
  allowCodex,
9
9
  codex,
@@ -1,4 +1,4 @@
1
- import { P as PolicyServiceDescriptor, W as WorkspacePolicy } from '../types-BCgprbo8.js';
1
+ import { P as PolicyServiceDescriptor, W as WorkspacePolicy } from '../types-Dpr_BkF9.js';
2
2
 
3
3
  interface GeminiOptions {
4
4
  readonly apiKey?: string;
@@ -2,8 +2,8 @@ import {
2
2
  allowGemini,
3
3
  gemini,
4
4
  resolveGeminiDefaultApiKey
5
- } from "../chunk-7DLK7LOM.js";
6
- import "../chunk-VISDS5T7.js";
5
+ } from "../chunk-6GHZO3Y5.js";
6
+ import "../chunk-NKTNTBOY.js";
7
7
  export {
8
8
  allowGemini,
9
9
  gemini,
@@ -1,5 +1,5 @@
1
- import { a as SandkitAdapter, S as SharedSetup, W as WorkspaceRecord, b as WorkspaceMetadata, c as WorkspaceStatus } from './types-Cy36bS1j.js';
2
- import { W as WorkspacePolicy } from './types-BCgprbo8.js';
1
+ import { a as SandkitAdapter, S as SharedSetup, W as WorkspaceRecord, b as WorkspaceMetadata, c as WorkspaceStatus } from './types-BRMAvcWc.js';
2
+ import { W as WorkspacePolicy } from './types-Dpr_BkF9.js';
3
3
 
4
4
  type JsonPrimitive = boolean | number | string | null;
5
5
  type JsonValue = JsonPrimitive | JsonValue[] | {
@@ -1,4 +1,4 @@
1
- import { W as WorkspacePolicy } from './types-BCgprbo8.js';
1
+ import { W as WorkspacePolicy } from './types-Dpr_BkF9.js';
2
2
 
3
3
  type WorkspaceStatus = "active" | "inactive" | "archived";
4
4
  type RunStatus = "started" | "succeeded" | "failed";
@@ -4,6 +4,7 @@ interface PolicyServiceDescriptor {
4
4
  readonly description?: string;
5
5
  readonly domains: readonly string[];
6
6
  readonly headers?: readonly PolicyServiceHeaderTransform[];
7
+ readonly domainHeaders?: Readonly<Record<string, readonly PolicyServiceHeaderTransform[]>>;
7
8
  }
8
9
  interface PolicyServiceCredentialDefault {
9
10
  readonly kind: "default";
@@ -19,6 +20,8 @@ type PolicyServiceCredentialSource = PolicyServiceCredentialDefault | PolicyServ
19
20
  interface PolicyServiceHeaderTransform {
20
21
  readonly headerName: string;
21
22
  readonly valuePrefix?: string;
23
+ readonly credentialPrefix?: string;
24
+ readonly valueEncoding?: "plain" | "base64";
22
25
  readonly credential: PolicyServiceCredentialSource;
23
26
  }
24
27
  interface WorkspaceAllowAllPolicy {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@giselles-ai/sandkit",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Workspace state, session management, and durable command execution for Vercel Sandbox.",
5
5
  "keywords": [
6
6
  "agent",
@@ -1 +0,0 @@
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 if (!headerName) {\n throw new Error(\"Policy header transform must include a header name.\");\n }\n\n return {\n headerName,\n valuePrefix: header.valuePrefix,\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 return {\n id,\n name,\n description: service.description?.trim() || undefined,\n domains,\n headers: service.headers?.map((header) => normalizeHeaderTransform(header)),\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 credential: header.credential.kind === \"value\" ? { kind: \"redacted\" } : header.credential,\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 }\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 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 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 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 });\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":[]}
@@ -1,37 +0,0 @@
1
- // src/policies/github.ts
2
- var GITHUB_DOMAINS = ["github.com", "*.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.apiKey !== "string" || options.apiKey.trim().length === 0) {
8
- throw new Error(
9
- 'github(...) explicit override requires a non-empty "apiKey". Omit the options object to use GITHUB_TOKEN.'
10
- );
11
- }
12
- return { kind: "value", value: options.apiKey };
13
- }
14
- function resolveGithubDefaultApiKey() {
15
- return process.env.GITHUB_TOKEN;
16
- }
17
- function github(options) {
18
- return {
19
- id: "github",
20
- name: "GitHub",
21
- description: "Allow outbound access commonly needed for GitHub APIs and assets.",
22
- domains: GITHUB_DOMAINS,
23
- headers: [
24
- {
25
- headerName: "authorization",
26
- valuePrefix: "Bearer ",
27
- credential: resolveGithubCredential(options)
28
- }
29
- ]
30
- };
31
- }
32
-
33
- export {
34
- resolveGithubDefaultApiKey,
35
- github
36
- };
37
- //# sourceMappingURL=chunk-XM4HGRXW.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/policies/github.ts"],"sourcesContent":["import type { PolicyServiceDescriptor } from \"./types.ts\";\n\nconst GITHUB_DOMAINS = [\"github.com\", \"*.github.com\", \"api.github.com\", \"*.githubusercontent.com\"];\n\nexport interface GithubOptions {\n readonly apiKey?: string;\n}\n\nfunction resolveGithubCredential(options?: GithubOptions) {\n if (options === undefined) {\n return { kind: \"default\" } as const;\n }\n\n if (typeof options.apiKey !== \"string\" || options.apiKey.trim().length === 0) {\n throw new Error(\n 'github(...) explicit override requires a non-empty \"apiKey\". Omit the options object to use GITHUB_TOKEN.',\n );\n }\n\n return { kind: \"value\", value: options.apiKey } as const;\n}\n\nexport function resolveGithubDefaultApiKey(): string | undefined {\n return process.env.GITHUB_TOKEN;\n}\n\nexport function github(options?: GithubOptions): PolicyServiceDescriptor {\n return {\n id: \"github\",\n name: \"GitHub\",\n description: \"Allow outbound access commonly needed for GitHub APIs and assets.\",\n domains: GITHUB_DOMAINS,\n headers: [\n {\n headerName: \"authorization\",\n valuePrefix: \"Bearer \",\n credential: resolveGithubCredential(options),\n },\n ],\n };\n}\n"],"mappings":";AAEA,IAAM,iBAAiB,CAAC,cAAc,gBAAgB,kBAAkB,yBAAyB;AAMjG,SAAS,wBAAwB,SAAyB;AACxD,MAAI,YAAY,QAAW;AACzB,WAAO,EAAE,MAAM,UAAU;AAAA,EAC3B;AAEA,MAAI,OAAO,QAAQ,WAAW,YAAY,QAAQ,OAAO,KAAK,EAAE,WAAW,GAAG;AAC5E,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,SAAO,EAAE,MAAM,SAAS,OAAO,QAAQ,OAAO;AAChD;AAEO,SAAS,6BAAiD;AAC/D,SAAO,QAAQ,IAAI;AACrB;AAEO,SAAS,OAAO,SAAkD;AACvE,SAAO;AAAA,IACL,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,aAAa;AAAA,IACb,SAAS;AAAA,IACT,SAAS;AAAA,MACP;AAAA,QACE,YAAY;AAAA,QACZ,aAAa;AAAA,QACb,YAAY,wBAAwB,OAAO;AAAA,MAC7C;AAAA,IACF;AAAA,EACF;AACF;","names":[]}