Repository navigation
feat(ui,host,desktop): mark Inbox items read and unread - #3633
Merged
Merged
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
14 tasks done
An unread Inbox item, one changed since the reader last read it or marked
unread, wears the blue dot in a gutter before its tile, its title in the
semibold weight and its preview in the body's ink. Opening an item marks
it read, once each time it is shown. A row offers Mark as read / Mark as
unread (MailOpen / Mail) over its time while hovered or focused, and as
the first item of its right-click menu, beside U; a plain U toggles the
chosen item; the view's menu gains Mark all as read, which clears the
dots alone. A mark flips the dot at once and is let go where the service
refuses it. The Factory's rows and summary wear the attention mark for
what waits, so blue means unread everywhere.
The host gains two acts over the service's read state:
codingAgents.inboxReadState ({ itemId, unread }) and
codingAgents.inboxReadAll ({ workspaceId? }). ListRow gains
LIST_ROW_ACTIONS.HOVER, and its unread look is the semibold title and
the description in the body's ink.
Co-authored-by: luke-agent[bot] <339870089+luke-agent[bot]@users.noreply.github.com>
luke-agent
Bot
force-pushed
the
luke/feat-inbox-read-unread
branch
from
October 18, 2026 17:03
97c5d12 to
99c92f4
Compare
…r, and Mark all as read reads again A read mark stands over the reads only until they hold the item as it left it, so another window's later mark is drawn. Marks reach the service one at a time in the order they were made, an item's latest standing for its own still waiting, Mark all as read in its turn. Once Mark all as read is taken, every listed plan and agent is read again, since the write moves nothing main hears of. U and opening an item stand down while the side panel holds the keys or fills the window. Co-authored-by: luke-agent[bot] <339870089+luke-agent[bot]@users.noreply.github.com>
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.
Summary
PR 2 of 3 for the Inbox list rows in
docs/proposals/inbox-threads.md§3–§4, approved by Dean. It builds on #3612 (the two-line rows) and #3618 (the service's per-member read state), both merged. PR 3, the two-stage swipe, stacks on this one.Unread (
tasks/inbox-list.tsx). An item is unread when it changed since the reader last read it, or when they marked it unread. An unread item shows:The gutter stands on every row, so the tiles line up whether or not a row has a dot. Needs you stays the orange attention mark, independent of unread.
Ways to mark. Each one sends one act and flips the dot at once (
tasks/use-inbox-read-marks.ts).MailOpen"Mark as read" on an unread item andMail"Mark as unread" on a read one. While the row is hovered or holds the keyboard, the time and the attention mark step aside, as Pin and Archive do on a sidebar row. It reuses the plans'markReadItem.Ubeside it, above Copy link.Utoggles the chosen item. It's a newAPP_COMMAND.TOGGLE_INBOX_ITEM_READwith{ key: U, plain: true }, so it's skipped while typing, like J/K.⇧⌘Ustays Automations'.How the marks hold (
withReadMarksininbox-model.ts,use-inbox-read-marks.ts).U, and marking an item read when it opens, both stand down while the side panel holds the keys or fills the window.A task's own Inbox tab draws the same rows with the same marks. It has no view menu, so it doesn't offer Mark all as read.
The Factory (
desktop-factory.tsx). Its rows and summary now show the attention mark for "waits on you" instead of the blue.inbox-row-dot, so blue means unread everywhere. The orchestrator agreed to this..inbox-row-dotand its CSS are gone.Host acts (
packages/host,packages/gateway). Each has oneACT_KINDentry, a payload schema, a result guard, and one router row, over #3618's client methods:codingAgents.inboxReadState, payload{ itemId, unread }, callsmarkInboxItemReadormarkInboxItemUnread.codingAgents.inboxReadAll, payload feat(service,features,database): keep each member's read state on Inbox items #3618's owninboxReadAllRequestSchema({ workspaceId? }), callsmarkInboxRead.@luke/uiListRowactionsAt: LIST_ROW_ACTIONS.HOVER, which puts the row's actions over the end of its metadata, shown on:hoverand:has(:focus-visible).unreadnow means a semibold title and the description in the body's ink. Nothing else used ListRow'sunread.Screenshots
Rendered from the jsdom fixtures with the built
apps/desktop/dist/renderer/styles.css, captured with Playwright.Evidence
pnpm check:affected: lint, knip, anddiscarded-effectpass.@luke/desktoptypecheck was OOM-killed (exit 137); alone, it reports 0 errors.issue-client.test.tstimed out under load; alone, it passes 4/4.src/main/app-menu.test.tscan't run here because the sandbox has no Electron binary.coding-agent-view-codingAgentInboxReadStateParamsSchema.json({ itemId: non-empty string, unread: boolean }, both required, no extra keys), written underLUKE_UPDATE_FIXTURES=1. No existing golden changed.desktop-inbox.test.ts, +5:Uabove Copy link, and plainU;desktop-tasks.test.ts, +1: a task's own Inbox marks what it opens read and offers the row mark.inbox-model.test.ts, +1:withReadMarksholds until the item changes.coding-agent-acts.test.ts, +1: both acts route, and the voice window is refused.hosted-wire-schemas, +1: the recorded params schema.compose-coding-agents.test.ts: the existing round-trip test now covers both gateway methods.use-inbox-read-marks.test.ts(+3): a mark stands until the reads catch up, after which another window's mark is drawn; marks go one at a time in order, with an item's latest mark winning and Mark all as read taking its turn; a refused mark, or a refused Mark all as read, is dropped and asks nothing again.use-inbox-items.test.ts(+1):onRereadreads every listed plan again.desktop-inbox.test.ts(+1): Mark all as read re-reads every plan and every agent with no plan.inbox-side-panel.test.ts(+1):Uis not the Inbox's while the panel holds the keys.desktop-factory.test.ts:rows()now requires the attention mark with "Needs you" and no blue dot on every waiting row, and the summary counts beside the mark.Invariants
./scripts/check.shgreen. (CI)LUKE_UPDATE_FIXTURESnot run, or diff explained line by line). (CI) One new golden, explained above; no existing one changed.AGENTS.md"Testing")astype assertion outside the allowlisted files. (CI via anti-slop)Effect.runPromise/runSync/runForkoutside the runtime edges and the shimstools/anti-slop/effect-edges.jsonrecords. (CI viaanti-slop/no-run-promise-outside-edges)setTimeout/setInterval/new Promise/AbortController/fs.watchoutside the filestools/anti-slop/effect-edges.jsonrecords. (CI viaanti-slop/no-raw-async-primitives)pnpm discarded-effect)vitest run --reporter=json)AGENTS.md's "The permanent adaptors" with the reason it stays.CLAUDE.md/AGENTS.mdsentence naming a changed part is edited; root pair stays byte-identical. (CI for pair existence; manual for wording)PRIVACY.mdunchanged, or the change is a product decision called out in the PR body.package.jsondeps match what the sources import by bare specifier;effectviacatalog:. (CI)@effect/platform-node,effect/sql) behind a barrel the renderer or a web function opens. (CI: existing renderernode:grep plus a new grep for those specifiers in renderer bundles)Notes
Made with Luke
Summary by cubic
Adds read and unread states to Inbox item rows: an item changed since the reader last read it, or marked unread, wears a blue dot, a semibold title, and a body-ink preview until opened. Opening an item marks it read; a hover button, right-click menu item, plain
U, and View options › Mark all as read mark items read or unread.New Features
@luke/uiListRowgainsLIST_ROW_ACTIONS.HOVER, placing row actions over the metadata's end, and a new unread look.Written for commit da946ed. Summary will update on new commits.