mirror of
https://github.com/pbakaus/impeccable.git
synced 2026-09-11 21:57:14 +03:00
Cursor Bugbot review on 8660d3a flagged a real corruption bug:
> Multi-line self-closing div breaks depth tracking in expandReplaceRange.
> The forward div-depth walk applies openRe / selfCloseRe / closeRe
> per-line. A multi-line `<div\n className="spacer"\n/>` causes openRe
> to match the opener line but selfCloseRe fails on both lines because
> `/<div\b[^>]*\/\s*>/` requires the full tag on one line. Depth is
> permanently over-counted by 1, so the walk overshoots.
Trace on the JSX-marker-inside-wrapper layout:
- Inside the wrapped element, a multi-line `<div … />` increments depth
at the `<div` line and never decrements.
- Forward walk's depth never returns to 0 → end stays at block.end (the
inner marker comment) → replace range stops there.
- Wrapper's outer `</div>` is left orphaned in the file after
accept/discard, breaking the JSX. Worse: an unrelated subsequent
`<div className="next-card">…</div>` sibling gets its `</div>`
mis-counted as the wrapper close, and the depth walk corrupts further.
Fix: rewrite the forward walk on JOINED text instead of per-line. A
single regex `/<div\b[^>]*?(\/?)>|<\/div\s*>/g` spans newlines (because
`[^>]` matches `\n`), so it correctly identifies multi-line opens,
closes, AND self-closes. Convert the match offset back to a file line
index to set `end`. Walk-back logic for the wrapper opener is
unchanged.
Test coverage:
- New `expandReplaceRange handles multi-line self-closing <div />` test
in live-accept.test.mjs constructs the exact Bugbot scenario: a
multi-line `<div\n className="spacer"\n/>` inside the picked
element AND an unrelated `<div className="next-card">After</div>`
sibling right after. Asserts the discard removes ALL impeccable
markers / wrapper attrs, preserves the next-card sibling intact, and
the multi-line `<div />` survives inside the restored content.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>