v0.8.0 · HackerOS Linux

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.

$ hpm install <package>

Overview #

Git-native Sandboxed Debian-compatible No binary archives Semver tags

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
Note hpm requires root (sudo) for install/remove operations because it writes to /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

CommandDescription
hpm refreshDownload 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 updateUpdate all non-pinned packages to their latest tagged version
hpm upgradeUpgrade hpm itself
hpm switch <pkg> <ver>Switch the active version of an installed package

Query Commands

CommandDescription
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 listList all installed packages and their versions
hpm outdatedShow 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

CommandDescription
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 cleanRemove 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):

LayerMechanismWhat it isolates
Namespacesuser, mount, UTS, PID, cgroupFilesystem view, process tree, hostname, control groups
NetworkCLONE_NEWNET (opt-in)Network stack — disabled by default
Pivot rootpivot_root(2)Root filesystem replaced with tmpfs + bind mounts
LandlockLandlock LSM v1Fine-grained filesystem access control
Resource limitssetrlimit(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 => ""
   }
Warning Setting 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:

my-package/
  ├── 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
Tip The 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

ConstraintMeaning
""Any version
=1.2.0Exactly 1.2.0
>=1.2.01.2.0 or newer
>1.2.0Strictly newer than 1.2.0
1.2.0Exactly 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"
Note Build commands run inside the hpm sandbox. The sandbox has access to /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"
    }
  }
}
Tip — versions field is optional You only need to add the "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 #

/usr/lib/HackerOS/hpm/store/
  └── 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