Skip to content

feat: add write tool for creating and overwriting files - #16

Closed
minixalpha wants to merge 6 commits into
mainfrom
claude/write-tool
Closed

feat: add write tool for creating and overwriting files#16
minixalpha wants to merge 6 commits into
mainfrom
claude/write-tool

Conversation

@minixalpha

@minixalpha minixalpha commented Aug 13, 2026

Copy link
Copy Markdown
Owner

Summary

Adds a write tool — the thin whole-file write chosen as Route A in the accompanying research — plus the research doc and dev notes that motivated it.

Research (docs/research/write_tool.md)

  • Surveys the model-facing file-mutation tools of five agent projects (grok-build, pi, claude-code mirror, opencode, codex): why a dedicated write exists next to bash, what each project implements, and what none of them actually guarantee.
  • Revised conclusion: a thin write is worth building now for content/command separation (it removes the class of silently corrupted heredoc writes) and for terminal presentation — not as a control plane. Staleness guards and atomic replace are deliberately out of scope in a single-threaded agent, where they would be pretend safety.

The tool (src/nanopycodeagent/write_tool.py)

  • Structured {path, content} input: content lands on disk as data — no shell expansion, heredoc delimiters, or quote escaping.
  • Creates the file (missing parent directories included) or replaces it whole; the result states which happened, with byte and line counts.
  • Path handling matches read: absolute or relative to the working directory, leading ~ expanded.
  • Refuses directories and non-regular files — a FIFO write-open would block with no timeout, a device file must not be clobbered as text; a symlink to a regular file writes its target.
  • Content is written exactly as given (UTF-8, no newline normalization); a lone surrogate is an error instead of a silently corrupted file.
  • Every error states the next step, read-style — e.g. a quoted ls -ld -- <parent> bash hint when the write fails, or bash as the escape hatch for a FIFO target.
  • The description is honest: plain overwrite, last writer wins, no prior-read or staleness checks claimed.

Wiring and display (src/nanopycodeagent/agent.py)

  • Registered in TOOLS and the system prompt. The terminal echoes [write] <path> plus the content folded to its first 10 lines (over-long lines cut at 200 chars) on the tool-use shade, with the result on the output shade.

Tests

  • 17 new cases covering run_write and content_preview (create/overwrite, parent creation, CRLF passthrough, FIFO rejection, symlink target, surrogate error, preview folding) plus an agent-loop dispatch test.

Docs

  • Changelog entry under [Unreleased] in docs/changelogs/0.6.x.md.
  • Dev notes: the write-tool plan added to the Chinese source, English version regenerated from it.

A structured {path, content} call writes a whole UTF-8 text file: content
lands on disk as data instead of passing through shell quoting and
heredocs, which could silently corrupt it. Missing parent directories are
created; directories and non-regular files (FIFOs, device files) are
refused as targets; the result states created vs overwrote with byte and
line counts. The terminal echoes the target path with the content folded
to its first lines, matching the tool output shading.
The non-regular-file and cannot-write errors stated only what failed;
now the first names bash as the escape hatch for a FIFO or device
target, and the second hands the model an ls -ld command pointed at the
blocking parent, following read's bash-hint conventions. The line-split
logic duplicated between content_preview and run_write moves into a
shared _logical_lines helper.
@minixalpha

Copy link
Copy Markdown
Owner Author

Merged into main as 11bb0b7 — the merge API call was interrupted by a 502 upstream, which updated main but left this PR record open. Closing manually; all commits are contained in main.

@minixalpha minixalpha closed this Aug 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant