SQLR-41 — Tauri 2 + Svelte 5 local-first journaling example app#145
Merged
Conversation
New `examples/desktop-journal/` showcases SQLRite as a serious choice for a local-first desktop product. Tauri 2 backend owns one Arc<Mutex<Connection>> in tauri::State; every #[tauri::command] grabs the mutex and runs against the modern `Connection` API. Phase 8 BM25 full-text search drives the search bar with token-boundary-aware <mark> highlighting in Rust. An "ask my journal" panel calls Connection::ask, validates the returned SQL is SELECT/WITH-only, and shows the user both the SQL and the rows. In-app Settings dialog persists the Anthropic key to a separate settings.json next to the journal file — the key never crosses into the webview (DTO returns has_api_key: bool, not the value) and falls back to SQLRITE_LLM_API_KEY when nothing's saved. Capabilities are locked down to core window/event + dialog — no fs/shell/http, so the IPC boundary is the only path to the engine. Wiring: workspace gains `examples/desktop-journal/src-tauri` as a member; CI's existing rust-build/test/clippy/doc commands pick up an `--exclude sqlrite-journal` (same shape as the existing sqlrite-desktop exclude). A new `journal-build` CI job mirrors `desktop-build` for the frontend bundle + cargo build, including a no-default-features pass to prove the off-`ask` build still works. A separate `journal-release.yml` (manual / journal-v* tag trigger) builds .dmg / .deb / .AppImage / .msi via tauri-action and attaches them to a draft release. 14 unit tests cover migrations, CRUD, tag filtering, FTS+highlight, stats, the ask-readonly SQL classifier, settings save/load round-trip, empty-string-key normalisation, three-valued update semantics, the no-leak-to-DTO contract, and settings-over-env precedence. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…d poster Follow-up to be35e4c. Captures the journal app in seven UI states (empty, new entry, markdown preview, list+tags, FTS highlight, Settings, Ask panel), then composes them into a 21s demo video via a Remotion project under `examples/desktop-journal/demo/`. The composition gives each screen a Ken Burns slow zoom with a fade-in caption strip; consecutive screens cross-fade for 8 frames. Renders to `docs/demo.mp4` (1080p H.264, ~8.5 MB) and `docs/demo.gif` (960×540, 15fps, first 5 screens, ~8.8 MB). The GIF fits comfortably in the README and on GitHub's inline image viewer; the MP4 is what the website Examples card points at. Replacing a screenshot is `cd demo && npm run render` — `prep` copies the latest PNGs from `../docs/screenshots/` into `public/` (.gitignore'd so the canonical source stays in `docs/`). Side change: pin `@tauri-apps/{api,cli}` to ~2.10 and `plugin-dialog` to ~2.7 in the journal app's `package.json`. `tauri build` rejects mismatched JS↔Rust major/minor versions; the mismatch shows up the moment you bundle for installer shipping (SQLR-41's release workflow) even though dev mode tolerates it. Website Examples card gains an `Example.demoAsset` field carrying the GIF + MP4 paths. The journal card renders the GIF inline from raw.githubusercontent.com so the homepage tracks the repo on next deploy instead of needing the asset copied into `web/public/`. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
joaoh82
added a commit
that referenced
this pull request
May 30, 2026
…146) The SQL playground (`sqlrite-desktop`) read its `ask` config exclusively from `SQLRITE_LLM_API_KEY`. Launched from Finder/the Dock — which don't inherit a shell's env — the Ask… button just errored. Port the in-app settings pattern from the journal example (SQLR-41, #145) so the key can be pasted in a ⚙ dialog and persists across restarts. - settings.rs: AskSettings (JSON at $APP_DATA/com.sqlrite.desktop/ settings.json), scrubbed AskSettingsDto (has_api_key bool — the raw key never crosses to the webview), three-valued AskSettingsUpdate, build_ask_config (saved key, env var fallback). 5 unit tests. - main.rs: AppState gains settings_path; ask_sql builds config from saved settings instead of from_env; add get_ask_settings / update_ask_settings commands. - SettingsPanel.svelte (plain-CSS, matches the playground) + ⚙ header button + lib/api.ts wrappers. - README: Configuring `ask` + security note. Deviation from the journal port: build_ask_config is unconditional (the desktop crate has no `ask` feature gate) and tempdir() in tests uses an atomic counter, not subsec-nanos, to avoid a parallel-run collision. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
joaoh82
added a commit
that referenced
this pull request
May 30, 2026
#145 added `examples/desktop-journal/src-tauri` (package `sqlrite-journal`, a Tauri/GTK crate) as a workspace member and updated ci.yml's build/test/clippy/doc steps to `--exclude sqlrite-journal`, but release-pr.yml's "Refresh Cargo.lock" step was missed. So `cargo build --workspace --exclude sqlrite-desktop` tried to compile sqlrite-journal → glib-sys on a runner without the GTK system libs, failing the first release-PR dispatch since #145 merged. Mirror ci.yml: also exclude sqlrite-journal here. Lock-refresh only needs to resolve versions, not build the desktop/journal apps. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.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.
Summary
Closes SQLR-41. Adds a polished example app under
examples/desktop-journal/— a markdown daily-notes desktop product backed by a single.sqlritefile. Showcases Phase 8 BM25 full-text search with hit highlighting, the engine'saskfeature in a non-AI-native product context, and the Tauri-friendlyArc<Mutex<Connection>>embedding pattern using the modernConnectionAPI.This is the third in the SQLR-38 example-apps umbrella (after
examples/python-agent/andexamples/nodejs-notes/).Demo
Full 1080p MP4:
examples/desktop-journal/docs/demo.mp4What's in this PR
New example app —
examples/desktop-journal/src-tauri/) owns oneArc<Mutex<Connection>>intauri::State. Every#[tauri::command]grabs the mutex, runs SQL via the publicConnection/StatementAPI, returns serde-serialised structs.BEGIN CONCURRENTretry loops and just as correct. Documented inmain.rsmodule doc.Connection/Statement(not the olderDatabase/process_commandpath used by the existingdesktop/SQL playground, which AGENTS.md says new SDKs should avoid).entries,tags,entry_tags(synthetic PK because SQLRite'sPRIMARY KEYis single-column today), plus secondary indexes onentries.date/updated_atand FTS indexes onentries.content/title.<mark>highlighting on the Rust side, "Ask my journal" panel that callsConnection::askand gates the returned SQL toSELECT/WITHonly, export-DB / export-markdown commands.settings.rs): Anthropic API key persists to$APP_DATA/com.sqlrite.journal/settings.json— a separate file fromjournal.sqlriteso the key doesn't ride along if you sync the DB. DTO returnshas_api_key: bool, never the value; falls back toSQLRITE_LLM_API_KEYenv var when unset.core:default/core:window:default/core:event:default/dialog:default. Nofs/shell/http— the IPC boundary is the only path to the engine.@tailwindcss/vite(no PostCSS dance). All a11y warnings cleared (labels paired, keyboard handlers on interactive elements only).Workspace + CI integration
examples/desktop-journal/src-tauri; existing CI commands gain--exclude sqlrite-journal(same shape as the existingsqlrite-desktopexclude).journal-buildjob in.github/workflows/ci.ymlmirrorsdesktop-build: frontend bundle thencargo build, including a no-default-features pass to prove the off-askbuild still works..github/workflows/journal-release.ymlbuilds.dmg/.deb/.AppImage/.msiinstallers viatauri-apps/tauri-action@v0on manual trigger orjournal-v*tag push, attaching to a draft release.AGENTS.mdupdated symmetrically (CLAUDE.mdchange deferred — see follow-ups).Remotion demo composition —
examples/desktop-journal/demo/docs/screenshots/01-empty.png…07-ask-panel.png) into a 21s demo with Ken Burns slow zoom + fade-in caption strips + cross-fade transitions.docs/demo.mp4(1080p H.264, 8.5 MB) anddocs/demo.gif(960×540, 15fps, 8.8 MB, first 5 screens).npm run prepcopies the canonical screenshots fromdocs/screenshots/into the Remotionpublic/(gitignored) so there's one source of truth.npm run renderre-produces both formats.Website Examples card
/examples. JSON-LD updated. NewExample.demoAssetfield carrying GIF + MP4 paths.raw.githubusercontent.com(noweb/public/copy to keep in sync); clicks through to the MP4 on github.com.Test plan
cargo fmt --all -- --check— PASScargo build --workspace --exclude {desktop,journal,python,nodejs,benchmarks} --all-targets— PASScargo test --workspace --exclude … --exclude sqlrite-journal— PASScargo build -p sqlrite-journal --all-targets(default features) — PASS, no warningscargo build -p sqlrite-journal --no-default-features --all-targets— PASS, no warningscargo test -p sqlrite-journal— 14 / 14 tests pass (9 journal + 5 settings)cargo clippy -p sqlrite-journal --all-targets— clean (no warnings on new code)npm install && npm run build(Vite) inexamples/desktop-journal/— PASSnpm run check(svelte-check + tsc) — 0 errors, 0 warningsnpm install && npm run buildinweb/(Next.js production) — PASS,/examplespage statically pre-rendered with the new card + JSON-LD.sqlritefile via the journal's schema — passes (mirror of the README demo script)Follow-ups (will file separately)
bm25_score(...)in the SELECT projection list in the engine — would let the journal show real BM25 scores instead of the current positional surrogate.CLAUDE.mdedit to matchAGENTS.md(workspace-members line + four CI exclude-pattern blocks). Auto-mode classifier blocked the edit in-session; needs a manual one-line change.🤖 Generated with Claude Code