Commit Graph
5 Commits
Author SHA1 Message Date
rzen 53bc71f7fb Materialize the trash — store, undo, and the container universe
Phase 2 swaps every consumer: Liveness and its ancestor walk are gone,
replaced by ItemContainer — a UUID set plus the container side it
lives on, presence the whole test, one selection boundary instead of
the old liveness law. Deletion stages by place: board cards move to
the trash at a store-minted head rank, trash-side delete is permanent
behind its confirmation, Delete Immediately skips the trash from
anywhere, lane delete captures the subtree and removes the folder.
Restore has no method at all — moveCards resolves members in either
container, so drag-out and cut-paste are the ordinary moves 13 calls
them, registering ordinary Move steps. The delete inverse moves the
card back to its captured lane and rank; redo replays the captured
trash rank, a value the gesture actually wrote; lane undo recreates
the subtree byte-faithfully in session. Purges register nothing —
where 13's trash section contradicts its own Rules on that, Rules
wins, filed for ruling. Staleness collapsed to present-or-absent: a
container is a path, so a foreign restore fails the delete step's
expectation structurally. Legacy tombstones migrate on the loose-file
tail hook, cards oldest-first so minting above top reproduces the
retired newest-first column, lanes returning live, one folded loss
row naming both directions. Put Back, restoreByDrag,
receiveRestoredCards, TrashEntry, and the kind machinery are deleted;
the trash column renders the container correctly with its full face
rework left to phase 3.

Claude-Session: https://claude.ai/code/session_01SR4XGjmBE16ZUYWpfFHXwY
2026-07-28 17:47:56 -04:00
rzen 46397c740e Build the attachments sidebar section
The card's complete file inventory: compact QuickLook-thumbnail rows
over Card.attachments — no reference tracking, subfolders tolerated
and unsurfaced — with a quiet header add affordance and the drop hint
empty state. The whole window is the file-drop surface, Edit mode
included (the editor's drag types were already filtered; now tested),
sharing the board's folder-refusal semantics literally: FinderDrop
moved verbatim into its own file so both windows run the same
partition and loss row. Dragged text still lands at the caret and is
inert elsewhere — the window delegate accepts file payloads only.
Rows open on double-click or Return, drag out their file URL, and
Remove is a bracketed write through FileManager.trashItem — the system
Trash, never a hard delete, returning the in-Trash URL so the promise
is testable; the attachment listing is the guard, so traversal and
subfolder names refuse in one line. Keyboard-native per 05: the
section is one Tab stop, arrows walk rows by name, Space toggles the
shared QuickLook panel, Backspace removes. File > Add Attachment
(shift-cmd-A) comes alive through the same import path.

Claude-Session: https://claude.ai/code/session_01SR4XGjmBE16ZUYWpfFHXwY
2026-07-28 11:52:37 -04:00
rzen bf18512abc Make Duplicate a cancellable per-item walk with a save-panel fallback
The copy now walks the source tree item by item, checking cancellation
between items, and the in-progress banner row carries its promised
Cancel — a cancelled duplicate removes the partial sibling and never
happened (DESIGN/03 > File menu). A sandbox permission refusal of the
silent Finder-style sibling falls back to an NSSavePanel pre-filled with
the parent folder and the copy name — the panel's grant is the sandbox's
own answer; cancelling the panel cancels quietly, and non-permission
failures keep the ordinary one-shot banner. Refusal classification is
deliberately narrow (NSFileWriteNoPermissionError itself, no underlying-
chain walk) so an unreadable source never masquerades as a destination
refusal. Directories are created writable first with mode and timestamps
restored after the subtree lands, so a read-only source folder can't
strand its own copy. BoardDuplicatorTests grows from 9 to 18 tests.

Claude-Session: https://claude.ai/code/session_01SR4XGjmBE16ZUYWpfFHXwY
2026-07-28 07:20:14 -04:00
rzen 6c490ec71c Build per-surface context menus
The remaining rows of 11-command-nexus.md § Context menus, every entry a
twin of an existing command path, never a parallel implementation:

- Card: Open (the double-click's own openCard closure, always the clicked
  card alone), Rename (Board ▸ Rename's beginRename path), Style… and the
  quick-style recents (already present), Delete (File ▸ Delete's
  store.delete on the standard widened target — selection when the clicked
  card is a member, else the card alone).
- Lane (one menu, header and empty space): Rename and Delete join the
  existing Style…/recents/Width rows, in table order.
- Trash entries and welcome recents verified already exact against the
  table; the attachment row's menu is marked for m6 beside its command.
- File ▸ Reveal in Finder gains its board-window scope, the branch the m4
  comment deferred here: the selection's folders on either side of the
  trash boundary — enabled under every lock, inspection being a read — or
  the board root with nothing selected; a selection resolving to no
  folders disables rather than guessing.

904 unit tests.

Claude-Session: https://claude.ai/code/session_01SR4XGjmBE16ZUYWpfFHXwY
2026-07-27 23:42:37 -04:00
rzen 4b97ecf3f0 Build the welcome screen
The welcome window becomes the real thing: Xcode-style, hidden title
bar with background drag, branding and actions left, recents right —
rows carrying the board symbol, name, location, and the registry's
cached lane/card counts (stamped at close, never a scan at welcome
time), sorted by last opened. Launch failures surface row-level per
02: a failure joins its recents row as a warning caption, an
unresolvable bookmark renders unavailable with Forget its one
affordance, and only a failure with no row to carry it falls back to
a compact list; a board opening again heals its row. New Board
(Opt-Cmd-N) opens the Pages-style template chooser — shipped with
the single Basic template and the m9 seams marked — flowing through
the save panel into createBoard/createLane and straight into a board
window. Open Recent gains its submenu with Clear Menu (byte-identical
to forgetting every row, pinned by test), and File > Duplicate forks
the frontmost board to a Finder-style copy sibling: pending work
flushes first through the close flush's step two alone (sessions stay
open — 09's stated exception), every GUID and tombstone carries (the
whole-board carve-out from copies-remint), and the copy opens in its
own window while the original stays put. 36 new tests.

Claude-Session: https://claude.ai/code/session_01SR4XGjmBE16ZUYWpfFHXwY
2026-07-27 16:50:39 -04:00