You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Add a minimal macOS desktop shell for memo that looks nearly identical to the existing Zed-like web UI. Ship a thin Tauri 2 app that loads the live web app over HTTPS in production (https://memo.chasehuh.com) and http://localhost:3000 during tauri dev. Do not redesign the UI, do not introduce a local SQLite / anarlog-style local-first stack, and do not bundle a second Next/static frontend for v1.
Why This Matters
memo already has a dense, editor-like chrome in the Next app. Users want a native window on macOS without maintaining a second product surface. A thin webview shell reuses Postgres + existing APIs + the current UI as the single source of truth, while giving a real macOS app feel (traffic lights / titlebar overlay). This unblocks “open memo as an app” without forking the product into a local-first desktop rewrite.
Conversation Context
Product lock from research / user direction:
Goal: fully minimal desktop app that looks almost the same as the current web UI (Zed-like memo chrome already in the Next app).
Not a separate native redesign.
Not an anarlog-style local-first SQLite product for v1.
Architecture SoT:
Thin Tauri 2 shell loading the web app over HTTPS in production.
Hybrid URL: tauri dev → http://localhost:3000; production build → https://memo.chasehuh.com.
Do not bundle static Next export / second frontend for v1.
Web (Postgres + APIs + Clerk-when-ready) remains source of truth.
Keep in-page shortcuts (⌘B / ⌘N); overlay macOS traffic lights / transparent titlebar if needed so chrome still matches.
anarlog is only a layout/packaging reference (e.g. apps/desktop + src-tauri) — ignore local DB, plugin sprawl, custom auth storage for v1.
Auto-update / App Store / iOS: non-goals for this issue.
Auth dependency: production identity is moving to Clerk GitHub OAuth via issue #17 / PR #18. The desktop shell can load today’s password login today, but the intended production path is Clerk. Document WKWebView / OAuth popup risks; do not block the shell PR on Clerk landing.
Duplicate check (2026-07-14): no open/closed issues for tauri, desktop, or macOS desktop shell (existing #10 is ⌘⌫ editor behavior only).
Current Behavior
Repo is a single Next.js App Router app (not yet an apps/* monorepo), live at memo.chasehuh.com.
pnpm --filter @memo/desktop tauri dev (or documented equivalent) opens a macOS window that loads http://localhost:3000 when the Next app is running.
Production tauri build produces a macOS .app / DMG that loads https://memo.chasehuh.com (remote URL as frontendDist / app URL — no bundled Next export).
Window chrome is macOS-native with Overlay / transparent titlebar and visible traffic lights; web UI remains the primary chrome so the app still looks like memo.
Existing web shortcuts (⌘B, ⌘N) continue to work inside the webview (do not reimplement as exclusive native menu handlers that steal them).
README documents prerequisites (Rust, Xcode CLT), run/build commands, and the Clerk dependency note.
Scope stays macOS-only for v1 (no Windows/Linux targets required).
app/globals.css — Zed chrome (.zed-titlebar, .zed-shell, panels). If Overlay titlebar overlaps content, adjust padding / optional data-tauri / CSS env only as needed — do not redesign.
app/layout.tsx, app/page.tsx, app/login/ — surfaces the shell will load remotely.
app/api/**, lib/db.ts, lib/auth.ts, lib/notes.ts — remain server SoT; desktop must not duplicate.
README.md — add Desktop section.
package.json / pnpm-workspace.yaml — extend so apps/desktop is a workspace package (today workspace file only lists ignoredBuiltDependencies; promote to real packages if needed).
Issue #17 / PR #18 — Clerk GitHub auth dependency for production identity.
Exact Tauri 2 schema field names must match current @tauri-apps/cli / docs at implement time.
Validation Rules
Desktop must not ship DATABASE_URL, MEMO_PASSWORD, or Clerk secrets inside the binary.
Desktop must not open IPC to arbitrary remote origins beyond what’s required to load the trusted memo origin (keep capabilities minimal; prefer zero custom commands for v1).
Backward compatibility: web app unchanged for browser users.
Implementation Notes
Likely files to modify
pnpm-workspace.yaml — include apps/* (or apps/desktop).
Minimal stub frontend only if Tauri tooling requires a local index.html for scaffolding; production must still load the remote URL. Prefer config-only remote URL with empty/minimal local assets.
Optional tiny CSS/JS bridge only if needed for titlebar safe-area (e.g. detect Tauri user-agent and pad .zed-titlebar for traffic lights). Prefer CSS-only; avoid product redesign.
Flow
Scaffold Tauri 2 app under apps/desktop (macOS focus).
Configure hybrid devUrl / remote frontendDist.
Configure window: decorations on, titleBarStyle: Overlay (or Transparent + documented traffic lights), reasonable default size (~1200×800), product name memo.
Keep capabilities empty/minimal — no filesystem/db plugins.
Wire workspace + README.
Verify tauri build produces a macOS app that opens the remote site; verify tauri dev against local Next.
Tests
No unit-test harness required for the shell itself in v1.
Manual verification checklist in QA below.
Do not add CI notarization / Apple signing in this issue unless already trivial; document residual risk.
Titlebar / chrome guidance
Prefer Overlay titlebar so traffic lights sit over / beside existing .zed-titlebar.
If overlap is ugly, add a small left padding to .zed-titlebar when running inside Tauri (detect via window.__TAURI_INTERNALS__ or user-agent / data-desktop="tauri" injected once). Do not invent a second custom HTML titlebar system.
M — one PR: scaffold apps/desktop, workspace wiring, README, minimal titlebar CSS tweak if required. Do not combine with Clerk (#18) unless already merged and trivial to adapt.
Implementer should use a fresh worktree from origin/main, commit, push, and open PR with Closes #<issue>. Do not merge. Do not force-push. Do not commit .env*.
Summary
Add a minimal macOS desktop shell for memo that looks nearly identical to the existing Zed-like web UI. Ship a thin Tauri 2 app that loads the live web app over HTTPS in production (
https://memo.chasehuh.com) andhttp://localhost:3000duringtauri dev. Do not redesign the UI, do not introduce a local SQLite / anarlog-style local-first stack, and do not bundle a second Next/static frontend for v1.Why This Matters
memo already has a dense, editor-like chrome in the Next app. Users want a native window on macOS without maintaining a second product surface. A thin webview shell reuses Postgres + existing APIs + the current UI as the single source of truth, while giving a real macOS app feel (traffic lights / titlebar overlay). This unblocks “open memo as an app” without forking the product into a local-first desktop rewrite.
Conversation Context
Product lock from research / user direction:
tauri dev→http://localhost:3000; production build →https://memo.chasehuh.com.⌘B/⌘N); overlay macOS traffic lights / transparent titlebar if needed so chrome still matches.apps/desktop+src-tauri) — ignore local DB, plugin sprawl, custom auth storage for v1.Auth dependency: production identity is moving to Clerk GitHub OAuth via issue #17 / PR #18. The desktop shell can load today’s password login today, but the intended production path is Clerk. Document WKWebView / OAuth popup risks; do not block the shell PR on Clerk landing.
Duplicate check (2026-07-14): no open/closed issues for
tauri,desktop, ormacOSdesktop shell (existing #10 is ⌘⌫ editor behavior only).Current Behavior
apps/*monorepo), live at memo.chasehuh.com.components/memo-app.tsx+app/globals.css(.zed-shell,.zed-titlebar,.zed-panel, etc.).⌘N/Ctrl+N→ new note⌘B/⌘\→ toggle notes sidebarMEMO_PASSWORD/ session cookie) viaapp/login+app/api/auth/*.lib/db.ts+app/api/notes/*; optional media upload worker.Desired Behavior
After this issue:
apps/desktop(+apps/desktop/src-tauri) exists insidechasehuh/memo.pnpm --filter @memo/desktop tauri dev(or documented equivalent) opens a macOS window that loadshttp://localhost:3000when the Next app is running.tauri buildproduces a macOS.app/ DMG that loadshttps://memo.chasehuh.com(remote URL asfrontendDist/ app URL — no bundled Next export).⌘B,⌘N) continue to work inside the webview (do not reimplement as exclusive native menu handlers that steal them).Source Of Truth
Internal repo/source
components/memo-app.tsx— primary UI + keyboard shortcuts (⌘N,⌘B,⌘\).app/globals.css— Zed chrome (.zed-titlebar,.zed-shell, panels). If Overlay titlebar overlaps content, adjust padding / optionaldata-tauri/ CSS env only as needed — do not redesign.app/layout.tsx,app/page.tsx,app/login/— surfaces the shell will load remotely.app/api/**,lib/db.ts,lib/auth.ts,lib/notes.ts— remain server SoT; desktop must not duplicate.README.md— add Desktop section.package.json/pnpm-workspace.yaml— extend soapps/desktopis a workspace package (today workspace file only lists ignoredBuiltDependencies; promote to real packages if needed).External docs/source
frontendDistmay be a URL to load remote assets without bundling.titleBarStyle,trafficLightPosition.apps/desktop— ignore local DB plugins, updater, deep links, custom auth store for v1.https://memo.chasehuh.com(currently redirects unauthenticated users to/login).Proposed API / Schema
No new HTTP API. Desktop is a client shell only.
Runtime URL matrix
tauri devhttp://localhost:3000.apphttps://memo.chasehuh.comSuggested package identity
{ "productName": "memo", "identifier": "com.chasehuh.memo", "build": { "devUrl": "http://localhost:3000", "frontendDist": "https://memo.chasehuh.com" } }Exact Tauri 2 schema field names must match current
@tauri-apps/cli/ docs at implement time.Validation Rules
DATABASE_URL,MEMO_PASSWORD, or Clerk secrets inside the binary.Implementation Notes
Likely files to modify
pnpm-workspace.yaml— includeapps/*(orapps/desktop).package.json— optional convenience scripts (desktop:dev,desktop:build).README.md— Desktop run/build section + Clerk / OAuth caveat..gitignore— ignore Tauri/Rust targets (apps/desktop/src-tauri/target, etc.).New files
apps/desktop/package.json—@memo/desktop,@tauri-apps/cliscripts.apps/desktop/src-tauri/Cargo.toml,tauri.conf.json,capabilities/,src/main.rs/lib.rs, icons.index.htmlfor scaffolding; production must still load the remote URL. Prefer config-only remote URL with empty/minimal local assets..zed-titlebarfor traffic lights). Prefer CSS-only; avoid product redesign.Flow
apps/desktop(macOS focus).devUrl/ remotefrontendDist.titleBarStyle: Overlay(or Transparent + documented traffic lights), reasonable default size (~1200×800), product namememo.tauri buildproduces a macOS app that opens the remote site; verifytauri devagainst local Next.Tests
Titlebar / chrome guidance
.zed-titlebar..zed-titlebarwhen running inside Tauri (detect viawindow.__TAURI_INTERNALS__or user-agent /data-desktop="tauri"injected once). Do not invent a second custom HTML titlebar system.⌘B/⌘N.Edge Cases And Risks
openexternal browser for OAuth — follow-up after Clerk GitHub auth + per-user note sync (new memo Clerk app) #17/Clerk GitHub auth + per-user note sync #18. Call this out in README.memo.chasehuh.com. Do not enable broad remote IPC.tauri buildmay produce an unsigned app that Gatekeeper warns on. Non-goal to fully notarize in this issue unless cheap.tauri devrequires Next (pnpm dev) running; document this.Non-Goals
Acceptance Criteria
Closes #<this-issue>).apps/desktop(+src-tauri) lands with Tauri 2 macOS-focused thin shell.http://localhost:3000; prod build loadshttps://memo.chasehuh.com.⌘B/⌘Nstill work in-app.tauri buildsucceeds on macOS (or failure is documented with exact error if environment blocks).QA Plan
pnpm dev(Next on :3000).tauri dev→ window shows login/app at localhost; log in with password; create note; toggle sidebar with⌘B; new note with⌘N.tauri build→ open built.app→ confirmshttps://memo.chasehuh.com(login redirect OK).target// secrets staged.Suggested PR Scope
M — one PR: scaffold
apps/desktop, workspace wiring, README, minimal titlebar CSS tweak if required. Do not combine with Clerk (#18) unless already merged and trivial to adapt.Implementer should use a fresh worktree from
origin/main, commit, push, and open PR withCloses #<issue>. Do not merge. Do not force-push. Do not commit.env*.