One transparent CLI for every package manager already on your machine.
English · فارسی · Wiki · ویکی فارسی
Allp unifies discovery, search, installation, removal, maintenance, diagnostics, and reproducible package profiles while keeping native commands visible and native package managers authoritative.
Allp is a transparent package-manager orchestrator with a cross-platform runtime core and Linux-first package backends. It discovers native tools such as APT, Pacman, DNF, rpm-ostree on Bazzite/Atomic hosts, Flatpak, Snap, Homebrew/Linuxbrew, Python and Node installers, and Rust/Cargo, then shows the exact native command or local API request before anything mutates the system.
Current build version: 0.6.3.1 (Cargo base version 0.6.3) Maturity: public alpha
| I want to… | Go to |
|---|---|
| Follow a complete everyday workflow | Practical usage guide |
| Install Allp and run the first commands | Quick start |
| Learn every CLI command with examples | Command reference |
| Understand supported package managers | Backend guide |
| Automate Allp safely with JSON | Automation and JSON |
| Understand architecture and safety boundaries | Architecture · Security |
| Develop or contribute | Development · Contributing |
| Diagnose a problem | Troubleshooting |
The English wiki and Persian wiki are the
long-form documentation hubs. Files under docs/ remain the canonical
engineering contracts for contributors.
Linux software often lives across system repositories, universal app stores, Homebrew, Python, Node, and Rust/Cargo. Allp gives those sources one consistent command surface without hiding the native package managers or pretending they are interchangeable.
Core principles:
- Native package managers remain visible and authoritative.
- Every mutating plan shows the exact native command.
- Commands are executed directly, not through hidden shell pipelines.
- Source selection is explicit when names collide.
- Backends advertise capabilities instead of generic code guessing behavior.
- Privilege handling is centralized and child-process only.
The platform layer detects Linux distributions and package-manager families, including Bazzite as a Fedora-family image-based host, plus macOS, Windows, WSL, containers, architecture, libc, users, executable ownership, and platform data directories. Package orchestration is maturest on Linux. Homebrew/macOS remains experimental; Windows currently supports compilation, diagnostics, release-target selection, and deferred self-replacement, but does not advertise Linux-only Snap or Flatpak backends.
| Source | Status | Search | Install | Remove | Update | Upgrade | List | Info |
|---|---|---|---|---|---|---|---|---|
| APT | Stable alpha | yes | yes | yes | yes | yes | yes | yes |
| Pacman | Stable alpha | yes | yes | yes | yes | yes | yes | yes |
| DNF / DNF5 | Stable alpha | yes | yes | yes | yes | yes | yes | yes |
| rpm-ostree / Bazzite / Fedora Atomic | Experimental | yes | yes | yes | yes | yes | yes | yes |
| Flatpak | Stable alpha | yes | yes | yes | yes | yes | yes | yes |
| Snap | Stable alpha | yes | yes | yes | yes | yes | yes | yes |
| Zypper, APK, XBPS, Portage, eopkg, swupd | Experimental | yes | mixed | mixed | mixed | mixed | mixed | mixed |
| Homebrew / Linuxbrew | Experimental | yes | yes | yes | yes | yes | yes | yes |
| Python: PyPI with pip, pipx, uv | Experimental | yes | yes | yes | yes | yes | yes | yes |
| Node: npm registry with npm, pnpm, Yarn | Experimental | yes | yes | yes | yes | yes | yes | yes |
| Rust: crates.io with Cargo | Experimental | yes | yes | yes | no | optional¹ | yes | yes |
¹ Cargo binary upgrades use the optional community cargo-update subcommand; Allp never rewrites project dependencies or Cargo.lock during host maintenance.
JSON is available for read-only commands and dry-run maintenance/install planning where supported. See docs/CAPABILITY_MATRIX.md for the detailed matrix.
Install the verified prebuilt release without Rust:
curl --fail --location --output install-allp.sh \
https://github.com/allp-manager/allp-manager/releases/latest/download/install-allp.sh
less install-allp.sh
sh install-allp.shThe installer detects Linux/macOS architecture, downloads the exact release
archive and adjacent SHA-256 file, verifies it, checks the archive contains only
the allp binary, and installs to ~/.local/bin. It is deliberately not
documented as a curl | sh pipeline. Pass an exact version such as 0.6.3 as
the first argument, or set ALLP_INSTALL_DIR to choose another user-writable
directory.
If a distribution package owns the running binary, allp self-update never
overwrites /usr/bin/allp; it reports the owning dpkg/rpm/Pacman package and
hands updates back to that package source. Native .deb, .rpm, and AUR
publication is intentionally deferred until signed repository update delivery
exists.
Build from source for development:
git clone https://github.com/allp-manager/allp-manager.git
cd allp-manager
cargo build --release
./target/release/allp --versionInstall the release binary globally:
make install
allp --version
allp update && allp upgradeallp --version prints the display/build version; allp --version --verbose also prints the base version, build revision, channel, commit, build ID, target, timestamp, and whether CI marked the build official. Fresh installs default to the verified tagged stable channel. Existing alpha state that used the old implicit channel remains on verified continuous builds; any explicit --update-channel stable|continuous|prerelease choice is sticky.
make install builds the release binary and installs it as
/usr/local/bin/allp. It uses sudo install for that one file copy. For a
user-local install without sudo:
make install-userSource-build requirements:
- Rust 1.74 or newer
- Cargo
- The native package managers you want Allp to detect
sudoonly when a root-required child command actually needs elevation
Release binary usage is simply:
allp detect
allp search gitallp detect
allp search git
allp install git
allp install git --dry-run
allp install pycharm
allp install ripgrep --from cargo --dry-run
allp install htop --from bazzite --dry-run
allp update
allp upgrade
allp upgrade --allow-stale-metadata # explicit recovery only
allp update --scope dev
allp search git --jsonupdate refreshes backend metadata; it does not upgrade Snap, Flatpak, or Homebrew packages. upgrade upgrades installed software. When APT needs a metadata refresh first, that refresh is a required dependency: a failure defers the APT upgrade. --allow-stale-metadata is an explicit override, never the default.
Homebrew discovery uses one validated locator across detect, doctor, and package operations. It checks configured/custom locations, PATH, revalidated state, deterministic original-user paths, and the official Linux/macOS prefixes, so sudo omitting Linuxbrew from root's PATH does not make an existing installation disappear. Homebrew metadata refresh prefers brew update-if-needed. Upgrade discovery and execution set HOMEBREW_NO_AUTO_UPDATE=1, use structured brew outdated --json=v2 evidence, skip empty upgrades, and verify outdated state afterward. Homebrew probes and operations run in its validated owner's user context even when Allp was launched through sudo.
Before changing Homebrew on a host where Allp is invoked through sudo, verify
the shared locator and the original-user boundary first:
allp doctor homebrew --verbose --no-color
sudo allp doctor homebrew --verbose --no-color
sudo allp update --from homebrew --dry-run --skip-self-update --no-interactive --no-color -vThe dry run must identify the selected owner and Homebrew executable; its preview is descriptive, while the real child retains the validated privilege boundary and sanitized owner environment. After review, a real metadata refresh can be requested explicitly:
sudo allp update --from homebrew --yes --skip-self-updateSee the Homebrew backend guide for validation details and macOS/Linuxbrew limits.
Rust/Cargo is a user-scoped development backend for crates.io binary tools.
Search, install, remove, list, and info use Cargo's native commands. Host
maintenance never runs cargo add or cargo update, so it does not modify a
project manifest or lockfile. allp upgrade --from cargo --target global
upgrades installed binaries only when the optional cargo-update subcommand is
present. Cargo operations run as the original user under sudo and show the
local-compilation/build-script warning before execution. See
the Rust/Cargo backend guide.
On Bazzite, Allp disables DNF host mutations and selects rpm-ostree for package
layering and transactional image upgrades. update runs rpm-ostree refresh-md; upgrade stages rpm-ostree upgrade; install/remove stage layered
package changes that normally require a reboot. Because Bazzite recommends
layering only as a last resort, every layering plan points users toward
Homebrew, Flatpak, or containers first. See
the Bazzite backend guide.
Package profiles capture package identifiers and their owning backends in a portable TOML document. They are useful for reviewing a machine's package set, moving an explicit package list between compatible systems, and replaying that list through Allp's normal search, planning, and confirmation flow.
allp profile save dev
allp profile list
allp profile show dev
allp profile export dev dev.toml
allp profile import dev.toml
allp profile import dev.toml --name laptop-dev
allp profile install dev --dry-run
allp profile install devExample profile:
version = 1
name = "rust-dev"
[[packages]]
backend = "apt"
package = "git"
[[packages]]
backend = "rust"
package = "ripgrep"
[[packages]]
backend = "flatpak"
package = "org.mozilla.firefox"Profiles deliberately preserve the backend instead of guessing an equivalent
package on another ecosystem. All required backends are checked before the
first installation, then packages are installed sequentially with the same
safety checks and confirmations as allp install. Review a profile with
show, or export and edit it, before applying it on another machine.
In profile format version 1, the stored package version is observed inventory
metadata, not a version pin; installation resolves the version currently
available from the named backend. profile save records every package exposed
by each backend's installed-package listing, which can include system
dependencies on APT, DNF, or Pacman. Profiles therefore work best between
systems with compatible backends and should not yet be treated as a universal
cross-distribution lockfile. Import uses the name declared inside the TOML file
unless --name overrides it.
On a real interactive update or upgrade, Allp presents an inline live
APT-style progress line during execution. Native logs remain unchanged in the
normal terminal scrollback; only the current bottom line is redrawn with the
percentage, active backend, action, elapsed time, and queue completion. The
line is fitted to the actual terminal width so it cannot wrap into prompts.
When selected maintenance plans need administrator access, Allp validates it
with sudo -v before progress starts, then runs those children with sudo -n --
so a password prompt never appears in the live line.
Use the classic output whenever you prefer it or are recording a familiar log:
allp update --no-tui
allp upgrade --no-tuiLive progress is intentionally absent from JSON, dry runs, redirected/non-TTY
output, TERM=dumb, and --no-interactive runs. --no-color keeps the line
but removes color. The renderer only observes the process runner: it never
rewrites the planned native argv or plan-level privilege requirement; the
privilege boundary is fixed before rendering begins. Full behavior and fallback
rules are in
docs/TERMINAL_UI.md.
Use --from for a precise backend:
allp install git --from apt --dry-run
allp install pycharm --from snap --dry-run
allp install black --from pipx --dry-run
allp install typescript --from pnpm --dry-run
allp install ripgrep --from cargo --dry-run
allp install htop --from bazzite --dry-runWithout --from or --scope, interactive search and install ask for one of three scopes:
apps: system packages, universal applications, and Homebrewdev: Python, Node, and Rust/Cargo ecosystemsall: every eligible source
JSON, redirected, and --no-interactive searches cannot ask that question, so
they default to apps unless --from or --scope is explicit. Eligible
backends search concurrently in bounded groups of four. A parser that receives
unknown native output reports unrecognized_output instead of claiming no
matches; valid rows from a partially failed backend are retained with
complete=false.
Default human output is one line per candidate. -v adds identity,
relationship, artifact, installer, and native metadata. Verified canonical
relationships are grouped, probable relationships appear in an explicit
uncertainty section, and unverified same-name results remain separate. Allp can
recognize relationships, but it does not choose between meaningful sources for
you.
Results are ranked as Exact, Related, or Fuzzy. All exact matches are shown, related matches are capped per backend, and weak fuzzy matches require --all.
Large interactive result sets keep stable global numbers. Space moves forward, b moves back, / filters, a number selects directly, Enter selects the highlighted or first visible result, and q or Escape cancels.
Preferred:
allp updateAllp itself should normally run as your user. For a confirmed maintenance run,
Allp validates administrator access once with sudo -v before live progress
starts, then runs root-required children with sudo -n --. This keeps password
prompts out of the progress line. If a later cached credential
expires, Allp clears the footer, revalidates with sudo -v outside the
renderer, and resumes only after success; an unsuccessful revalidation is a
blocked operation rather than a package-manager failure. Dry runs never invoke
sudo.
If you intentionally run:
sudo allp updateAllp does not add nested sudo. Root-required system plans run directly, and user-scoped plans such as Homebrew, Python, Node, Rust/Cargo, and Flatpak-user run as the original sudo user when that identity is available.
--yes bypasses only Allp's final confirmation after choices are resolved. It
does not indiscriminately add native confirmation flags: APT upgrades receive
their documented -y flag, while APT metadata refreshes remain apt-get update
without -y.
Snap uses the local snapd REST API through /run/snapd.socket when it is reachable. Wide discovery and exact resolution are separate:
GET /v2/find?q=<encoded-query>&scope=wide
GET /v2/find?name=<encoded-canonical-name>
A discovery row is never an installation plan. After selection, exact resolution verifies:
- canonical package name and display title;
- publisher and verification state;
- confinement;
- architecture availability;
- tracks and channels;
- stable-channel availability;
- installed state.
An authoritative snapd 404 with kind: snap-not-found means unavailable. It is not a transport error and never falls through to snap info. Allp stops before sudo or installation, and Try another installer performs a fresh search with Snap excluded and cached Snap results discarded.
CLI fallback is allowed only when the socket is absent or denied, connection fails, an endpoint is unsupported, or the response is not recognizable as snapd. The concrete fallback reason is kept in diagnostics. CLI exact resolution uses an argv vector equivalent to snap info <name>; successful exit status remains success even if stderr contains a warning.
REST installation sends POST /v2/snaps/<name>, includes "classic": true only for classic confinement, and polls /v2/changes/<id> until a terminal state. A change ID alone is not success. CLI fallback adds --classic only when metadata requires it:
allp install pycharm --from snap --dry-run
# when CLI fallback is active, the native plan includes:
snap install pycharm --classicStrict snaps do not receive --classic. If no stable channel exists, or multiple stable tracks exist without a safe default, Allp stops instead of silently choosing candidate, beta, edge, or an arbitrary track.
Flatpak distinguishes four states: not installed, installed without remotes, installed with remotes, and backend error. Remote detection uses:
flatpak remotes --columns=name,title,url,filter,optionsNo remotes means no searchable catalog; it is not reported as "no package match." Allp can offer a separate, user-scoped Flathub plan using the exact remote name and URL. It never adds Flathub automatically. --yes alone cannot bootstrap an executable, enable a service, or add a remote; unattended approval requires both --yes --allow-bootstrap, after the full plan is printed.
Missing Flatpak or Snap executables can be planned through structured APT, DNF, Pacman, Zypper, or APK bootstrap providers where a mapping is known. After an approved install, Allp refreshes capability and backend detection and continues only if the requirement is verified. Flatpak results preserve application ID, branch, remote, version, name, and description, and installation uses the remote plus application ID.
Python support treats PyPI as the source and pip, pipx, and uv as installer choices. Node support treats the npm registry as the source and npm, pnpm, and Yarn as installer choices. Rust support treats crates.io as the source and Cargo as the installer. Registry matches are not treated as official merely because a name looks familiar, and fuzzy Python/Node/Rust matches are never installed automatically.
Examples:
allp search openai --from python
allp install black --from pipx --dry-run
allp search typescript --from node
allp install typescript --from pnpm --dry-run
allp update --scope dev --target all --dry-runDry run performs discovery, search, selection, metadata validation, and execution-plan construction. It skips only mutating native command execution.
allp install git --dry-run
allp install pycharm --from snap --dry-run
allp update --dry-runJSON examples:
allp detect --json
allp search git --json
allp list --json
allp info git --json
allp update --dry-run --jsonHuman logs are not mixed into JSON stdout.
allp update checks the trusted repository allp-manager/allp-manager before ordinary backend metadata updates unless disabled. Its phases cover self-update, platform/capability refresh, backend planning, confirmation, execution, and summary.
allp doctor
allp self-update --check-only
allp self-update --offline
allp update --check-only
allp update --skip-self-update
allp update --self-only
allp update --offline
allp update --update-channel prereleaseFresh installs use the stable tagged-release channel. Migrated alpha installs may retain the verified continuous main-branch channel; stable, continuous, and prerelease selections are explicit and persisted. Stable release metadata must contain allp-release-manifest.json, while continuous builds use their dedicated manifest and trusted workflow identity. Allp compares base SemVer before build revision, selects an asset by OS, architecture, libc, executable format, and target, and reports unsupported targets without staging an update.
If the installed build is newer than the selected channel, Allp reports the
distinct LocalAhead state and does not downgrade it; this is not described as
up to date.
A binary installed with make reinstall is marked as a local development build. When continuous is selected, it still follows a newer verified continuous build from main (including the local revision-1 collision); the normal replacement confirmation remains in place.
Downloads are HTTPS-only, bounded by redirects, time, and size, restricted to the exact official repository/tag/asset, and verified with SHA-256 before safe extraction. The staged binary must report the expected version. Linux and macOS replacement uses same-directory staging, a rollback backup, post-install verification, and minimal elevation for non-writable installations. Windows uses a verified deferred helper. A guarded relaunch continues allp update once without entering an update loop. Offline mode contacts neither GitHub nor backend remote sources.
allp doctor reports platform, users, install path ownership/writability, executable paths, backend states, Snap socket reachability, Flatpak remotes, trusted update source, release target, and cache/state/config paths without printing tokens or unrelated environment data.
The root Makefile keeps development, installation, and local release work in plain commands:
make help
make fmt
make fmt-check
make check
make clippy
make test
make architecture
make build
make release
make quality
make run ARGS="search git"
make doctor
make version
make git-status
make docs-check
make install
make reinstall
make uninstall
make install-user
make install-checkmake install, make reinstall, and make uninstall use sudo only to manage
/usr/local/bin/allp. They do not install native packages, run Allp package
operations, commit, push, tag, publish, or hide failures.
make reinstall now warns if your shell resolves allp from another location
(for example ~/.local/bin/allp). Run make install-check after installing;
use make install-user deliberately when the user-local copy is the one you
want to refresh.
The release workflow is explicit. Local preparation never pushes, publishes a
GitHub Release, or uploads assets. A GitHub Release is created only after a
semantic-version tag such as v0.5.0 is pushed.
Run once per clone:
make hooks-installPrepare the next version explicitly:
make release-prepare BUMP=patch
# or:
make release-prepare VERSION=0.5.0release-prepare updates the package version, Cargo.lock through Cargo,
CHANGELOG, README version references, a tracked release title such as
release/RELEASE_TITLE_v0.5.0.txt, and a tracked draft such as
release/RELEASE_NOTES_v0.5.0.md, then runs make quality. It writes an
ignored readiness marker only after that quality gate passes.
Commit the prepared files normally, for example from VS Code Source Control:
release: Allp v0.5.0
Only a commit whose subject begins with release: and matches the prepared
marker is finalized. The post-commit hook creates:
- annotated local tag
v0.5.0 dist/allp-v0.5.0-source.tar.gzdist/allp-v0.5.0-source.tar.gz.sha256dist/RELEASE_NOTES_v0.5.0.md
The source archive is generated from the exact committed tag with git archive.
Ordinary commits such as fix: improve Snap parsing do not change versions,
create tags, or generate dist/ output. Use make release-status to inspect
state and make release-workflow-test to run the temp-repository automation
tests. VS Code task examples live in contrib/vscode/tasks.json because
.vscode/ is editor-local and ignored.
When the local release tag is ready, run make release-push explicitly. It
verifies the release commit, annotated tag, and tag target, then pushes the
current branch and matching tag. The tag-only GitHub Actions workflow creates
the GitHub Release from the prepared title and notes. It builds and tests
Linux x86_64/aarch64, macOS x86_64/aarch64, and Windows x86_64 binaries;
uploads their archives and checksums; creates the exact-tag source archive; and
generates and verifies allp-release-manifest.json. It refuses an existing
conflicting release.
| Symptom | What to do |
|---|---|
| APT lock error | Wait for the owning package process. Do not delete dpkg lock files. |
| DNF/RPM database error | Check rpmdb permissions or repair the RPM database before retrying. |
| Bazzite host package change | Prefer Homebrew, Flatpak, or a container; if layering is necessary, review the rpm-ostree plan and reboot after it completes. |
| Missing pip, pipx, or uv | Run allp detect --verbose and install/configure the missing Python tool intentionally. |
| npm global permission issue | Fix npm prefix ownership or use a user-owned Node manager; Allp will not sudo npm globals. |
| Cargo upgrade unavailable | Install the optional cargo-update crate intentionally, or keep managing installed Cargo binaries manually. |
| Flatpak has no remotes | Run allp doctor; review and explicitly approve the offered Flathub user-remote plan if desired. |
| Snap exact result unavailable | Run allp doctor and Snap diagnostics. A valid REST snap-not-found is authoritative. |
| Snap CLI fallback | Diagnostics show why REST was unavailable and the exact CLI argv/output. |
| Self-update unavailable | Use allp self-update --check-only -v; unsupported targets leave the installed binary unchanged. |
Allp stores commands as program plus argument vector and never executes package-manager work through sh -c. Native package output is data, not trusted code. Dry runs do not execute installers. Bootstrap actions are separate plans. Self-update rejects foreign repositories, unsafe asset names, malformed manifests, checksum mismatches, archive traversal, and staged-version mismatches. State files contain no credentials. Allp does not store sudo passwords or collect telemetry; any operation-specific native confirmation flag is explicit in its reviewed plan.
Read SECURITY.md for reporting and alpha limitations.
CLI -> platform/capabilities -> requirements -> discovery -> operation -> backend -> execution
| | |
bootstrap alternatives diagnostics
CLI -> self_update -> release manifest -> verified replacement -> guarded re-execution
Backends own native syntax, REST/CLI transport details, and parsers. Generic operations coordinate capabilities, selection, alternatives, confirmation, and immutable plans. Bootstrap providers are independent of the backend that needs them. The runner owns direct process execution, output streaming, sudo handling, and original-user de-escalation.
See ARCHITECTURE.md, docs/BACKEND_CONTRACT.md, and docs/PRIVILEGE_MODEL.md.
cargo fmt --all
cargo fmt --all -- --check
cargo check --all-targets
cargo test --all-targets
bash scripts/check-architecture.sh
cargo build --release
make qualityUse fake executable fixtures for package-manager behavior. Do not run destructive package-manager operations in tests.
cargo clippy --all-targets --all-features -- -D warnings
Keep backend-specific parsing and flags inside backend modules. Add fixtures for parser changes. Preserve command syntax, JSON contracts, privilege behavior, dry-run semantics, and terminal UI expectations. See CONTRIBUTING.md.
Near-term work is broader real-distro validation, richer parser fixtures, an interactive Snap channel chooser, deeper signal/trusted-path testing, and real-host Homebrew, Cargo, and Bazzite validation. Version 0.6.3 includes Rust/Cargo binary-tool management and transactional rpm-ostree support for Bazzite; a broader full-screen TUI and GUI remain later work, alongside future ecosystems such as Composer, Go, RubyGems, and Maven/Gradle.
See ROADMAP.md and TODO.md.
Version 0.6.3 is the current published release. It includes Rust/Cargo
binary-tool management and Bazzite/rpm-ostree support while retaining the
Homebrew, Node, and Python user-scope boundaries.
See CHANGELOG.md.
- Allp is public alpha software and not security-audited.
- Snap multiple-track selection is conservative and may require native
snapcommands for explicit channel choice. - Existing GitHub releases without a valid manifest and matching binary asset cannot self-update automatically.
- Experimental backends need broader validation on real distributions and host setups.
- Python and Node project-scope policies remain intentionally cautious; Cargo host maintenance intentionally excludes project dependencies.
- rpm-ostree and Cargo support still require wider real-host validation.
- Signal forwarding and deeper trusted-path validation remain future hardening work.
MIT. See LICENSE.