Libra CodeHub

CedarCopilot/cedar-mail

Branch: staging

feat(inbox): unibox keyboard parity, undo-send that restores the draft, sharper chat context

merged#2349CedarCopilot

CedarCopilot wants to merge 0 commits into staging from feat/slack-channels-entity

Live on prod since Fri, 1 of 16 behaviors workingTimeline and evidence
  1. Opened
    Jul 31, 2026, 12:08 AM
  2. Merged
    Jul 31, 2026, 12:21 AM
  3. Live on prod
    Jul 31, 2026, 12:21 AM
  4. Observed 3 days
    Jul 31, 2026, 12:21 AM
  5. Pipelines steady after this deploy
    Jul 31, 2026, 12:21 AM
  6. Verified

    Live on prod since Fri, 1 of 16 behaviors working

    Aug 3, 2026, 12:09 AM

Behaviors Libra is checking

Calendar overlay views, including a newly opened email compose window, should render through ActiveViewDisplay while the calendar remains mounted underneath.Workingmedium confidence

Evidence snapshot saw 12 prod OTEL spans matching /calendar ActiveViewDisplay since deploy with 0 error spans.

prod, checked Aug 2, 2026, 8:06 PM
Clicking the agenda task Trash button should remove the task row immediately while still soft-deleting the backing task through sync.Inconclusivelow confidence

OTEL fallback found no prod spans matching AgendaDocument handleDeleteTask since deploy.

prod, checked Aug 2, 2026, 7:07 PM
Current/active meeting cards should show a Draft no show email action that sends a combined no-show and reschedule prompt directly to chat.Inconclusivelow confidence

OTEL fallback found no prod spans matching AgendaEventBlock / EventCard sendNoShowPrompt since deploy.

prod, checked Aug 2, 2026, 7:07 PM
Clicking a calendar event should select it and open its details popover without opening the linked conversation or replacing the calendar view.Inconclusivelow confidence

OTEL fallback found no prod spans matching calendar page event click since deploy.

prod, checked Aug 2, 2026, 8:07 PM
Leaving the calendar route should clear any draft calendar event so the right column returns to chat on pages that cannot display the draft.Inconclusivelow confidence

OTEL fallback found no prod spans matching AppShell route change cleanup since deploy.

prod, checked Aug 2, 2026, 9:07 PM
While the calendar event editor is open, the chat column should be hidden rather than unmounted so streaming and scroll state are preserved.Inconclusivelow confidence

OTEL fallback found no prod spans matching AppShell ChatColumn since deploy.

prod, checked Aug 2, 2026, 9:07 PM

Libra has verdicts on 1 of 16 tracked behaviors on prod; 15 are still being checked. Libra checks hourly for 3 days after each deploy.

Summary

Three main threads of work, plus polish.

Unibox keyboard parity. The unified feed had no keyboard behaviour at all , useMailNavigation lives in MailList, which isn't mounted there, so j/k/Enter/Escape did nothing on ?channel=all. A new activeListSource on the thread slice declares which ordered list is on screen, so every keyboard action walks the list the user can actually see (the two lists share selectedThreadId / bulkSelected / focusedIndex; the unibox just holds unified ids). Enter routes through the unibox's own opener so a Slack/LinkedIn/WhatsApp row opens its chat rather than a mail thread. Escape now clears the whole selection , focused row, bulk checkboxes, and the ambient conversation that feeds the chat's context badges , instead of only the keyboard cursor, which read as "escape did nothing".

Undo send actually puts the draft back. It used to serialize attachments into localStorage and rewrite the URL. Now the send records where the draft came from (UndoSendRestore) and undo reopens that surface , conversation, thread, or compose session , writing the held-back, un-quoted body onto the draft row via a new restoreUndoneDraft, recreating the row (or the whole thread entry) when the send removed it. A restored reply no longer comes back with the quoted history pasted into it.

Chat context follows the deal you're on. An auto-committed primary conversation is treated as provisional while the chat is still empty and is dropped when you move on (shouldDropProvisionalPrimary); user-attached items are never touched. The context cards now key off the conversation you're actually on rather than whatever the thread was opened with, so they stop going stale on row change. Threads with no conversation get a link prompt instead of a blank panel, and the conversation surface shows a keyboard legend rather than restating Overview / Next steps cards that are already on screen beside it.

Also: agenda Trash removes the row outright (the keyboard Cmd/Ctrl+X path still tombstones); Next steps renders as one card with its booked calls beneath it, matching the chat empty state; channel chats focus the composer on open; landing on the inbox no longer inherits a conversation from wherever you just were; compose sessions stop 400ing on mail.get.

The second commit fixes two failures that predate this work on the branch: a comment inside the backfill's sql `` template quoted slack_threads in backticks, which closed the template literal and made the file unparseable to oxlint, and AppShell gained a useLocation() call whose persistence test still rendered it without a router.

Test plan

  • pnpm run autofix:local green on the merged tree , oxlint (--deny-warnings), deps:check, paraglide compile, 1053 Jest tests, 4466 Vitest tests.
  • Merged fresh origin/staging (91 files) and re-validated after pnpm install picked up the new @armature-tech/mcp-analytics dep.
  • New coverage: unibox-navigation-parity, mail-navigation-escape, undoSendRestore, provisionalPrimaryContext, contextCardsConversation, contextChipLabel.

🤖 Generated with Claude Code

Greptile Summary

This PR substantially expands unified-inbox navigation, undo-send restoration, calendar interactions, chat context behavior, and Slack/LinkedIn backend handling.

  • Adds keyboard navigation and shared selection semantics for the unified inbox.
  • Restores held-back email content and its originating surface when undoing a send.
  • Reworks calendar event presentation, editing, meeting actions, and conversation linking.
  • Updates chat context selection, empty states, and conversation timeline cards.
  • Revises Slack persistence/migrations, integration routing, settings writes, and chat workflow configuration.

Confidence Score: 4/5

The PR should not merge until calendar metadata is isolated from agent instructi

Show production surfaces and changed-file mapping

Production surfaces

Libra has not measured any production surfaces for this change yet.

Changed files → surfaces

  • .env.exampleno production surface mapped
  • apps/mail/app/(routes)/calendar/page.tsxno production surface mapped
  • apps/mail/app/(routes)/settings/appearance/page.tsxno production surface mapped
  • apps/mail/app/(routes)/settings/signature/page.tsxno production surface mapped
  • apps/mail/app/globals.cssno production surface mapped
  • apps/mail/components/layout/AppShell.tsxno production surface mapped
  • apps/mail/config/shortcuts.tsno production surface mapped
  • apps/mail/docs/omni-channel-inbox.mdno production surface mapped
  • apps/mail/docs/slack-inbox-read-and-empty-channels.mdno production surface mapped
  • apps/mail/docs/url-driven-layout.mdno production surface mapped
  • apps/mail/modules/agentCanvas/components/AgendaDocument.tsxno production surface mapped
  • apps/mail/modules/agentCanvas/components/AgendaEventBlock.tsxno production surface mapped
  • apps/mail/modules/agentCanvas/components/EventCard.tsxno production surface mapped
  • apps/mail/modules/calendar/calendarUtils.tsno production surface mapped
  • apps/mail/modules/calendar/components/AllDayEventsRow.tsxno production surface mapped
  • apps/mail/modules/calendar/components/CalendarDraftEditor.tsxno production surface mapped
  • apps/mail/modules/calendar/components/CalendarEventContent.tsxno production surface mapped
  • apps/mail/modules/calendar/components/CalendarSidebar.tsxno production surface mapped
  • apps/mail/modules/calendar/components/CalendarView.tsxno production surface mapped
  • apps/mail/modules/calendar/components/DayColumn.tsxno production surface mapped
  • apps/mail/modules/calendar/components/DraggableCalendarEvent.tsxno production surface mapped
  • apps/mail/modules/calendar/components/EventConversationBadge.tsxno production surface mapped
  • apps/mail/modules/calendar/components/EventDetailsPopover.tsxno production surface mapped
  • apps/mail/modules/calendar/utils/meetingEmailPrompts.tsno production surface mapped
  • apps/mail/modules/canvas/components/CanvasRenderer.tsxno production surface mapped
  • apps/mail/modules/canvas/components/CardListCanvasView.tsxno production surface mapped
  • apps/mail/modules/cedar-os/__tests__/EmptyStateSuggestions.test.tsxno production surface mapped
  • apps/mail/modules/cedar-os/__tests__/contextChipLabel.test.tsno production surface mapped
  • apps/mail/modules/cedar-os/__tests__/emptyChatLayout.surfaces.test.tsno production surface mapped
  • apps/mail/modules/cedar-os/src/cedar-os-components/chatComponents/AmbientContextChip.tsxno production surface mapped
  • apps/mail/modules/cedar-os/src/cedar-os-components/chatComponents/ChatContextRow.tsxno production surface mapped
  • apps/mail/modules/cedar-os/src/cedar-os-components/chatComponents/EmbeddedCedarChat.tsxno production surface mapped
  • apps/mail/modules/cedar-os/src/cedar-os-components/chatComponents/EmptyStateSuggestions.tsxno production surface mapped
  • apps/mail/modules/cedar-os/src/cedar-os-components/chatComponents/contextKinds.tsno production surface mapped
  • apps/mail/modules/cedar-os/src/cedar-os-components/chatComponents/emptyChatLayout.tsno production surface mapped
  • apps/mail/modules/cedar-os/src/cedar-os-components/chatComponents/provisionalPrimaryContext.tsno production surface mapped
  • apps/mail/modules/cedar-os/src/cedar-os-components/chatInput/ChatInput.tsxno production surface mapped
  • apps/mail/modules/cedar-os/src/cedar-os-components/chatInput/ContextBadgeRow.tsxno production surface mapped
  • apps/mail/modules/cedar-os/src/components/chatInput/useCedarEditor.tsno production surface mapped
  • apps/mail/modules/cedar-os/src/components/renderers/messageRenderers.tsxno production surface mapped
  • apps/mail/modules/cedar-os/src/store/agentContext/agentContextSlice.tsno production surface mapped
  • apps/mail/modules/conversations/components/ConversationSearchCommandBar.tsxno production surface mapped
  • apps/mail/modules/conversations/components/LeftSidebarContent.tsxno production surface mapped
  • apps/mail/modules/conversations/components/LinkThreadToConversationDialog.tsxno production surface mapped
  • apps/mail/modules/conversations/components/OverviewDocTab.tsxno production surface mapped
  • apps/mail/modules/conversations/components/ThreadContextCards.tsxno production surface mapped
  • apps/mail/modules/conversations/components/strategicOverview/RecommendationsPanel.tsxno production surface mapped
  • apps/mail/modules/conversations/components/strategicOverview/StrategicOverviewTab.tsxno production surface mapped
  • apps/mail/modules/conversations/components/timeline/EventHoverActions.tsxno production surface mapped
  • apps/mail/modules/conversations/components/timeline/InboxThreadList.tsxno production surface mapped
  • apps/mail/modules/conversations/components/timeline/MeetingDetailContent.tsxno production surface mapped
  • apps/mail/modules/conversations/components/timeline/MeetingProviderBadge.tsxno production surface mapped
  • apps/mail/modules/conversations/components/timeline/NextStepsCard.tsxno production surface mapped
  • apps/mail/modules/conversations/components/timeline/SlackThreadDisplay.tsxno production surface mapped
  • apps/mail/modules/conversations/components/timeline/SlackThreadRow.tsxno production surface mapped
  • apps/mail/modules/conversations/components/timeline/SlackTimelineEvent.tsxno production surface mapped
  • apps/mail/modules/conversations/components/timeline/UniversalComposer.tsxno production surface mapped
  • apps/mail/modules/conversations/components/timeline/meetingProviderDisplay.tsno production surface mapped
  • apps/mail/modules/conversations/utils/conversation-display-hotkeys.tsxno production surface mapped
  • apps/mail/modules/crm/types/index.tsno production surface mapped
  • apps/mail/modules/crm/utils/time.tsno production surface mapped
  • apps/mail/modules/dashboards/components/blocks.tsxno production surface mapped
  • apps/mail/modules/documents/document.tsxno production surface mapped
  • apps/mail/modules/drafting/components/compose-display.tsxno production surface mapped
  • apps/mail/modules/drafting/components/email-composer.tsxno production surface mapped
  • apps/mail/modules/drafting/hooks/use-undo-send.tsno production surface mapped
  • apps/mail/modules/drafting/store/draftSlice.tsno production surface mapped
  • apps/mail/modules/home/components/DisplayArtifactPanel.tsxno production surface mapped
  • apps/mail/modules/inbox/components/ChannelThreadView.tsxno production surface mapped
  • apps/mail/modules/inbox/components/InboxList.tsxno production surface mapped
  • apps/mail/modules/inbox/components/InboxRow.tsxno production surface mapped
  • apps/mail/modules/inbox/store/inboxSlice.tsno production surface mapped
  • apps/mail/modules/linkedin/components/ChatDetail.tsxno production surface mapped
  • apps/mail/modules/threads/mail.tsxno production surface mapped
  • apps/mail/modules/threads/thread/components/mail-display.tsxno production surface mapped
  • apps/mail/modules/threads/thread/components/thread-data-sync.tsxno production surface mapped
  • apps/mail/modules/threads/threadList/hooks/use-mail-navigation.tsno production surface mapped
  • apps/mail/modules/threads/threadList/store/threadSlice.tsno production surface mapped
  • apps/mail/modules/threads/threadList/utils/mail-list-hotkeys.tsxno production surface mapped
  • apps/mail/modules/userSettings/theme/sidebar-theme-switcher.tsxno production surface mapped
  • apps/mail/modules/userSettings/theme/theme-switcher.tsxno production surface mapped
  • apps/mail/modules/userSettings/theme/theme-toggle.tsxno production surface mapped
  • apps/mail/modules/ux/components/navigation-page-url-sync.tsxno production surface mapped
  • apps/mail/modules/ux/layout/layoutSlice.tsno production surface mapped
  • apps/mail/modules/ux/layout/storeNavigator.tsno production surface mapped
  • apps/mail/modules/ux/layout/useBackOrUp.tsno production surface mapped
  • apps/mail/modules/ux/uxSlice.tsno production surface mapped
  • apps/mail/public/logos/meetings/askelephant.svgno production surface mapped
  • apps/mail/public/logos/meetings/attention.pngno production surface mapped
  • apps/mail/public/logos/meetings/attio.pngno production surface mapped
  • apps/mail/public/logos/meetings/circleback.pngno production surface mapped
  • apps/mail/public/logos/meetings/fathom.pngno production surface mapped
  • apps/mail/public/logos/meetings/fireflies.pngno production surface mapped
  • apps/mail/public/logos/meetings/gong.svgno production surface mapped
  • apps/mail/public/logos/meetings/granola.svgno production surface mapped
  • apps/mail/public/logos/meetings/krisp.pngno production surface mapped
  • apps/mail/tests/modules/calendar/calendarEventLayout.test.tsno production surface mapped
  • apps/mail/tests/modules/cedar-os/provisionalPrimaryContext.test.tsno production surface mapped
  • apps/mail/tests/modules/conversations/contextCardsConversation.test.tsno production surface mapped
  • apps/mail/tests/modules/crm/utils/format-relative-date.test.tsno production surface mapped
  • apps/mail/tests/modules/drafting/undoSendRestore.test.tsno production surface mapped
  • apps/mail/tests/modules/layout/appShellPersist.test.tsxno production surface mapped
  • apps/mail/tests/modules/thread/mail-navigation-escape.test.tsxno production surface mapped
  • apps/mail/tests/modules/thread/threadSlice.test.tsno production surface mapped
  • apps/mail/tests/modules/thread/unibox-navigation-parity.test.tsno production surface mapped
  • apps/mail/tests/modules/ux/layout/useRouteChatThread.mail.test.tsxno production surface mapped
  • apps/mail/tests/modules/ux/uxSlice.test.tsno production surface mapped
  • apps/server/docs/design/slack-external-participant-routing.mdno production surface mapped
  • apps/server/docs/design/slack-marketplace-approval.mdno production surface mapped
  • apps/server/src/db/crm-schema.tsno production surface mapped
  • apps/server/src/db/migrations/scripts/backfill-slack-channels.tsno production surface mapped
  • apps/server/src/db/migrations/slack_channel_envelope_heal.sqlno production surface mapped
  • apps/server/src/db/migrations/slack_read_state_channel_only.sqlno production surface mapped
  • apps/server/src/db/schema.tsno production surface mapped
  • apps/server/src/env.tsno production surface mapped
  • apps/server/src/mastra/utils/__tests__/prompt-cache-fetch.test.tsno production surface mapped
  • apps/server/src/mastra/utils/prompt-cache-fetch.tsno production surface mapped
  • apps/server/src/mastra/workflows/chat/chat-workflow.tsno production surface mapped
  • apps/server/src/mastra/workflows/chat/run-chat-agent-sdk.tsno production surface mapped
  • apps/server/src/routes/unipile-webhook.tsno production surface mapped
  • apps/server/src/services/crm/__tests__/slack-events.ingest.test.tsno production surface mapped
  • apps/server/src/services/crm/conversations.tsno production surface mapped
  • apps/server/src/services/crm/slack-events.tsno production surface mapped
  • apps/server/src/services/inbox/feed-core.tsno production surface mapped
  • apps/server/src/services/integrations/linkedin/__test__/linkedin.subscription.test.tsno production surface mapped
  • apps/server/src/services/integrations/linkedin/index.tsno production surface mapped
  • apps/server/src/services/posthog/posthog.tsno production surface mapped
  • apps/server/src/trpc/routes/__tests__/settings-router.test.tsno production surface mapped
  • apps/server/src/trpc/routes/crm.tsno production surface mapped
  • apps/server/src/trpc/routes/settings.tsno production surface mapped