From 3fa757204667469f4985f963bb4da9e2e1c99e0d Mon Sep 17 00:00:00 2001 From: can1357 Date: Wed, 27 May 2026 01:56:23 +0200 Subject: [PATCH] docs(coding-agent/prompts): clarified hashline insert and line-number rules - Added rule that inserts add only listed rows; trailing blank payload writes a literal empty line. - Added rule that a bare anchor op inserts one blank line and is not a no-op. - Clarified that frozen line numbers do not shift as earlier ops in the same hunk apply. - Expanded anti-pattern example to show trailing-blank doubling and anchor-offset mistakes. --- .../coding-agent/src/prompts/tools/hashline.md | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/packages/coding-agent/src/prompts/tools/hashline.md b/packages/coding-agent/src/prompts/tools/hashline.md index 01dc762d4..5a94bb6dc 100644 --- a/packages/coding-agent/src/prompts/tools/hashline.md +++ b/packages/coding-agent/src/prompts/tools/hashline.md @@ -19,8 +19,10 @@ A-B! delete A..B (or A! == A..A) - **Payload is only what's NEW.** `:` replaces inside; `↑`/`↓` add at anchor. NEVER repeat anchor lines or neighbors. - **Continuation lines require `+`.** Use `+` for a blank payload line; use `++text` to write a line starting with `+text`. +- **Inserts add ONLY the rows you list.** The file's existing newlines around the anchor stay. NEVER tack a trailing `+` blank "for spacing" — it writes a literal blank line into the file, doubling whatever is already there. +- **A bare `LINE↑`/`LINE↓` with no payload still inserts ONE blank line.** Not a no-op. Omit the op if you want nothing there. - **Go small.** Add → `↑`/`↓`; replace → `:`; delete → `!`. -- **Line numbers are frozen references to what you have seen.** Later ops still use original line numbers. +- **Line numbers are frozen references to what you have seen.** Later ops in the same hunk still use original line numbers; they do NOT shift as earlier ops apply. @@ -32,7 +34,9 @@ A-B! delete A..B (or A! == A..A) ```a.ts#1a2b 1:const X = "a"; -2:export function f() { return X; } +2: +3:export function f() { return X; } +4:f(); ``` # replace with a continuation line, insert after, delete @@ -41,7 +45,7 @@ A-B! delete A..B (or A! == A..A) 1:const X = "b"; +export const Y = X; 1↓const Z = Y; -2! +4! ``` @@ -52,6 +56,12 @@ A-B! delete A..B (or A! == A..A) 1:const X = "a"; 1-2:const X = "b"; +export const Y = X; +# WRONG — trailing `+` blank writes a literal empty line; the new blank lands right next to the orig blank at line 2, doubling it +1↓const Y = X; ++ +# WRONG — `2↓` still anchors at PRE-EDIT line 2 (frozen), NOT at the line just inserted by `1↓`. Both inserts land at their own anchors, giving three consecutive blanks (new from `1↓`, orig blank line 2, new from `2↓`). +1↓ +2↓