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’spipmanager has a hard>=26.1.0floor, butpipxmaintains its own virtualenvs whose pip may be older or whose resolution may be routed throughuv(where the right env var isUV_EXCLUDE_NEWERinstead ofPIP_UPLOADED_PRIOR_TO). Probing the resolver per venv would letmpmrefuse 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-packagetakes aPACKAGE=DATEpair, npm’smin-release-age-excludetakes names orminimatchglobs. The catch is that this would not fit the uniformcooldown_env_varinjection: uv publishes no environment variable for--exclude-newer-package(only the plain--exclude-newercarries aUV_EXCLUDE_NEWERbinding), so uv needs the exemption appended to the command line while npm can keep taking it throughnpm_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_varframework 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 commandsmpmdrives never reach. Onboard each one if upstream widens it tocargo install, togem install, or to themambaandmicromambacommand lines. The notes under the support table record what each gate covers today.Advisory mode for
outdatedon managers without a native gate.mpmcould query each package registry directly (PyPI, RubyGems, crates.io, …) to annotateoutdatedwith 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 whichmpmhas 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 intompmwould 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 forflatpakandmasis 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, andsnap infoprints no dates (snapd’s autonomous background refresh would bypass anmpm-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:
strict:--exact, on ID or name.substring: regex, case-insensitive, no splitting.fuzzy: token-based.extended:fuzzyplus 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.)