Not stable yet. WolOS is in active development and the current ISO is a test build: try it in a virtual machine or on a spare disk, not on a computer you depend on.

WolOS

Plugins

One folder, one manifest, a sandbox.

Plugins add to the menu bar, the Dock, the desktop, Search and the Control Center. They are small enough to write in an afternoon, and an AI agent can write and test one on its own.

What
A plugin is a folder named after its id, with a plugin.toml and the Lua and image files it names. No install scripts, no binaries, at most 1 MiB.
Why
Small extensions should be easy to make and impossible to abuse. Plugin code runs in WolOS's Lua sandbox with memory and instruction limits, and anything that changes the system goes through the same on-screen approval as any helper.
How
Drop the folder into ~/.local/share/wolos/plugins, or run wol plugin add with a path, a git URL or a .wolplug file. Updates come through wopkg, independent of system releases.

The manifest

A header that names the plugin and its permissions, then one section per thing it adds. This one puts CPU and memory in the menu bar, adds a desktop card, and binds a shortcut that opens btop.

Unknown keys are refused with a sentence that names the place, so a typo never fails silently.

~/.local/share/wolos/plugins/alice.stats/plugin.toml
schema = 1id = "alice.stats"name = "Stats"version = "1.0"author = "Alice"license = "MIT"description = "CPU and memory in the menu bar, with a desktop card."min_wolos = "0.12"permissions = ["run"][[menubar]]id = "bar"script = "bar.lua"side = "right"[[widget]]id = "card"script = "card.lua"sizes = ["small", "medium"][[hotkey]]id = "top"default = "super+shift+t"exec = ["foot", "-e", "btop"]group = "Stats"

What a plugin can add

Each section of the manifest is one kind of contribution. The shell draws all of them with its own components, so a plugin always looks like the rest of WolOS.

  • [[menubar]]

    A menu bar item

    A bar item. side is left, centre or right (default). The script returns wol.menubar.

  • [[dock]]

    A Dock tile

    A Dock tile that runs exec (argv, never a shell line).

  • [[widget]]

    A desktop card

    A desktop card (today's lua:<id>). sizes: any of small, medium, large (default all).

  • [[panel]]

    A panel

    A sheet the shell shows on wol.show("<id>") or a hotkey. anchor: top (default), bottom, left, right, centre.

  • [[search]]

    Search results

    Search rows. kind = "results" (default) sees every query; kind = "command" sees queries starting with prefix (1 to 8 characters, no spaces).

  • [[tile]]

    A Control Center tile

    A Control Center tile bound to a [[toggle]] of this plugin.

  • [[toggle]]

    An on/off switch

    Two argv commands; the state is a flag file in $XDG_STATE_HOME/wolos/toggles/<plugin>.<id>.

  • [[hotkey]]

    A shortcut

    A user-rebindable shortcut (shortcuts::Custom). default: modifiers from super, ctrl, alt, shift, then a key (super+shift+t, super+f5, super+space). group is the heading in Settings (default: the plugin name).

  • [[webapp]]

    A web app window

    A frameless browser window for an https:// URL, in Search and the Dock. profile: shared (default) or own (isolated cookies).

  • [[theme]]

    A theme

    A theme.json (shared::theme tokens, optional extends); checked for contrast.

  • [[look]]

    A Looks preset

    A Looks preset JSON (wol_core::looks).

  • [[hypr]]

    Window rules

    keyword = value lines; only windowrule, layerrule, bezier, animation. Never bind, exec, env, source, plugin, $variables or { } blocks. Parsed into hyprprefs keywords, never sourced raw.

Permissions

Declared in the manifest, shown before you turn a plugin on, and revocable in Settings. A plugin without a permission cannot use the call it guards.

notifications
wol.notify
run
wol.run
http
wol.http_get
clipboard
wol.clipboard.text
open
wol.open
toggles
wol.toggle_set

How an agent writes one, in five steps

Every step has a command with JSON output, so an AI agent can make, check and test a plugin without a screen, and a person can follow the same steps by hand.

  1. 1.wol plugin new alice.weather menubar,widget makes a folder that already passes check. Read /usr/share/wolos/plugins.schema.json (the manifest schema) and this page.
  2. 2.Edit plugin.toml (name, description, permissions, entries) and the .lua files. Keep scripts small: one read() that fetches data, one render() that returns parts.
  3. 3.wol plugin check alice.weather --json until "valid": true. Every problem is one sentence naming the file or [[section]] n and what to change.
  4. 4.wol plugin run alice.weather menubar --json prints the view tree; wol plugin run alice.weather widget card 1 --json clicks part 1 first and shows the new tree and the events the handler caused. Use XDG_STATE_HOME=$(mktemp -d) for a clean state and WOL_PLUGIN_HOSTS=api.example.com when the plugin reads the web.
  5. 5.wol plugin enable alice.weather to see it on the desktop; wol plugin pack alice.weather to make the .wolplug to share.

Sharing and updates

wol plugin pack makes a .wolplug: the folder as one archive with its checksum and an optional signature.

The plugin index is a signed list that wopkg reads like any other source, so wopkg update updates plugins without touching the system. Plugins without a review are marked unreviewed, as AUR packages are, and need a typed yes.

The full API, with every key, the Lua calls and the limits, is in the manual: Plugin API reference.