Files
lanework/DESIGN/11-command-nexus.md
T
rzen 546fd2840f The corpus catches up with the wave — sixteen colors, a symbol browser, a hideable sidebar, and the context menu's four groups
Amendments the worktree agents owed but could not write: 03's palette
counts and the symbol full-browser reversal (CoreGlyphs-derived catalog),
05's sidebar visibility ruling, 11's Show Sidebar row and the card
context-menu row reshaped to the four-group structure with its two
flagged gaps (style pre-focus, the disabled Navigation pair).

Claude-Session: https://claude.ai/code/session_014PtZdPwqZuqEDLc6wZMtEy
2026-08-09 09:48:39 -04:00

25 KiB
Raw Blame History

Command Nexus

The single source of truth for every command and action the app can perform — what exists, the context it applies in, its default binding, and whether it can be customized. Behavior is specified in the home docs (cross-referenced per row); this inventory is normative for existence, context, and bindings: a command absent here doesn't exist, and adding one means adding a row here first. 04-interactions.md's contract underwrites the tables — every board function has a menu item, keyboard-reachable and remappable, with a default chord only where one earns its keyspace — the "— (no default)" rows below are deliberate — and configuration as the one carve-out (04 ▸ The map) — and 04 remains normative for the behavior behind the rows.

Customizability classes

Class Meaning Customization
M Menu command Remappable system-natively (System Settings ▸ Keyboard ▸ App Shortcuts — 04 ▸ Configurable bindings). Titles are API.
M Menu command, effectively fixed Undo/Redo only: NSUndoManager rewrites their titles dynamically, which defeats title-matched remapping (04).
G Fixed grammar key Platform grammar, deliberately not remappable — Finder's own Return/arrows aren't either (04 ▸ Grammar).
P Pointer grammar Clicks, drags, modifiers — not customizable.
C Configuration control Form-like controls (board popover, chooser, welcome); the keyboard path is reachability (Board Info ⌘I + Tab-reachable controls), not bindings — 04's configuration carve-out. (Container amended 2026-08-07: the board settings sheet and its Board ▸ Board Settings… path retired with the reversal of the 2026-07-31 popover/sheet split — 03 ▸ Board settings sheet.)

Toolbar presence is a separate axis, orthogonal to the classes: toolbar items mirror menu commands, their presence per window is user-customizable (Customize Toolbar — 03-board-ui.md ▸ Toolbar; defaults and catalogs live there), and a toolbar is never a function's only home. Labels match menu titles except Undo/Redo, whose toolbar labels stay static (03).

Menu commands (M unless noted)

Menu Command Default Context
App Settings… ⌘, Everywhere; the app-wide preferences pane. v1 holds one control: "Restore open boards at launch" (02 ▸ Launch and window lifecycle)
File New Card ⌘N Board window; disabled on a zero-lane board. Target rule: 04
File New Lane ⇧⌘N Board window
File New Board… (opens the template chooser) ⌥⌘N Everywhere
File Open… ⌘O Everywhere; standard open panel (boards = .kanban packages and extension-less board folders — 01)
File Open Recent ▸ (with Clear Menu) Everywhere; reads the board registry (02)
File Import Board… (open panel → format detected, never user-picked — Obsidian Kanban frontmatter marker, .csv, lenient Markdown outline as the unfailable fallback → save panel places the fresh .kanban, which opens the ordinary way) — (no default) Everywhere, no board needed in front; 15-import-export.md
File Export ▸ Obsidian Kanban Markdown… / Markdown Outline… / CSV… (three named rows, no format popup — menu titles are API here, and a title whose meaning lives in a popup would be one title standing for three commands; each row a save panel pointed at the right extension; omissions post a loss row, silent when lossless) — (no defaults) Board window; 15-import-export.md
File Board Info (toggles the board popover — opens it closed, closes it open) ⌘I Board window
File Duplicate (the board — a Finder-style "copy" sibling, 03 ▸ Welcome; never the selection) ⇧⌘S Board window
File Save as Template — (no default) Board window; 09-templates.md
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 Add Attachment… ⇧⌘A Card window
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 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 Delete ⌘⌫ Board window, any card or lane selection — staged by place (resettled 2026-07-28; lanes rejoined 2026-07-29): board cards and lanes move to .trash/, trash selections delete permanently (03's recoverability confirm — freight-counting for lanes). Deliberately not extended to the card window: an enabled ⌘⌫ key equivalent would steal delete-to-line-start from the window's text surfaces, so there the card's delete is the sidebar Actions button (05). Delete Immediately (⌥⌘⌫) is deliberately absent (removed 2026-07-30): permanence is only reachable inside the trash — 03 ▸ Trash
File Empty Trash… (confirmed) ⇧⌘⌫ Board window, trash shown and non-empty (whole-trash scope, search-independent — 03 ▸ Trash)
File Print… ⌘P Board window: prints the board as a linear document — lanes in left-to-right order, each lane's cards top-to-bottom, never a graphical snapshot of the strip; the trash is unreachable (it is a sibling container of lanes, not a lane — 01 ▸ Deletion). Card window: prints that card. The sandbox needs an entitlement to print at all (owner-reported 2026-08-09, board window frontmost, row enabled): Kanban.entitlements carried no com.apple.security.print, so a sandboxed NSPrintOperation was denied with the system alert "This application does not support printing" regardless of which code path invoked it — the fix is the entitlement key, not app logic. Also revised the same day, as hardening rather than as the fix: the row is now always enabled — a print is a read, so neither the read-only lock nor the focused-editor rule ever closed it (Reveal in Finder's posture), and the row claims ⌘P unconditionally rather than disabling, because a disabled Button still owns its key equivalent — a window with neither scope (welcome, the template chooser, Settings, the restore-bootstrap window, a card window whose board hasn't joined) used to drop the unclaimed chord into AppKit's own nil-target print handling, whose stock failure happens to be the identical alert text by a wholly separate mechanism. Scope now resolves at the moment ⌘P is pressed instead: board, then card, then — with neither — a one-sentence app-drawn refusal ("Nothing to Print" / "Open a board or a card to print it."), the same voice the empty-document refusal already uses. Finder's own printFiles Apple Event (File ▸ Print… on a selected board, a drag onto a printer queue, a print-and-open service) is implemented rather than left unhandled — its own separate route to the same stock alert: AppDelegate loads the path headless through BoardLoader and either prints it or gives the identical one-sentence refusal. Options ride in a print-panel accessory with the system's live preview: which components (title, icon+labels line, rendered body, comments — off by default, oldest- or newest-first), page breaks (continuous / between lanes / between cards, real sheet boundaries), one base font face and size every other size derives from, and a toggleable header/footer (board title, print date, page numbers, custom line). The option sets persist app-side as named print profiles with a reserved "Last Used" pseudo-profile that auto-captures the most recent settings — UserDefaults, never board data (02 ▸ Per-board app state), the zoom level's own argument. Page Setup… is deliberately absent: the paper questions are answered in the print panel's own page-setup group, so a second dialog would be a second place to set one margin
File Close ⌘W Any window; flushes per 02 ▸ Windows
Edit Undo / Redo (M) ⌘Z / ⇧⌘Z Focus-routed (06 ▸ Undo routing): text undo in a focused editor, git undo otherwise; git undo disabled on no-git and repo-nested boards, during 06's abnormal-state pause (detached HEAD, in-progress merge/rebase), and under the read-only lock (02)
Edit Cut / Copy / Paste ⌘X / ⌘C / ⌘V Board window: cards and lanes (cards-XOR-lanes selections; lane paste lands after the anchor lane — 04 ▸ Clipboard; on a zero-lane board only a lane payload pastes — 04 ▸ ⌘N target rule); in the trash, ⌘C copies out and ⌘X/⌘V is the keyboard restore path (resettled 2026-07-28 — 04 ▸ The trash); paste never targets the trash; ⌘V's image-data branch (2026-08-09 — 04 ▸ Clipboard) lands a pasteboard picture in the anchor card's attachments/, and in a card window in that window's card; text editors: standard text clipboard
Edit Paste as Board Background — (no default) Board window; enabled with image data on the pasteboard and a writable board — no selection needed, since a backdrop has one value per board (2026-08-09 — 03 ▸ Styling ▸ Capabilities)
Edit Select All ⌘A Board: all visible cards on the active board side (filter-respecting); on the active trash side it selects all visible trash rows, both kinds — the container boundary decides which "all" is meant, and trash selection is kind-blind (04 ▸ The trash); text editors: the text
Edit Find ⌘F Board window: board search (04 ▸ Search); card window: find-in-text (05)
Edit Find Next / Find Previous ⌘G / ⇧⌘G Card window: the find bar's stepping — the rows enable only while the comments-thread find bar is up and step that bar; otherwise they disable and the chord falls through the responder chain to the focused text surface's own NSTextFinder stepping (pinned 2026-07-31 — routing by focus applied to find); disabled in the board window — board search is a live filter, not a cursor. Use Selection for Find (⌘E) is deliberately absent: the chord belongs to View ▸ Edit Body, which outranks the text view's binding; a user who wants it back remaps Edit Body system-natively
Board Open Card ⌘↩ Board window, sole selected live card; during an inline title edit (placeholder or rename), commits it and opens — the one board command enabled mid-edit (04 ▸ Grammar)
Board Copy Link — (no default) Board window, sole selected live card; writes the card folder's file:// URL and plain absolute path to the pasteboard, one write, two representations; disabled on multi-selections and wherever edit-shaped actions disable (design ruling 2026-08-09)
Board Rename — (cards: Return in place) Board window, sole selected card/lane; a lane's only rename path (Return on a lane creates); exists for completeness and remapping
Board Style… (the style editor; selection-aware) ⌥⌘S Board window: selected cards or lane; nothing selected = the board
Board Move Up / Move Down ⌥⌘↑ / ⌥⌘↓ Card selection within one lane (within-lane sort, logical order; non-contiguous selections gather behind their first card on the first press); disabled when the selection spans lanes; inert on lanes and on trash cards
Board Move Left / Move Right ⌘← / ⌘→ Lane selection only (one slot; never into the trash) — cards cross lanes by drag or Cut/Paste, not ⌘-arrows; disabled while any text control is focused (04 ▸ Grammar, caret-chords rule)
Board Increase Lane Width / Decrease Lane Width (the stepper's re-divide semantics, never the window's size — 03 ▸ Lane) ⌥⌘→ / ⌥⌘← Selected lane(s) — batches over a multi-lane selection like style (03 ▸ Lane); disabled while any text control is focused (04 ▸ Grammar, caret-chords rule)
Board Pull / Push — (no default) Remote-backed boards only (07); disabled during 06's abnormal-state pause (the whole git surface holds) and on an unresolvable remote (07's one-time remote picker case); popover twins exist
View Show Trash (checkmark toggle) — (no default) Board window — ⇧⌘T is deliberately left to the system's Show Tab Bar: window tabbing stays enabled (settled; see Standard macOS furniture), so the chord is the system's; assign one via the remapping mechanism if wanted (04 ▸ Configurable bindings)
View Zoom In ⌘+ Board window; steps the board's zoom one rung up the ladder (03 ▸ Layout — zoom). Disabled at the top rung, and while a drag session is in flight (a drag freezes geometry the level feeds — the dragged run's heights and the resting-layout cache)
View Zoom Out ⌘− Board window; the twin, one rung down. Disabled at the bottom rung and under the same guard
View Actual Size ⌘0 Board window; returns to 100%, where the strip renders exactly what it rendered before zoom existed. Disabled when already there, and under the same guard. The level is app-wide and persisted across restarts (the Show Comments precedent) — a zoom is a viewing comfort, not a property of any one board
View Edit Body (checkmark toggle) ⌘E Card window; disabled while Raw Source is active
View Show Comments (checkmark toggle) — (no default) Card window; app-wide, persisted across restarts (re-ruled 2026-07-29 — no content-derived auto-show; 05 ▸ The comments column)
View Show Sidebar (checkmark toggle) — (no default) Card window; app-wide, persisted, default on (2026-08-09 — 05 ▸ The attributes sidebar); twin of the card toolbar's sidebar.right item, the fourth default beside Edit Body / Raw Source / Add Attachment
View Comments Beside Body (checkmark toggle) — (no default) Card window; checked = side-by-side (default), unchecked = body over comments; app-wide, persisted (05 ▸ Composition)
View Raw Source (checkmark toggle; toggling off = Apply) ⌥⌘E Card window
View History — (no default) Card window; focuses the sidebar History section (05); git boards only — section absent, item disabled on mode none / repo-nested
View Appearance ▸ Auto — (no default) Everywhere (no board or card window needed); app-wide, persisted across restarts — follows the system appearance; radio-exclusive with Light/Dark, checkmark on the active one (03-board-ui.md ▸ Toolbar)
View Appearance ▸ Light — (no default) Everywhere; app-wide, persisted across restarts; radio-exclusive with Auto/Dark
View Appearance ▸ Dark — (no default) Everywhere; app-wide, persisted across restarts; radio-exclusive with Auto/Light
Window Welcome to Lanework — (no default) Everywhere; shows (or focuses) the welcome window (02 ▸ Launch and window lifecycle)

Fixed grammar keys (G)

All board grammar keys are inert while a title editor is focused, and menu dispatch narrows to the text domain — board-scoped commands disable, text chords route to the field, Open Card ⌘↩ excepted (04 ▸ Grammar, focused-editor rule).

Key Context Action
Arrows / ⇧-arrows Board window Spatial card navigation / extend selection; lane selected: ←/→ move lane selection; shown trash is the last container
⌥↑ / ⌥↓ / ⌥← / ⌥→ Board window Jump: lane's first/last card; first/last lane; ⌥→ reaches the shown trash
Return Board, lane selected Create card at its bottom (placeholder; Return commits and re-selects the lane)
Return Board, sole selected card Inline rename; committing empty removes title; inert on multi-card selections
Escape Board window One layer per press: abandon editor, else clear search (focus to board), else deselect
Board, any selection Delete, staged by place — plain-key synonym of File ▸ Delete (board side moves to .trash/, trash side deletes permanently with 03's confirm), kept grammar so no second "Delete" title exists (04)
Return Card window, Preview Enter Edit
Escape Card window, Edit Return to Preview
Return Card window, title field Commit title, focus into body
⌘↩ Card window, comment composer or inline comment editor focused Post the draft (rename + restamp, one commit) / end the edit session at its commit point — 05 ▸ The comments column; twinned by the Comment / Save buttons
Escape Card window, comment composer focused Focus moves out, draft file untouched — Escape never discards a draft (ruled 2026-07-29; 05 ▸ The comments column)
Escape Card window, inline comment editor focused Cancel — revert to session-start bytes and end the session, the Cancel button's keyboard twin (05)
Escape Card window, title field Abandon: revert to the on-disk title, focus into body — routes by focus, winning over Edit-mode's Escape while the field is focused (05)
Escape / ⌘↩ Card window, source mode Cancel / Apply (leaving-by-toggle is Apply too — 05)
Arrows / Space / Return / ⌫ Card window, attachments section focused Row navigation / QuickLook / open / Remove to system Trash (05)

Pointer grammar (P)

  • Selection clicks (board): click selects, ⌘-click toggles, ⇧-click range-extends, click-drag rubber-bands; lane empty-space click selects the lane, double-click creates a card. Clicking never edits; fast double-click opens the card window (04 ▸ Selection).
  • Drag & drop — the locality model (04): within-board move / cross-board copy; ⌥ always forces copy, ⌘ always forces move; multi-drag; lane header is the lane drag surface; drag-to-restore from the trash.
  • Lane edge drag (03 ▸ Lane): window-growing resize between integer widths — the one width control that moves the window.
  • Finder file drops (04): onto a card = attach; onto lane empty space = one card per file; anywhere on the card window = attach (05's payload-split precedence).
  • Preview (05): task-list checkbox toggle (the one interactive exception), link opens, text selection. In-content controls aren't P-only (settled): checkboxes and links are real controls in the focus/accessibility tree, so Full Keyboard Access + Space and VO-Space reach them (05 ▸ Task-list checkboxes) — content rides the system focus model rather than earning command rows; "a command absent here doesn't exist" scopes to commands, not content.
  • The card window's attachments-section quiet add affordance (05): a pointer twin of File ▸ Add Attachment…, no separate behavior. (The lane header once carried a matching "+" new-card button with its own click-names-target carve-out over 04's ⌘N rule; it is removed — every creation path now goes through the selection-derived rule, Return on a selected lane, or empty-space double-click.)
  • Attachment rows drag out their file URL (05). Welcome rows: single click selects, double click opens (03).

Context menus

Context menus are the per-item action inventory VoiceOver reads (10 ▸ The board through VoiceOver). Every entry is a twin of a menu command, a fixed grammar key, or a configuration control — no function's only home:

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)
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
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
Comment Edit (inline session — 05 ▸ The comments column), Delete (immediate, undoable — 01), Reveal in Finder
Welcome recent Open, Reveal in Finder, Forget (C — registry management, welcome-scoped)

Configuration controls (C)

  • Board popover (Board Info ⌘I — 03 ▸ Board popover; the board's one configuration surface since the 2026-08-07 reversal of the 2026-07-31 popover/sheet split): board rename and the board glyph; the Theme tab's preset backgrounds; the Info tab's dossier; and the Git tab — posture lines (repo-nested explanation, unreadable/paused states — 06); branch display and switch picker with its New Branch… reveal; add-git (mode none, 06); commit-identity name/email (06); ahead/behind with Pull/Push buttons and the status badges.
  • Board settings sheetretired 2026-08-07 (03 ▸ Board settings sheet). Its contents rehomed into the popover above, and Board ▸ Board Settings… left this document's menu inventory with it. 07-sync-collab.md's own surfaces — add/change remote with inline verify, credential fields, the SSH key surface (machine key Copy + Verify, key import by paste or drag, the per-host key picker, removal of an unreferenced import, confirm-gated machine-key regeneration), the Authentication-needed capture and TOFU confirms, the push-on-commit toggle — need a home ruled on that card; they were inventoried here as the sheet's and are homeless until then.
  • Style editor (three anchors — 03 ▸ Styling ▸ Controls): grids arrow-navigable, every well Tab-reachable.
  • Template chooser (09): template selection; Reveal in Finder for the user store.
  • Welcome (03): recents list; Forget.
  • Comments header (05 ▸ The comments column): the sort-direction control (ascending/descending, app-wide persisted) — Tab-reachable beside the count.

Standard macOS furniture

System-provided: App menu (About, Hide, Quit), Window menu, Help (carries the one line teaching the System Settings remap path — 04). The app's own additions to this furniture are inventoried in Menu commands above — App ▸ Settings… and Window ▸ Welcome to Lanework; the remaining app-wide preferences, quick-style recents and NSUserKeyEquivalents, need no UI. Print is the app's own row now (added 2026-08-09, retiring "No Print story in v1 (⌘P unused)"): File ▸ Print… ⌘P above replaces the platform's nil-target item outright, for Undo/Redo's reason — the standard row resolves through the responder chain and this app's print target is the document behind the focused window, which no responder vends. Customize Toolbar… per system convention (03). Window tabbing stays enabled (settled): the system's Show Tab Bar / tab items appear with their standard chords — ⇧⌘T is the system's, which is why Show Trash ships without a default (Menu commands above); tabbed board windows are ordinary system behavior, each tab still a full board window (a tab's saved per-board frame applies when it stands alone — 02-architecture.md).

Changes from Kanban

  • New doc — no pathfinder counterpart; 04's map table moved here (04 keeps the behavioral rules).
  • The first compilation audit added two commands that existed only as context/pointer surfaces, violating 04's contract: File ▸ Open… (⌘O) and File ▸ Reveal in Finder (no default; selection-aware).

Open questions

None currently.