> ## Documentation Index
> Fetch the complete documentation index at: https://docs.microsandbox.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Filesystem

> Rust SDK - Filesystem API reference

Read, write, list, and manipulate files inside a running sandbox. Obtained via [`sb.fs()`](/sdk/rust/sandbox#sb-fs). Every op dispatches through the same host-guest channel as command execution, so there is no SSH and no network involved. For bulk file movement, prefer a [volume](/sdk/rust/volumes) that gives the guest direct filesystem access. See [Filesystem](/sandboxes/filesystem) for conceptual usage.

<p className="msb-label" id="typical-flow">Typical flow</p>

```rust theme={null}
use microsandbox::Sandbox;

let sb = Sandbox::builder("api").image("python").create().await?;
let fs = sb.fs();

fs.write("/tmp/config.json", r#"{"debug": true}"#).await?;
let text = fs.read_to_string("/tmp/config.json").await?;
println!("{text}");

for entry in fs.list("/tmp").await? {
    println!("{} ({} bytes)", entry.path, entry.size);
}
```

`sb.fs()` is synchronous and just borrows the sandbox's backend and name; the work happens on the `await`ed methods below, every one of which is `async`.

## Read operations

#### <span className="msb-recv">fs.</span><span className="msb-hn">read()</span>

```rust theme={null}
async fn read(&self, path: &str) -> MicrosandboxResult<Bytes>
```

<Accordion title="Example">
  ```rust theme={null}
  let bytes = sb.fs().read("/app/logo.png").await?;
  println!("{} bytes", bytes.len());
  ```
</Accordion>

Read an entire file from the guest filesystem into memory as raw bytes.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>path</code><span className="msb-type">\&str</span></div>
    <div className="msb-param-desc">Absolute path inside the guest, e.g. <code>"/app/config.json"</code>.</div>
  </div>
</div>

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><span className="msb-type">Bytes</span></div>
    <div className="msb-param-desc">File contents as raw bytes.</div>
  </div>
</div>

#### <span className="msb-recv">fs.</span><span className="msb-hn">read\_to\_string()</span>

```rust theme={null}
async fn read_to_string(&self, path: &str) -> MicrosandboxResult<String>
```

<Accordion title="Example">
  ```rust theme={null}
  let text = sb.fs().read_to_string("/etc/hostname").await?;
  println!("{}", text.trim());
  ```
</Accordion>

Read an entire file and decode it as UTF-8. Errors if the contents are not valid UTF-8.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>path</code><span className="msb-type">\&str</span></div>
    <div className="msb-param-desc">Absolute path inside the guest.</div>
  </div>
</div>

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><span className="msb-type">String</span></div>
    <div className="msb-param-desc">File contents as a UTF-8 string.</div>
  </div>
</div>

#### <span className="msb-recv">fs.</span><span className="msb-hn">read\_stream()</span>

```rust theme={null}
async fn read_stream(&self, path: &str) -> MicrosandboxResult<FsReadStream>
```

<Accordion title="Example">
  ```rust theme={null}
  let mut stream = sb.fs().read_stream("/var/log/big.log").await?;
  let mut total = 0;
  while let Some(chunk) = stream.recv().await? {
      total += chunk.len();
  }
  println!("read {total} bytes");
  ```
</Accordion>

Open a streaming reader that yields chunks of file data as they arrive. Use this for files too large to hold in memory, or to process data incrementally.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>path</code><span className="msb-type">\&str</span></div>
    <div className="msb-param-desc">Absolute path inside the guest.</div>
  </div>
</div>

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><a className="msb-type" href="#fsreadstream">FsReadStream</a></div>
    <div className="msb-param-desc">Reader that yields chunks until the file is exhausted.</div>
  </div>
</div>

## Write operations

#### <span className="msb-recv">fs.</span><span className="msb-hn">write()</span>

```rust theme={null}
async fn write(&self, path: &str, data: impl AsRef<[u8]>) -> MicrosandboxResult<()>
```

<Accordion title="Example">
  ```rust theme={null}
  sb.fs().write("/tmp/hello.txt", "hi there").await?;
  ```
</Accordion>

Write data to a file in the guest, creating it if it doesn't exist and truncating it if it does. Parent directories must already exist.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>path</code><span className="msb-type">\&str</span></div>
    <div className="msb-param-desc">Absolute path inside the guest.</div>
  </div>

  <div className="msb-param">
    <div className="msb-param-key"><code>data</code><span className="msb-type">impl AsRef\<\[u8]></span></div>
    <div className="msb-param-desc">File content (bytes or a string).</div>
  </div>
</div>

#### <span className="msb-recv">fs.</span><span className="msb-hn">write\_stream()</span>

```rust theme={null}
async fn write_stream(&self, path: &str) -> MicrosandboxResult<FsWriteSink>
```

<Accordion title="Example">
  ```rust theme={null}
  let sink = sb.fs().write_stream("/tmp/out.bin").await?;
  sink.write(&[0u8; 4096]).await?;
  sink.write(&[1u8; 4096]).await?;
  sink.close().await?;
  ```
</Accordion>

Open a streaming writer for large files. Write chunks incrementally, then call [`FsWriteSink::close()`](#fswritesink) to flush and finalize. The file is created if missing and truncated if it exists.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>path</code><span className="msb-type">\&str</span></div>
    <div className="msb-param-desc">Absolute path inside the guest.</div>
  </div>
</div>

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><a className="msb-type" href="#fswritesink">FsWriteSink</a></div>
    <div className="msb-param-desc">Writer for sending chunks; must be closed to finalize.</div>
  </div>
</div>

## Directory operations

#### <span className="msb-recv">fs.</span><span className="msb-hn">list()</span>

```rust theme={null}
async fn list(&self, path: &str) -> MicrosandboxResult<Vec<FsEntry>>
```

<Accordion title="Example">
  ```rust theme={null}
  for entry in sb.fs().list("/app").await? {
      println!("{:?} {}", entry.kind, entry.path);
  }
  ```
</Accordion>

List the immediate children of a directory (non-recursive). Each entry carries its path, kind, size, mode, and modification time.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>path</code><span className="msb-type">\&str</span></div>
    <div className="msb-param-desc">Absolute directory path inside the guest.</div>
  </div>
</div>

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><a className="msb-type" href="#fsentry">Vec\<FsEntry></a></div>
    <div className="msb-param-desc">Directory entries.</div>
  </div>
</div>

#### <span className="msb-recv">fs.</span><span className="msb-hn">mkdir()</span>

```rust theme={null}
async fn mkdir(&self, path: &str) -> MicrosandboxResult<()>
```

<Accordion title="Example">
  ```rust theme={null}
  sb.fs().mkdir("/app/data/cache").await?;
  ```
</Accordion>

Create a directory, including any missing parent directories.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>path</code><span className="msb-type">\&str</span></div>
    <div className="msb-param-desc">Absolute directory path inside the guest.</div>
  </div>
</div>

#### <span className="msb-recv">fs.</span><span className="msb-hn">remove\_dir()</span>

```rust theme={null}
async fn remove_dir(&self, path: &str) -> MicrosandboxResult<()>
```

<Accordion title="Example">
  ```rust theme={null}
  sb.fs().remove_dir("/app/data/cache").await?;
  ```
</Accordion>

Remove a directory and everything under it, recursively. For a single file use [`remove()`](#fs-remove).

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>path</code><span className="msb-type">\&str</span></div>
    <div className="msb-param-desc">Absolute directory path inside the guest.</div>
  </div>
</div>

## File operations

#### <span className="msb-recv">fs.</span><span className="msb-hn">remove()</span>

```rust theme={null}
async fn remove(&self, path: &str) -> MicrosandboxResult<()>
```

<Accordion title="Example">
  ```rust theme={null}
  sb.fs().remove("/tmp/hello.txt").await?;
  ```
</Accordion>

Delete a single file. Use [`remove_dir()`](#fs-remove_dir) for directories.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>path</code><span className="msb-type">\&str</span></div>
    <div className="msb-param-desc">Absolute file path inside the guest.</div>
  </div>
</div>

#### <span className="msb-recv">fs.</span><span className="msb-hn">copy()</span>

```rust theme={null}
async fn copy(&self, from: &str, to: &str) -> MicrosandboxResult<()>
```

<Accordion title="Example">
  ```rust theme={null}
  sb.fs().copy("/app/config.json", "/app/config.bak.json").await?;
  ```
</Accordion>

Copy a file from one path to another within the sandbox.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>from</code><span className="msb-type">\&str</span></div>
    <div className="msb-param-desc">Source path inside the guest.</div>
  </div>

  <div className="msb-param">
    <div className="msb-param-key"><code>to</code><span className="msb-type">\&str</span></div>
    <div className="msb-param-desc">Destination path inside the guest.</div>
  </div>
</div>

#### <span className="msb-recv">fs.</span><span className="msb-hn">rename()</span>

```rust theme={null}
async fn rename(&self, from: &str, to: &str) -> MicrosandboxResult<()>
```

<Accordion title="Example">
  ```rust theme={null}
  sb.fs().rename("/tmp/draft.txt", "/tmp/final.txt").await?;
  ```
</Accordion>

Rename or move a file or directory within the sandbox.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>from</code><span className="msb-type">\&str</span></div>
    <div className="msb-param-desc">Current path inside the guest.</div>
  </div>

  <div className="msb-param">
    <div className="msb-param-key"><code>to</code><span className="msb-type">\&str</span></div>
    <div className="msb-param-desc">New path inside the guest.</div>
  </div>
</div>

## Metadata

#### <span className="msb-recv">fs.</span><span className="msb-hn">stat()</span>

```rust theme={null}
async fn stat(&self, path: &str) -> MicrosandboxResult<FsMetadata>
```

<Accordion title="Example">
  ```rust theme={null}
  let meta = sb.fs().stat("/app/config.json").await?;
  println!("{} bytes, mode {:o}", meta.size, meta.mode);
  ```
</Accordion>

Get metadata for a file or directory: kind, size, mode, read-only flag, and timestamps. A final symlink is followed (equivalent to `stat_with_follow(path, true)`); use [`stat_with_follow()`](#fs-stat_with_follow) to control that.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>path</code><span className="msb-type">\&str</span></div>
    <div className="msb-param-desc">Absolute path inside the guest.</div>
  </div>
</div>

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><a className="msb-type" href="#fsmetadata">FsMetadata</a></div>
    <div className="msb-param-desc">File metadata.</div>
  </div>
</div>

#### <span className="msb-recv">fs.</span><span className="msb-hn">stat\_with\_follow()</span>

```rust theme={null}
async fn stat_with_follow(&self, path: &str, follow_symlink: bool) -> MicrosandboxResult<FsMetadata>
```

<Accordion title="Example">
  ```rust theme={null}
  let link_meta = sb.fs().stat_with_follow("/app/current", false).await?;
  println!("{:?}", link_meta.kind);
  ```
</Accordion>

Get metadata, choosing whether to follow a final symlink. With `follow_symlink = false` you stat the link itself rather than its target. Local backend only; cloud returns `Unsupported`.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>path</code><span className="msb-type">\&str</span></div>
    <div className="msb-param-desc">Absolute path inside the guest.</div>
  </div>

  <div className="msb-param">
    <div className="msb-param-key"><code>follow\_symlink</code><span className="msb-type">bool</span></div>
    <div className="msb-param-desc">When <code>false</code>, stat the symlink itself instead of its target.</div>
  </div>
</div>

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><a className="msb-type" href="#fsmetadata">FsMetadata</a></div>
    <div className="msb-param-desc">File metadata.</div>
  </div>
</div>

#### <span className="msb-recv">fs.</span><span className="msb-hn">set\_stat()</span>

```rust theme={null}
async fn set_stat(&self, path: &str, follow_symlink: bool, attrs: FsSetAttrs) -> MicrosandboxResult<()>
```

<Accordion title="Example">
  ```rust theme={null}
  use microsandbox::sandbox::FsSetAttrs;

  sb.fs().set_stat("/app/run.sh", true, FsSetAttrs {
      mode: Some(0o755),
      ..Default::default()
  }).await?;
  ```
</Accordion>

Update metadata on a file or directory: mode, owner uid/gid, size, and access/modification times. Only the fields you set on [`FsSetAttrs`](#fssetattrs) are applied. Local backend only; cloud returns `Unsupported`.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>path</code><span className="msb-type">\&str</span></div>
    <div className="msb-param-desc">Absolute path inside the guest.</div>
  </div>

  <div className="msb-param">
    <div className="msb-param-key"><code>follow\_symlink</code><span className="msb-type">bool</span></div>
    <div className="msb-param-desc">When <code>false</code>, target the symlink itself instead of its target.</div>
  </div>

  <div className="msb-param">
    <div className="msb-param-key"><code>attrs</code><a className="msb-type" href="#fssetattrs">FsSetAttrs</a></div>
    <div className="msb-param-desc">Attributes to change; unset fields are left untouched.</div>
  </div>
</div>

#### <span className="msb-recv">fs.</span><span className="msb-hn">read\_link()</span>

```rust theme={null}
async fn read_link(&self, path: &str) -> MicrosandboxResult<String>
```

<Accordion title="Example">
  ```rust theme={null}
  let target = sb.fs().read_link("/app/current").await?;
  println!("-> {target}");
  ```
</Accordion>

Read the target of a symbolic link, returning the literal target text. Local backend only; cloud returns `Unsupported`.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>path</code><span className="msb-type">\&str</span></div>
    <div className="msb-param-desc">Absolute path of the symlink inside the guest.</div>
  </div>
</div>

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><span className="msb-type">String</span></div>
    <div className="msb-param-desc">The link's target path.</div>
  </div>
</div>

#### <span className="msb-recv">fs.</span><span className="msb-hn">symlink()</span>

```rust theme={null}
async fn symlink(&self, target: &str, link_path: &str) -> MicrosandboxResult<()>
```

<Accordion title="Example">
  ```rust theme={null}
  sb.fs().symlink("/app/releases/v2", "/app/current").await?;
  ```
</Accordion>

Create a symbolic link at `link_path` that points to `target`. Local backend only; cloud returns `Unsupported`.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>target</code><span className="msb-type">\&str</span></div>
    <div className="msb-param-desc">What the link points to (literal target text).</div>
  </div>

  <div className="msb-param">
    <div className="msb-param-key"><code>link\_path</code><span className="msb-type">\&str</span></div>
    <div className="msb-param-desc">Absolute path of the symlink to create.</div>
  </div>
</div>

#### <span className="msb-recv">fs.</span><span className="msb-hn">exists()</span>

```rust theme={null}
async fn exists(&self, path: &str) -> MicrosandboxResult<bool>
```

<Accordion title="Example">
  ```rust theme={null}
  if sb.fs().exists("/app/config.json").await? {
      println!("config present");
  }
  ```
</Accordion>

Check whether a file or directory exists at the given path in the guest. Implemented as a `stat()` probe: a successful stat yields `true`, a filesystem-op error yields `false`, and transport errors still propagate.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>path</code><span className="msb-type">\&str</span></div>
    <div className="msb-param-desc">Absolute path inside the guest.</div>
  </div>
</div>

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><span className="msb-type">bool</span></div>
    <div className="msb-param-desc"><code>true</code> if the path exists.</div>
  </div>
</div>

## Host transfer

#### <span className="msb-recv">fs.</span><span className="msb-hn">copy\_from\_host()</span>

```rust theme={null}
async fn copy_from_host(&self, host_path: impl AsRef<Path>, guest_path: &str) -> MicrosandboxResult<()>
```

<Accordion title="Example">
  ```rust theme={null}
  sb.fs().copy_from_host("./local/model.bin", "/app/model.bin").await?;
  ```
</Accordion>

Copy a file from the host machine into the sandbox, streaming it in chunks. For transferring many files, consider a [bind-mounted volume](/sdk/rust/volumes) instead.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>host\_path</code><span className="msb-type">impl AsRef\<Path></span></div>
    <div className="msb-param-desc">Path on the host filesystem.</div>
  </div>

  <div className="msb-param">
    <div className="msb-param-key"><code>guest\_path</code><span className="msb-type">\&str</span></div>
    <div className="msb-param-desc">Destination path inside the sandbox.</div>
  </div>
</div>

#### <span className="msb-recv">fs.</span><span className="msb-hn">copy\_to\_host()</span>

```rust theme={null}
async fn copy_to_host(&self, guest_path: &str, host_path: impl AsRef<Path>) -> MicrosandboxResult<()>
```

<Accordion title="Example">
  ```rust theme={null}
  sb.fs().copy_to_host("/app/out/report.pdf", "./report.pdf").await?;
  ```
</Accordion>

Copy a file from the sandbox to the host machine.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>guest\_path</code><span className="msb-type">\&str</span></div>
    <div className="msb-param-desc">Path inside the sandbox.</div>
  </div>

  <div className="msb-param">
    <div className="msb-param-key"><code>host\_path</code><span className="msb-type">impl AsRef\<Path></span></div>
    <div className="msb-param-desc">Destination path on the host.</div>
  </div>
</div>

## Types

### SandboxFs

<p className="msb-backref">Returned by <a href="/sdk/rust/sandbox#sb-fs">sb.fs()</a></p>

Filesystem operations handle for a running sandbox, borrowing the parent sandbox's backend and name (it is generic over a lifetime, `SandboxFs<'a>`). Every method dispatches through the same host-guest channel as command execution. Local routes to `core.fs.*` agent messages; cloud returns `Unsupported` per method until cloud guest-fs lands. All operations are listed in the sections above.

`with_backend(backend, name)` is a public constructor for FFI shims that re-assemble a `SandboxFs` per call; most callers obtain one via [`sb.fs()`](/sdk/rust/sandbox#sb-fs).

### FsEntry

<p className="msb-backref">Returned by <a href="#fs-list">list()</a></p>

Metadata for a single entry returned from a directory listing.

| Field    | Type                          | Description                         |
| -------- | ----------------------------- | ----------------------------------- |
| path     | `String`                      | Path of the entry                   |
| kind     | [`FsEntryKind`](#fsentrykind) | Kind of entry                       |
| size     | `u64`                         | Size in bytes                       |
| mode     | `u32`                         | Unix permission bits (e.g. `0o644`) |
| modified | `Option<DateTime<Utc>>`       | Last modification time              |

### FsEntryKind

<p className="msb-backref">Used by <a href="#fsentry">FsEntry.kind</a> · <a href="#fsmetadata">FsMetadata.kind</a></p>

The kind of a filesystem entry. Derives `Copy`, `PartialEq`, and `Eq`.

| Variant     | Description                             |
| ----------- | --------------------------------------- |
| `File`      | Regular file                            |
| `Directory` | Directory                               |
| `Symlink`   | Symbolic link                           |
| `Other`     | Other entry type (device, socket, etc.) |

### FsMetadata

<p className="msb-backref">Returned by <a href="#fs-stat">stat()</a> · <a href="#fs-stat_with_follow">stat\_with\_follow()</a></p>

Detailed metadata for a file or directory.

| Field    | Type                          | Description                                                          |
| -------- | ----------------------------- | -------------------------------------------------------------------- |
| kind     | [`FsEntryKind`](#fsentrykind) | Kind of entry                                                        |
| size     | `u64`                         | Size in bytes                                                        |
| mode     | `u32`                         | Unix permission bits                                                 |
| readonly | `bool`                        | Whether the entry is read-only (no owner write bit)                  |
| modified | `Option<DateTime<Utc>>`       | Last modification time                                               |
| created  | `Option<DateTime<Utc>>`       | Creation time (not populated by guest stat, currently always `None`) |

### FsSetAttrs

<p className="msb-backref">Used by <a href="#fs-set_stat">set\_stat()</a></p>

Attributes accepted by `set_stat()`. Re-exported from `microsandbox_protocol::fs`. Derives `Default`, so set only the fields you want to change and spread the rest with `..Default::default()`. Each field is `Option`: `None` leaves that attribute unchanged.

| Field | Type          | Description                                 |
| ----- | ------------- | ------------------------------------------- |
| mode  | `Option<u32>` | Unix permission bits                        |
| uid   | `Option<u32>` | Owner user ID                               |
| gid   | `Option<u32>` | Owner group ID                              |
| size  | `Option<u64>` | File size (truncate or extend)              |
| atime | `Option<i64>` | Access time as Unix timestamp seconds       |
| mtime | `Option<i64>` | Modification time as Unix timestamp seconds |

### FsReadStream

<p className="msb-backref">Returned by <a href="#fs-read_stream">read\_stream()</a></p>

Streaming reader for file data from the sandbox. Obtained via [`read_stream()`](#fs-read_stream).

| Method    | Signature                                              | Description                                                                                        |
| --------- | ------------------------------------------------------ | -------------------------------------------------------------------------------------------------- |
| recv()    | `recv(&mut self) -> MicrosandboxResult<Option<Bytes>>` | Receive the next chunk; `None` once the file is fully read. Errors if the guest reports a failure. |
| collect() | `collect(self) -> MicrosandboxResult<Bytes>`           | Consume the stream and collect all remaining chunks into a single buffer.                          |

### FsWriteSink

<p className="msb-backref">Returned by <a href="#fs-write_stream">write\_stream()</a></p>

Streaming writer for file data to the sandbox. Obtained via [`write_stream()`](#fs-write_stream).

| Method  | Signature                                                        | Description                                                                                                            |
| ------- | ---------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| write() | `write(&self, data: impl AsRef<[u8]>) -> MicrosandboxResult<()>` | Write a chunk of data.                                                                                                 |
| close() | `close(self) -> MicrosandboxResult<()>`                          | Send EOF and wait for confirmation. Must be called to finalize the write; errors if the guest reports a write failure. |

### FsHandle

Type alias for an agentd-side filesystem handle. Internal plumbing: no public method takes or returns it, and the streaming types hold one only behind their own state.

```rust theme={null}
pub type FsHandle = u64;
```
