Simple conversation threads for organizing chat by topic/feature. NO branching, NO merging - just clean organization.
conversations:
- id (uuid)
- project_id (FK to projects)
- name (e.g., "Login Feature", "Dashboard Work")
- description (optional)
- first_commit_hash (git commit when started)
- last_commit_hash (most recent git commit)
- created_at
- updated_atmessages:
+ conversation_id (FK to conversations) <- NEW!File: supabase/migrations/20251027000000_add_conversations.sql
Migrates existing data:
- Creates "Main" conversation for each project
- Links all existing messages to it
- Zero data loss
-
src/lib/db/conversations.tscreateConversation()listConversations()listConversationsWithMessageCount()updateConversation()deleteConversation()getOrCreateDefaultConversation()
-
src/server/actions/conversations.tscreateNewConversation- Start new topiclistProjectConversations- Get all with message countsupdateConversationMetadata- Rename, update commit hashesdeleteConversationAction- Delete (prevents deleting last one)
Chat Header:
┌─────────────────────────────────────────┐
│ AI Assistant │
│ Conversation: Login Feature ▼ [+ New] │
└─────────────────────────────────────────┘
Dropdown Menu:
📝 Conversations
✓ Login Feature (23 messages) <- Current
Dashboard Work (15 messages)
Bug Fixes (8 messages)
───────────────────
+ New Conversation
1. Switch Conversation
- Click dropdown → select conversation
- Loads only messages for that conversation
- Shows git commits from that conversation's timeframe
2. Create New Conversation
- Click "+ New" button
- Modal: "Name your conversation"
- Creates new thread, switches to it
- Tracks first git commit hash
3. Continue in Current
- Just keep chatting
- All messages go to current conversation
- Last commit hash updates automatically
4. Restore Code State
- View conversation's git commits
- Click "Restore to [commit]"
- Checks out that commit
- Conversation context stays intact
Add state:
const [conversations, setConversations] = useState([]);
const [currentConversation, setCurrentConversation] = useState(null);
const [showNewConvDialog, setShowNewConvDialog] = useState(false);Load conversations:
useEffect(() => {
async function loadConversations() {
const { listProjectConversations } = await import('@/server/actions/conversations');
const result = await listProjectConversations({ projectId });
if (result?.data?.conversations) {
setConversations(result.data.conversations);
setCurrentConversation(result.data.conversations[0]); // Most recent
}
}
loadConversations();
}, [projectId]);Filter messages:
// Only show messages from current conversation
const filteredMessages = messages.filter(
msg => msg.conversation_id === currentConversation?.id
);In chat header:
<DropdownMenu>
<DropdownMenuTrigger>
{currentConversation?.name} ({messages.length} messages) ▼
</DropdownMenuTrigger>
<DropdownMenuContent>
{conversations.map(conv => (
<DropdownMenuItem onClick={() => switchConversation(conv.id)}>
{conv.name} ({conv.message_count} messages)
</DropdownMenuItem>
))}
<DropdownMenuSeparator />
<DropdownMenuItem onClick={() => setShowNewConvDialog(true)}>
+ New Conversation
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>When sending messages:
// Include conversation_id
await fetch('/api/chat', {
method: 'POST',
body: JSON.stringify({
projectId,
conversationId: currentConversation.id, // <- Add this
message: input,
}),
});When agent completes task:
// After successful AI response
if (commitHash) {
await updateConversationMetadata({
conversationId: currentConversation.id,
lastCommitHash: commitHash,
});
}✅ Organize by topic - "Login", "Dashboard", "Refactor" ✅ Context switching - Jump between features ✅ Clean history - No clutter, just what you need ✅ Code restoration - "Go back to dashboard work state" ✅ Simple - No branching complexity
❌ NOT git branches - Just chat organization ❌ NOT mergeable - Can't combine conversations ❌ NOT parallel code states - One codebase, multiple contexts ❌ NOT version control - Use git for that
MIGRATION_DEPLOYMENT.md for full deployment instructions!
Quick summary:
-
Migration file already created:
../e2b-infra/packages/db/migrations/20251027000000_add_conversations.sql -
Build db-migrator image:
cd ../e2b-infra/packages/db make build-and-upload -
Deploy API job:
cd ../e2b-infra/iac/provider-gcp export ENV=prod make deploy-api
-
Verify:
- Check
_migrationstable has version 20251027000000 - Check conversations table exists
- Check messages have conversation_id
- Check "Main" conversation created for existing projects
- Check
-
Update chat UI (see Next Steps above)
-
Regenerate types:
cd botlink-dashboard bun generate:supabase
- Archive old conversations
- Export conversation as markdown
- Search across all conversations
- Conversation templates ("Bug Fix", "Feature", etc.)
- Show git diff between first/last commit of conversation