feat(deps/bootstraps/installs/updates): Add Nix flake for cross-platform install + dev shell. PLEASE 🙏#1118
Conversation
apps.default — nix run github:.../PAI
packages.default — same, as a derivation
devShells.default — nix develop, FHS-shaped on Linux (incl. WSL),
plain mkShell on macOS
Linux uses pkgs.buildFHSEnv with appimageTools.defaultFhsEnvArgs so
the bundled Electron GUI installer finds its libs. The runScript
mirrors README 'Manual install': cp Releases/v5.0.0/.claude into
$HOME/.claude, then exec the bundled installer.
|
Made this as a compromise after seeing an immediate libc error when trying out PAI 5. It changes no underlying logic for now and solves installation, at least for me :) Love what you're doing and just trying to help anyway I can without getting in the way of rapid iteration seeing this is a sharp alpha release ❤️ |
|
It's a middle-ground since people can still choose to install imperatively through their Ubuntu's and Homebrews (🤮) and pollute their userspace with node modules and non-human intents, so at the very least this PR can just be thought as a developer shell for PAI. |
|
I also have strong opinions about literate programming and how all code and markdown literature should be interleaved with one another and that this is the gateway into companies being an easily traversable wiki with state machines generated from the wiki itself aka a graph of algorithms. Maybe one day I can refactor this into markdown... |
|
Hey @zitongcharliedeng, thanks for raising this, and sorry it sat for a while. We're changing how LifeOS ships. Instead of cloning a full That's aimed right at what you hit here. The old "one directory, one layout, hope it matches your setup" approach is exactly what broke for so many people, and the new model should handle it far better because your AI does the integration per machine instead of us guessing. So we're closing this in prep for that release. If it still bites you once the skill-based version is out, reopen or file a fresh one and we'll jump on it. Appreciate you taking the time. |
FIXES ISSUES RELATED TO (i.e.):
Unreliable installs across operating systems:
Electron installer fails at libnss3.so #708 — Electron installer fails at libnss3.so (closed; same class as our libglib2)
Installer Silently Fails Due to Missing unzip Dependency #856 — Installer Silently Fails Due to Missing unzip Dependency (closed)
Installation Error on v4.0.1-v4.0.3 (fresh install) #848 — Installation Error on v4.0.1–v4.0.3 (fresh install)
error during installation from scratch (Ubuntu-24.04 wsl) #1117 — error during installation from scratch (Ubuntu-24.04 wsl)
Unable to install PAI on an Ubuntu WSL instance #438 — Unable to install PAI on an Ubuntu WSL instance
Failed install with Claude Code on Windows #440 — Failed install with Claude Code on Windows
Run on Windows without recoding bits and pieces? #543 — Run on Windows without recoding bits and pieces?
Interrupted install creates multiple Bun alias entries in environment file #954 — Interrupted install creates multiple Bun alias entries
Shell alias (pai): Not found — run: source ~/.zshrc #977 — Shell alias (pai): Not found — run: source ~/.zshrc
bad instructions after installation with fish shell #1053 — bad instructions after installation with fish shell
First install -- says it's upgrading, and doesn't find Claude Code #1088 — First install — says it's upgrading, and doesn't find Claude Code
4.0.3: install.sh crashes on headless Linux — hardcodes --mode gui with no display detection #912 — install.sh crashes on headless Linux — hardcodes --mode gui
Installer doesn't fall back to CLI mode in headless/SSH environments (v3.0) #755 — Installer doesn't fall back to CLI mode in headless/SSH (closed)
Unreliable updates / idempotency:
4.0.3 upgrade overwrites configured settings.json with template placeholders #893 — 4.0.3 upgrade overwrites configured settings.json with template placeholders
feat: Local patch tracking and update-safe SYSTEM file management #650 — Local patch tracking and update-safe SYSTEM file management
TOOL enhance, feat: Add
diff,backup --user-only, andmigrate --autofor safer PAI release updates #973 — TOOL enhance: diff, backup --user-only, migrate --auto for safer release updatesPreserve user preferences (YouTube channels, etc.) across version upgrades #439 — Preserve user preferences across version upgrades (closed)
PAI upgrade skill points to wrong folder #1080 — PAI upgrade skill points to wrong folder
SecurityValidator hook runs in fail-open mode after v4.0 install: PAISECURITYSYSTEM patterns not migrated #967 — SecurityValidator runs in fail-open mode after v4.0 install: patterns not migrated
Dependency hell on different OSes:
Installer Silently Fails Due to Missing unzip Dependency #856 — missing unzip (closed)
Electron installer fails at libnss3.so #708 — libnss3 (closed)
VoiceServer: afplay (macOS-only) breaks audio on Linux — silent failure #855 — VoiceServer: afplay (macOS-only) breaks audio on Linux
v3.0 VoiceServer has hard macOS dependencies — no Linux support #685 — v3.0 VoiceServer has hard macOS dependencies — no Linux support
statusline-command.sh uses macOS-only stat syntax, breaks on Linux/WSL #495 — statusline-command.sh uses macOS-only stat syntax (closed)
statusline-command.sh v3.0: stat -f %m regression on Linux/WSL (was #495) #679 — stat -f %m regression on Linux/WSL (closed)
statusline-command.sh silently shows empty defaults when jq is missing (common on fresh Linux/WSL installs) #1065 — statusline-command.sh silently shows empty defaults when jq is missing
Windows/MSYS: Bun.stdin.text() doesn't work - hooks fail silently #385 — Windows/MSYS: Bun.stdin.text() doesn't work — hooks fail silently
Linux compatibility (headless, shell, statusline) #849 — Linux compatibility (headless, shell, statusline) (closed)
The need for dependency checks and per-OS install advice at all.
Today install.sh has to detect whether bun is present, offer to
install it, fall back when it isn't, then re-detect after — and emit
"On Debian/Ubuntu run apt-get install …" hints branched per distro
— all because the runtime is whatever the user happens to have. Nix
makes the runtime guaranteed; the whole detect/offer/fallback dance
and the per-OS advice disappear together.
The need for a separate, website-only wrapper script at all. As a
natural consequence of the previous bullet, today there has to be a
script at https://ourpai.ai/install.sh whose job is exactly to do
the prereq-checking, the bun-installing, the ~/.claude → backup mv,
and the tarball fetch — i.e. all the work that exists ONLY because
the runtime isn't defined. With Nix, none of that work exists, so
no separate wrapper is needed: the website can simply say "run
nix run github:.../PAI". And as a side win this also closes thegap that the current website wrapper is, for some reason, nowhere
version-tracked on the PAI repo — the README links to a live URL
with no git history. With this PR, the install path is
flake.nixin the repo: source-controlled, signed by your own commits,
reviewable in PRs.
Agnosticism (longer-term goal). No direct issues — this is the
larger arc. I look forward to the day we break free from Anthropic.
This PR is one precondition: a defined, portable runtime environment
is what lets PAI's runtime be swapped (Claude Code → Pi → another
agent layer) without distro-by-distro breakage every time.
I BEG YOU TO CONSIDER MR MIESSLER!
A big hole in PAI I've noticed whenever trying out your features (and
why I haven't moved from my personal lightweight Pi-Mono DA yet) is
the lack of idempotency. We have workarounds like LLM-driven adaptive
updates — but really, in your own words, determinism is the default
when we can make it so. It makes it easier for consumers and
developers to work on PAI together.
The current
curl … | bashis presented as a one-line install but itisn't really one. It leaves the prerequisite story to chance: the
script itself has to detect whether bun is present, offer to install
it, fall back gracefully when it isn't — all because the runtime
environment is whatever the user happens to have. That work shouldn't
live in a shell script. With Nix it disappears:
bun,curl,rsync,git, plus the FHS libs Electron needs, are all guaranteedby the runtime — the installer doesn't have to ask, doesn't have to
offer, doesn't have to fall back. THAT'S a true one-line install.
This is also a forcing function for cleaner architecture. Once Nix is
the install path,
node_modules/can move into the immutable store(out of
~/.claude/PAI/PAI-Install/electron/and out of the user'shome), upgrades become atomic via
nix flake update, rollback is onecommand, and the whole "did the curl piped script run cleanly?"
question goes away — the closure is content-addressed and pinned in
flake.lock.Journey is identical, only the bootstrap shrinks
The user experience from the inner installer onward — banners, DA
identity setup, voice, Pulse — is unchanged. The only differences are
in the outer bootstrap:
bun, curl, rsync, git, bash, plus the FHS libs Electron needs.
the source. Tarball download is redundant.
(place release at ~/.claude/) happen exactly the same way, just
without the
▸ 2/5/▸ 4/5ceremony around them.same banner, same prompts.
What disappears is exactly the part that was leaving outcome to
chance — what the user happens to have installed, what their distro
ships by default, whether the bun installer succeeds non-interactively.
What this adds
A single new file (
flake.nix) exposing:nix run github:danielmiessler/Personal_AI_Infrastructure— installsPAI on any Nix-supporting system (macOS, regular Linux, NixOS, WSL)
with one command, no prereq install, no
curl | bash.nix develop github:danielmiessler/Personal_AI_Infrastructure—drops hackers into a shell with bun/curl/rsync/git/bash + (on Linux)
the FHS libs PAI's bundled Electron GUI needs (libglib2, GTK, NSS,
etc.).
Existing install paths (
curl | bash, manual clone) are unchanged.Why this PR exists
Non-Nix install paths today:
curl -sSL https://ourpai.ai/install.sh | bash— fails on NixOS atstep 5/5 with
libglib-2.0.so.0: cannot open shared object filebecause PAI's bundled Electron expects an FHS userspace.
The Nix flake wraps the install in
pkgs.buildFHSEnvwithpkgs.appimageTools.defaultFhsEnvArgs(nixpkgs-curated, community-maintained dep list for desktop Electron-shaped apps). No hand-rolled
library list, no per-distro install hints, no "On Debian/Ubuntu run
apt-get install …" branches. The FHS env covers any desktop Linux app
shape Electron might evolve into.
Forward-looking notes (not part of this PR)
this repo — the README links to the live URL with no git history. If
it lived in the repo (or was source-controlled somewhere visible),
the install path would be auditable, the Nix flake could mirror it
exactly, and the two paths could share code.
node_modules/andthe bundled Electron into the Nix store at derivation-build time, so
~/.claude/PAI/only contains user-mutable state (skills, agents,memory, DA identity, settings).
Tested
nix run --refresh github:zitongcharliedeng/PAI/nix-flakefrom asandbox HOME on NixOS:
/nix/store/...paths~/.claude.backup-{timestamp}, then cp Releases/v5.0.0/.claude →
~/.claude)
exercised in headless test, but FHS env is what fixes that case)
macOS not directly tested. Flake evaluates clean across all four
default systems; macOS branch is plain
writeShellApplicationwith noFHS wrap since Electron uses native frameworks there.