viby

Previews and sandboxes

Sandboxes execute one immutable version. Previews add a durable lifecycle around a long-running sandbox process and its reachable URL.

Configure a sandbox and preview

const viby = createViby({
  framework: "farmjs",
  model,
  sandbox,
  sandboxPolicy: sandboxCommandPolicy({
    allowCommands: ["npm", "pnpm", "npx"],
    maxTimeoutMs: 120_000,
  }),
  preview: {
    prepare: [{ command: "pnpm", args: ["install", "--prefer-offline"] }],
    start: { command: "pnpm", args: ["dev", "--host", "0.0.0.0"] },
    port: 3000,
    environment: "preview",
    env: { CI: "1" },
    readiness: { path: "/", timeoutMs: 60_000 },
  },
});

The preview command is framework or product configuration. Viby does not infer package-manager or framework commands. env supplies safe host defaults to every preview; values passed to version.preview({ env }) override those defaults for that opening only.

Set generation.workspace: { preview: "eager" } to open the base version while a generation runs. The generation stream emits the preview URL as soon as preparation and readiness finish. Source edits, final dependency reconciliation, and quality checks continue in that same sandbox. After the new immutable version commits, Viby retargets the durable preview record without restarting the process or creating a second lease.

Capability discovery

Every adapter declares the same capability record:

  • files — materialize and read project files;
  • commands — run foreground commands;
  • commandStreaming — emit stdout/stderr while a command runs;
  • portUrls — resolve an externally reachable URL for a port;
  • backgroundProcesses — start, wait for, and kill long-running work;
  • reconnect — restore an adapter instance from a durable provider ID;
  • snapshots — provider snapshot support where implemented.

Use session.supports(name) instead of branching on the provider string.

SandboxCollection

MethodBehavior
get(leaseId)Loads one scoped durable lease record.
reconnect(leaseId, options?)Validates lease status and provider compatibility, reconnects the instance, and returns SandboxSession.

SandboxSession

MemberBehavior
id / provider / leaseIdProvider instance identity, adapter identity, and nullable durable Viby lease.
capabilities / supports(name)Normalized capability discovery.
stoppedWhether this session has been stopped locally.
writeFiles(files, options?)Writes normalized text or binary paths when file capability exists.
readFile(path, options?)Reads one file as Uint8Array.
authorizeCommand(command, action?)Evaluates policy and returns a grant or throws a typed denial/approval error.
run(command, grant?)Executes one bounded foreground command and returns exit code, output, and duration.
start(command, grant?)Starts a background process when supported.
url(port)Resolves a provider URL when supported.
waitForPort(port, options?)Polls readiness with an optional host-supplied check and returns the resolved URL.
stop(options?)Idempotently stops the provider instance and closes its durable lease.

Commands use separate command and args values. Policy receives the executable, arguments, working directory, environment variable names, timeout, action, and immutable version context; secret values are omitted.

Command policy

Policy returns allow, deny, or approval-required. sandboxCommandPolicy(options) is a convenient allow/deny implementation; applications may supply an async policy backed by their own authorization system.

approval-required throws SandboxCommandApprovalRequiredError with a serializable proposedAction. The default agent converts that proposal into a durable permission task. An approved action key can then be resumed safely without bypassing policy for unrelated commands.

PreviewCollection

MethodBehavior
get(id)Loads a scoped preview session.
list({ chatId?, versionId?, status? })Filters durable preview records.
cleanupExpired(limit?)Stops and marks a bounded set of expired sessions; intended for a host-owned schedule.

Preview

MemberBehavior
id, chatId, versionId, frameworkDurable ownership and source identity.
statusstarting, ready, failed, stopped, or expired.
urlProvider URL when ready, otherwise null.
data()Returns the complete durable preview record.
reconnect(signal?)Reconnects the underlying sandbox, re-runs readiness, and refreshes this handle. A non-aborted readiness failure stops the stale sandbox and persists failed.
stop(signal?)Idempotently stops the process/sandbox and persists stopped.

Starting a preview materializes source, starts the configured process, obtains a port URL, and waits for readiness. Any failure is persisted with a safe message before PreviewError is thrown.

Included sandbox adapters

Entry pointProvider/runtime note
@viby/sdk/sandbox/e2bE2B sandbox client; optional peer required.
@viby/sdk/sandbox/vercelVercel Sandbox; optional peer required.
@viby/sdk/sandbox/dockerLocal Docker CLI/daemon; intended for trusted local or single-tenant use.
@viby/sdk/sandbox/daytonaDaytona sandbox client; optional peer required.
@viby/sdk/sandbox/modalModal sandbox client; optional peer required.
@viby/sdk/sandbox/cloudflareCloudflare Worker binding and container runtime; optional peer required.

Use @viby/sdk/sandbox/conformance to verify a custom adapter against the provider-neutral lifecycle before using it with generated code.