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
176 lines
6.9 KiB
Markdown
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
|