File Editing
BOR reads, writes, and surgically patches files like a coding agent. This is what powers “build a real project”, “fix the bug in my repo”, and “write a script that…”. File tools live inserver/protocol/handlers/file.js.
Reading
| Tool | Purpose |
|---|---|
read_file | Read a file. Relative paths resolve against the project root; absolute paths are allowed. device:/ maps to your home folder, bor:/ to BOR-created files. |
read_file_in_chunks | Read a large file by chunk. |
read_batch | Read several files at once. |
list_files | List a directory. |
search_files | Search file contents (regex). |
list_code_definition_names | List top-level code definitions in a file/folder. |
Writing
| Tool | Purpose |
|---|---|
write_file / write_to_file | Create or fully replace a file. |
replace_in_file | Surgically patch a file with SEARCH/REPLACE blocks. |
delete_file | Remove a file. |
write_file
The file content rides in the tag body (CDATA-safe). BOR streams it into a live editor card in the bubble — one card per file. For a multi-file project, you watch each file fill in and finalize separately.
replace_in_file (surgical edits)
For targeted changes, BOR reads the file, then patches it with a diff of SEARCH/REPLACE blocks:
Where files go
The default destination follows the.bor artifact policy (see Storage):
- New projects →
.bor/workspaces/<slug>/ - Individual scripts →
.bor/files/<slug>.<ext> - Images / downloads / reports / exports / scratch → the matching
.bor/subfolder
Write protection
server/protocol/paths.js refuses writes to the OS source tree (server/, shell/, node_modules/, .git/, lockfiles) and to absolute paths outside $HOME (except /tmp, /var/folders). Narrow carve-outs let the AI write a theme’s user-extras.css and theme assets. This keeps BOR from damaging its own source while leaving you free.
Robust parsing
File content can contain anything —<, >, even ]]> or stray markup from a confused model. BOR’s parser is hardened so this never corrupts a write:
- It anchors on the tool’s own close tag, not on the (fragile) CDATA delimiter — so a malformed CDATA close can’t make one file swallow the next.
- It accepts content with embedded
]]>or no CDATA at all. - It strips BOR’s internal turn-structure tags (
<tool_results>etc.) if a weak model hallucinates them into file content — they never land on disk.
Use cases
- “Write a Python script that renames my photos by date.” → one file in
.bor/files/, run it. - “Fix the off-by-one in
/Users/me/app/src/list.ts.” →read_file, thenreplace_in_filein place. - “Scaffold a Next.js dashboard.” → a real project in
.bor/workspaces/, then run it and preview it. - “Refactor this module.” → read, surgically patch, re-read to verify.