Skip to content

feat(tauri): desktop shell (Tauri 2.0) — validated on Windows (dev + .msi/.exe) - #77

Merged
danielgorgonha merged 7 commits into
mainfrom
feat/tauri-shell
Aug 3, 2026
Merged

feat(tauri): desktop shell (Tauri 2.0) — validated on Windows (dev + .msi/.exe)#77
danielgorgonha merged 7 commits into
mainfrom
feat/tauri-shell

Conversation

@danielgorgonha

Copy link
Copy Markdown
Member

Brings the Tauri 2.0 desktop shell into main — now validated on native Windows (it was unvalidated groundwork on this branch; ADR-0004 correctly predicted it does not render under WSL/WebKitGTK but works with WebView2 on Windows).

Validated on Windows (WebView2)

  • tauri dev → the native window opens and renders the current app (the /vaults screen, live).
  • tauri build → produces both installers:
    • Konclave_0.1.0_x64_en-US.msi (WiX)
    • Konclave_0.1.0_x64-setup.exe (NSIS)

What's here

  • src-tauri/ — the thin Tauri shell that loads the built Vite/React UI (../ui/dist) in the OS webview. The whole browser-proven app carries over unchanged. The one native capability added: a per-device share in the OS keychain (share_store.rs, ShareStore trait + KeychainShareStore, mock-tested).
  • Fixes on top of the original scaffold (found by actually building it):
    • beforeDevCommand/beforeBuildCommand run from the project root, so ui (not ../ui) — the scaffold pointed one level too high and a fresh clone could not find ui/package.json.
    • The app icons are versioned (src-tauri/icons/, generated from ui/public/icon-512.png) — tauri-build needs icon.ico for the Windows resource; the scaffold gitignored them.
  • Docs: docs/TAURI-PLAN.md + docs/NATIVE-STORAGE-BRIDGE.md.

CI safety

ci.yml builds only the 5 backend crates (orchestrator/signer/wasm/relay/helper); it does not build src-tauri (which needs a per-platform GUI toolchain), so this merge does not touch the existing CI.

Next (follow-ups, not in this PR)

Lay down groundwork for a native Konclave shell without overclaiming. Nothing
here is compiled or run: the dev machine's WSLg/GTK webview does not render
(ADR-0004), and no macOS/iOS/Android build host was available.

docs/TAURI-PLAN.md: what the browser path already validates (UI, konclave-wasm
crypto, relay/helper protocol, custody invariant) vs. what Tauri adds (OS-keychain
share persistence, native packaging, offline shell, optional bundled orchestrator).
Includes the share-persistence abstraction design (a ShareStore over the existing
IndexedDB storage.ts plus a Tauri keychain backend, encryption stays in the UI),
a per-platform build matrix (Windows/macOS/Linux desktop + iOS/Android, each with
toolchain and an honest "what blocks validation here" note), and security notes.
All Mermaid diagrams are GitHub-renderable.

src-tauri/: minimal, schema-valid Tauri 2.0 scaffold. Cargo.toml (lib crate-type
for mobile), tauri.conf.json (frontendDist -> ../ui/dist), lib.rs (app builder +
three keychain commands that move only already-encrypted share bytes, with one
offline base64 round-trip test), main.rs, capabilities, .gitignore. Every source
file is headed as an unvalidated scaffold.

Does not touch ui/orchestrator/konclave-wasm/helper-server source or CI. The
share-store.ts swap is documented but not added, so the ui build stays green
until the Tauri deps are installed.
…choice

Advance the native shell's core value: durable, OS-backed custody for the
per-device FROST share, so a browser eviction (iOS Safari clears IndexedDB after
~7 days idle) no longer loses a vault.

share_store.rs (no tauri dep, logic-tested headlessly, 12 green tests against
keyring's in-memory mock, clippy/-D-warnings + rustfmt clean):
  - ShareStore trait + OS-keychain KeychainShareStore, mirroring the orchestrator's
    KeyStore/KeychainStore pattern and its keyring="3" pin (no backend feature).
  - StoreError with explicit Backend / NotFound / InvalidId variants (no silent loss).
  - list() served from a public-id index entry (keyring has no portable enumeration);
    the index holds only public vault ids, so it does not weaken the threat model.
  - id guard rejects empty / reserved-index ids before touching the backend.
  - The bytes stored are ALREADY ciphertext sealed by the UI (PBKDF2->AES-GCM);
    this layer is durable at-rest storage, not the encryptor. Plaintext never crosses.

lib.rs: four thin #[tauri::command]s (secure_store / secure_load / secure_delete /
secure_list) over the store, base64 at the JS boundary. Scaffold wiring only: the
tauri crate needs a system webview (webkit2gtk/glib) absent on this machine (ADR-0004),
so the enclosing crate is not compiled here.

docs/NATIVE-STORAGE-BRIDGE.md: the JS<->native abstraction. A StorageBackend interface
with the existing IndexedDB module (web) and an invoke-based native backend, selected at
runtime via isTauri(); exact invoke arg shapes matching the Rust commands; the sealing
path stays in the UI; the one-line NetVault.tsx swap. Deliberately not wired into ui/ so
npm build / CI stay green until the Tauri deps are installed.

docs/TAURI-PLAN.md: rewrote the share-persistence section to what is now implemented;
added a Tauri 2.0 vs React Native vs Flutter comparison (recommendation: Tauri, the only
option reusing both the React UI and the Rust crypto with ~zero rewrite; honest tradeoff
is its younger mobile story); refreshed the status ladder (logic-tested vs unbuilt-here
vs design-only vs needs-hardware).

Honesty: the keychain LOGIC is proven by a real test run; the GUI does not build on this
machine and mobile needs a Mac/Android host. Nothing here claims a working native build.
… '../ui'

Tauri runs beforeDevCommand/beforeBuildCommand from the app root (konclave, the parent of
src-tauri), so '../ui' resolved one level too high (to the user's home) and npm could not find
ui/package.json on a fresh clone. Point them at 'ui' (relative to the project root); frontendDist
stays '../ui/dist' (relative to tauri.conf.json in src-tauri). Also merges main so the desktop
shell wraps the CURRENT app (the whole signing convergence), not the Jul-27 snapshot.
The scaffold gitignored /icons as host-generated, but tauri-build requires icon.ico to exist to
build on Windows, and a fresh clone had none. Standard Tauri templates commit the icon set;
version the 5 small derived icons (from ui/public/icon-512.png) so any clone builds with no extra
step. Mobile /gen stays ignored (truly host-generated).
@vercel

vercel Bot commented Aug 3, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
konclave-demo Ready Ready Preview Aug 3, 2026 12:15am

Request Review

A desktop app already has its user (they installed it), so opening on the marketing Intro is
wrong. Detect the Tauri shell (isDesktop) and redirect '/' -> '/vaults'; the web keeps the landing
at '/'. The vault list is the right home: enter a vault or create one.
@danielgorgonha
danielgorgonha merged commit 6bad0f9 into main Aug 3, 2026
7 checks passed
@danielgorgonha
danielgorgonha deleted the feat/tauri-shell branch August 3, 2026 00:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant