Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions box/overall/ephemeral-box.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,9 @@ The request sends `{ ephemeral: true, ttl?, runtime? }` to `POST /v2/box`.
| `exec.code()` | Yes | Yes |
| `exec.stream()` | Yes | Yes |
| `exec.streamCode()` | Yes | Yes |
| `exec.session()` | Yes | Yes |
| `files.read/write/list/upload/download` | Yes | Yes |
| `files.stat/mkdir/rename/remove` | Yes | Yes |
| `schedule.exec/prompt/list/get/pause/resume/delete` | Yes | Yes |
| `cd()` / `cwd` | Yes | Yes |
| `getStatus()` | Yes | Yes |
Expand Down
112 changes: 112 additions & 0 deletions box/overall/files.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,118 @@ print(json.loads(content))

---

### Read part of a file

Pass `length` to read a bounded byte range instead of the whole file, starting at `offset` (default `0`). This keeps a large log or dataset out of memory when you only need a slice of it. The server rejects a length above 8 MiB.

<CodeGroup>
```typescript box.ts
// First 512 bytes
const head = await box.files.read("train.csv", { length: 512 })

// 1 KB starting at byte 4096
const chunk = await box.files.read("train.csv", { offset: 4096, length: 1024 })
```

```python box.py
# First 512 bytes
head = box.files.read("train.csv", length=512)

# 1 KB starting at byte 4096
chunk = box.files.read("train.csv", offset=4096, length=1024)
```
</CodeGroup>

---

### Inspect a path

Get metadata for a single path without reading it: the entry type, size, last modified time, inode, and an opaque `version` token.

Use `version` for optimistic concurrency. Read it before a slow operation, then compare it afterwards to detect whether the file changed underneath you. Compare it for equality only, and do not parse it.

<CodeGroup>
```typescript box.ts
const info = await box.files.stat("report.csv")

console.log(info.type) // "file" | "directory" | "symlink" | "other"
console.log(info.size) // 1024
console.log(info.version) // opaque freshness token
```

```python box.py
info = box.files.stat("report.csv")

print(info.type) # "file" | "directory" | "symlink" | "other"
print(info.size) # 1024
print(info.version) # opaque freshness token
```
</CodeGroup>

By default a symlink is reported as `"symlink"`. Pass `follow` to resolve it and describe the target instead.

<CodeGroup>
```typescript box.ts
const target = await box.files.stat("latest", { follow: true })
```

```python box.py
target = box.files.stat("latest", follow=True)
```
</CodeGroup>

---

### Create directories

Create a directory. Pass `parents` to create missing parent directories, the way `mkdir -p` does, and to succeed when the directory already exists.

<CodeGroup>
```typescript box.ts
await box.files.mkdir("output/reports", { parents: true })
```

```python box.py
box.files.mkdir("output/reports", parents=True)
```
</CodeGroup>

---

### Move and rename

Move a path to a new location, which is also how you rename it.

<CodeGroup>
```typescript box.ts
await box.files.rename("draft.md", "final.md")
```

```python box.py
box.files.rename("draft.md", "final.md")
```
</CodeGroup>

---

### Delete files

Remove a file. Removing a directory requires `recursive`, so a directory is never deleted by accident.

<CodeGroup>
```typescript box.ts
await box.files.remove("scratch.tmp")
await box.files.remove("build", { recursive: true })
```

```python box.py
box.files.remove("scratch.tmp")
box.files.remove("build", recursive=True)
```
</CodeGroup>

---

### List files

List the entries in a directory. Each entry includes the path, size, type, and last modified timestamp.
Expand Down
4 changes: 2 additions & 2 deletions box/overall/how-it-works.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ Every box is a self-contained environment with five capabilities:
| -------------- | ------------------------------------------------------------ |
| **Agent** | Run a coding agent (Claude Code or Codex) |
| **Git** | Clone repos, inspect diffs, and open pull requests |
| **Shell** | Execute OS-level commands directly |
| **Filesystem** | Upload, write, read, list, and download files inside the box |
| **Shell** | Execute OS-level commands, or hold one open with [live sessions](/box/overall/live-sessions) |
| **Filesystem** | Upload, write, read, list, download, and manage files inside the box |
| **Snapshots** | Capture box state and restore new boxes from it |

The agent has full access to the shell, filesystem, and git inside its box. It can install packages, write files, run tests, and interact with the network.
Expand Down
Loading
Loading