{ config, pkgs, lib, inputs, ... }: let cfg = config.dot.llm; in { options.dot.llm = { enable = lib.mkEnableOption "LLM tools"; claude-code.enable = lib.mkOption { type = lib.types.bool; default = false; description = "Enable claude-code"; }; opencode.enable = lib.mkOption { type = lib.types.bool; default = false; description = "Enable opencode"; }; gemini-cli.enable = lib.mkOption { type = lib.types.bool; default = false; description = "Enable gemini-cli"; }; pi.enable = lib.mkOption { type = lib.types.bool; default = false; description = "Enable pi"; }; pi.workMode = lib.mkOption { type = lib.types.bool; default = false; description = "Apply work machine (WSL NixOS) specific pi patches"; }; bubblewrap.enable = lib.mkOption { type = lib.types.bool; default = pkgs.stdenv.isLinux; description = "Enable bubblewrap (Linux only)"; }; }; config = lib.mkMerge [ { programs.direnv = { enable = true; enableZshIntegration = true; nix-direnv.enable = true; stdlib = '' : ''${XDG_CACHE_HOME:=$HOME/.cache} declare -A direnv_layout_dirs direnv_layout_dir() { echo "''${direnv_layout_dirs[$PWD]:=$( echo -n "$XDG_CACHE_HOME"/direnv/layouts/ echo -n "$PWD" | sha1sum | cut -d ' ' -f 1 )}" } ''; }; home.packages = with pkgs; [ visidata codespelunker jq inputs.hunk.packages.${pkgs.stdenv.hostPlatform.system}.hunk ]; } (lib.mkIf cfg.enable { home.packages = (lib.optional cfg.claude-code.enable pkgs.unstable.claude-code) ++ (lib.optional cfg.opencode.enable pkgs.unstable.opencode) ++ (lib.optional cfg.gemini-cli.enable pkgs.unstable.gemini-cli) ++ (lib.optional cfg.pi.enable ( let pi = inputs.llm-agents.packages.${pkgs.stdenv.hostPlatform.system}.pi; in if cfg.pi.workMode then # Work machine runs WSL NixOS, which needs the checks disabled and the # Bun binary's ELF interpreter patched to the correct dynamic linker. pi.overrideAttrs (oldAttrs: { doInstallCheck = false; # Run patchelf after the package is installed/fixed up by nix postFixup = (oldAttrs.postFixup or "") + '' # 1. Target the actual Bun binary inside libexec, not the shell wrapper in bin/ TARGET_BIN="$out/libexec/pi/pi" if [ -f "$TARGET_BIN" ]; then # 2. Make it writable in the build store so patchelf can edit it chmod +w "$TARGET_BIN" # 3. Running patchelf to set the interpreter forces it to rebuild the ELF headers patchelf --set-interpreter "$(cat $NIX_CC/nix-support/dynamic-linker)" "$TARGET_BIN" fi ''; }) else pi )) ++ (lib.optional (cfg.bubblewrap.enable && pkgs.stdenv.isLinux) pkgs.unstable.bubblewrap); }) ]; }