Hashline Edit Format

Line-hash-referenced file editing in the cowboy WASM plugin. Each line gets a 2-character hex hash (FNV-1a truncated to 8 bits) enabling reliable change detection and edit rejection when files have been modified since last read.

Status

Fully implemented in src/hashline.rs. Integrated as built-in tools (__HASHLINE_READ__, __HASHLINE_EDIT__) with handlers in handlers.rs.

Format

Lines are formatted as {line_num}:{hash}|{content}:

1:a3|fn main() {
2:7f|    println!("hello");
3:b2|}

Hash Function

FNV-1a with offset basis 2166136261 and prime 16777619, truncated to lowest byte (hash & 0xff), formatted as 2-char lowercase hex. Deterministic and fast. 256 possible values -- sufficient for change detection, not collision resistance.

Operations

Four edit actions, all referencing lines by line:hash pairs:

  • replace: Replace line(s) from start to optional end with new content
  • insert_before: Insert content before the referenced line
  • insert_after: Insert content after the referenced line
  • delete: Delete line(s) from start to optional end

All line references are validated before any changes are applied. On hash mismatch, the entire edit is rejected with a descriptive error asking the agent to re-read the file.

Operations are sorted in reverse line order before application to preserve line indices.

Additional Features

  • read_range_with_hashlines(): Read a specific line range with context lines above/below
  • format_hashline_with_comment(): Format hashes as inline comments for display, with language-aware comment markers (supports 20+ languages)
  • rolling_hash(): Cross-line hash for detecting multi-line changes
  • JSON schema helpers for tool definitions (hashline_read_schema(), hashline_edit_schema())
  • parse_edit_operations(): Accepts both operations and edits keys, and both content and new_text keys
  • Atomic writes via temp file + rename

Integration

The harness registers these as built-in tools during initialization. handle_hashline_read() dispatches a sandboxed cat command, then formats the result with hashlines in handle_hashline_read_result(). handle_hashline_edit() calls apply_edits() directly and returns a hashline preview of the edited file.