Files
Momento/memento-note/BRAINSTORM-CANVAS-SPEC.md
Antigravity 1fcea6ed7d
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 7s
feat: brainstorm sessions, PDF document Q&A, embedding fixes, and UI improvements
- 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
2026-05-14 17:43:21 +00:00

176 lines
6.9 KiB
Markdown

# Brainstorm Canvas — Feature Spec for OpenCode
## PROJECT CONTEXT
- **Stack**: Next.js 15 + Prisma + PostgreSQL (pgvector)
- **Location**: ~/dev/Momento/memento-note/
- **Existing models**: User, Note, Notebook, Canvas (Excalidraw), Agent, Conversation, Workflow, etc.
- **Existing API routes**: /app/api/notes, /notebooks, /ai, /canvas, /chat, /agents, etc.
- **UI lib**: Radix UI + Tailwind CSS + shadcn components
- **State**: @tanstack/react-query
- **Auth**: NextAuth (auth.ts, auth.config.ts)
## ⚠️ CRITICAL RULES
1. **DO NOT modify existing models or API routes** — only ADD new ones
2. **DO NOT touch prisma/schema.prisma without creating a migration** — use `npx prisma migrate dev --name add_brainstorm`
3. **Study the existing code patterns** before writing new code — match the project conventions
4. **Look at how existing API routes are structured** (e.g., /app/api/notes/route.ts) and follow the same pattern
5. **Look at how existing components use React Query** and follow the same pattern
6. **Use existing UI components** from /components/ui/ (shadcn) — don't install new UI libs
7. **The project uses TypeScript** — maintain strict typing
8. **Do NOT run npm build** — only dev server if needed for testing
## FEATURE: Brainstorm Canvas (Wave Brainstorming)
### Concept
A temporary workspace for brainstorming ideas using AI-generated "waves" of ideas, displayed as a radial graph. The output feeds back into the notes system.
### Data Model — ADD these 2 models to prisma/schema.prisma:
```prisma
model BrainstormSession {
id String @id @default(cuid())
seedIdea String
sourceNoteId String?
contextNoteIds String? // JSON array of note IDs
exportedNoteId String?
userId String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
ideas BrainstormIdea[]
sourceNote Note? @relation(fields: [sourceNoteId], references: [id])
exportedNote Note? @relation(fields: [exportedNoteId], references: [id])
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@index([userId])
@@index([userId, createdAt])
}
model BrainstormIdea {
id String @id @default(cuid())
sessionId String
waveNumber Int // 1, 2, or 3
title String
description String
connectionToSeed String?
noveltyScore Int?
parentIdeaId String? // for "dig deeper" sub-brainstorms
convertedToNoteId String?
relatedNoteIds String? // JSON array
status String @default("active") // active, dismissed, converted
positionX Float?
positionY Float?
createdAt DateTime @default(now())
session BrainstormSession @relation(fields: [sessionId], references: [id], onDelete: Cascade)
parentIdea BrainstormIdea? @relation("IdeaTree", fields: [parentIdeaId], references: [id])
children BrainstormIdea[] @relation("IdeaTree")
convertedNote Note? @relation(fields: [convertedToNoteId], references: [id])
@@index([sessionId])
@@index([waveNumber])
@@index([status])
@@index([parentIdeaId])
}
```
Also add relations to User model:
```
brainstormSessions BrainstormSession[]
```
And to Note model — add these two relations:
```
sourceBrainstormSessions BrainstormSession[] @relation via sourceNoteId
exportedBrainstormSessions BrainstormSession[] @relation via exportedNoteId
convertedBrainstormIdeas BrainstormIdea[] @relation via convertedToNoteId
```
### API Routes — Create /app/api/brainstorm/
1. **POST /api/brainstorm/wave** — Create new brainstorm session
- Input: { seedIdea, sourceNoteId?, contextNoteIds? }
- Uses existing AI setup (check how /api/ai/ routes call LLM)
- Generates 3 waves of ~3 ideas each (9 total)
- For each idea, does an embedding search to find related notes (check how semantic search works in existing code)
- Saves session + ideas to DB
- Returns: { sessionId, ideas: [...] }
2. **POST /api/brainstorm/[sessionId]/expand** — Dig deeper on an idea
- Input: { ideaId }
- Uses the clicked idea as new seed
- Generates 3 more waves, linked as children
- Returns new ideas with parentIdeaId set
3. **POST /api/brainstorm/[sessionId]/dismiss** — Mark idea as not relevant
- Input: { ideaId }
- Sets status = "dismissed"
4. **POST /api/brainstorm/[sessionId]/convert** — Convert idea to a real Note
- Input: { ideaId }
- Creates a Note with pre-filled content
- Auto-tags: "brainstorm", "idée"
- Links to source note if exists
- Sets idea.status = "converted", idea.convertedToNoteId = newNote.id
- Returns the created note
5. **POST /api/brainstorm/[sessionId]/export** — Export session as summary note
- Generates a Markdown summary note
- Groups by waves, shows which ideas were converted
- Links to all converted notes
- Returns the created note
6. **GET /api/brainstorm** — List user's brainstorm sessions
- Returns sessions ordered by date, with idea counts
7. **GET /api/brainstorm/[sessionId]** — Get full session with ideas
- Returns session + all ideas + their status
### Frontend — Canvas Component
Use **react-force-graph-2d** (install it: `npm install react-force-graph-2d`).
It's a React wrapper around d3-force — declarative API, same physics engine.
**Layout:**
- Center node = seed idea (large, white)
- Ring 1 (radius ~150px) = Wave 1 ideas (orange)
- Ring 2 (radius ~300px) = Wave 2 ideas (blue)
- Ring 3 (radius ~450px) = Wave 3 ideas (purple)
- Use d3.forceRadial for ring constraint
- Dismissed nodes = opacity 0.3, smaller
- Converted nodes = green border + icon
- Click node = side panel with details + 3 action buttons
**Side Panel (when clicking a node):**
- Show: title, description, connection to seed, related notes
- 3 buttons: Dig Deeper, Create Note, Dismiss
- Uses existing shadcn Sheet or Dialog component
**Sidebar Integration:**
- Add "Brainstorms" section in the existing sidebar
- List sessions with preview (seed idea + count)
- Click to reopen saved canvas state
**Entry Points:**
1. From a note: Brainstorm button in note toolbar/editor
2. From sidebar: "+ New Brainstorm" button
### AI Prompt for Wave Generation
The LLM prompt should generate 3 waves:
- **Wave 1 — Variations**: Direct variations/expansions of the seed (sous-aspects, reformulations, variations)
- **Wave 2 — Analogies**: Cross-domain analogies (autres domaines, biologie, technologie, etc.)
- **Wave 3 — Disruptions**: Inversions, provocations, ideas that challenge assumptions
Each idea should have:
- title (short)
- description (1-2 sentences)
- connectionToSeed (how it relates to the seed)
- noveltyScore (1-10)
### Implementation Order
1. Prisma schema + migration
2. API routes (start with /wave and /convert)
3. Brainstorm canvas component (react-force-graph-2d)
4. Sidebar integration
5. Note toolbar button
6. Export functionality