Skip to main content
Filesystems are persistent storage objects that tasks mount at /workspace. The critical thing to understand is that Terminal Use exposes three different file flows.

Choose The Right File Flow

GoalUse thisDo not use
Upload or download the whole filesystemtu fs push, tu fs pull, getUploadUrl, getDownloadUrluploadFile, downloadFile
Upload or download one file by pathuploadFile, download_file, downloadFile, getFilegetUploadUrl, getDownloadUrl
Sync /workspace inside a running agentPython ADK adk.filesystem.sync_down and sync_upCLI or TypeScript SDK

Resource Operations

OperationDescription
Create FilesystemCreate a new filesystem in a project
List FilesystemsList filesystems you can access
Get FilesystemRetrieve filesystem metadata
List FilesList file metadata from the filesystem manifest
Get FileRetrieve one file’s metadata or embedded content
Single-File DownloadDownload one file as binary content
Upload FileUpload one file with overwrite or conditional semantics
Get Upload URLGet a presigned URL for whole-filesystem archive upload
Get Download URLGet a presigned URL for whole-filesystem archive download
Complete SyncInternal/archive sync completion API used by higher-level sync flows

Whole-Filesystem Archive Flow

This is the flow for syncing an entire filesystem as a compressed archive.

CLI

tu fs push <filesystem_id> ./local-directory
tu fs pull <filesystem_id> ./local-directory
The CLI handles archive creation and extraction for you.

TypeScript

const { url } = await client.filesystems.getUploadUrl({
  filesystem_id: 'fs_123',
  body: {},
});

await fetch(url, {
  method: 'PUT',
  body: archiveBuffer,
  headers: {
    'Content-Type': 'application/zstd',
  },
});

Python

from terminaluse import AsyncTerminalUse, PresignedUrlRequest
import httpx

client = AsyncTerminalUse(token="your_api_key")

upload = await client.filesystems.get_upload_url(
    filesystem_id=filesystem_id,
    request=PresignedUrlRequest(),
)

async with httpx.AsyncClient() as http:
    await http.put(
        upload.url,
        content=archive_bytes,
        headers={"Content-Type": "application/zstd"},
    )
get_upload_url and get_download_url are archive-level operations. They are not single-file APIs.

Single-File Flow

Use this when your app needs to read or write one path without rebuilding the whole archive.

TypeScript

await client.filesystems.uploadFile(
  new TextEncoder().encode('# report\\n'),
  'fs_123',
  {
    path: 'output/report.md',
  },
);

const binary = await client.filesystems.downloadFile({
  filesystem_id: 'fs_123',
  path: 'output/report.md',
});

Python

await client.filesystems.upload_file(
    filesystem_id,
    path="output/report.md",
    request=b"# report\n",
)

chunks = client.filesystems.download_file(
    filesystem_id,
    path="output/report.md",
)
For metadata-only reads, use list_files or get_file.

In-Agent Runtime Sync

This flow is for code already running inside the agent runtime. It is a Python ADK surface, not a CLI surface and not a TypeScript SDK surface.
from terminaluse.lib import adk

await adk.filesystem.sync_down(filesystem_id=ctx.task.filesystem_id)

# work inside /workspace

await adk.filesystem.sync_up(filesystem_id=ctx.task.filesystem_id)
See Filesystem Sync.

Read-Only Workspace Behavior

The mounted filesystem is not always writable. If a caller can run the task and read the filesystem but cannot update the filesystem, Terminal Use mounts /workspace read-only for that task. See Access Control.