Skip to content

Play/inbox work states and navigation split - #32903

Open
Duncid wants to merge 4 commits into
mainfrom
play/inboxWorkStates
Open

Duncid wants to merge 4 commits into
mainfrom
play/inboxWorkStates

Conversation

@Duncid

@Duncid Duncid commented Sep 21, 2026

Copy link
Copy Markdown
Contributor

Description

TLDR: experimentation around the Inbox as a productivity surface — work states, statuses and the rest — and a split of the navigation experiment out of the Inbox experiment itself, so the two can move without stepping on each other.

Inbox: the state of the work

Reframe the Inbox playground around the state of the work in each row: an agent still working, a row waiting on you, an answer you have not read, or a row you are done with. The timestamp slot carries that state — a spinner while an agent works, a pause glyph while it waits on you, a counter while it is unread — and the reply line it replaces is gone.

The rows themselves now read as work: the avatar and name are whoever spoke last, the badge says what kind of work it is, a working row reports the step its agent is on with the tool it reaches for, and the pod a conversation happened in opens its description instead of sitting in a chip.

What the list holds is planned over the rows it can actually list, since a pod you are not in takes its rows with it: two or three agents at work in the top five, a handful of unread, a few requests and a long tail of read rows. Work in flight settles by itself a minute or three later. The list can be narrowed by status, Clear is a menu of what to clear, and a row can be cleared on its own from its menu.

Navigation: split into its own story

The navigation experiment now lives in its own New_Navigation story, forked from the Inbox one, so changing the sidebar no longer means changing the Inbox playground. It drops the old Inbox entry and the sidebar conversation list, and opens the Inbox with a composer above the search and toolbar.

The Inbox story keeps its own, narrower navigation: three fewer top-level entries, the Recent section renamed to Conversations and grouped by date the way Pods does it, and the Build tab renamed to Spaces.

Sparkle

Adds the Pause and PauseFill icons; PauseFill is what a row waiting on you shows.

Tests

playground/inbox, playground/new_navigation

Risk

n/a — playground and two new icons.

Deploy Plan

n/a

Reframe the Inbox playground around the state of the work in each row:
an agent still working, a row waiting on you, an answer you have not read,
or a row you are done with. The timestamp slot carries that state — a
spinner while an agent works, a breathing dot while it waits on you, a
counter while it is unread — and the reply line it replaces is gone.

The rows themselves now read as work: the avatar and name are whoever
spoke last, the badge says what kind of work it is, a working row reports
the step its agent is on, and the pod a conversation happened in opens its
description instead of sitting in a chip.

What the list holds is planned over the rows it can actually list, since a
pod you are not in takes its rows with it: two or three agents at work in
the top five, a handful of unread, a few requests and a long tail of read
rows. Work in flight settles by itself a minute or three later. The list
can be narrowed by status, and Clear is a menu of what to clear.

Co-authored-by: Cursor <cursoragent@cursor.com>
@vercel

vercel Bot commented Sep 21, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
playground Ready Ready Preview Sep 22, 2026 3:43pm UTC
1 Skipped Deployment
Project Deployment Actions Updated
storybook Ignored Ignored Preview Sep 22, 2026 3:43pm UTC

Request Review

Co-authored-by: Cursor <cursoragent@cursor.com>
- Fork the Inbox story into New_Navigation, without Inbox (Old) or the
  sidebar conversation list.
- Inbox: drop the Conversations, Automated work and Inbox (Old) entries,
  rename Recent to Conversations and group it by date, rename the Build
  tab to Spaces.
- Add the Pause and PauseFill icons, and use PauseFill in the playground
  Counter for pending rows.
- Show the pending and in-flight action, with its tool icon, on the row.
- Add Clear to the conversation row menu and fix the read dwell timer
  restarting while other rows work.

Co-authored-by: Cursor <cursoragent@cursor.com>
Add an opt-in showComposer prop to InboxAltView, which opens the list
with an InputBar above the search and toolbar row, and turn it on from
the New_Navigation story only.

Co-authored-by: Cursor <cursoragent@cursor.com>
@Duncid Duncid changed the title Play/inbox work states Play/inbox work states and navigation split Sep 22, 2026
* truncation. It MUST NOT become a chip, a badge or a line of its own: what it
* says belongs to the sentence, not beside it.
*/
export function ConversationListItem({

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

React Doctor · react-doctor/no-high-complexity-react-function (warning)

ConversationListItem has cyclomatic complexity 17, cognitive complexity 19, and maximum nesting depth 3, so its React logic is hard to understand and change. Extract independent branches into components or hooks.

Fix → Extract independent render branches and state logic into focused components or hooks until the control flow is easy to follow.

Docs

})),
previous?.visibleRequestIds
);
planRef.current = composition;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

React Doctor · react-doctor/no-ref-current-in-render (error)

This ref is mutated during render. React can replay or discard render work, so the mutation can leak from UI that never commits.

Fix → Move ref writes into an event handler or effect. Render must stay pure because React can replay or discard it. The predictable null-guarded lazy initialization pattern remains supported.

Docs

"thinking"
);
const waitable = conversations
.filter((row) => row.hasAgentSpeaker && top.includes(row.id))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

React Doctor · react-doctor/js-set-map-lookups (warning)

This scales poorly because array.includes() inside a loop scans the whole list every time. Use a Set for constant-time lookups.

Fix → Use a Set or Map when you check for the same items over and over. Array.includes/find scans the whole list each time

Docs

@@ -2192,7 +2121,7 @@ function Inbox() {
<NavigationList className="mx-sidebar-side-spacing mt-2">
{(recentConversations.length > 0 || !searchText.trim()) && (
<NavigationListCollapsibleSection

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

React Doctor · react-doctor/duplicate-jsx-subtree (warning)

2 copies of this 19-node JSX tree appear across 2 files, repeating about 138 lines. Composition path: Inbox > div > div > ScrollArea > NavigationList > NavigationListCollapsibleSection.

Fix → Consider extracting a shared component if these trees represent the same UI concept. Keep them separate when the resemblance is incidental or the variants are likely to evolve independently.

Docs

This branch was successfully deployed

1 active deployment
Preview – playground 9d21acad Deployed Sep 22, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant