samiandClaude Opus 5.5 c4a677fc3d
ci / build (ubuntu-22.04) (push) Canceled after 0s
ci / build (windows-2025) (push) Canceled after 0s
ci / deny (push) Canceled after 0s
Title bar in bg on Windows: theme colours on the native caption
Tauri 2 overlays web content on the title bar only on macOS, so Windows and
Linux keep the native title bar and window controls. On Windows 11 the
caption, title and border now take the theme's bg and text (DWM), re-applied
on every theme change and when the OS setting changes under "System", so the
caption and the app header read as one custom title bar. Linux (GTK) keeps
its own colours.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-20 21:36:31 +09:00
2026-10-16 10:55:29 +09:00

kestrove-desktop

Windows and Linux app built on Tauri 2. The Rust side links kestrove-core's kv-ffi directly. The web UI only renders and never touches keys. macOS uses the native kestrove-apple app.

Also ships kestrove-nmh, the native-messaging host that bridges kestrove-browser to the app.

# prerequisites: rustup, Node 20+, and Tauri's OS deps (https://tauri.app/start/prerequisites/)
npm install
npm run tauri dev
npm run tauri build                   # MSI/NSIS on Windows, AppImage/deb on Linux
npm run tauri build -- --debug --bundles app   # macOS dev build (Kestrove.app)
npm run tauri icon assets/logo.png    # regenerate src-tauri/icons (placeholder logo)
(cd src-tauri && cargo clippy --all-targets -- -D warnings && cargo test)

The vault lives in the OS app-data dir (vault.sqlite, plus pairings.json, settings.json and secret-key, all owner-only). Closing the window keeps Kestrove in the tray so the browser extension keeps working; Quit is in the tray menu.

Browser integration (docs/05)

extension ─ native messaging (stdio) ─▶ kestrove-nmh ─ local IPC ─▶ app (src-tauri/src/broker.rs)
            └──────────── pairing channel: X25519 → 6 words → AES-256-GCM, end to end ───────────┘
  • IPC (ipc.rs): Unix socket $XDG_RUNTIME_DIR/kestrove/nmh.sock (macOS: the per-user temp dir), dir 0700, socket 0600, peer uid checked on both ends. Windows: \\.\pipe\kestrove-nmh-<user>, first instance only, local clients only, DACL for the current user, client token SID checked (compile-checked only). KESTROVE_IPC_DIR isolates an instance for tests.
  • Pairing (channel.rs, mirrored by kestrove-browser src/channel.ts, shared test vectors): both UIs show 6 words; the user confirms in the app (needs an unlocked vault) and in the extension. Each connection derives a fresh session key from both sides' nonces; messages carry strict counters, so replay and reordering fail. kestrove-nmh only relays ciphertext.
  • Protocol (broker.rs): query → identities for the origin (items_for_url); fill/totp re-check that the item matches the origin and need an unlocked vault; save shows a prompt in the app (new login or password update).
  • Native host manifests: native-messaging/install.sh (Linux, macOS) and install.ps1 (Windows, HKCU registry) fill in the host path and extension ids.
  • Tests: cargo test (unit tests + tests/nmh_stdio.rs, which drives the real kestrove-nmh over stdio through the paired channel). examples/test-host.rs is a headless, auto-approving stand-in for the app used by kestrove-browser's interop and Chrome end-to-end tests.

Auto-lock

10 minutes idle by default (Settings), plus screen lock and sleep (autolock.rs). Idle time is the system's on Windows (GetLastInputInfo) and macOS; on Linux it is activity inside Kestrove (UI input and fills). Screen lock: Windows input-desktop check, Linux logind LockedHint, macOS session dictionary. Sleep: a jump in the wall clock between polls.

Sync and onboarding (docs/03, docs/10)

  • First start offers four ways in: Use my phone (default: type the server URL, scan the QR on screen with a signed-in phone, compare the 6-digit code, then type only the master password), Emergency Kit (PDF, or a PNG/JPEG photo of its QR), Paste setup code, and New account (server URL + the server's KV_SETUP_CODE).
  • Device key (device_key.rs): Windows TPM via CNG, else a DPAPI-sealed software key; Linux Secret Service, else a 0600 file (with a warning in Settings); macOS dev runs use the keychain. KESTROVE_DEVICE_KEY=file forces the file store.
  • Sync (sync.rs) runs after unlock, after a save, every 15 minutes while unlocked, and on "Sync now". Lock drops all keys (core), cancels a scan-to-join and revokes an "Add a device" ticket still on screen. An integrity alarm shows a hard alert and a banner; syncing that vault stops.
  • Settings → Devices: approve pending devices (compare fingerprints), remove devices, Add a phone or tablet (10-minute single-use QR; Done/Cancel revokes it) and Approve a computer (paste the join code a new computer shows under "No phone?").
  • Two instances on one machine: KESTROVE_DATA_DIR=/tmp/kv-b Kestrove.app/Contents/MacOS/kestrove-desktop (the second one has no browser integration). KESTROVE_DEVICE_NAME overrides the device name.
  • Live test: tests/live_sync.rs (ignored) drives three instances against a running server; see its header.

Roadmap (M3, kestrove-spec/docs/07)

  • Unlock with Windows Hello (KeyCredentialManager, TPM) and libsecret on Linux
  • Persistent vault (VaultCore::open in app data)
  • Sync, device approval and scan-to-join onboarding
  • Auto-lock on idle, screen lock and suspend
  • Local IPC between kestrove-nmh and the app, plus the pairing AEAD channel
  • Native-messaging manifest installers (native-messaging/install.sh, install.ps1)
  • Quick Access global hotkey (Ctrl+Shift+Space): search, then copy or auto-type (Windows SendInput, X11 XTest; Wayland gets copy only)
  • MSI/deb installers run the manifest installers
  • Windows 11 passkey plugin provider
S
Description
Windows and Linux app
Readme
1.5 MiB
2026-10-30 14:29:35 +00:00
Languages
Rust 54.2%
TypeScript 28.4%
CSS 9.8%
Shell 4%
NSIS 1.2%
Other 2.4%