Skip to content

Refactor to flake-parts + import-tree (Dendritic pattern) - #7

Merged
kriswill merged 5 commits into
mainfrom
dendritic
May 25, 2026
Merged

Refactor to flake-parts + import-tree (Dendritic pattern)#7
kriswill merged 5 commits into
mainfrom
dendritic

Conversation

@kriswill

Copy link
Copy Markdown
Owner

What

Refactors the flake to the Dendritic pattern: a flake-parts top-level configuration where every file under ./modules is a flake-parts module, auto-imported by import-tree. Replaces the bespoke autoImport / mkDarwin / mkHomeManager plumbing.

How it works

  • flake.nix is a minimal entry point: flake-parts.lib.mkFlake { … } (import-tree ./modules)
  • inputs.flake-parts.flakeModules.modules provides the flake.modules.<class>.<name> option; every feature file merges its darwin / home-manager module into it
  • modules/darwin.nix declares configurations.darwin.<host> and realises each into darwinConfigurations.<host> (plus a toplevel build check via flake.checks)
  • modules/home.nix wires home-manager in as a darwin module, importing every flake.modules.homeManager.*
  • Hosts live in modules/hosts/*.nix

Preserved behavior

  • Per-feature kriswill.<tool>.enable toggles kept verbatim — each tool is just wrapped in a flake.modules.{darwin,homeManager}.<name> value; the option/config bodies are unchanged
  • Per-host differences ported exactly (dnsmasq everywhere, alias-en0 on SOC, podman-desktop on k + SOC)

Notable details

  • Pure helpers (mkProgramOption, kanagawa) stay in top-level lib/ — outside ./modules, so import-tree ignores them
  • home-manager derives its user-eval lib from the darwin system's already-extended lib (carries kanagawa/mkProgramOption) and adds its own hm extensions — so extraSpecialArgs deliberately does not pass lib (would drop lib.hm.*)
  • yazi theme assets moved to _themes/ (import-tree skips /_ paths)
  • Removed: autoImport/mkDarwin/mkHomeManager, all autoImport default.nix shims, old hosts/, dead overlays/default.nix

Verification

  • nix build .#darwinConfigurations.{k,mini,SOC-Kris-Williams}.system — all three build; only the always-rebuilt system-wrapper derivations rebuilt, everything else a cache hit → closure parity with main
  • nix build .#packages.aarch64-darwin.kitten
  • nix fmt + deadnix clean; per-host toggles + lib.hm.* / lib.kanagawa eval correctly

Known / not blocking

  • iv package fails to build (libvipsVips-8.0.gir gobject-introspection step fails from source, no cache for this nixpkgs rev). pkgs/iv.nix is byte-identical to main — environmental, not a refactor regression.
  • statix emits empty_pattern warnings for the canonical dendritic { ... }: module signature; remaining warnings are in verbatim-copied bodies that already tripped statix on main.
  • CLAUDE.md still documents the old autoImport "Adding a New Module" flow — stale, left for a follow-up.

kriswill added 5 commits May 24, 2026 19:25
Replace the bespoke flake plumbing (autoImport/mkDarwin/mkHomeManager) with
a flake-parts top-level configuration where every file under ./modules is a
flake-parts module auto-imported by import-tree.

- flake.nix: minimal entry point — mkFlake (import-tree ./modules)
- Each feature is flake.modules.{darwin,homeManager}.<name>; per-feature
  kriswill.<tool>.enable toggles preserved verbatim
- modules/darwin.nix realises configurations.darwin into darwinConfigurations
  + toplevel checks; modules/home.nix wires home-manager as a darwin module
- Hosts move to modules/hosts/*.nix (configurations.darwin.<host>)
- Pure helpers (mkProgramOption, kanagawa) kept in top-level lib/ (outside
  ./modules so import-tree skips them); yazi theme assets moved to _themes/
- Remove autoImport shims, old hosts/, dead overlays/default.nix

Verified: all three darwinConfigurations build (cache-hit parity with main),
kitten builds, nix fmt + deadnix clean, per-host toggles eval correctly.
Every file under modules/ is auto-imported as a flake-parts module, and a
module may be a bare attrset or a function. These 32 files destructured no
module args, so the leading `{ ... }:` bound nothing and was a pure no-op.
Removing it leaves the attrset directly. nix fmt also normalized the direnv
overlay's overrideAttrs to multi-line.
Directories under modules/home-manager/ that held only a default.nix with no
supporting files (zk, podman-desktop, neovide, tmux, neovim, karabiner,
ghostty) are now flat <name>.nix files. Dirs are reserved for modules that
bundle adjacent config (firefox/user.js, kitty/*.conf, yazi/_themes, etc.).
All symlink sources are homeDirectory-based absolutes, so moving the files up
one level is safe. Also removed leftover empty mixins/ dirs from the refactor.
…import-tree

The Dendritic refactor dropped lib.autoImport, mkDarwin, and mkHomeManager;
discovery is now flake-parts + import-tree over ./modules. Update the overview,
file-organization tree, custom-lib section, module-add and package-add steps,
the module-pattern reference (nh path), and unfree handling to match.
CHANGED
[U.] chafa 1.18.1, 1.18.1-bin -> 1.18.2, 1.18.2-bin
[U.] kitty 0.46.2, 0.46.2-terminfo -> 0.47.0, 0.47.0-terminfo

SIZE: 11.1 GiB -> 11.1 GiB
DIFF: 3.26 MiB
> Activating configuration
@kriswill
kriswill merged commit 42f0bf7 into main May 25, 2026
kriswill added a commit that referenced this pull request Jun 29, 2026
nix-darwin has no programs.* for most of these tools, so port them the way
the rest of the repo already does (cf. tmux/zsh/yazi): static config lives in
the stow tree (home/) and the /nix/store-derived bits are generated and linked
during activation. The shell integrations (fzf/zoxide/direnv/hstr) already live
in the stow zshrc, so only the FZF_* env vars needed re-adding there.

Moved out of modules/home-manager/core.nix (now deleted) into system-level
modules/darwin/<feature>.nix + home/<pkg> stow packages:

  git/gh      modules/darwin/git.nix         + home/git, home/gh (bare-name
                                                helpers, no stale store paths)
  ssh         modules/darwin/ssh.nix         + home/ssh
  zk          modules/darwin/zk.nix
  diffnav     modules/darwin/diffnav.nix     installs a delta wrapped with the
                                              kanagawa theme (matches HM's
                                              finalPackage; diffnav bundles its
                                              own delta and is unaffected)
  kitty       modules/darwin/kitty.nix       + home/kitty
  neovide     modules/darwin/neovide.nix     toggle only; pkg is per-host
  direnv      modules/darwin/direnv.nix      + home/direnv; nix-direnv stdlib
                                              linked into ~/.config/direnv/lib
  direnv-nom  modules/darwin/direnv-nom.nix  nom wrapper generated + linked
  htop        modules/darwin/htop.nix        immutable htoprc generated + linked
  qmd-sqlite  modules/darwin/qmd-sqlite.nix  extension-enabled sqlite (hiPrio so
                                              it wins the sqlite3 collision with
                                              neovim's plain sqlite) + qmd link
  bat jq nix-index lazygit rmpc fzf go nodejs_24 yamlfmt -> user-packages.nix
  FZF_* env vars -> home/zsh/.config/zsh/.zshrc

The home-manager master `kriswill.enable` toggle and core.nix were removed;
home-manager stays wired only for the GUI/per-host modules (brave, firefox,
vscode, podman-desktop, claude-account-selector). All three host configs build
(nix flake check) and the HM->stow config handoff is clean (the old HM configs
were store symlinks HM removes on switch, then stow/activation redeploys).

flake.lock: `nix flake update` bumps nixpkgs, home-manager and yazi-plugins.
This is a closure no-op for host k -- the new lock evaluates to the identical
darwin-system derivation (verified: same .drv d15di5x4..., same output
axiznxg2...). It is included so future builds and the other hosts track the
newer inputs.

nvd diff -- previous generation (system-184, pre-migration) -> this commit's
closure (== the running gen-185 system). The Selection-state / Added / Removed
sections are this port (note the hm_* generated configs removed and the
delta-wrapped/delta-config -> delta-kanagawa swap); the Version changes are the
already-committed af761b8 nixpkgs bump that the pre-port generation had not yet
realized.

<<< /nix/store/7kx6ii60i6fwp4gsn4l987r9klgwd909-darwin-system-26.11.a1fa429
>>> /nix/store/axiznxg2fgby564shlpxjkjp208wa6p8-darwin-system-26.11.a1fa429
Version changes:
[U*]  #1  buf                           1.70.0 -> 1.71.0
[U.]  #2  expat                         2.8.0 -> 2.8.1
[U*]  #3  fastfetch                     2.64.2, 2.64.2-man -> 2.65.1, 2.65.1-man
[U.]  #4  ffmpeg-headless               8.1-bin, 8.1-data, 8.1-lib -> 8.1.1-bin, 8.1.1-data, 8.1.1-lib
[U.]  #5  fftw-double                   3.3.10 -> 3.3.11
[U*]  #6  fish                          4.7.1, 4.7.1-doc -> 4.8.0, 4.8.0-doc
[U.]  #7  freetype                      2.14.2 -> 2.14.3
[U+]  #8  gh                            2.94.0 -> 2.95.0
[U*]  #9  ghostscript                   10.07.0, 10.07.0-fonts, 10.07.0-man -> 10.07.1, 10.07.1-fonts, 10.07.1-man
[U*]  #10  go                            1.26.3 -> 1.26.4
[U.]  #11  icu4c                         76.1, 76.1-dev -> 78.3, 78.3-dev
[U.]  #12  ijs                           10.07.0 -> 10.07.1
[U*]  #13  imagemagick                   7.1.2-23 -> 7.1.2-24
[U.]  #14  just                          1.51.0, 1.51.0-man -> 1.54.0, 1.54.0-man
[U.]  #15  krb5                          1.22.1-lib -> 1.22.2-lib
[U.]  #16  libde265                      1.0.18 -> 1.1.1
[U.]  #17  libgcrypt                     1.11.2-lib -> 1.12.2-lib
[U.]  #18  libheif                       1.21.2-lib -> 1.23.0-lib
[U.]  #19  libpng-apng                   1.6.56 -> 1.6.58
[U*]  #20  libxml2                       2.15.2, 2.15.2-bin -> 2.15.3, 2.15.3-bin
[U*]  #21  lua-language-server           3.18.1 -> 3.18.2
[D.]  #22  nix                           2.34.7+1 x2 -> 2.34.7 x2
[D.]  #23  nix-cmd                       2.34.7+1 -> 2.34.7
[D.]  #24  nix-expr                      2.34.7+1 -> 2.34.7
[D.]  #25  nix-fetchers                  2.34.7+1 -> 2.34.7
[D.]  #26  nix-flake                     2.34.7+1 -> 2.34.7
[D.]  #27  nix-main                      2.34.7+1 -> 2.34.7
[D.]  #28  nix-store                     2.34.7+1 -> 2.34.7
[D.]  #29  nix-util                      2.34.7+1 -> 2.34.7
[U*]  #30  nodejs                        24.15.0 -> 24.16.0
[C.]  #31  nodejs-slim                   22.22.3, 24.15.0, 24.15.0-corepack, 24.15.0-npm -> 22.23.1, 24.16.0, 24.16.0-corepack, 24.16.0-npm
[U.]  #32  openapv                       0.2.1.2 -> 0.2.1.3
[U.]  #33  openexr                       3.4.10 -> 3.4.11
[U.]  #34  podman                        5.8.2, 5.8.2-man -> 5.8.3, 5.8.3-man
[U.]  #35  publicsuffix-list             0-unstable-2026-03-26 -> 0-unstable-2026-05-13
[U.]  #36  rsync                         3.4.1 -> 3.4.4
[U*]  #37  rumdl                         0.2.16 -> 0.2.21
[U.]  #38  simdjson                      4.6.0 -> 4.6.4
[C*]  #39  sqlite                        3.51.2 x2, 3.51.2-bin x2, 3.51.2-dev, 3.51.2-man x2 -> 3.51.2 x2, 3.51.2-bin x2, 3.51.2-dev, 3.51.2-man
[U.]  #40  unbound                       1.25.0-lib -> 1.25.1-lib
[U.]  #41  uv                            0.11.19 -> 0.11.22
[D*]  #42  vscode-langservers-extracted  4.10.0 -> 1.121.03429
Selection state changes:
[C+]  #1  direnv   2.37.1
[C+]  #2  git-lfs  3.7.1
[C+]  #3  htop     3.5.1, 3.5.1-man
[C+]  #4  kitty    0.47.4, 0.47.4-terminfo
Added packages:
[A+]  #1  delta-kanagawa                                   <none>
[A.]  #2  delta-kanagawa.gitconfig                         <none>
[A.]  #3  fastfetch-unwrapped                              2.65.1, 2.65.1-man
[A.]  #4  home-manager-agent-domains                       <none>
[A.]  #5  org.nix-community.home.claude-config-dir.domain  <none>
[A.]  #6  zz-nom-wrapper.sh                                <none>
Removed packages:
[R.]  #1  delta-config                 <none>
[R.]  #2  delta-wrapped                <none>
[R.]  #3  direnv-config                <none>
[R.]  #4  empty-directory              <none>
[R.]  #5  gh-config.yml                <none>
[R.]  #6  hm_.sshconfig                <none>
[R.]  #7  hm_direnvlibzznomwrapper.sh  <none>
[R.]  #8  hm_gitallowed_signers        <none>
[R.]  #9  hm_gitconfig                 <none>
[R.]  #10  hm_gitignore                 <none>
[R.]  #11  hm_kanagawa.conf             <none>
[R.]  #12  hm_kittydiff.conf            <none>
[R.]  #13  hm_kittykitty.conf           <none>
[R.]  #14  yyjson                       0.12.0
Closure size: 624 -> 616 (611 paths added, 619 paths removed, delta -8, disk usage -53.1MiB).
kriswill added a commit that referenced this pull request Jun 29, 2026
Completes the migration. The home-manager bridge, flake input, and the last
runtime hook are gone; the repo is now pure nix-darwin + the GNU Stow tree under
home/.

- flake.nix: drop the home-manager input (flake.lock: removed the home-manager
  and home-manager/nixpkgs nodes).
- modules/home.nix deleted -- the darwin <- home-manager bridge.
- modules/darwin/core.nix: drop pkgs.home-manager from environment.systemPackages.
- home/zsh/.config/zsh/.zshrc: drop the hm-session-vars.sh source line.
- AGENTS.md / CLAUDE.md updated to describe a darwin-only repo (no home.nix, no
  modules/home-manager/, no mkOutOfStoreSymlink mechanism).

Terminfo is unaffected -- the one real risk. nix-darwin's own set-environment
already exports the full TERMINFO_DIRS (the Ghostty.app bundle, the per-user and
system nix profiles, and /usr/share/terminfo), so xterm-kitty (in the system
profile's share/terminfo) and xterm-ghostty (Ghostty's bundle) still resolve
without the home-manager session-vars line. Verified with infocmp.

nix flake check passes for k, mini, SOC.

nvd diff -- previous generation (system-186, home-manager present) -> this commit
(system-187, now active). Removes the entire home-manager apparatus plus the deps
nothing else in the closure used (man-db, groff, diffutils, inetutils,
libpipeline).

<<< /nix/store/gf8hnm6w88ng2kajiy4x5n29k55nq0wz-darwin-system-26.11.a1fa429
>>> /run/current-system
Removed packages:
[R.]  #1  activation-k                             <none>
[R.]  #2  check-link-targets.sh                    <none>
[R.]  #3  cleanup                                  <none>
[R.]  #4  diffutils                                3.12
[R.]  #5  groff                                    1.24.1
[R.]  #6  hm-modules-messages                      <none>
[R.]  #7  hm-session-vars.sh                       <none>
[R.]  #8  hm_LibraryFonts.homemanagerfontsversion  <none>
[R.]  #9  hm_Usersk.cache.keep                     <none>
[R.]  #10  hm_Usersk.localstate.keep                <none>
[R-]  #11  home-manager                             0-unstable-2026-04-24
[R.]  #12  home-manager-agent-domains               <none>
[R.]  #13  home-manager-agents                      <none>
[R.]  #14  home-manager-applications                <none>
[R.]  #15  home-manager-files                       <none>
[R.]  #16  home-manager-fonts                       <none>
[R.]  #17  home-manager-generation                  <none>
[R.]  #18  home-manager-path                        <none>
[R.]  #19  home-manager-source                      <none>
[R.]  #20  home-manager.sh                          <none>
[R.]  #21  inetutils                                2.7
[R.]  #22  libpipeline                              1.5.8
[R.]  #23  link                                     <none>
[R.]  #24  man-db                                   2.13.1
[R.]  #25  nixos-option                             <none>
[R.]  #26  nixos-option.nix                         <none>
Closure size: 613 -> 587 (6 paths added, 32 paths removed, delta -26, disk usage -20.7MiB).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant