feat: brainstorm sessions, PDF document Q&A, embedding fixes, and UI improvements
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 7s

- Add brainstorm feature with collaborative canvas, AI idea generation, live cursors, playback, and export
- Add PDF upload/extraction/ingestion pipeline with pgvector document search (RAG)
- Add document Q&A overlay with streaming chat and PDF preview
- Add note attachments UI with status polling, grid layout, and auto-scroll
- Add task extraction AI tool and agent executor improvements
- Fix NoteEmbedding missing updatedAt column, re-index 66 notes with 1536-dim embeddings
- Fix brainstorm 'Create Note' button: add success toast and redirect to created note
- Fix memory echo notification infinite polling
- Fix chat route to always include document_search tool
- Add brainstorm i18n keys across all 14 locales
- Add socket server for real-time brainstorm collaboration
- Add hierarchical notebook selector and organize notebook dialog improvements
- Add sidebar brainstorm section with session management
- Update prisma schema with brainstorm tables, attachments, and document chunks
This commit is contained in:
Antigravity
2026-05-14 17:43:21 +00:00
parent 195e845f0a
commit 1fcea6ed7d
228 changed files with 57656 additions and 1059 deletions

View File

@@ -152,7 +152,7 @@ export function AIChat({ showFloatingTrigger = true }: { showFloatingTrigger?: b
return (
<Button
onClick={() => setIsOpen(true)}
className="fixed bottom-6 right-6 h-12 w-12 rounded-full shadow-xl z-40 transition-transform hover:scale-105 bg-muted text-foreground hover:bg-muted/80 border border-border"
className="fixed bottom-6 end-6 h-12 w-12 rounded-full shadow-xl z-40 transition-transform hover:scale-105 bg-muted text-foreground hover:bg-muted/80 border border-border"
size="icon"
title={t('ai.openAssistant')}
>
@@ -163,7 +163,7 @@ export function AIChat({ showFloatingTrigger = true }: { showFloatingTrigger?: b
return (
<aside className={cn(
"fixed bottom-20 right-6 border border-border/40 bg-memento-paper dark:bg-background flex flex-col z-40 shadow-2xl rounded-2xl overflow-hidden transition-all duration-300",
"fixed bottom-20 end-6 border border-border/40 bg-memento-paper dark:bg-background flex flex-col z-40 shadow-2xl rounded-2xl overflow-hidden transition-all duration-300",
isExpanded ? "w-[80vw] h-[85vh] max-w-[1200px]" : "h-[700px] max-h-[85vh] w-[360px]"
)}>
{/* Header */}
@@ -239,7 +239,7 @@ export function AIChat({ showFloatingTrigger = true }: { showFloatingTrigger?: b
{/* AI Welcome Message */}
{messages.length === 0 && (
<div className="flex gap-3">
<div className="w-8 h-8 rounded-full bg-memento-blue/10 text-memento-blue flex items-center justify-center flex-shrink-0 border border-memento-blue/20">
<div className="w-8 h-8 rounded-full bg-memento-blue/20 text-memento-blue flex items-center justify-center flex-shrink-0 border border-memento-blue/30 shadow-sm">
<Bot className="h-4 w-4" />
</div>
<div className="bg-memento-paper dark:bg-background border border-border/50 p-3.5 rounded-2xl rounded-tl-sm shadow-sm">
@@ -261,7 +261,7 @@ export function AIChat({ showFloatingTrigger = true }: { showFloatingTrigger?: b
'w-8 h-8 rounded-full flex items-center justify-center flex-shrink-0 border text-[10px] font-bold',
msg.role === 'user'
? 'bg-muted border-border text-muted-foreground'
: 'bg-memento-blue/10 text-memento-blue border-memento-blue/20',
: 'bg-memento-blue/20 text-memento-blue border-memento-blue/30 shadow-sm',
)}>
{msg.role === 'user' ? 'U' : <Bot className="h-4 w-4" />}
</div>
@@ -323,7 +323,7 @@ export function AIChat({ showFloatingTrigger = true }: { showFloatingTrigger?: b
history.map(conv => (
<button
key={conv.id}
className="w-full text-left p-3 rounded-xl border border-border/50 hover:bg-muted/50 hover:border-memento-blue/30 transition-all flex flex-col gap-1"
className="w-full text-start p-3 rounded-xl border border-border/50 hover:bg-muted/50 hover:border-memento-blue/30 transition-all flex flex-col gap-1"
onClick={() => {
setConversationId(conv.id)
setMessages(conv.messages.map((m: any) => ({
@@ -353,22 +353,22 @@ export function AIChat({ showFloatingTrigger = true }: { showFloatingTrigger?: b
<div className={cn("p-4 border-t border-border/40 bg-memento-paper dark:bg-background shrink-0", activeTab !== 'chat' && "hidden")}>
{/* Context Scope */}
<div className="mb-3 space-y-2">
<span className="text-[9px] font-bold uppercase tracking-widest text-muted-foreground block ml-1">Source du Contexte</span>
<span className="text-[9px] font-bold uppercase tracking-widest text-muted-foreground block ms-1">Source du Contexte</span>
<button
onClick={() => setChatScope('all')}
className={cn(
'w-full p-2.5 border rounded-lg text-xs flex items-center justify-between transition-all',
chatScope === 'all' ? 'bg-blueprint/10 border-blueprint/30' : 'bg-card border-border hover:border-foreground/20'
chatScope === 'all' ? 'bg-memento-blue/15 border-memento-blue/40 shadow-inner' : 'bg-card border-border hover:border-foreground/20'
)}
>
<div className="flex items-center gap-2">
<Layers className="h-3.5 w-3.5 text-blueprint/60" />
<span className={cn('font-medium', chatScope === 'all' ? 'text-blueprint' : 'text-foreground/60')}>
<Layers className="h-3.5 w-3.5 text-memento-blue/70" />
<span className={cn('font-bold', chatScope === 'all' ? 'text-memento-blue' : 'text-foreground/60')}>
{t('ai.allMyNotes') || 'Toutes mes notes'}
</span>
</div>
{chatScope === 'all' && (
<span className="text-[8px] bg-blueprint/10 text-blueprint px-1.5 py-0.5 rounded uppercase font-bold">Auto</span>
<span className="text-[8px] bg-memento-blue/20 text-memento-blue px-1.5 py-0.5 rounded uppercase font-bold border border-memento-blue/30">Auto</span>
)}
</button>
@@ -389,7 +389,7 @@ export function AIChat({ showFloatingTrigger = true }: { showFloatingTrigger?: b
{/* Tone Selection */}
<div className="mb-3">
<span className="text-[9px] font-bold uppercase tracking-widest text-muted-foreground block mb-1.5 ml-1">{t('ai.writingTone')}</span>
<span className="text-[9px] font-bold uppercase tracking-widest text-muted-foreground block mb-1.5 ms-1">{t('ai.writingTone')}</span>
<div className="grid grid-cols-4 gap-1">
{TONES.map(tone => {
const Icon = tone.icon
@@ -402,7 +402,7 @@ export function AIChat({ showFloatingTrigger = true }: { showFloatingTrigger?: b
className={cn(
"py-1 rounded-md border text-[10px] font-medium transition-all flex flex-col items-center justify-center gap-0.5",
isSelected
? "border-memento-blue bg-memento-blue/10 text-memento-blue shadow-sm"
? "border-memento-blue bg-memento-blue/15 text-memento-blue shadow-sm font-bold"
: "border-border/60 bg-memento-paper dark:bg-background text-muted-foreground hover:bg-muted hover:border-border"
)}
>
@@ -454,7 +454,7 @@ export function AIChat({ showFloatingTrigger = true }: { showFloatingTrigger?: b
onClick={handleSend}
disabled={!input.trim()}
>
<Send className="h-4 w-4 ml-0.5" />
<Send className="h-4 w-4 ms-0.5" />
</Button>
)}
</div>