@viloris/vela-plugin-tray
v0.0.1
Published
Host TS capability plugin: system tray icons and menus
Readme
@viloris/vela-plugin-tray
First-party T1 capability plugin: system tray / status item (not a composition Layer).
| Surface | Value |
|---------|--------|
| Permission | tray:manage (BuiltinPermissions.TrayManage) |
| Methods | tray.create, tray.update, tray.remove |
| Events | tray.action (TrayEventChannels.action) |
| Systems | HostAPI.sys.tray (injected; mock for tests) |
| Platforms | desktop (macos / windows / linux) |
Host registration
import { createCapabilityHost, createHostEventBus } from "@viloris/vela-host-core";
import { BuiltinPermissions } from "@viloris/vela-api";
import { registerTrayPlugin, createMockTraySys } from "@viloris/vela-plugin-tray";
const events = createHostEventBus();
const mock = createMockTraySys({ events });
const host = createCapabilityHost({
api: {
platform: "linux",
sys: { tray: mock.facade },
events,
},
capabilities: {
default: { permissions: [BuiltinPermissions.TrayManage] },
},
});
registerTrayPlugin(host);App (page)
const { id } = await window.vela.call("tray.create", {
tooltip: "My App",
menu: [
{ type: "item", id: "open", label: "Open" },
{ type: "separator" },
{ type: "item", id: "quit", label: "Quit" },
],
});
window.vela.events.subscribe("tray.action", (payload) => {
// { id, action: "click" | "menu" | …, itemId? }
});Tray is OS chrome, not layers.insert. Real icons/menus come from @viloris/vela-sys-desktop:
import { createDesktopSystems } from "@viloris/vela-sys-desktop";
const desktop = createDesktopSystems({
platform: "auto",
events,
// trayMode: "memory", // headless CI
});
// desktop.sys.tray → HostAPI.sys.tray| Platform | Helper |
|----------|--------|
| Linux | python3 + AppIndicator/Ayatana |
| macOS | swift + NSStatusItem |
| Windows | PowerShell NotifyIcon |
Verify
bun test plugins/tray
bun run --filter @viloris/vela-plugin-tray typecheck