GNOME Shell extension

The Meta Package Manager project maintains a GNOME Shell extension.

A top bar indicator lists the outdated packages reported by mpm outdated across every package manager on the system, and lets you upgrade them one by one or per manager. Each outdated package has its version diff colored with the same convention as mpm outdated: unchanged prefix in gray, installed-version suffix in red, latest-version suffix in green.

The extension is a frontend to the mpm CLI, which must be installed separately: see Installation. It looks for mpm on the session PATH, then in well-known locations (~/.local/bin, /usr/local/bin, Linuxbrew), and a custom launcher (like uv run mpm) can be configured in its settings. mpm 6.4.0 or newer is required.

Requirements

  • GNOME Shell 46 to 50.

  • The mpm CLI, 6.4.0 or newer, reachable from the GNOME session.

  • For upgrades run in a terminal: any of xdg-terminal-exec, Ptyxis, Console (kgx) or GNOME Terminal, or a custom terminal command set in the extension settings.

Installation

From extensions.gnome.org

The extension is not yet published on extensions.gnome.org. Once it lands there, it will be installable with one click from the site. Until then, use one of the methods below.

From a release zip

Every GitHub release carries the packed extension as a mpm-gnome-shell-extension.zip asset, next to the mpm binaries. Its provenance is attested, so you can verify it was built by this project’s release pipeline before installing:

$ gh attestation verify mpm-gnome-shell-extension.zip --repo kdeldycke/meta-package-manager --signer-repo kdeldycke/repomatic

Then install and enable it:

$ gnome-extensions install --force mpm-gnome-shell-extension.zip
$ gnome-extensions enable mpm@kdeldycke.github.io

Log out and back in (or restart GNOME Shell) for the extension to load.

Between releases, the bleeding-edge equivalent is produced on each extension change as a workflow artifact of tests-gnome-extension.yaml.

From a source checkout

$ git clone https://github.com/kdeldycke/meta-package-manager.git
$ cd ./meta-package-manager
$ glib-compile-schemas "gnome-shell/mpm@kdeldycke.github.io/schemas/"
$ ln -snf "$(pwd)/gnome-shell/mpm@kdeldycke.github.io" ~/.local/share/gnome-shell/extensions/
$ gnome-extensions enable mpm@kdeldycke.github.io

Configuration

Settings live in the extension preferences window, also reachable from the indicator menu:

Setting

Description

Type

Default

submenu-layout

Group packages into a sub-menu for each manager.

Boolean

false

check-interval

Minutes between two package checks.

Integer

420

boot-wait

Seconds before the first check after login.

Integer

30

timeout

Seconds passed to mpm --timeout for background checks.

Integer

60

mpm-command

Custom mpm launcher, empty to autodetect.

String

Empty

always-visible

Show the indicator even when everything is up to date.

Boolean

true

show-count

Show the outdated package count next to the icon.

Boolean

true

notify

Desktop notification when new outdated packages appear.

Boolean

false

upgrade-in-terminal

Run upgrades in a terminal window.

Boolean

true

terminal-command

Custom terminal emulator, empty to autodetect.

String

Empty

post-upgrade-recheck

Seconds before refreshing the list after an upgrade is started.

Integer

300

These settings only drive the menu layout and check cadence. Everything else comes from mpm’s own configuration file: the extension passes no option beyond the ones it decides itself, so the file found at its default location on the system applies to every run it triggers. See Configuration for the search paths and the full schema.

Development workflow

The extension lives in the gnome-shell/ directory of the mpm repository and shares its version, release cycle and issue tracker.

Its logic is split in two: extension.js owns the widgetry while mpm.js is shell-free (it never imports resource:///org/gnome/shell/* modules), so the latter runs under a bare gjs interpreter:

$ gjs -m tests/gnome/run-tests.js
ok 1 - parseVersion nominal
(...)

Static invariants (metadata, GSettings schema, stylesheet and icon drift) are enforced by tests/test_gnome_extension.py in the regular Python test suite. The tests-gnome-extension.yaml workflow runs the gjs suite, packs the installable zip with gnome-extensions pack, and proves it installs with a gnome-extensions install round-trip.

Its eslint job holds the JavaScript to GNOME Shell’s own coding style, with the eslint-config-gnome rules declared by gnome-shell/eslint.config.mjs and pinned to the commit gnome-shell itself pins. No package.json or lockfile is committed: nobody would keep one refreshed, so the ESLint stack floats and a 7-day npm --min-release-age window gates the whole resolved tree, the same supply-chain guard mpm --cooldown applies to the packages mpm installs.

To exercise the extension in a real session, install it from your checkout (see above), then run a nested GNOME Shell so crashes and reloads stay contained:

$ dbus-run-session -- gnome-shell --nested --wayland

Logs are visible with:

$ journalctl --follow --output=cat /usr/bin/gnome-shell

Release process

The extension version is advertised through the version-name field of metadata.json, kept in lockstep with the mpm version by bump-my-version.

If the extension changed between releases, a fresh zip is uploaded to extensions.gnome.org for review. Reviews there are manual and can take a while.