- Replaced legacy `SWAP`, `INS`, and `PASTE` commands with unified `PUT` and `CUT` hunks across parser, grammar, tokenizer, and test suites.
- Added support for named registers and span paste operations in clipboard and block execution logic.
- Implemented indentation repair and enhanced gap locator formatting for improved patch resilience.
- Updated documentation, system prompts, and session analysis scripts to reflect the new syntax and header shapes.
- Removed copy and delete operations across tokenizer, parser, grammar, and clipboard logic.
- Standardized line-editing operations and block resolvers to use cut exclusively.
- Updated documentation, prompts, and test suites to reflect the removal of copy and delete syntax.
- Add leniency rule in parser to auto-accept bare `-` rows as literal content when hunks represent Markdown bullet lists.
- Emit MINUS_BULLET_AUTO_PIPED_WARNING when bullet-shaped rows lack explicit plus prefixes.
- Reject ambiguous or non-bullet minus rows to prevent unified-diff contamination.
- Accepted comma-separated ranges and harmless malformed trailers emitted by local models.
- Added focused array-input diagnostics and reinforced canonical hashline syntax in the edit prompt.
- Covered the recovered forms with behavioral regression tests.
Fixes#5805
Clarified hashline minus-row errors and model-facing prompt examples so Markdown list rows use the + body-row prefix instead of triggering write fallbacks.
Fixes#4179
GLM 5.2 inserts an extra `.` between the line number/range and the
trailing `:` (e.g. `SWAP 2.=3.:`, `INS.POST 2.:`, `DEL 2.=3.`).
The parser failed with "payload line has no preceding hunk header"
and could not recover. Add a `skipStrayDot` helper that skips a
spurious `.` before the optional colon or end-of-line, wired into
`consumeOptionalColon` (covers SWAP, INS.*, SWAP.BLK, INS.BLK.POST)
and the DEL / DEL.BLK branches.
- Renamed line and block patch op verbs to XCHG, DEL, and INS in parsing and formatting.
- Updated grammar and tokenizer to support XCHG.BLK, DEL.BLK, and INS.PRE/POST/HEAD/TAIL forms.
- Updated diagnostics, docs, prompts, tests, and changelog to use XCHG/DEL/INS-based operators.
- Expanded session-stats parsing to normalize legacy op aliases to compact IDs.
Defer read-output line-number stripping from #handleRaw to #flushPending and
gate it on uniformity: a bare "N:text" row is only a pasted-snapshot artifact
when *every* bare body row in the hunk carries the prefix. A mixed set (e.g.
"3:keep" next to "plain") is treated as genuine content and left intact,
avoiding silent corruption of bodies that legitimately start with "digits:".
Removes at most one prefix per row; "+"-prefixed literal rows stay untouched.
Reverts the now-orphaned stripLeadingHashlinePrefixes export back to private.
- Replace recursive stripLeadingHashlinePrefixes with single-pass
stripOneLeadingHashlinePrefix in #handleRaw to prevent over-stripping
content whose own text starts with digits:colon (e.g. YAML ports,
timestamps: 2:42:hello → 42:hello, not hello)
- Export stripOneLeadingHashlinePrefix from prefixes.ts
- Move hashline CHANGELOG entry to [Unreleased] section
- Add regression tests for nested N: prefix and +N: asymmetry
- Replaced `¶path#hash` prefix with `[path#hash]` delimiters across parser, tokenizer, and grammar.
- Updated prompts, docs, and recovery paths to the new bracketed form.
Aligned the runtime header parser with the formal grammar's no-`#`-in-filename rule: any `#` left in the path body after detecting the trailing `#XXXX` tag means the header is malformed (short `#1A2`, non-hex `#1A2G`, over-long `#1A2B5`, stale-tag copy-paste, line-suffixed tags), not a path with an embedded hash. Mirrored the same rule on the apply_patch recovery path.
Added strict and recovery regression coverage for the three malformed-tag shapes the reviewer named.
Rejected headers such as ¶src/file.ts#1A2B:42 as malformed headers instead of treating the whole tail as a hashless path and failing later in body parsing.
Added strict and apply_patch-recovery regression coverage for line-suffixed snapshot tags.
Tightened the relaxed header parser so a 4-hex token sitting before whitespace + more content (e.g. `¶src/a.ts#1A2B copied from read`) still raises the focused "must be ¶PATH or ¶PATH#TAG" diagnostic instead of being silently re-interpreted as a hashless path.
Also stopped rejecting hashless paths whose last five characters look like #TAG with a non-hex digit, and mirrored the same anti-junk rule in the apply_patch recovery parser.
Parsed hashline section headers by recognizing only a trailing #TAG as the snapshot delimiter, allowing whitespace inside valid paths.
Updated recovery parsing and grammar docs to match the runtime parser, and added regression coverage for canonical and recovered headers with spaces.
Fixes#1634
- Updated the grammar to parse replace hunks with zero body lines.
- Changed empty replace execution to emit delete edits across the target range.
- Updated tests to verify empty replace syntax deletes lines while empty inserts still throw errors.
- Replaced bare `A B` range headers with `replace N..M:`, `delete N..M`, `insert before N:`, `insert after N:`, `insert head:`, and `insert tail:`.
- Removed `&A..B` repeat rows; insert-before/after ops now express the same intent explicitly.
- Empty replace bodies now error instead of deleting; `delete` is the canonical deletion op.
- Updated grammar, prompt, docs, tests, and all call sites to the new syntax.
- Rejected bare `A` anchors; single-line ranges must now be spelled `A A`.
- Added a descriptive error for single-number headers to guide model output.
- Updated grammar, tokenizer, prompt docs, and tests to reflect the change.
- Redesigned hashline patch syntax from anchor-based (`A-B:`) to hunk-header format (`@@ A..B @@`) with unified-diff compatibility.
- Removed `autoDropPureInsertDuplicates` option and simplified apply behavior to preserve duplicated boundary and context lines.
- Changed repeat operator from `^A-B` to `&A..B` and range separator from `-` to `..` for consistency with hunk-header syntax.
- Added image resizing and dimension notes to eval tool output; improved write tool hashline header sanitation for legacy formats.
- Removed 521 lines of boundary-duplicate absorption code and simplified parser to auto-convert bare body rows and unified-diff contamination.
- Replaced 4-hex content-derived file hashes with 3-hex opaque tags minted by InMemorySnapshotStore, making tags session-bound pointers rather than content fingerprints.
- Removed lru-cache dependency; replaced LRU-bounded per-path rings with a flat 4096-slot global ring using a scrambled permutation to prevent LLM tag extrapolation.
- Made SnapshotStore required in Patcher (was optional); tag resolution now drives stale-anchor detection instead of recomputing hashes at apply time.
- Changed literal payload sigil from `|` to `+` and accepted `^A` shorthand for `^A-A`; added lenient recovery for bare bodies, lone `-` rows, and overlapping bare/concrete block pairs.