Skip to content

Install and Manage Desktop Extensions

Desktop extensions add capabilities to the Wayland app itself: new settings panels, pre-configured assistants, custom AI backend adapters, MCP servers, themes, and channel integrations. They are separate from Wayland Core CLI plugins, which extend the command-line engine.

These are two distinct systems.

Desktop Extension HubCore CLI plugins
What they extendThe desktop app (GUI, settings, assistants, adapters)Wayland Core CLI engine (providers, tools)
Install pathExtension Hub modal in Settings > Agentswayland-core plugin install <name>
Package formataion-extension.json manifest in a .zip archiveTOML manifest, installed via plugin subcommand
Settings tabsExtension-contributed tabs appear in the Settings sidebarNo GUI; configured in config.toml

For Core CLI plugins, see Plugins and Marketplace.

  1. Open Settings from the sidebar.
  2. Navigate to Settings > Agents.
  3. Select Install from Market (the hub button near the agent list).

The hub modal loads the extension index. The index is fetched from the FerroxLabs/waylandHub GitHub repository (two mirror URLs are tried in order). Bundled extensions ship inside the app package and are available offline; non-bundled ones require a network connection to download.

Each card in the hub shows:

  • Display name and author
  • Short description
  • Current install status: Not Installed, Installing…, Installed, Update Available, or Failed

The hub merges a local bundled index (shipped in the app bundle) with a remote index fetched at open time. If the remote fetch times out (5-second timeout), the local bundled index is still shown.

  1. Find the extension card.

  2. Select Install.

  3. A native confirmation dialog appears:

    “Extension [name] by [author] runs code with full system access during installation and while active. Only install extensions you trust.”

    You must click Install in this dialog. The install will not proceed without local confirmation; a remote session cannot bypass this gate.

  4. The app downloads the .zip archive, verifies its SHA-512 integrity hash against the index, extracts it, and runs the extension’s onInstall and onActivate lifecycle hooks in a forked child process.

  5. The registry hot-reloads without restarting the app. Any settings tabs, assistants, or adapters the extension contributes become available immediately.

If the install fails, the card shows a Retry button. The error message is displayed on hover.

The installer runs these steps in order:

  1. Resolves the archive: bundled zip from app resources first, then remote download.
  2. Verifies SHA-512 integrity (sha512-<base64>). Remote archives with no declared hash are rejected. Bundled archives covered by code-signing tolerate a missing hash.
  3. Extracts the zip to a temporary directory, then moves it to the install target directory (~/.wayland/extensions/<name>/ on macOS/Linux; the Electron userData path on Windows).
  4. Confirms aion-extension.json is present at the root of the extracted package.
  5. Runs onInstall (first install or upgrade) then onActivate lifecycle hooks. Each hook runs in a forked Node.js process with a timeout (2 minutes for onInstall, 30 seconds for onActivate). A hook that exceeds the timeout is killed with SIGKILL.
  6. Re-detects all agent backends (CLI adapters on PATH may have changed if the onInstall hook installed a new CLI tool).
  7. Verifies contributed capabilities are present (for example, checks that a contributed ACP adapter backend is now detectable).

Where extension-contributed settings tabs appear

Section titled “Where extension-contributed settings tabs appear”

An extension can declare one or more settings tabs in its aion-extension.json manifest under contributes.settingsTabs. Each tab has:

  • id: unique within the extension (the global ID becomes ext-<extensionName>-<tabId>)
  • name: label shown in the sidebar
  • icon: optional icon file relative to the extension directory
  • entryPoint: an HTML file (local, served via wayland-asset://) or an https:// URL
  • position: optional anchor to a built-in tab - { anchor: "models", placement: "after" } - so the tab appears before or after a specific built-in entry
  • order: numeric fallback sort when multiple tabs share the same anchor

Once the extension is installed and active, its tabs appear in the Settings sidebar alongside the built-in tabs. The route for each tab is /settings/ext/<tabId>. The sidebar refreshes automatically when an extension’s state changes.

Built-in tab IDs you can anchor to: assistants, skills, constitution, models, agents, images, voice, webui, channels, mcp-library, theme, editor, general, notifications, storage, about.

Tabs without a position are inserted before the General group by default.

The tab content renders in a sandboxed <iframe> (sandbox="allow-scripts"). External https:// URLs render in a <webview> with an isolated session partition.

Extensions can be disabled without uninstalling them. A disabled extension’s lifecycle hooks (onDeactivate) run, its contributions (settings tabs, assistants, adapters) are removed from the registry, and state is persisted to disk. Enabling re-runs onActivate.

Before the native install dialog, the extension’s declared permissions are readable in the hub UI. Permissions follow the manifest’s permissions block:

PermissionRisk level
storage: trueSafe - read/write to the extension’s own persistent store
network: { allowedDomains: [...] }Moderate - outbound to specific domains
network: trueDangerous - unrestricted network access
shell: trueDangerous - can execute system shell commands
filesystem: "workspace"Moderate - access to your project files
filesystem: "full"Dangerous - full filesystem access
clipboard: trueModerate - read/write clipboard
activeUser: trueModerate - read current user info

An extension with no permissions block defaults to event bus access only (safe). Extensions that request shell: true or network: true or filesystem: "full" are flagged as high-risk in the hub UI.

Extensions in the hub come from the open FerroxLabs/waylandHub repository on GitHub. The hub modal includes a link to open a pull request if you want a new extension listed.