Capsa is experimental software. APIs may change without notice.
Skip to content

Working with Files

The agent provides direct file operations and sandboxes support automatic directory sharing.

Agent File Operations

Reading Files

Read file contents as bytes:

rust,no_run
let data = agent.read_file("/etc/hostname").await?;
let hostname = String::from_utf8_lossy(&data);
println!("Hostname: {}", hostname.trim());

Writing Files

Write bytes to a file:

rust,no_run
agent.write_file("/tmp/config.json", br#"{"debug": true}"#).await?;

// Write string content
let content = "Hello, world!\n";
agent.write_file("/tmp/greeting.txt", content.as_bytes()).await?;

Checking Existence

Check if a path exists:

rust,no_run
if agent.exists("/tmp/output.txt").await? {
    let data = agent.read_file("/tmp/output.txt").await?;
    println!("Output: {}", String::from_utf8_lossy(&data));
} else {
    println!("No output file generated");
}

Listing Directories

List directory contents:

rust,no_run
let entries = agent.list_dir("/tmp").await?;

for entry in entries {
    let kind = if entry.is_dir { "dir" } else { "file" };
    println!("{}: {}", kind, entry.name);
}

Shared Directories

For high-performance file access, share host directories with the sandbox using virtio-fs.

Basic Sharing

rust,no_run
let vm = capsa::sandbox()
    .share("./workspace", "/mnt/workspace", AccessMode::ReadWrite)
    .build()
    .await?;

The host directory ./workspace is automatically mounted at /mnt/workspace inside the sandbox.

Access Modes

Control read/write permissions:

rust,no_run
let vm = capsa::sandbox()
    // Read-only: sandbox can read but not modify
    .share("./source", "/src", AccessMode::ReadOnly)
    // Read-write: sandbox can read and modify
    .share("./output", "/out", AccessMode::ReadWrite)
    .build()
    .await?;

Multiple Shares

Share multiple directories:

rust,no_run
let vm = capsa::sandbox()
    .share("./project", "/project", AccessMode::ReadOnly)
    .share("./data", "/data", AccessMode::ReadOnly)
    .share("./artifacts", "/artifacts", AccessMode::ReadWrite)
    .build()
    .await?;

When to Use Each Approach

ApproachBest For
agent.read_file() / write_file()Small files, one-off operations
Shared directoriesLarge files, frequent access, bulk operations

Example: Processing Large Data

rust,no_run
// Share data directory for bulk access
let vm = capsa::sandbox()
    .share("./large-dataset", "/data", AccessMode::ReadOnly)
    .share("./results", "/results", AccessMode::ReadWrite)
    .build()
    .await?;

let agent = vm.agent().await?;

// Process data using shared directories (fast)
let result = agent.exec("python3")
    .args(["/data/process.py", "--input", "/data", "--output", "/results"])
    .run()
    .await?;

// Read small result file via agent (convenient)
let summary = agent.read_file("/results/summary.json").await?;

File Operation Patterns

Create Directory Structure

rust,no_run
agent.exec("/bin/sh").args(["-c", "mkdir -p /tmp/project/{src,build,test}"]).run().await?;

Copy Files

rust,no_run
agent.exec("/bin/sh").args(["-c", "cp /mnt/templates/* /tmp/project/"]).run().await?;

Read Config, Write Results

rust,no_run
// Write config
let config = r#"{"workers": 4, "timeout": 30}"#;
agent.write_file("/tmp/config.json", config.as_bytes()).await?;

// Run processing
agent.exec("process").args(["--config", "/tmp/config.json"]).run().await?;

// Read results
let results = agent.read_file("/tmp/results.json").await?;
let results_str = String::from_utf8_lossy(&results);
println!("Results: {}", results_str);

Complete Example

rust,no_run
use capsa::AccessMode;
use std::collections::HashMap;

async fn build_project() -> capsa::Result<()> {
    // Create sandbox with source code
    let vm = capsa::sandbox()
        .cpus(4)
        .memory_mb(4096)
        .share("./src", "/src", AccessMode::ReadOnly)
        .share("./build", "/build", AccessMode::ReadWrite)
        .build()
        .await?;

    let agent = vm.agent().await?;

    // Write build script
    agent.write_file("/tmp/build.sh", br#"#!/bin/sh
cd /src
cargo build --release
cp target/release/myapp /build/
"#).await?;

    // Make executable and run
    agent.exec("chmod").args(["+x", "/tmp/build.sh"]).run().await?;
    let result = agent.exec("/tmp/build.sh").run().await?;

    if result.exit_code == 0 {
        println!("Build successful!");
        // Binary is now in ./build/myapp on host
    } else {
        eprintln!("Build failed: {}", result.stderr);
    }

    vm.shutdown().await?;
    Ok(())
}

Next Steps

Released under the MIT License.