A NotebookLM-inspired workspace that turns sources into a two-host podcast. OpenAI scripts, Kokoro TTS.
TypeScript
0
5 commits
updated Apr 24, 2026
A local-first Next.js workspace that mirrors the parts of Google NotebookLM that matter: chat grounded in your sources, a two-host audio overview, and a growing library of structured artifacts (study guide, briefing, FAQ, mind map, quiz, flashcards, timeline) — all persisted to a single SQLite file.
text-embedding-3-small, and given a short OpenAI-generated summary + key entities on ingest.gpt-4o-mini over SSE, grounded in the top-K retrieved chunks of the notebook (or your current selection).[S1] citation pills — click one to open the exact source chunk highlighted in the preview.All generate from the selected sources (or all sources if none are picked) and persist per-notebook. Regenerating replaces the previous copy.
1 again / 2 got it, ← / →, Space)Collapsible Notes card in the Studio column. Manual notes (Markdown) + Save-as-note on any chat reply. Inline edit + delete.
data/notebook.db (SQLite, WAL) stores notebooks, sources, embeddings (as BLOBs), messages, jobs, artifacts, and notes.data/audio/<jobId>.wav and are garbage-collected when the notebook is deleted./ is a grid of notebook cards with title, emoji, source count, and last-updated. /n/[id] is the workspace.
⌘K focus chat · ⌘U open upload · ? or ⌘/ toggle shortcut cheat sheet · Esc close dialogs.cp .env.example .env # add OPENAI_API_KEY
npm install
npm run dev # http://localhost:3000
The first Generate of an audio overview downloads ~300 MB of Kokoro ONNX weights (cached in ~/.cache/huggingface). Subsequent generations are fast.
Without an API key the app still boots and persists, but chat / embeddings / summaries / artifacts degrade to small demo placeholders. The podcast pipeline still runs end-to-end in demo mode.
npm run build # scripts use `next start`, so build first
npm run smoke:persist # ~30 s: notebook + source survive a restart
npm run smoke # ~2–10 min: chat, every artifact kind, notes CRUD, audio WAV
app/
page.tsx notebook grid (home)
n/[id]/page.tsx workspace
api/
notebooks/route.ts list + create
notebooks/[id]/route.ts get/patch/delete
notebooks/[id]/sources/route.ts upload text / PDF / URL / YouTube
notebooks/[id]/chat/route.ts SSE streaming RAG chat
notebooks/[id]/artifacts/route.ts all 7 artifact kinds
notebooks/[id]/audio/route.ts start an audio job
notebooks/[id]/notes/route.ts list + create notes
notes/[id]/route.ts patch + delete note
sources/[id]/route.ts get + delete source
sources/[id]/summary/route.ts regenerate summary
audio/[id]/status/route.ts poll a job
audio/[id]/route.ts stream the WAV
components/
SourcesPanel / ChatPanel / StudioPanel
UploadDialog / SourcePreviewModal / ArtifactModal
MindMapViewer / QuizViewer / FlashcardsViewer / TimelineViewer
NotesPanel / KeyboardHelp / Toast / Markdown / Icon
lib/
db.ts SQLite + migrations
store.ts CRUD for every table
types.ts shared types
chunking.ts paragraph-aware ~800-char splitter
embeddings.ts OpenAI embeddings + cosine top-K
ingest.ts chunk + embed + summarize on upload
summarize.ts per-source summary + entities
openai.ts two-host podcast script (JSON mode)
kokoro.ts TTS + per-line timings + WAV encode
voices.ts Kokoro voice catalog
artifacts.ts prompts + validators for all 7 kinds
extract.ts PDF via pdfjs-dist + URL scraper
youtube.ts YouTube URL → transcript
| Env var | Default | Notes |
|---|---|---|
OPENAI_API_KEY | — | Required for chat, embeddings, summaries, artifacts, and full-quality scripts. |
OPENAI_MODEL | gpt-4o-mini | Any Chat Completions model with JSON mode + streaming. |
OPENAI_EMBED_MODEL | text-embedding-3-small | 1536-dim. |
HF_HOME | ~/.cache/huggingface | Where Kokoro weights are cached on first run. |
5 commits
TypeScript
90.0%
JavaScript
9.2%
A NotebookLM-inspired workspace that turns sources into a two-host podcast. OpenAI scripts, Kokoro TTS.
TypeScript
0
5 commits
updated Apr 24, 2026
A local-first Next.js workspace that mirrors the parts of Google NotebookLM that matter: chat grounded in your sources, a two-host audio overview, and a growing library of structured artifacts (study guide, briefing, FAQ, mind map, quiz, flashcards, timeline) — all persisted to a single SQLite file.
text-embedding-3-small, and given a short OpenAI-generated summary + key entities on ingest.gpt-4o-mini over SSE, grounded in the top-K retrieved chunks of the notebook (or your current selection).[S1] citation pills — click one to open the exact source chunk highlighted in the preview.All generate from the selected sources (or all sources if none are picked) and persist per-notebook. Regenerating replaces the previous copy.
1 again / 2 got it, ← / →, Space)Collapsible Notes card in the Studio column. Manual notes (Markdown) + Save-as-note on any chat reply. Inline edit + delete.
data/notebook.db (SQLite, WAL) stores notebooks, sources, embeddings (as BLOBs), messages, jobs, artifacts, and notes.data/audio/<jobId>.wav and are garbage-collected when the notebook is deleted./ is a grid of notebook cards with title, emoji, source count, and last-updated. /n/[id] is the workspace.
⌘K focus chat · ⌘U open upload · ? or ⌘/ toggle shortcut cheat sheet · Esc close dialogs.cp .env.example .env # add OPENAI_API_KEY
npm install
npm run dev # http://localhost:3000
The first Generate of an audio overview downloads ~300 MB of Kokoro ONNX weights (cached in ~/.cache/huggingface). Subsequent generations are fast.
Without an API key the app still boots and persists, but chat / embeddings / summaries / artifacts degrade to small demo placeholders. The podcast pipeline still runs end-to-end in demo mode.
npm run build # scripts use `next start`, so build first
npm run smoke:persist # ~30 s: notebook + source survive a restart
npm run smoke # ~2–10 min: chat, every artifact kind, notes CRUD, audio WAV
app/
page.tsx notebook grid (home)
n/[id]/page.tsx workspace
api/
notebooks/route.ts list + create
notebooks/[id]/route.ts get/patch/delete
notebooks/[id]/sources/route.ts upload text / PDF / URL / YouTube
notebooks/[id]/chat/route.ts SSE streaming RAG chat
notebooks/[id]/artifacts/route.ts all 7 artifact kinds
notebooks/[id]/audio/route.ts start an audio job
notebooks/[id]/notes/route.ts list + create notes
notes/[id]/route.ts patch + delete note
sources/[id]/route.ts get + delete source
sources/[id]/summary/route.ts regenerate summary
audio/[id]/status/route.ts poll a job
audio/[id]/route.ts stream the WAV
components/
SourcesPanel / ChatPanel / StudioPanel
UploadDialog / SourcePreviewModal / ArtifactModal
MindMapViewer / QuizViewer / FlashcardsViewer / TimelineViewer
NotesPanel / KeyboardHelp / Toast / Markdown / Icon
lib/
db.ts SQLite + migrations
store.ts CRUD for every table
types.ts shared types
chunking.ts paragraph-aware ~800-char splitter
embeddings.ts OpenAI embeddings + cosine top-K
ingest.ts chunk + embed + summarize on upload
summarize.ts per-source summary + entities
openai.ts two-host podcast script (JSON mode)
kokoro.ts TTS + per-line timings + WAV encode
voices.ts Kokoro voice catalog
artifacts.ts prompts + validators for all 7 kinds
extract.ts PDF via pdfjs-dist + URL scraper
youtube.ts YouTube URL → transcript
| Env var | Default | Notes |
|---|---|---|
OPENAI_API_KEY | — | Required for chat, embeddings, summaries, artifacts, and full-quality scripts. |
OPENAI_MODEL | gpt-4o-mini | Any Chat Completions model with JSON mode + streaming. |
OPENAI_EMBED_MODEL | text-embedding-3-small | 1536-dim. |
HF_HOME | ~/.cache/huggingface | Where Kokoro weights are cached on first run. |
5 commits
TypeScript
90.0%
JavaScript
9.2%