nix: add a flake with a package profile
Assisted-by: Claude Opus 5.5 via Claude Code
change ypvrtnukrzzlqzpqovtqsrxwsqsuwyot
commit da9d6223ed6a0bd59be6025aa2a1c1fa32f9bcbc
author Alpha Chen <alpha@kejadlen.dev>
date
parent uoyzstvr
diff --git a/docs/nix-migration.md b/docs/nix-migration.md
index 878f479d..404d7718 100644
--- a/docs/nix-migration.md
+++ b/docs/nix-migration.md
@@ -1,6 +1,8 @@
 # Moving the dotfiles to nix
 
-Status: exploring, nothing built yet (2026-11-03).
+Status: `flake.nix` builds a package profile, and imperishable-night
+installs it for `alpha`. The Mac still uses its hand-installed
+`nix profile` entries (2026-11-05).
 
 This note records a plan to install packages with nix, so the dotfiles
 work on Linux hosts as well as the Mac. frork keeps creating the
@@ -231,10 +233,9 @@ but `.hammerspoon/init.lua` would then need a nix store path on
 ## Risks
 
 Nix flakes in a git repo only see files that are in the git index. In a
-colocated jj repo, new files in `@` may be missing from the index, which
-would cause "path is not tracked by Git" errors right after adding a
-file to the flake. This is unverified with jj 0.46; test it before
-settling the layout. The `path:` flake URL skips the git check, but it
+colocated jj repo, new files in `@` are missing from the index, so
+evaluating fails with "path is not tracked by Git" until the file is
+committed. The `path:` flake URL skips the git check, but it
 copies the whole directory into the store, including untracked and
 ignored paths like `ai/claude/projects` and `.direnv`.
 
diff --git a/flake.lock b/flake.lock
new file mode 100644
index 00000000..032638e8
--- /dev/null
+++ b/flake.lock
@@ -0,0 +1,101 @@
+{
+  "nodes": {
+    "flake-parts": {
+      "inputs": {
+        "nixpkgs-lib": [
+          "neovim-nightly-overlay",
+          "nixpkgs"
+        ]
+      },
+      "locked": {
+        "lastModified": 1793576659,
+        "narHash": "sha256-V1h85lUaJBQoHFrB2vpXZOE0Ju1MYSnIpsehoVZYlDo=",
+        "owner": "hercules-ci",
+        "repo": "flake-parts",
+        "rev": "ea2630b7470978622c7689a1ff75d2b389175399",
+        "type": "github"
+      },
+      "original": {
+        "owner": "hercules-ci",
+        "repo": "flake-parts",
+        "type": "github"
+      }
+    },
+    "neovim-nightly-overlay": {
+      "inputs": {
+        "flake-parts": "flake-parts",
+        "neovim-src": "neovim-src",
+        "nixpkgs": "nixpkgs"
+      },
+      "locked": {
+        "lastModified": 1793837004,
+        "narHash": "sha256-ZDOEpcyM7iJUqAFPjZiGeQQw5d4nUk0ND/v9pbVpgfc=",
+        "owner": "nix-community",
+        "repo": "neovim-nightly-overlay",
+        "rev": "79bc7f43b343fadd4f6f42a4e7f3c3942ae1378b",
+        "type": "github"
+      },
+      "original": {
+        "owner": "nix-community",
+        "repo": "neovim-nightly-overlay",
+        "type": "github"
+      }
+    },
+    "neovim-src": {
+      "flake": false,
+      "locked": {
+        "lastModified": 1793835735,
+        "narHash": "sha256-vEoHG2Mz0Myh7CwcL6eEUFSG+wNsi+AI4AxgvSjzIqo=",
+        "owner": "neovim",
+        "repo": "neovim",
+        "rev": "ab7d2d42a47bf167807d7b0303aaa52405b59579",
+        "type": "github"
+      },
+      "original": {
+        "owner": "neovim",
+        "repo": "neovim",
+        "type": "github"
+      }
+    },
+    "nixpkgs": {
+      "locked": {
+        "lastModified": 1793735720,
+        "narHash": "sha256-smoxPKrzAhdGuFd2LLnG4m8P6IrZuW95DVyzjnlab7w=",
+        "owner": "NixOS",
+        "repo": "nixpkgs",
+        "rev": "9d3b8db48266c17be0b5f9c6360c3ecfbac3d1f5",
+        "type": "github"
+      },
+      "original": {
+        "owner": "NixOS",
+        "ref": "nixpkgs-unstable",
+        "repo": "nixpkgs",
+        "type": "github"
+      }
+    },
+    "nixpkgs_2": {
+      "locked": {
+        "lastModified": 1793795574,
+        "narHash": "sha256-pgG/CO+txdf2sA2z6DsM+2G3F9ajfIp/3BMC4wfKMDY=",
+        "owner": "NixOS",
+        "repo": "nixpkgs",
+        "rev": "13e53762c5afaf384d4614e94527a9ccfafe41d0",
+        "type": "github"
+      },
+      "original": {
+        "owner": "NixOS",
+        "ref": "nixpkgs-unstable",
+        "repo": "nixpkgs",
+        "type": "github"
+      }
+    },
+    "root": {
+      "inputs": {
+        "neovim-nightly-overlay": "neovim-nightly-overlay",
+        "nixpkgs": "nixpkgs_2"
+      }
+    }
+  },
+  "root": "root",
+  "version": 7
+}
diff --git a/flake.nix b/flake.nix
new file mode 100644
index 00000000..e70128ce
--- /dev/null
+++ b/flake.nix
@@ -0,0 +1,42 @@
+{
+  inputs = {
+    nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
+    # Its own nixpkgs, since a different tree-sitter breaks its vendored-deps hash.
+    neovim-nightly-overlay.url = "github:nix-community/neovim-nightly-overlay";
+  };
+
+  outputs =
+    { nixpkgs, neovim-nightly-overlay, ... }:
+    let
+      forAllSystems = nixpkgs.lib.genAttrs [
+        "aarch64-darwin"
+        "x86_64-linux"
+      ];
+    in
+    {
+      # Tools with a DotSlash file in bin/ stay there.
+      packages = forAllSystems (
+        system:
+        let
+          pkgs = nixpkgs.legacyPackages.${system};
+        in
+        {
+          profile = pkgs.buildEnv {
+            name = "profile";
+            paths = with pkgs; [
+              # nix-direnv needs bash 4 or later.
+              bash
+              dotslash
+              entr
+              eza
+              git
+              neovim-nightly-overlay.packages.${system}.default
+              nix-direnv
+              tmux
+              zsh
+            ];
+          };
+        }
+      );
+    };
+}