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.