distilled-daytona
v0.1.0
Published
Effect-native SDK for the Daytona control-plane API
Readme
distilled-daytona
Effect-native Daytona SDK with a curated, scoped runtime and complete generated escape hatches.
- 184 control-plane operations across all 150 API paths
- 103 Toolbox HTTP operations across all 92 paths
- typed request, transport, timeout, parse, HTTP, and daemon failures
- safe, operation-aware retries and per-call options
- sandbox lifecycle polling with one total timeout budget
- true streaming file transfer and scoped PTY/interpreter/log WebSockets
Installation
npm install distilled-daytona effectHigh-level Daytona client
import { Effect } from "effect"
import * as Daytona from "distilled-daytona/Daytona"
const program = Effect.gen(function* () {
const sandbox = yield* Daytona.create({ name: "example" })
yield* Effect.log(`started ${sandbox.id}`)
return yield* Daytona.stop(sandbox)
})
await Effect.runPromise(
program.pipe(
Effect.provide(Daytona.live({
apiKey: "your-api-key",
target: "us",
})),
),
)Daytona.layerWith leaves HttpClient.HttpClient injectable. Daytona.live and Daytona.liveFromEnv provide Effect's Fetch transport.
The high-level service exposes immutable sandbox values, create/get/list streams, lifecycle operations, state polling, sandbox-bound Toolbox layers, and curated snapshot, volume, and secret services.
Configuration
API-key and JWT authentication are first-class:
Daytona.live({ apiKey: "...", target: "us" })
Daytona.live({
jwtToken: "...",
organizationId: "org-id",
target: "us",
})Environment layers read configuration through Effect Config:
DAYTONA_API_KEY, or bothDAYTONA_JWT_TOKENandDAYTONA_ORGANIZATION_IDDAYTONA_API_URL(defaults tohttps://app.daytona.io/api)DAYTONA_TARGET(optional default for sandbox creation)
Configuration is validated when the layer is acquired and fails with ConfigError; missing configuration is not converted into a defect.
Raw operations
Every generated route remains available:
import { getSandbox } from "distilled-daytona/operations"
import * as Raw from "distilled-daytona/Raw"Raw calls require both credentials and HttpClient.HttpClient in their Effect environment. Their error channels include global HTTP errors, request validation, response parsing, timeouts, and Effect HTTP transport/body failures.
Generated metadata classifies calls as safe, idempotent, or unsafe. Unsafe mutations are not retried by default. Per-call retry of an unsafe operation requires an idempotency key:
operation(input, {
retry: { while: () => true },
idempotencyKey: "request-123",
timeout: "30 seconds",
})Toolbox
Toolbox credentials are explicitly bound to one sandbox:
import { Effect } from "effect"
import * as Files from "distilled-daytona/Files"
import * as ToolboxCredentials from "distilled-daytona/Toolbox/Credentials"
const bytes = Files.downloadBytes("/home/daytona/report.pdf").pipe(
Effect.provide(
ToolboxCredentials.layer({
apiKey: "...",
sandboxId: "sandbox-id",
toolboxProxyUrl: "https://proxy.app.daytona.io/toolbox",
}),
),
)Curated entry points include:
Files: backpressured downloads, incremental multipart bulk decoding, byte helpers, and raw streaming uploadsProcessandSession: one-shot execution and scoped background sessionsPty: scoped interactive terminals with output streams, input, resize, kill, and waitInterpreter: typed stdout/stderr/error/control event streamsGit: repository-bound operationsLsp: project/language-bound operationsComputerUse: grouped display, mouse, keyboard, recording, process, and recursive accessibility APIs
WebSocket protocols use an injected transport from distilled-daytona/WebSocket. Connections are scoped and close on interruption or scope finalization.
Images and signed URLs
distilled-daytona/Image provides an immutable Dockerfile DSL. Local build context upload is capability-based: provide Image.Context.Store to hash/archive/upload entries using temporary credentials, keeping Node-only filesystem and object-storage dependencies out of the browser-safe base package.
distilled-daytona/SignedUrls computes cross-runtime HMAC download/upload URLs and caches signing keys for 15 seconds with Effect Cache. Rotating a key updates the cache immediately.
distilled-daytona/Telemetry exposes latest Toolbox metrics and historical control-plane metrics, with an optional adapter for the separately distributed Analytics API.
Regeneration
Pinned specifications live in specs/openapi.yaml and specs/toolbox-openapi.json.
bun run generate
bun run check
bun run buildGeneration is atomic, validates exact operation/export counts, aggregates generation failures, and treats required patch drift as fatal. Do not hand-edit generated files under src/operations/ or src/toolbox/operations/.
Releasing
From a clean Jujutsu working copy directly on main, run:
bun run release patch # or minor, major, or an exact versionThe release script fetches origin, verifies that local and remote main agree, updates package.json, runs the release checks, creates a chore: release vX.Y.Z commit and matching tag, and pushes both. Tangled CI publishes tags matching v* after independently checking the tag against the package version.
The first 0.1.0 release can be created with bun run release 0.1.0.
License
Apache-2.0
