Docs / Workspaces

Workspaces

A workspace is a durable filesystem and work-state object. It is not owned by a single run or session.

Sessions attach to workspaces. Direct workspace operations also attach to workspaces without creating sessions. This lets a task finish while the workspace remains available for later inspection, another task invocation, or a direct command or terminal operation.

Lifecycle

Workspaces are scoped to a project and environment. Creating a workspace pins it to a deployed sandbox definition, so later execution uses the same sandbox contract.

The current user-facing lifecycle is:

ActionMeaning
CreateCreate a durable workspace from a deployed sandbox.
Retrieve/listRead workspace metadata and lifecycle state.
UpdateReplace user metadata and tags.
Read filesRead, list, or stat files from persisted ready versions.
MaterializeAsk Helmr to prepare a live VM/worker materialization for the workspace.
ConnectReturn the current live materialization, creating or requesting one when needed.
StopRequest controlled shutdown of the live materialization.
Delete/archiveRemove the workspace from normal use.

Materialization

A materialization is the live execution instance for a workspace. It is the bridge between durable workspace state and active execution.

Task runs, workspace execs, and PTY sessions use materializations when they need to execute code. If a workspace is not live, Helmr can request a materialization before dispatching the operation.

Files and Versions

Workspace file reads inspect persisted read-only version artifacts. They do not start a VM, request materialization, acquire a workspace lease, or run shell commands inside the workspace.

import { workspaces } from "@helmr/sdk"

const workspace = workspaces.open("workspace-id")
const bytes = await workspace.files.read("src/app.ts")
const entries = await workspace.files.list("src")
const stat = await workspace.files.stat("src/app.ts")

By default, file reads use source: "current" and read the workspace’s ready currentVersionId. To inspect a specific ready version from the same workspace, pass { source: "version", versionId }. source: "live" is reserved for future live file access and is not implemented.

const version = await workspace.versions.retrieve("version-id")
const versionBytes = await workspace.files.read("src/app.ts", {
  source: "version",
  versionId: version.id,
})

Exec

Workspace exec creates a durable command handle on a workspace:

import { workspaces } from "@helmr/sdk"

const workspace = workspaces.open("workspace-id")
const exec = await workspace.exec(["bash", "-lc", "echo ok"], {
  cwd: "/workspace",
})

The handle records command state, exit information, stdin cursor, stdout cursor, and stderr cursor. Stdout and stderr are durable stream chunks. Blocking helper methods can wait for terminal state, but the handle remains the source of truth.

Execs are write-capable in the current API. Read-only workspace exec is not part of the current documented contract.

PTY

Workspace PTY creates a durable interactive terminal handle:

const pty = await workspaces.open("workspace-id").pty.create({
  cwd: "/workspace",
  cols: 100,
  rows: 32,
})

The PTY handle records open/resize/close state and input/output cursors. Output can be read as durable chunks or followed over SSE.

Streams

Exec stdout/stderr and PTY output are cursor-based durable streams. Read APIs return chunks after a cursor. Follow APIs use server-sent events and reconnect from the last cursor.

Stream cursors are byte offsets, not page numbers. If a cursor is older than the retained stream window, the API returns a cursor-expired error with the earliest available cursor.

Runtime Directory

Tasks and direct workspace operations run inside the configured sandbox workspace mount path, usually /workspace. Use relative paths for workspace files. Absolute paths behave like normal Linux paths inside the sandbox image.

The workspace mount path is part of the sandbox definition. It must be absolute, cannot be /, cannot contain .., and cannot overlap Helmr-managed runtime paths such as /dev, /proc, /sys, /run, /tmp, or /opt/helmr.

Repository Access

Repository access is a task-level or command-level integration. Pass repository identifiers in payload and credentials through declared secrets or direct exec environment values. Workspace creation stays provider-neutral; tasks and commands decide which external systems to fetch from.