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

1713
config/shell/p10k.zsh Normal file

File diff suppressed because it is too large Load Diff

75
config/shell/zshrc Normal file
View File

@@ -0,0 +1,75 @@
# =============================================================================
# .zshrc — Julian's Zsh configuration
# Generated from Pop!_OS "thinkpad" machine audit.
# =============================================================================
# This file is managed by the linux-provision repo.
#
# API keys and secrets are loaded from Bitwarden on shell startup.
# If Bitwarden is unlocked, keys are available immediately.
# If locked, bw-env fails silently and you just won't have env vars
# (run `bw && bw-env` when you need them).
#
# To set up: bw-env --setup (one-time interactive)
# See config/scripts/bw-env.sh for details.
# =============================================================================
# ---- Powerlevel10k instant prompt ----
# Must stay close to the top.
if [[ -r "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh" ]]; then
source "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh"
fi
# ---- PATH setup ----
export PATH=$HOME/bin:$HOME/.local/bin:/usr/local/bin:$PATH
# ---- Oh My Zsh ----
export ZSH="$HOME/.oh-my-zsh"
ZSH_THEME="powerlevel10k/powerlevel10zsh"
# ---- Plugins ----
plugins=(git zsh-autosuggestions)
source $ZSH/oh-my-zsh.sh
# ---- Custom Aliases ----
# Bluetooth hard reset (ath11k WiFi/Bluetooth adapter hang workaround)
alias bt-reset='rfkill block bluetooth && sleep 1 && rfkill unblock bluetooth && sleep 1 && systemctl restart bluetooth'
# ---- Key bindings ----
# Ctrl+Backspace → delete word before cursor
bindkey "^H" backward-kill-word
# ---- Powerlevel10k config ----
[[ ! -f ~/.p10k.zsh ]] || source ~/.p10k.zsh
# ---- NVM (Node Version Manager) ----
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"
# ---- Custom completions ----
fpath+=~/.zfunc; autoload -Uz compinit; compinit
# =============================================================================
# Secrets — API keys and tokens
# Loaded from Bitwarden on every shell start.
# Fetches the "Environment" item and exports all custom fields as env vars.
# Falls back silently if vault is locked or item doesn't exist.
#
# Prerequisites: bw (Bitwarden CLI), jq
# To set up:
# 1. bw login
# 2. bw unlock --raw > ~/.config/Bitwarden\ CLI/.session
# 3. Create a Bitwarden item named "Environment" (type: Secure Note)
# with custom fields for each API key (name = VAR_NAME, value = the_key)
# =============================================================================
if [ -z "${BW_SESSION:-}" ] && [ -f "$HOME/.config/Bitwarden CLI/.session" ]; then
export BW_SESSION=$(cat "$HOME/.config/Bitwarden CLI/.session")
fi
if [ -n "${BW_SESSION:-}" ]; then
eval "$(bw get item Environment 2>/dev/null | jq -r '
.fields[] | select(.type != 0) |
"export " + (.name | gsub(" "; "_")) + "=" + (.value | @sh)
' 2>/dev/null)" 2>/dev/null
fi

View File

@@ -0,0 +1,65 @@
# =============================================================================
# ~/.zshrc.local — API keys and secrets (EXAMPLE)
# ===== THIS FILE IS OPTIONAL =====
# The recommended approach is to store all secrets in Bitwarden and load
# them via bw-env.sh. See config/scripts/bw-env.sh for setup.
#
# If you prefer a plain file, copy this to ~/.zshrc.local and fill in
# your real keys. Then uncomment the "source ~/.zshrc.local" line in .zshrc.
#
# DO NOT commit this file to version control.
# =============================================================================
# From the Pop machine audit, Julian stores ~17 API keys in his env.
# Using Bitwarden (bw-env.sh) is the recommended approach because:
# - Keys are encrypted at rest (not in dotfiles)
# - Syncs across machines automatically
# - One source of truth
# - Cache falls back silently if vault is locked
# =============================================================================
# ---- AI API Keys ----
export GROQ_API_KEY="gsk_your_key_here"
export ANTHROPIC_API_KEY="sk-ant-your-key-here"
export GOOGLE_API_KEY="AIza-your-key-here"
export OPENCODE_API_KEY="sk-your-key-here"
# ---- LiteLLM Proxy ----
export OPENAI_BASE_URL="https://ai.julianprester.com"
export OPENAI_API_KEY="sk-your-key-here"
# ---- Calendar (CalDAV) ----
export CALDAV_URL="https://nc.julianprester.com/remote.php/dav"
export CALDAV_USERNAME="julian.prester@sydney.edu.au"
export CALDAV_PASSWORD="your-password-here"
# ---- Thunderbird API ----
export TB_API_HOSTS="thunderbird"
# ---- Zotero ----
export ZOTERO_KEY=""
# ---- Canvas LMS ----
export CANVAS_API_KEY="3156~your-key-here"
export CANVAS_API_URL="https://canvas.sydney.edu.au/"
# ---- Nextcloud ----
export NC_URL="https://nc.julianprester.com"
export NC_USERNAME="julian.prester@sydney.edu.au"
export NC_PASSWORD="your-password-here"
# ---- Actual Budget ----
export ACTUAL_URL="https://actual.your-domain.ts.net"
export ACTUAL_PASSWORD="your-password-here"
export ACTUAL_SYNC_ID="your-sync-id-here"
# ---- Tavily (web search API) ----
export TAVILY_API_KEY="tvly-your-key-here"
# ---- FreshRSS ----
export FRESHRSS_API_KEY="your-key-here"
# ---- Semantic Scholar ----
export SEMANTIC_SCHOLAR_API_KEY="your-key-here"
# ---- OpenAlex ----
export OPENALEX_API_KEY="your-key-here"