Export chat session: Markdown, plain text, and clipboard#189
Merged
Conversation
Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>
…adow Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>
…Panel shadow" This reverts commit 03311ec.
Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>
Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>
Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>
Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>
Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>
…ping, popover a11y Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>
3a71129 to
187f25b
Compare
Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>
Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>
quiet-node
added a commit
that referenced
this pull request
May 25, 2026
Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>
quiet-node
added a commit
that referenced
this pull request
May 25, 2026
Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Overview
Adds a chat-session export feature reachable from a new icon in the chat header. Users can save the active conversation as a self-contained Markdown file or copy a clipboard-friendly Markdown body to the system clipboard. The flow is built around the existing NSPanel overlay so the native save dialog feels at home with the rest of the spotlight surface.
What changed
menu/menuitemwidget with first-item autofocus andEscape-to-dismiss.src/lib/exportSerializer.ts:serializeForFileemits a self-contained Markdown artefact (YAML frontmatter, role-labelled blocks, inline base64 screenshots, search source links).serializeForClipboardemits a body-only Markdown block with image markers (no frontmatter, no base64) so paste targets like Slack and Discord stay readable.export::prompt_and_save_chat_export). The frontend hands over the serialised content and a suggested filename; the destination path is consumed entirely inside Rust and never crosses the IPC boundary.NSNavPanelExpandedStateForSaveModewrite), matching the spotlight feel.How it works
set_overlay_alpha(0)and invokesprompt_and_save_chat_export.NSSavePanelwith a Markdown filter.Ok(false). On a write failure it returns a sanitised, kind-specific message (no absolute path).finally, regardless of which branch executed.Security and correctness notes
fs::writeat an arbitrary path.dialog:allow-savecapability is no longer required and was removed fromcapabilities/default.json;@tauri-apps/plugin-dialogis dropped from frontend dependencies because the renderer no longer calls the dialog plugin directly.std::io::ErrorKind, so the destination path never appears in the error banner / screenshots / screen recordings.\n,\",\\, or---cannot escape the block and inject keys downstream parsers would honour.javascript:,data:, and other non-http(s) URLs degrade to a non-clickable line that preserves the raw URL for context. Streamdown + rehype-sanitize already protect Thuki's own renderer; this is the matching protection for the exported file when it is opened in a third-party Markdown viewer.runFileExportensures the alpha:0/alpha:1 brackets cannot interleave if the user double-clicks the menuitem while a save dialog is still on screen.Testing
bun run test:all:coverage— Vitest (1480 tests, 100% line/branch/statement/function coverage acrosssrc/) pluscargo +nightly-2026-03-30 llvm-cov(882 unit tests, lib.rs/main.rs-excluded line gate passes).bun run validate-build— lint (ESLint + cargo clippy-D warnings), Prettier + rustfmt format check,tsc --noEmit, frontend Vite build,tauri buildrelease bundle.Note
The Markdown path runs image loads in parallel via
Promise.allso an image-heavy session does not stall the overlay-hidden window any longer than the actual file write.