Phase C of channel-roster import. Adds the optional addMembers(threadId, userIds)
adapter seam (+ BulkAddResult) and, in ConversationSettings, a '#' mode on the
existing Add-people box that lists the channels you belong to — public AND
private, since the source list is your own membership-scoped conversation list.
Picking a channel STAGES the import (reads its roster, diffs against who is
already here) and shows a confirm — 'Add 9 people from #design? (3 already here)'
— so an administrative action never fires on a stray click. The result line
reports added / already-a-member / failed. Absent addMembers => the affordance is
hidden entirely and '#' is just a search string.
Bumped to 0.1.8. SDK suite: 15 files / 78 tests green.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Every message now shows a Slack-style time (clock today, then 'Yesterday',
weekday, else a date; full timestamp on hover).
- New ConversationSettings panel for groups AND channels (public + private):
rename, member list, add people (from the directory), remove, and leave.
Opened from a new thread header gear; DMs show no gear. Adapter gains
addMember/removeMember/renameConversation (optional, OPA still gates writes).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add a 'New message' + on the Direct messages section that opens a people picker
(NewConversation): pick one person -> DM, two or more -> group with an optional
name, via the adapter's existing openThread({participantIds, membership, subject}).
Expose directory() on MessagingAdapter (org people list); MockAdapter implements
it + dedupes 1:1 DMs. 72 tests green.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Adds a third membership beyond dm/group: a discoverable, joinable room.
- contract: Membership += 'channel'; Conversation.topic; ChannelSummary +
CreateChannelInput; optional adapter methods browseChannels/createChannel/
joinChannel/leaveChannel (capability-degrading — absent hides the UI)
- MockAdapter implements them (seeds a joined public, a joinable public, and a
private channel); listConversations now returns only threads I'm in
- useChannels hook (browse/create/join/leave + supported flag)
- UI: sidebar sections (Channels vs Direct messages), a + that opens a
ChannelBrowser (join + create), # / lock glyphs; themeable styles
- KernelClientAdapter passes channel membership + topic through
- 4 channel tests (mock browse/join/create + render browse→join); 52 total green
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>