From 8616e4811234151ebcad307ed14855079d2e1de5 Mon Sep 17 00:00:00 2001 From: Harivansh Rathi Date: Fri, 13 Mar 2026 11:39:29 -0400 Subject: [PATCH] updates --- .cache-home/nix/fetcher-cache-v4.sqlite | Bin 0 -> 135168 bytes README.md | 15 ++- home/zsh.nix | 9 +- justfile | 12 ++- modules/homebrew.nix | 13 +-- modules/packages.nix | 88 +++++++++++++++--- scripts/backup-machine.sh | 119 ++++++++++++++++++++++++ 7 files changed, 216 insertions(+), 40 deletions(-) create mode 100644 .cache-home/nix/fetcher-cache-v4.sqlite create mode 100755 scripts/backup-machine.sh diff --git a/.cache-home/nix/fetcher-cache-v4.sqlite b/.cache-home/nix/fetcher-cache-v4.sqlite new file mode 100644 index 0000000000000000000000000000000000000000..518af802c8202cecc3adffe16d11adbc49a09bad GIT binary patch literal 135168 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

@hmme6WA6A*1995w09B7^u;9BbI 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 literal 0 HcmV?d00001 diff --git a/README.md b/README.md index a8a7bc7..14e16f4 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ The repo now owns the active shell/editor/tool config directly: - `home/` contains the Home Manager modules for user-facing tools - `config/` contains the repo-owned config trees copied from your daily setup -- `modules/homebrew.nix` is intentionally narrow and should keep shrinking over time +- `modules/homebrew.nix` is intentionally narrow and should eventually disappear - Homebrew cleanup is still set to `"none"` so the first switch is non-destructive ## Layout @@ -16,7 +16,7 @@ The repo now owns the active shell/editor/tool config directly: - `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 apps and packages +- `modules/homebrew.nix`: the remaining Homebrew-managed GUI apps - `home/`: Home Manager modules for shell, editor, CLI tools, and app config - `config/`: repo-owned config files consumed by Home Manager @@ -42,4 +42,13 @@ just check - Launch agents that are currently outside Nix - App state under `~/Library/Application Support` - Anything that depends on local credentials, keychains, or encrypted stores -- Deciding whether the remaining Homebrew entries should stay there or be eliminated +- Replacing or intentionally dropping the remaining GUI apps still delivered via Homebrew + +## Current Homebrew Scope + +The current Homebrew boundary is only: + +- `cap` +- `raycast` +- `thebrowsercompany-dia` +- `wispr-flow` diff --git a/home/zsh.nix b/home/zsh.nix index 90228f5..3bd35be 100644 --- a/home/zsh.nix +++ b/home/zsh.nix @@ -57,13 +57,6 @@ '') (lib.mkOrder 1000 '' - export HOMEBREW_PREFIX="/opt/homebrew" - export HOMEBREW_CELLAR="/opt/homebrew/Cellar" - export HOMEBREW_REPOSITORY="/opt/homebrew" - export PATH="/opt/homebrew/bin:/opt/homebrew/sbin:$PATH" - export MANPATH="/opt/homebrew/share/man''${MANPATH+:$MANPATH}:" - export INFOPATH="/opt/homebrew/share/info:''${INFOPATH:-}" - if [[ -f ~/.config/secrets/shell.zsh ]]; then source ~/.config/secrets/shell.zsh elif [[ -f ~/.secrets ]]; then @@ -71,7 +64,7 @@ fi export PATH="$HOME/.local/bin:$PATH" - export PATH="${pkgs.postgresql_16}/bin:$PATH" + export PATH="${pkgs.postgresql_17}/bin:$PATH" export PATH="$HOME/.opencode/bin:$PATH" eval "$(zoxide init zsh)" diff --git a/justfile b/justfile index 9c64db7..182b281 100644 --- a/justfile +++ b/justfile @@ -2,14 +2,16 @@ default: just --list check: - nix flake check + nix --extra-experimental-features 'nix-command flakes' flake check build: - nix build .#darwinConfigurations.hari-macbook-pro.system + nix --extra-experimental-features 'nix-command flakes' build .#darwinConfigurations.hari-macbook-pro.system switch: - nix run github:LnL7/nix-darwin/master#darwin-rebuild -- switch --flake .#hari-macbook-pro + sudo env PATH="$PATH" nix --extra-experimental-features 'nix-command flakes' run github:LnL7/nix-darwin/master#darwin-rebuild -- switch --flake .#hari-macbook-pro + +backup: + ./scripts/backup-machine.sh fmt: - nix fmt - + nix --extra-experimental-features 'nix-command flakes' fmt diff --git a/modules/homebrew.nix b/modules/homebrew.nix index 83718ac..9195360 100644 --- a/modules/homebrew.nix +++ b/modules/homebrew.nix @@ -8,18 +8,9 @@ cleanup = "none"; }; - taps = [ - "nicosuave/tap" - "withgraphite/tap" - ]; + taps = []; - brews = [ - "nicosuave/tap/memex" - "postgresql@17" - "python@3.13" - "withgraphite/tap/graphite" - "worktrunk" - ]; + brews = []; casks = [ "cap" diff --git a/modules/packages.nix b/modules/packages.nix index a9d156f..575f200 100644 --- a/modules/packages.nix +++ b/modules/packages.nix @@ -1,21 +1,81 @@ { inputs, + lib, pkgs, - username, ... }: let - berkeleyMono = pkgs.stdenvNoCC.mkDerivation { - pname = "berkeley-mono"; - version = "local"; - src = /. + "/Users/${username}/Library/Fonts/BerkeleyMono-Regular.otf"; - dontUnpack = true; - installPhase = '' - install -Dm644 "$src" "$out/share/fonts/opentype/BerkeleyMono-Regular.otf" - ''; - }; - gwsPackage = inputs.googleworkspace-cli.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 { environment.systemPackages = with pkgs; [ codex @@ -24,6 +84,7 @@ in { diff-so-fancy git-filter-repo git-lfs + graphite google-cloud-sdk gwsPackage imagemagickBig @@ -31,17 +92,18 @@ in { libpq librsvg llmfit + memex mise ngrok - postgresql_16 + postgresql_17 redis tailscale terraform + worktrunk yt-dlp ]; fonts.packages = with pkgs; [ - berkeleyMono jetbrains-mono nerd-fonts.symbols-only ]; diff --git a/scripts/backup-machine.sh b/scripts/backup-machine.sh new file mode 100755 index 0000000..c19b67f --- /dev/null +++ b/scripts/backup-machine.sh @@ -0,0 +1,119 @@ +#!/usr/bin/env bash +set -euo pipefail + +umask 077 + +backup_root="${HOME}/Backups/nix-migration" +timestamp="$(date +%Y%m%d-%H%M%S)" +backup_dir="${1:-${backup_root}/${timestamp}}" + +mkdir -p "${backup_dir}/archives" "${backup_dir}/manifests" + +snapshot_log="$(tmutil localsnapshot 2>&1 || true)" +printf '%s\n' "${snapshot_log}" > "${backup_dir}/manifests/apfs-localsnapshot.log" +tmutil listlocalsnapshots / > "${backup_dir}/manifests/apfs-localsnapshots.txt" 2>&1 || true + +{ + printf 'created_at=%s\n' "$(date -u +%Y-%m-%dT%H:%M:%SZ)" + printf 'hostname=%s\n' "$(scutil --get HostName 2>/dev/null || hostname)" + printf 'local_host_name=%s\n' "$(scutil --get LocalHostName 2>/dev/null || true)" + printf 'computer_name=%s\n' "$(scutil --get ComputerName 2>/dev/null || true)" + printf 'repo_root=%s\n' "$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +} > "${backup_dir}/manifests/backup-meta.txt" + +sw_vers > "${backup_dir}/manifests/sw_vers.txt" +uname -a > "${backup_dir}/manifests/uname.txt" +df -h / /System/Volumes/Data /nix > "${backup_dir}/manifests/disk-usage.txt" + +if command -v brew >/dev/null 2>&1; then + brew bundle dump --file=- --force --describe > "${backup_dir}/manifests/Brewfile" 2> "${backup_dir}/manifests/brew-bundle.stderr" || true + brew list --formula --versions > "${backup_dir}/manifests/brew-formulae.txt" 2> "${backup_dir}/manifests/brew-formulae.stderr" || true + brew list --cask --versions > "${backup_dir}/manifests/brew-casks.txt" 2> "${backup_dir}/manifests/brew-casks.stderr" || true + brew services list > "${backup_dir}/manifests/brew-services.txt" 2> "${backup_dir}/manifests/brew-services.stderr" || true +fi + +if command -v nix >/dev/null 2>&1; then + nix --version > "${backup_dir}/manifests/nix-version.txt" 2>&1 || true +fi + +repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +git -C "${repo_root}" status --short > "${backup_dir}/manifests/nix-repo-status.txt" 2>&1 || true +git -C "${repo_root}" rev-parse HEAD > "${backup_dir}/manifests/nix-repo-head.txt" 2>&1 || true + +find /Applications -maxdepth 1 -type d -name "*.app" | sort > "${backup_dir}/manifests/applications-system.txt" +find "${HOME}/Applications" -maxdepth 1 -type d -name "*.app" | sort > "${backup_dir}/manifests/applications-user.txt" 2>/dev/null || true + +{ + printf '%s\n' "${HOME}/.claude" + printf '%s\n' "${HOME}/.codex" + printf '%s\n' "${HOME}/Library/Application Support/Claude" + printf '%s\n' "${HOME}/Library/Application Support/Code" + printf '%s\n' "${HOME}/Library/Application Support/Cursor" + printf '%s\n' "${HOME}/Library/Application Support/Zed" +} > "${backup_dir}/manifests/excluded-paths.txt" + +home_paths=( + ".config" + ".ssh" + ".gnupg" + ".aws" + ".npmrc" + ".gitconfig" + ".gitignore" + ".zshenv" + ".zprofile" + ".zshrc" + ".zlogin" + ".zlogout" + ".bash_profile" + ".profile" + ".secrets" + ".claude.json" + ".claude.json.backup" + "dots" + "Documents/GitHub/nix" +) + +library_paths=( + "Library/Preferences" + "Library/Fonts" + "Library/Application Support/Codex" +) + +archive_from_home() { + local archive_name="$1" + shift + local source_root="$1" + shift + local -a requested=("$@") + local -a existing=() + + for path in "${requested[@]}"; do + if [[ -e "${source_root}/${path}" || -L "${source_root}/${path}" ]]; then + existing+=("${path}") + fi + done + + printf '%s\n' "${existing[@]}" > "${backup_dir}/manifests/${archive_name%.tar.gz}-contents.txt" + + if ((${#existing[@]} == 0)); then + return + fi + + COPYFILE_DISABLE=1 tar \ + --exclude ".ssh/agent" \ + --exclude ".ssh/controlmasters" \ + -C "${source_root}" \ + -czf "${backup_dir}/archives/${archive_name}" \ + "${existing[@]}" +} + +archive_from_home "home-config.tar.gz" "${HOME}" "${home_paths[@]}" +archive_from_home "library-config.tar.gz" "${HOME}" "${library_paths[@]}" + +( + cd "${backup_dir}" + shasum -a 256 archives/*.tar.gz > manifests/archive-checksums.txt +) + +printf 'Backup written to %s\n' "${backup_dir}"