hpm — HackerOS
Package Manager
A git-native, sandboxed package manager for HackerOS and Debian-based systems. No binary archives — packages are git repositories with tagged versions.
Overview #
hpm is a modern package manager built for HackerOS.
Each package is a plain git repository. Versions are git tags.
There are no .deb or .hpm archives — hpm clones the repo,
reads info.hk, optionally runs a build step, and copies
contents/ into a content-addressable store.
Every package runs inside a Linux namespace sandbox (user, mount, UTS, PID, cgroup
namespaces + Landlock filesystem restrictions). Network, GUI, and device access are
opt-in per-package via info.hk.
How it works
# 1. Central index
repo.json ──► { "mypkg": { "repo": "https://github.com/user/mypkg" } }
# 2. Install flow
hpm install mypkg
└─ fetch repo.json (HTTP)
└─ clone git repo (git2)
└─ checkout latest semver tag (blob-by-blob, no conflict)
└─ read info.hk (hk-parser)
└─ install apt deps if needed
└─ run build.toml / build.info (in sandbox)
└─ copy contents/ → store (/usr/lib/HackerOS/hpm/store/)
└─ create /usr/bin wrapper (calls: hpm run pkg bin)
└─ update state.json (/var/lib/hpm/state.json)
# 3. Run flow
$ mypkg
└─ /usr/bin/mypkg → hpm run mypkg mypkg
└─ setup Linux namespaces + Landlock
└─ exec /app/bin/mypkg
Installing hpm #
# Download and install the hpm binary
sudo curl -L https://github.com/HackerOS-Linux-System/HackerOS-Package-Manager/releases/latest/download/hpm \
-o /usr/bin/hpm
sudo chmod +x /usr/bin/hpm
# Verify
hpm --version
/usr/lib/HackerOS/hpm/store/ and /usr/bin/.
Search, info, list, and query commands work without root.
Quickstart #
# Refresh the package index
sudo hpm refresh
# Search for a package
hpm search editor
# Show package details
hpm info hedit
# Install a package (latest version)
sudo hpm install hedit
# Install a specific version
sudo hpm install hedit@2.1.0
# Run it
hedit myfile.txt
# List installed packages
hpm list
# Update all packages
sudo hpm update
# Remove a package
sudo hpm remove hedit
Command Reference #
Package Commands
| Command | Description |
|---|---|
| hpm refresh | Download the package index and pre-fetch metadata for all packages |
| hpm install <pkg>[@<ver>]... | Install one or more packages, resolving hpm and apt dependencies automatically |
| hpm remove <pkg>[@<ver>] | Remove a package or a specific version |
| hpm update | Update all non-pinned packages to their latest tagged version |
| hpm upgrade | Upgrade hpm itself |
| hpm switch <pkg> <ver> | Switch the active version of an installed package |
Query Commands
| Command | Description |
|---|---|
| hpm search <query> | Search by name or description — fast HTTP fetch, never clones git |
| hpm info <package> | Show full package details: version, author, license, description, build type |
| hpm list | List all installed packages and their versions |
| hpm outdated | Show packages that have newer versions available |
| hpm deps <pkg>[@<ver>] | Print the full dependency tree for a package |
| hpm verify <package> | Verify installed package integrity against stored SHA-256 checksum |
Maintenance Commands
| Command | Description |
|---|---|
| hpm run <pkg> <bin> [args] | Run a binary from an installed package inside its sandbox |
| hpm build <name> | Package the current directory (creates a tar.zst archive) |
| hpm clean | Remove cached git repos (~/.cache/hpm/repos/) and temp files |
| hpm pin <pkg> <ver> | Pin a package to a version — prevents automatic updates |
| hpm unpin <pkg> | Unpin the current version |
Search & Install #
hpm search fetches only info.hk via raw HTTP — it never clones
a git repository. This makes search nearly instant regardless of package size.
$ hpm search editor
→ Search results for 'editor' (2 found):
Package Version Description
────────────────────────────────────────────────────────────────────────
hedit 2.1.0 Lightweight terminal text editor
nanovim 0.9.3 Nano-style editor with vim motions
Run hpm info <package> for details, hpm install <package> to install.
# Install latest
sudo hpm install hedit
# Install exact version
sudo hpm install hedit@2.0.0
# Install multiple
sudo hpm install hedit nanovim ripgrep
Version Management #
hpm reads versions from git tags in the format v1.2.3 or 1.2.3.
Multiple versions can be installed side by side. Only one is "current" at a time,
tracked via a current symlink in the store.
# See installed versions
hpm list
# Install an older version alongside the current
sudo hpm install hedit@1.9.0
# Switch active version
sudo hpm switch hedit 1.9.0
# Pin to prevent updates
sudo hpm pin hedit 1.9.0
# Unpin when ready to update
sudo hpm unpin hedit
# Remove a specific old version
sudo hpm remove hedit@1.9.0
Sandbox #
Every package binary runs inside an isolated environment using Linux kernel primitives. Isolation layers (from outermost to innermost):
| Layer | Mechanism | What it isolates |
|---|---|---|
| Namespaces | user, mount, UTS, PID, cgroup | Filesystem view, process tree, hostname, control groups |
| Network | CLONE_NEWNET (opt-in) | Network stack — disabled by default |
| Pivot root | pivot_root(2) | Root filesystem replaced with tmpfs + bind mounts |
| Landlock | Landlock LSM v1 | Fine-grained filesystem access control |
| Resource limits | setrlimit(2) | CPU (60s), memory (512 MB), processes (1024) |
Sandbox options in info.hk
[sandbox]
-> network => false # allow outbound network
-> gui => false # bind-mount X11/Wayland/D-Bus/PulseAudio
-> full_gui => false # same as gui but includes /dev/dri
-> dev => false # expose /dev (null, zero, random, urandom, tty)
-> filesystem => { # extra host paths to bind-mount read-write
/home/user/Documents => ""
}
network = true, gui = true, or adding filesystem paths
reduces isolation. Only enable what the package genuinely requires.
Repository Layout #
An hpm package is a git repository with this structure:
├── info.hk ← required: manifest
├── build.toml ← optional: build/download instructions
├── contents/ ← optional: pre-built files (copied to store)
│ └── bin/
│ └── my-binary ← executable, chmod +x in git
└── README.md
contents/ directory is copied verbatim to the store.
Use contents/bin/<name> for binaries — this maps to
/usr/lib/HackerOS/hpm/store/<pkg>/<ver>/bin/<name>.
Versioning via git tags
# Tag a release — hpm reads this as version 1.0.0
git tag v1.0.0
git push origin v1.0.0
# Both formats are accepted
git tag 1.0.0 # also fine
info.hk Manifest #
The manifest is written in HK format,
parsed by hk-parser.
[metadata]
-> name => hello-hpm # package name (must match repo.json key)
-> version => 1.0.0 # must match the git tag
-> authors => HackerOS Team
-> license => MIT
-> bins.hello-hpm => "" # binary name → gets /usr/bin/hello-hpm wrapper
[description]
-> summary => One-line shown in hpm search
-> long => Longer description shown in hpm info
[sandbox]
-> network => false
-> gui => false
-> dev => false
-> full_gui => false
-> filesystem => {}
[build]
-> commands => {} # shell commands if no build.toml
-> deb_deps => {} # apt packages required at build time
[runtime]
-> deb_deps => {} # apt packages required at runtime
[specs]
-> dependencies.other-hpm-pkg => ">=1.0" # hpm package dependency
Multiple binaries
[metadata]
-> bins.editor => ""
-> bins.editorx => "" # creates /usr/bin/editor and /usr/bin/editorx
Dependency version constraints
| Constraint | Meaning |
|---|---|
| "" | Any version |
| =1.2.0 | Exactly 1.2.0 |
| >=1.2.0 | 1.2.0 or newer |
| >1.2.0 | Strictly newer than 1.2.0 |
| 1.2.0 | Exactly 1.2.0 (same as =1.2.0) |
build.toml #
When build.toml is absent, hpm uses contents/ directly (prebuilt layout).
Add build.toml when the binary must be downloaded or compiled.
type = "prebuilt" (default)
# Explicit — same as having no build.toml at all
type = "prebuilt"
type = "download"
type = "download"
url = "https://github.com/user/repo/releases/download/v{version}/mybinary-linux-x86_64"
install_path = "bin/mybinary" # destination inside contents/
# For tar archives:
type = "download"
url = "https://example.com/releases/v{version}/tool-linux.tar.gz"
binary_path = "tool-linux/bin/tool" # path inside the archive
strip_components = 1
install_path = "bin/tool"
type = "build"
type = "build"
commands = ["cargo build --release"]
output = "target/release/mytool" # where the binary appears after build
install_path = "bin/mytool"
build_deps = ["build-essential", "rustup"] # apt packages for build
runtime_deps = ["libssl3"] # apt packages for runtime
[env]
CARGO_PROFILE_RELEASE_LTO = "true"
/usr, /lib, /bin, /etc (read-only)
and /app + /tmp (read-write).
Set network = true in info.hk if the build step needs internet access.
Publishing a Package #
1. Create the repository
mkdir my-package && cd my-package
git init
# Create info.hk
cat > info.hk << 'EOF'
[metadata]
-> name => my-package
-> version => 1.0.0
-> authors => Your Name
-> license => MIT
-> bins.my-package => ""
[description]
-> summary => What my package does
[sandbox]
-> network => false
-> gui => false
-> dev => false
-> full_gui => false
-> filesystem => {}
[build]
-> commands => {}
-> deb_deps => {}
[runtime]
-> deb_deps => {}
EOF
# Add your binary
mkdir -p contents/bin
cp /path/to/my-binary contents/bin/my-package
chmod +x contents/bin/my-package
git add .
git commit -m "initial release"
git tag v1.0.0
git push origin main --tags
2. Add to repo.json
{
"packages": {
"my-package": {
"repo": "https://github.com/yourname/my-package"
}
}
}
"repo" URL. hpm discovers available versions
automatically from git tags. The optional "versions" array is only
needed if you want to hint at supported versions in the index.
3. Submit a pull request
Open a PR to the
HackerOS-Package-Manager
repository adding your entry to repo/repo.json.
repo.json Format #
{
"packages": {
// Minimal entry — versions read from git tags
"hello-hpm": {
"repo": "https://github.com/HackerOS-Linux-System/hpm-example-repo"
},
// With optional version hints
"hedit": {
"repo": "https://github.com/hackerOS/hedit",
"versions": ["1.0.0", "2.0.0", "2.1.0"]
}
}
}
Store Layout #
└── my-package/
├── 1.0.0/ ← installed version
│ ├── bin/
│ │ └── my-package ← the binary
│ └── info.hk ← manifest copy
├── 2.0.0/ ← another version (side-by-side)
└── current ← symlink → 2.0.0
/usr/bin/
└── my-package ← wrapper: exec hpm run my-package my-package
/var/lib/hpm/
└── state.json ← installed packages + checksums
hpm vs AUR vs PPA #
| Feature | hpm | AUR (yay) | PPA (apt) |
|---|---|---|---|
| Package format | Git repo + info.hk | PKGBUILD | .deb archive |
| Sandbox / isolation | Built-in (namespaces + Landlock) | None | None |
| Multiple versions installed | Yes (side-by-side) | No | No |
| Version pinning | Yes | Partial | Partial (hold) |
| Search speed | Fast (raw HTTP, no clone) | Medium (AUR RPC) | Fast (apt cache) |
| Binary integrity check | SHA-256 on install | Optional | GPG signed |
| Dependency resolution | hpm + apt deps | Full (makepkg) | Full (dpkg) |
| Build from source | Yes (build.toml) | Yes (PKGBUILD) | No (binary only) |
| Pre-built binary download | Yes (build.toml download) | Partial | Yes |