12 Commits

Author SHA1 Message Date
NCBM ac33e92d33 core/tools+config: refuse write_file overwrite unless overwrite=true 2026-10-16 18:44:14 +08:00
NCBM 6c4c8b9328 core/tools: edit_lineno rejections name the read_file call 2026-10-09 19:46:16 +08:00
NCBM 5436457ac0 core/tools: allow edit_lineno append to an empty file
Appending via edit_lineno required the last line to be read, which made
writing to an empty file impossible (line 0 does not exist). An empty
file has nothing to clobber, so the append needs no prior read.
2026-08-15 17:41:06 +08:00
NCBM 2cf66edb60 core/tools: edit results preview the old content
Wrong-target edits (the test_run_aside pass clobber, the edit_replace
mangling) were silent: the success message reported counts only, so the
model had no signal it replaced the wrong thing until later.

edit_lineno now reports the first removed line ("first: 'pass'") and
edit_replace reports the matched pattern ('old' -> 'new'), giving the
model an immediate self-correction signal.
2026-08-15 17:40:26 +08:00
NCBM 38671482f2 core/tools: edit_lineno unread error names the read window
The boundary overguard (read offset=50 shows lines 51+, then editing
line 50 fails) forced blind re-reads. The error now reports the read
window ("this turn read lines 51-86") and advises reading with a margin
around the target range; read_file's description says the same.
2026-08-15 17:38:58 +08:00
NCBM c9815e32bb core/tools: mtime freshness replaces per-write lineno invalidation
edit_lineno now rejects edits when the file changed since the numbered
read (mtime recorded at read time), so stale line numbers are caught
even when the mutation came from run_argv / an external process — the
class the explicit invalidations could never cover.

This lets write_file / edit_replace / edit_lineno drop their explicit
invalidate calls (the write itself changes the mtime, and the error is
now the accurate "changed since it was read" instead of a misleading
"not read"). copy/move keep explicit invalidation because shutil
preserves the source mtime, which the freshness check cannot see.
2026-08-15 17:38:10 +08:00
NCBM 132ac520ec core/tools: mark only displayed lines read on truncated read_file
read_file(with_lineno=true) marked the whole requested slice before
applying the max_chars cap, so a truncated read silently unlocked every
line of the file for edit_lineno even though the model never saw them.
Mark only the complete numbered lines actually returned (excluding the
[Truncated] marker); the unseen tail stays unread.
2026-08-15 17:31:43 +08:00
NCBM 25e6ec3d44 core/tools: show 1-based line range on read_file results 2026-08-11 15:33:12 +08:00
NCBM 19ac4533d4 core/tools: invalidate lineno read state on file mutation 2026-08-01 01:22:30 +08:00
NCBM 56ac8d17d7 core/tools: restrict edit_lineno to lines read with line numbers 2026-08-01 01:21:00 +08:00
NCBM f5b566b371 core/tools: add per-turn guard requiring lineno read before edit_lineno 2026-07-29 01:40:31 +08:00
NCBM 81a30d0e4d core/tools/file: add edit_lineno line-range edit tool
1-based inclusive range replace/delete/append; document Phase B agent
and tool updates in CLAUDE.md.
2026-07-14 23:24:34 +08:00