/work like any directory, and changes autosave to a durable private workspace WAL. The server workspace is created lazily on the first WAL checkpoint. Autosave never creates a Git commit or updates a branch; snapshots and promotion remain deliberate. Read-only views create no private workspace.
Because durable WAL checkpoints, snapshots, operations, and mount heartbeats live on the server, your control plane can track workspace state across a fleet of sandboxes. See Observe Workspaces.
Directory mounts also automatically save your work and if your sandbox crashes, you can resume from the last auto-saved checkpoint.
Prerequisites
Install the Tensorlake CLI and choose an existing repository with a branch, tag, or full commit to mount. The destination directory must be empty; the CLI creates it if needed. For the SDK examples, use Node.js 22 or later, install thetensorlake npm package, and set TENSORLAKE_API_KEY. See Install and Configure. SDK mounts also require the separately installed CLI and appear on the machine running Node.js.
Install the file-system extension once on macOS. Linux needs no setup.
Choose a Mount
- CLI
- TypeScript
The command shape:
Writable Mounts (the Default)
- CLI
- TypeScript
/work is an ordinary writable directory based on the branch tip; name a different base with agent-outputs:<ref-or-full-commit>. Writes enter a crash-safe local journal and autosave to private server WAL; the branch does not change while the agent works. Workspace mounts can take a subtree too; snapshots record paths relative to the repository root.
Autosave WAL
Writable mounts autosave every 30 seconds. Each autosave uploads changed content and advances the workspace’s durable WAL checkpoint, but creates no Git commit and moves no branch. This is the recovery layer for an agent run: another machine can resume through the latest server checkpoint, while the same machine can additionally recover a newer unsealed tail from its local journal. Autosave is intentionally separate from Git history. Create a snapshot when the current state should become an attributable workspace commit.Read-Only Mounts
Use a read-only view to read repository content without creating a private workspace:- CLI
- TypeScript
- CLI
- TypeScript
- CLI
- TypeScript
await view.unmount() when you finish.
Subtree and commit forms combine: agent-outputs:9f2a1c8e4d6b1a0f3c7e9d2b8a4f6c1e0d3b7a99//services/auth.
Snapshot Changes
- CLI
- TypeScript
- CLI
- TypeScript
Promote to a Branch
- CLI
- TypeScript
--merge, or pass { merge: true } to mount.promote(), to land a two-parent merge instead. See Merging Changes for conflict reports and the resolve loop.
Activity history shows who published the promotion and which workspace it came from.
Rebase a Workspace
When the branch has moved and you want the workspace replayed on top of it (a linear history instead of a merge), rebase it onto a target ref or commit:- CLI
- TypeScript
--fail-on-conflict, or pass { failOnConflict: true } to mount.rebase(), to report conflicts without materializing markers into the workspace.
Refresh a Mount
Refresh the current source, or switch a workspace without snapshots to another branch, tag, or full commit:- CLI
- TypeScript
Prefetch Files
Download and verify the mounted working set so subsequent reads do not need to fetch file content. Make sure the machine has enough local disk for that content.- CLI
- TypeScript
Check Status
- CLI
- TypeScript
status() also returns path, repository, and reference, with the complete CLI JSON in raw. repos.mountStatus() defaults to the mount containing the current directory.
Daemon and credential diagnostics follow those lines; they are for support, not for the workflow.
With unsealed changes, status reports how many paths are dirty and makes snapshotting the next valid transition:
workspace_clean, workspace_target_advanced (the branch moved past your base), read_only_following, read_only_pinned, source_ref_deleted, and server_unreachable_stale_view for a mount that cannot currently reach the server. Add --json for machine-readable output.
Observe Workspaces
Durable workspace state is server-side, so you can inspect a fleet without touching its sandboxes. List workspace WAL, snapshot, and attachment state first:tl git smartlog shows every branch, tag, workspace, and snapshot chain and how they sit relative to each other:
tl git log shows one mount’s own workspace snapshot chain; tl git smartlog --project widens the view to the whole project. The same graph is in the dashboard’s repository page, with each workspace’s snapshot chain and actor attribution. Every snapshot, promote, rebase, and merge is also a durable entry in the repository’s activity history: the audit trail of what your agents did, queryable long after the sandboxes are gone.
Live mounts also report a liveness heartbeat (that a mount exists, where it’s mounted, and that it’s still alive) so the control plane can tell which sessions are active. Fine-grained edits remain local until autosave; durable WAL checkpoints report progress without exposing every in-progress edit.
Reattach a Workspace
The mount path is disposable. The workspace is the resumable state behind it. Unmounting keeps the workspace by default:- CLI
- TypeScript
--workspace takes the full workspace id (tl git workspaces <repo> lists them; mount and status print an abbreviation):
- CLI
- TypeScript
status.workspaceId after the first autosaved write or snapshot to resume later. It is null before a private workspace exists, and stays null for read-only views.
A workspace that already has a live writable mount refuses a second mount. Unmount it there first to take writes.
Delete a Workspace
Delete the workspace while unmounting when its history is no longer needed:- CLI
- TypeScript
tl git unmount /work --discard, or mount.unmount({ discard: true }), to drop unpublished local state.
Detached workspaces are also collected automatically. By default, a WAL-only workspace is retained for 48 hours and a workspace with snapshots for 14 days. An actively mounted workspace is retained. These periods are deployment configuration, so use explicit deletion when your application requires deterministic cleanup.
What a Mount Is Not
- Not a Git checkout. There is no
.gitdirectory inside a mount, andgitcommands do not run there. The verbs on this page are the interface; see Git or the tl CLI? for how they map onto Git habits.tl git cloneexists when you need a real clone. - Not auto-publishing. A repository mount autosaves to private workspace WAL, but autosave never creates a commit or changes a branch. For a shared directory whose autosave windows periodically advance the common state, use a file system.
- Not fully offline. Cached content and the crash-safe local journal can remain usable during a disconnection. Fetching uncached content and making work remotely durable require reconnection.
Errors
SDK CLI discovery failures raiseCliNotFoundError. Failed CLI operations and malformed status JSON raise MountError. Both errors are exported from tensorlake. The SDK passes its selected API key and API URL to the CLI and looks for TENSORLAKE_CLI, tl on PATH, then ~/.tensorlake/bin/tl. SDK mounts require an API key even if you previously authenticated the CLI with a personal access token.
Next Steps
Merging Changes
Land workspaces on moved branches, resolve conflicts, and merge branches directly.
Architecture
Learn how promotion and merge conflict handling work internally.