1817d6f0b9049ec47cef5026fb4e6a244cdcc969
9
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
c27cc93ec1 |
The card window's title learns Edit mode — a sibling session rides the body's own doors
CardWindowView's header is now the title, live: a static Text in Preview, an editable single-line TextField in Edit, both reading a new CardTitleEditSession's buffer rather than the card's own snapshot value — the same "buffer outranks the snapshot" reason the body surface already reads bodySession.text instead of card.body. CardTitleEditSession is CardBodyEditSession's shape one field over: the one-isDirty write gate, dirty-buffer-wins on adopt(diskTitle:), the ~700ms injectable debounce, flush() / flushOrThrow() for DirtyBufferGuard, and beginEditSession()/endEditSession() with a session-coalesced undo step (one per session, never per debounced tick). It rides the body's own begin/end/flush doors rather than opening a second session boundary — title is only ever editable while the body column is in Edit mode — because the two write through different WriteOperations with different validation and merging them would conflate two unrelated frontmatter keys behind one buffer. BoardStore.commitCardTitle(inCard:title:) reuses the same private setTitle helper and the same .rename WriteOperation the board's own inline rename commits through, so trimming, empty-removes-the-key, unchanged-writes-nothing and banner enrichment are one code path, not a re-implementation. It resolves through cardBodyTarget (spans lanes and the trash), not boardItem (board only), because a card window's title field stays live through the same dismissal-into-trash flush the body already gets — the one deliberate divergence from the board's own rename, which treats a trashed target as vanished. registerTitleEdit(inCard:priorTitle:newTitle🔛) mirrors registerBodyEdit, anchored by card identity and the already-reserved ExpectedField.title, folding into the same one-coarse-step-per-window-close undo model. Every place the body's Edit buffer flushes, the title's now does too: mode exit (bodyPresentation.flushEdits/beginEdits), window close and the dismissal path (CardWindowSession.endSession()), raw-source entry (configureRawSource), the close-time DirtyBufferGuard modal (attemptSave tries body then title), and the fast-path close gate (closeAfterFlushing() now checks title.isDirty alongside body.isDirty). holdsUnsavedContent and settlement carry the title too. Tests: CardTitleEditSessionTests.swift mirrors CardBodyEditSessionTests.swift (write gates, normalization and newline-stripping, dirty-buffer-wins, debounce, undo-step coalescing). CardTitleWriteTests.swift covers commitCardTitle/registerTitleEdit: byte-identity no-op, empty-removes-key, vanished, the trashed-card-is-still-writable divergence, a readable-but-uneditable target refusing and bannering, and a read-only board suspending quietly. CardSessionUndoTests.swift gains coverage that a title edit folds into the coarse close step alongside a body edit and registers on the window's own stack, never the board's. RawSourceTests.swift's hand-wired rig picks up the title session configureRawSource now also flushes. 3148 KanbanTests pass, 0 failures. Claude-Session: https://claude.ai/code/session_014PtZdPwqZuqEDLc6wZMtEy |
||
|
|
dfc6057f0d |
The sidebar's Actions section retires — Delete and Reveal in Finder move to the card window's toolbar
Actions is gone from the trailing sidebar. Its two rows land on the card
window's toolbar instead: Delete Card is a new default item (trash SF
Symbol), and Reveal in Finder joins the customizable catalog. The sidebar's
final order is now Style, Details, Attachments — no fourth section.
Delete Card is a push button gated by the same read-only predicate the
sidebar button carried, and it fires the identical write
(BoardStore.deleteCard(_:)) — same bracket, same stamps, no confirmation,
matching the delete flow exactly: recovery is the board's trash lane, so
there is nothing here for an alert to guard. It sits behind a trailing
flexibleSpace in the default set, apart from the four creation/view items
ahead of it, the HIG separation Mail.app's own toolbar Delete models —
one-click, no-confirm, recoverable by trash.
Reveal in Finder is catalog-only: it already had a menu-bar twin with no
default chord (File ▸ Reveal in Finder / RevealInFinderCommand), so nothing
was unreachable before this — the toolbar item is Customize's shortcut to
the same computation (CardAttachments.revealURLs), not a new path.
Delete Card needed a menu-row twin of its own before it could sit on the
toolbar at all ("toolbars are pure enhancement: every function they host
already has a menu item + shortcut" — 03-board-ui.md ▸ Toolbar). File ▸
Delete Card is that row: distinctly titled from the board-scope File ▸
Delete (whose title 11-command-nexus.md calls out as the ⌘⌫ chord's
singleton), and deliberately chord-less — an enabled delete-key equivalent
in the card window would steal delete-to-line-start from its text surfaces,
the same reason the board's own ⌘⌫ was never extended here in the first
place. A new small handle, CardWindowActions, carries the wiring through the
focus system the way CardAttachments and CardPrintSubject already do for
their own single-purpose seams — kept separate from CardAttachments on
purpose, since a delete has nothing to do with the attachments section that
type is scoped to.
CardToolbarTests grows the BoardToolbarTests split (defaults vs. catalog,
now that they differ) plus two new suites: Delete Card firing the wired
write under the lock, and Reveal in Finder's enablement mirroring the menu
row's own card-window computation.
05-card-window.md's Actions section and 11-command-nexus.md's File-menu
inventory are now stale; both amendments are owed and tracked on the card's
own thread rather than made here.
Claude-Session: https://claude.ai/code/session_014PtZdPwqZuqEDLc6wZMtEy
|
||
|
|
05ae703989 |
replace symbol grid in card window sidebar with a compact symbol picker
The card window sidebar's Style section embedded StyleEditorView symbols-only (showsBackground: false, showsSymbols: true), drawing the curated grid whole inside the sidebar's own scroll view — a permanently open 5-7 row grid ahead of every other section. Replace it with the reusable compact SymbolPicker (already used by BoardInfoPopover for the board's glyph): a single well at rest, the grid only inside its own popover. - CardStyleSection no longer instantiates StyleEditorView at all. A new "Symbol" row mirrors the existing "Background" row's inspector shape (caption leading, control trailing), wiring SymbolPicker's onSelect/ onSelectColor to icon/iconColor through StyleCommand.apply(...on: undo), the exact funnel the background combo already rides — so the card window's undo session semantics (13-native-undo.md) are unchanged. - The picker is fed CuratedSymbols.available rather than its own smaller general-purpose default, so a card's curated vocabulary doesn't shrink. - StyleEditorLayout.sidebar and showsBackground stay in StyleEditor.swift (still correct, still tested) rather than being cut as dead code — a separate, larger cleanup this card doesn't make (recorded on the card). - DESIGN/03-board-ui.md and DESIGN/05-card-window.md: updated the sentences describing the sidebar hosting the style editor's symbol grid to describe the compact picker instead. - Tests: CardSessionUndoTests gains a symbol/tint analogue of the existing background-combo session-routing test; CardSidebarTests gains a curated-set tripwire and an updated file-header note. Claude-Session: https://claude.ai/code/session_014PtZdPwqZuqEDLc6wZMtEy |
||
|
|
2d919b8131 |
The prose catches up with the one-version app — tier qualifiers retired, the entitlement comment carried over
The excision's follow-up sweep: present-tense prose that still implied an edition axis now reads
correctly under one version ("in every tier" clauses dropped or turned substrate-shaped, the
announcer's "every free-tier bracket today" is "every bracket today" — nothing passes a phrase),
and forward-looking promises pinned to the mooted pro-m1/pro-m2 milestones now name the thing
itself (the change narrator in Kanban/Changes/, the foreign-change journal successor) or fall to
past tense. Kanban.entitlements' network-client comment sheds its "dormant until Pro ships"
framing for the pivot's own reasoning: the key stays because the sync capability to come needs
it regardless. Untouched on purpose: the storage layer's coerce/tolerate/refuse tiers, the
chooser's bundled/user/keyless tiers, verbatim design-doc quotations, and genuine past-tense
record. One dangling reference repaired en route: EndToEndVerification.md cited the long-renamed
InertGitTests. Comment-only throughout; 2,686 unit tests green, unchanged.
Claude-Session: https://claude.ai/code/session_014PtZdPwqZuqEDLc6wZMtEy
|
||
|
|
edaf5be706 |
The stack comes out — Kanban/Git/ deleted wholesale, ten thousand lines into history
Step 5 of strategy/01-git-excision.md: the seventeen dead engine files and the five remaining git test suites go (InertGitTests stays — the naming footgun is a Storage keeper). Two rescues ride ahead of the delete: HarvestedReceipt relocates to EchoLedger (the harvest surface outlives its git consumer; foundation for the deferred journal), and commentTimestamps joins the narrator it always served. The provider-swap purge test re-expresses over a git-free fake; the duplicate-id ladder keeps every pure historyRank pin and loses only the two ranker-driven ones. Resurrection point: tag pre-git-excision. 2,707 tests green. Claude-Session: https://claude.ai/code/session_014PtZdPwqZuqEDLc6wZMtEy |
||
|
|
d5ad21c3da |
The board wears a picture — background becomes a mapping, and the window chrome follows it under a thin frost
background is {color:, image:} and only a mapping at every level; the board's image paints the full window under a transparent title bar, with a thin-material frost strip keeping the chrome legible and the standard accommodations intact.
Claude-Session: https://claude.ai/code/session_014PtZdPwqZuqEDLc6wZMtEy
|
||
|
|
274ccd9ff5 |
Realign code with the 2026-07-31 findings-resolution rulings
The full bullet list from Implementation card bf080d9a — both ruling batches, including the three appended mid-session by |
||
|
|
d076427ee0 |
Realign undo with the evening rulings — repo-nested and identity anchors
Repo-nested boards bind native undo in every tier ( |
||
|
|
a381fac742 |
Make the card window the commit unit on Pro boards
Phase C of the two-level undo card: the committer stages around the
whole open card folder — comments included — so gestures in an open
window never land in interim commits; window close flushes the session
as one semantically-named commit ("Edit card 'X'" with the thread as
body bullets, "Mixed update — N changes to card 'X'" when events mix),
with the two-commit foreign/user split preserved and the
comments/.trash purge riding the same bracket. Comment gestures lose
their per-gesture commits structurally (they write inside the held
folder). Branch-switch settle releases every window's staging before
checkout and re-arms on resume.
Fixes two latent pro-m1 defects: the committer was composed without
the store's EchoLedger, so every production commit classified foreign
and was authored Lanework External; and interim flushes dropped
harvest receipts they had not spent, unvouching the session's own
writes at close. Also lands 06's mixed-subject re-ruling (the retired
"Update board" fallback) and phase B's two files missed by the
previous commit's pathspec.
2444 tests in 422 suites green.
Claude-Session: https://claude.ai/code/session_01CqjXB7ASoWtbyoGod68k97
|