@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
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
import {
|
|
2
2
|
resolveGithubDefaultApiKey
|
|
3
|
-
} from "../chunk-
|
|
3
|
+
} from "../chunk-5MXHFOJH.js";
|
|
4
|
+
import {
|
|
5
|
+
createSandboxProvider
|
|
6
|
+
} from "../chunk-XN6DGLRP.js";
|
|
4
7
|
import {
|
|
5
8
|
resolveCodexDefaultApiKey
|
|
6
|
-
} from "../chunk-
|
|
9
|
+
} from "../chunk-2M2AZUOC.js";
|
|
7
10
|
import {
|
|
8
11
|
resolveGeminiDefaultApiKey
|
|
9
|
-
} from "../chunk-
|
|
12
|
+
} from "../chunk-6GHZO3Y5.js";
|
|
10
13
|
import {
|
|
11
14
|
resolveAiGatewayDefaultApiKey
|
|
12
|
-
} from "../chunk-
|
|
13
|
-
import
|
|
14
|
-
createSandboxProvider
|
|
15
|
-
} from "../chunk-HVYCAAZQ.js";
|
|
16
|
-
import "../chunk-VISDS5T7.js";
|
|
15
|
+
} from "../chunk-UEAKE56H.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 ?? ""}${
|
|
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
|
}
|
|
@@ -129,13 +141,24 @@ var VercelSandboxDriver = class {
|
|
|
129
141
|
expiresAt: new Date(Date.parse(observedAt) + timeoutMs).toISOString()
|
|
130
142
|
};
|
|
131
143
|
}
|
|
132
|
-
async runCommand(command, args) {
|
|
133
|
-
const
|
|
134
|
-
|
|
144
|
+
async runCommand(command, args, options) {
|
|
145
|
+
const rawResult = options?.detached ? await this.#sandbox.runCommand({
|
|
146
|
+
cmd: command,
|
|
147
|
+
args,
|
|
148
|
+
detached: true
|
|
149
|
+
}) : await this.#sandbox.runCommand(command, args);
|
|
150
|
+
const logIterator = options?.detached ? getCommandLogIterator(rawResult) : void 0;
|
|
151
|
+
const commandLogs = logIterator ? () => createEphemeralCommandLogStream(logIterator) : void 0;
|
|
135
152
|
return {
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
153
|
+
wait: async () => {
|
|
154
|
+
const finished = await this.#toCommandFinished(rawResult);
|
|
155
|
+
return {
|
|
156
|
+
exitCode: finished.exitCode,
|
|
157
|
+
stdout: await finished.stdout(),
|
|
158
|
+
stderr: await finished.stderr()
|
|
159
|
+
};
|
|
160
|
+
},
|
|
161
|
+
logs: commandLogs
|
|
139
162
|
};
|
|
140
163
|
}
|
|
141
164
|
async startProcess(input) {
|
|
@@ -156,7 +179,7 @@ var VercelSandboxDriver = class {
|
|
|
156
179
|
return {
|
|
157
180
|
processId,
|
|
158
181
|
wait: async () => {
|
|
159
|
-
const finished = await started
|
|
182
|
+
const finished = await this.#toCommandFinished(started);
|
|
160
183
|
return {
|
|
161
184
|
exitCode: finished.exitCode,
|
|
162
185
|
stdout: await finished.stdout(),
|
|
@@ -205,6 +228,25 @@ var VercelSandboxDriver = class {
|
|
|
205
228
|
return raw;
|
|
206
229
|
}
|
|
207
230
|
};
|
|
231
|
+
function createEphemeralCommandLogStream(logs) {
|
|
232
|
+
return {
|
|
233
|
+
async *[Symbol.asyncIterator]() {
|
|
234
|
+
try {
|
|
235
|
+
for await (const log of logs) {
|
|
236
|
+
const normalized = normalizeCommandLog(log);
|
|
237
|
+
if (normalized) {
|
|
238
|
+
yield normalized;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
} catch (cause) {
|
|
242
|
+
if (cause instanceof Error) {
|
|
243
|
+
throw cause;
|
|
244
|
+
}
|
|
245
|
+
throw new Error("Command logs failed.");
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
};
|
|
249
|
+
}
|
|
208
250
|
function isVercelCommandHandle(value) {
|
|
209
251
|
if (typeof value !== "object" || value === null) {
|
|
210
252
|
return false;
|
|
@@ -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 Command,\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(\n command: string,\n args: string[],\n options?: { readonly detached?: boolean },\n ): Promise<Command> {\n const rawResult = options?.detached\n ? await this.#sandbox.runCommand({\n cmd: command,\n args,\n detached: true,\n })\n : await this.#sandbox.runCommand(command, args);\n\n const logIterator = options?.detached ? getCommandLogIterator(rawResult) : undefined;\n const commandLogs = logIterator\n ? () => createEphemeralCommandLogStream(logIterator)\n : undefined;\n\n return {\n wait: async () => {\n const finished = await this.#toCommandFinished(rawResult);\n return {\n exitCode: finished.exitCode,\n stdout: await finished.stdout(),\n stderr: await finished.stderr(),\n };\n },\n logs: commandLogs,\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 this.#toCommandFinished(started);\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 createEphemeralCommandLogStream(\n logs: AsyncIterable<unknown>,\n): AsyncIterable<WorkspaceSessionLog> {\n return {\n async *[Symbol.asyncIterator]() {\n try {\n for await (const log of logs) {\n const normalized = normalizeCommandLog(log);\n if (normalized) {\n yield normalized;\n }\n }\n } catch (cause) {\n if (cause instanceof Error) {\n throw cause;\n }\n throw new Error(\"Command logs failed.\");\n }\n },\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":[]}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { W as WorkspacePolicy, P as PolicyServiceDescriptor } from '../types-Dpr_BkF9.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Allow outbound access to Bun distribution and install endpoints.
|
|
5
|
+
*/
|
|
6
|
+
declare function bun(): PolicyServiceDescriptor;
|
|
7
|
+
declare function allowBun(): WorkspacePolicy;
|
|
8
|
+
|
|
9
|
+
export { allowBun, bun };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
package/dist/policies/codex.d.ts
CHANGED
package/dist/policies/codex.js
CHANGED
package/dist/policies/gemini.js
CHANGED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { W as WorkspacePolicy, P as PolicyServiceDescriptor } from '../types-Dpr_BkF9.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Allow outbound access to the public npm package registry.
|
|
5
|
+
*
|
|
6
|
+
* Keep this preset scoped to the actual package source host instead of
|
|
7
|
+
* broadening to unrelated npm web properties.
|
|
8
|
+
*/
|
|
9
|
+
declare function npm(): PolicyServiceDescriptor;
|
|
10
|
+
declare function allowNpm(): WorkspacePolicy;
|
|
11
|
+
|
|
12
|
+
export { allowNpm, npm };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { W as WorkspacePolicy } from './types-
|
|
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";
|
|
@@ -15,7 +15,7 @@ interface SharedSetup {
|
|
|
15
15
|
* Shared setup state is durable and reused across workspaces, so this policy
|
|
16
16
|
* must also be durable. Explicit secret-bearing policies are rejected.
|
|
17
17
|
*/
|
|
18
|
-
readonly policy
|
|
18
|
+
readonly policy: WorkspacePolicy;
|
|
19
19
|
}
|
|
20
20
|
/**
|
|
21
21
|
* Internal durable artifact produced by a successful shared bootstrap.
|
|
@@ -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 {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { a as SandkitAdapter, S as SharedSetup, W as WorkspaceRecord, b as WorkspaceMetadata, c as WorkspaceStatus } from './types-
|
|
2
|
-
import { W as WorkspacePolicy } from './types-
|
|
1
|
+
import { a as SandkitAdapter, S as SharedSetup, W as WorkspaceRecord, b as WorkspaceMetadata, c as WorkspaceStatus } from './types-DNpj280o.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[] | {
|
|
@@ -28,6 +28,18 @@ interface CommandResult {
|
|
|
28
28
|
stderr: string;
|
|
29
29
|
stdout: string;
|
|
30
30
|
}
|
|
31
|
+
interface Command {
|
|
32
|
+
/**
|
|
33
|
+
* Wait for durable completion of the command unit-of-work: process exit,
|
|
34
|
+
* snapshot/commit, and persist outcome.
|
|
35
|
+
*/
|
|
36
|
+
readonly wait: () => Promise<CommandResult>;
|
|
37
|
+
/**
|
|
38
|
+
* Ephemeral log stream for detached execution. The stream is live-only and does
|
|
39
|
+
* not participate in durable state replay.
|
|
40
|
+
*/
|
|
41
|
+
readonly logs?: () => AsyncIterable<WorkspaceSessionLog>;
|
|
42
|
+
}
|
|
31
43
|
interface SandboxSessionLease {
|
|
32
44
|
readonly sandboxId: string;
|
|
33
45
|
readonly observedAt: string;
|
|
@@ -69,10 +81,26 @@ interface WorkspaceSessionProcessStartInput {
|
|
|
69
81
|
*/
|
|
70
82
|
readonly onStderr?: ((chunk: string) => void) | undefined;
|
|
71
83
|
}
|
|
72
|
-
interface
|
|
84
|
+
interface WorkspaceSessionRunCommandOptions {
|
|
85
|
+
readonly command: string;
|
|
86
|
+
readonly args?: readonly string[];
|
|
87
|
+
readonly policy?: WorkspacePolicy;
|
|
88
|
+
}
|
|
89
|
+
interface WorkspaceRunCommandBaseOptions {
|
|
73
90
|
readonly command: string;
|
|
74
91
|
readonly args?: readonly string[];
|
|
75
92
|
readonly policy?: WorkspacePolicy;
|
|
93
|
+
/**
|
|
94
|
+
* Ephemeral timeout override for this durable runCommand() invocation.
|
|
95
|
+
* This affects sandbox create/restore lease timing for the run only and
|
|
96
|
+
* must not mutate durable workspace defaults.
|
|
97
|
+
*/
|
|
98
|
+
readonly timeoutMs?: number;
|
|
99
|
+
}
|
|
100
|
+
interface WorkspaceRunCommandOptions extends WorkspaceRunCommandBaseOptions {
|
|
101
|
+
}
|
|
102
|
+
interface WorkspaceRunCommandDetachedOptions extends WorkspaceRunCommandBaseOptions {
|
|
103
|
+
readonly detached: true;
|
|
76
104
|
}
|
|
77
105
|
interface PersistedSandboxState {
|
|
78
106
|
readonly kind: string;
|
|
@@ -90,7 +118,9 @@ interface SandboxDriver {
|
|
|
90
118
|
* so callers should not treat mere reads as lease refreshes.
|
|
91
119
|
*/
|
|
92
120
|
getSessionLease(): Promise<SandboxSessionLease>;
|
|
93
|
-
runCommand(command: string, args: string[]
|
|
121
|
+
runCommand(command: string, args: string[], options?: {
|
|
122
|
+
readonly detached?: boolean;
|
|
123
|
+
}): Promise<Command>;
|
|
94
124
|
startProcess?(input: WorkspaceSessionProcessStartInput): Promise<WorkspaceSessionProcess>;
|
|
95
125
|
/** Persists and restores durability state through commit() and attach/restore APIs. */
|
|
96
126
|
snapshot(): Promise<PersistedSandboxState>;
|
|
@@ -136,4 +166,4 @@ interface SandkitOptions {
|
|
|
136
166
|
readonly sandbox: SandkitSandboxProvider;
|
|
137
167
|
}
|
|
138
168
|
|
|
139
|
-
export type { CommandResult as C, PersistedSandboxState as P, SandkitOptions as S, VercelSandboxOptions as V,
|
|
169
|
+
export type { CommandResult as C, PersistedSandboxState as P, SandkitOptions as S, VercelSandboxOptions as V, WorkspaceRunCommandOptions as W, SandboxDriverFactory as a, WorkspaceRunCommandDetachedOptions as b, Command as c, WorkspaceSessionRunCommandOptions as d, WorkspaceSessionProcess as e, WorkspaceSessionProcessStartInput as f, WorkspaceSandboxLease as g, WorkspaceCreateOptions as h, SandboxCreateOptions as i, SandboxDriver as j, SandkitSandboxProvider as k };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@giselles-ai/sandkit",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "Workspace state, session management, and durable command execution for Vercel Sandbox.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"agent",
|
|
@@ -65,6 +65,11 @@
|
|
|
65
65
|
"import": "./dist/policies/ai-gateway.js",
|
|
66
66
|
"default": "./dist/policies/ai-gateway.js"
|
|
67
67
|
},
|
|
68
|
+
"./policies/bun": {
|
|
69
|
+
"types": "./dist/policies/bun.d.ts",
|
|
70
|
+
"import": "./dist/policies/bun.js",
|
|
71
|
+
"default": "./dist/policies/bun.js"
|
|
72
|
+
},
|
|
68
73
|
"./policies/codex": {
|
|
69
74
|
"types": "./dist/policies/codex.d.ts",
|
|
70
75
|
"import": "./dist/policies/codex.js",
|
|
@@ -75,6 +80,11 @@
|
|
|
75
80
|
"import": "./dist/policies/gemini.js",
|
|
76
81
|
"default": "./dist/policies/gemini.js"
|
|
77
82
|
},
|
|
83
|
+
"./policies/npm": {
|
|
84
|
+
"types": "./dist/policies/npm.d.ts",
|
|
85
|
+
"import": "./dist/policies/npm.js",
|
|
86
|
+
"default": "./dist/policies/npm.js"
|
|
87
|
+
},
|
|
78
88
|
"./schema": {
|
|
79
89
|
"types": "./dist/schema/index.d.ts",
|
|
80
90
|
"import": "./dist/schema/index.js",
|
|
@@ -1 +0,0 @@
|
|
|
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 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 SandboxRunCommandOptions {\n readonly command: string;\n readonly args?: readonly string[];\n readonly policy?: WorkspacePolicy;\n}\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(command: string, args: string[]): Promise<CommandResult>;\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":";AAoLA,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":[]}
|
|
@@ -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":[]}
|
package/dist/chunk-XM4HGRXW.js
DELETED
|
@@ -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":[]}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|