# File Tools

Tools that find, read, edit, open and track files.

| Tool | Description |
|---|---|
| `find_files` | Locate files (`queries: [{dir, pattern, file_pattern, recursive}]`). `mode=list` returns a directory's entries (alphabetical), `mode=glob` matches paths against a filename pattern and, since v1.0.23, returns them most recently modified first, `mode=search` greps file contents by RE2 regex. Mode is inferred when omitted: `pattern` + `file_pattern` → search, `pattern` alone → glob, neither → list. Glob patterns must carry a literal — all-wildcard (`**/*`) is rejected. Matches merge and deduplicate across queries. `mode=list` and `mode=glob` are capped at 128 KiB in total and the tail reports how many entries were dropped. Since v1.0.11 `mode=search` is paged instead of truncated: `output=files` (the default) returns one `{path, count, lines}` row per matching file — since v1.0.23 `lines` carries the row numbers of its first five matches, ready for `read_files` `around` — `output=content` returns the matching lines with their line numbers, `multiline=true` (v1.0.23) matches the regex against whole files so `.` crosses newlines and reports every row a match spans, `offset` / `limit` (default 256) walk the pages, and `context` adds surrounding lines — marked `context: true` and not counted toward `offset` / `limit`. A single match line is cut at 512 bytes. Every page ends with `[files a-b of N ...]` / `[lines a-b of N ...]` carrying the next `offset`, or `last page`; the queries and `output` must stay identical between pages |
| `read_files` | Batched read of one or more files (`files: [{path, offset, limit, around, context}]`); text, PDF, DOCX, PPTX, CSV/TSV, image, or audio/video — a media file comes back as a verbatim transcript through the configured speech-to-text model, so there is no separate transcription tool. Reads up to 2048 lines by default (1 MiB cap for documents, 10 MiB for images); `offset`/`limit` page through larger files — page for PDF, slide for PPTX, row for CSV. Since v1.0.23 `around` takes 1-based rows of a plain-text file and reads `context` lines (default 20, `0` = the rows alone) on each side, merging overlapping windows and marking skipped text with a `...` line (`offset`/`limit` are then ignored), and the same path may appear more than once in `files`, its results joined in order. Since v1.0.11 a truncated text read ends with `[lines a-b of N; call again with offset=... for more]`, so the continuation offset never has to be guessed. Text lines arrive as `"<row>\t<line>"`; the number is added by the reader and is not in the file, so it must be stripped before a line is reused as an `edit_file` anchor. Must be called before `edit_file` changes an existing file: since v1.0.23 the edit is refused unless the file was read in this run and its modification time is unchanged since that read. **Sensitive file guard**: SSH keys, `.pem`, `.key`, `.env` always require confirmation regardless of sudo or allowlist |
| `edit_file` | Every change to a file on disk. `mode=write` creates a first version or deliberately replaces one wholesale; `mode=patch` edits regions via a `targets` array — each target is `{old_string, new_string}` plus optional `replace_all`, and every anchor is located against the original file content before anything is applied. Two targets covering the same region, or a target whose `old_string` occurs inside an earlier target's `new_string`, reject the whole call with nothing written. An empty `new_string` deletes; an insert is expressed by repeating `old_string` at the start of `new_string`. The line-anchored `row` / `insert_string` form was removed — row numbers counted the earlier targets in the same call, which are not yet on disk; `mode=remove` moves the file aside, still restorable; `mode=restore` puts a recorded version back by `version` id, or undoes a whole task via `task_id` (`current` = the task running now). Mode is inferred from `content` → write and `targets` → patch; remove and restore are never inferred. Since v1.0.23 `write` over an existing file and every `patch` pass a read-freshness guard: the file must have been read with `read_files` in this run and not changed on disk since (by the user, a formatter or another command), otherwise nothing is written and the error asks for a fresh read; a successful write counts as a fresh read for the next edit. A `patch` anchor that only differs from the file in curly vs straight quotes still matches, and the replacement keeps the file's quote style. The tool description sends a file made for the user with no location asked for to the output directory |
| `file_history` | Recorded versions of every file the tools changed — when each changed, what the task was after, and what the content was. `mode=list` returns versions newest-first, filterable by `path`, `task_id`, `from`/`to` local time, and `limit` (capped at 24); `mode=read` diffs the newest recorded version of each path against what is on disk now. This is the snapshot layer `edit_file(mode=restore)` restores from |
| `open_file` | Open a file with the OS default application (play a video, view an image, open a PDF viewer). Replaces `run_command` `open`/`xdg-open`, which the sandbox cannot reach. 10 s cap |
