mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-02 15:11:32 +00:00
120 lines
6.9 KiB
Markdown
120 lines
6.9 KiB
Markdown
# OpenClaw for Linux
|
||
|
||
The Linux companion is a Tauri v2 desktop shell for OpenClaw Gateways. It discovers nearby Gateways over Bonjour, installs the CLI when needed, delegates local Gateway service management to `openclaw gateway`, opens the selected Gateway's Control UI, and stays available in the system tray.
|
||
|
||
## Linux prerequisites
|
||
|
||
Debian and Ubuntu development packages:
|
||
|
||
```bash
|
||
sudo apt update
|
||
sudo apt install libwebkit2gtk-4.1-dev build-essential curl wget file \
|
||
libxdo-dev libssl-dev libayatana-appindicator3-dev librsvg2-dev
|
||
```
|
||
|
||
Install a current stable Rust toolchain with `rustup`.
|
||
|
||
## Media codecs
|
||
|
||
The companion uses GStreamer plugins for audio and video playback.
|
||
WebM/VP9, Opus, Vorbis, and WAV normally work through `plugins-good`.
|
||
H.264/MP4, AAC, and MP3 require the `libav` and/or `plugins-bad` packages.
|
||
The `.deb` uses the host's plugins and declares all three packages as
|
||
dependencies. The AppImage bundles the GStreamer media framework and the
|
||
plugins available on its Ubuntu build host. For a source build or when
|
||
rebuilding either Linux bundle, install the packages explicitly:
|
||
|
||
```bash
|
||
sudo apt update && sudo apt install gstreamer1.0-libav gstreamer1.0-plugins-good gstreamer1.0-plugins-bad
|
||
```
|
||
|
||
The released AppImage therefore carries the codecs installed by the release
|
||
workflow instead of relying on GStreamer packages from the user's system.
|
||
|
||
## Develop and build
|
||
|
||
The companion frontend is static HTML, CSS, and JavaScript. The shared Canvas A2UI renderer is
|
||
generated from the Canvas plugin, so install repository dependencies once before building:
|
||
|
||
```bash
|
||
pnpm install
|
||
cd apps/linux/src-tauri
|
||
cargo run
|
||
cargo build
|
||
```
|
||
|
||
The app uses `OPENCLAW_DESKTOP_CLI` when set. Otherwise it checks `~/.openclaw/bin/openclaw`, then `openclaw` on `PATH`.
|
||
|
||
Desktop notifications use each platform's system notification service. macOS 13+ uses Apple's User Notifications framework; Windows uses native system toasts and Linux uses the desktop notification service through `notify-rust`. On macOS, test notifications from a signed `.app` bundle: a direct `cargo run` stays unbundled, so the app disables notifications instead of initializing Apple's framework with no bundle identity.
|
||
|
||
On first run, release builds automatically install the stable CLI channel, while development builds ask for a release channel and preselect Development. After the CLI install, the app opens the local dashboard once with onboarding mode enabled. Reconnects and later app launches use the normal dashboard URL.
|
||
|
||
## Updates
|
||
|
||
The companion checks the latest GitHub release shortly after launch and from **Check for Updates** in the tray menu. AppImage installs download and verify the signed update in place, then wait for **Restart to update**. Package-managed installs such as `.deb` stay owned by the system package manager and link to the release download page instead of replacing installed files. The macOS and Windows test builds use a separate opt-in desktop-test update channel; macOS self-updates like the AppImage build, while Windows downloads the update first and runs its installer only after **Restart to update**.
|
||
|
||
## Canvas bridge
|
||
|
||
The running app gives the headless `openclaw node run` host a single Canvas WebView. The bundled `linux-canvas` plugin advertises `canvas.*` only while the app socket exists. The app listens at `$XDG_RUNTIME_DIR/openclaw-canvas.sock` (or `/tmp/openclaw-canvas-$UID.sock`) with mode `0600`; a headless Linux node without the app does not advertise Canvas.
|
||
|
||
The Canvas plugin sources remain the source of truth for the A2UI renderer. Each native build
|
||
generates `index.html` and `a2ui.bundle.js` into its isolated build output before compiling. Run
|
||
`node scripts/sync-native-a2ui.mjs --check` from the repository root to verify fresh bundles are
|
||
byte-identical and every native build owner is wired.
|
||
|
||
## Quick Chat widgets
|
||
|
||
Quick Chat advertises the Gateway `inline-widgets` capability and renders hosted `show_widget` results in isolated child WebViews. The parent Quick Chat WebView is the only one granted Tauri commands; widget WebViews match no capability and therefore have no IPC access. Quick Chat accepts only assistant-message Canvas previews under the capability-scoped `/__openclaw__/canvas/documents/` route, blocks navigation away from the original document, uses nonpersistent WebViews, and keeps stable widget instances while switching among multiple previews. Connections that require a custom Gateway TLS leaf pin remain text-only because the platform WebView cannot bind that pin. Like the other native clients, Quick Chat does not expose the Control UI `sendPrompt` bridge.
|
||
|
||
## Installer resource
|
||
|
||
`tauri.conf.json` bundles the repository's canonical `scripts/install-cli.sh` directly as `install-cli.sh`. The app never keeps a forked copy. Stable, beta, and dev installs select `latest`, `beta`, and a managed Git `main` checkout respectively, always under `~/.openclaw`.
|
||
|
||
## Icons
|
||
|
||
The icon sources of truth live next to the PNGs: `icons/icon.svg` (transparent
|
||
claw mark, used by the tray) and `icons/icon-tile.svg` (claw mark on the dark
|
||
brand tile, used for the app and package icons). Regenerate the committed PNGs
|
||
with librsvg:
|
||
|
||
```bash
|
||
cd apps/linux/src-tauri/icons
|
||
rsvg-convert -w 32 --keep-aspect-ratio icon.svg -o 32x32.png
|
||
magick 32x32.png -background none -gravity center -extent 32x32 PNG32:32x32.png
|
||
rsvg-convert -w 128 -h 128 icon-tile.svg -o 128x128.png
|
||
rsvg-convert -w 256 -h 256 icon-tile.svg -o 128x128@2x.png
|
||
rsvg-convert -w 512 -h 512 icon-tile.svg -o icon.png
|
||
magick icon.png -define icon:auto-resize=256,128,64,48,32,16 icon.ico
|
||
rsvg-convert -w 36 -h 36 tray-template.svg -o tray-template.png
|
||
```
|
||
|
||
macOS gets its own tray asset, `icons/tray-template.svg`. AppKit template images
|
||
are drawn from the alpha channel alone, so a colored or edge-to-edge opaque icon
|
||
arrives in the menu bar as a featureless blob; the template source is a
|
||
silhouette with the eyes knocked back out of it. Its geometry mirrors the native
|
||
macOS app's `CritterIconRenderer` at rest so both clients wear the same face, and
|
||
the 36px render is the 2× backing store for the 18pt slot `tray-icon` scales
|
||
menu bar images into. Non-Apple platforms keep the full-color `32x32.png`.
|
||
|
||
## Packaging
|
||
|
||
Build a `.deb` and AppImage locally (the same command CI runs):
|
||
|
||
```bash
|
||
cd apps/linux/src-tauri
|
||
pnpm dlx @tauri-apps/cli@2.11.4 build --bundles deb,appimage
|
||
```
|
||
|
||
Bundles land in `target/release/bundle/{deb,appimage}/`. The `Linux App` CI
|
||
workflow uploads them as the `openclaw-linux-companion` artifact on pull
|
||
requests touching `apps/linux/**` and on manual dispatch.
|
||
|
||
## Releases
|
||
|
||
The `Linux App Release` workflow (manual dispatch, release operators) builds
|
||
the bundles from an existing stable release tag (prerelease tags are
|
||
rejected: their semver suffix breaks Debian upgrade ordering) and attaches them to that tag's
|
||
GitHub release with a `SHA256SUMS.linux-app.txt` checksum file. It refuses
|
||
tags whose commit is not reachable from `main`: Linux bundles ship for
|
||
main-based releases only.
|