Proposal: Synthesize Mode¶
Status: Implemented (local-first v1) · Last updated: 2026-07-13
Summary¶
An IDE-like workspace for turning sources into documents: collapsible sidebar of projects/files/sources, resizable tabbed panes holding chat threads, markdown editors, and source viewers side by side. The UI is SvelteReader's WorkspaceLayout; the data model and agent are socratic-seminar's.
Motivation¶
Synthesize is where the other modes converge: sources from Search, annotations from Read, and (structurally) the same workspace Debate needs. SvelteReader's synthesize mode is the strongest layout reference in the reference set; socratic-seminar already implements the matching data model (projects → threads + versioned artifacts + sources) and the agent that edits files through approval-gated tools.
Design¶
- Layout: port SvelteReader's
WorkspaceLayout.sveltepattern — left sidebar (drag-resize 180–400px, collapsible) + two tabbed columns with draggable divider; tabs render chat / editor / source viewer via snippets. - Data model (socratic-seminar
db/types.ts, one IndexedDB per npub):Project,Thread(+ verbatim piTranscriptRecord),Artifact+ArtifactVersion(versioned markdown snapshots),Source/Bibliography,WorkspaceState/LayoutState. - Editor: CodeMirror 6 with Obsidian-style live preview (socratic-seminar's
codemirror/livePreview.ts);[[Title]]wiki-links between artifacts and sources. - Agent: pi runner with the file tools (
read_file/patch_filewith approval gate), sources, todos, clarify — socratic-seminar'sagent/directory nearly verbatim. Reads see live editor content. - Nostr sync: deferred to a shared decision with Debate mode (same entities). Local-first ships first; relays-as-filesystem follows the event-kind design in the Debate proposal.
Reference material¶
- SvelteReader
frontend/src/lib/components/synthesize/—WorkspaceLayout,TabbedPanel,SynthSidebar,ProjectDashboard - socratic-seminar
src/lib/db/,src/lib/agent/,src/lib/codemirror/,src/lib/components/{Editor,ChatPanel,ToolCallDisplay}.svelte
Decisions (2026-07-13)¶
- Shared workspace core now: the workspace (layout, db entities, editor, agent wiring) is built mode-agnostic in
$lib/workspace/; Synthesize is its first consumer, Debate later = the same core + the seminar template/persona. Synthesize-only bits (persona, dashboard copy) stay under$lib/synthesize/or the route. - Full mode, built in phases (see plan below), committed to master phase by phase.
- Mobile: below a breakpoint the sidebar becomes an overlay drawer and the two tabbed columns collapse to one pane. No separate mobile design.
- Embeddings deferred: plain title/text search over sources; no in-browser transformer models in the bundle. The agent reads source content directly.
- Data model: socratic-seminar's shapes verbatim (they are SvelteReader's types with the LangGraph fields already stripped):
Project,Thread+TranscriptRecord(verbatim piAgentMessage[]),Artifactwith embeddedArtifactVersion[],Source(+ deferred file fields),WorkspaceStateper project /LayoutStateper npub. New stores land in the existing per-npubplebchat::<npub>DB via a version bump — no second database.
Phase plan¶
- Data model + dashboard —
$lib/workspace/types + db stores (DB v3), projects store,/synthesizeproject dashboard (create/rename/tag/delete),/synthesize/[id]shell. - WorkspaceLayout port — sidebar (files/sources/threads, drag-resize 180–400px, collapsible) + two tabbed columns with draggable divider, snippet-rendered tabs, persisted
WorkspaceState/LayoutState; mobile single-pane + drawer. - Editor + versioning — CodeMirror 6 markdown with live preview (socratic-seminar
codemirror/livePreview.ts),[[Title]]links, version snapshots + history, read-only source viewer. - Agent —
$lib/airunner + workspace tools (list_files/read_fileauto-approved,patch_file/write_fileapproval-gated), sources tools, chat panel with tool cards; reads see live editor content. - e2e + docs — Playwright (mocked SSE endpoint like
e2e/search.test.ts): project CRUD, artifact editing + versions, agent patch approval. MkDocs page.
Open questions¶
- Nostr sync (unchanged): deferred to the shared event-kind decision with Debate mode; local-first ships first.
- Sources from Search mode: importing a Search thread's sources into a project is a natural follow-up once both exist; not in this build-out.
Progress¶
- Shared workspace core decision (with Debate) — yes,
$lib/workspace/ - Phase 1: IndexedDB schema (DB v3) + projects store + dashboard +
?project=deep links - Phase 2: WorkspaceLayout port (sidebar + tabbed panes, drag-to-split, persisted layout, mobile drawer). Interim panes: textarea file editor (CodeMirror is Phase 3), placeholder chat (agent is Phase 4), manual add-source modal. Dropped from the SvelteReader sidebar for now: file tags, thread status filters.
- Phase 3: CodeMirror editor with live preview +
[[links]]+ versions. Live-content store layer (dirty tracking, debounced flush; versions only by explicit snapshot), version toolbar (prev/next/snapshot), theme-aware livePreview recolored to semantic tokens, Cmd/Ctrl+click wiki-links open-or-create artifacts. - Phase 4: Agent integration.
$lib/airunner gained the mode-agnostic approval seam (approvalRequired+pendingApproval/respond) and async transcript hydration; workspace tools = list/read/grep/glob/write/patch files (patch approval-gated, reads see live editor content) + list/read sources; per-thread runners persist verbatim transcripts to thetranscriptsstore and auto-title threads. ChatPanel shows tool cards, a search/replace approval banner with rejection feedback, and reuses the shared AI settings dialog. Deferred from socratic-seminar: ask_user/choices clarify tools, todos, think. - Phase 5: Playwright e2e (built alongside each phase: project lifecycle, tabs/persistence, versions, wiki-links, patch approve/reject, unconfigured gate — 8 tests) +
LIVE=1smoke (real endpoint: patch proposal → approval → edited file, verified green 2026-07-13) +docs/synthesize.mduser guide. - Type-homed columns (2026-07-16, superseding SvelteReader's free-form two-column model): files and sources live in the LEFT column, chat threads in the RIGHT — strict, no cross-column tab dragging (the Split-Right drop affordance and the open/close-panel buttons are gone). The right pane exists exactly while chat tabs exist; opening a chat always splits, closing the last chat tab returns the editor to full width. Saved arrangements re-partition on load (
rehome), and crossing the phone breakpoint folds everything into the single column and back. "New chat" reuses an existing empty thread, and closing a never-used chat's tab deletes it (removeIfEmpty) — no orphaned empties. The per-pane "+" menus keep the same items everywhere; everything (menus, ⌘K, sidebar, agent write/approval reveals) routes by type home. - View context for the agent (2026-07-16): the system prompt (rebuilt each send) gains a "What the user is looking at" section — open file/source tabs with the active file marked, plus the text currently highlighted in an editor or source viewer (runtime-only
wsContextstore; CodeMirror selections survive composer focus, source-viewer selections are captured on pointer release; 2k-char cap). Default split moved to 2/3 document / 1/3 chat. - Reference-parity pass (2026-07-16, from the SvelteReader feature audit): New File modal (filename + template grid from
$lib/workspace/templates.ts+ drag-drop import of text files — the templates seam is also Debate's Socratic Seminar seeding path); URL-fetching sources (AddSourceModal "From the web" mode: multi-URL, Firecrawl reader markdown, per-URL status; manual paste stays the no-key path); unread dots (viewedflag on artifacts/sources — set false on create and on agentpatch_fileto a non-visible file, cleared by a WorkspaceView effect when the item is the active tab); richer tab "+" menu (New file / New chat / Add source / Open…) and a real ⌘K QuickOpen palette searching files/chats/sources (SvelteReader only rendered the ⌘K hint). Modals are owned by WorkspaceView and column-targeted. Still deferred: ask_user/choices clarify tools, image artifacts/file-type icons, source web search.
Follow-ups (post-v1)¶
- Nostr sync (shared event-kind decision with Debate).
- Import a Search thread's sources into a project; ~~agent-driven source scraping (Firecrawl)~~ — user-driven URL fetching landed 2026-07-16 (AddSourceModal); an agent-callable scrape tool remains open.
- ~~Sidebar file tags + thread status filters~~ — done 2026-07-14, see
workspace-thread-status-and-file-tags.md. - Clarify/todos/think tools from socratic-seminar; Debate mode = this core + seminar persona.