Filesystem — File
The File namespace gives agents access to the local filesystem. It is auto-imported — no use required.
Reading and writing
content = file.read("data/report.txt") # str — raises FileError if file missing
file.write("output/result.txt", content)
file.read returns str. If the file does not exist it raises a FileError at runtime — use file.exists to guard reads when the path may be absent.
file.write creates parent directories automatically.
All file.* paths and file.write content must be str values. Dynamic values with
another runtime type raise a clear type error; they are not silently formatted as strings.
Existence and listing
if file.exists("config.json") {
cfg = file.read("config.json")
}
entries = file.list("output") # list[str] — names only, not full paths
Creating directories
file.mkdir("output/reports/2026") # creates all missing parents
Copying and moving
file.copy("template.txt", "output/report.txt") # src unchanged
file.move("draft.txt", "published/final.txt") # src removed; atomic on same filesystem
Both copy and move create missing parent directories on the destination side automatically.
Removing files and directories
file.remove("tmp/scratch.txt") # single file
file.remove("tmp/cache") # directory — removed recursively (rm -rf semantics)
file.remove auto-detects whether the path is a file or a directory. Removing a non-existent path is a runtime error.
Glob patterns
reports = file.glob("output/*.txt") # files in output/ matching *.txt
all_rs = file.glob("src/**/*.rs") # recursive — all .rs files under src/
Returns a list[str] of matching paths. No matches → empty list. An invalid pattern is a runtime error.
Supported pattern syntax: * (any chars in one segment), ? (single char), ** (zero or more segments, recursive).
Temporary files and directories
tmp = file.mktemp() # creates a temp file; returns its path as str
tmpdir = file.mktemp(dir: true) # creates a temp directory; returns its path
file.mktemp creates the file or directory immediately and returns the path. Lifecycle is the caller’s responsibility — use file.remove(path) when done:
tmp = file.mktemp()
file.write(tmp, processed_content)
result = file.read(tmp)
file.remove(tmp)
Quick reference
| Method | Signature | Description |
|---|---|---|
file.read | file.read(path: str) → str | Read a file and return its contents as a string. |
file.write | file.write(path: str, content: str) → none | Write a string to a file, creating or overwriting it. |
file.exists | file.exists(path: str) → bool | Return true if the path exists on the filesystem. |
file.list | file.list(path: str) → list[str] | List the entries in a directory. |
file.mkdir | file.mkdir(path: str) → none | Create a directory and all intermediate parents. |
file.remove | file.remove(path: str) → none | Remove a file or directory. |
file.copy | file.copy(src: str, dst: str) → none | Copy a file from src to dst. |
file.glob | file.glob(pattern: str) → list[str] | Return file paths that match a glob pattern. |
file.move | file.move(src: str, dst: str) → none | Move (rename) a file from src to dst. |
file.mktemp | file.mktemp() → str | Create a temporary file and return its path. |
Error handling
All file.* methods that fail for I/O reasons throw a FileError. Catch it by type name:
try {
content = file.read("config.json")
} catch err: FileError {
io.notify("Could not read config: {err.message}")
content = "{}"
} catch err: Error {
io.notify("Unexpected error: {err.message}")
}
FileError carries a message: str field. Its diagnostic code is keel::runtime::FileError.
For subprocess execution, see Shell — subprocess bridge.