Implement the hybrid clipboard with deferred cut
⌘X/⌘C/⌘V for cards and lanes per 04-interactions.md § Clipboard: - ClipboardStore stages full folder snapshots eagerly at the gesture into Application Support (at most the current copy; sweep at launch and on each copy purges what the pasteboard no longer references; a copy made before quitting pastes whole after restart) and writes the pasteboard a JSON manifest — every entry embedding its index.md, lane entries their cards' too — plus plain-text titles. - Cut is Finder-style deferred: items dim in place off pendingCut, void on pasteboard takeover (changeCount, no timers), source-board close, or per-item external tombstoning; the first armed paste moves the surviving originals whole (tombstoned interior cards land in the destination's trash), a second paste materializes copies from staging. - Paste anchors by the shared flatten-order rule (NewCardTarget's anchor, extracted); a tombstoned selection never anchors; lane paste reaches the right end and stays enabled on a zero-lane board; paste into the source board is the within-board lane duplicate; copies keep created, take fresh GUIDs, and strip tombstoned cards; trash-sourced copies strip deleted: at materialization; ⌘X is disabled on the trash side. - A degraded paste is loud, never silent: staging gone → the embedded index.md fallback lands content-intact, attachments absent, and a BannerCenter-phrased row names what was lost. - The standard Edit items validate through conditionally-attached onCommand handlers, so AppKit's enablement mirrors the availability predicates; text fields keep their own clipboard while focused. 879 unit tests (68 new). Claude-Session: https://claude.ai/code/session_01SR4XGjmBE16ZUYWpfFHXwY
This commit is contained in:
@@ -9,7 +9,12 @@ import Observation
|
||||
/// mixes live and tombstoned items, so the side is a property of the set as a whole rather than of
|
||||
/// each member — which is exactly what makes re-resolution across a reload a matching rule rather
|
||||
/// than a partition.
|
||||
public enum Liveness: Sendable, Equatable {
|
||||
///
|
||||
/// **`String`-backed and `Codable` because the clipboard manifest carries one** (04-interactions.md
|
||||
/// ▸ Clipboard: a manifest records its entries' "source side (live/trashed)"). The raw spellings are
|
||||
/// therefore pasteboard API — a manifest written before a quit is decoded after the relaunch — and
|
||||
/// they are the case names so nothing has to remember a second vocabulary.
|
||||
public enum Liveness: String, Codable, Sendable, Equatable {
|
||||
case live
|
||||
case trashed
|
||||
|
||||
|
||||
Reference in New Issue
Block a user