Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

pith pkg

Local-first package management across three isolated scopes.

Commands

pith pkg install [--global|--global-root]
pith pkg sync    [--global|--global-root]
pith pkg add <name> <version>
pith pkg                          # status report

Scopes

ScopeFlagInstall rootBinaries dir
Local (default),<cwd>/.pith/pkgs/<name>@<ver>/(none)
User global--global~/.pith/pkgs/<name>@<ver>/~/.pith/bin/
Machine root--global-root/usr/local/pith/pkgs//usr/local/bin/

Local (default)

Hermetic to the current project. Installs into <cwd>/.pith/pkgs/ and updates <cwd>/pith.lock. Nothing touches the global system.

User global (--global)

No elevated privileges required. Installs into ~/.pith/pkgs/ and symlinks any package-provided executables into ~/.pith/bin/.

Machine root (--global-root)

Requires root. Checks geteuid(), if not 0, re-executes the command via sudo (or fails with a clear error if sudo is unavailable). Installs into /usr/local/pith/pkgs/ and copies tools into /usr/local/bin/.

On Windows NT: checks token elevation via OpenProcessToken and GetTokenInformation, relaunching via ShellExecuteExW with the runas verb to trigger the UAC prompt.

Sources

Packages resolve from (in order):

  1. PITH_REGISTRY, a local directory of tarballs (<name>-<ver>.tar or compiled plugin bundles <name>-<ver>.ppkg)
  2. Already-installed scopes (user, then machine root)
  3. A path directly in pith.toml (e.g., mylib = "./libs/mylib" or a plugin bundle myplugin = "./dist/myplugin.ppkg")

Remote fetching is not implemented in v0.1, the local-first design means the cache is consulted before anything external.

Installing pith plugins (.ppkg)

A .ppkg (a plugin built with pith build --plugin) installs like a tar bundle: it is unpacked into the scope directory, giving plugin.o (the compiled, author-namespaced object) and manifest (the symbol table).

pith pkg: installed myplugin@/path/myplugin.ppkg -> .pith/pkgs/myplugin@...
pith pkg: 1 package installed

Consuming projects list the plugin under [dependencies]; their builds read the manifest, register the plugin’s namespace (<author>.<module>.*), and link the plugin’s object. The plugin’s functions are then callable as <author>.<module>.<fn>:

if alice.myos.identifyKernel == 42
    print "plugin works"
end

See pith build for building plugins and Namespaces for the resolution rules.

pith pkg install

Installs all [dependencies] from pith.toml into the selected scope. If a package provides an executable matching its name, that tool is symlinked (or copied on NT) into the scope’s binaries dir.

pith pkg sync

Reads [dependencies], checks which are already installed in the target scope, verifies their integrity against pith.lock (FNV-1a hash), installs missing ones, and writes pith.lock.

pith pkg: os-utils@1.0.0 ok (verified)
pith pkg: synced mylib@0.1.0 -> /path/.pith/pkgs/mylib@0.1.0
pith pkg: sync complete (2 packages)

pith pkg add

pith pkg add <name> <version>

Appends the dependency to pith.toml under [dependencies] and invokes sync (local scope).

pith.lock

Generated by sync/install. Records resolved versions with FNV-1a integrity hashes over the package contents (file paths + file bytes):

# pith.lock, concrete resolved dependencies (generated by pith pkg)
os-utils@1.0.0 9c35886d5a608143

On subsequent syncs, installed packages are re-hashed and compared against the lock, mismatches are reported as unverified.