WolOS
Reference contents

Reference · Desktop and system

wopkg: one tool for every source

pacman repositories, Flatpak, AppImages, recipes and community packages behind one command.

On this page

What it is

wopkg installs, updates and removes apps from every place apps come from: the WolOS and base-distribution repositories, Flatpak remotes, AppImages, WolOS recipes and the community package collection. The Store uses the same library.

Why

Each source has its own tool, search and update command, and AppImages have no updater at all. One command with one search means one app shows once, with every source it is available from, and wopkg update updates all of them.

How

  1. Search: wopkg search <name>. You see one entry per app, with every source it is available from.
  2. Install: wopkg install <name>. System packages go through the sealed system's live layer and ask for confirmation; Flatpaks, AppImages and recipes install for your account only.
  3. Update: wopkg update updates everything, wopkg update <name> one app. wopkg pin <name> keeps a package through updates.
  4. Community packages are always marked unreviewed and checked first: wopkg audit <package> shows the state (see Community package laws).

If something goes wrong

What you seeWhat to do
Exit code 3, 5 or 63: an installer failed. 5: refused for trust (an unsigned remote). 6: not found or not available from that source.
A community package is BlockedA named law was broken. Blocked packages never install; read the finding with wopkg audit <package>.
A package should stay as it iswopkg pin <name> keeps it through updates; wopkg unpin <name> releases it.
One app needs updatingwopkg update <name> updates just that app.
Search finds nothing for an appSearch reads the base distribution's app metadata and, when Flatpak has none, the public Flatpak list.
A download was refusedDownloads have size limits; the last good copy stays.

The Store · Community package laws · Packages · Updates

Reference

One tool for every source. wopkg (Crystal CLI, wopkg/) drives libwopkg (crates/wopkg, libwopkg.so.1, header include/wopkg.h, symbols in abi/wopkg.map). The App Store links the Rust crate directly.

The CLI's lib LibWopkg (wopkg/src/wopkg/lib_wopkg.cr) is generated from wopkg.h by the same generator as libwol's (crates/wol-abi/tests/common/bindgen.rs); cargo test -p wol-abi --test bindings fails when it drifts. Crystal apps reach the same calls through require "cryswol/pkg" (Wol::Pkg, cryswol.md).

Sources and ids

kindWhereidInstalls asUpdate
pacman[wolos], [wolos-cachy], Arch repospackage namesystem change through woldwopkg update (pacman, sealed live layer)
wol.wol recordsapp idsystem change (pacman package)with the system
flatpakFlathub and other signed remotesapp idflatpak --userflatpak update
appimagegh:owner/repo releases, filesURL~/Applicationszsync delta, else full download; key pinned at first install
recipewopkg/recipes/*/recipe.tomlrecipe name~/.localrebuild when the version changes
aurcommunity package collection metadata dumppackage namesandboxed build, then package.install-filerebuild; always unreviewed

Flathub is added for the account the first time an app is installed from it. On an installed slot the package database is the one /etc/pacman.conf names (/usr/lib/pacman).

catalog is Arch's AppStream (archlinux-appstream-data). It installs nothing: it ties a package name to an AppStream id, so search can find a package by its app's name and one app shows once. Sources join only when their ids agree. In the October 2026 data, 604 of Arch's 1401 apps share an id with Flathub; the rest stay separate entries, and a package without metadata never joins by name. wopkg pin <name> keeps a package out of wopkg update (package.update-holding passes --ignore); wopkg update <name> updates one app.

wopkg audit <pkg> checks a community-collection package out and reads it with wopkg-aurlaws without building it (see aurlaws). The same analyser runs after the sandboxed build, on the files, the built package and the trace.

Search ranks exact name, prefix, word, summary; ties by the source order above. One result per app (key), each listing every source.

JSON documents

Config (wopkg_context_create, all optional): home, cache_dir, state_dir, data_dir, apps_dir, pacman_local, flatpak_dirs, wol_records, keys_dir, wold_socket, release_file, allow_loopback_http, jobs. Unknown keys are refused.

Search result (wopkg_search):

{"query":"firefox","took_us":210,"results":[
 {"key":"firefox","name":"firefox","summary":"...","score":1000,
  "sources":[{"kind":"pacman","repo":"extra","name":"firefox","id":"firefox","version":"150.0-1","summary":"...","installed":false}]}]}

wopkg_info returns the same hit for one name. wopkg_installed returns {"pacman":[names],"flatpak":[ids],"wol":[ids],"recipe":[names],"appimage":[{"name","path"}]}.

Index update request: {"sources":[{"name","kind","url"|"path","format"?}]} (the CLI builds it from /etc/pacman.conf, Flatpak's appstream copy and the local feeds), result {"sources":[{"name","records","rebuilt","error"?}]}. A source is rebuilt only when its input's size, mtime or ETag changed.

Downloads are bounded: an index input at most 512 MiB (fetch::MAX_INPUT), the release feed <channel>.json 4 MiB, the plugin index index.json 4 MiB, a .sig 64 bytes. A longer body is refused and its part file deleted, so the last good copy stays.

The release feed lives at wopkg::FEEDS, the assets of the latest wolos-packages release: https://github.com/wonderlandos/wolos-packages/releases/latest/download/<channel>.json and <channel>.json.sig (GitHub redirects to the asset; the download follows it). Every publication uploads the feeds of all channels again, so latest always carries each one. In v0.12 the feeds are published with expires 0: the serial floor alone stops a replayed older feed.

Signed lists (release feed and plugin index) carry serial (increasing with each publication) and expires (Unix seconds, 0 = none) next to format, both covered by the signature. A copy is checked (signature, format, channel, serial not below the highest seen, not expired) before it replaces the cached copy and its ETag; the highest feed serial per channel lives in the state dir. When a new copy fails, the cached copy is used while it still checks. The Store downloads the plugin index again once half of its remaining lifetime or a day has passed, and an expired cached list is not shown.

Progress events (callback, valid during the call, JSON with an event): bytes (url, done, total), done (url, outcome), source (report, from an index update), appimage (name, result). New events and fields may appear; ignore what you do not know.

History entry (wopkg_history_record, one JSON line each in history.jsonl): {"source","action","name","from","to","undo"}; undo is a document tagged by type (restore with from/to, remove with path, run with argv, system with note). wopkg_rollback(id) runs the undo.

System changes (wold)

wopkg_system_call sends one line call <json> to the wold socket and reads one answer line. Calls: package.change (verb install|remove|update, names), package.install-file (path), system.update (manifest, signature hex), system.channel (channel), system.rollback. wold takes the caller's executable from the kernel and checks the consent grant: packages-install, packages-remove, packages-update, and packages-unreviewed for files built locally. Denials say where to allow it (Settings > Privacy & Security > Software). Nothing else is trusted from the request. Every call except system.update (a signed, newer release) is an administrator sheet the shell runs through wol-admind after the password; install-file installs wold's own staged copy (ADR 0034).

Recipes

recipe.toml: name, version, summary, license, homepage, needs (tools the sandbox must have), [[source]] (url, sha256, file), optional [fetch] (lockfile step, with network), [build] and [install] (run = shell lines, offline sandbox; $TARGET_PREFIX is the final prefix, /work/out the staging one). Built output is cached by the recipe's hash.

Exit codes (CLI)

0 done, 1 usage or bad input, 3 an installer failed, 5 refused for trust (unsigned remote), 6 not found or not available from that source.

From the developer documentation, wonderlandos/wolos docs/modules/wopkg.md.