Replies (messages with parentInteractionId) now open in a right-hand ThreadPane
instead of inline quoting:
- extracted a shared Composer (draft + @mention autocomplete + attach) and
MessageItem (bubble + mentions + attachment + reactions + reply affordance)
- Thread shows top-level messages only; a message with replies gets a
'💬 N replies' link, and hovering shows 💬 'Reply in thread'
- ThreadPane renders the root + its replies + a composer that posts back with
parentInteractionId; Messenger becomes 3-column (list | thread | pane),
pane closes on conversation switch
- no contract/adapter/backend change (parentInteractionId was already wired)
- thread-pane render test (open → reply → parent shows the count); 58 green
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- useMessages exposes upload(); Thread gains a hover reaction picker (react to
a message) and an attach button (upload → stage → send), plus inline image /
file rendering of message attachments — all capability-degrading (hidden when
the adapter lacks react/upload)
- themeable styles for the picker, attach button, staged chip, and attachments
- 57 tests still green
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Turns the SDK from hooks-only into a real UI SDK: <Messenger> (conversation
list + open thread + composer), plus <ConversationList> and <Thread>, all
driven by the existing useConversations/useMessages hooks over the injected
adapter — zero transport imports (boundary intact).
- themeable via --miu-* CSS variables; default theme ships as ./styles.css
- optimistic send, typing indicator, seen ticks, reactions display, unread badges
- render smoke tests (jsdom + MockAdapter): mounts, auto-selects first thread,
sends a message, switches threads (3 tests) — 48 total green
- tsup: css bundled to dist/styles.css; dts scoped to TS entries
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>