@viloris/vela-sys-desktop
v0.0.1
Published
Desktop Host systems facades (notify, tray, dialog, clipboard, fs, shell) for linux/macOS/windows
Readme
@viloris/vela-sys-desktop
Desktop Host systems facades for the three desktop platforms: Linux, macOS, Windows.
Inject into HostAPI.sys after capability checks (T1). Does not run in the WebView.
| Feature | Linux | macOS | Windows |
|---------|-------|-------|---------|
| notify | notify-send (--print-id + gdbus close/replace) | osascript display notification | PowerShell WinRT toast → balloon fallback |
| tray | Python3 + AppIndicator/Ayatana + GTK3 helper | Swift NSStatusItem helper | PowerShell NotifyIcon helper |
| dialog | zenity / kdialog | osascript choose file | PowerShell WinForms |
| clipboard | wl-copy/wl-paste, xclip, or xsel | pbcopy / pbpaste | PowerShell Get/Set-Clipboard |
| shell | xdg-open | open | cmd /c start |
| fs | Sandboxed Host FS under configured root (all desktops) | same | same |
Usage
import { createCapabilityHost, createHostEventBus } from "@viloris/vela-host-core";
import { createDesktopSystems } from "@viloris/vela-sys-desktop";
import { registerNotifyPlugin } from "@viloris/vela-plugin-notify";
import { registerTrayPlugin } from "@viloris/vela-plugin-tray";
import { registerDialogPlugin } from "@viloris/vela-plugin-dialog";
import { registerClipboardPlugin } from "@viloris/vela-plugin-clipboard";
import { registerFsPlugin } from "@viloris/vela-plugin-fs";
import { registerShellPlugin } from "@viloris/vela-plugin-shell";
import { BuiltinPermissions } from "@viloris/vela-api";
const events = createHostEventBus();
const desktop = createDesktopSystems({
platform: "auto", // or "linux" | "macos" | "windows"
events,
appName: "MyApp",
// trayMode: "memory", // headless CI — no real icon
fs: { root: "/path/to/app-data" }, // optional; omit → sys.fs undefined
});
const host = createCapabilityHost({
api: {
platform: desktop.platform,
sys: desktop.sys, // notify + tray + dialog + clipboard + shell (+ fs when configured)
events,
},
capabilities: {
default: {
permissions: [
BuiltinPermissions.NotifyShow,
BuiltinPermissions.TrayManage,
BuiltinPermissions.DialogOpen,
BuiltinPermissions.DialogSave,
BuiltinPermissions.ClipboardRead,
BuiltinPermissions.ClipboardWrite,
BuiltinPermissions.FsAppRead,
BuiltinPermissions.FsAppWrite,
BuiltinPermissions.ShellOpenExternal,
],
},
},
});
registerNotifyPlugin(host);
registerTrayPlugin(host);
registerDialogPlugin(host);
registerClipboardPlugin(host);
registerFsPlugin(host);
registerShellPlugin(host);
// … later
await desktop.dispose();Notify events: CLI backends (notify-send / osascript / PowerShell toast) implement show/close only. Action/click delivery needs a richer long-lived helper (same class as tray). Subscribe handlers under mock/tests may work; production OS notify does not emit notify.action yet.
Tray helpers
Real tray icons spawn a long-lived helper (JSON-lines over stdio):
| Platform | Command | Script |
|----------|---------|--------|
| Linux | python3 | helpers/tray-linux.py |
| macOS | swift | helpers/tray-macos.swift |
| Windows | powershell.exe | helpers/tray-windows.ps1 |
Linux deps: python3, PyGObject, gir1.2-ayatanaappindicator3-0.1 or gir1.2-appindicator3-0.1, GTK3.
macOS deps: Xcode/CLI tools (swift), AppKit session (GUI login).
Windows deps: PowerShell, WinForms (standard desktop).
Headless CI should use trayMode: "memory".
Notify tools
| Platform | Tool |
|----------|------|
| Linux | notify-send (libnotify-bin) |
| macOS | osascript |
| Windows | powershell.exe |
Architecture note
This is T1 Host TS + OS tools / helpers — valid interim per ADR 0006.
Long-term first-party kernels may move behind a Zig systems surface (ADR 0008) without changing vela.call method names.
Verify
bun test packages/sys-desktop
bun run --filter @viloris/vela-sys-desktop typecheck