Skip to content

fix(webview): announce a rejected draft that an external write replaces - #458

Merged
mtskf merged 2 commits into
mainfrom
fix/notify-discarded-rejected-draft
Oct 10, 2026
Merged

mtskf merged 2 commits into
mainfrom
fix/notify-discarded-rejected-draft

Conversation

@mtskf

@mtskf mtskf commented Oct 10, 2026

Copy link
Copy Markdown
Owner

Summary

When the host rejects an edit ("Cannot save" banner), the draft stays on screen only. If another writer then changed the file, the editor swapped in the new content and dropped both the draft and the banner without telling the user. The editor now shows the existing "local edit discarded" notice in that case.

Changes

  • src/webview/editor.ts (applyDocument): raise the existing discard notice when a reseed replaces a rejected draft. The predicate is computed before the replace, because the shell clears serializeError right after the snapshot is applied.
    • Not raised while edit-sync still holds the bytes on a leading lineage (a readonly Document only rewinds the view; the buffer is restored and re-sent on re-grant).
    • Not raised when the incoming text differs in line endings only.
    • The notifier call is wrapped in try/catch, matching the existing call site in cm/edit-sync.ts, so a throwing notifier cannot leave the reducer behind the view.
  • test/webview/shell.test.ts: the real-host harness gains a failing-validator switch, edit-rejected delivery, an external write, and a way to mark a posted Edit as lost. No new message or notice kind.

Related

  • TODO: ARCH-03a
  • Known residual, not handled here (recorded under ARCH-05): if a draft Document is re-sent to a fresh webview and only the separate edit-rejected delivery fails, the webview has neither a holder nor serializeError, so this notice does not fire. Dropping the serializeError condition would mis-announce ordinary external updates.

Test Plan

  • New real-host test: parse-failed Edit, then an external write → exactly one discard notice (red before the fix, green after)
  • Negative pin: rejected draft + same text with CRLF → no notice, text unchanged (goes red when the EOL conjunct is removed)
  • Negative pin: failed send, then a readonly Document → no notice, buffer reaches the host on re-grant (goes red when the leading-lineage conjunct is removed)
  • pnpm compile, pnpm lint, full pnpm vitest run green
  • Not verified in a real VS Code window or E2E — in-memory (happy-dom + real host reducer) only

mtskf added 2 commits October 11, 2026 02:26
A draft the host answered with edit-rejected stays on screen without a carrier in edit-sync, so when a version-advancing external write reseeded the view, both the draft and the Cannot save banner vanished with no notice. applyDocument now raises the existing discard notice for that reseed, excluding the two reseeds that lose nothing: bytes edit-sync still holds on a leading lineage (a readonly Document rewinds the view only) and an EOL-only difference.

The real-host test harness gains only what the repro needs: a failing validator switch, edit-rejected delivery and an external write.
@mtskf
mtskf merged commit 5ce2105 into main Oct 10, 2026
2 checks passed
@mtskf
mtskf deleted the fix/notify-discarded-rejected-draft branch October 10, 2026 15:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant