f2cf3843ec
`edit_file` and `write_file` now capture the file contents before and after the mutation, generate a unified diff with `similar`, and emit it at the head of the `ToolResult` body. The TUI's existing `output_looks_like_diff` detector (history.rs:1335) sees the `@@` header in the first 5 lines and routes the payload through `diff_render::render_diff`, which already renders unified diffs with line numbers and coloured `+`/`-` gutters. The model also benefits — it sees exactly which lines changed instead of just `Replaced N occurrence(s)` or `Wrote N bytes`. Identical content produces an empty diff, in which case the body falls back to `<summary>\n(no changes)`. ### What's wired - New `crates/tui/src/tools/diff_format.rs` exposes `make_unified_diff(path, old, new) -> String` using `similar::TextDiff::from_lines(...).unified_diff().context_radius(3)`. - `WriteFileTool::execute` snapshots prior contents (or empty for new files), writes, then emits `<diff>\n<summary>` where summary is `Wrote N bytes to PATH` for existing files and `Created PATH (N bytes)` for new ones. - `EditFileTool::execute` snapshots, replaces, writes, emits `<diff>\nReplaced N occurrence(s) in PATH`. - `similar = "2"` added to `crates/tui/Cargo.toml`. Pure-Rust, no C deps; v2.7.0 in Cargo.lock. ### Tests - 4 unit tests in `diff_format::tests` covering identical inputs, replacement, new-file (against empty), and presence of the `@@` header in the first 5 lines (so the TUI detector trips). - Existing `test_write_file_tool` / `test_edit_file_tool` updated to assert both the summary line and the unified-diff body (`--- a/`, `-old`, `+new`). ### Verification cargo fmt --all -- --check ✓ cargo clippy --workspace --all-targets --all-features --locked -- -D warnings ✓ cargo test --workspace --all-features --locked ✓ (1824 + supporting; was 1820) Closes #505 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>