Many chats per space. A space used to be one rolling AI thread; now it
holds many named conversations — like Claude or the VS Code assistant. A
left chat sidebar (Claude-style) lists them with + New chat, and each
row has inline rename and delete. It appears as a slide-in column in
the compact popover (new sidebar / new-chat buttons in the header) and
replaces the space list in Agent mode with the current space's chats.
New chats start blank. Opening a fresh chat shows starter chips instead of
auto-running a scan. The signature space briefing is now an explicit
"✨ Brief me on this space" chip (still plays the scan) rather than an
automatic run on open.
Auto-titled chats. A chat is "New chat" until its first message, then
titled from it (renameable).
Cloud persistence (supabase/migrations/20260706000100_ai_conversations.sql):
new ai_conversations table (RLS mirroring ai_messages); ai_messages
gains a conversation_id; existing per-space threads are backfilled into
one conversation each (no history lost); retention trims per conversation now.
New app/api/ai/conversations route lists / creates / renames / deletes
chats. Local spaces keep the same model client-side in lib/ai/conversations.ts
(per-space chat index + per-chat threads, with a one-time migration of the old
single thread).
Changed
/api/ai brief + chat turns persist against a conversationId, and its GET
loads a single chat by conversationId (still accepts spaceId for older
clients). Message history is stored per chat instead of per space.
Agent view chrome trimmed to match the Claude reference. Dropped the
full-width divider bands around the header and follow-up composer (their
border + surface background); both now float on the page background instead of
sitting in boxed-off bars. The header now shows the active chat's title
(space/card context and settings/account live in the left sidebar), and the
redundant AI-settings gear + account avatar were removed from it.
Claude-style empty state. A fresh chat with no messages now shows a
centered greeting ("Afternoon, {name}") with the composer directly beneath it
and the starter chips below — instead of a bottom-docked composer over an empty
thread. Once the chat has a turn, it reverts to the scrolling thread + docked
composer.