use-setup-connect.tsMerge remote-tracking branch 'origin/staging' into feat/inbox-client-composed-feed # Conflicts: # apps/mail/app/(full-width)/onboarding/page.tsx # apps/mail/modules/conversations/components/LeftSidebarContent.tsx # apps/mail/modules/inbox/components/InboxList.tsx # apps/mail/modules/inbox/hooks/use-inbox-items.ts # apps/mail/tests/modules/inbox/feedPartialFailure.test.tsxSep 1, 2026, 11:58 AMuse-setup-pipeline.tsfeat(onboarding): a setup flow that shows you the product while you configure it Adds `/onboarding-setup` — a sidebar-driven flow over the four surfaces a new user actually has to configure (Inbox, sub-inboxes, Tasks, Pipeline), each step paired with a live preview of the real product rather than a screenshot of it. Reachable from the profile menu as "Set up Cedar". Two inbox-creation races surfaced by clicking through the template gallery are fixed on the way, since the flow leans on that path hard: - Per-mutation `invalidateQueries` lost rows. Create #1's refetch was issued after #2 had written its optimistic row, so a server list predating #2 landed last and overwrote it — the row vanished and the template card flipped back to unselected. Now the last create to settle does the single refetch. - Two adds fired back to back both read the cache before either had written to it and claimed the same position, so a run of template clicks piled up at one index and the tab strip reordered itself on refetch. Positions are now issued from a carried-forward high-water mark. A failed create drops only its own row instead of restoring a whole snapshot, and `removeInbox` no longer swallows the rejection — callers holding their own selected-state need to hear about it, or the row returns while the card stays deselected. Co-Authored-By: Claude Opus 5 (1M context) <<email>>Aug 31, 2026, 10:48 PMuse-setup-settings.tsfeat(onboarding): a setup flow that shows you the product while you configure it Adds `/onboarding-setup` — a sidebar-driven flow over the four surfaces a new user actually has to configure (Inbox, sub-inboxes, Tasks, Pipeline), each step paired with a live preview of the real product rather than a screenshot of it. Reachable from the profile menu as "Set up Cedar". Two inbox-creation races surfaced by clicking through the template gallery are fixed on the way, since the flow leans on that path hard: - Per-mutation `invalidateQueries` lost rows. Create #1's refetch was issued after #2 had written its optimistic row, so a server list predating #2 landed last and overwrote it — the row vanished and the template card flipped back to unselected. Now the last create to settle does the single refetch. - Two adds fired back to back both read the cache before either had written to it and claimed the same position, so a run of template clicks piled up at one index and the tab strip reordered itself on refetch. Positions are now issued from a carried-forward high-water mark. A failed create drops only its own row instead of restoring a whole snapshot, and `removeInbox` no longer swallows the rejection — callers holding their own selected-state need to hear about it, or the row returns while the card stays deselected. Co-Authored-By: Claude Opus 5 (1M context) <<email>>Aug 31, 2026, 10:48 PMuse-setup-splits.tsfeat(calendar,tasks): mint real Zoom meetings, and two fixes for surfaces that lied Zoom reaches a Google Calendar event through the vendor's Workspace Add-on running INSIDE Google, never through an external API client. Probed live against two accounts: all 17 calendars report `allowedConferenceSolutionTypes: ["hangoutsMeet"]`, so the `addOn` option added in ead6b26a4 was unreachable code — and had it rendered, Google would have answered "Invalid conference type value". Cedar now holds a Zoom OAuth token per user, mints the meeting through Zoom's own API, and writes the join details onto the event. That is what Superhuman does, and there is no Calendar-API shortcut they know that we do not. The driver implements the existing OAuth interface, which buys the sealed AES-GCM state, `initiateOAuth`'s URL builder, and `refreshMcpConnection`. The last is load-bearing rather than convenient: Zoom rotates the refresh token on every refresh and kills the old one, so two concurrent refreshes presenting the same stored token leave it dead — exactly the failure the single-flight coalescing there already exists for. The row is written `direct_oauth`, never `external_mcp`, because every MCP surface selects on that column and an agent enumerating tools from api.zoom.us should not be possible. Attachment goes to `location` (the only field that renders on every Google client), `description` (a fenced, idempotent dial-in block — recreating the meeting REPLACES it rather than appending beside it, which is what a "does it already contain this URL?" check gets wrong), and `conferenceData` best-effort. `addOn` is gone from both `createRequest` enums, the agent tool, the chat route, and `CalendarEvent.conferenceType`; describing an existing conference is still allowed, because that is what a Zoom meeting is by the time it reaches the event body. Inert until ZOOM_CLIENT_ID is set. Two unrelated fixes, both reported by the same customer: - "Search a deal…" searched every conversation the user owned. Cedar mints one per unrecognised correspondent, so on the reporting account 117 conversations held 6 deals and typing "gmail" returned a column of recruiters' addresses. `dealsOnly` narrows to the AOPs the user actually works — `isNoOp = false` being their own declaration that Cedar does work there — and falls back to today's behaviour for the 18 of 109 active accounts that have no workable AOP. - Every task surface splits due-now from upcoming at `endOfToday()`, read inside memos whose dependencies are all data. Nothing in them moves when the day does, so a tab left open past midnight files everything due TODAY under Upcoming, out of its group column, which then collapses into the hidden-columns rail for being empty. `useDayKey` is the missing dependency. Staged whole-tree, not session-scoped: this branch is shared with a concurrent session whose in-flight work (the board's Done lane, the calendar drag-settle animation, the onboarding setup flow, the task-groups CLI) is entangled with these changes both within files and across them — CalendarView passes props DayColumn only accepts in its uncommitted form — so a scoped commit would not have compiled. That session likewise swept this change's crm.ts and NewTaskDialog edits into a5fc7b295. Co-Authored-By: Claude Opus 5 (1M context) <<email>>Sep 1, 2026, 10:35 PMuse-setup-task-groups.tsfeat(onboarding): a setup flow that shows you the product while you configure it Adds `/onboarding-setup` — a sidebar-driven flow over the four surfaces a new user actually has to configure (Inbox, sub-inboxes, Tasks, Pipeline), each step paired with a live preview of the real product rather than a screenshot of it. Reachable from the profile menu as "Set up Cedar". Two inbox-creation races surfaced by clicking through the template gallery are fixed on the way, since the flow leans on that path hard: - Per-mutation `invalidateQueries` lost rows. Create #1's refetch was issued after #2 had written its optimistic row, so a server list predating #2 landed last and overwrote it — the row vanished and the template card flipped back to unselected. Now the last create to settle does the single refetch. - Two adds fired back to back both read the cache before either had written to it and claimed the same position, so a run of template clicks piled up at one index and the tab strip reordered itself on refetch. Positions are now issued from a carried-forward high-water mark. A failed create drops only its own row instead of restoring a whole snapshot, and `removeInbox` no longer swallows the rejection — callers holding their own selected-state need to hear about it, or the row returns while the card stays deselected. Co-Authored-By: Claude Opus 5 (1M context) <<email>>Aug 31, 2026, 10:48 PM