@yolk-sdk/sandbox 0.1.0-canary.76 → 0.1.0-canary.78
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 +2 -2
- package/dist/agent.d.mts.map +1 -1
- package/dist/agent.mjs +50 -55
- package/dist/agent.mjs.map +1 -1
- package/dist/errors.d.mts +1 -2
- package/dist/errors.d.mts.map +1 -1
- package/dist/errors.mjs +7 -8
- package/dist/errors.mjs.map +1 -1
- package/dist/lifecycle.d.mts +6 -5
- package/dist/lifecycle.d.mts.map +1 -1
- package/dist/lifecycle.mjs +46 -54
- package/dist/lifecycle.mjs.map +1 -1
- package/dist/model.d.mts.map +1 -1
- package/dist/model.mjs.map +1 -1
- package/dist/name.d.mts.map +1 -1
- package/dist/name.mjs.map +1 -1
- package/dist/testing/index.mjs.map +1 -1
- package/dist/vercel/client.d.mts +6 -2
- package/dist/vercel/client.d.mts.map +1 -1
- package/dist/vercel/client.mjs +64 -58
- package/dist/vercel/client.mjs.map +1 -1
- package/dist/vercel/layer.d.mts.map +1 -1
- package/dist/vercel/layer.mjs +20 -20
- package/dist/vercel/layer.mjs.map +1 -1
- package/package.json +3 -3
- package/src/agent.ts +93 -66
- package/src/errors.ts +7 -9
- package/src/index.ts +8 -0
- package/src/lifecycle.ts +60 -34
- package/src/model.ts +7 -0
- package/src/name.ts +1 -0
- package/src/testing/index.ts +1 -0
- package/src/vercel/client.ts +115 -51
- package/src/vercel/index.ts +3 -0
- package/src/vercel/layer.ts +107 -37
package/README.md
CHANGED
|
@@ -5,11 +5,11 @@ Effect-native sandbox execution contracts, an agent tool, testing fakes, and a V
|
|
|
5
5
|
## Install
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
|
-
pnpm add @yolk-sdk/sandbox@canary @yolk-sdk/agent@canary effect@4.0.0-
|
|
8
|
+
pnpm add @yolk-sdk/sandbox@canary @yolk-sdk/agent@canary effect@4.0.0-rc.115
|
|
9
9
|
```
|
|
10
10
|
|
|
11
11
|
Canary APIs are unstable. Keep all `@yolk-sdk/*` packages on the same version.
|
|
12
|
-
Use the SDK's matching Effect version (`4.0.0-
|
|
12
|
+
Use the SDK's matching Effect version (`4.0.0-rc.115`) in host code.
|
|
13
13
|
Published package metadata requires Node.js 22+; `@yolk-sdk/sandbox/vercel` is server-only.
|
|
14
14
|
|
|
15
15
|
## Subpaths
|
package/dist/agent.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent.d.mts","names":[],"sources":["../src/agent.ts"],"mappings":";;;;;;;;cAuBa,eAAA;AAAA,cAEP,iBAAA,EAAiB,MAAA,CAAA,MAAA;EAAA;;;;;;
|
|
1
|
+
{"version":3,"file":"agent.d.mts","names":[],"sources":["../src/agent.ts"],"mappings":";;;;;;;;cAuBa,eAAA;AAAA,cAEP,iBAAA,EAAiB,MAAA,CAAA,MAAA;EAAA;;;;;;KA4CX,iBAAA,UAA2B,iBAAA,CAAkB,IAAI;AAAA,KAEjD,wBAAA;EAAA,SACD,YAAA,GAAe,aAAA;EAAA,SACf,oBAAA;EAAA,SACA,oBAAA;EAAA,SACA,YAAA,GAAe,aAAA;EAAA,SACf,SAAA,IAAa,OAAA,EAAS,OAAA,KAAY,MAAA,CAAO,MAAA,UAAgB,iBAAA;AAAA;AAAA,KAG/D,sBAAA;EAAA,SACM,IAAA;EAAA,SACA,GAAG;AAAA;AAAA,KAGT,iBAAA;EAAA,SACM,IAAA;EAAA,SACA,IAAA;EAAA,SACA,WAAA;EAAA,SACA,YAAA;EAAA,SACA,WAAA;EAAA,SACA,cAAA;AAAA;AAAA,KAGC,4BAAA;EAAA,SACD,QAAA;EAAA,SACA,UAAA;EAAA,SACA,QAAA;EAAA,SACA,SAAA;EAAA,SACA,cAAA;EAAA,SACA,YAAA;EAAA,SACA,WAAA,EAAa,aAAA,CAAc,sBAAA;EAAA,SAC3B,KAAA,EAAO,iBAAA;AAAA;AAAA,cAoLL,qBAAA,GAAyB,KAAA;EAAA,SAC3B,MAAA;EAAA,SACA,MAAA,EAAQ,oBAAA;AAAA,MAClB,UAUA;AAAA,cA4BY,4BAAA,YACX,OAAA,EAAS,UAAA,EACT,OAAA,GAAS,wBAAA,CAAyB,OAAA,MACjC,UAAA,CAAW,OAAA;AAAA,cA0CD,qBAAA,YACX,OAAA,GAAS,wBAAA,CAAyB,OAAA,MACjC,MAAA,CAAO,MAAA,CAAO,UAAA,CAAW,OAAA,UAAiB,OAAA;AAAA,KAOjC,yBAAA;EAAA,SACD,IAAA,EAAM,QAAA;EAAA,SACN,OAAA,EAAS,OAAA;EAAA,SACT,MAAA,EAAQ,iBAAA;AAAA"}
|
package/dist/agent.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { maxSandboxCommandTimeoutMs, normalizeWorkspaceCwd, sandboxCommandTimeoutMs, sandboxToolOutputLimit, validateSandboxCommand } from "./lifecycle.mjs";
|
|
2
2
|
import { Sandbox } from "./service.mjs";
|
|
3
|
-
import { Effect } from "effect";
|
|
3
|
+
import { Effect, Match } from "effect";
|
|
4
4
|
import * as Schema from "effect/Schema";
|
|
5
5
|
import { ToolError } from "@yolk-sdk/agent/loop";
|
|
6
6
|
import { ToolResult } from "@yolk-sdk/agent/protocol";
|
|
@@ -20,29 +20,25 @@ const toolError = (message, cause) => new ToolError({
|
|
|
20
20
|
message,
|
|
21
21
|
cause
|
|
22
22
|
});
|
|
23
|
-
const modelVisibleSandboxError = (error) => {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
case "SandboxStateError":
|
|
43
|
-
case "SandboxStateStoreError": return toolError(error.message, "unavailable");
|
|
44
|
-
}
|
|
45
|
-
};
|
|
23
|
+
const modelVisibleSandboxError = (error) => Match.value(error).pipe(Match.tagsExhaustive({
|
|
24
|
+
SandboxInputError: (inputError) => modelVisibleToolError({
|
|
25
|
+
tool: sandboxToolName,
|
|
26
|
+
message: inputError.message,
|
|
27
|
+
reason: "invalid_input"
|
|
28
|
+
}),
|
|
29
|
+
SandboxExpiredError: (expiredError) => modelVisibleToolError({
|
|
30
|
+
tool: sandboxToolName,
|
|
31
|
+
message: expiredError.message,
|
|
32
|
+
reason: "unavailable",
|
|
33
|
+
details: { expiredAtMs: expiredError.expiredAtMs }
|
|
34
|
+
})
|
|
35
|
+
}));
|
|
36
|
+
const sandboxInfraToolError = (error) => Match.value(error).pipe(Match.tagsExhaustive({
|
|
37
|
+
SandboxConfigError: (configError) => toolError(configError.message, "invalid_input"),
|
|
38
|
+
SandboxProviderError: (providerError) => toolError(providerError.message, "execution"),
|
|
39
|
+
SandboxStateError: (stateError) => toolError(stateError.message, "unavailable"),
|
|
40
|
+
SandboxStateStoreError: (storeError) => toolError(storeError.message, "unavailable")
|
|
41
|
+
}));
|
|
46
42
|
const normalizeTimeoutMs = (timeoutSeconds) => {
|
|
47
43
|
const value = nullToUndefined(timeoutSeconds);
|
|
48
44
|
if (value === void 0) return Effect.succeed(sandboxCommandTimeoutMs(void 0));
|
|
@@ -100,28 +96,29 @@ const plainSandboxPreviewUrl = (previewUrl) => ({
|
|
|
100
96
|
port: previewUrl.port,
|
|
101
97
|
url: previewUrl.url
|
|
102
98
|
});
|
|
103
|
-
const plainSandboxState = (state) => {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
99
|
+
const plainSandboxState = (state) => Match.value(state._tag).pipe(Match.when("Vercel", () => ({
|
|
100
|
+
_tag: state._tag,
|
|
101
|
+
name: state.name,
|
|
102
|
+
createdAtMs: state.createdAtMs,
|
|
103
|
+
lastUsedAtMs: state.lastUsedAtMs,
|
|
104
|
+
expiresAtMs: state.expiresAtMs,
|
|
105
|
+
maxExpiresAtMs: state.maxExpiresAtMs
|
|
106
|
+
})), Match.exhaustive);
|
|
107
|
+
const structuredContent = (result, truncated) => {
|
|
108
|
+
const content = {
|
|
109
|
+
exitCode: result.exitCode,
|
|
110
|
+
durationMs: result.durationMs,
|
|
111
|
+
timedOut: result.timedOut,
|
|
112
|
+
truncated,
|
|
113
|
+
workspaceReset: result.workspaceReset
|
|
114
|
+
};
|
|
115
|
+
if (result.backgroundId !== void 0) content.backgroundId = result.backgroundId;
|
|
116
|
+
return {
|
|
117
|
+
...content,
|
|
118
|
+
previewUrls: result.previewUrls.map(plainSandboxPreviewUrl),
|
|
119
|
+
state: plainSandboxState(result.state)
|
|
120
|
+
};
|
|
114
121
|
};
|
|
115
|
-
const structuredContent = (result, truncated) => ({
|
|
116
|
-
exitCode: result.exitCode,
|
|
117
|
-
durationMs: result.durationMs,
|
|
118
|
-
timedOut: result.timedOut,
|
|
119
|
-
truncated,
|
|
120
|
-
workspaceReset: result.workspaceReset,
|
|
121
|
-
...result.backgroundId === void 0 ? {} : { backgroundId: result.backgroundId },
|
|
122
|
-
previewUrls: result.previewUrls.map(plainSandboxPreviewUrl),
|
|
123
|
-
state: plainSandboxState(result.state)
|
|
124
|
-
});
|
|
125
122
|
const makeSandboxToolResult = (input) => {
|
|
126
123
|
const output = truncateOutputs(input.result.stdout, input.result.stderr, sandboxToolOutputLimit);
|
|
127
124
|
return ToolResult.make({
|
|
@@ -163,16 +160,14 @@ const makeSandboxToolModuleFromApi = (sandbox, options = {}) => ({
|
|
|
163
160
|
execute: ({ call, params }) => Effect.gen(function* () {
|
|
164
161
|
if (call.name !== "sandbox") return yield* Effect.fail(toolError(`Tool is not configured: ${call.name}`, "not_found"));
|
|
165
162
|
const normalized = yield* normalizeToolParams(params);
|
|
166
|
-
const result = yield* sandbox.run(normalized).pipe(Effect.mapError((error) => {
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
}
|
|
175
|
-
}));
|
|
163
|
+
const result = yield* sandbox.run(normalized).pipe(Effect.mapError((error) => Match.value(error).pipe(Match.tagsExhaustive({
|
|
164
|
+
SandboxInputError: (inputError) => modelVisibleSandboxError(inputError),
|
|
165
|
+
SandboxExpiredError: (expiredError) => modelVisibleSandboxError(expiredError),
|
|
166
|
+
SandboxConfigError: (configError) => sandboxInfraToolError(configError),
|
|
167
|
+
SandboxProviderError: (providerError) => sandboxInfraToolError(providerError),
|
|
168
|
+
SandboxStateError: (stateError) => sandboxInfraToolError(stateError),
|
|
169
|
+
SandboxStateStoreError: (storeError) => sandboxInfraToolError(storeError)
|
|
170
|
+
}))));
|
|
176
171
|
return makeSandboxToolResult({
|
|
177
172
|
callId: call.id,
|
|
178
173
|
result
|
package/dist/agent.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent.mjs","names":[],"sources":["../src/agent.ts"],"sourcesContent":["import { Effect } from 'effect'\nimport * as Schema from 'effect/Schema'\nimport { ToolError } from '@yolk-sdk/agent/loop'\nimport { ToolResult, type ToolCall } from '@yolk-sdk/agent/protocol'\nimport {\n makeTool,\n modelVisibleToolError,\n type ModelVisibleToolError,\n type ToolModule,\n type ToolRegistryError\n} from '@yolk-sdk/agent/tools'\nimport {\n maxSandboxCommandTimeoutMs,\n normalizeWorkspaceCwd,\n sandboxCommandTimeoutMs,\n sandboxToolOutputLimit,\n validateSandboxCommand\n} from './lifecycle.ts'\nimport type { SandboxError, SandboxExpiredError, SandboxInputError } from './errors.ts'\nimport type { SandboxApi } from './service.ts'\nimport { Sandbox } from './service.ts'\nimport type { SandboxCommandResult } from './model.ts'\n\nexport const sandboxToolName = 'sandbox'\n\nconst SandboxToolParams = Schema.Struct({\n command: Schema.String.pipe(\n Schema.annotate({ description: 'Shell command to run. Multiline commands are allowed.' })\n ),\n cwd: Schema.optional(\n Schema.NullOr(\n Schema.String.pipe(\n Schema.annotate({\n description: 'Workspace-relative working directory. Absolute paths are rejected.'\n })\n )\n )\n ),\n stdin: Schema.optional(\n Schema.NullOr(\n Schema.String.pipe(\n Schema.annotate({ description: 'Optional stdin text passed to the command.' })\n )\n )\n ),\n timeoutSeconds: Schema.optional(\n Schema.NullOr(\n Schema.Number.pipe(\n Schema.annotate({ description: 'Foreground timeout in seconds. Default 120, max 600.' })\n )\n )\n ),\n background: Schema.optional(\n Schema.NullOr(\n Schema.Boolean.pipe(\n Schema.annotate({\n description: 'Start command in background and return after a quick probe.'\n })\n )\n )\n )\n})\n\nexport type SandboxToolParams = typeof SandboxToolParams.Type\n\nexport type SandboxToolModuleOptions<Context> = {\n readonly capabilities?: ReadonlyArray<string>\n readonly workspaceDescription?: string\n readonly lifecycleDescription?: string\n readonly previewPorts?: ReadonlyArray<number>\n readonly isEnabled?: (context: Context) => Effect.Effect<boolean, ToolRegistryError>\n}\n\ntype PlainSandboxPreviewUrl = {\n readonly port: number\n readonly url: string\n}\n\ntype PlainSandboxState = {\n readonly _tag: 'Vercel'\n readonly name: string\n readonly createdAtMs: number\n readonly lastUsedAtMs: number\n readonly expiresAtMs: number\n readonly maxExpiresAtMs: number\n}\n\nexport type SandboxToolStructuredContent = {\n readonly exitCode: number | null\n readonly durationMs: number\n readonly timedOut: boolean\n readonly truncated: boolean\n readonly workspaceReset: boolean\n readonly backgroundId?: string\n readonly previewUrls: ReadonlyArray<PlainSandboxPreviewUrl>\n readonly state: PlainSandboxState\n}\n\ntype OutputSlice = {\n readonly stdout: string\n readonly stderr: string\n readonly truncated: boolean\n}\n\nconst nullToUndefined = <A>(value: A | null | undefined) => (value === null ? undefined : value)\n\nconst toolError = (message: string, cause: ToolError['cause']) =>\n new ToolError({\n tool: sandboxToolName,\n message,\n cause\n })\n\nconst modelVisibleSandboxError = (\n error: SandboxInputError | SandboxExpiredError\n): ModelVisibleToolError => {\n switch (error._tag) {\n case 'SandboxInputError':\n return modelVisibleToolError({\n tool: sandboxToolName,\n message: error.message,\n reason: 'invalid_input'\n })\n case 'SandboxExpiredError':\n return modelVisibleToolError({\n tool: sandboxToolName,\n message: error.message,\n reason: 'unavailable',\n details: { expiredAtMs: error.expiredAtMs }\n })\n }\n}\n\nconst sandboxInfraToolError = (\n error: Exclude<SandboxError, SandboxInputError | SandboxExpiredError>\n) => {\n switch (error._tag) {\n case 'SandboxConfigError':\n return toolError(error.message, 'invalid_input')\n case 'SandboxProviderError':\n return toolError(error.message, 'execution')\n case 'SandboxStateError':\n case 'SandboxStateStoreError':\n return toolError(error.message, 'unavailable')\n }\n}\n\nconst normalizeTimeoutMs = (timeoutSeconds: number | null | undefined) => {\n const value = nullToUndefined(timeoutSeconds)\n\n if (value === undefined) {\n return Effect.succeed(sandboxCommandTimeoutMs(undefined))\n }\n\n if (!Number.isFinite(value) || value <= 0) {\n return Effect.fail(\n modelVisibleToolError({\n tool: sandboxToolName,\n message: 'timeoutSeconds must be greater than 0',\n reason: 'invalid_input'\n })\n )\n }\n\n return Effect.succeed(sandboxCommandTimeoutMs(Math.floor(value * 1_000)))\n}\n\nconst normalizeToolParams = (params: SandboxToolParams) =>\n Effect.gen(function* () {\n const command = yield* validateSandboxCommand(params.command).pipe(\n Effect.mapError(modelVisibleSandboxError)\n )\n const cwd = yield* normalizeWorkspaceCwd(params.cwd).pipe(\n Effect.mapError(modelVisibleSandboxError)\n )\n const timeoutMs = yield* normalizeTimeoutMs(params.timeoutSeconds)\n\n return {\n command,\n cwd,\n stdin: nullToUndefined(params.stdin),\n timeoutMs,\n background: nullToUndefined(params.background)\n }\n })\n\nconst truncateOutputs = (stdout: string, stderr: string, limit: number): OutputSlice => {\n if (stdout.length + stderr.length <= limit) {\n return { stdout, stderr, truncated: false }\n }\n\n const initialStderrBudget = Math.min(stderr.length, Math.floor(limit / 2))\n const initialStdoutBudget = Math.min(stdout.length, limit - initialStderrBudget)\n const unused = limit - initialStdoutBudget - initialStderrBudget\n const stdoutBudget = Math.min(stdout.length, initialStdoutBudget + unused)\n const stderrBudget = Math.min(stderr.length, limit - stdoutBudget)\n\n return {\n stdout: stdout.slice(0, stdoutBudget),\n stderr: stderr.slice(0, stderrBudget),\n truncated: true\n }\n}\n\nconst formatSandboxToolContent = (result: SandboxCommandResult, output: OutputSlice) =>\n [\n `exit_code: ${result.exitCode === null ? 'null' : String(result.exitCode)}`,\n `duration_ms: ${result.durationMs}`,\n `truncated: ${output.truncated}`,\n `timed_out: ${result.timedOut}`,\n `workspace_reset: ${result.workspaceReset}`,\n result.backgroundId === undefined ? undefined : `background_id: ${result.backgroundId}`,\n '<stdout>',\n output.stdout,\n '</stdout>',\n '<stderr>',\n output.stderr,\n '</stderr>'\n ]\n .filter(line => line !== undefined)\n .join('\\n')\n\nconst plainSandboxPreviewUrl = (\n previewUrl: SandboxCommandResult['previewUrls'][number]\n): PlainSandboxPreviewUrl => ({\n port: previewUrl.port,\n url: previewUrl.url\n})\n\nconst plainSandboxState = (state: SandboxCommandResult['state']): PlainSandboxState => {\n switch (state._tag) {\n case 'Vercel':\n return {\n _tag: state._tag,\n name: state.name,\n createdAtMs: state.createdAtMs,\n lastUsedAtMs: state.lastUsedAtMs,\n expiresAtMs: state.expiresAtMs,\n maxExpiresAtMs: state.maxExpiresAtMs\n }\n }\n}\n\nconst structuredContent = (\n result: SandboxCommandResult,\n truncated: boolean\n): SandboxToolStructuredContent => ({\n exitCode: result.exitCode,\n durationMs: result.durationMs,\n timedOut: result.timedOut,\n truncated,\n workspaceReset: result.workspaceReset,\n ...(result.backgroundId === undefined ? {} : { backgroundId: result.backgroundId }),\n previewUrls: result.previewUrls.map(plainSandboxPreviewUrl),\n state: plainSandboxState(result.state)\n})\n\nexport const makeSandboxToolResult = (input: {\n readonly callId: string\n readonly result: SandboxCommandResult\n}) => {\n const output = truncateOutputs(input.result.stdout, input.result.stderr, sandboxToolOutputLimit)\n\n return ToolResult.make({\n toolCallId: input.callId,\n content: formatSandboxToolContent(input.result, output),\n isError:\n input.result.timedOut || (input.result.exitCode !== null && input.result.exitCode !== 0),\n structuredContent: structuredContent(input.result, output.truncated)\n })\n}\n\nconst sandboxToolDescription = <Context>(options: SandboxToolModuleOptions<Context>) => {\n const capabilities = options.capabilities ?? [\n 'run project commands such as typechecks, lint, tests, and builds',\n 'edit files with shell tools such as apply_patch when available',\n 'start dev servers and use preview ports',\n 'run browser checks through agent-browser when available'\n ]\n const ports = options.previewPorts ?? []\n\n return [\n 'Run one non-interactive bash command inside a real sandbox workspace.',\n options.workspaceDescription ?? 'The working directory is the sandbox workspace root.',\n options.lifecycleDescription ??\n 'The sandbox is disposable and may reset after idle or max lifetime expiry.',\n `Foreground timeout defaults to 120s and is capped at ${Math.floor(maxSandboxCommandTimeoutMs / 1_000)}s.`,\n 'Use workspace-relative cwd only; absolute paths and workspace escapes are rejected.',\n 'Use stdin for large patches, scripts, or data.',\n 'Set background=true for long-running servers; the tool returns after a quick probe.',\n ports.length === 0\n ? 'Preview URLs are returned when configured by the host.'\n : `Preview ports: ${ports.join(', ')}.`,\n `Available capabilities:\\n${capabilities.map(capability => `- ${capability}`).join('\\n')}`\n ].join('\\n\\n')\n}\n\nexport const makeSandboxToolModuleFromApi = <Context>(\n sandbox: SandboxApi,\n options: SandboxToolModuleOptions<Context> = {}\n): ToolModule<Context> => ({\n id: 'sandbox',\n tools: [\n makeTool({\n name: sandboxToolName,\n description: sandboxToolDescription(options),\n parameters: SandboxToolParams,\n access: 'destructive',\n isEnabled: options.isEnabled,\n invalidParamsMessage: error =>\n `Invalid sandbox arguments: ${error instanceof Error ? error.message : String(error)}`,\n execute: ({ call, params }) =>\n Effect.gen(function* () {\n if (call.name !== sandboxToolName) {\n return yield* Effect.fail(\n toolError(`Tool is not configured: ${call.name}`, 'not_found')\n )\n }\n\n const normalized = yield* normalizeToolParams(params)\n const result = yield* sandbox.run(normalized).pipe(\n Effect.mapError(error => {\n switch (error._tag) {\n case 'SandboxInputError':\n case 'SandboxExpiredError':\n return modelVisibleSandboxError(error)\n case 'SandboxConfigError':\n case 'SandboxProviderError':\n case 'SandboxStateError':\n case 'SandboxStateStoreError':\n return sandboxInfraToolError(error)\n }\n })\n )\n\n return makeSandboxToolResult({ callId: call.id, result })\n })\n })\n ]\n})\n\nexport const makeSandboxToolModule = <Context>(\n options: SandboxToolModuleOptions<Context> = {}\n): Effect.Effect<ToolModule<Context>, never, Sandbox> =>\n Effect.gen(function* () {\n const sandbox = yield* Sandbox\n return makeSandboxToolModuleFromApi(sandbox, options)\n })\n\nexport type SandboxToolExecutionInput<Context> = {\n readonly call: ToolCall\n readonly context: Context\n readonly params: SandboxToolParams\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"agent.mjs","names":[],"sources":["../src/agent.ts"],"sourcesContent":["import { Effect, Match } from 'effect'\nimport * as Schema from 'effect/Schema'\nimport { ToolError } from '@yolk-sdk/agent/loop'\nimport { ToolResult, type ToolCall } from '@yolk-sdk/agent/protocol'\nimport {\n makeTool,\n modelVisibleToolError,\n type ModelVisibleToolError,\n type ToolModule,\n type ToolRegistryError\n} from '@yolk-sdk/agent/tools'\nimport {\n maxSandboxCommandTimeoutMs,\n normalizeWorkspaceCwd,\n sandboxCommandTimeoutMs,\n sandboxToolOutputLimit,\n validateSandboxCommand\n} from './lifecycle.ts'\nimport type { SandboxError, SandboxExpiredError, SandboxInputError } from './errors.ts'\nimport type { SandboxApi } from './service.ts'\nimport { Sandbox } from './service.ts'\nimport type { SandboxCommandResult } from './model.ts'\n\nexport const sandboxToolName = 'sandbox'\n\nconst SandboxToolParams = Schema.Struct({\n command: Schema.String.pipe(\n Schema.annotate({\n description: 'Shell command to run. Multiline commands are allowed.'\n })\n ),\n cwd: Schema.optional(\n Schema.NullOr(\n Schema.String.pipe(\n Schema.annotate({\n description: 'Workspace-relative working directory. Absolute paths are rejected.'\n })\n )\n )\n ),\n stdin: Schema.optional(\n Schema.NullOr(\n Schema.String.pipe(\n Schema.annotate({\n description: 'Optional stdin text passed to the command.'\n })\n )\n )\n ),\n timeoutSeconds: Schema.optional(\n Schema.NullOr(\n Schema.Number.pipe(\n Schema.annotate({\n description: 'Foreground timeout in seconds. Default 120, max 600.'\n })\n )\n )\n ),\n background: Schema.optional(\n Schema.NullOr(\n Schema.Boolean.pipe(\n Schema.annotate({\n description: 'Start command in background and return after a quick probe.'\n })\n )\n )\n )\n})\n\nexport type SandboxToolParams = typeof SandboxToolParams.Type\n\nexport type SandboxToolModuleOptions<Context> = {\n readonly capabilities?: ReadonlyArray<string>\n readonly workspaceDescription?: string\n readonly lifecycleDescription?: string\n readonly previewPorts?: ReadonlyArray<number>\n readonly isEnabled?: (context: Context) => Effect.Effect<boolean, ToolRegistryError>\n}\n\ntype PlainSandboxPreviewUrl = {\n readonly port: number\n readonly url: string\n}\n\ntype PlainSandboxState = {\n readonly _tag: 'Vercel'\n readonly name: string\n readonly createdAtMs: number\n readonly lastUsedAtMs: number\n readonly expiresAtMs: number\n readonly maxExpiresAtMs: number\n}\n\nexport type SandboxToolStructuredContent = {\n readonly exitCode: number | null\n readonly durationMs: number\n readonly timedOut: boolean\n readonly truncated: boolean\n readonly workspaceReset: boolean\n readonly backgroundId?: string\n readonly previewUrls: ReadonlyArray<PlainSandboxPreviewUrl>\n readonly state: PlainSandboxState\n}\n\ntype OutputSlice = {\n readonly stdout: string\n readonly stderr: string\n readonly truncated: boolean\n}\n\nconst nullToUndefined = <A>(value: A | null | undefined) => (value === null ? undefined : value)\n\nconst toolError = (message: string, cause: ToolError['cause']) =>\n new ToolError({\n tool: sandboxToolName,\n message,\n cause\n })\n\nconst modelVisibleSandboxError = (\n error: SandboxInputError | SandboxExpiredError\n): ModelVisibleToolError =>\n Match.value(error).pipe(\n Match.tagsExhaustive({\n SandboxInputError: inputError =>\n modelVisibleToolError({\n tool: sandboxToolName,\n message: inputError.message,\n reason: 'invalid_input'\n }),\n SandboxExpiredError: expiredError =>\n modelVisibleToolError({\n tool: sandboxToolName,\n message: expiredError.message,\n reason: 'unavailable',\n details: { expiredAtMs: expiredError.expiredAtMs }\n })\n })\n )\n\nconst sandboxInfraToolError = (\n error: Exclude<SandboxError, SandboxInputError | SandboxExpiredError>\n) =>\n Match.value(error).pipe(\n Match.tagsExhaustive({\n SandboxConfigError: configError => toolError(configError.message, 'invalid_input'),\n SandboxProviderError: providerError => toolError(providerError.message, 'execution'),\n SandboxStateError: stateError => toolError(stateError.message, 'unavailable'),\n SandboxStateStoreError: storeError => toolError(storeError.message, 'unavailable')\n })\n )\n\nconst normalizeTimeoutMs = (timeoutSeconds: number | null | undefined) => {\n const value = nullToUndefined(timeoutSeconds)\n\n if (value === undefined) {\n return Effect.succeed(sandboxCommandTimeoutMs(undefined))\n }\n\n if (!Number.isFinite(value) || value <= 0) {\n return Effect.fail(\n modelVisibleToolError({\n tool: sandboxToolName,\n message: 'timeoutSeconds must be greater than 0',\n reason: 'invalid_input'\n })\n )\n }\n\n return Effect.succeed(sandboxCommandTimeoutMs(Math.floor(value * 1_000)))\n}\n\nconst normalizeToolParams = (params: SandboxToolParams) =>\n Effect.gen(function* () {\n const command = yield* validateSandboxCommand(params.command).pipe(\n Effect.mapError(modelVisibleSandboxError)\n )\n\n const cwd = yield* normalizeWorkspaceCwd(params.cwd).pipe(\n Effect.mapError(modelVisibleSandboxError)\n )\n\n const timeoutMs = yield* normalizeTimeoutMs(params.timeoutSeconds)\n\n return {\n command,\n cwd,\n stdin: nullToUndefined(params.stdin),\n timeoutMs,\n background: nullToUndefined(params.background)\n }\n })\n\nconst truncateOutputs = (stdout: string, stderr: string, limit: number): OutputSlice => {\n if (stdout.length + stderr.length <= limit) {\n return { stdout, stderr, truncated: false }\n }\n\n const initialStderrBudget = Math.min(stderr.length, Math.floor(limit / 2))\n const initialStdoutBudget = Math.min(stdout.length, limit - initialStderrBudget)\n const unused = limit - initialStdoutBudget - initialStderrBudget\n const stdoutBudget = Math.min(stdout.length, initialStdoutBudget + unused)\n const stderrBudget = Math.min(stderr.length, limit - stdoutBudget)\n\n return {\n stdout: stdout.slice(0, stdoutBudget),\n stderr: stderr.slice(0, stderrBudget),\n truncated: true\n }\n}\n\nconst formatSandboxToolContent = (result: SandboxCommandResult, output: OutputSlice) =>\n [\n `exit_code: ${result.exitCode === null ? 'null' : String(result.exitCode)}`,\n `duration_ms: ${result.durationMs}`,\n `truncated: ${output.truncated}`,\n `timed_out: ${result.timedOut}`,\n `workspace_reset: ${result.workspaceReset}`,\n result.backgroundId === undefined ? undefined : `background_id: ${result.backgroundId}`,\n '<stdout>',\n output.stdout,\n '</stdout>',\n '<stderr>',\n output.stderr,\n '</stderr>'\n ]\n .filter(line => line !== undefined)\n .join('\\n')\n\nconst plainSandboxPreviewUrl = (\n previewUrl: SandboxCommandResult['previewUrls'][number]\n): PlainSandboxPreviewUrl => ({\n port: previewUrl.port,\n url: previewUrl.url\n})\n\nconst plainSandboxState = (state: SandboxCommandResult['state']): PlainSandboxState =>\n Match.value(state._tag).pipe(\n Match.when('Vercel', () => ({\n _tag: state._tag,\n name: state.name,\n createdAtMs: state.createdAtMs,\n lastUsedAtMs: state.lastUsedAtMs,\n expiresAtMs: state.expiresAtMs,\n maxExpiresAtMs: state.maxExpiresAtMs\n })),\n Match.exhaustive\n )\n\ntype SandboxToolStructuredContentFields = {\n readonly exitCode: number | null\n readonly durationMs: number\n readonly timedOut: boolean\n readonly truncated: boolean\n readonly workspaceReset: boolean\n backgroundId?: string\n}\n\nconst structuredContent = (\n result: SandboxCommandResult,\n truncated: boolean\n): SandboxToolStructuredContent => {\n const content: SandboxToolStructuredContentFields = {\n exitCode: result.exitCode,\n durationMs: result.durationMs,\n timedOut: result.timedOut,\n truncated,\n workspaceReset: result.workspaceReset\n }\n\n if (result.backgroundId !== undefined) {\n content.backgroundId = result.backgroundId\n }\n\n return {\n ...content,\n previewUrls: result.previewUrls.map(plainSandboxPreviewUrl),\n state: plainSandboxState(result.state)\n }\n}\n\nexport const makeSandboxToolResult = (input: {\n readonly callId: string\n readonly result: SandboxCommandResult\n}) => {\n const output = truncateOutputs(input.result.stdout, input.result.stderr, sandboxToolOutputLimit)\n\n return ToolResult.make({\n toolCallId: input.callId,\n content: formatSandboxToolContent(input.result, output),\n isError:\n input.result.timedOut || (input.result.exitCode !== null && input.result.exitCode !== 0),\n structuredContent: structuredContent(input.result, output.truncated)\n })\n}\n\nconst sandboxToolDescription = <Context>(options: SandboxToolModuleOptions<Context>) => {\n const capabilities = options.capabilities ?? [\n 'run project commands such as typechecks, lint, tests, and builds',\n 'edit files with shell tools such as apply_patch when available',\n 'start dev servers and use preview ports',\n 'run browser checks through agent-browser when available'\n ]\n\n const ports = options.previewPorts ?? []\n\n return [\n 'Run one non-interactive bash command inside a real sandbox workspace.',\n options.workspaceDescription ?? 'The working directory is the sandbox workspace root.',\n options.lifecycleDescription ??\n 'The sandbox is disposable and may reset after idle or max lifetime expiry.',\n `Foreground timeout defaults to 120s and is capped at ${Math.floor(maxSandboxCommandTimeoutMs / 1_000)}s.`,\n 'Use workspace-relative cwd only; absolute paths and workspace escapes are rejected.',\n 'Use stdin for large patches, scripts, or data.',\n 'Set background=true for long-running servers; the tool returns after a quick probe.',\n ports.length === 0\n ? 'Preview URLs are returned when configured by the host.'\n : `Preview ports: ${ports.join(', ')}.`,\n `Available capabilities:\\n${capabilities.map(capability => `- ${capability}`).join('\\n')}`\n ].join('\\n\\n')\n}\n\nexport const makeSandboxToolModuleFromApi = <Context>(\n sandbox: SandboxApi,\n options: SandboxToolModuleOptions<Context> = {}\n): ToolModule<Context> => ({\n id: 'sandbox',\n tools: [\n makeTool({\n name: sandboxToolName,\n description: sandboxToolDescription(options),\n parameters: SandboxToolParams,\n access: 'destructive',\n isEnabled: options.isEnabled,\n invalidParamsMessage: error =>\n `Invalid sandbox arguments: ${error instanceof Error ? error.message : String(error)}`,\n execute: ({ call, params }) =>\n Effect.gen(function* () {\n if (call.name !== sandboxToolName) {\n return yield* Effect.fail(\n toolError(`Tool is not configured: ${call.name}`, 'not_found')\n )\n }\n\n const normalized = yield* normalizeToolParams(params)\n\n const result = yield* sandbox.run(normalized).pipe(\n Effect.mapError(error =>\n Match.value(error).pipe(\n Match.tagsExhaustive({\n SandboxInputError: inputError => modelVisibleSandboxError(inputError),\n SandboxExpiredError: expiredError => modelVisibleSandboxError(expiredError),\n SandboxConfigError: configError => sandboxInfraToolError(configError),\n SandboxProviderError: providerError => sandboxInfraToolError(providerError),\n SandboxStateError: stateError => sandboxInfraToolError(stateError),\n SandboxStateStoreError: storeError => sandboxInfraToolError(storeError)\n })\n )\n )\n )\n\n return makeSandboxToolResult({ callId: call.id, result })\n })\n })\n ]\n})\n\nexport const makeSandboxToolModule = <Context>(\n options: SandboxToolModuleOptions<Context> = {}\n): Effect.Effect<ToolModule<Context>, never, Sandbox> =>\n Effect.gen(function* () {\n const sandbox = yield* Sandbox\n\n return makeSandboxToolModuleFromApi(sandbox, options)\n })\n\nexport type SandboxToolExecutionInput<Context> = {\n readonly call: ToolCall\n readonly context: Context\n readonly params: SandboxToolParams\n}\n"],"mappings":";;;;;;;;AAuBA,MAAa,kBAAkB;AAE/B,MAAM,oBAAoB,OAAO,OAAO;CACtC,SAAS,OAAO,OAAO,KACrB,OAAO,SAAS,EACd,aAAa,wDACf,CAAC,CACH;CACA,KAAK,OAAO,SACV,OAAO,OACL,OAAO,OAAO,KACZ,OAAO,SAAS,EACd,aAAa,qEACf,CAAC,CACH,CACF,CACF;CACA,OAAO,OAAO,SACZ,OAAO,OACL,OAAO,OAAO,KACZ,OAAO,SAAS,EACd,aAAa,6CACf,CAAC,CACH,CACF,CACF;CACA,gBAAgB,OAAO,SACrB,OAAO,OACL,OAAO,OAAO,KACZ,OAAO,SAAS,EACd,aAAa,uDACf,CAAC,CACH,CACF,CACF;CACA,YAAY,OAAO,SACjB,OAAO,OACL,OAAO,QAAQ,KACb,OAAO,SAAS,EACd,aAAa,8DACf,CAAC,CACH,CACF,CACF;AACF,CAAC;AA2CD,MAAM,mBAAsB,UAAiC,UAAU,OAAO,KAAA,IAAY;AAE1F,MAAM,aAAa,SAAiB,UAClC,IAAI,UAAU;CACZ,MAAM;CACN;CACA;AACF,CAAC;AAEH,MAAM,4BACJ,UAEA,MAAM,MAAM,KAAK,EAAE,KACjB,MAAM,eAAe;CACnB,oBAAmB,eACjB,sBAAsB;EACpB,MAAM;EACN,SAAS,WAAW;EACpB,QAAQ;CACV,CAAC;CACH,sBAAqB,iBACnB,sBAAsB;EACpB,MAAM;EACN,SAAS,aAAa;EACtB,QAAQ;EACR,SAAS,EAAE,aAAa,aAAa,YAAY;CACnD,CAAC;AACL,CAAC,CACH;AAEF,MAAM,yBACJ,UAEA,MAAM,MAAM,KAAK,EAAE,KACjB,MAAM,eAAe;CACnB,qBAAoB,gBAAe,UAAU,YAAY,SAAS,eAAe;CACjF,uBAAsB,kBAAiB,UAAU,cAAc,SAAS,WAAW;CACnF,oBAAmB,eAAc,UAAU,WAAW,SAAS,aAAa;CAC5E,yBAAwB,eAAc,UAAU,WAAW,SAAS,aAAa;AACnF,CAAC,CACH;AAEF,MAAM,sBAAsB,mBAA8C;CACxE,MAAM,QAAQ,gBAAgB,cAAc;CAE5C,IAAI,UAAU,KAAA,GACZ,OAAO,OAAO,QAAQ,wBAAwB,KAAA,CAAS,CAAC;CAG1D,IAAI,CAAC,OAAO,SAAS,KAAK,KAAK,SAAS,GACtC,OAAO,OAAO,KACZ,sBAAsB;EACpB,MAAM;EACN,SAAS;EACT,QAAQ;CACV,CAAC,CACH;CAGF,OAAO,OAAO,QAAQ,wBAAwB,KAAK,MAAM,QAAQ,GAAK,CAAC,CAAC;AAC1E;AAEA,MAAM,uBAAuB,WAC3B,OAAO,IAAI,aAAa;CACtB,MAAM,UAAU,OAAO,uBAAuB,OAAO,OAAO,EAAE,KAC5D,OAAO,SAAS,wBAAwB,CAC1C;CAEA,MAAM,MAAM,OAAO,sBAAsB,OAAO,GAAG,EAAE,KACnD,OAAO,SAAS,wBAAwB,CAC1C;CAEA,MAAM,YAAY,OAAO,mBAAmB,OAAO,cAAc;CAEjE,OAAO;EACL;EACA;EACA,OAAO,gBAAgB,OAAO,KAAK;EACnC;EACA,YAAY,gBAAgB,OAAO,UAAU;CAC/C;AACF,CAAC;AAEH,MAAM,mBAAmB,QAAgB,QAAgB,UAA+B;CACtF,IAAI,OAAO,SAAS,OAAO,UAAU,OACnC,OAAO;EAAE;EAAQ;EAAQ,WAAW;CAAM;CAG5C,MAAM,sBAAsB,KAAK,IAAI,OAAO,QAAQ,KAAK,MAAM,QAAQ,CAAC,CAAC;CACzE,MAAM,sBAAsB,KAAK,IAAI,OAAO,QAAQ,QAAQ,mBAAmB;CAC/E,MAAM,SAAS,QAAQ,sBAAsB;CAC7C,MAAM,eAAe,KAAK,IAAI,OAAO,QAAQ,sBAAsB,MAAM;CACzE,MAAM,eAAe,KAAK,IAAI,OAAO,QAAQ,QAAQ,YAAY;CAEjE,OAAO;EACL,QAAQ,OAAO,MAAM,GAAG,YAAY;EACpC,QAAQ,OAAO,MAAM,GAAG,YAAY;EACpC,WAAW;CACb;AACF;AAEA,MAAM,4BAA4B,QAA8B,WAC9D;CACE,cAAc,OAAO,aAAa,OAAO,SAAS,OAAO,OAAO,QAAQ;CACxE,gBAAgB,OAAO;CACvB,cAAc,OAAO;CACrB,cAAc,OAAO;CACrB,oBAAoB,OAAO;CAC3B,OAAO,iBAAiB,KAAA,IAAY,KAAA,IAAY,kBAAkB,OAAO;CACzE;CACA,OAAO;CACP;CACA;CACA,OAAO;CACP;AACF,EACG,QAAO,SAAQ,SAAS,KAAA,CAAS,EACjC,KAAK,IAAI;AAEd,MAAM,0BACJ,gBAC4B;CAC5B,MAAM,WAAW;CACjB,KAAK,WAAW;AAClB;AAEA,MAAM,qBAAqB,UACzB,MAAM,MAAM,MAAM,IAAI,EAAE,KACtB,MAAM,KAAK,iBAAiB;CAC1B,MAAM,MAAM;CACZ,MAAM,MAAM;CACZ,aAAa,MAAM;CACnB,cAAc,MAAM;CACpB,aAAa,MAAM;CACnB,gBAAgB,MAAM;AACxB,EAAE,GACF,MAAM,UACR;AAWF,MAAM,qBACJ,QACA,cACiC;CACjC,MAAM,UAA8C;EAClD,UAAU,OAAO;EACjB,YAAY,OAAO;EACnB,UAAU,OAAO;EACjB;EACA,gBAAgB,OAAO;CACzB;CAEA,IAAI,OAAO,iBAAiB,KAAA,GAC1B,QAAQ,eAAe,OAAO;CAGhC,OAAO;EACL,GAAG;EACH,aAAa,OAAO,YAAY,IAAI,sBAAsB;EAC1D,OAAO,kBAAkB,OAAO,KAAK;CACvC;AACF;AAEA,MAAa,yBAAyB,UAGhC;CACJ,MAAM,SAAS,gBAAgB,MAAM,OAAO,QAAQ,MAAM,OAAO,QAAQ,sBAAsB;CAE/F,OAAO,WAAW,KAAK;EACrB,YAAY,MAAM;EAClB,SAAS,yBAAyB,MAAM,QAAQ,MAAM;EACtD,SACE,MAAM,OAAO,YAAa,MAAM,OAAO,aAAa,QAAQ,MAAM,OAAO,aAAa;EACxF,mBAAmB,kBAAkB,MAAM,QAAQ,OAAO,SAAS;CACrE,CAAC;AACH;AAEA,MAAM,0BAAmC,YAA+C;CACtF,MAAM,eAAe,QAAQ,gBAAgB;EAC3C;EACA;EACA;EACA;CACF;CAEA,MAAM,QAAQ,QAAQ,gBAAgB,CAAC;CAEvC,OAAO;EACL;EACA,QAAQ,wBAAwB;EAChC,QAAQ,wBACN;EACF,wDAAwD,KAAK,MAAM,6BAA6B,GAAK,EAAE;EACvG;EACA;EACA;EACA,MAAM,WAAW,IACb,2DACA,kBAAkB,MAAM,KAAK,IAAI,EAAE;EACvC,4BAA4B,aAAa,KAAI,eAAc,KAAK,YAAY,EAAE,KAAK,IAAI;CACzF,EAAE,KAAK,MAAM;AACf;AAEA,MAAa,gCACX,SACA,UAA6C,CAAC,OACrB;CACzB,IAAI;CACJ,OAAO,CACL,SAAS;EACP,MAAM;EACN,aAAa,uBAAuB,OAAO;EAC3C,YAAY;EACZ,QAAQ;EACR,WAAW,QAAQ;EACnB,uBAAsB,UACpB,8BAA8B,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;EACrF,UAAU,EAAE,MAAM,aAChB,OAAO,IAAI,aAAa;GACtB,IAAI,KAAK,SAAA,WACP,OAAO,OAAO,OAAO,KACnB,UAAU,2BAA2B,KAAK,QAAQ,WAAW,CAC/D;GAGF,MAAM,aAAa,OAAO,oBAAoB,MAAM;GAEpD,MAAM,SAAS,OAAO,QAAQ,IAAI,UAAU,EAAE,KAC5C,OAAO,UAAS,UACd,MAAM,MAAM,KAAK,EAAE,KACjB,MAAM,eAAe;IACnB,oBAAmB,eAAc,yBAAyB,UAAU;IACpE,sBAAqB,iBAAgB,yBAAyB,YAAY;IAC1E,qBAAoB,gBAAe,sBAAsB,WAAW;IACpE,uBAAsB,kBAAiB,sBAAsB,aAAa;IAC1E,oBAAmB,eAAc,sBAAsB,UAAU;IACjE,yBAAwB,eAAc,sBAAsB,UAAU;GACxE,CAAC,CACH,CACF,CACF;GAEA,OAAO,sBAAsB;IAAE,QAAQ,KAAK;IAAI;GAAO,CAAC;EAC1D,CAAC;CACL,CAAC,CACH;AACF;AAEA,MAAa,yBACX,UAA6C,CAAC,MAE9C,OAAO,IAAI,aAAa;CAGtB,OAAO,6BAA6B,OAFb,SAEsB,OAAO;AACtD,CAAC"}
|
package/dist/errors.d.mts
CHANGED
|
@@ -38,7 +38,6 @@ declare const SandboxProviderError_base: Schema.Class<SandboxProviderError, Sche
|
|
|
38
38
|
}>, import("effect/Cause").YieldableError>;
|
|
39
39
|
declare class SandboxProviderError extends SandboxProviderError_base {}
|
|
40
40
|
type SandboxError = SandboxInputError | SandboxConfigError | SandboxExpiredError | SandboxStateError | SandboxStateStoreError | SandboxProviderError;
|
|
41
|
-
declare const unknownToMessage: (error: unknown) => string;
|
|
42
41
|
//#endregion
|
|
43
|
-
export { SandboxConfigError, SandboxError, SandboxExpiredError, SandboxInputError, SandboxInputErrorCause, SandboxProviderError, SandboxStateError, SandboxStateStoreError
|
|
42
|
+
export { SandboxConfigError, SandboxError, SandboxExpiredError, SandboxInputError, SandboxInputErrorCause, SandboxProviderError, SandboxStateError, SandboxStateStoreError };
|
|
44
43
|
//# sourceMappingURL=errors.d.mts.map
|
package/dist/errors.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.mts","names":[],"sources":["../src/errors.ts"],"mappings":";;;cAEa,sBAAA,EAAsB,MAAA,CAAA,QAAA;AAAA,
|
|
1
|
+
{"version":3,"file":"errors.d.mts","names":[],"sources":["../src/errors.ts"],"mappings":";;;cAEa,sBAAA,EAAsB,MAAA,CAAA,QAAA;AAAA,KAMvB,sBAAA,UAAgC,sBAAA,CAAuB,IAAI;AAAA,cAAA,sBAAA;;;;cAE1D,iBAAA,SAA0B,sBAMtC;AAAA,cAAG,uBAAA;;;;cAES,kBAAA,SAA2B,uBAMvC;AAAA,cAAG,wBAAA;;;;cAES,mBAAA,SAA4B,wBAMxC;AAAA,cAAG,sBAAA;;;;;cAES,iBAAA,SAA0B,sBAOtC;AAAA,cAAG,2BAAA;;;;;cAES,sBAAA,SAA+B,2BAO3C;AAAA,cAAG,yBAAA;;;;;;cAES,oBAAA,SAA6B,yBAQzC;AAAA,KAEW,YAAA,GACR,iBAAA,GACA,kBAAA,GACA,mBAAA,GACA,iBAAA,GACA,sBAAA,GACA,oBAAA"}
|
package/dist/errors.mjs
CHANGED
|
@@ -5,36 +5,35 @@ const SandboxInputErrorCause = Schema.Literals([
|
|
|
5
5
|
"invalid_cwd",
|
|
6
6
|
"invalid_timeout"
|
|
7
7
|
]);
|
|
8
|
-
var SandboxInputError = class extends Schema.
|
|
8
|
+
var SandboxInputError = class extends Schema.TaggedError()("SandboxInputError", {
|
|
9
9
|
cause: SandboxInputErrorCause,
|
|
10
10
|
message: Schema.String
|
|
11
11
|
}) {};
|
|
12
|
-
var SandboxConfigError = class extends Schema.
|
|
12
|
+
var SandboxConfigError = class extends Schema.TaggedError()("SandboxConfigError", {
|
|
13
13
|
message: Schema.String,
|
|
14
14
|
cause: Schema.String
|
|
15
15
|
}) {};
|
|
16
|
-
var SandboxExpiredError = class extends Schema.
|
|
16
|
+
var SandboxExpiredError = class extends Schema.TaggedError()("SandboxExpiredError", {
|
|
17
17
|
message: Schema.String,
|
|
18
18
|
expiredAtMs: Schema.Number
|
|
19
19
|
}) {};
|
|
20
|
-
var SandboxStateError = class extends Schema.
|
|
20
|
+
var SandboxStateError = class extends Schema.TaggedError()("SandboxStateError", {
|
|
21
21
|
message: Schema.String,
|
|
22
22
|
cause: Schema.String,
|
|
23
23
|
underlying: Schema.optional(Schema.Unknown)
|
|
24
24
|
}) {};
|
|
25
|
-
var SandboxStateStoreError = class extends Schema.
|
|
25
|
+
var SandboxStateStoreError = class extends Schema.TaggedError()("SandboxStateStoreError", {
|
|
26
26
|
message: Schema.String,
|
|
27
27
|
operation: Schema.String,
|
|
28
28
|
underlying: Schema.optional(Schema.Unknown)
|
|
29
29
|
}) {};
|
|
30
|
-
var SandboxProviderError = class extends Schema.
|
|
30
|
+
var SandboxProviderError = class extends Schema.TaggedError()("SandboxProviderError", {
|
|
31
31
|
provider: Schema.Literal("vercel"),
|
|
32
32
|
operation: Schema.String,
|
|
33
33
|
message: Schema.String,
|
|
34
34
|
underlying: Schema.optional(Schema.Unknown)
|
|
35
35
|
}) {};
|
|
36
|
-
const unknownToMessage = (error) => error instanceof Error ? error.message : String(error);
|
|
37
36
|
//#endregion
|
|
38
|
-
export { SandboxConfigError, SandboxExpiredError, SandboxInputError, SandboxInputErrorCause, SandboxProviderError, SandboxStateError, SandboxStateStoreError
|
|
37
|
+
export { SandboxConfigError, SandboxExpiredError, SandboxInputError, SandboxInputErrorCause, SandboxProviderError, SandboxStateError, SandboxStateStoreError };
|
|
39
38
|
|
|
40
39
|
//# sourceMappingURL=errors.mjs.map
|
package/dist/errors.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.mjs","names":[],"sources":["../src/errors.ts"],"sourcesContent":["import * as Schema from 'effect/Schema'\n\nexport const SandboxInputErrorCause = Schema.Literals([\n 'empty_command',\n 'invalid_cwd',\n 'invalid_timeout'\n])\nexport type SandboxInputErrorCause = typeof SandboxInputErrorCause.Type\n\nexport class SandboxInputError extends Schema.
|
|
1
|
+
{"version":3,"file":"errors.mjs","names":[],"sources":["../src/errors.ts"],"sourcesContent":["import * as Schema from 'effect/Schema'\n\nexport const SandboxInputErrorCause = Schema.Literals([\n 'empty_command',\n 'invalid_cwd',\n 'invalid_timeout'\n])\n\nexport type SandboxInputErrorCause = typeof SandboxInputErrorCause.Type\n\nexport class SandboxInputError extends Schema.TaggedError<SandboxInputError>()(\n 'SandboxInputError',\n {\n cause: SandboxInputErrorCause,\n message: Schema.String\n }\n) {}\n\nexport class SandboxConfigError extends Schema.TaggedError<SandboxConfigError>()(\n 'SandboxConfigError',\n {\n message: Schema.String,\n cause: Schema.String\n }\n) {}\n\nexport class SandboxExpiredError extends Schema.TaggedError<SandboxExpiredError>()(\n 'SandboxExpiredError',\n {\n message: Schema.String,\n expiredAtMs: Schema.Number\n }\n) {}\n\nexport class SandboxStateError extends Schema.TaggedError<SandboxStateError>()(\n 'SandboxStateError',\n {\n message: Schema.String,\n cause: Schema.String,\n underlying: Schema.optional(Schema.Unknown)\n }\n) {}\n\nexport class SandboxStateStoreError extends Schema.TaggedError<SandboxStateStoreError>()(\n 'SandboxStateStoreError',\n {\n message: Schema.String,\n operation: Schema.String,\n underlying: Schema.optional(Schema.Unknown)\n }\n) {}\n\nexport class SandboxProviderError extends Schema.TaggedError<SandboxProviderError>()(\n 'SandboxProviderError',\n {\n provider: Schema.Literal('vercel'),\n operation: Schema.String,\n message: Schema.String,\n underlying: Schema.optional(Schema.Unknown)\n }\n) {}\n\nexport type SandboxError =\n | SandboxInputError\n | SandboxConfigError\n | SandboxExpiredError\n | SandboxStateError\n | SandboxStateStoreError\n | SandboxProviderError\n"],"mappings":";;AAEA,MAAa,yBAAyB,OAAO,SAAS;CACpD;CACA;CACA;AACF,CAAC;AAID,IAAa,oBAAb,cAAuC,OAAO,YAA+B,EAC3E,qBACA;CACE,OAAO;CACP,SAAS,OAAO;AAClB,CACF,EAAE,CAAC;AAEH,IAAa,qBAAb,cAAwC,OAAO,YAAgC,EAC7E,sBACA;CACE,SAAS,OAAO;CAChB,OAAO,OAAO;AAChB,CACF,EAAE,CAAC;AAEH,IAAa,sBAAb,cAAyC,OAAO,YAAiC,EAC/E,uBACA;CACE,SAAS,OAAO;CAChB,aAAa,OAAO;AACtB,CACF,EAAE,CAAC;AAEH,IAAa,oBAAb,cAAuC,OAAO,YAA+B,EAC3E,qBACA;CACE,SAAS,OAAO;CAChB,OAAO,OAAO;CACd,YAAY,OAAO,SAAS,OAAO,OAAO;AAC5C,CACF,EAAE,CAAC;AAEH,IAAa,yBAAb,cAA4C,OAAO,YAAoC,EACrF,0BACA;CACE,SAAS,OAAO;CAChB,WAAW,OAAO;CAClB,YAAY,OAAO,SAAS,OAAO,OAAO;AAC5C,CACF,EAAE,CAAC;AAEH,IAAa,uBAAb,cAA0C,OAAO,YAAkC,EACjF,wBACA;CACE,UAAU,OAAO,QAAQ,QAAQ;CACjC,WAAW,OAAO;CAClB,SAAS,OAAO;CAChB,YAAY,OAAO,SAAS,OAAO,OAAO;AAC5C,CACF,EAAE,CAAC"}
|
package/dist/lifecycle.d.mts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { SandboxInputError } from "./errors.mjs";
|
|
2
2
|
import { DisposableSandboxLifecycle, EmptySandboxInitialSource, SandboxInitialSource, SandboxLifecycle, SandboxState, VercelSandboxState } from "./model.mjs";
|
|
3
3
|
import { Effect, Option } from "effect";
|
|
4
|
+
import * as Schema from "effect/Schema";
|
|
4
5
|
|
|
5
6
|
//#region src/lifecycle.d.ts
|
|
6
7
|
declare const defaultSandboxIdleTtlMs: number;
|
|
@@ -14,14 +15,14 @@ declare const defaultSandboxWorkspaceRoot = "/vercel/sandbox";
|
|
|
14
15
|
declare const defaultSandboxLifecycle: DisposableSandboxLifecycle;
|
|
15
16
|
declare const defaultSandboxInitialSource: EmptySandboxInitialSource;
|
|
16
17
|
type SandboxRecreateReason = 'idle_expired' | 'max_expired' | 'name_mismatch';
|
|
18
|
+
declare const SandboxCreateDecision: Schema.TaggedStruct<"Create", {
|
|
19
|
+
readonly workspaceReset: Schema.Boolean;
|
|
20
|
+
readonly reason: Schema.optionalKey<Schema.Literals<readonly ["idle_expired", "max_expired", "name_mismatch"]>>;
|
|
21
|
+
}>;
|
|
17
22
|
type SandboxStateDecision = {
|
|
18
23
|
readonly _tag: 'UseExisting';
|
|
19
24
|
readonly state: SandboxState;
|
|
20
|
-
} |
|
|
21
|
-
readonly _tag: 'Create';
|
|
22
|
-
readonly workspaceReset: boolean;
|
|
23
|
-
readonly reason?: SandboxRecreateReason;
|
|
24
|
-
};
|
|
25
|
+
} | typeof SandboxCreateDecision.Type;
|
|
25
26
|
declare const sandboxLifecycleOrDefault: (lifecycle?: SandboxLifecycle) => SandboxLifecycle;
|
|
26
27
|
declare const sandboxSourceOrDefault: (source?: SandboxInitialSource) => SandboxInitialSource;
|
|
27
28
|
declare const sandboxCommandTimeoutMs: (timeoutMs?: number) => number;
|
package/dist/lifecycle.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lifecycle.d.mts","names":[],"sources":["../src/lifecycle.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"lifecycle.d.mts","names":[],"sources":["../src/lifecycle.ts"],"mappings":";;;;;;cAYa,uBAAA;AAAA,cAEA,2BAAA;AAAA,cAEA,8BAAA;AAAA,cAEA,0BAAA;AAAA,cAEA,wBAAA;AAAA,cAEA,sBAAA;AAAA,cAEA,mBAAA,EAAqB,aAAa;AAAA,cAElC,2BAAA;AAAA,cAEA,uBAAA,EAAuB,0BAGlC;AAAA,cAEW,2BAAA,EAA2B,yBAAqC;AAAA,KAEjE,qBAAA;AAAA,cAMN,qBAAA,EAAqB,MAAA,CAAA,YAAA;EAAA;;;KAKf,oBAAA;EAAA,SAEG,IAAA;EAAA,SACA,KAAA,EAAO,YAAA;AAAA,WAEX,qBAAA,CAAsB,IAAI;AAAA,cAUxB,yBAAA,GAA6B,SAAA,GAAY,gBAAA,KAAmB,gBACnC;AAAA,cAEzB,sBAAA,GAA0B,MAAA,GAAS,oBAAA,KAAuB,oBAChC;AAAA,cAE1B,uBAAA,GAA2B,SAAkB;AAAA,cAG7C,sBAAA,GAA0B,OAAA,aAAe,MAAA,CAAA,MAAA,QAAA,iBAAA,WAAA,MAAA,CAAA,MAAA;AAAA,cAazC,qBAAA,GACX,GAAA,qBACC,MAAA,CAAO,MAAM,SAAS,iBAAA;AAAA,cA4CZ,kBAAA,GAAsB,aAAA,UAAuB,aAAqB;AAAA,cAGlE,mBAAA,GAAuB,KAAA;EAAA,SACzB,IAAA;EAAA,SACA,KAAA;EAAA,SACA,SAAA,EAAW,gBAAA;AAAA,MACrB,kBAsBE;AAAA,cAEU,iBAAA,GAAqB,KAAA;EAAA,SACvB,KAAA,EAAO,YAAA;EAAA,SACP,KAAA;EAAA,SACA,SAAA,EAAW,gBAAA;AAAA,MACrB,kBAAA;AAAA,cAoBY,2BAAA,GAA+B,KAAA;EAAA,SACjC,MAAA,EAAQ,YAAA;EAAA,SACR,KAAA,EAAO,YAAY;AAAA;AAAA,cAGjB,oBAAA,GAAwB,KAAA;EAAA,SAC1B,KAAA,EAAO,MAAA,CAAO,MAAA,CAAO,YAAA;EAAA,SACrB,IAAA;EAAA,SACA,KAAA;EAAA,SACA,SAAA,EAAW,gBAAA;AAAA,MAClB,oBAAA"}
|
package/dist/lifecycle.mjs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { SandboxInputError } from "./errors.mjs";
|
|
2
2
|
import { DisposableSandboxLifecycle, EmptySandboxInitialSource, VercelSandboxState } from "./model.mjs";
|
|
3
|
-
import { Effect, Option } from "effect";
|
|
3
|
+
import { Effect, Match, Option, Predicate } from "effect";
|
|
4
|
+
import * as Schema from "effect/Schema";
|
|
4
5
|
//#region src/lifecycle.ts
|
|
5
6
|
const defaultSandboxIdleTtlMs = 30 * 6e4;
|
|
6
7
|
const defaultSandboxMaxLifetimeMs = 45 * 6e4;
|
|
@@ -20,6 +21,19 @@ const defaultSandboxLifecycle = DisposableSandboxLifecycle.make({
|
|
|
20
21
|
maxLifetimeMs: defaultSandboxMaxLifetimeMs
|
|
21
22
|
});
|
|
22
23
|
const defaultSandboxInitialSource = EmptySandboxInitialSource.make({});
|
|
24
|
+
const SandboxUseExistingDecision = Schema.TaggedStruct("UseExisting", { state: Schema.Unknown });
|
|
25
|
+
const SandboxCreateDecision = Schema.TaggedStruct("Create", {
|
|
26
|
+
workspaceReset: Schema.Boolean,
|
|
27
|
+
reason: Schema.optionalKey(Schema.Literals([
|
|
28
|
+
"idle_expired",
|
|
29
|
+
"max_expired",
|
|
30
|
+
"name_mismatch"
|
|
31
|
+
]))
|
|
32
|
+
});
|
|
33
|
+
const existingSandboxStateDecision = (state) => ({
|
|
34
|
+
...SandboxUseExistingDecision.make({ state }),
|
|
35
|
+
state
|
|
36
|
+
});
|
|
23
37
|
const positiveOr = (value, fallback) => value === void 0 || !Number.isFinite(value) || value <= 0 ? fallback : Math.floor(value);
|
|
24
38
|
const sandboxLifecycleOrDefault = (lifecycle) => lifecycle ?? defaultSandboxLifecycle;
|
|
25
39
|
const sandboxSourceOrDefault = (source) => source ?? defaultSandboxInitialSource;
|
|
@@ -53,68 +67,46 @@ const normalizeWorkspaceCwd = (cwd) => {
|
|
|
53
67
|
return Effect.succeed(parts.length === 0 ? "." : parts.join("/"));
|
|
54
68
|
};
|
|
55
69
|
const absoluteSandboxCwd = (workspaceRoot, normalizedCwd) => normalizedCwd === "." ? workspaceRoot : `${workspaceRoot}/${normalizedCwd}`;
|
|
56
|
-
const initialSandboxState = (input) => {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
lastUsedAtMs: input.nowMs,
|
|
79
|
-
expiresAtMs: Math.min(input.nowMs + input.lifecycle.idleTtlMs, input.state.maxExpiresAtMs)
|
|
80
|
-
});
|
|
81
|
-
case "Persistent": return VercelSandboxState.make({
|
|
82
|
-
...input.state,
|
|
83
|
-
lastUsedAtMs: input.nowMs,
|
|
84
|
-
expiresAtMs: input.nowMs + input.lifecycle.idleTtlMs
|
|
85
|
-
});
|
|
86
|
-
}
|
|
87
|
-
};
|
|
70
|
+
const initialSandboxState = (input) => Match.value(input.lifecycle).pipe(Match.withReturnType(), Match.tag("Disposable", (lifecycle) => VercelSandboxState.make({
|
|
71
|
+
name: input.name,
|
|
72
|
+
createdAtMs: input.nowMs,
|
|
73
|
+
lastUsedAtMs: input.nowMs,
|
|
74
|
+
expiresAtMs: input.nowMs + lifecycle.idleTtlMs,
|
|
75
|
+
maxExpiresAtMs: input.nowMs + lifecycle.maxLifetimeMs
|
|
76
|
+
})), Match.tag("Persistent", (lifecycle) => VercelSandboxState.make({
|
|
77
|
+
name: input.name,
|
|
78
|
+
createdAtMs: input.nowMs,
|
|
79
|
+
lastUsedAtMs: input.nowMs,
|
|
80
|
+
expiresAtMs: input.nowMs + lifecycle.idleTtlMs,
|
|
81
|
+
maxExpiresAtMs: Number.MAX_SAFE_INTEGER
|
|
82
|
+
})), Match.exhaustive);
|
|
83
|
+
const touchSandboxState = (input) => Match.value(input.lifecycle).pipe(Match.withReturnType(), Match.tag("Disposable", (lifecycle) => VercelSandboxState.make({
|
|
84
|
+
...input.state,
|
|
85
|
+
lastUsedAtMs: input.nowMs,
|
|
86
|
+
expiresAtMs: Math.min(input.nowMs + lifecycle.idleTtlMs, input.state.maxExpiresAtMs)
|
|
87
|
+
})), Match.tag("Persistent", (lifecycle) => VercelSandboxState.make({
|
|
88
|
+
...input.state,
|
|
89
|
+
lastUsedAtMs: input.nowMs,
|
|
90
|
+
expiresAtMs: input.nowMs + lifecycle.idleTtlMs
|
|
91
|
+
})), Match.exhaustive);
|
|
88
92
|
const sandboxTimeoutExtendDeltaMs = (input) => Math.max(0, input.after.expiresAtMs - input.before.expiresAtMs);
|
|
89
93
|
const sandboxStateDecision = (input) => {
|
|
90
|
-
if (Option.isNone(input.state)) return {
|
|
91
|
-
_tag: "Create",
|
|
92
|
-
workspaceReset: false
|
|
93
|
-
};
|
|
94
|
+
if (Option.isNone(input.state)) return SandboxCreateDecision.make({ workspaceReset: false });
|
|
94
95
|
const state = input.state.value;
|
|
95
|
-
if (state.name !== input.name) return {
|
|
96
|
-
_tag: "Create",
|
|
96
|
+
if (state.name !== input.name) return SandboxCreateDecision.make({
|
|
97
97
|
workspaceReset: true,
|
|
98
98
|
reason: "name_mismatch"
|
|
99
|
-
};
|
|
100
|
-
if (input.lifecycle
|
|
101
|
-
|
|
102
|
-
state
|
|
103
|
-
};
|
|
104
|
-
if (input.nowMs >= state.maxExpiresAtMs) return {
|
|
105
|
-
_tag: "Create",
|
|
99
|
+
});
|
|
100
|
+
if (Predicate.isTagged(input.lifecycle, "Persistent")) return existingSandboxStateDecision(state);
|
|
101
|
+
if (input.nowMs >= state.maxExpiresAtMs) return SandboxCreateDecision.make({
|
|
106
102
|
workspaceReset: true,
|
|
107
103
|
reason: "max_expired"
|
|
108
|
-
};
|
|
109
|
-
if (input.nowMs >= state.expiresAtMs) return {
|
|
110
|
-
_tag: "Create",
|
|
104
|
+
});
|
|
105
|
+
if (input.nowMs >= state.expiresAtMs) return SandboxCreateDecision.make({
|
|
111
106
|
workspaceReset: true,
|
|
112
107
|
reason: "idle_expired"
|
|
113
|
-
};
|
|
114
|
-
return
|
|
115
|
-
_tag: "UseExisting",
|
|
116
|
-
state
|
|
117
|
-
};
|
|
108
|
+
});
|
|
109
|
+
return existingSandboxStateDecision(state);
|
|
118
110
|
};
|
|
119
111
|
//#endregion
|
|
120
112
|
export { absoluteSandboxCwd, backgroundSandboxProbeMs, defaultSandboxCommandTimeoutMs, defaultSandboxIdleTtlMs, defaultSandboxInitialSource, defaultSandboxLifecycle, defaultSandboxMaxLifetimeMs, defaultSandboxPorts, defaultSandboxWorkspaceRoot, initialSandboxState, maxSandboxCommandTimeoutMs, normalizeWorkspaceCwd, sandboxCommandTimeoutMs, sandboxLifecycleOrDefault, sandboxSourceOrDefault, sandboxStateDecision, sandboxTimeoutExtendDeltaMs, sandboxToolOutputLimit, touchSandboxState, validateSandboxCommand };
|
package/dist/lifecycle.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lifecycle.mjs","names":[],"sources":["../src/lifecycle.ts"],"sourcesContent":["import { Effect, Option } from 'effect'\nimport { SandboxInputError } from './errors.ts'\nimport {\n DisposableSandboxLifecycle,\n EmptySandboxInitialSource,\n type SandboxInitialSource,\n type SandboxLifecycle,\n type SandboxState,\n VercelSandboxState\n} from './model.ts'\n\nexport const defaultSandboxIdleTtlMs = 30 * 60_000\nexport const defaultSandboxMaxLifetimeMs = 45 * 60_000\nexport const defaultSandboxCommandTimeoutMs = 120_000\nexport const maxSandboxCommandTimeoutMs = 600_000\nexport const backgroundSandboxProbeMs = 2_000\nexport const sandboxToolOutputLimit = 50_000\nexport const defaultSandboxPorts: ReadonlyArray<number> = [3000, 5173, 4321, 8000]\nexport const defaultSandboxWorkspaceRoot = '/vercel/sandbox'\n\nexport const defaultSandboxLifecycle = DisposableSandboxLifecycle.make({\n idleTtlMs: defaultSandboxIdleTtlMs,\n maxLifetimeMs: defaultSandboxMaxLifetimeMs\n})\n\nexport const defaultSandboxInitialSource = EmptySandboxInitialSource.make({})\n\nexport type SandboxRecreateReason = 'idle_expired' | 'max_expired' | 'name_mismatch'\n\nexport type SandboxStateDecision =\n | {\n readonly _tag: 'UseExisting'\n readonly state: SandboxState\n }\n |
|
|
1
|
+
{"version":3,"file":"lifecycle.mjs","names":[],"sources":["../src/lifecycle.ts"],"sourcesContent":["import { Effect, Match, Option, Predicate } from 'effect'\nimport * as Schema from 'effect/Schema'\nimport { SandboxInputError } from './errors.ts'\nimport {\n DisposableSandboxLifecycle,\n EmptySandboxInitialSource,\n type SandboxInitialSource,\n type SandboxLifecycle,\n type SandboxState,\n VercelSandboxState\n} from './model.ts'\n\nexport const defaultSandboxIdleTtlMs = 30 * 60_000\n\nexport const defaultSandboxMaxLifetimeMs = 45 * 60_000\n\nexport const defaultSandboxCommandTimeoutMs = 120_000\n\nexport const maxSandboxCommandTimeoutMs = 600_000\n\nexport const backgroundSandboxProbeMs = 2_000\n\nexport const sandboxToolOutputLimit = 50_000\n\nexport const defaultSandboxPorts: ReadonlyArray<number> = [3000, 5173, 4321, 8000]\n\nexport const defaultSandboxWorkspaceRoot = '/vercel/sandbox'\n\nexport const defaultSandboxLifecycle = DisposableSandboxLifecycle.make({\n idleTtlMs: defaultSandboxIdleTtlMs,\n maxLifetimeMs: defaultSandboxMaxLifetimeMs\n})\n\nexport const defaultSandboxInitialSource = EmptySandboxInitialSource.make({})\n\nexport type SandboxRecreateReason = 'idle_expired' | 'max_expired' | 'name_mismatch'\n\nconst SandboxUseExistingDecision = Schema.TaggedStruct('UseExisting', {\n state: Schema.Unknown\n})\n\nconst SandboxCreateDecision = Schema.TaggedStruct('Create', {\n workspaceReset: Schema.Boolean,\n reason: Schema.optionalKey(Schema.Literals(['idle_expired', 'max_expired', 'name_mismatch']))\n})\n\nexport type SandboxStateDecision =\n | {\n readonly _tag: 'UseExisting'\n readonly state: SandboxState\n }\n | typeof SandboxCreateDecision.Type\n\nconst existingSandboxStateDecision = (state: SandboxState): SandboxStateDecision => ({\n ...SandboxUseExistingDecision.make({ state }),\n state\n})\n\nconst positiveOr = (value: number | undefined, fallback: number) =>\n value === undefined || !Number.isFinite(value) || value <= 0 ? fallback : Math.floor(value)\n\nexport const sandboxLifecycleOrDefault = (lifecycle?: SandboxLifecycle): SandboxLifecycle =>\n lifecycle ?? defaultSandboxLifecycle\n\nexport const sandboxSourceOrDefault = (source?: SandboxInitialSource): SandboxInitialSource =>\n source ?? defaultSandboxInitialSource\n\nexport const sandboxCommandTimeoutMs = (timeoutMs?: number) =>\n Math.min(maxSandboxCommandTimeoutMs, positiveOr(timeoutMs, defaultSandboxCommandTimeoutMs))\n\nexport const validateSandboxCommand = (command: string) => {\n if (command.trim().length === 0) {\n return Effect.fail(\n new SandboxInputError({\n cause: 'empty_command',\n message: 'Sandbox command must not be empty'\n })\n )\n }\n\n return Effect.succeed(command)\n}\n\nexport const normalizeWorkspaceCwd = (\n cwd?: string | null\n): Effect.Effect<string, SandboxInputError> => {\n if (cwd === undefined || cwd === null || cwd.trim().length === 0) {\n return Effect.succeed('.')\n }\n\n const trimmed = cwd.trim()\n\n if (trimmed.startsWith('/') || trimmed.includes('\\0')) {\n return Effect.fail(\n new SandboxInputError({\n cause: 'invalid_cwd',\n message: 'cwd must be workspace-relative'\n })\n )\n }\n\n const parts: Array<string> = []\n\n for (const segment of trimmed.split('/')) {\n if (segment.length === 0 || segment === '.') {\n continue\n }\n\n if (segment === '..') {\n const previous = parts.pop()\n\n if (previous === undefined) {\n return Effect.fail(\n new SandboxInputError({\n cause: 'invalid_cwd',\n message: 'cwd must not escape the workspace'\n })\n )\n }\n\n continue\n }\n\n parts.push(segment)\n }\n\n return Effect.succeed(parts.length === 0 ? '.' : parts.join('/'))\n}\n\nexport const absoluteSandboxCwd = (workspaceRoot: string, normalizedCwd: string) =>\n normalizedCwd === '.' ? workspaceRoot : `${workspaceRoot}/${normalizedCwd}`\n\nexport const initialSandboxState = (input: {\n readonly name: string\n readonly nowMs: number\n readonly lifecycle: SandboxLifecycle\n}) =>\n Match.value(input.lifecycle).pipe(\n Match.withReturnType<SandboxState>(),\n Match.tag('Disposable', lifecycle =>\n VercelSandboxState.make({\n name: input.name,\n createdAtMs: input.nowMs,\n lastUsedAtMs: input.nowMs,\n expiresAtMs: input.nowMs + lifecycle.idleTtlMs,\n maxExpiresAtMs: input.nowMs + lifecycle.maxLifetimeMs\n })\n ),\n Match.tag('Persistent', lifecycle =>\n VercelSandboxState.make({\n name: input.name,\n createdAtMs: input.nowMs,\n lastUsedAtMs: input.nowMs,\n expiresAtMs: input.nowMs + lifecycle.idleTtlMs,\n maxExpiresAtMs: Number.MAX_SAFE_INTEGER\n })\n ),\n Match.exhaustive\n )\n\nexport const touchSandboxState = (input: {\n readonly state: SandboxState\n readonly nowMs: number\n readonly lifecycle: SandboxLifecycle\n}) =>\n Match.value(input.lifecycle).pipe(\n Match.withReturnType<SandboxState>(),\n Match.tag('Disposable', lifecycle =>\n VercelSandboxState.make({\n ...input.state,\n lastUsedAtMs: input.nowMs,\n expiresAtMs: Math.min(input.nowMs + lifecycle.idleTtlMs, input.state.maxExpiresAtMs)\n })\n ),\n Match.tag('Persistent', lifecycle =>\n VercelSandboxState.make({\n ...input.state,\n lastUsedAtMs: input.nowMs,\n expiresAtMs: input.nowMs + lifecycle.idleTtlMs\n })\n ),\n Match.exhaustive\n )\n\nexport const sandboxTimeoutExtendDeltaMs = (input: {\n readonly before: SandboxState\n readonly after: SandboxState\n}) => Math.max(0, input.after.expiresAtMs - input.before.expiresAtMs)\n\nexport const sandboxStateDecision = (input: {\n readonly state: Option.Option<SandboxState>\n readonly name: string\n readonly nowMs: number\n readonly lifecycle: SandboxLifecycle\n}): SandboxStateDecision => {\n if (Option.isNone(input.state)) {\n return SandboxCreateDecision.make({ workspaceReset: false })\n }\n\n const state = input.state.value\n\n if (state.name !== input.name) {\n return SandboxCreateDecision.make({ workspaceReset: true, reason: 'name_mismatch' })\n }\n\n if (Predicate.isTagged(input.lifecycle, 'Persistent')) {\n return existingSandboxStateDecision(state)\n }\n\n if (input.nowMs >= state.maxExpiresAtMs) {\n return SandboxCreateDecision.make({ workspaceReset: true, reason: 'max_expired' })\n }\n\n if (input.nowMs >= state.expiresAtMs) {\n return SandboxCreateDecision.make({ workspaceReset: true, reason: 'idle_expired' })\n }\n\n return existingSandboxStateDecision(state)\n}\n"],"mappings":"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"}
|
package/dist/model.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model.d.mts","names":[],"sources":["../src/model.ts"],"mappings":";;;cAAuC,wBAAA;;;;;;;
|
|
1
|
+
{"version":3,"file":"model.d.mts","names":[],"sources":["../src/model.ts"],"mappings":";;;cAAuC,wBAAA;;;;;;;cAY1B,mBAAA,SAA4B,wBAMvC;AAAA,cAAG,sBAAA;;;;cAEQ,iBAAA,SAA0B,sBAGrC;AAAA,cAAG,uBAAA;;;;;;;cAEQ,kBAAA,SAA2B,uBAMtC;AAAA,cAEW,YAAA,EAAY,MAAA,CAAA,KAAA,kBAAA,kBAAA;AAAA,KAEb,YAAA,UAAsB,YAAA,CAAa,IAAI;AAAA,cAAA,yBAAA;;;;;;;;;;;cAEtC,oBAAA,SAA6B,yBAYxC;AAAA,cAAG,+BAAA;;;;cAEQ,0BAAA,SAAmC,+BAM/C;AAAA,cAAG,6BAAA;;;;;cAES,wBAAA,SAAiC,6BAM5C;AAAA,cAAG,+BAAA;;;;;cAEQ,0BAAA,SAAmC,+BAO/C;AAAA,cAEY,gBAAA,EAAgB,MAAA,CAAA,KAAA,kBAAA,0BAAA,SAAA,0BAAA;AAAA,KAKjB,gBAAA,UAA0B,gBAAA,CAAiB,IAAI;AAAA,cAAA,8BAAA;cAE9C,yBAAA,SAAkC,8BAG9C;AAAA,cAAG,iCAAA;;;cAES,4BAAA,SAAqC,iCAKjD;AAAA,cAAG,wBAAA;;;;cAES,mBAAA,SAA4B,wBAGvC;AAAA,cAAG,4BAAA;;;;;;cAEQ,uBAAA,SAAgC,4BAK3C;AAAA,cAAG,gCAAA;;;cAEQ,2BAAA,SAAoC,gCAKhD;AAAA,cAEY,oBAAA,EAAoB,MAAA,CAAA,KAAA,kBAAA,yBAAA,SAAA,4BAAA,SAAA,uBAAA,SAAA,2BAAA;AAAA,KAOrB,oBAAA,UAA8B,oBAAA,CAAqB,IAAI;AAAA,cAAA,qBAAA;;;cAEtD,gBAAA,SAAyB,qBAEpC"}
|
package/dist/model.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model.mjs","names":[],"sources":["../src/model.ts"],"sourcesContent":["import * as Schema from 'effect/Schema'\n\nconst NonEmptyTrimmedString = Schema.Trimmed.pipe(Schema.check(Schema.isNonEmpty()))\nconst NonNegativeInteger = Schema.Int.pipe(Schema.check(Schema.isGreaterThanOrEqualTo(0)))\nconst PositiveInteger = Schema.Int.pipe(Schema.check(Schema.isGreaterThan(0)))\nconst PositiveNumber = Schema.Number.pipe(Schema.check(Schema.isGreaterThan(0)))\nconst SnapshotRetentionCount = PositiveInteger.pipe(Schema.check(Schema.isLessThanOrEqualTo(10)))\n\nexport class SandboxCommandInput extends Schema.Class<SandboxCommandInput>('SandboxCommandInput')({\n command: Schema.String,\n cwd: Schema.optional(Schema.String),\n stdin: Schema.optional(Schema.String),\n timeoutMs: Schema.optional(PositiveInteger),\n background: Schema.optional(Schema.Boolean)\n}) {}\n\nexport class SandboxPreviewUrl extends Schema.Class<SandboxPreviewUrl>('SandboxPreviewUrl')({\n port: PositiveInteger,\n url: NonEmptyTrimmedString\n}) {}\n\nexport class VercelSandboxState extends Schema.TaggedClass<VercelSandboxState>()('Vercel', {\n name: NonEmptyTrimmedString,\n createdAtMs: NonNegativeInteger,\n lastUsedAtMs: NonNegativeInteger,\n expiresAtMs: NonNegativeInteger,\n maxExpiresAtMs: NonNegativeInteger\n}) {}\n\nexport const SandboxState = Schema.Union([VercelSandboxState])\nexport type SandboxState = typeof SandboxState.Type\n\nexport class SandboxCommandResult extends Schema.Class<SandboxCommandResult>(\n 'SandboxCommandResult'\n)({\n exitCode: Schema.NullOr(Schema.Int),\n stdout: Schema.String,\n stderr: Schema.String,\n durationMs: NonNegativeInteger,\n timedOut: Schema.Boolean,\n workspaceReset: Schema.Boolean,\n backgroundId: Schema.optional(NonEmptyTrimmedString),\n previewUrls: Schema.Array(SandboxPreviewUrl),\n state: SandboxState\n}) {}\n\nexport class DisposableSandboxLifecycle extends Schema.TaggedClass<DisposableSandboxLifecycle>()(\n 'Disposable',\n {\n idleTtlMs: PositiveInteger,\n maxLifetimeMs: PositiveInteger\n }\n) {}\n\nexport class SandboxSnapshotRetention extends Schema.Class<SandboxSnapshotRetention>(\n 'SandboxSnapshotRetention'\n)({\n count: SnapshotRetentionCount,\n expirationMs: Schema.optional(NonNegativeInteger),\n deleteEvicted: Schema.optional(Schema.Boolean)\n}) {}\n\nexport class PersistentSandboxLifecycle extends Schema.TaggedClass<PersistentSandboxLifecycle>()(\n 'Persistent',\n {\n idleTtlMs: PositiveInteger,\n snapshotExpirationMs: Schema.optional(NonNegativeInteger),\n keepLastSnapshots: Schema.optional(SandboxSnapshotRetention)\n }\n) {}\n\nexport const SandboxLifecycle = Schema.Union([\n DisposableSandboxLifecycle,\n PersistentSandboxLifecycle\n])\nexport type SandboxLifecycle = typeof SandboxLifecycle.Type\n\nexport class EmptySandboxInitialSource extends Schema.TaggedClass<EmptySandboxInitialSource>()(\n 'Empty',\n {}\n) {}\n\nexport class SnapshotSandboxInitialSource extends Schema.TaggedClass<SnapshotSandboxInitialSource>()(\n 'Snapshot',\n {\n snapshotId: NonEmptyTrimmedString\n }\n) {}\n\nexport class GitSandboxBasicAuth extends Schema.Class<GitSandboxBasicAuth>('GitSandboxBasicAuth')({\n username: NonEmptyTrimmedString,\n password: NonEmptyTrimmedString\n}) {}\n\nexport class GitSandboxInitialSource extends Schema.TaggedClass<GitSandboxInitialSource>()('Git', {\n url: NonEmptyTrimmedString,\n auth: Schema.optional(GitSandboxBasicAuth),\n depth: Schema.optional(PositiveInteger),\n revision: Schema.optional(NonEmptyTrimmedString)\n}) {}\n\nexport class TarballSandboxInitialSource extends Schema.TaggedClass<TarballSandboxInitialSource>()(\n 'Tarball',\n {\n url: NonEmptyTrimmedString\n }\n) {}\n\nexport const SandboxInitialSource = Schema.Union([\n EmptySandboxInitialSource,\n SnapshotSandboxInitialSource,\n GitSandboxInitialSource,\n TarballSandboxInitialSource\n])\nexport type SandboxInitialSource = typeof SandboxInitialSource.Type\n\nexport class SandboxResources extends Schema.Class<SandboxResources>('SandboxResources')({\n vcpus: PositiveNumber\n}) {}\n"],"mappings":";;AAEA,MAAM,wBAAwB,OAAO,QAAQ,KAAK,OAAO,MAAM,OAAO,WAAW,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"model.mjs","names":[],"sources":["../src/model.ts"],"sourcesContent":["import * as Schema from 'effect/Schema'\n\nconst NonEmptyTrimmedString = Schema.Trimmed.pipe(Schema.check(Schema.isNonEmpty()))\n\nconst NonNegativeInteger = Schema.Int.pipe(Schema.check(Schema.isGreaterThanOrEqualTo(0)))\n\nconst PositiveInteger = Schema.Int.pipe(Schema.check(Schema.isGreaterThan(0)))\n\nconst PositiveNumber = Schema.Number.pipe(Schema.check(Schema.isGreaterThan(0)))\n\nconst SnapshotRetentionCount = PositiveInteger.pipe(Schema.check(Schema.isLessThanOrEqualTo(10)))\n\nexport class SandboxCommandInput extends Schema.Class<SandboxCommandInput>('SandboxCommandInput')({\n command: Schema.String,\n cwd: Schema.optional(Schema.String),\n stdin: Schema.optional(Schema.String),\n timeoutMs: Schema.optional(PositiveInteger),\n background: Schema.optional(Schema.Boolean)\n}) {}\n\nexport class SandboxPreviewUrl extends Schema.Class<SandboxPreviewUrl>('SandboxPreviewUrl')({\n port: PositiveInteger,\n url: NonEmptyTrimmedString\n}) {}\n\nexport class VercelSandboxState extends Schema.TaggedClass<VercelSandboxState>()('Vercel', {\n name: NonEmptyTrimmedString,\n createdAtMs: NonNegativeInteger,\n lastUsedAtMs: NonNegativeInteger,\n expiresAtMs: NonNegativeInteger,\n maxExpiresAtMs: NonNegativeInteger\n}) {}\n\nexport const SandboxState = Schema.Union([VercelSandboxState])\n\nexport type SandboxState = typeof SandboxState.Type\n\nexport class SandboxCommandResult extends Schema.Class<SandboxCommandResult>(\n 'SandboxCommandResult'\n)({\n exitCode: Schema.NullOr(Schema.Int),\n stdout: Schema.String,\n stderr: Schema.String,\n durationMs: NonNegativeInteger,\n timedOut: Schema.Boolean,\n workspaceReset: Schema.Boolean,\n backgroundId: Schema.optional(NonEmptyTrimmedString),\n previewUrls: Schema.Array(SandboxPreviewUrl),\n state: SandboxState\n}) {}\n\nexport class DisposableSandboxLifecycle extends Schema.TaggedClass<DisposableSandboxLifecycle>()(\n 'Disposable',\n {\n idleTtlMs: PositiveInteger,\n maxLifetimeMs: PositiveInteger\n }\n) {}\n\nexport class SandboxSnapshotRetention extends Schema.Class<SandboxSnapshotRetention>(\n 'SandboxSnapshotRetention'\n)({\n count: SnapshotRetentionCount,\n expirationMs: Schema.optional(NonNegativeInteger),\n deleteEvicted: Schema.optional(Schema.Boolean)\n}) {}\n\nexport class PersistentSandboxLifecycle extends Schema.TaggedClass<PersistentSandboxLifecycle>()(\n 'Persistent',\n {\n idleTtlMs: PositiveInteger,\n snapshotExpirationMs: Schema.optional(NonNegativeInteger),\n keepLastSnapshots: Schema.optional(SandboxSnapshotRetention)\n }\n) {}\n\nexport const SandboxLifecycle = Schema.Union([\n DisposableSandboxLifecycle,\n PersistentSandboxLifecycle\n])\n\nexport type SandboxLifecycle = typeof SandboxLifecycle.Type\n\nexport class EmptySandboxInitialSource extends Schema.TaggedClass<EmptySandboxInitialSource>()(\n 'Empty',\n {}\n) {}\n\nexport class SnapshotSandboxInitialSource extends Schema.TaggedClass<SnapshotSandboxInitialSource>()(\n 'Snapshot',\n {\n snapshotId: NonEmptyTrimmedString\n }\n) {}\n\nexport class GitSandboxBasicAuth extends Schema.Class<GitSandboxBasicAuth>('GitSandboxBasicAuth')({\n username: NonEmptyTrimmedString,\n password: NonEmptyTrimmedString\n}) {}\n\nexport class GitSandboxInitialSource extends Schema.TaggedClass<GitSandboxInitialSource>()('Git', {\n url: NonEmptyTrimmedString,\n auth: Schema.optional(GitSandboxBasicAuth),\n depth: Schema.optional(PositiveInteger),\n revision: Schema.optional(NonEmptyTrimmedString)\n}) {}\n\nexport class TarballSandboxInitialSource extends Schema.TaggedClass<TarballSandboxInitialSource>()(\n 'Tarball',\n {\n url: NonEmptyTrimmedString\n }\n) {}\n\nexport const SandboxInitialSource = Schema.Union([\n EmptySandboxInitialSource,\n SnapshotSandboxInitialSource,\n GitSandboxInitialSource,\n TarballSandboxInitialSource\n])\n\nexport type SandboxInitialSource = typeof SandboxInitialSource.Type\n\nexport class SandboxResources extends Schema.Class<SandboxResources>('SandboxResources')({\n vcpus: PositiveNumber\n}) {}\n"],"mappings":"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"}
|
package/dist/name.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"name.d.mts","names":[],"sources":["../src/name.ts"],"mappings":";
|
|
1
|
+
{"version":3,"file":"name.d.mts","names":[],"sources":["../src/name.ts"],"mappings":";cAsBa,qBAAA,GAAyB,gBAAwB"}
|
package/dist/name.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"name.mjs","names":[],"sources":["../src/name.ts"],"sourcesContent":["const fnvOffsetBasis32 = 0x811c9dc5\nconst fnvPrime32 = 0x01000193\n\nconst fnv1a32 = (value: string, seed: number) => {\n let hash = seed\n\n for (const character of value) {\n hash ^= character.codePointAt(0) ?? 0\n hash = Math.imul(hash, fnvPrime32)\n }\n\n return (hash >>> 0).toString(36).padStart(7, '0')\n}\n\nconst stableHash = (value: string) => {\n const first = fnv1a32(value, fnvOffsetBasis32)\n const second = fnv1a32([...value].reverse().join(''), fnvOffsetBasis32 ^ 0x9e3779b9)\n\n return `${first}${second}`\n}\n\nexport const makeVercelSandboxName = (sandboxSessionId: string) =>\n `sandbox-${stableHash(sandboxSessionId)}`\n"],"mappings":";AAAA,MAAM,mBAAmB;
|
|
1
|
+
{"version":3,"file":"name.mjs","names":[],"sources":["../src/name.ts"],"sourcesContent":["const fnvOffsetBasis32 = 0x811c9dc5\n\nconst fnvPrime32 = 0x01000193\n\nconst fnv1a32 = (value: string, seed: number) => {\n let hash = seed\n\n for (const character of value) {\n hash ^= character.codePointAt(0) ?? 0\n hash = Math.imul(hash, fnvPrime32)\n }\n\n return (hash >>> 0).toString(36).padStart(7, '0')\n}\n\nconst stableHash = (value: string) => {\n const first = fnv1a32(value, fnvOffsetBasis32)\n const second = fnv1a32([...value].reverse().join(''), fnvOffsetBasis32 ^ 0x9e3779b9)\n\n return `${first}${second}`\n}\n\nexport const makeVercelSandboxName = (sandboxSessionId: string) =>\n `sandbox-${stableHash(sandboxSessionId)}`\n"],"mappings":";AAAA,MAAM,mBAAmB;AAEzB,MAAM,aAAa;AAEnB,MAAM,WAAW,OAAe,SAAiB;CAC/C,IAAI,OAAO;CAEX,KAAK,MAAM,aAAa,OAAO;EAC7B,QAAQ,UAAU,YAAY,CAAC,KAAK;EACpC,OAAO,KAAK,KAAK,MAAM,UAAU;CACnC;CAEA,QAAQ,SAAS,GAAG,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG;AAClD;AAEA,MAAM,cAAc,UAAkB;CAIpC,OAAO,GAHO,QAAQ,OAAO,gBAGf,IAFC,QAAQ,CAAC,GAAG,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,mBAAmB,UAElD;AACzB;AAEA,MAAa,yBAAyB,qBACpC,WAAW,WAAW,gBAAgB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../../src/testing/index.ts"],"sourcesContent":["import { Effect, Layer, Option, Ref } from 'effect'\nimport type { SandboxCommandInput, SandboxCommandResult, SandboxState } from '../model.ts'\nimport { Sandbox } from '../service.ts'\nimport { SandboxStateStore } from '../state-store.ts'\nimport type { SandboxError } from '../errors.ts'\n\nexport type FakeSandboxRun = (\n input: SandboxCommandInput\n) => Effect.Effect<SandboxCommandResult, SandboxError>\n\nexport type FakeSandboxOptions = {\n readonly run: FakeSandboxRun\n readonly initialState?: SandboxState\n}\n\nexport const makeFakeSandboxLayer = (options: FakeSandboxOptions) =>\n Layer.effect(\n Sandbox,\n Ref.make(Option.fromNullishOr(options.initialState)).pipe(\n Effect.map(stateRef =>\n Sandbox.of({\n run: input =>\n options\n .run(input)\n .pipe(Effect.tap(result => Ref.set(stateRef, Option.some(result.state)))),\n currentState: Ref.get(stateRef),\n delete: Ref.set(stateRef, Option.none())\n })\n )\n )\n )\n\nexport type InMemorySandboxStateStoreEntry = {\n readonly sandboxSessionId: string\n readonly state: SandboxState\n}\n\nexport const makeInMemorySandboxStateStoreLayer = (\n initial: ReadonlyArray<InMemorySandboxStateStoreEntry> = []\n) =>\n Layer.effect(\n SandboxStateStore,\n Effect.gen(function* () {\n const states = yield* Ref.make(\n new Map(initial.map(entry => [entry.sandboxSessionId, entry.state]))\n )\n\n return SandboxStateStore.of({\n load: sandboxSessionId =>\n Ref.get(states).pipe(\n Effect.map(current => Option.fromNullishOr(current.get(sandboxSessionId)))\n ),\n save: input =>\n Ref.update(\n states,\n current => new Map([...current, [input.sandboxSessionId, input.state]])\n ),\n clear: sandboxSessionId =>\n Ref.update(states, current => {\n const next = new Map(current)\n next.delete(sandboxSessionId)\n return next\n })\n })\n })\n )\n"],"mappings":";;;;AAeA,MAAa,wBAAwB,YACnC,MAAM,OACJ,SACA,IAAI,KAAK,OAAO,cAAc,QAAQ,YAAY,CAAC,EAAE,KACnD,OAAO,KAAI,aACT,QAAQ,GAAG;CACT,MAAK,UACH,QACG,IAAI,KAAK,EACT,KAAK,OAAO,KAAI,WAAU,IAAI,IAAI,UAAU,OAAO,KAAK,OAAO,KAAK,CAAC,CAAC,CAAC;CAC5E,cAAc,IAAI,IAAI,QAAQ;CAC9B,QAAQ,IAAI,IAAI,UAAU,OAAO,KAAK,CAAC;AACzC,CAAC,CACH,CACF,CACF;AAOF,MAAa,sCACX,UAAyD,CAAC,MAE1D,MAAM,OACJ,mBACA,OAAO,IAAI,aAAa;CACtB,MAAM,SAAS,OAAO,IAAI,KACxB,IAAI,IAAI,QAAQ,KAAI,UAAS,CAAC,MAAM,kBAAkB,MAAM,KAAK,CAAC,CAAC,CACrE;CAEA,OAAO,kBAAkB,GAAG;EAC1B,OAAM,qBACJ,IAAI,IAAI,MAAM,EAAE,KACd,OAAO,KAAI,YAAW,OAAO,cAAc,QAAQ,IAAI,gBAAgB,CAAC,CAAC,CAC3E;EACF,OAAM,UACJ,IAAI,OACF,SACA,YAAW,IAAI,IAAI,CAAC,GAAG,SAAS,CAAC,MAAM,kBAAkB,MAAM,KAAK,CAAC,CAAC,CACxE;EACF,QAAO,qBACL,IAAI,OAAO,SAAQ,YAAW;GAC5B,MAAM,OAAO,IAAI,IAAI,OAAO;GAC5B,KAAK,OAAO,gBAAgB;
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../../src/testing/index.ts"],"sourcesContent":["import { Effect, Layer, Option, Ref } from 'effect'\nimport type { SandboxCommandInput, SandboxCommandResult, SandboxState } from '../model.ts'\nimport { Sandbox } from '../service.ts'\nimport { SandboxStateStore } from '../state-store.ts'\nimport type { SandboxError } from '../errors.ts'\n\nexport type FakeSandboxRun = (\n input: SandboxCommandInput\n) => Effect.Effect<SandboxCommandResult, SandboxError>\n\nexport type FakeSandboxOptions = {\n readonly run: FakeSandboxRun\n readonly initialState?: SandboxState\n}\n\nexport const makeFakeSandboxLayer = (options: FakeSandboxOptions) =>\n Layer.effect(\n Sandbox,\n Ref.make(Option.fromNullishOr(options.initialState)).pipe(\n Effect.map(stateRef =>\n Sandbox.of({\n run: input =>\n options\n .run(input)\n .pipe(Effect.tap(result => Ref.set(stateRef, Option.some(result.state)))),\n currentState: Ref.get(stateRef),\n delete: Ref.set(stateRef, Option.none())\n })\n )\n )\n )\n\nexport type InMemorySandboxStateStoreEntry = {\n readonly sandboxSessionId: string\n readonly state: SandboxState\n}\n\nexport const makeInMemorySandboxStateStoreLayer = (\n initial: ReadonlyArray<InMemorySandboxStateStoreEntry> = []\n) =>\n Layer.effect(\n SandboxStateStore,\n Effect.gen(function* () {\n const states = yield* Ref.make(\n new Map(initial.map(entry => [entry.sandboxSessionId, entry.state]))\n )\n\n return SandboxStateStore.of({\n load: sandboxSessionId =>\n Ref.get(states).pipe(\n Effect.map(current => Option.fromNullishOr(current.get(sandboxSessionId)))\n ),\n save: input =>\n Ref.update(\n states,\n current => new Map([...current, [input.sandboxSessionId, input.state]])\n ),\n clear: sandboxSessionId =>\n Ref.update(states, current => {\n const next = new Map(current)\n next.delete(sandboxSessionId)\n\n return next\n })\n })\n })\n )\n"],"mappings":";;;;AAeA,MAAa,wBAAwB,YACnC,MAAM,OACJ,SACA,IAAI,KAAK,OAAO,cAAc,QAAQ,YAAY,CAAC,EAAE,KACnD,OAAO,KAAI,aACT,QAAQ,GAAG;CACT,MAAK,UACH,QACG,IAAI,KAAK,EACT,KAAK,OAAO,KAAI,WAAU,IAAI,IAAI,UAAU,OAAO,KAAK,OAAO,KAAK,CAAC,CAAC,CAAC;CAC5E,cAAc,IAAI,IAAI,QAAQ;CAC9B,QAAQ,IAAI,IAAI,UAAU,OAAO,KAAK,CAAC;AACzC,CAAC,CACH,CACF,CACF;AAOF,MAAa,sCACX,UAAyD,CAAC,MAE1D,MAAM,OACJ,mBACA,OAAO,IAAI,aAAa;CACtB,MAAM,SAAS,OAAO,IAAI,KACxB,IAAI,IAAI,QAAQ,KAAI,UAAS,CAAC,MAAM,kBAAkB,MAAM,KAAK,CAAC,CAAC,CACrE;CAEA,OAAO,kBAAkB,GAAG;EAC1B,OAAM,qBACJ,IAAI,IAAI,MAAM,EAAE,KACd,OAAO,KAAI,YAAW,OAAO,cAAc,QAAQ,IAAI,gBAAgB,CAAC,CAAC,CAC3E;EACF,OAAM,UACJ,IAAI,OACF,SACA,YAAW,IAAI,IAAI,CAAC,GAAG,SAAS,CAAC,MAAM,kBAAkB,MAAM,KAAK,CAAC,CAAC,CACxE;EACF,QAAO,qBACL,IAAI,OAAO,SAAQ,YAAW;GAC5B,MAAM,OAAO,IAAI,IAAI,OAAO;GAC5B,KAAK,OAAO,gBAAgB;GAE5B,OAAO;EACT,CAAC;CACL,CAAC;AACH,CAAC,CACH"}
|