This is a Nix-managed dotfiles repository. The primary mechanism for all
configuration is a Nix flake (nix/flake.nix) that drives both
system-level setup (NixOS / nix-darwin) and user-level setup (Home Manager).
Almost everything — packages, shell config, git, tmux, editor wiring — is
declared in Nix. A few configurations live outside Nix as standalone trees that
are symlinked in by Home Manager.
make switch # rebuild and activate the current host's configuration
make update # update flake inputs (nixpkgs, home-manager, etc.)
make switch detects the OS and hostname and selects the right flake output
automatically.
nix/flake.nix pins the personalAssistant input (Pandeck) to a release tag
(?ref=refs/tags/vX.Y.Z) or an exact commit (?ref=<branch>&rev=<sha>), never
to a moving branch. That line plus flake.lock is the record of what devbox
runs, so:
make switchreproduces the deployed revision.make updatere-locks the same revision and cannot drag the assistant forward.- Neither restarts the assistant, and neither even changes its unit: the unit's
only store paths are the app package and its own drain script, both from the
app's flake.
restartIfChanged = falsestays as a belt so anything that does move the unit cannot interrupt an agent turn as a side effect. A restart means a deploy shipped. The flip side: a moved pin takes effect only aftersystemctl restart personal-assistant, whichmake pandeckdoes. - This host configures no packages for the assistant. No
extraPackages, no recognizer, no model. The agents' toolbox is this host's own profiles, which the service PATH ends in; the app declares what it needs in itsconfig/host-tools.jsonand fails its own boot if the host is below a floor. Optional capabilities (dictation, docker, java) are discovered and degrade with a reason.sherpa-onnxinenvironment.systemPackagesplusspeech.modelDiris what makes dictation possible — ordinary host config. - Nothing here reaches into the app flake for a package. The dictation weights
are ours:
nix/pkgs/stt-model-*.nix, our URL and our hash, wired through the overlay likegogcli/tempomatand handed tospeech.modelDir. It is afetchzipon purpose — a fixed-output path depends only on name and hash, somake updatecannot move it (verified against two unrelated nixpkgs revisions). Never turn it into amkDerivation: that is input-addressed and would churn the assistant's unit on every input update. - Nothing deploys automatically: the app's GitHub CI never reaches this host.
make pandeck REF=<tag|branch|sha>(defaultmain;scripts/pandeck-deploy) moves the pin, switches, commits the bump here (never pushes) and queues the app restart, which drains running agent turns first.make pandeck-statuscompares the pin with the latest release andmain. Sogit log nix/flake.lockis the deploy history, and rollback is deploying an older ref. - Agents can deploy, but only reviewed code. Agent sessions cannot sudo, so a
commit on
mainor a release tag switches through the root oneshotpandeck-deploy@<sha>.service(nix/modules/pandeck-deploy.nix), which a polkit rule lets thasso start. It fetches the public Pandeck repository itself, refuses anything not onmainor tagged, and rebuilds the dotfiles source the running system was built from with only the pin changed, so checkout edits still needmake switch. Unmerged branch commits switch this checkout with sudo: human only. Keep it that way: Pandeck's NixOS module is evaluated as root. make pandeckrefuses a target on an unmerged branch that changes migrations, and a target that lacks migrations the pinned commit already ran, unlessALLOW_MIGRATIONS=1: the data directory cannot un-run a migration, so either case needs aDATA_DIRbackup first.
nix/
├── flake.nix # Entry point — defines all hosts and wires Home Manager
├── flake.lock
├── pkgs/ # Custom package derivations
├── hosts/
│ ├── macbox/configuration.nix # nix-darwin (macOS aarch64)
│ ├── devbox/configuration.nix # NixOS (x86_64-linux, bare metal)
│ └── limabox/configuration.nix# NixOS (aarch64-linux, Lima VM on macOS)
└── home/
├── thasso.nix # Home Manager config — the bulk of user setup
└── zsh/p10k.zsh # Powerlevel10k prompt theme
- Three host configurations share a single Home Manager user config
(
home/thasso.nix). Platform differences are handled withlib.mkIf pkgs.stdenv.isDarwin/lib.optionals. home/thasso.nixis where most tools are configured: zsh, git, tmux, fzf, bat, eza, atuin, delta, ghostty, vscode, and opencode.- Packages are declared in
home.packagesinsidethasso.nix, not in the host configs (those only carry system-level concerns like bootloader, networking, SSH). - Overlays in
flake.nixaddclaude-codeto nixpkgs.
| What you're looking for | Where to look |
|---|---|
| Which packages are installed | nix/home/thasso.nix → home.packages |
| Shell aliases and env vars | nix/home/thasso.nix → programs.zsh, home.sessionVariables |
| Git configuration | nix/home/thasso.nix → programs.git |
| Tmux configuration | nix/home/thasso.nix → programs.tmux |
| Ghostty terminal config | nix/home/thasso.nix → programs.ghostty |
| OpenCode settings | nix/home/thasso.nix → programs.opencode |
| System-level config (boot, network, SSH) | nix/hosts/<hostname>/configuration.nix |
| Custom Nix packages | nix/pkgs/ |
These directories are not generated by Nix — they are maintained directly
and symlinked into place via home.file or xdg.configFile entries in
thasso.nix.
A full Lua-based Neovim setup using lazy.nvim. Symlinked to ~/.config/nvim.
Has its own nvim/AGENTS.md with detailed guidelines for plugin structure,
keybinding conventions, and the current stack.
opencode/agent/— Custom agent definitions (PM workflows, planning agents)opencode/command/— Slash commands (commit, review)
These are referenced from thasso.nix (programs.opencode.agents,
programs.opencode.commands).
Small shell scripts placed on $PATH via home.file:
Scripts and config for creating the NixOS Lima VM (limabox).
- Subject: short, imperative ("Add tmux split bindings", not "Added...")
- Body: explain the why and high-level intent, not line-by-line code changes
- Do NOT push upstream without explicit confirmation