SandboxProvider
A sandbox provider creates sandboxes on one platform, such as this machine or Daytona, and resumes sandboxes it created before. The settings a platform needs, such as credentials or a root directory, go to the provider’s layer, so code that creates sandboxes does not depend on which provider it uses.
Since v0.1.0
Constructors
Section titled “Constructors”The service over a provider’s create and resume, with createScoped derived from them, as
ChildProcessSpawner.make derives the rest of that service from spawn.
Example (A sandbox for one piece of work)
import { SandboxProvider } from "@amends-dev/sandbox"import { Effect } from "effect"
declare const create: SandboxProvider.SandboxProvider["Service"]["create"]declare const resume: SandboxProvider.SandboxProvider["Service"]["resume"]
const sandboxProvider = SandboxProvider.make({ create, resume })
// The sandbox is destroyed when the scope closes, however it closes.const program = Effect.scoped( Effect.gen(function* () { const sandbox = yield* sandboxProvider.createScoped() return sandbox.workingDirectory }))Signature
declare const make: (provider: Pick<SandboxProvider["Service"], "create" | "resume">) => SandboxProvider["Service"]Since v0.1.0
Options
Section titled “Options”CreateOptions (interface)
Section titled “CreateOptions (interface)”What a sandbox is created with: its id, the ports it exposes, the template that prepares it, the network policy it starts under, and what only its provider takes. Each has a default.
Signature
export interface CreateOptions<E> { /** * Names the new sandbox. Creating never looks a sandbox up, so an id already in use fails with * `AlreadyExistsError`. When omitted, the provider picks one. */ readonly id?: Sandbox.SandboxId
/** The ports to expose from the start; `Sandbox.exposePorts` exposes more later. */ readonly ports?: ReadonlyArray<Network.Port>
/** * Prepares the sandbox before `create` returns it. It may be given as `undefined`, as an agent's * `template` is when the agent needs no sandbox. */ readonly template?: Template.Template<E> | undefined
/** * The outbound network policy the sandbox starts under, `AllowAll` when omitted. It is in force * before `create` returns, so nothing run in the sandbox afterwards reaches further than it * allows; the template prepares the sandbox before it applies, as preparing may download what it * installs. Fails with `UnsupportedError`, creating nothing, when the provider cannot enforce the * policy, as `Sandbox.setNetworkPolicy` does. */ readonly networkPolicy?: Network.NetworkPolicy
/** What only one platform takes, under its provider's id, as `ProviderOptions` describes. */ readonly providerOptions?: ProviderOptions}Since v0.1.0
ProviderOptions
Section titled “ProviderOptions”What only one platform takes on a create, keyed by the provider’s id, as SandboxError.provider
names it, with JSON values: such as the snapshot a sandbox on Daytona starts from.
Details
A provider decodes its own entry and ignores the others, so one value can name several providers;
an entry that is not what the provider takes fails with InvalidOptionsError, creating nothing.
Example (The snapshot a sandbox on Daytona starts from)
import { SandboxProvider } from "@amends-dev/sandbox"import { Effect } from "effect"
const program = Effect.gen(function* () { const sandboxProvider = yield* SandboxProvider.SandboxProvider return yield* sandboxProvider.create({ providerOptions: { daytona: { snapshot: "python-3.13" } } })})Signature
declare const ProviderOptions: Schema.$Record<Schema.String, Schema.Codec<Schema.Json, Schema.Json, never, never>>Since v0.1.0
ProviderOptions (type alias)
Section titled “ProviderOptions (type alias)”Signature
type ProviderOptions = typeof ProviderOptions.TypeSince v0.1.0
Services
Section titled “Services”SandboxProvider (class)
Section titled “SandboxProvider (class)”Creates sandboxes on one platform and resumes the ones it created before.
Details
A program asks for the service and gets whichever provider’s layer it runs under. make builds
the service from a provider’s create and resume.
Example (Creating a sandbox, stopping it, and resuming it later)
import { Network, Sandbox, SandboxProvider } from "@amends-dev/sandbox"import { Effect, FileSystem, Path } from "effect"
const id = Sandbox.SandboxId.make("review-42")const port = Network.Port.make(3000)
const program = Effect.gen(function* () { const sandboxProvider = yield* SandboxProvider.SandboxProvider const sandbox = yield* sandboxProvider.create({ id, ports: [port] }) yield* Effect.gen(function* () { const fs = yield* FileSystem.FileSystem const path = yield* Path.Path yield* fs.writeFileString(path.join(sandbox.workingDirectory, "notes.md"), "# Review") }).pipe(Effect.provide(Sandbox.layerServices(sandbox))) yield* sandbox.stop
// Later, in this process or another: the files are still there, and so is the port. const resumed = yield* sandboxProvider.resume(id) const endpoint = yield* resumed.endpoint(port, "http") return endpoint.url})Signature
declare class SandboxProviderSince v0.1.0