MessageReplies

A single thread-opening surface with an authoritative count and up to three recent reply previews.

Preview#

export function MessageRepliesDefaultComposition() {
  return (
    <MessageItem className="w-full max-w-3xl">
      <MessageItemAvatarSlot>
        <Avatar size="md" type="human">
          <AvatarImage src={MESSAGE_REPLIES_AVATAR_SRC.developer} alt="" />
          <AvatarFallback>D</AvatarFallback>
        </Avatar>
      </MessageItemAvatarSlot>
      <MessageItemContent>
        <MessageItemHeader>
          <MessageItemSender>Developer</MessageItemSender>
          <MessageItemTime>1:30 PM</MessageItemTime>
        </MessageItemHeader>
        <MessageItemBody>
          Heads up: deploying v0.30.1 to staging after lunch. Changes include the new DM
          notification logic and the agent restart fix.
        </MessageItemBody>
        <MessageReplies
          render={
            <a
              href="/playground/s/raft/channel/all?thread=all%3Ainvite-security"
              aria-label="Open the invite security thread"
            />
          }
        >
          <MessageRepliesSummary>
            <MessageRepliesSummaryItem>4 replies</MessageRepliesSummaryItem>
            <span aria-hidden>·</span>
            <MessageRepliesSummaryItem render={<strong />}>1 new</MessageRepliesSummaryItem>
            <span aria-hidden></span>
          </MessageRepliesSummary>
          <MessageRepliesItem>
            <Avatar size="sm" type="human">
              <AvatarImage src={MESSAGE_REPLIES_AVATAR_SRC.developer} alt="" />
              <AvatarFallback>D</AvatarFallback>
            </Avatar>
            <MessageRepliesItemSender>Developer</MessageRepliesItemSender>
            <MessageRepliesItemContent>
              Yes, no breaking changes. The new column has a default value.
            </MessageRepliesItemContent>
            <MessageRepliesItemTime dateTime="2026-07-27T13:32:00Z">1:32 PM</MessageRepliesItemTime>
          </MessageRepliesItem>
          <MessageRepliesItem>
            <Avatar size="sm" type="agent">
              <AvatarImage src={MESSAGE_REPLIES_AVATAR_SRC.claudeAssistant} alt="" />
              <AvatarFallback>CA</AvatarFallback>
            </Avatar>
            <MessageRepliesItemSender>Claude Assistant</MessageRepliesItemSender>
            <MessageRepliesItemContent>
              Deployed. Staging looks good so far. Will monitor for 30 min before promoting.
            </MessageRepliesItemContent>
            <MessageRepliesItemTime dateTime="2026-07-27T13:33:00Z">1:33 PM</MessageRepliesItemTime>
          </MessageRepliesItem>
          <MessageRepliesItem>
            <Avatar size="sm" type="human">
              <AvatarImage src={MESSAGE_REPLIES_AVATAR_SRC.developer} alt="" />
              <AvatarFallback>D</AvatarFallback>
            </Avatar>
            <MessageRepliesItemSender>Developer</MessageRepliesItemSender>
            <MessageRepliesItemContent>
              All clear. No errors in the last 30 min. Ready for production whenever.
            </MessageRepliesItemContent>
            <MessageRepliesItemTime dateTime="2026-07-27T13:34:00Z">1:34 PM</MessageRepliesItemTime>
          </MessageRepliesItem>
        </MessageReplies>
      </MessageItemContent>
    </MessageItem>
  );
}

Single unread reply#

Use singular count copy when the thread contains one reply, then append unread status when that reply is new.

CA
Claude Assistant1:20 PM
Should we version the internal API? Right now /internal/* has no version prefix, which makes daemon backward compatibility harder to reason about.
1 reply1 newDDeveloperI'd rather keep it versionless and use feature flags in the handshake. Versioned APIs add a lot of routing complexity.

Unread replies with draft#

Keep unread count and draft status in the summary. The draft body belongs in the composer and is not rendered in the preview.

API#WIP

PropTypeDefaultDescription
...propsuseRender.ComponentProps<"button">Single interactive thread-preview surface. Use render to replace the default button with the consumer's link.
PropTypeDefaultDescription
...propsuseRender.ComponentProps<"span">Flex container that spaces its direct summary fragments by 4px.
PropTypeDefaultDescription
...propsuseRender.ComponentProps<"span">Inline summary fragment with an optional icon. It centers children and standardizes nested SVG icon size; use render for semantic emphasis.
PropTypeDefaultDescription
...propsuseRender.ComponentProps<"span">One compact reply-preview row. Compose the avatar and fields as children.
PropTypeDefaultDescription
...propsuseRender.ComponentProps<"span">Non-shrinking sender display name.
PropTypeDefaultDescription
...propsuseRender.ComponentProps<"span">Flexible, single-line truncated reply excerpt.
PropTypeDefaultDescription
...propsuseRender.ComponentProps<"time">Semantic timestamp aligned to the trailing edge.