Skip to content

Install

Three ways in, in increasing order of commitment: the install script, a wheel from PyPI, or a source checkout. uv is the supported package manager for working on Punix; everything below the source section assumes uv is on your PATH.

Prerequisites

  • Python 3.13 or 3.14. The CI matrix tests both; earlier versions are not supported.
  • uv ≥ 0.5, for the source path only. Install via curl -LsSf https://astral.sh/uv/install.sh | sh or brew install uv.
  • POSIX shell + coreutils (mkdir, cp, mv, ln, rm). Standard on Linux and macOS.
  • For SSH deploys: ssh + rsync (any reasonably recent OpenSSH).
  • For multi-arch source builds: curl or wget (the fetcher uses a curl-class User-Agent; browser UAs hit anti-AI gateways).

Install

The script

curl -fsSL https://punix.lab.abilian.com/install.sh | sh

It prints what it will do and pauses before doing it.

From PyPI

pip install punix        # or: uv tool install punix

The wheel depends on cyclopts and tabulate, and nothing else: no compiler, no git, no evaluator you don't invoke. (MIXINv2 is a development dependency, used only by the dual-engine differential harness; see architecture.)

From source

git clone https://github.com/fermigier/punix-v2.git  # adjust to your fork
cd punix-v2
uv sync

uv sync resolves the dependency graph (everything from PyPI, no git sources) and creates a .venv. After that, uv run punix --help works. This is the path to take if you intend to change Punix; see contributing.

Run without activating the venv

Prefix every command with uv run:

uv run punix check stack.pcl
uv run punix build stack.pcl
uv run punix service deploy MyStack --file stack.pcl

Or activate it once:

source .venv/bin/activate
punix --help

Verify

uv run punix --help

You should see the top-level command list:

Usage: punix COMMAND

Punix v2 — typed declarative build & service deployer.

Commands:
  build       Check + build-closure pre-pass, then realise every package module.
  check       Type-check FILE only.
  help        Show the help overview, or a focused help page for TOPIC.
  info        Show recipe metadata and the predicted store path for MODULE.
  install     Build MODULE (cache-hit if already built) and link binaries into the profile.
  list        List installed packages.
  migrate     Migrate a Homebrew formula tree to a mirrored tree of PCL files.
  profile     Inspect and switch the active user profile (list/switch/diff).
  search      Search packages whose pname or description matches REGEX.
  service     Deploy and roll back service stacks (atomic via single os.replace).
  store       Content-addressed store queries.
  uninstall   Remove module from the active profile.
  upgrade     Report newer upstream versions for packages with meta.upstream.
  why         Print TARGET's resolved value and its provenance chain.

Get the package collection

Installing the punix CLI doesn't ship the recipe corpus. Before your first punix install, fetch the collection once:

punix packages sync

This clones the recipe tree into ~/.punix/packages/ (pinned to a revision) so punix install, search, info, and friends resolve against it from any directory. Re-run it to update; check what you have with punix packages status. Point it at a different collection or pin with [packages] in ~/.punix/config.toml or the --url / --rev flags; see punix help collections.

If you're working inside a Punix source checkout, this step is optional: a local packages/official/ tree is discovered automatically.

If you get command not found, your shell can't see uv's virtualenv; use uv run punix --help instead.

Run the test suite (optional)

Before relying on Punix, confirm the conformance suite passes on your box:

make test         # uv run pytest
make check        # ruff + ty + pyrefly + mypy
nox -s tests      # the full matrix (3.13 + 3.14)

All tests should pass. The conformance suite (tests/c_e2e/test_conformance_stage*.py) is the executable spec; a failure there means a property this site claims does not hold on your box.

SSH-only: localhost sshd fixture

The SSH e2e tests spin up a real sshd on a free port. They auto-skip if sshd / ssh-keygen aren't on PATH. On macOS /usr/sbin/sshd ships with the OS; on Linux:

sudo apt install openssh-server   # Debian/Ubuntu
sudo dnf install openssh-server   # Fedora

No daemon needs to be running: the fixture starts its own per-test.

Common install issues

uv sync fails resolving a dependency

Every dependency, including the mixinv2 dev dependency, resolves from PyPI; there are no git sources and no [tool.uv.sources] entries. A resolution failure signals a network or index problem. There is no pin to adjust. (Earlier releases did pin MIXINv2 by git rev; if you are following an old copy of these instructions, drop the [tool.uv.sources] block.)

Python 3.12 or earlier

Not supported. Punix uses 3.13-specific typing features (PEP 695 type statement, TypeAliasType). Upgrade or use uv's --python flag: uv sync --python 3.13.

macOS BSD vs GNU coreutils

Punix targets POSIX. macOS mv, ln, cp all work. One historical snag was mv -T (GNU-only) for the atomic symlink flip; now removed (see decisions).

Next

Your first build: a single-package PCL module, realised into the content-addressed store.