Initial commit: linux-provision repo

Distribution-agnostic provisioning script that sets up a new Linux machine
(Detected via lib/distro.sh - supports Debian/Ubuntu/Pop and Fedora families).

13 stages covering:
- System packages, external repos, toolchains (nvm, uv, Python)
- Shell config (zsh, oh-my-zsh, p10k), git, SSH
- Custom uv tools from ~40 git repos
- Desktop config (keybindings, hotkeys, ghostty, fonts)
- Docker, system tweaks, browser/app installs
- Custom systemd user services (porridge, swayidle, mempi-sync, etc.)
- API keys loaded from Bitwarden at shell startup
This commit is contained in:
2026-06-05 21:21:46 +10:00
commit 180c5838ea
36 changed files with 4176 additions and 0 deletions

102
stages/03-toolchains.sh Normal file
View File

@@ -0,0 +1,102 @@
#!/usr/bin/env bash
# ===========================================================================
# Stage 03: Language Toolchains
# Installs nvm + Node.js LTS, uv (Python), and sets up the toolchain.
# ===========================================================================
# On Pop/Ubuntu these are post-system-package installs.
# Fedora packages for Node/python are available but we use version managers
# for flexibility (nvm for Node, uv for Python).
# ===========================================================================
# ---- nvm + Node.js ----
# nvm is installed to ~/.nvm. Node LTS is installed and set as default.
# This matches the Pop machine which had v24.11.1 via nvm.
info "Installing nvm (Node Version Manager)..."
if [ -d "$HOME/.nvm" ] && [ -f "$HOME/.nvm/nvm.sh" ]; then
ok "nvm already installed."
else
# Install latest nvm
# curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.2/install.sh | bash
# Use the install script from nvm's GitHub
export NVM_DIR="$HOME/.nvm"
curl -fsSL https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.2/install.sh | bash
ok "nvm installed."
fi
# Source nvm for this script
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"
# Install latest LTS Node
info "Installing Node.js LTS via nvm..."
nvm install --lts 2>/dev/null || {
warn "nvm install --lts failed. Trying specific version..."
nvm install 24 2>/dev/null || warn "Could not install Node via nvm."
}
nvm alias default 'lts/*' 2>/dev/null || true
ok "Node.js $(node --version 2>/dev/null || echo 'installed')"
# Install/update npm to latest
npm install -g npm@latest 2>/dev/null || true
ok "npm $(npm --version 2>/dev/null || echo 'installed')"
# ---- npm global packages ----
# Julian's daily tools: pi agent, browser automation, subagents
info "Installing npm global packages..."
npm install -g \
@earendil-works/pi-coding-agent \
agent-browser \
pi-subagents \
2>/dev/null || warn "Some npm global packages failed."
ok "npm global packages installed."
# ---- uv (Python toolchain) ----
# uv is the recommended Python package + project manager.
# On Pop: uv was installed standalone from astral.sh — binary lives in ~/.local/bin
# The binary is self-updating via 'uv self update'.
info "Installing uv (Python project manager)..."
if command -v uv &>/dev/null; then
ok "uv already installed: $(uv --version)"
# Self-update to latest
uv self update 2>/dev/null || true
else
curl -fsSL https://astral.sh/uv/install.sh | bash
# Ensure ~/.local/bin is in PATH
export PATH="$HOME/.local/bin:$PATH"
ok "uv installed: $(uv --version)"
fi
# Install system Python if not present (Fedora usually has it)
if ! command -v python3 &>/dev/null; then
info "Installing Python..."
pkg_install python3 python3-pip python3-devel 2>/dev/null || true
fi
# ---- uv tool installs (from PyPI) ----
# Julian's daily Python CLI tools, installed via uv.
info "Installing uv tools from PyPI..."
if command -v uv &>/dev/null; then
uv tool install markitdown 2>/dev/null && echo " markitdown" || warn " markitdown install failed."
uv tool install pre-commit 2>/dev/null && echo " pre-commit" || warn " pre-commit install failed."
uv tool install yq 2>/dev/null && echo " yq (tomlq, xq)" || warn " yq install failed."
ok "PyPI uv tools installed."
fi
# ---- (Optional) Rust toolchain ----
# The Pop machine did NOT have Rust installed. Uncomment if you want it.
# info "Installing Rust via rustup..."
# if command -v rustc &>/dev/null; then
# ok "Rust already installed: $(rustc --version)"
# else
# curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
# . "$HOME/.cargo/env"
# ok "Rust installed: $(rustc --version)"
# fi
# ---- (Optional) Go toolchain ----
# The Pop machine did NOT have Go installed. Uncomment if you want it.
# info "Installing Go..."
# sudo dnf install -y golang 2>/dev/null || warn "Go install failed."
# ok "Go installed: $(go version)"
ok "Stage 03 complete: language toolchains installed."