Newer
Older
navi-1 / manuals / filesystem_read.md

filesystem_read — Manual

What it does

Reads, lists, searches and compares files without changing them. Writing and editing live in filesystem_write; LLM-backed questions and edits live in file_ai.

Actions

Action Use it for
read one file, line-numbered by default; page large files with offset/limit
list the top level of a directory, or the whole tree with recursive: true
find files whose path matches a glob (*.py, **/*.scad)
find_up walk parent directories looking for one exact filename (pyproject.toml, .git)
grep search file contents; literal by default, regex: true for a pattern
info size, type, timestamps, line count — call before reading an unknown file
exists true or false without an error
diff unified diff between path and other (both files)

Reading

read numbers lines as 12: text. The number column is not part of the file — when you copy text into edit, read with numbered: false or strip the column.

Large files are paged automatically: by default the first 500 lines (or first 50 KB). The header says lines 1–500 of 3200, and a numbered read ends with [more: call read with offset=501]. Continue with offset. A raw (numbered: false) read has no footer, so its text is safe to copy.

{"action": "read", "path": "src/app.py"}
{"action": "read", "path": "src/app.py", "offset": 40, "limit": 30}
{"action": "read", "path": "src/app.py", "numbered": false}

Binary files (a NUL byte in the first 8 KB) are refused; use info for metadata or image_view for images.

Searching

grep walks a directory recursively, returns relative/path.py:42: text, and stops at 100 matches by default. It skips .git, node_modules, .venv, __pycache__, dist, build and similar directories; pass include_ignored: true to search them too.

  • regex: true enables regular expressions. The default is a literal substring.
  • case_sensitive: true is available; the default is case-insensitive.
  • glob: "*.py" limits the filenames searched.
  • context: 2 adds two lines before and after each match (path-42- text marks context).
  • max_results raises or lowers the cap.
{"action": "grep", "path": "src", "pattern": "TODO", "glob": "*.py"}
{"action": "grep", "path": "src", "pattern": "def \\w+\\(", "regex": true, "context": 1}
{"action": "find", "path": ".", "pattern": "*.scad"}
{"action": "find_up", "path": "src/deep/file.py", "name": "pyproject.toml"}
{"action": "diff", "path": "src/app.py", "other": "src/app.py.bak"}

If nothing matches, the error suggests a shorter pattern, regex: true, include_ignored: true, or a different path — try one of those before concluding that the text is absent.

Access

In multi-user mode every path resolves inside user_data/<user_id>/ or the current session directory. A path outside both returns Access denied. Relative paths resolve against the user sandbox. Do not work around a refusal by copying files into the sandbox or /tmp; ask the user to upload the file.

Common mistakes

  • Copying the 12: number column into an edit — read with numbered: false.
  • Reading a whole large file when one fact was needed — use grep, or file_ai ask.
  • Using find for content — find matches paths; grep matches text.
  • Passing destination to diff — the second file goes in other.