Skip to content

Latest commit

 

History

History
80 lines (62 loc) · 3.58 KB

File metadata and controls

80 lines (62 loc) · 3.58 KB

luna-desktop

Luna's native face on the Linux desktop — a thin client of the Hermes agent that lives in luna-os.

She already runs as an always-on agent inside luna-os. This repo is how you reach her without a browser tab: the luna binary, which is both

  • a CLIluna ask / chat / repl / status / sessions, and
  • a GUIluna gui: a Slint frosted-glass chat window + a StatusNotifierItem tray + freedesktop notifications.

Design rule: the brain owns the API; this repo owns the clients. Every surface talks to Hermes over its local API (see docs/hermes-gateway-api.md). That keeps Hermes (the upstream-tracked Python agent) clean and these clients decoupled.

One app, every desktop

The GUI is deliberately not a per-desktop widget. The desktops NixOS supports share no panel-applet API, so rather than maintain a dozen bespoke applets in a half-dozen toolchains, luna gui is one Rust app that rides the two freedesktop standards every desktop implements:

  • StatusNotifierItem — the crescent-moon tray icon (KDE, LXQt, Cinnamon, Budgie, Pantheon, XFCE, MATE show it natively; GNOME via the AppIndicator extension luna-os enables; Enlightenment falls back to the menu launcher).
  • org.freedesktop.Notifications — a "Luna replied" notification when her answer lands while you're looking elsewhere. Works everywhere.

Built with Slint (pure Rust, no webview) on its software renderer, so it survives headless / flaky-GPU VMs. Each tab is a Hermes session with its own transcript, persisted under ~/.local/state/luna/ so conversations survive logout/reboot. Replies stream, there's a stop button, text is selectable/copyable, and it's single-instance (a second luna gui just raises the running one — which is how the menu entry and the autostart tray coexist).

The luna binary

cd cli
cargo build --release            # → target/release/luna

luna ask "what's on my plate today?"   # one-shot via `hermes -z` (no server)
luna chat "hi"                         # streamed + threaded (needs the dashboard)
luna repl                              # interactive terminal chat
luna gui                               # the graphical chat + tray
luna gui --hidden                      # start in the tray only (used by autostart)
luna status   /   luna sessions        # dashboard API

Connection defaults to http://127.0.0.1:9119; override with --url or $LUNA_GATEWAY_URL. The session token comes from $HERMES_DASHBOARD_SESSION_TOKEN or luna-os's /var/lib/hermes/dashboard.env (see src/config.rs).

Building outside Nix

The GUI links fontconfig and Slint's winit backend dlopens the windowing libraries, so a non-Nix build needs those present, e.g.:

nix-shell -p pkg-config fontconfig libxkbcommon wayland libGL \
             xorg.libX11 xorg.libXcursor xorg.libXi xorg.libXrandr \
  --run "cargo build"

luna-os's modules/luna-desktop.nix packages it reproducibly and wraps the binary's LD_LIBRARY_PATH, so on luna-os none of this is your problem.

Layout

luna-desktop/
├── cli/                # the `luna` binary — CLI + Slint GUI + tray
│   ├── src/            # main · client (API) · config · gui · tray · state
│   ├── ui/luna.slint   # the frosted-glass chat UI
│   └── build.rs        # compiles the .slint
└── docs/               # the gateway API contract + notes