Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions apps/launcher/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
node_modules/
bun.lock

# Rust / Tauri build artifacts
src-tauri/target/
src-tauri/gen/
105 changes: 105 additions & 0 deletions apps/launcher/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
# Deco Studio Launcher

A lightweight, cross-platform desktop launcher for **Deco Studio**. It renders the
**hosted** studio (`https://studio.decocms.com`) inside native OS WebViews — one window
per organization — so you can keep several orgs open at once without the memory footprint
of a full browser per org.

- **Native WebView, not Chromium.** Tauri uses WKWebView (macOS), WebView2 (Windows) and
WebKitGTK (Linux). N windows share one system WebView runtime, so the footprint is a
fraction of N browser windows or an Electron app (which bundles ~150 MB of Chromium).
- **One login, many windows.** All windows share a single persistent WebView data store
(one cookie jar). Log in once and every window — and every org — is authenticated. This
is the intended model: one account, many orgs.
- **No local backend.** It talks only to the hosted Studio over HTTPS. No Postgres, no
NATS, no server process on your machine.
- **Session restore.** The set of open org windows is remembered and reopened on the next
launch, so your orgs stay "always on".

This package is **fully decoupled** from `apps/mesh`: it imports no app code and only knows
a URL. It is intentionally excluded from the root Bun workspace (`"!apps/launcher"` in the
root `package.json`) so a normal `bun install` does not pull in the Tauri CLI or the Rust
toolchain.

## Prerequisites

- **Rust** (stable) + Cargo — https://rustup.rs
- **Bun** (for the bundled `@tauri-apps/cli`)
- Platform WebView deps: macOS none extra; Windows WebView2 runtime; Linux
`webkit2gtk-4.1` + `libayatana-appindicator`.

## Develop

```bash
cd apps/launcher
bun install # installs @tauri-apps/cli locally (not part of the root install)
bun run dev # cargo + tauri dev: opens the launcher window(s)
```

Point at a different instance (self-hosted or local mesh) without recompiling:

```bash
DECO_STUDIO_URL="http://localhost:3000" bun run dev
```

## Build a distributable

```bash
cd apps/launcher
bun run build # produces .app/.dmg (macOS), .msi/.exe (Windows), .deb/.AppImage (Linux)
```

Regenerate icons from the source art (`assets/icon-source.png`):

```bash
bun run icons
```

## How it works

All logic lives in `src-tauri/src/main.rs` (desktop-only, single file):

- `open_studio_window` — builds a `WebviewWindow` at the target URL with a desktop
User-Agent and the shared persistent data store.
- App menu (with `CmdOrCtrl+N` → New Window) and an Edit submenu so copy/paste work in the
WebView.
- A **system-tray** menu: New Window, recently-opened orgs, Quit.
- `tauri-plugin-single-instance` — relaunching focuses the running app.
- `tauri-plugin-window-state` — restores window geometry.
- `tauri-plugin-store` (`launcher.json`) — persists the recent-orgs list and the set of
open window URLs; `save_open_windows` / `restore_or_open` reopen your orgs on next launch.

Remote Studio windows intentionally get **no Tauri IPC** (their origin isn't allow-listed
in `capabilities/default.json`) — the native layer drives everything from Rust.

## Login (known WebView caveat)

Login happens **inside** the WebView against the hosted Studio; the session cookie persists
in the shared data store. The one caveat is OAuth: some identity providers (notably Google)
refuse to render their consent screen in an "embedded" WebView. Mitigations, in order:

1. **Desktop User-Agent** (already set in `DESKTOP_UA`) — often enough. **Validate this
first** with a real login.
2. **Email magic-link / OTP** — supported by the Studio backend and works flawlessly in a
WebView. Recommend this as the desktop-friendly login path.
3. **System-browser OAuth handoff** — only if (1) and (2) are insufficient: open the
provider flow in the system browser, return via a `deco-launcher://` deep link, and
exchange a one-time token for a session cookie. This needs a small backend endpoint and
is deliberately **out of scope** for this first version.

## Verify

1. **Footprint** — open ~5 org windows; compare total RSS against 5 browser windows in
Activity Monitor / Task Manager. This is the whole point.
2. **Shared session** — log in once; new windows are already authenticated; switching a
window to a different org needs no re-login.
3. **Restore** — quit with several org windows open; relaunch reopens them.
4. **Tray + shortcut** — tray lists recent orgs and reopens them; `⌘/Ctrl+N` opens a new
window; relaunching focuses the existing instance.

## Not in this version

- Running mesh / Postgres / NATS locally (hosted-only; `DECO_STUDIO_URL` leaves the door
open).
- Per-window account isolation (not needed for one-account / many-orgs).
- A native org list/palette and auto-update (`tauri-plugin-updater`) — planned follow-ups.
Binary file added apps/launcher/assets/icon-source.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
17 changes: 17 additions & 0 deletions apps/launcher/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"name": "@decocms/launcher",
"version": "0.1.0",
"private": true,
"type": "module",
"description": "Lightweight cross-platform desktop launcher for Deco Studio. Renders the hosted studio in native OS WebViews (one window per org) instead of heavyweight browser tabs.",
"scripts": {
"dev": "tauri dev",
"build": "tauri build",
"tauri": "tauri",
"icons": "tauri icon ./assets/icon-source.png",
"check": "echo 'launcher is a Rust/Tauri app with no TS; run cargo check in src-tauri'"
},
"devDependencies": {
"@tauri-apps/cli": "^2.9.2"
}
}
Loading
Loading