Merge pull request #2 from harivansh-afk/linux

linux
This commit is contained in:
Hari 2026-03-22 14:50:37 -04:00 committed by GitHub
commit 9994efaef9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
14 changed files with 329 additions and 303 deletions

101
README.md
View file

@ -1,27 +1,17 @@
# Nix Config
## Approach
This repo is the source of truth for the machine's reproducible developer
environment:
- `home/` contains the Home Manager modules for user-facing tools
- `config/` contains the repo-owned config trees copied from your daily setup
- `modules/` contains host-level `nix-darwin` policy and package layers
- `modules/homebrew.nix` is intentionally narrow and only exists for GUI apps
that are still easier to keep in Brew on macOS
- `home/migration.nix` contains one-time ownership handoff logic from `~/dots`
into Home Manager so the steady-state modules can stay focused on real config
## Layout
- `flake.nix`: top-level flake and host wiring
- `hosts/hari-macbook-pro/default.nix`: this machine's host config
- `hosts/darwin/default.nix`: macOS nix-darwin host config
- `hosts/linux/default.nix`: standalone Linux Home Manager host config
- `modules/base.nix`: Nix settings and core packages
- `modules/macos.nix`: macOS defaults and host-level settings
- `modules/packages.nix`: system packages and fonts
- `modules/homebrew.nix`: the remaining Homebrew-managed GUI apps
- `home/`: Home Manager modules for shell, editor, CLI tools, and app config
- `home/common.nix`: shared Home Manager imports used by macOS and Linux
- `home/linux.nix`: Linux Home Manager entrypoint
- `home/migration.nix`: transitional cleanup for old `~/dots` symlinks
- `config/`: repo-owned config files consumed by Home Manager
@ -34,15 +24,7 @@ environment:
`~/Library/Application Support` state are intentionally outside declarative
Nix ownership
## Dedicated Inputs
Most tools come from `nixpkgs`. Fast-moving CLIs that you want to update on
their own cadence are pinned as dedicated flake inputs:
- `googleworkspace-cli`
- `claudeCode`
Bitwarden note:
## Bitwarden note:
- `bw` is installed via Homebrew as `bitwarden-cli`
- `bws` is not currently managed in this repo because I did not find a
@ -51,76 +33,3 @@ Bitwarden note:
via `just secrets-sync`
- vault items are currently the source of truth for imported machine secrets and
SSH material
## Commands
First switch:
```bash
nix run github:LnL7/nix-darwin/master#darwin-rebuild -- switch --flake .#hari-macbook-pro
```
After the first successful switch:
```bash
just switch
just build
just check
```
Update everything pinned by the flake:
```bash
nix flake update
just switch
```
Update only Codex or Claude:
```bash
nix flake lock --update-input claudeCode
just switch
```
Update Codex:
```bash
brew upgrade --cask codex
just switch
```
Sync Bitwarden-backed shell secrets:
```bash
export BW_SESSION="$(bw unlock --raw)"
just secrets-sync
```
Restore file-based secrets from Bitwarden:
```bash
export BW_SESSION="$(bw unlock --raw)"
just secrets-restore-files
```
## What Still Needs Manual Handling
- Promoting vault-backed secrets into Bitwarden Secrets Manager machine-account
flows, if you want fully non-interactive sandbox secret injection later
- App state under `~/Library/Application Support`
- Anything that depends on local credentials, keychains, or encrypted stores
- Manual cleanup of old non-Nix installs that are no longer wanted
## Current Homebrew Scope
The current Homebrew boundary is only:
- `cap`
- `codex`
- `raycast`
- `riptide-dev`
- `thebrowsercompany-dia`
- `wispr-flow`
Homebrew activation is currently `cleanup = "uninstall"`, so anything outside
that list is treated as drift and removed on `darwin-rebuild switch`.

View file

@ -1,5 +1,5 @@
{
description = "Rathi's macOS nix-darwin + Home Manager config";
description = "Rathi's macOS nix-darwin + Linux Home Manager config";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
@ -38,18 +38,29 @@
nix-homebrew,
...
}: let
system = "aarch64-darwin";
darwinSystem = "aarch64-darwin";
linuxSystem = "x86_64-linux";
username = "rathi";
hostname = "hari-macbook-pro";
pkgs = import nixpkgs {inherit system;};
darwinConfigName = "darwin";
darwinMachineHostname = "hari-macbook-pro";
linuxConfigName = "linux";
darwinPkgs = import nixpkgs {system = darwinSystem;};
linuxPkgs = import nixpkgs {
system = linuxSystem;
config.allowUnfree = true;
};
in {
formatter.${system} = pkgs.alejandra;
formatter.${darwinSystem} = darwinPkgs.alejandra;
formatter.${linuxSystem} = linuxPkgs.alejandra;
darwinConfigurations.${hostname} = nix-darwin.lib.darwinSystem {
inherit system;
specialArgs = {inherit inputs self username hostname;};
darwinConfigurations.${darwinConfigName} = nix-darwin.lib.darwinSystem {
system = darwinSystem;
specialArgs = {
inherit inputs self username;
hostname = darwinMachineHostname;
};
modules = [
./hosts/${hostname}
./hosts/${darwinConfigName}
home-manager.darwinModules.home-manager
nix-homebrew.darwinModules.nix-homebrew
{
@ -57,7 +68,10 @@
home-manager.useGlobalPkgs = true;
home-manager.useUserPackages = true;
home-manager.extraSpecialArgs = {inherit inputs self username hostname;};
home-manager.extraSpecialArgs = {
inherit inputs self username;
hostname = darwinMachineHostname;
};
home-manager.backupFileExtension = "hm-bak";
home-manager.users.${username} = import ./home;
@ -70,5 +84,16 @@
}
];
};
homeConfigurations.${linuxConfigName} = home-manager.lib.homeManagerConfiguration {
pkgs = linuxPkgs;
extraSpecialArgs = {
inherit inputs self username;
hostname = linuxConfigName;
};
modules = [
./hosts/${linuxConfigName}
];
};
};
}

24
home/common.nix Normal file
View file

@ -0,0 +1,24 @@
{...}: {
imports = [
./bat.nix
./eza.nix
./claude.nix
./codex.nix
./fzf.nix
./gcloud.nix
./gh.nix
./ghostty.nix
./git.nix
./k9s.nix
./lazygit.nix
./migration.nix
./nvim.nix
./scripts.nix
./tmux.nix
./zsh.nix
];
home.stateVersion = "24.11";
programs.home-manager.enable = true;
xdg.enable = true;
}

View file

@ -1,26 +1,7 @@
{...}: {
imports = [
./bat.nix
./eza.nix
./claude.nix
./codex.nix
./fzf.nix
./gcloud.nix
./gh.nix
./ghostty.nix
./git.nix
./common.nix
./karabiner.nix
./k9s.nix
./lazygit.nix
./migration.nix
./nvim.nix
./rectangle.nix
./scripts.nix
./tmux.nix
./zsh.nix
];
home.stateVersion = "24.11";
programs.home-manager.enable = true;
xdg.enable = true;
}

View file

@ -1,5 +1,6 @@
{
config,
lib,
pkgs,
...
}: let
@ -38,8 +39,10 @@
keybind = vim/i=deactivate_key_table
keybind = vim/catch_all=ignore
mouse-hide-while-typing = true
macos-titlebar-style = hidden
macos-option-as-alt = true
${lib.optionalString pkgs.stdenv.isDarwin ''
macos-titlebar-style = hidden
macos-option-as-alt = true
''}
confirm-close-surface = true
window-title-font-family = VictorMono NFM Italic
window-padding-balance = true
@ -52,7 +55,10 @@
in {
programs.ghostty = {
enable = true;
package = pkgs.ghostty-bin;
package =
if pkgs.stdenv.isDarwin
then pkgs.ghostty-bin
else pkgs.ghostty;
installBatSyntax = true;
};
@ -64,8 +70,10 @@ in {
xdg.configFile."ghostty/themes/cozybox-dark".text = theme.renderGhostty "dark";
xdg.configFile."ghostty/themes/cozybox-light".text = theme.renderGhostty "light";
home.file."Library/Application Support/com.mitchellh.ghostty/config.ghostty" = {
text = ghosttyConfig;
force = true;
home.file = lib.mkIf pkgs.stdenv.isDarwin {
"Library/Application Support/com.mitchellh.ghostty/config.ghostty" = {
text = ghosttyConfig;
force = true;
};
};
}

View file

@ -1,4 +1,12 @@
{...}: {
home.file."Library/Application Support/lazygit/config.yml".source =
../config/lazygit/config.yml;
{
lib,
pkgs,
...
}: {
xdg.configFile."lazygit/config.yml".source = ../config/lazygit/config.yml;
home.file = lib.mkIf pkgs.stdenv.isDarwin {
"Library/Application Support/lazygit/config.yml".source =
../config/lazygit/config.yml;
};
}

5
home/linux.nix Normal file
View file

@ -0,0 +1,5 @@
{...}: {
imports = [
./common.nix
];
}

View file

@ -22,43 +22,53 @@
autosuggestion.enable = true;
syntaxHighlighting.enable = true;
shellAliases = {
co = "codex --dangerously-bypass-approvals-and-sandbox";
ca = "cursor-agent";
cc = "claude";
ch = "claude-handoff";
cl = "clear";
gc = "git commit";
gd = "git diff";
gk = "git checkout";
gp = "git push";
gpo = "git pull origin";
gs = "git status";
ld = "lumen diff";
lg = "lazygit";
nim = "nvim .";
sshnet = "ssh -i ~/.ssh/atlas-ssh.txt rathiharivansh@152.53.195.59";
tailscale = "/Applications/Tailscale.app/Contents/MacOS/Tailscale";
shellAliases =
{
co = "codex --dangerously-bypass-approvals-and-sandbox";
ca = "cursor-agent";
cc = "claude";
ch = "claude-handoff";
cl = "clear";
gc = "git commit";
gd = "git diff";
gk = "git checkout";
gp = "git push";
gpo = "git pull origin";
gs = "git status";
ld = "lumen diff";
lg = "lazygit";
nim = "nvim .";
sshnet = "ssh -i ~/.ssh/atlas-ssh.txt rathiharivansh@152.53.195.59";
# nix helpers
nr = "nix profile remove"; # nr <index> - remove from profile
ns = "nix search nixpkgs"; # ns <query> - search packages
nls = "nix profile list"; # nls - list installed profile packages
nrb = "sudo darwin-rebuild switch --flake ~/Documents/GitHub/nix"; # nrb - rebuild declarative config
nup = "nix flake update ~/Documents/GitHub/nix && sudo darwin-rebuild switch --flake ~/Documents/GitHub/nix"; # nup - update flake + rebuild
# nix helpers
nr = "nix profile remove"; # nr <index> - remove from profile
ns = "nix search nixpkgs"; # ns <query> - search packages
nls = "nix profile list"; # nls - list installed profile packages
}
// lib.optionalAttrs pkgs.stdenv.isDarwin {
tailscale = "/Applications/Tailscale.app/Contents/MacOS/Tailscale";
nrb = "sudo darwin-rebuild switch --flake path:$HOME/Documents/GitHub/nix#darwin"; # nrb - rebuild declarative config
nup = "nix flake update $HOME/Documents/GitHub/nix && sudo darwin-rebuild switch --flake path:$HOME/Documents/GitHub/nix#darwin"; # nup - update flake + rebuild
}
// lib.optionalAttrs pkgs.stdenv.isLinux {
nrb = "nix run github:nix-community/home-manager -- switch --flake path:$HOME/Documents/GitHub/nix#linux -b hm-bak"; # nrb - rebuild declarative config
nup = "nix flake update $HOME/Documents/GitHub/nix && nix run github:nix-community/home-manager -- switch --flake path:$HOME/Documents/GitHub/nix#linux -b hm-bak"; # nup - update flake + rebuild
};
envExtra = ''
if [[ -f "$HOME/.cargo/env" ]]; then
. "$HOME/.cargo/env"
fi
# Ghostty shell integration expects a resource directory; the Nix app
# bundle lives in the store instead of /Applications.
export GHOSTTY_RESOURCES_DIR="${pkgs.ghostty-bin}/Applications/Ghostty.app/Contents/Resources/ghostty"
export MANPAGER="nvim +Man!"
'';
envExtra =
''
if [[ -f "$HOME/.cargo/env" ]]; then
. "$HOME/.cargo/env"
fi
''
+ lib.optionalString pkgs.stdenv.isDarwin ''
# Ghostty shell integration expects a resource directory; the Nix app
# bundle lives in the store instead of /Applications.
export GHOSTTY_RESOURCES_DIR="${pkgs.ghostty-bin}/Applications/Ghostty.app/Contents/Resources/ghostty"
''
+ ''
export MANPAGER="nvim +Man!"
'';
initContent = lib.mkMerge [
(lib.mkOrder 550 ''
@ -88,7 +98,11 @@
[ -s "$HOME/.bun/_bun" ] && source "$HOME/.bun/_bun"
export BUN_INSTALL="$HOME/.bun"
export PNPM_HOME="$HOME/Library/pnpm"
export PNPM_HOME="${
if pkgs.stdenv.isDarwin
then "$HOME/Library/pnpm"
else "${config.xdg.dataHome}/pnpm"
}"
bindkey -v
typeset -U path PATH
path=(
@ -103,8 +117,10 @@
"/etc/profiles/per-user/${config.home.username}/bin"
"/run/current-system/sw/bin"
"/nix/var/nix/profiles/default/bin"
${lib.optionalString pkgs.stdenv.isDarwin ''
"/opt/homebrew/bin"
"/opt/homebrew/sbin"
''}
$path
)

21
hosts/linux/default.nix Normal file
View file

@ -0,0 +1,21 @@
{
inputs,
lib,
pkgs,
username,
...
}: let
packageSets = import ../../lib/package-sets.nix {inherit inputs lib pkgs;};
in {
imports = [
../../home/linux.nix
];
targets.genericLinux.enable = true;
home = {
inherit username;
homeDirectory = "/home/${username}";
packages = packageSets.core ++ packageSets.extras;
};
}

View file

@ -4,11 +4,21 @@ default:
check:
nix --extra-experimental-features 'nix-command flakes' flake check
build:
nix --extra-experimental-features 'nix-command flakes' build .#darwinConfigurations.hari-macbook-pro.system
build config='darwin':
#!/usr/bin/env bash
if [[ "{{config}}" == "darwin" ]]; then
nix --extra-experimental-features 'nix-command flakes' build path:.#darwinConfigurations.{{config}}.system
else
nix --extra-experimental-features 'nix-command flakes' run github:nix-community/home-manager -- build --flake path:.#{{config}}
fi
switch:
sudo env PATH="$PATH" nix --extra-experimental-features 'nix-command flakes' run github:LnL7/nix-darwin/master#darwin-rebuild -- switch --flake .#hari-macbook-pro
switch config='darwin':
#!/usr/bin/env bash
if [[ "{{config}}" == "darwin" ]]; then
sudo env PATH="$PATH" nix --extra-experimental-features 'nix-command flakes' run github:LnL7/nix-darwin/master#darwin-rebuild -- switch --flake path:.#{{config}}
else
nix --extra-experimental-features 'nix-command flakes' run github:nix-community/home-manager -- switch --flake path:.#{{config}} -b hm-bak
fi
fmt:
nix --extra-experimental-features 'nix-command flakes' fmt

139
lib/package-sets.nix Normal file
View file

@ -0,0 +1,139 @@
{
inputs,
lib,
pkgs,
}: let
gwsPackage =
inputs.googleworkspace-cli.packages.${pkgs.stdenv.hostPlatform.system}.default;
claudePackage =
inputs.claudeCode.packages.${pkgs.stdenv.hostPlatform.system}.default;
memex = pkgs.stdenvNoCC.mkDerivation rec {
pname = "memex";
version = "0.3.1";
src = pkgs.fetchurl {
url = "https://github.com/nicosuave/memex/releases/download/v${version}/memex-${version}-macos-arm64.tar.gz";
hash = "sha256-OIqT0xS+8vc0dQNi+YdDXLmN8V/7AT4Q/cnvbbhZ+3s=";
};
dontUnpack = true;
installPhase = ''
tar -xzf "$src"
install -Dm755 memex "$out/bin/memex"
'';
meta = {
description = "Fast local history search for Claude and Codex logs";
homepage = "https://github.com/nicosuave/memex";
license = lib.licenses.mit;
mainProgram = "memex";
platforms = lib.platforms.darwin;
};
};
graphite = pkgs.stdenvNoCC.mkDerivation rec {
pname = "graphite";
version = "1.7.20";
src = pkgs.fetchurl {
url = "https://github.com/withgraphite/homebrew-tap/releases/download/v${version}/gt-macos-arm64";
hash = "sha256-ho9VQw1ic3jhG3yxNwUL0W1WvNFku9zw6DQnGehs7+8=";
};
dontUnpack = true;
installPhase = ''
install -Dm755 "$src" "$out/bin/gt"
'';
meta = {
description = "Manage stacked Git changes and submit them for review";
homepage = "https://graphite.dev/";
license = lib.licenses.agpl3Only;
mainProgram = "gt";
platforms = lib.platforms.darwin;
};
};
worktrunk = pkgs.rustPlatform.buildRustPackage rec {
pname = "worktrunk";
version = "0.23.1";
src = pkgs.fetchurl {
url = "https://github.com/max-sixty/worktrunk/archive/refs/tags/v${version}.tar.gz";
hash = "sha256-cdQDUz7to3JkriWE9i5iJ2RftJFZivw7CTwGxDZPAqw=";
};
cargoHash = "sha256-DHjwNqMiVkWqL3CuOCITvyqkdKe+GOZ2nlMSstDIcTg=";
doCheck = false;
meta = {
description = "CLI for Git worktree management";
homepage = "https://worktrunk.dev";
license = with lib.licenses; [asl20 mit];
mainProgram = "wt";
platforms = lib.platforms.darwin;
};
};
in {
core = with pkgs; [
curl
fd
fzf
gnupg
go_1_26
jq
just
nodejs_22
python3
ripgrep
rustup
tree
uv
wget
zoxide
];
extras =
(with pkgs; [
awscli2
claudePackage
coreutils-prefixed
delta
diff-so-fancy
git-filter-repo
git-lfs
goose
google-cloud-sdk
gwsPackage
imagemagickBig
kind
kubectl
kubernetes-helm
lazygit
libpq
librsvg
llmfit
mise
minikube
ngrok
postgresql_17
redis
tailscale
terraform
texliveFull
yt-dlp
])
++ lib.optionals pkgs.stdenv.isDarwin [
graphite
memex
worktrunk
];
fonts = with pkgs; [
jetbrains-mono
nerd-fonts.symbols-only
];
}

View file

@ -1,8 +1,12 @@
{
inputs,
lib,
pkgs,
username,
...
}: {
}: let
packageSets = import ../lib/package-sets.nix {inherit inputs lib pkgs;};
in {
nix.enable = true;
nix.settings = {
@ -31,23 +35,7 @@
programs.zsh.enable = true;
environment.shells = [pkgs.zsh];
environment.systemPackages = with pkgs; [
curl
fd
fzf
gnupg
go_1_26
jq
just
nodejs_22
python3
ripgrep
rustup
tree
uv
wget
zoxide
];
environment.systemPackages = packageSets.core;
environment.variables = {
EDITOR = "nvim";

View file

@ -4,116 +4,8 @@
pkgs,
...
}: let
gwsPackage =
inputs.googleworkspace-cli.packages.${pkgs.stdenv.hostPlatform.system}.default;
claudePackage =
inputs.claudeCode.packages.${pkgs.stdenv.hostPlatform.system}.default;
memex = pkgs.stdenvNoCC.mkDerivation rec {
pname = "memex";
version = "0.3.1";
src = pkgs.fetchurl {
url = "https://github.com/nicosuave/memex/releases/download/v${version}/memex-${version}-macos-arm64.tar.gz";
hash = "sha256-OIqT0xS+8vc0dQNi+YdDXLmN8V/7AT4Q/cnvbbhZ+3s=";
};
dontUnpack = true;
installPhase = ''
tar -xzf "$src"
install -Dm755 memex "$out/bin/memex"
'';
meta = {
description = "Fast local history search for Claude and Codex logs";
homepage = "https://github.com/nicosuave/memex";
license = lib.licenses.mit;
mainProgram = "memex";
platforms = lib.platforms.darwin;
};
};
graphite = pkgs.stdenvNoCC.mkDerivation rec {
pname = "graphite";
version = "1.7.20";
src = pkgs.fetchurl {
url = "https://github.com/withgraphite/homebrew-tap/releases/download/v${version}/gt-macos-arm64";
hash = "sha256-ho9VQw1ic3jhG3yxNwUL0W1WvNFku9zw6DQnGehs7+8=";
};
dontUnpack = true;
installPhase = ''
install -Dm755 "$src" "$out/bin/gt"
'';
meta = {
description = "Manage stacked Git changes and submit them for review";
homepage = "https://graphite.dev/";
license = lib.licenses.agpl3Only;
mainProgram = "gt";
platforms = lib.platforms.darwin;
};
};
worktrunk = pkgs.rustPlatform.buildRustPackage rec {
pname = "worktrunk";
version = "0.23.1";
src = pkgs.fetchurl {
url = "https://github.com/max-sixty/worktrunk/archive/refs/tags/v${version}.tar.gz";
hash = "sha256-cdQDUz7to3JkriWE9i5iJ2RftJFZivw7CTwGxDZPAqw=";
};
cargoHash = "sha256-DHjwNqMiVkWqL3CuOCITvyqkdKe+GOZ2nlMSstDIcTg=";
doCheck = false;
meta = {
description = "CLI for Git worktree management";
homepage = "https://worktrunk.dev";
license = with lib.licenses; [asl20 mit];
mainProgram = "wt";
platforms = lib.platforms.darwin;
};
};
packageSets = import ../lib/package-sets.nix {inherit inputs lib pkgs;};
in {
environment.systemPackages = with pkgs; [
awscli2
claudePackage
coreutils-prefixed
delta
diff-so-fancy
git-filter-repo
git-lfs
goose
graphite
google-cloud-sdk
gwsPackage
kubernetes-helm
imagemagickBig
kind
kubectl
lazygit
libpq
librsvg
llmfit
memex
mise
minikube
ngrok
postgresql_17
redis
tailscale
terraform
texliveFull
worktrunk
yt-dlp
];
fonts.packages = with pkgs; [
jetbrains-mono
nerd-fonts.symbols-only
];
environment.systemPackages = packageSets.extras;
fonts.packages = packageSets.fonts;
}