HPM is the community package manager for HackerOS. It installs, builds, sandboxes, and manages packages entirely in your own home directory — no root required for day-to-day use.
- No more root. Packages install to
~/.hackeros/hpm/store/, wrappers to~/.local/bin/, desktop/icon integration to~/.local/share/.... Old versions used/usr/lib/HackerOS/hpm/store/+/usr/bin/, which requiredsudofor every operation. That's gone — see Directory layout. hpm dev <path>— test a local package directory that isn't (yet) inrepo-list.json/repo.json. See Local package testing.hpm install <pkg> --release— install from a package's GitHub Release.hpmasset instead ofgit clone-ing the whole repo. See Distributing via GitHub Releases.- Hooks now run sandboxed (namespaces + seccomp + Landlock + rlimits), and
pre-remove/post-remove/post-updatehooks actually fire now (they used to be defined but never called). - Preflight conflict checking —
hpm install a b cresolves and cross-checks every package's manifest before touching any files, instead of discovering a conflict halfway through a multi-package install. hpm buildcan now sign packages (--sign <key-id>, GPG detached signature) and always emits a.sha256checksum alongside the.hpmarchive — the same integrity story as pacman's.pkg.tar.zst+.sig.
hpm install <package>[@<version>]
hpm install <package> --release # from GitHub Releases instead of git clone
hpm install @<tag> # install every package with a given group tagNo sudo needed. If you see a permission error, it almost always means
~/.hackeros or ~/.local/bin was previously created by root (e.g. a stray
sudo hpm ... before 0.9) — hpm will tell you exactly what to chown.
| Command | Description |
|---|---|
hpm install <pkg>[@<ver>]... |
Install one or more packages |
hpm install <pkg> --release |
Install from a GitHub Release .hpm asset |
hpm install @<tag> |
Install every package tagged <tag> |
hpm remove <pkg>[@<ver>] |
Remove a package (runs pre/post-remove hooks) |
hpm autoremove |
Remove orphaned dependencies |
hpm update |
Update all packages (runs post-update hooks) |
hpm switch <pkg> <ver> |
Switch the active version |
hpm rollback [<pkg>] |
Restore previous state |
hpm pin / hpm unpin |
Lock a package to a version across updates |
| Command | Description |
|---|---|
hpm search <query|@tag> |
Search the package index |
hpm info <package> |
Show package details |
hpm list |
List installed packages |
hpm outdated |
Show packages with available updates |
hpm deps <pkg>[@<ver>] |
Show dependency tree |
hpm diff <pkg> <v1> [<v2>] |
Compare two package versions |
| Command | Description |
|---|---|
hpm run <pkg> <bin> [args] |
Run an installed binary, sandboxed |
hpm build [name] |
Package the current directory into a .hpm archive |
hpm build --output <path> |
Custom output path |
hpm build --sign <key-id> |
Also produce a detached GPG .sig |
hpm verify <package> |
Verify SHA-256 + GPG signature |
hpm dev <path> |
Test a local package directory (see below) |
hpm dev <path> run <bin> [args] |
...and run one of its binaries |
| Command | Description |
|---|---|
hpm doctor |
Diagnose consistency issues |
hpm repair |
Auto-fix issues found by doctor |
hpm clean [--all] |
Remove cached repos/temp files (and old versions with --all) |
hpm lock <subcmd> |
Manage hpm.lock for reproducible installs |
Run hpm --help for the full, current list — this table is a summary, the
--help output is generated from the same code that implements the commands
so it can't drift out of sync the way this file can.
~/.hackeros/hpm/
├── store/ installed packages (was /usr/lib/HackerOS/hpm/store/)
├── cache/ repo index (repo-list.json/repo.json) + downloaded .hpm files
└── db/ state.json, wrapper-names.json, system.lock
~/.local/
├── bin/ binary wrappers (was /usr/bin/)
├── share/applications/ .desktop files (was /usr/share/applications/)
├── share/icons/hicolor/ icons (was /usr/share/icons/hicolor/)
├── share/pixmaps/
├── share/bash-completion/completions/
├── share/zsh/site-functions/
└── config/fish/completions/
Everything above is per-user. Two packages installed by two different users on the same machine don't conflict, and nothing here needs elevated privileges.
The one exception is hpm upgrade (upgrading hpm itself, not a package it
manages) — that still touches the system-wide hpm binary and may ask for
sudo, same as upgrading any other system tool.
hpm dev has two modes. With no path, it runs hpm's own internal test suite
(hpm dev test / hpm dev test-full / hpm dev check-env) — useful if you're
hacking on hpm itself.
With a path, it tests your package:
hpm dev ./my-package
hpm dev /home/user/packages/firefoxThe directory needs the same layout a real package would (info.hk, plus
contents/ or a build step) — it does not need to be listed in
repo-list.json / repo.json. This is the intended workflow for porting a new
tool: build the package directory, hpm dev it repeatedly while iterating, and
only register it in the repo index once it works.
hpm dev <path> will:
- Load and print the manifest (name, version, arch, sandbox policy, hooks).
- Validate hooks and check architecture compatibility.
- Build
contents/if it's missing (build.tomlfirst, then classic[build] commands/build.info— same code pathhpm installuses). - Run
pre-installandpost-installhooks, sandboxed, exactly like a real install (without touching~/.hackeros/hpm/store). - List every declared binary and whether it was actually found.
Then run one of its binaries through the exact same sandbox hpm run uses:
hpm dev ./my-package run my-binary --some-flagrepo-list.json / repo.json still just contains a repo URL — that format is
unchanged:
{ "packages": { "my-tool": "https://github.com/someone/my-tool" } }By default hpm install my-tool clones that repo with git. If you instead run
hpm build --output my-tool.hpm --sign <your-gpg-key-id>in your package directory and attach my-tool.hpm (+ the .sha256 it
produces, + the .sig if you signed it) to a GitHub Release, then anyone can
fetch that exact artifact instead of cloning your repo:
hpm install my-tool --release # latest release
hpm install my-tool@v1.2.0 --release # specific taghpm verifies the .sha256 automatically if it's present next to the .hpm
asset. This doesn't change how packages are registered — it's purely a faster,
optionally-signed transport for packages that opt in by publishing releases.
Package hooks live in hooks/ and run sandboxed (namespaces, seccomp,
Landlock, resource limits — the same isolation hpm run uses for the app
itself):
| Hook | Runs | Blocks install/remove on failure? |
|---|---|---|
pre-install |
before install | yes |
post-install |
after install | no |
pre-remove |
before removal | yes |
post-remove |
after removal | no |
post-update |
after update | no |
Hooks never get network access by default, even if the package itself declares
sandbox.network = true — that only applies to the app, not its install-time
scripts. If a hook genuinely needs network (e.g. registering with an external
service on first install), declare it explicitly and narrowly:
[sandbox]
-> hooks_network => true
Supported hook interpreters, by extension: .hl (Hacker Lang), .py, .rb,
.sh.
info.hk Manifest: name, version, bins, deps, conflicts, sandbox, tags
build.toml Build/download instructions (optional — see BuildConfig)
contents/ Pre-built files (skip build.toml if you ship these directly)
hooks/ pre-install / post-install / pre-remove / post-remove / post-update
info.hk.sig GPG signature (optional)
- Every package runs sandboxed by default (Linux namespaces + seccomp + Landlock + resource limits), degrading gracefully layer-by-layer when the host/container doesn't support a given primitive rather than refusing to run at all.
- Hooks get the same sandboxing, network-isolated by default (see above).
hpm installresolves and conflict-checks every package in a batch before installing any of them..hpmarchives fetched via--releaseare checksum-verified when a.sha256asset is published alongside them, and can be GPG-signed.
- No full dependency SAT solver yet — conflicts are checked, but hpm won't automatically pick alternate versions to resolve them.
- State/history is still a JSON file under
~/.hackeros/hpm/db/, not a real embedded database. hpm upgrade(upgrading hpm itself) still uses system paths and may needsudo— everything else doesn't.