Apply hiddenInset titleBarStyle on darwin so the system titlebar is hidden but native traffic lights remain. Reusable web sidebars inject a new DesktopShellKey to reserve a 36px TopBar that holds the traffic-light inset (drag region + right border) without colliding with the bot list, and the sidebar stays pinned open in the Electron shell so window resize doesn't fight the layout. Overlay a centered "Title - BotName" header above the chat content with a bottom shadow gradient that obscures scrolling messages, and reserve top padding so the first message stays visible when content fits the viewport. Route the sidebar + action by path (/settings/bots) so the chat router's /settings/* interception forwards it to the settings window cleanly while remaining a normal navigation in web.
@memohai/desktop
Memoh desktop application built with electron-vite.
The renderer owns its own src/renderer/src/main.ts — it imports the reusable
building blocks from @memohai/web (App.vue, router, i18n, api-client,
style.css) but assembles the Vue app locally. Desktop-only customization (extra
Pinia plugins, Electron-specific stores / providers, alternate routers, etc.)
belongs in this main.ts, not in @memohai/web.
How the reuse is wired
@memohai/web/package.jsonexposesApp.vue,router,i18n,api-client, andstyle.cssthrough itsexportsfield.- Vite (via
electron.vite.config.ts) resolves those subpaths to the real files inapps/web/src/at bundle time. vue-tscis pointed at local type stubs insrc/renderer/types/web-stubs.d.tsvia tsconfigpaths, so desktop's typecheck does not descend intoapps/web/src/orpackages/ui/src/(those have their own CI).
Development
# from repo root
pnpm --filter @memohai/desktop dev
# or via mise
mise run desktop:dev
MEMOH_WEB_PROXY_TARGET overrides the backend that the renderer's /api proxy points
at (defaults to whatever config.toml / conf/app.docker.toml declares).
Build
pnpm --filter @memohai/desktop build # full platform installer
pnpm --filter @memohai/desktop build:dir # unpacked app dir (CI smoke test)
Output goes to apps/desktop/dist/.
Icons
All app icons are generated from apps/web/public/logo.svg (the brand mark) by
scripts/build-icons.mjs. Re-run after the logo changes:
pnpm --filter @memohai/desktop icons
Outputs:
| File | Purpose |
|---|---|
build/icon.icns |
macOS bundle icon (16…1024 + @2x) — packaged into .app/Contents/Resources/ |
build/icon.ico |
Windows installer / .exe icon (16/24/32/48/64/128/256) |
build/icon.png |
Linux .deb/.rpm/.AppImage icon (1024×1024) |
resources/icon.png |
Runtime BrowserWindow.icon + macOS dev app.dock.setIcon (512×512); bundled via asarUnpack |
build/icon.icns requires macOS (iconutil); the script skips it on other
platforms.