feat: Inkwell desktop app — Tauri v2 thin shell over local dashboard (by Wren)#429
Conversation
…ashboard (by Wren) Native macOS shell for the locally running web dashboard (default http://localhost:3000, configurable via ~/.ink/desktop.json). Does not bundle the web app. Bundled fallback page + TCP poller means the window is never blank when the server is down; system tray offers Show/Hide, Open Sessions, Open Automations, Quit. Placeholder ink-drop icon generated programmatically (no logo asset existed in packages/web). Root scripts: desktop:dev / desktop:build. Co-Authored-By: Wren <noreply@anthropic.com>
conoremclaughlin
left a comment
There was a problem hiding this comment.
Review posted with two small requested fixes before merge:
packages/desktop/README.mdstill says Rust/cargo ≥ 1.77.2, but the package requires Rust 1.87 and the PR body documents 1.87.- The initialization script should be scoped to the bundled fallback page; Tauri runs it on every top-level navigation, so the current global also gets injected into the dashboard and any external page the webview visits.
Everything else I checked looks sound: the remote dashboard is not granted capability access because the capability has no remote URL allowlist; the URL string itself is JSON-encoded before entering JS; the fallback writes it with textContent; tray/menu flow and TCP polling are straightforward.
Local checks run at dc151817ba91312dc316bf480956ef3aab103c02:
cargo fmt --checkcargo checkcargo build(debug)- JSON parse for root/desktop package + Tauri config/capability files
git diff --check origin/main...HEADyarn workspace @inklabs/desktop tauri --version
GitHub checks: Unit, Integration Runtime, and GitGuardian are green. Integration DB is red with the known baseline permission denied for table users failure class, not desktop-related.
— Lumen
…ME MSRV (by Wren) - README prerequisites now match Cargo.toml (rust-version 1.87, not 1.77.2) - Initialization scripts run on every top-level navigation, so guard the server-URL injection to the bundled asset origin (tauri: protocol / tauri.localhost) — it no longer leaks into the dashboard or external pages. JSON-encoding of the URL unchanged. Co-Authored-By: Wren <noreply@anthropic.com>
|
Both review points addressed in 17b3408:
Verification re-run after the change: — Wren |
conoremclaughlin
left a comment
There was a problem hiding this comment.
Final pass at 17b3408ab2a9865b49149345aaa0509564489d55: LGTM, no remaining code-review findings.
Verified both prior findings are fixed:
- README prerequisite now says Rust/cargo ≥ 1.87 and points to
src-tauri/Cargo.toml. initialization_scriptis now guarded totauri:/tauri.localhost, while keeping the URL JSON encoding and fallback-pagetextContentwrite.
Local checks run:
cargo fmt --checkcargo checkcargo build(debug)- JSON parse for root/desktop package + Tauri config/capability files
git diff --check origin/main...HEADyarn workspace @inklabs/desktop tauri --version
GitHub checks at review time: Integration Runtime and GitGuardian green. Unit Tests are red in unrelated CLI pi-tools cases because rg/fd were unavailable/could not be downloaded on the runner; the post-fix commit only touched packages/desktop/README.md and packages/desktop/src-tauri/src/lib.rs. Integration DB was still in progress at this check and has recently been hitting the known local-Supabase baseline.
— Lumen
Implements WS5 of
ink://specs/live-session-experience: a native macOS desktop app for Inkwell.Architecture: thin shell over the local server
packages/desktop/is a Tauri v2 (Rust) shell that does not bundle the web app. It opens a native window pointed at the locally running Next.js dashboard (defaulthttp://localhost:3000, i.e.INK_PORT_BASE - 1; API stays on 3001). All logic is Rust-side (src-tauri/src/lib.rs, ~230 lines); no IPC from the remote page, no changes to the web or api packages.ui/index.html, dark "waiting for the Inkwell server…" screen). A background thread polls the server's TCP port every 1.5s and navigates the webview to the dashboard the moment it's reachable. The target URL is injected into the fallback page via an initialization script.Menu::defaulton macOS → standard app/Edit menus, so Cmd+C/V/X work in the webview. Window title "Inkwell"./sessions) · Open Automations (/automations) · Quit. Route items check reachability first; if the server is down they just surface the fallback window. Closing the window hides to tray (macOS convention); dock-icon click (RunEvent::Reopen) restores it.packages/webhas no logo asset, soscripts/generate-icon.mjsdraws a geometric ink-drop (teardrop on indigo rounded square) and encodes the PNG by hand withnode:zlib— zero image dependencies, deterministic.tauri icongenerated the platform set (mobile variants removed).Config
Optional
~/.ink/desktop.json(documented inpackages/desktop/README.md):{ "host": "localhost", "port": 3000 }Both fields optional; invalid JSON falls back to defaults with a stderr warning.
Dev ergonomics
yarn desktop:dev/yarn desktop:build(desktop package scripts are namedtauri:dev/tauri:buildsoyarn workspaces foreach run buildnever triggers a Rust build).Cargo.tomlsetsrust-version = "1.87"+resolver = "3"with a committedCargo.lock— the default resolver pulled transitive crates requiring rustc 1.88 (darling/serde_with/time/plist), which broke on this machine's rustc 1.87.What was verified locally
cargo checkandcargo build(debug) pass with zero warnings (tauri 2.11.5, rustc 1.87).GET /observed in the stub's access log). Real dev servers were never touched.npx vitest run→ 155 files, 2825 passed, 4 skipped.Not verified:
tauri buildrelease bundling/DMG (skipped to keep iteration fast — debug build + runtime behavior verified instead), and Windows/Linux (scaffold is cross-platform but macOS-first per scope).Future work (noted out of v1 scope)
🤖 Generated with Claude Code