Give card windows their own undo stacks and coarsen the close
Phase B of the two-level undo card: every card-window gesture — comment
post/delete/edit, body Edit sessions, style and details changes —
registers fine-grained on the window's own stack (window.undoManager
answers with it; board ⌘Z never sees mid-session card steps; an empty
window stack beeps, never falls through). Window close folds the stack
into one coarse values-based board step ("Edit card 'X'") — per-target
per-field later-wins merge, so foreign mid-session writes stay out by
construction, a no-net-change session registers nothing, and any stale
component skips the whole step. The comments/.trash purge defers with
the coarse step via a step-retirement seam on the providers: it runs
when the step leaves the board stack or the board session ends; the git
provider retires dropped steps on register, which keeps Pro's
purge-at-close-flush structural with no tier check. Interim on git
boards: gestures still auto-commit per debounce until phase C's
close-flush commit.
2432 tests in 418 suites green.
Claude-Session: https://claude.ai/code/session_01CqjXB7ASoWtbyoGod68k97
This commit is contained in:
@@ -64,9 +64,12 @@ public enum HistoryPhrase {
|
||||
case card
|
||||
case lane
|
||||
case board
|
||||
/// One comment. Only `.delete` reaches it: posting has its own phrase (`comment`, below), and
|
||||
/// the draft save, the inline edit and the trash purge register no step at all
|
||||
/// (13-native-undo.md — no byte capture in any tier, and the permanent-delete posture).
|
||||
/// One comment. `.delete` and `.edit` reach it — the inline edit session joined the
|
||||
/// vocabulary with the window stack (re-ruled 2026-07-31: "every gesture issued in that
|
||||
/// window — comment post/delete/**edit**, body Edit sessions ... registers there at fine
|
||||
/// grain"), registered at its own commit point exactly as the body's session is. Posting has
|
||||
/// its own phrase (`comment`, below); the draft save and the trash purge still register no
|
||||
/// step at all (13-native-undo.md — the permanent-delete posture).
|
||||
case comment
|
||||
|
||||
var singular: String {
|
||||
@@ -99,6 +102,19 @@ public enum HistoryPhrase {
|
||||
/// login'") is dropped exactly as every other phrase drops it — a menu row has to stay short.
|
||||
public static let comment = "Comment"
|
||||
|
||||
// MARK: The card-window session
|
||||
|
||||
/// **The coarse close step's phrase** — one card window's whole session, as the board's stack sees
|
||||
/// it: 13-native-undo.md ▸ Rules names it "Edit card 'Fix login'", so the menu title is the same
|
||||
/// verb and noun every other card edit uses, dropping the item clause a menu row has no space for.
|
||||
///
|
||||
/// Deliberately *not* a new verb. The session is an edit to a card — the fine-grained things
|
||||
/// inside it (a comment posted, a colour chosen, a paragraph rewritten) are the window stack's
|
||||
/// story, and a board-level row that tried to enumerate them would be the "Mixed update" problem
|
||||
/// in a menu (06-history-undo.md ▸ Commit messages). It reads identically to a body-edit step
|
||||
/// because on the board's stack it *is* the card's edit.
|
||||
public static let cardSession = name(.edit, kind: .card)
|
||||
|
||||
// MARK: Composition
|
||||
|
||||
/// The phrase for one gesture: `"Move Card"`, `"Move 3 Cards"`, `"Restyle Board"`.
|
||||
|
||||
Reference in New Issue
Block a user