Ended
A message you saw anywhere is read: Summarize, Explain and every surface mark what they show #196
A message you read anywhere should count as read. Today, Home's Summarize (and Explain, and the other buttons that ask g1t from a page) leaves g1t's answer as an unread direct message, even though you watched it stream in on Home. Fix it at the root: every place that shows g1t's (or anyone's) messages marks them read when they are actually seen, and nothing you saw nags you afterwards.
Why it happens (checked 2026-10-15)
- Ask and a DM with @g1t are one conversation. Home's Summarize is
apps/web/app/components/home-summary.tsx. It opens the @g1t DM (chat intentg1t_dm), posts the question there (post), and streams g1t's answer into the card over the chat live socket. - Only the top bar's Ask panel marks that DM read.
ask-composer.tsx(around line 159) sends chat intentreadwith the newest message id while the panel is open and visible, on focus and onvisibilitychange, and firesg1t:chat-readso the counts update.home-summary.tsxnever does any of this. So the answer (and the echo of the question, if it's counted) stays unread in the sidebar, the Chat badge, notifications, and desktop and phone toasts. - Read state is
channel_members.last_read_idinservices/chat/src/index.ts, and unread counts are the messages with an id above it. The web client's counts live inapps/web/app/lib/notify-store.tsandnotify-client.ts.
What to do
- Find every surface that shows chat messages outside the conversation itself: Home's Summarize and What changed, the Explain buttons (Landed rows, attention rows),
home-ask.tsx, the Ask panel, notification previews, the desktop app and the phone app. List them in the pull request. - Give them one shared way to say "these messages were seen here", for example a hook
useReadWhenShown(channelId, newestShownId)moved out of ask-composer's logic. It marks messages read only when the page is visible and the messages are on screen, does so once per newest id, and firesg1t:chat-read. ask-composer uses it too. - Streaming: an answer written while you watch is read as it lands. Mark the final message when the stream finishes, not before that message exists.
- Toasts and sounds: no desktop toast, sound or phone push for an answer you're watching on the page that asked for it. Check how notify decides, and suppress them for the asking tab or page. (Sounds already never play for your own messages, muted conversations or a focused, visible conversation.)
- Across tabs and devices: reading on Home clears the DM's unread count on other tabs, the desktop app and the phone. The chat live events should already carry read updates; confirm that they do.
- Tests: notify-store and the hook's rules (visible, on screen, newest id once, after the stream ends), and a chat service test that a
readfrom any surface moveslast_read_id.
Also keep this rule: notifications that later events resolve clear themselves, so Home and notifications show only what still needs you.
Verify live
Sign in, press Summarize on Home and let it finish. Check that the sidebar's DM count, the Chat badge, the notifications slide-over and the desktop app all stay at zero for it, then open Chat and see the answer marked as read. Render the pages with real data.
Companion item: #197 (Home's span switch sets the whole page).
How to work on this repository
- Claim this item before you start (
g1t work claim <number>), and addG1t-Session: $G1T_SESSIONto every commit. - Other sessions share the main checkout: work in a worktree of your own and stage only your own files.
- Pushing to
maindeploys production, and pushes tomainand release tags are the owner's. Land the work through a pull request on this item, or commit locally and hand the owner the exactgit -C <path> push …. - Shipped means on
mainand deployed. Check it live with real data and look at the rendered pages: a status code doesn't show it works. - Docs ship in the same change as the feature (guides, reference, llms.txt), to a high standard.
- User-facing text never names other products or compares g1t to them. Internal notes and code comments may.
Repositories
Decisions
Why the work is the way it is, and how sure that is
Discussion
Sign in to comment.