Todo-list¶

Todo

Declare the marker so it takes that slot back, once a click-extra release carries a deprecated field on HelpKeywords:

mpm.extra_keywords = HelpKeywords(…, deprecated={UNMAINTAINED_MARKER})

Naming it on a release without the field raises TypeError at import, so this waits on the floor rather than being guarded.

(The original entry is located in /home/runner/work/meta-package-manager/meta-package-manager/meta_package_manager/cli.py:docstring of meta_package_manager.cli.UNMAINTAINED_MARKER, line 22.)

Todo

Inert on click-extra 9.1 and below, which renders the table from the base class’s column set rather than the running option’s, so this override never reaches it. The one-line fix is proposed upstream; drop this paragraph once a release carrying it becomes the floor.

(The original entry is located in /home/runner/work/meta-package-manager/meta-package-manager/meta_package_manager/cli.py:docstring of meta_package_manager.cli.SourcedParamsOption, line 13.)

Todo

Name the release that drops the deprecated [mpm] cooldown = "<duration>" top-level spelling. It is accepted as a migration aid with no removal scheduled, so the warning above has no deadline for a reader to act on.

(The original entry is located in /home/runner/work/meta-package-manager/meta-package-manager/docs/configuration.md, line 99.)

Todo

  • Detect pipx’s internal pip (or uv) at runtime. mpm’s pip manager has a hard >=26.1.0 floor, but pipx maintains its own virtualenvs whose pip may be older or whose resolution may be routed through uv (where the right env var is UV_EXCLUDE_NEWER instead of PIP_UPLOADED_PRIOR_TO). Probing the resolver per venv would let mpm refuse to advertise enforcement when the underlying pip is stale.

  • Per-package exemptions (--cooldown-exclude). The gate is currently all-or-nothing per run, so one legitimately-fresh package (a security fix, a package the user publishes themselves) forces the cooldown off for the whole tree. Both enforcing managers already expose the escape hatch natively: uv’s --exclude-newer-package takes a PACKAGE=DATE pair, npm’s min-release-age-exclude takes names or minimatch globs. The catch is that this would not fit the uniform cooldown_env_var injection: uv publishes no environment variable for --exclude-newer-package (only the plain --exclude-newer carries a UV_EXCLUDE_NEWER binding), so uv needs the exemption appended to the command line while npm can keep taking it through npm_config_min-release-age-exclude. Supporting it therefore means a per-manager hook alongside the env var rather than a one-line addition, which is worth knowing before the option is designed.

  • Onboard mechanisms as they ship upstream. Several managers have active work that would slot into the cooldown_env_var framework as a one-line addition once released: Composer (composer/composer#12692), conda (conda/conda#15759), dnf5 (rpm-software-management/dnf5#2743), Scoop (ScoopInstaller/Scoop#6513), winget (microsoft/winget-cli#6178), VS Code extension installs (microsoft/vscode#321136).

  • Watch the three gates that shipped outside mpm’s scope. Cargo, Bundler and mamba each ship a release-age gate that the commands mpm drives never reach. Onboard each one if upstream widens it to cargo install, to gem install, or to the mamba and micromamba command lines. The notes under the support table record what each gate covers today.

  • Advisory mode for outdated on managers without a native gate. mpm could query each package registry directly (PyPI, RubyGems, crates.io, …) to annotate outdated with a “safe latest” column: purely informational, no install-side enforcement. This avoids the transitive-resolution trap while still being useful. It requires a new HTTP client surface and a state directory for date caching, neither of which mpm has today.

  • Consult a curated compromise-window denylist. aur-cooldown pairs its age gate with aur-malware-check’s campaigns.json, denying only the versions pushed inside a dated compromise window rather than freezing a package by name. This is orthogonal to release age: a version can be old enough to clear the cooldown yet still sit inside a known-bad window. Wiring such a feed into mpm would lean on the same HTTP client and state directory the advisory mode above already calls for.

  • Block-mode for the remaining bundled-artifact managers (snap, vscode). These install self-contained artifacts with no separate transitive resolution at install time, so the per-package hold shipped for flatpak and mas is sound for them too. The bottleneck is a server-set publish date the manager’s own CLI can reach: the VS Code Marketplace only answers over HTTP, and snap info prints no dates (snapd’s autonomous background refresh would bypass an mpm-side gate anyway).

(The original entry is located in /home/runner/work/meta-package-manager/meta-package-manager/docs/cooldown.md, line 362.)

Todo

Implement a best matching strategy, across package managers of different kinds.

(The original entry is located in /home/runner/work/meta-package-manager/meta-package-manager/docs/dump.md, line 87.)

Todo

Track the origin remote of each installed flatpak package, so a Brewfile dump emits the with: ["remote_name"] keyword instead of leaving non-flathub entries to be edited in by hand.

(The original entry is located in /home/runner/work/meta-package-manager/meta-package-manager/docs/dump.md, line 167.)

Todo

Add an --installed boolean flag to search to reduce the searched packages to those already installed. (installed itself now accepts a QUERY argument to filter its own listing.)

(The original entry is located in /home/runner/work/meta-package-manager/meta-package-manager/docs/duplicates.md, line 90.)

Todo

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.

(The original entry is located in /home/runner/work/meta-package-manager/meta-package-manager/docs/gnome-shell.md, line 19.)

Todo

Declare outdated, upgrade_all and search. All three are expressible as further --eval forms, comparing package-alist against package-archive-contents, but none was captured on the drive that produced the samples below and no operation is declared from a form that was not run.

(The original entry is located in /home/runner/work/meta-package-manager/meta-package-manager/docs/managers/emacs.md, line 64.)

Todo

outdated is not implemented. The operation needs a sample naming both the installed and the available version, and the only illumos host available reported no packages have newer versions available.

That state cannot be manufactured on a consistent image, so do not spend time trying: installing a superseded build to force one is refused with did not match any allowable packages, the release incorporations constraining an image to one allowable version per package. Inventing a fixture is not an option either, a sample having to parse through this manager’s own parser and having to be real.

Capture it on a host whose image has fallen behind its publisher, which is the only state that emits the output.

(The original entry is located in /home/runner/work/meta-package-manager/meta-package-manager/docs/managers/ips.md, line 62.)

Todo

Declaring search would need a class: its records span three lines. It is worth the upgrade, because those records carry a server-set publication date (“Published on Mon Mar 2 17:23:45 2026”), which is what qualifies a manager for the per-package release_date() probe under --cooldown instead of the ❌ row this definition earns. Doing that would also unlock remove, the kind lookup being the same class-only capability.

(The original entry is located in /home/runner/work/meta-package-manager/meta-package-manager/docs/managers/platformio-core.md, line 70.)

Todo

Fold search’s --extended/--id-name-only and --exact/--fuzzy pair into a single --search-strategy=[exact, fuzzy, extended] option, whose help spells out what each strategy does. exact is case-sensitive and keeps every non-alphanumeric character. fuzzy lowercases the query, strips it of non-alphanumeric characters and tokenizes it, so word order stops mattering. extended is fuzzy widened past the package ID and name, reaching the description and whatever other metadata each manager supports.

The strategies sketched out were:

  1. strict: --exact, on ID or name.

  2. substring: regex, case-insensitive, no splitting.

  3. fuzzy: token-based.

  4. extended: fuzzy plus metadata.

(The original entry is located in /home/runner/work/meta-package-manager/meta-package-manager/meta_package_manager/cli_explore.py:docstring of meta_package_manager.cli_explore, line 12.)

Todo

Add a --force/--reinstall flag to install.

(The original entry is located in /home/runner/work/meta-package-manager/meta-package-manager/meta_package_manager/cli_maintenance.py:docstring of meta_package_manager.cli_maintenance, line 11.)

Todo

Resolve pkcon’s backend at dispatch time and merge it into that backend’s lane, in place of the fixed membership above. pkcon backend-details reports the backend in its first line, so the mapping needs no guessing, only a probe whose cost is paid once per run.

(The original entry is located in /home/runner/work/meta-package-manager/meta-package-manager/meta_package_manager/dispatch.py:docstring of meta_package_manager.dispatch.SHARED_LOCK_FAMILIES, line 64.)

Todo

Today every extractor is local-only (shell-outs to the manager’s CLI, plus on-disk reads). When extractors start reaching for network resources (PyPI’s JSON API, npm’s registry, crates.io, GitHub’s security advisories) the --bundled flag will no longer be a fine-grained enough knob: some users will want enrichment but not network traffic (offline scans, CI without egress). The natural split is a future --network/--no-network flag layered under --bundled to gate the network-touching code paths specifically, leaving local enrichment always-on for --bundled.

(The original entry is located in /home/runner/work/meta-package-manager/meta-package-manager/meta_package_manager/manager.py:docstring of meta_package_manager.manager.PackageManager.package_metadata_batch, line 28.)

Todo

Implement project-scope discovery. The candidate ecosystems, the project files that signal each and the architecture this waits on are catalogued in Unsupported managers.

(The original entry is located in /home/runner/work/meta-package-manager/meta-package-manager/meta_package_manager/manager.py:docstring of meta_package_manager.manager.PackageManager.discover_projects, line 13.)

Todo

Use the removed variable to detect removed packages (which are reported with a (!) flag). See #17.

(The original entry is located in /home/runner/work/meta-package-manager/meta-package-manager/meta_package_manager/managers/homebrew.py:docstring of meta_package_manager.managers.homebrew.Homebrew.installed, line 35.)

Todo

Surface pin state, or let mpm outdated filter on it, by reading the pinned and pinned_version fields the note above describes.

(The original entry is located in /home/runner/work/meta-package-manager/meta-package-manager/meta_package_manager/managers/homebrew.py:docstring of meta_package_manager.managers.homebrew.Homebrew.outdated, line 103.)

Todo

outdated is not implemented. The operation needs a sample naming both the installed and the available version, and the only illumos host available reported no packages have newer versions available.

That state cannot be manufactured on a consistent image, so do not spend time trying: installing a superseded build to force one is refused with did not match any allowable packages, the release incorporations constraining an image to one allowable version per package. Inventing a fixture is not an option either, a sample having to parse through this manager’s own parser and having to be real.

Capture it on a host whose image has fallen behind its publisher, which is the only state that emits the output.

(The original entry is located in /home/runner/work/meta-package-manager/meta-package-manager/meta_package_manager/managers/ips.py:docstring of meta_package_manager.managers.ips.IPS, line 24.)

Todo

Evaluate findpython (the maintained MIT rewrite of pythonfinder) to replace the discovery loop here. It would only cover discovery: the eligibility filters (_running_from_bundled_app(), _pip_install_blocked()) stay mpm’s job, since findpython locates interpreters but does not judge whether pip install is allowed into one.

(The original entry is located in /home/runner/work/meta-package-manager/meta-package-manager/meta_package_manager/managers/pip.py:docstring of meta_package_manager.managers.pip.Pip.search_all_cli, line 20.)

Todo

Drop the fallback, which mimics Pip.outdated(), once pipx 1.16.0 is old enough to be required outright.

(The original entry is located in /home/runner/work/meta-package-manager/meta-package-manager/meta_package_manager/managers/pipx.py:docstring of meta_package_manager.managers.pipx.Pipx.outdated, line 57.)

Todo

Add the --no-progress option once it is available in the stable release:

(The original entry is located in /home/runner/work/meta-package-manager/meta-package-manager/meta_package_manager/managers/winget.py:docstring of meta_package_manager.managers.winget.WinGet.post_args, line 19.)

Todo

Automatically uninstall the package if the technology is different:

> winget upgrade --id Microsoft.Edge
A newer version was found, but the install technology is different from the current version installed. Please uninstall the package and install the newer version.

(The original entry is located in /home/runner/work/meta-package-manager/meta-package-manager/meta_package_manager/managers/winget.py:docstring of meta_package_manager.managers.winget.WinGet.upgrade_one_cli, line 17.)

Todo

Contribute generic autodetection method to Click Extra?

(The original entry is located in /home/runner/work/meta-package-manager/meta-package-manager/meta_package_manager/sbom/base.py:docstring of meta_package_manager.sbom.base.SBOM.autodetect_export_format, line 4.)

Todo

Reuse the mapping that is proposed upstream to the package-url Python project.

(The original entry is located in /home/runner/work/meta-package-manager/meta-package-manager/meta_package_manager/specifier.py:docstring of meta_package_manager.specifier.PURL_MAP, line 16.)

Todo

Reassemble the package ID from purl.namespace where the type calls for it, instead of reading purl.name alone. Two claimed types carry a namespace today and both resolve wrongly: pkg:composer/monolog/monolog yields monolog where Composer needs monolog/monolog, and pkg:npm/@angular/animation yields animation, which is a real and unrelated package, so the install succeeds on the wrong thing rather than failing. Claiming golang for Go waits on the same fix, the module path being exactly the part that gets dropped.

The join cannot be blanket, which is what makes this more than a one-liner: a pkg:deb/debian/curl namespace names the distribution rather than half the package name, so joining it would ask apt for debian/curl. The rule has to be per-type, and tests/test_specifier.py covers only namespace-free pURLs today, which is why nothing caught it.

(The original entry is located in /home/runner/work/meta-package-manager/meta-package-manager/meta_package_manager/specifier.py:docstring of meta_package_manager.specifier.Specifier.parse_purl, line 5.)

Todo

Prime Microsoft’s sudo.exe once there is anything to prime. It caches nothing, so every escalation of a run raises a UAC dialog of its own, which is why ESCALATORS ranks it behind gsudo rather than beside it. microsoft/sudo#7 is the request that would give it a cache for prime_sudo() to warm; gsudo has the same gap open at gerardog/gsudo#378 for its own password path. Nothing else blocks the backend: the command line, the --preserve-env environment and the child’s exit code all survive the elevation, measured on build 26100.1742 from a Medium-integrity shell, the one path that really brokers it, so microsoft/sudo#117 never reaches the shapes this project builds.

Emulate an option a backend cannot express rather than failing on it: topgrade returns a hard error there, which its users report as a bug (topgrade-rs/topgrade#1435).

(The original entry is located in /home/runner/work/meta-package-manager/meta-package-manager/meta_package_manager/sudo.py:docstring of meta_package_manager.sudo, line 40.)

Todo

Escalate to the user owning a manager’s tree, not only to root: every escalate_args reaches root alone, where sudo --user and doas -u could reach the owner. The one legitimate case is a multi-user nix install, whose foreign-owned profiles are a first-class upstream configuration. A shared Homebrew prefix is not: Homebrew’s support tiers file “Multi-user Homebrew environments where multiple users share the same installation” as unsupported, so smoothing that setup over (as topgrade does for its brew step) would carry a burden upstream itself refuses. Stays unbuilt until a nix user asks.

(The original entry is located in /home/runner/work/meta-package-manager/meta-package-manager/meta_package_manager/sudo.py:docstring of meta_package_manager.sudo, line 61.)

Todo

Rebrand the hidden password prompt of an internal escalator with a SUDO_ASKPASS helper, once the stall notice of _StallWatchdog proves insufficient in the field. It is also the only route serving a hardened sudoers policy, whose timestamps the primed cache cannot reach (see _SUDO_CACHE_WARM). That class records why the helper was rejected first, and any implementation has to answer its two remaining points: the raw password it handles, and the tools it never reaches (brew honors the variable, fink’s plain sudo re-exec does not). The third, a still terminal for the prompt, _hidden_prompt_risk() now provides.

(The original entry is located in /home/runner/work/meta-package-manager/meta-package-manager/meta_package_manager/sudo.py:docstring of meta_package_manager.sudo, line 75.)

Todo

Make version pinning expressible in a manager definition. install and upgrade on a config-defined manager always let the manager choose the version today, and a {version} placeholder is not substituted.

(The original entry is located in /home/runner/work/meta-package-manager/meta-package-manager/docs/overrides.md, line 143.)

Todo

Drop the pyXXX-sqlite3 dependency once mpm requires a click-extra carrying kdeldycke/click-extra@c75292d, due in 9.1.0. That commit probes for the _sqlite3 extension at import time, and moves the sqlite3 import into the reader that needs it. An interpreter without the bindings then disables the SQLITE configuration format alone, and every other format keeps working, so mpm installs and starts on a stock FreeBSD Python with no preparation step. Other platforms gain the same guarantee: a distribution can package any standard library module wrapping a system library apart from its interpreter, and click-extra now covers that whole class rather than sqlite3 alone. Delete the note above and the FreeBSD note of docs/install.md in the same change.

(The original entry is located in /home/runner/work/meta-package-manager/meta-package-manager/docs/packaging.md, line 56.)

Todo

This is a big feature for the future, but is already delimited by the PROJECT concept, the discover_projects() extension point, and issue #1725.

(The original entry is located in /home/runner/work/meta-package-manager/meta-package-manager/docs/unsupported.md, line 744.)