componentsfeat: UI reorganization for conversation view components Extracts ConversationBodyContent, adds calendar RSVP banner, refactors ConversationView/timeline components, and updates drafting/snippets UI. Co-Authored-By: Claude Sonnet 4.6 (1M context) <<email>>Apr 24, 2026, 12:00 AMhooksfix: deleting threads & thread loading limitApr 9, 2026, 6:01 PMutilsfix: review pass — keep the ping out of the timeline, stop a rename escaping to root Three behavioural fixes found reviewing this branch, plus the deduplication the review turned up. The ambiguity ping's audit row is a dedupe key and a measurement surface, but both conversation reads returned it unfiltered and the timeline renders any action_type it does not recognise by de-underscoring it — so every pinged conversation would have shown the user a pill reading "Agent aop ambiguity ping" the moment the flag was turned on. Excluded from both reads; the ping's own dedupe query hits the table directly and is untouched. moveNode's new pure-rename path fell through to `null` when the parent row could not be loaded, and `null` there means "move to the scope root" — the same teleport the commit above it fixes, reached by a different door. It refuses now. The select-aop tool call is deliberately deferred so `conversationId` is the post-merge surviving id, which meant a throw out of setupConversationForAop lost the record of what the classifier decided — exactly the run you would open the log to diagnose. It flushes on the way out. Deduplication, all of it drift that had already caused a bug once: - resolveOrgId/getSessionOrgId now live in trpc/session-org.ts. user-tasks.ts had copied one and not the other, which is why it scoped conversation lookups to the owner while crm.ts scoped the same rows to the org — the "Untitled" task header. - The backfill script had its own copy of the LinkedIn cold-reach classifier. A backfill that classifies differently from ingest is how the folder=INMAIL check survived unnoticed; it imports the real one now. - One MAX_AOP_AMBIGUITY_ALTERNATIVES, owned by the Slack module where the four-buttons-per-row constraint actually comes from. Also: dropped the ping button's `aopId` arg, which agent_prompt's zod schema strips before the agent ever sees it (the id travels in the prompt, which is what is read); lazy-loaded TranscriptViewerModal off the root render — 10 fewer preloaded chunks and 85 KB off the critical path, though react-markdown stays on it via a second, pre-existing path through messagesSlice's eager renderer registry; and cleaned up two comments orphaned by the extractions, a sideEffects note the same PR falsified, a runbook query naming a table that does not exist, and three no-op eslint-disables. Co-Authored-By: Claude Opus 5 (1M context) <<email>>Aug 17, 2026, 11:58 PM