Repository navigation
Conversation
…a channel Add conversation.ui.Conversation, a host-owned scope for a page's own ui.Message rows and ui.Composer in one channel. It reuses the existing non-visiting ConversationChannel host mode, so rows get native edit, confirmed delete with recovery and retry, a per-scope edit target and host media review, while mounting never marks read, follows or holds the channel roster. Fixes NEXUS-4193 Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Kyle Zemek <kylez@squareup.com>
… consumer Observe the profile reservation an open channel makes, exercise ui.Conversation and its interactions in the packed author consumer fixture, and name the instance rather than the scope prop in the docs. Refs NEXUS-4193 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Kyle Zemek <kylez@squareup.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Kyle Zemek <kylez@squareup.com>
kazemek21
marked this pull request as ready for review
November 4, 2026 23:39
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.
TL;DR
Adds
conversation.ui.Conversation, a public host-owned scope that lets a plugin's ownui.Messagerows andui.Composerfor one channel get native Edit, confirmed Delete with recovery and retry, and host media review. Mounting it never marks anything read, follows a thread or enters the channel visit. Cross-channel overview cards need this; today a bareui.Messagerow has neither Edit nor Delete, andui.Threadalways visits.Fixes NEXUS-4193
How it works
ui.Conversation({ session, scope, channelId, channelName?, threadId?, children(interactions) })renders the existingConversationChannelin its host-dialog, non-visiting mode (hostplusactive={false}). Inbox Drafts already uses this mode internally. Inside it:MessageManagementsupplies the row menu's Edit/Delete under the existing permission checks, the delete confirmation and the failed/unconfirmed recovery notice.MessageEditScopemakes Edit target theui.Composerin the same scope. A scope without a composer offers no Edit, as in other previews.ConversationHostowns media review and panel overlays, focus return, and the existing stale-session guard (nothing opens once the relay snapshot is no longer this ready session).childrenreceives the host'sonOpenLink,canOpenLinkandonOpenMediaReviewto pass to the rows.EmbeddedThreadand the new scope now share oneHostedChannelwrapper, soui.Threadbehavior is unchanged. No changes toMessageManagement,ConversationHost,MessageComposerorcontracts.ts.Evidence
src/features/conversation/EmbeddedConversation.test.tsxmounts two fictional channel cards (real relay session, realui.Messagerows andui.ComposerfromConversationService; onlyMediaReviewVieweris reduced, since it has its own suites). It covers:enterChannel,leaveChannel,follow,markMessageRead,markChannelReador the roster'sprofiles.reserve, and publish nothingFail-then-pass: with
active={false}removed from the scope, all 4 tests fail (enterChannelandprofiles.reserveare called). The scope restored, all pass.The packed
@buzz/authorconsumer fixture (tests/fixtures/conversation-consumer) now renders its rows and composer insideui.Conversationand passesinteractions.onOpenLinkto its rows. So the generated declarations must export the new component and itschildren(interactions)type, and the existingconversation.spec.mjsjourney mounts it in the real app. The fixture type-checks against freshly built declarations. As a negative control, a misspelled interactions field failstsc.Run on a Linux Blox box on base
a34ba4f(the local host-build guard refused under load):vitest run src/features/conversation src/features/messages/MessageManagement.test.tsx src/bundled/inbox/DraftsView.test.tsx: 19 files, 221 tests passedtsc --noEmitandbiome check --error-on-warningson the touched files: cleanpnpm author:build, packed and installed into a copy of the consumer fixture, thenpnpm build(tsc): cleanNo browser journeys were added or removed. The existing consumer journey now mounts the scope; it runs only in hosted CI, not locally. Focus, overlay and native-edit geometry are unchanged existing
ConversationHost/composer behavior that existing suites already cover.Limits and coordination
ui.Conversations for the same channel each show that channel's recovery notice, because recovery is per channel. The docs say to render one per channel or card.service.tsx), NEXUS-4029: Add task source references and primary controls #1889, NEXUS-4022: Create durable task chats in New Chat #2306 or NEXUS-4022: Preserve Nexus metadata in existing composer tokens #2303 (contracts.ts), NEXUS-4082: Keep the new-message boundary stable during a visit #2083 (MessageManagement.tsx) or feat(messages): forward a message to a person #2167 (ConversationHost.tsx). This PR does not editcontracts.ts,MessageManagement.tsxorConversationHost.tsx.Initiative context
Buzz Threads status
🤖 Generated with Claude Code