镜像站点 · 本页由第三方 GitHub 只读镜像提供,非 GitHub 官方站点,不接受任何登录或凭据输入。前往 github.com
Skip to content

feat(search): lead empty quick open with unread conversations - #2634

Merged
kalvinnchau merged 6 commits into
mainfrom
feat/quick-open-unreads
Nov 5, 2026
Merged

kalvinnchau merged 6 commits into
mainfrom
feat/quick-open-unreads

Conversation

@kalvinnchau

@kalvinnchau kalvinnchau commented Nov 5, 2026 •

Copy link
Copy Markdown
Contributor

Opening search (⌘T/⌘K) with an empty query now leads with unread channels and DMs and selects the first one, so ⌘T then Enter opens it.

Changes

  • SearchResults: for the empty, unscoped All view, adds an Unread group ahead of This conversation and Recent activity.
    • Candidates use the existing Recent activity eligibility: joined or guest, not archived, not a sidebar-hidden DM, no huddles or pending metadata.
    • Unread state comes from the sidebar's useUnreadChannelIds / channelHasUnread signal: a manual mark, observed messages, or unread threads.
    • Confirmed-muted conversations are excluded, matching the Dock indicator and the sidebar's unread jump cues. The open conversation is excluded too.
    • Rows use the Recent activity order. The group shows up to six rows.
    • Recent activity omits every unread conversation, so no row appears twice.
    • highlightEmpty is set only while unread rows exist. With no unreads, the existing suggestions and unselected state are unchanged.
    • The highlight follows its row key, so an unread arriving while the picker is open does not redirect Enter.
  • New device setting Show unread first in search (Settings → Appearance → Conversations, on by default; search.unread_first for agents). Off restores the previous empty search and reopen behavior.
  • PageSearch: while the setting is on at reopen, an empty All view is not restored, so reopening reflects current unread state instead of restoring the last highlighted row. Remembered typed queries, the Channels tab, and scoped search are unchanged.
  • docs/buzz-help.md: describes jumping to unread from search.

Tests

  • SearchResults.test.tsx:
    • No unreads: no group, no selection, and Enter is inert.
    • Mixed unread channels and DMs.
    • Exclusion of the muted and the current conversation.
    • Group order and deduplication against Recent activity.
    • First-row selection, and a new unread above the selection not moving it.
    • Arrow and Enter navigation.
    • Typed queries unchanged.
  • SearchResults.test.tsx: six-row cap, and overflow kept out of Recent activity; turning the setting off removes the group and selection.
  • device-settings.test.ts: lists search.unread_first.
  • ChannelDirectoryResults.test.tsx: an empty All view reopens fresh; with the setting off it reopens where it was left, and turning it back on reopens fresh.
  • AppearanceSettings.test.tsx: the switch defaults on, saves, follows other windows, and retries a failed save.
  • identity-names/consumers.test.tsx: its fake session gains the unread and sidebarPreferences capabilities that SearchResults now reads.

Both new behavior tests fail without the production change. No browser journeys were added. The existing global-search spec passes in Chromium and WebKit, and an actual-app ⌘T → Enter journey (production broker, modeled relay) was exercised in both engines.

🤖 Generated with Claude Code

@kalvinnchau
kalvinnchau requested a review from a team as a code owner November 5, 2026 17:15
kalvinnchau and others added 2 commits November 5, 2026 09:51
an empty all-view search now lists the viewer's other unread channels and
dms first, ordered like recent activity, and highlights the first so enter
opens it. eligibility reuses the recent-activity filter (joined or guest,
not archived, not hidden) and the sidebar unread signal, minus confirmed
mutes and the open conversation. recent activity omits unread rows. an empty
all view is no longer remembered across reopen, so it reflects current
unread state.

Co-authored-by: peon <9ac6794b000690b7e814eb1805ad32405d0bec7d52838de3a86cf967565dacc0@buzz.block.builderlab.xyz>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Kalvin Chau <kalvin@block.xyz>
the empty-search unread group shows the first six eligible conversations and reports the full count through the partial-group setsize; unread rows past the cap stay out of recent activity.

Co-authored-by: peon <9ac6794b000690b7e814eb1805ad32405d0bec7d52838de3a86cf967565dacc0@buzz.block.builderlab.xyz>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Kalvin Chau <kalvin@block.xyz>
@kalvinnchau
kalvinnchau force-pushed the feat/quick-open-unreads branch from 5585b6c to e75504d Compare November 5, 2026 17:53

@wesbillman wesbillman left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Carl, an automated reviewer, commenting via Wes's GitHub account.

Requesting changes for two small user-facing issues in the empty-search Unread group, each in its inline thread. The rest holds up: eligibility matches Recent activity, mutes follow the sidebar's confirmed-only rule, the sidebarPreferences snapshot is reference-stable, and the highlight follows its channel: key, so a late unread does not redirect Enter.

Validation at e75504d: the three touched test files pass locally (174 tests). With SearchResults.tsx and PageSearch.tsx reverted to the merge base, the three new behavior tests fail as expected. Browser journeys (webkit, 10/14) failed on the first attempt and was pending a rerun when I checked; I did not verify the author's app journey.

To merge: fix the two inline findings and update the aria-setsize assertion. The help-doc note is optional.

Comment thread src/app/shell/SearchResults.tsx Resolved
Comment thread src/app/shell/SearchResults.tsx Resolved
Comment thread docs/buzz-help.md Resolved

@joahg joahg left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Read SearchResults and PageSearch changes; muted and current-conversation exclusion, dedup against Recent activity, and the no-unread fallback all hold up. Browser webkit shard was still pending when I reviewed.

…activity

the unread group no longer reports the full unread count as its set size, since rows past six cannot be reached. recent activity is omitted when every listed conversation is unread instead of showing its empty text under unread rows. help notes that only typed searches reopen where you left them.

Co-authored-by: peon <9ac6794b000690b7e814eb1805ad32405d0bec7d52838de3a86cf967565dacc0@buzz.block.builderlab.xyz>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Kalvin Chau <kalvin@block.xyz>
@kalvinnchau

Copy link
Copy Markdown
Contributor Author

🤖 @wesbillman all three findings are addressed in c901f61. Unread rows no longer carry aria-setsize, Recent activity is omitted when Unread fills the list, and the help line is reworded. The aria-setsize assertion is updated, and there is a new assertion for the all-unread case. Each assertion fails with its fix reverted. CI is green on c901f61. Could you take another look?

a device-local switch under appearance, conversations, on by default, controls whether an empty search leads with unread conversations. it is also offered to agents as the search.unread_first device setting. with it off, an empty search and its reopen memory behave as before.

Co-authored-by: peon <9ac6794b000690b7e814eb1805ad32405d0bec7d52838de3a86cf967565dacc0@buzz.block.builderlab.xyz>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Kalvin Chau <kalvin@block.xyz>
the unread-first check moves from close to reopen, so a place remembered while the setting was off is not restored after it is turned back on. typed queries and the channels tab still reopen where they were left. adds tests for the settings switch, its save retry and the off to on reopen.

Co-authored-by: peon <9ac6794b000690b7e814eb1805ad32405d0bec7d52838de3a86cf967565dacc0@buzz.block.builderlab.xyz>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Kalvin Chau <kalvin@block.xyz>
@kalvinnchau kalvinnchau added the buzz-review-completed Agent review and human UI testing recorded label Nov 5, 2026

@wesbillman wesbillman left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Carl, an automated reviewer, commenting via Wes's GitHub account.

Re-review of e75504d..abb8d91: both earlier findings are fixed, and I found no new blockers. The Unread group no longer reports a set size it can't show, and Recent activity is left out when Unread fills the list. The new Show unread first in search setting follows the existing autocorrect-preference pattern, and reopen reads the preference at open time, so toggling it while search is closed takes effect. It fits in Appearance → Conversations.

Validation at abb8d91: the five touched test files pass locally (205 tests). Browser journeys were still running when I checked.

Two non-blocking notes are inline. The help-doc one comes from wording I suggested last round, sorry about that.

Comment thread docs/buzz-help.md Resolved
Comment thread src/app/AppearanceSettings.tsx Resolved
the help guide again says search reopens where you left it, with the unread bullet naming the exception. the setting description no longer repeats first, and the retry button names the search preference like its toast.

Co-authored-by: peon <9ac6794b000690b7e814eb1805ad32405d0bec7d52838de3a86cf967565dacc0@buzz.block.builderlab.xyz>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Kalvin Chau <kalvin@block.xyz>
@kalvinnchau
kalvinnchau merged commit 0181f8d into main Nov 5, 2026
1 check passed
@kalvinnchau
kalvinnchau deleted the feat/quick-open-unreads branch November 5, 2026 18:40
johnmatthewtennant added a commit that referenced this pull request Nov 5, 2026
Co-authored-by: Simone <0828be588d5c9c4d092c5b1cf01761d5aef63d6b104807fd8e8284d517dd1a99@buzz.block.builderlab.xyz>

* origin/main:
  fix(mcp): accept create scopes in durable approvals (#2650)
  feat(bestie): Bestie tab and Remembers you for a hosted Bestie (#2478)
  fix(relay): p-tag a one-to-one DM's agent partner on new messages (#2475)
  fix(agents): show each message author's username and display name (#2628)
  fix(agents): preserve visible edits in conversation history (#2355)
  fix(canvas): keep todo edits from approving unrelated instructions (#2350)
  fix(messages): keep messages in their canonical channel (#2349)
  NEXUS-4165: Add Thinking to agent creation (#2409)
  feat(plugins): let a plugin paint a backdrop behind the shell (#2437)
  feat(search): lead empty quick open with unread conversations (#2634)
  NEXUS-4170: Allow external apps to create private Solo chats (#2411)
  fix(acp): count grouped thinking levels when checking a synced level (#2640)

Signed-off-by: John Tennant <jtennant@squareup.com>
agude-sq added a commit to agude-sq/buzz-app that referenced this pull request Nov 5, 2026
* origin/main: (28 commits)
  fix(mcp): accept create scopes in durable approvals (block#2650)
  feat(bestie): Bestie tab and Remembers you for a hosted Bestie (block#2478)
  fix(relay): p-tag a one-to-one DM's agent partner on new messages (block#2475)
  fix(agents): show each message author's username and display name (block#2628)
  fix(agents): preserve visible edits in conversation history (block#2355)
  fix(canvas): keep todo edits from approving unrelated instructions (block#2350)
  fix(messages): keep messages in their canonical channel (block#2349)
  NEXUS-4165: Add Thinking to agent creation (block#2409)
  feat(plugins): let a plugin paint a backdrop behind the shell (block#2437)
  feat(search): lead empty quick open with unread conversations (block#2634)
  NEXUS-4170: Allow external apps to create private Solo chats (block#2411)
  fix(acp): count grouped thinking levels when checking a synced level (block#2640)
  feat(conversation): let plugin rows manage messages without visiting a channel (block#2512)
  feat(github): make side-panel link opening optional (block#2629)
  feat(messages): show a blurred thumbnail until an image loads (block#2556)
  fix(relay): give large roster and read-state reads a 30s deadline (block#2627)
  fix(user-status): show a status emoji's :name: on hover where the full status shows (block#2384)
  fix(inbox): keep the list's place when returning in the same session (block#2134)
  fix(messages): pass verified labels to the forward recipient picker (block#2633)
  feat(messages): forward a message to a person (block#2167)
  ...

# Conflicts:
#	tests/browser/settings.spec.mjs
wpfleger96 added a commit that referenced this pull request Nov 5, 2026
* commit '4bb94e259':
  feat(github): rework the GitHub settings page (#2450)
  fix(mcp): accept create scopes in durable approvals (#2650)
  feat(bestie): Bestie tab and Remembers you for a hosted Bestie (#2478)
  fix(relay): p-tag a one-to-one DM's agent partner on new messages (#2475)
  fix(agents): show each message author's username and display name (#2628)
  fix(agents): preserve visible edits in conversation history (#2355)
  fix(canvas): keep todo edits from approving unrelated instructions (#2350)
  fix(messages): keep messages in their canonical channel (#2349)
  NEXUS-4165: Add Thinking to agent creation (#2409)
  feat(plugins): let a plugin paint a backdrop behind the shell (#2437)
  feat(search): lead empty quick open with unread conversations (#2634)
  NEXUS-4170: Allow external apps to create private Solo chats (#2411)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

buzz-review-completed Agent review and human UI testing recorded

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants