Repository navigation
Conversation
Add src/tokens.css with every spec v2 Section 4 to 6 token for light, dark (system and data-theme), and Increase Contrast, with the WebKit system color keywords declared after the measured fallbacks. Tailwind v3 runs with presets: [] and a theme built only from those tokens, so stock classes such as bg-blue-500, p-7, and rounded-xl emit no CSS. Drop IBM Plex for the system sans and mono stacks, and remap the existing component styles onto the tokens. Vendor dialog, dropdown-menu, context-menu, select, tooltip, command, tabs, popover, toggle, and scroll-area as React 18 forwardRef wrappers over Radix and cmdk, restyled to the spec, each with a behavior test. Guard tests fail on a hex color, px literal, or arbitrary Tailwind value in a component file, on any token pair under WCAG AA, and on stock Tailwind classes producing CSS.
Replace the top bar, scope chip, and bottom status bar with the spec v2 window (Sections 7, 8, 9.1, 9.9): - A source-list sidebar: All Sessions, Repositories, Folders, and Agents, with counts, Mail selection colors for focused and unfocused, arrow-key selection, collapsible sections, a folder context menu, and New Folder. Agent rows run the filter-only agent: search. Hidden below 1000px; toggled with Control-Command-S or the toolbar button. - A 52px toolbar split at the column edges: the scope title and session count over the list (a scope menu when the sidebar is hidden), an empty slot for reader actions, the palette button, Rescan, and the 260px capsule search field. Empty areas are Tauri drag regions. - Rescan shows a spinner, then a progress ring, a failure popover with Try Again, and the last scan time stored as ui.lastScanAt. Command-R rescans. - The filter reference opens from the magnifier, ?, or Command-/, never on focus. Filter-only queries now search. - Notices move from the status bar to a line under the toolbar.
With presets: [] a class outside the tokens compiles to nothing, so a typo or a stock value fails silently. The new test compiles every utility-looking class token in component strings and lists the ones that emit no CSS. It would have caught left-1.5 in the menu indicator before inset had a spacing scale.
The running Rescan button is aria-disabled, which grayed its spinner to the disabled label color (about 1.6:1 on the toolbar). The spinner now keeps the secondary label color. The scan warning moves before Rescan so the controls after it never shift when it appears (spec 17.23). Add the spec's --red-text and --orange-icon tokens for destructive labels and the toolbar warning icon, use them for the existing red text, and check both in the contrast test.
Session rows follow spec 9.2: 52px two-line rows with a Mail date and one "Claude Code, 6 messages" run, inset hairlines hidden around the selection, and a filled selection that is blue only while the list has focus in the key window. Arrow keys open sessions in place and Enter moves into the reader; "Load older sessions" selects the first new row and keeps focus on the list. The search field turns finished filters into tokens (mono key, sans value), deletes the last token with two Backspaces, offers values after a bare key (agents, repositories, has:), and keeps the filter reference off plain focus. The reference now lists repo: and worktree: and the sort options. Search results show one 68px row per session with its best snippet and "N more matches", or "More matches in this session" while pages remain. Filter-only queries list sessions as two-line rows. A scope bar sits under the toolbar while searching, the toolbar reads "Searching" with an exact or "More than" count, and No Results offers Search All Sessions and Clear Filters. Loading shows nothing for a second, then a spinner.
Closing the filter reference by clicking elsewhere no longer pulls focus back to the search field, so a clicked row keeps the blue selection and arrow keys. A pending "select the first new row" request is dropped as soon as a load finishes, so a later scroll load cannot move focus. Raw tool-call JSON hits never become rows. The list's top gap moves outside the scroller so keyboard scrolling never clips the last row.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stacked on #26. Review the commits after 15d87f5 (
15d87f5..ac52b37, two commits).Why
PR 2 of the macOS redesign (docs/design/lore-design-spec.md v2, local). PR #26 laid down the tokens, primitives and the Mail window shell, but the session list and search still used the pre-redesign rows: a colored stripe and link-blue title for selection, a rule under every row, one row per search hit with field names ("in tool call") and raw JSON, and a filter line rendered as tinted text. This PR makes the list and search behave and look like Mail's message list and search field (spec 8, 9.2, 10, 11, 18.5 to 18.7).
What changed
Session rows (spec 9.2, 18.5)
--t-headlinewith a trailing Mail date ("2:00 PM", "Yesterday", the weekday, then "10/19/26"), and one line-2 run: "Claude Code, 6 messages, Partially parsed".--selectedwith white text while the list has focus in the key window (tracked through list focus and blur plus window focus and blur), and--selected-unfocusedwith primary-color secondary text otherwise.Search field (spec 8)
key:valuefilter (followed by a space) becomes a token inside the capsule:key:in mono--token-key, the value in sans. Backspace at the start of the text selects the last token, and a second Backspace deletes it, as in Mail. A Clear Search button empties the field.key:opens a suggestion popover (Radix Popover) with values: agents fromlistDetectedAgents, repositories by name fromlistRepositories, andhas:patch/has:error. Arrow keys, Enter or Tab pick a value. Esc or a click elsewhere closes the popover and keeps the text. The last row opens the filter reference.?in an empty field, or ⌘/, never on plain focus. It now listsagent:,repo:(by name),worktree:,path:,has:patch,has:errorfirst, then the other filters, then Sort By (Best Match, Newest, Oldest). ⌥⌘F and/focus the field.Filter-only search
agent:codex, runssearchPageand lists the matching sessions in the order the backend returns them (newest first). A bareagent:with no value does not search yet, so the list stays put while the suggestion popover is open.src/mock/does not parse filters (it treatsagent:codexas two words). The new behavior test, "lists the matching sessions for agent:codex alone", therefore drives a mockedipcmodule, as the existing App tests do.Search results (spec 9.2, 18.6, 18.7)
session_id: title and date, the best snippet with--mark, then "N more matches" when the loaded pages are complete, or "More matches in this session" while more pages remain. No field names. Hits on raw tool-call JSON never become rows.Searching “All Sessions”. Its subtitle reads "N sessions" only when the count is exact, and "More than N sessions" otherwise. Sort is also in the scope menu while searching.States (spec 10)
“lookbehind” with agent:codex), plus "Search All Sessions" when the search is scoped and "Clear Filters" when filters are present.Theme
--row-h52px,--hit-row-h68px and--token-h20px. Tailwind gains thearia-checkedanddata-selectedvariants.Scope
In: list rows and selection, ListBox keyboard and focus, search field tokens and suggestions, the filter reference contents, result grouping, the scope bar, the toolbar search title and count, and the no-results and loading states.
Out: the reader, its header, actions and keyboard hint (PR 3), and the palette and settings (PR 4).
No changes to
src/ipc.ts,src/main.tsx,src/mock/,crates/, orsrc-tauri/.Tradeoffs
The reviewer accepted all eight deviations from the spec and the prototype:
SessionSummaryhas no secret count, andsessionSecretCountper row would mean one IPC call per row.folder:filter. It offers noworktree:values, because the catalog carries only worktree counts.Blast Radius
UI only, in the list pane, the search field, and the toolbar title while searching. Behavior changes:
Nothing new is persisted.
Verification
npm run lint: eslint, no errors.npm run typecheck:tsc --noEmit, no errors.npm test: 12 files, 123 tests passed (feat(ui): adopt macOS system tokens, shadcn primitives, and a Mail-style window shell #26 had 114). New or replaced tests cover:agent:codexalonerepo:andworktree:entries and its sort optionsnpm run build: passed. CSS 39.92 kB (8.53 kB gzip), JS 346.15 kB (111.17 kB gzip).docs/design/tools/wkshot.swift) at 1280x800 and 900x700, light and dark. States: list, search with hits, filter-only results, no results, the suggestion popover, and, for head only, unfocused selection. They are gitignored, so they exist only locally:/Volumes/990 Pro/Development/Lore/.claude/worktrees/agent-a465e531a504ecfbd/docs/design/shots/pr2/main//Volumes/990 Pro/Development/Lore/.claude/worktrees/agent-a465e531a504ecfbd/docs/design/shots/pr2/pr1/(the feat(ui): adopt macOS system tokens, shadcn primitives, and a Mail-style window shell #26 baseline)/Volumes/990 Pro/Development/Lore/.claude/worktrees/agent-a465e531a504ecfbd/docs/design/shots/pr2/head//Volumes/990 Pro/Development/Lore/.claude/worktrees/agent-a465e531a504ecfbd/docs/design/shots/pr2-review/(the reviewer's shots)invokein the screenshot script only. Nothing undersrc/changed for this.src-tauri/orcrates/changed.