From b081e33c0a37585a1ee60b6e0e1ea03457f1e5f4 Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Wed, 4 Mar 2026 16:14:26 -0600 Subject: [PATCH] feat: add Jupyter Notebook (.ipynb) preview in FileNav - New NotebookView component renders markdown cells (marked+DOMPurify), code cells (Shiki-highlighted with execution count gutter), and outputs (text, HTML tables, base64 images, error tracebacks) - ANSI escape codes stripped from error output - Source toggle shows raw JSON - Dark mode support throughout --- src/lib/components/chat/FileNav.svelte | 3 +- .../chat/FileNav/FilePreview.svelte | 19 ++ .../chat/FileNav/NotebookView.svelte | 303 ++++++++++++++++++ 3 files changed, 324 insertions(+), 1 deletion(-) create mode 100644 src/lib/components/chat/FileNav/NotebookView.svelte diff --git a/src/lib/components/chat/FileNav.svelte b/src/lib/components/chat/FileNav.svelte index 46df84b48..e79f7cba4 100644 --- a/src/lib/components/chat/FileNav.svelte +++ b/src/lib/components/chat/FileNav.svelte @@ -121,6 +121,7 @@ $: isHtml = HTML_EXTS.has(getFileExt(selectedFile)); $: isJson = ['json', 'jsonc', 'jsonl', 'json5'].includes(getFileExt(selectedFile)); $: isSvg = getFileExt(selectedFile) === 'svg'; + $: isNotebook = getFileExt(selectedFile) === 'ipynb'; $: isCode = isCodeFile(selectedFile); $: isOfficeFile = OFFICE_EXTS.has(getFileExt(selectedFile)); $: isTextFile = @@ -636,7 +637,7 @@ {/if} - {#if (isMarkdown || isCsv || isHtml || isCode || isJson || isSvg) && fileContent !== null && !editing} + {#if (isMarkdown || isCsv || isHtml || isCode || isJson || isSvg || isNotebook) && fileContent !== null && !editing}