The corpus absorbs the second wave — labels come alive on paper, the sidebar reorders, both context menus and the toolbar say what shipped
01 releases `labels` from the reserved list with its full first-party shape; 04's search note stops calling it inert (integration stays unruled); 05 reorders the sidebar inventory, retires Actions into the toolbar, and adds the Labels section; 11 rewrites the lane menu row to its five groups, brings the card row current (live Navigation, Labels ▸, Copy Special ▸), and adds the chord-less File ▸ Delete Card twin. Claude-Session: https://claude.ai/code/session_014PtZdPwqZuqEDLc6wZMtEy
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -85,7 +85,7 @@ Custom shortcuts are **system-native, with no in-app remapping UI**: macOS's App
|
|||||||
|
|
||||||
## Search
|
## Search
|
||||||
|
|
||||||
- Search field invoked with ⌘F (the board toolbar's sole default item; removed from the toolbar, ⌘F surfaces it transiently — 03-board-ui.md ▸ Toolbar; in the **card window**, Edit ▸ Find is find-in-text instead — 05-card-window.md), live filter: cards whose title *and* body both miss the query animate out; case/diacritic-insensitive substring. Scope is **all card content the format makes meaningful** (re-ruled 2026-07-29, superseding title-plus-body-only): title + body today; **comment bodies join when comments ship** — via a search-owned transient comment index, never the snapshot: the first live-query keystroke kicks an async sweep of `comments/*/index.md` bodies (`.draft` and `comments/.trash/` excluded), kept fresh by the same FSEvents stream while a query is active and discarded when it clears — the board walk stays O(cards), 01's window-scoped read untouched; **attributes join as they activate** (title now; labels/tags and their kin are reserved, inert keys this version — nothing to search until a future version gives them life). Attachment filenames stay unsearched. Scope options (content vs attributes, either/or) are WISHLIST #10.
|
- Search field invoked with ⌘F (the board toolbar's sole default item; removed from the toolbar, ⌘F surfaces it transiently — 03-board-ui.md ▸ Toolbar; in the **card window**, Edit ▸ Find is find-in-text instead — 05-card-window.md), live filter: cards whose title *and* body both miss the query animate out; case/diacritic-insensitive substring. Scope is **all card content the format makes meaningful** (re-ruled 2026-07-29, superseding title-plus-body-only): title + body today; **comment bodies join when comments ship** — via a search-owned transient comment index, never the snapshot: the first live-query keystroke kicks an async sweep of `comments/*/index.md` bodies (`.draft` and `comments/.trash/` excluded), kept fresh by the same FSEvents stream while a query is active and discarded when it clears — the board walk stays O(cards), 01's window-scoped read untouched; **attributes join as they activate** (title now; `labels` came alive 2026-08-09 — 01 § Frontmatter — but its search integration is deliberately unruled: labels stay unsearched until that pass happens; `assignees`/`due` remain reserved and inert). Attachment filenames stay unsearched. Scope options (content vs attributes, either/or) are WISHLIST #10.
|
||||||
- The filter is the single source of truth for "what's on the board": layout, drop zones, marquee, ranges, arrow nav, and lane count badges all read it. **A drop under an active filter counts in the rendered space** (ruled 2026-08-06, closing the divergence found 2026-08-01): the zones, the shadow, and the write all resolve through the same filtered list — the position the shadow shows is the landing the write performs (the shipped interim — zones and write counting the unfiltered lane while the slots rendered filtered — was self-consistent but named a position the user could not see; retired). The slot's meaning in the full order is its **visible anchor**: the dropped card enters immediately *after* the slot's visible predecessor — or immediately *before* its visible successor when the slot has none (top of the lane) — and a lane the query emptied appends at its true end; a multi-card drop enters in proposal order beside the same anchor. Hidden cards keep their ranks untouched, never displaced by a gesture that could not see them — and the anchor is what makes the gesture's meaning survive the query's clearing: when the filter lifts, the card sits exactly beside the card it was dropped against. The rendered space means everything rendered — the new-card placeholder occupies its slot for the zones exactly as it does for layout. Hidden cards leave the selection; creating a card clears the search — creation's carve-out exists because a brand-new card must not be born invisible, and it is **stated by mechanism, not by gesture** (settled): *any* user-initiated creation on the board clears the query — ⌘N, Return-creation, empty-space double-click, paste, and Finder file drops alike — while foreign/agent-filed cards keep riding the live filter (02-architecture.md's derived-result rule). **Rename deliberately gets no carve-out**: a rename committed during an active search re-runs the predicate like any edit — a title that stops matching animates the card out and drops it from the selection, exactly as an agent's edit would; the filter stays a pure predicate with one exception, not two. **Escape is staged** (settled): in a non-empty field it clears the query, focus staying in the field; in an empty field it returns focus to the board; with *board* focus and an active search, one press clears the search and the full board returns — search takes Escape before its clear-selection meaning, which applies only when no search is active. **A lane the query empties keeps its slot** (settled): lanes are never filtered out — an all-misses lane stays on the board at its width with a 0 badge (the count reads the filter, 03-board-ui.md); the search filters cards, and the board's structure is not a search result. **A leaving card stays input-reachable for its out-transition** (settled): marquee and arrow targets deregister when the ~0.28 s animate-out ends, so a card mid-departure is briefly reachable while already out of the selection — accepted: it is literally on screen for that span, and closing the window would teach three input sites a predicate the layout already applied. **An open inline rename survives the filter hiding its card** (settled): the editor is a surface the filter doesn't reach — it stays open and focused, commits by UUID wherever the card lives, Escape abandons; keystrokes are never silently discarded for a card that still exists (the dirty-buffer courtesy), and the vanish-discard rule stays reserved for true liveness flips. The typed-query path can't even occur — focusing the search field is focus loss, which commits the rename first — so the rule covers foreign edits that stop the card matching.
|
- The filter is the single source of truth for "what's on the board": layout, drop zones, marquee, ranges, arrow nav, and lane count badges all read it. **A drop under an active filter counts in the rendered space** (ruled 2026-08-06, closing the divergence found 2026-08-01): the zones, the shadow, and the write all resolve through the same filtered list — the position the shadow shows is the landing the write performs (the shipped interim — zones and write counting the unfiltered lane while the slots rendered filtered — was self-consistent but named a position the user could not see; retired). The slot's meaning in the full order is its **visible anchor**: the dropped card enters immediately *after* the slot's visible predecessor — or immediately *before* its visible successor when the slot has none (top of the lane) — and a lane the query emptied appends at its true end; a multi-card drop enters in proposal order beside the same anchor. Hidden cards keep their ranks untouched, never displaced by a gesture that could not see them — and the anchor is what makes the gesture's meaning survive the query's clearing: when the filter lifts, the card sits exactly beside the card it was dropped against. The rendered space means everything rendered — the new-card placeholder occupies its slot for the zones exactly as it does for layout. Hidden cards leave the selection; creating a card clears the search — creation's carve-out exists because a brand-new card must not be born invisible, and it is **stated by mechanism, not by gesture** (settled): *any* user-initiated creation on the board clears the query — ⌘N, Return-creation, empty-space double-click, paste, and Finder file drops alike — while foreign/agent-filed cards keep riding the live filter (02-architecture.md's derived-result rule). **Rename deliberately gets no carve-out**: a rename committed during an active search re-runs the predicate like any edit — a title that stops matching animates the card out and drops it from the selection, exactly as an agent's edit would; the filter stays a pure predicate with one exception, not two. **Escape is staged** (settled): in a non-empty field it clears the query, focus staying in the field; in an empty field it returns focus to the board; with *board* focus and an active search, one press clears the search and the full board returns — search takes Escape before its clear-selection meaning, which applies only when no search is active. **A lane the query empties keeps its slot** (settled): lanes are never filtered out — an all-misses lane stays on the board at its width with a 0 badge (the count reads the filter, 03-board-ui.md); the search filters cards, and the board's structure is not a search result. **A leaving card stays input-reachable for its out-transition** (settled): marquee and arrow targets deregister when the ~0.28 s animate-out ends, so a card mid-departure is briefly reachable while already out of the selection — accepted: it is literally on screen for that span, and closing the window would teach three input sites a predicate the layout already applied. **An open inline rename survives the filter hiding its card** (settled): the editor is a surface the filter doesn't reach — it stays open and focused, commits by UUID wherever the card lives, Escape abandons; keystrokes are never silently discarded for a card that still exists (the dirty-buffer courtesy), and the vanish-discard rule stays reserved for true liveness flips. The typed-query path can't even occur — focusing the search field is focus loss, which commits the rename first — so the rule covers foreign edits that stop the card matching.
|
||||||
- **Dispatch while the search field is focused** (settled): the field is a *control*, not a content editor — the focused-editor lockdown (Grammar above) does not apply. Text-domain keys route to the field: ⌘A/⌘X/⌘C/⌘V act on the query, plain ⌫ edits the query and never reaches the board, horizontal arrows move the caret. **Every key with the field focused acts on the field — stock NSSearchField behavior, no pass-throughs** (settled): vertical arrows are caret movement, ⇧-arrows select query text, and **Return is a swallowed no-op** (the filter is live, there is nothing to submit — it never reaches the board's rename/create grammar). **Tab is the keep-filter path**: plain key-view traversal moves focus to the board with the query intact, and the whole board grammar (arrows, ⌥↑ escalation, Return, ⌘↩) then applies over the *filtered* board; ⌘F returns to the field. Board menu commands stay enabled and act on the board selection exactly as when the field is unfocused — ⌘N included (creating a card clears the search, above) — **except the caret-chord commands**: Move Left/Right ⌘←/⌘→ and the width pair ⌥⌘←/⌥⌘→ disable while the field is focused (Grammar above, caret-chords rule), so ⌘←/⌘→ stay line-start/end in the query even with a lane selected — and the Delete pair stays unambiguous by construction: plain ⌫ is query editing, ⌘⌫ is File ▸ Delete on the selection, and ⌘Z/⇧⌘Z are the field's own text undo, never git undo (06-history-undo.md ▸ Undo routing's control-class rule).
|
- **Dispatch while the search field is focused** (settled): the field is a *control*, not a content editor — the focused-editor lockdown (Grammar above) does not apply. Text-domain keys route to the field: ⌘A/⌘X/⌘C/⌘V act on the query, plain ⌫ edits the query and never reaches the board, horizontal arrows move the caret. **Every key with the field focused acts on the field — stock NSSearchField behavior, no pass-throughs** (settled): vertical arrows are caret movement, ⇧-arrows select query text, and **Return is a swallowed no-op** (the filter is live, there is nothing to submit — it never reaches the board's rename/create grammar). **Tab is the keep-filter path**: plain key-view traversal moves focus to the board with the query intact, and the whole board grammar (arrows, ⌥↑ escalation, Return, ⌘↩) then applies over the *filtered* board; ⌘F returns to the field. Board menu commands stay enabled and act on the board selection exactly as when the field is unfocused — ⌘N included (creating a card clears the search, above) — **except the caret-chord commands**: Move Left/Right ⌘←/⌘→ and the width pair ⌥⌘←/⌥⌘→ disable while the field is focused (Grammar above, caret-chords rule), so ⌘←/⌘→ stay line-start/end in the query even with a lane selected — and the Delete pair stays unambiguous by construction: plain ⌫ is query editing, ⌘⌫ is File ▸ Delete on the selection, and ⌘Z/⇧⌘Z are the field's own text undo, never git undo (06-history-undo.md ▸ Undo routing's control-class rule).
|
||||||
|
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ Key grammar in source mode, completing the window's key story: **Escape is Cance
|
|||||||
|
|
||||||
## The attributes sidebar
|
## The attributes sidebar
|
||||||
|
|
||||||
Stacked sections under small-caps headers, in this order; quiet rows, read-optimized, edit affordances only where a section edits. The sidebar is the card's non-body inventory — future attributes (enhanced-schema fields, if they ever ship) slot in as new sections rather than growing new bars.
|
Stacked sections under small-caps headers, in this order; quiet rows, read-optimized, edit affordances only where a section edits. The sidebar is the card's non-body inventory — future attributes slot in as new sections rather than growing new bars. **Order re-ruled 2026-08-09** (Pipeline cards 8f26b029, a4462d28): **Style · Labels · Details · Attachments** — attachments moved to the bottom, Labels (the newly activated key, 01 § Frontmatter) sits above Details deliberately: Details is the section for keys the app does *not* own. The section headers below predate the reorder; the list above is the order.
|
||||||
|
|
||||||
### Attachments
|
### Attachments
|
||||||
|
|
||||||
@@ -79,10 +79,13 @@ The card-level styling home: the **Background color combo** over the compact **`
|
|||||||
- The section is **absent** on boards without app-managed git (mode none, repo-nested) — same honesty rule as the popover's git section (06-history-undo.md). Rows are focusable (arrows), but carry **no actions in v1** — restoring an old version stays a git-client task for now; a per-row forward-restore and lane history are wishlist items, deliberately.
|
- The section is **absent** on boards without app-managed git (mode none, repo-nested) — same honesty rule as the popover's git section (06-history-undo.md). Rows are focusable (arrows), but carry **no actions in v1** — restoring an old version stays a git-client task for now; a per-row forward-restore and lane history are wishlist items, deliberately.
|
||||||
- Menu path (contract): **View ▸ History** in the card window focuses the section — no default chord.
|
- Menu path (contract): **View ▸ History** in the card window focuses the section — no default chord.
|
||||||
|
|
||||||
### Actions (bottom)
|
### Actions — retired 2026-08-09 (Pipeline card bcd3b323)
|
||||||
|
|
||||||
- **Delete** — moves the card to the trash (destructive styling; the window then dismisses itself per Deletion & lifecycle below; recoverable from the board's trash lane — 03-board-ui.md).
|
The section's two rows moved to the card window's toolbar: **Delete Card** (trash symbol, a default item behind a trailing flexible space — Mail's own Delete placement; same no-confirm staged trash move, window dismissing per Deletion & lifecycle) and **Reveal in Finder** (catalog-only, customization adds it). Because every toolbar item needs a menu-row twin and ⌘⌫ stays reserved for the window's text surfaces, a chord-less **File ▸ Delete Card** row was added as Delete Card's twin (11-command-nexus.md). The sidebar toggle itself sits rightmost in the toolbar defaults (card 084d127f), and the sidebar as a whole can be hidden — Composition above.
|
||||||
- **Reveal in Finder** — the card's folder.
|
|
||||||
|
### Labels (added 2026-08-09 — cards a4462d28/28c79ffe)
|
||||||
|
|
||||||
|
The card's `labels` as removable rows with an add affordance (combo/autocomplete over the board's used-label universe + free-text creation). The key is schema-owned now — 01 § Frontmatter; the twelve-slot context-menu submenu and its More… dialog are the other surface (11 ▸ Context menus). Labels on the card *face* deliberately await their own design pass.
|
||||||
|
|
||||||
## The comments column
|
## The comments column
|
||||||
|
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ The single source of truth for **every command and action the app can perform**
|
|||||||
| File | Share… (the board, staged as a `.zip`, `NSSharingServicePicker` anchored to the board window's toolbar or its center) | — (no default) | Board window; design ruling 2026-08-09, card 72691b11 — a faithful copy like Duplicate's (`.git` the sole exclusion; attachments, comments and `.trash/` carried), never gated on the read-only lock (a share is a read, `Print…`'s own posture), disabled only while an inline title editor is focused |
|
| File | Share… (the board, staged as a `.zip`, `NSSharingServicePicker` anchored to the board window's toolbar or its center) | — (no default) | Board window; design ruling 2026-08-09, card 72691b11 — a faithful copy like Duplicate's (`.git` the sole exclusion; attachments, comments and `.trash/` carried), never gated on the read-only lock (a share is a read, `Print…`'s own posture), disabled only while an inline title editor is focused |
|
||||||
| File | Reveal in Finder | — (no default) | Board window: the selection's folder(s), or the board root with nothing selected; card window: the card's folder — the selected attachment's file instead when the attachments section is focused; welcome: the selected recent's folder (disabled on unavailable rows) — the context-menu entry's required twin |
|
| File | Reveal in Finder | — (no default) | Board window: the selection's folder(s), or the board root with nothing selected; card window: the card's folder — the selected attachment's file instead when the attachments section is focused; welcome: the selected recent's folder (disabled on unavailable rows) — the context-menu entry's required twin |
|
||||||
| File | Add Attachment… | ⇧⌘A | Card window |
|
| File | Add Attachment… | ⇧⌘A | Card window |
|
||||||
|
| File | Delete Card | — (no default, deliberately chord-less) | Card window (2026-08-09, card bcd3b323 — the retired sidebar Actions row's menu twin, required because its toolbar item needs one and ⌘⌫ stays reserved for the window's text surfaces; 05 ▸ Actions) |
|
||||||
| File | Set as Hero | — (no default) | Card window; the attachments section's selected row, when it is an image the card is not already using (2026-08-09 — 03 ▸ Card face ▸ Hero image). Twin of the row's own context entry; **two rows rather than one that renames itself**, since titles are the remapping key |
|
| File | Set as Hero | — (no default) | Card window; the attachments section's selected row, when it is an image the card is not already using (2026-08-09 — 03 ▸ Card face ▸ Hero image). Twin of the row's own context entry; **two rows rather than one that renames itself**, since titles are the remapping key |
|
||||||
| File | Remove Hero | — (no default) | Card window; the selected row when it *is* the card's hero — the key goes, the file stays. See Set as Hero for why the pair is two rows |
|
| File | Remove Hero | — (no default) | Card window; the selected row when it *is* the card's hero — the key goes, the file stays. See Set as Hero for why the pair is two rows |
|
||||||
| File | Add Comment | — (no default) | Card window (all tiers — 12); if Show Comments is off, turns it on (persisted, the same user choice) and focuses the composer — 05 ▸ The comments column |
|
| File | Add Comment | — (no default) | Card window (all tiers — 12); if Show Comments is off, turns it on (persisted, the same user choice) and focuses the composer — 05 ▸ The comments column |
|
||||||
@@ -106,8 +107,8 @@ Context menus are the per-item action inventory VoiceOver reads (10 ▸ The boar
|
|||||||
|
|
||||||
| Surface | Entries |
|
| Surface | Entries |
|
||||||
|---|---|
|
|---|---|
|
||||||
| Card | Four groups, separators between (reshaped 2026-08-09, Pipeline card fe66c461): **1** Open, Copy Link (kept — same-day feature, 2026-08-09), Rename, Style ▸ Symbol / Color (both open the Style… popover; no per-section focus yet — flagged); **2** Copy, Cut, Paste, Paste Special ▸ Paste Image into Card (enabled when the pasteboard carries an image); **3** Navigation ▸ Move Left / Move Right (wired but disabled — no per-card cross-lane move exists yet; follow-up Pipeline card 06322636); **4** Send to Trash (the board-side word for the staged `.trash/` move — "Delete" stays the trash lane's). The quick-style recents row left this menu in the reshape (flagged for review; the ⌥-alternate Delete Immediately row had already retired with its command, 2026-07-30) |
|
| Card | Four groups, separators between (reshaped 2026-08-09, Pipeline card fe66c461): **1** Open, Copy Link (kept — same-day feature, 2026-08-09), Rename, Style ▸ Symbol / Color (both open the Style… popover; no per-section focus yet — flagged); **2** Copy, Cut, Paste, Paste Special ▸ Paste Image into Card (enabled when the pasteboard carries an image); **3** Navigation ▸ Move Left / Move Right (**live since 085a84a, 2026-08-09** — a real per-card cross-lane move: clicked card widened to the selection Copy/Cut-style, index-preserving landing in the adjacent live lane through the drop's own rank machinery, disabled on lane-spanning selections, enablement via cheap per-lane compared parameters); **4** Send to Trash (the board-side word for the staged `.trash/` move — "Delete" stays the trash lane's). Amended same day (cards 28c79ffe/a4462d28): group 1 gains **Labels ▸** (twelve frequency-then-recency ranked checkmark toggles for the clicked card, then More… — a dialog over all used labels + creation) and Copy Link moved from group 1 into a new **Copy Special ▸** submenu in group 2, mirroring Paste Special. The quick-style recents row left this menu in the reshape (flagged for review; the ⌥-alternate Delete Immediately row had already retired with its command, 2026-07-30) |
|
||||||
| Lane | One menu, invoked on the header or lane empty space (settled — a full lane still has its header): Rename, Style…, quick-style recents row (03), Width control (stepper — menu twins Increase/Decrease Lane Width), Delete |
|
| Lane | Five groups, separators between (reshaped 2026-08-09, Pipeline card 22f660b0; invocation unchanged — header or lane empty space): **1** Rename, Properties… (deliberately inert placeholder for a future pane), Style ▸ Symbol / Color (one shared popover, the card menu's v1 posture); **2** Copy, Cut, Paste (Copy/Cut widen to the clicked lane — the card menu's explicit-target twins; Paste stays generic); **3** Width ▸ Increase / Decrease / Reset (Reset = width 1 through the same write, key removed at default, disabled when already there); **4** Collapse Lane / Expand Lane (title-flip row); **5** Send to Trash (relabeled from "Delete"; lanes rejoined the trash 2026-07-29). Quick-style recents row dropped for symmetry with the card menu (flagged for review) |
|
||||||
| Trash selection | Delete (permanent — 03's recoverability confirm), Reveal in Finder (inspection before a purge; twin of File ▸ Reveal in Finder, not edit-shaped, enabled on trash selections — 04 ▸ The trash) |
|
| Trash selection | Delete (permanent — 03's recoverability confirm), Reveal in Finder (inspection before a purge; twin of File ▸ Reveal in Finder, not edit-shaped, enabled on trash selections — 04 ▸ The trash) |
|
||||||
| Attachment row | Open, Remove (system Trash) — twins of the focused section's grammar keys (Return / ⌫ — 05); Reveal in Finder — twin of File ▸ Reveal in Finder in its attachments-focused context; **Set as Hero / Remove Hero** (2026-08-09 — 03 ▸ Card face ▸ Hero image) — one slot with two words, present on image rows only and absent rather than greyed where neither applies; twins of the two File rows below, which address the section's *selected* row |
|
| Attachment row | Open, Remove (system Trash) — twins of the focused section's grammar keys (Return / ⌫ — 05); Reveal in Finder — twin of File ▸ Reveal in Finder in its attachments-focused context; **Set as Hero / Remove Hero** (2026-08-09 — 03 ▸ Card face ▸ Hero image) — one slot with two words, present on image rows only and absent rather than greyed where neither applies; twins of the two File rows below, which address the section's *selected* row |
|
||||||
| Comment | Edit (inline session — 05 ▸ The comments column), Delete (immediate, undoable — 01), Reveal in Finder |
|
| Comment | Edit (inline session — 05 ▸ The comments column), Delete (immediate, undoable — 01), Reveal in Finder |
|
||||||
|
|||||||
Reference in New Issue
Block a user