Dotfiles, powered by Nix and home-manager.
Shared choices go in mods/; machine differences go in homes/.
You do not need to read installer code to change your setup.
- npm/uv packages, including Scute:
mods/native-tools.nix. - Shared agent skills, settings, MCP and packages:
mods/agents/default.nix. Add skill sources tomods/agents/skills.nixand select shared ones inmods/agents/shared-skills.nix. - Common local models:
mods/model-runtimes.nix. - One machine: its
homes/home-*.nix. The Loancrate home explicitly importshomes/nicks-loancrate-mbp/agents.nixand declares its npm authentication and model overrides itself. - Nix-installed programs:
mods/base-packages.nix; sibling flake inputs are wired inflake.nixandlib/builders.nix. - Shell/editor configuration and authored agent assets:
mods/dotfiles/. Intentionally live links remain live; store-backed content requires a switch.
homes/profiles/ composes shared/platform modules; it no longer hides package,
agent or model selections. mods/internal/ contains option schemas, native
adapters, installer scripts/tests, and shared global-tools machinery. Edit it
only to change how configuration is realized. Installer code is bound to the
installed generation, not executed from your mutable checkout.
Routine workflow: edit configuration → validate → switch. Use global-tools status
to inspect the installed generation, or global-tools repair [component] for
native repair. Neither reads unswitched configuration edits or repairs Nix-owned
links. See the lifecycle contract for details.
Google Workspace access for agents uses gog and its shared skills.
See Google account setup for OAuth authorization and read-only
verification commands.
Run sys-update for help, or press Tab after sys-update to discover its commands.
Dependency commands use the monorepo's scripts/deps.ts from any directory:
sys-update list # list every dependency domain and its pins
sys-update check # check the dotfiles project's pins
sys-update pins nix-core # update and verify one domain, without switching
sys-update pins pi # update pinned Pi packagesChecks and pin updates default to --project dotfiles-nix. Pass another
--project NAME to change the scope. Review the diff and any changed agent
content before applying it with nixswitch. Standalone clones can still apply
configuration, but dependency commands require the monorepo checkout.
sys-update brew, sys-update nvim, and sys-update claude call their native updaters.
sys-update tools runs all three, skips tools that are absent, and reports failures
without stopping the remaining updates. Neovim sync rewrites lazy-lock.json;
Homebrew packages and Claude plugins are unpinned.
Activation and cleanup remain separate:
nixswitchapplies the current configuration without updating pins.nixswitchuppulls configuration changes, then applies them.nixcleandeletes old Nix generations and optimizes the store.
update-interactive walks through all of this with a yes/no question per
step (Enter means no). Each step first says what it changes and when that
takes effect, then shows its command and scope. Order:
- Pull the checkout with
git pull --ff-only. It runs first because pin updates dirty the tree, and it never merges, rebases, or autostashes. - Optionally run
sys-update check, thensys-update pins DOMAINfor each domain thatsys-update list --jsonreports underpub/dotfiles-nix. Majors stay held. A failed pull or pin update skips activation. - Review the whole checkout read-only:
git status --short(untracked paths are listed, never read),git diff --stat, and the full trackedgit diffagainst HEAD. Read changed skills and Pi packages before activating. - Activate with
nixswitch. Pulling already happened, sonixswitchupwould only pull a second time. - Update
brew,nvim, andclaudeone at a time, after activation soglobal-toolsis the new generation's andnvimrewrites a tracked lockfile only after the pull. Neversys-update tools. - Optionally
nixclean, which deletes old rollback generations. It is skipped after a failed activation.
Failures are reported with their scope, later steps still run, and the exit status is 1 if any action failed. End of input aborts the run.
nix-channel --add https://github.com/nix-community/home-manager/archive/release-24.05.tar.gz home-manager nix-channel --update nixos-rebuild --flake .#supermicro switch
- Install Nix:
sh <(curl -L https://nixos.org/nix/install)
# install home manager
nix-channel --add https://github.com/nix-community/home-manager/archive/master.tar.gz home-manager
# nix-channel --add https://github.com/nix-community/home-manager/archive/release-24.05.tar.gz home-manager
nix-channel --update
nix-shell '<home-manager>' -A install
# install homebrew
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"-
Get this flake onto the machine. Two ways to do it, depending on where you're applying from:
Standalone clone (anyone cloning just this repo):
mkdir ~/.config && cd ~/.config && \ git clone https://github.com/napisani/dotfiles-nix.git home-manager && cd home-manager
From the napisani/monorepo checkout (this flake lives at
pub/dotfiles-nix/there and gets mirrored to this repo on every push tomain):mkdir -p ~/code && cd ~/code && \ git clone git@github.com:napisani/monorepo.git && cd monorepo/pub/dotfiles-nix
Each host's flake config sets its own
homeManagerRelPath(seeflake.nix/lib/builders.nix) so out-of-store symlinks and thenixswitch*functions resolve to wherever you actually checked this out — no extra config needed beyond cloning to the expected path for that host. -
one-time build of the
darwin-rebuildbinary
export MY_HOST=nick-mb
nix build --extra-experimental-features "nix-command flakes" .#darwinConfigurations.$MY_HOST.system- Then apply the nix flake:
./result/sw/bin/darwin-rebuild switch --flake ./.#-
set the shell go to the 'settings' app -> then go to 'users and groups' -> right click on your user and click "advanced settings". finally, set the shell to the last
bashoption -
Open tmux with
tmuxand install plugins using<leader> + I -
Open tmux with
tmuxand install finger/thumbs using<leader>+space- choose 'compile' -
Open new vim with command
nvim. Let the plugins install, ignore all of the errors. -
Reopen neovim and run the following commands:
:Lazy
:TSUpdate
:MasonUpdate
:Copilot
- doppler auth and gh auth
# allow doppler to install a new version - then follow the instructions to login
sudo doppler login
# follow the instructions to login
gh auth login
# install the copilot extension
gh extension install github/gh-copilotHelpful github issue thread for diagnosing any initial Karabiner problems:
https://github.com/LnL7/nix-darwin/issues/564
- setup the two 18tb drives using zfs
https://nixos.wiki/wiki/ZFS
fdisk -l
# format the drives
fdisk /dev/sda
fdisk /dev/sdb
# p - print
# g - create a new GPT partition table
# w - write the changes
# n - new partition
# --- use defaults for the entire disk
# w - write the changes
# create the zpool with compression on
# enable acltype=posixacl to allow for linux style ACLs
# enable xattr=sa to store extended attributes in the inode
# ashift=12 is the default for 4k sector drives
zpool create -O compression=on -O mountpoint=none -O xattr=sa -O acltype=posixacl -o ashift=12 storagepool mirror /dev/sda1 /dev/sdb1
zfs create -o mountpoint=legacy storagepool/storage
sudo zfs set acltype=posixacl storagepool/storage
sudo zfs set aclinherit=discard storagepool/storage
sudo zfs set aclmode=discard storagepool/storage
sudo zfs get acltype,aclinherit,aclmode storagepool/storage
sudo zfs set aclmode=discard storagepool/storage
mount -t zfs storagepool/storage /media/storage