From e947e13a02d286ac51d968d58eb667a5af9a09af Mon Sep 17 00:00:00 2001 From: Evan Reichard Date: Sun, 14 Dec 2025 16:24:11 -0500 Subject: [PATCH] feat: comprehensive NixOS and home-manager configuration updates This commit includes significant updates to the Nix configuration including: - Added common NixOS module with system packages - Updated home-manager configurations for various systems - Enhanced terminal programs including Claude Code integration - Updated LLM server configurations with new models - Improved btop configuration with custom package - Added opencode support with permission settings - Updated tmux and nvim configurations The changes introduce new features, update existing configurations, and improve the overall system setup. --- flake.nix | 1 + .../evanreichard@mac-va-mbp-work/default.nix | 9 ++- .../evanreichard@lin-va-desktop/default.nix | 30 +++++++ .../evanreichard@lin-va-terminal/default.nix | 4 +- .../home/programs/terminal/btop/default.nix | 15 +++- .../programs/terminal/claude-code/default.nix | 81 +++++++++++++++++++ .../programs/terminal/nvim/config/lua/llm.lua | 7 +- .../programs/terminal/opencode/default.nix | 17 ++++ .../home/programs/terminal/tmux/default.nix | 7 +- modules/nixos/common/default.nix | 6 ++ .../x86_64-linux/lin-va-desktop/default.nix | 34 ++++---- 11 files changed, 182 insertions(+), 29 deletions(-) create mode 100755 homes/x86_64-linux/evanreichard@lin-va-desktop/default.nix create mode 100755 modules/home/programs/terminal/claude-code/default.nix create mode 100644 modules/nixos/common/default.nix diff --git a/flake.nix b/flake.nix index c3661c3..5ce1bed 100755 --- a/flake.nix +++ b/flake.nix @@ -70,6 +70,7 @@ nixos = with inputs; [ disko.nixosModules.disko sops-nix.nixosModules.sops + ./modules/nixos/common ]; darwin = with inputs; [ home-manager.darwinModules.home-manager diff --git a/homes/aarch64-darwin/evanreichard@mac-va-mbp-work/default.nix b/homes/aarch64-darwin/evanreichard@mac-va-mbp-work/default.nix index 65e9d16..81a442b 100755 --- a/homes/aarch64-darwin/evanreichard@mac-va-mbp-work/default.nix +++ b/homes/aarch64-darwin/evanreichard@mac-va-mbp-work/default.nix @@ -22,13 +22,14 @@ in }; terminal = { - opencode = enabled; + aws = enabled; btop = enabled; + claude-code = enabled; direnv = enabled; git = enabled; k9s = enabled; nvim = enabled; - aws = enabled; + opencode = enabled; }; }; }; @@ -43,7 +44,9 @@ in texliveSmall # Pandoc PDF Dep google-cloud-sdk tldr - claude-code + + # AI Assistants reichard.qwen-code + codex ]; } diff --git a/homes/x86_64-linux/evanreichard@lin-va-desktop/default.nix b/homes/x86_64-linux/evanreichard@lin-va-desktop/default.nix new file mode 100755 index 0000000..f791fba --- /dev/null +++ b/homes/x86_64-linux/evanreichard@lin-va-desktop/default.nix @@ -0,0 +1,30 @@ +{ lib +, config +, namespace +, ... +}: +let + inherit (lib.${namespace}) enabled; +in +{ + home.stateVersion = "25.11"; + + reichard = { + user = { + enable = true; + inherit (config.snowfallorg.user) name; + }; + + services = { + ssh-agent = enabled; + }; + + programs = { + terminal = { + bash = enabled; + btop = enabled; + tmux = enabled; + }; + }; + }; +} diff --git a/homes/x86_64-linux/evanreichard@lin-va-terminal/default.nix b/homes/x86_64-linux/evanreichard@lin-va-terminal/default.nix index c52e152..86d21a2 100755 --- a/homes/x86_64-linux/evanreichard@lin-va-terminal/default.nix +++ b/homes/x86_64-linux/evanreichard@lin-va-terminal/default.nix @@ -22,12 +22,14 @@ in programs = { terminal = { bash = enabled; - tmux = enabled; btop = enabled; + claude-code = enabled; direnv = enabled; git = enabled; k9s = enabled; nvim = enabled; + opencode = enabled; + tmux = enabled; }; }; }; diff --git a/modules/home/programs/terminal/btop/default.nix b/modules/home/programs/terminal/btop/default.nix index a43a5ec..05f502e 100755 --- a/modules/home/programs/terminal/btop/default.nix +++ b/modules/home/programs/terminal/btop/default.nix @@ -1,4 +1,9 @@ -{ lib, config, namespace, ... }: +{ lib +, pkgs +, config +, namespace +, ... +}: let inherit (lib) mkIf; cfg = config.${namespace}.programs.terminal.btop; @@ -9,10 +14,12 @@ in }; config = mkIf cfg.enable { - programs.btop.enable = true; + programs.btop = { + enable = true; + package = pkgs.btop-cuda; + }; - home.file.".config/btop/btop.conf".text = - builtins.readFile ./config/btop.conf; + home.file.".config/btop/btop.conf".text = builtins.readFile ./config/btop.conf; home.file.".config/btop/themes/catppuccin_mocha.theme".text = builtins.readFile ./config/catppuccin_mocha.theme; }; diff --git a/modules/home/programs/terminal/claude-code/default.nix b/modules/home/programs/terminal/claude-code/default.nix new file mode 100755 index 0000000..09e97cb --- /dev/null +++ b/modules/home/programs/terminal/claude-code/default.nix @@ -0,0 +1,81 @@ +{ lib +, pkgs +, config +, namespace +, ... +}: +let + inherit (lib) mkIf; + cfg = config.${namespace}.programs.terminal.claude-code; +in +{ + options.${namespace}.programs.terminal.claude-code = { + enable = lib.mkEnableOption "enable claude-code"; + }; + + config = mkIf cfg.enable { + programs.claude-code = { + enable = true; + mcpServers = { + gopls = { + type = "stdio"; + command = "gopls"; + args = [ "mcp" ]; + }; + }; + }; + + programs.bash = lib.mkIf config.programs.bash.enable { + shellAliases = { + claude = "default_claude_custom"; + }; + + initExtra = + let + baseUrl = "https://llm-api.va.reichard.io"; + authToken = "placeholder"; + in + '' + default_claude_custom() { + local model_id="" + while [[ $# -gt 0 ]]; do + case $1 in + -m|--model) + model_id="$2" + shift 2 + ;; + *) + shift + ;; + esac + done + + if [ -z "$model_id" ]; then + echo "Error: Model ID is required. Usage: claude --model " + return 1 + fi + + ANTHROPIC_BASE_URL="${baseUrl}" \ + ANTHROPIC_AUTH_TOKEN="${authToken}" \ + ANTHROPIC_MODEL="$model_id" \ + ANTHROPIC_SMALL_FAST_MODEL="$model_id" \ + ${lib.getExe pkgs.claude-code} + } + + # Completion Function + _complete_claude_custom() { + local cur=''${COMP_WORDS[COMP_CWORD]} + local prev=''${COMP_WORDS[COMP_CWORD-1]} + + if [[ "$prev" == "-m" || "$prev" == "--model" ]]; then + local models=( $(${pkgs.curl}/bin/curl -s -H "Authorization: Bearer ${authToken}" "${baseUrl}/v1/models" | ${pkgs.jq}/bin/jq -r '.data[].id' 2>/dev/null) ) + COMPREPLY=( $(compgen -W "''${models[*]}" -- "$cur") ) + fi + } + + # Register Completion + complete -F _complete_claude_custom claude + ''; + }; + }; +} diff --git a/modules/home/programs/terminal/nvim/config/lua/llm.lua b/modules/home/programs/terminal/nvim/config/lua/llm.lua index 1df2a28..96aab97 100755 --- a/modules/home/programs/terminal/nvim/config/lua/llm.lua +++ b/modules/home/programs/terminal/nvim/config/lua/llm.lua @@ -1,6 +1,9 @@ local llm_endpoint = "https://llm-api.va.reichard.io" -local llm_assistant_model = "gpt-oss-20b-thinking" -local llm_infill_model = "qwen2.5-coder-3b-instruct" +-- local llm_assistant_model = "gpt-oss-20b-thinking" +-- local llm_infill_model = "qwen2.5-coder-3b-instruct" + +local llm_assistant_model = "qwen3-30b-2507-instruct" +local llm_infill_model = llm_assistant_model -- Default Llama - Toggle Llama & Copilot -- vim.g.copilot_filetypes = { ["*"] = false } diff --git a/modules/home/programs/terminal/opencode/default.nix b/modules/home/programs/terminal/opencode/default.nix index ee39f20..893a8d4 100755 --- a/modules/home/programs/terminal/opencode/default.nix +++ b/modules/home/programs/terminal/opencode/default.nix @@ -1,4 +1,5 @@ { lib +, pkgs , config , namespace , ... @@ -18,6 +19,22 @@ in enableMcpIntegration = true; settings = { theme = "catppuccin"; + permission = { + edit = "allow"; + bash = "ask"; + webfetch = "ask"; + doom_loop = "ask"; + external_directory = "ask"; + }; + lsp = { + nil = { + command = [ + "${pkgs.nil}/bin/nil" + "--stdio" + ]; + extensions = [ ".nix" ]; + }; + }; provider = { "llama-swap" = { npm = "@ai-sdk/openai-compatible"; diff --git a/modules/home/programs/terminal/tmux/default.nix b/modules/home/programs/terminal/tmux/default.nix index 3c529a0..7ab9cb9 100755 --- a/modules/home/programs/terminal/tmux/default.nix +++ b/modules/home/programs/terminal/tmux/default.nix @@ -1,4 +1,9 @@ -{ lib, pkgs, config, namespace, ... }: +{ lib +, pkgs +, config +, namespace +, ... +}: let inherit (lib) mkIf; cfg = config.${namespace}.programs.terminal.tmux; diff --git a/modules/nixos/common/default.nix b/modules/nixos/common/default.nix new file mode 100644 index 0000000..2fbffda --- /dev/null +++ b/modules/nixos/common/default.nix @@ -0,0 +1,6 @@ +{ pkgs, ... }: +{ + environment.systemPackages = with pkgs; [ + wget + ]; +} diff --git a/systems/x86_64-linux/lin-va-desktop/default.nix b/systems/x86_64-linux/lin-va-desktop/default.nix index 2d54f30..8bfc647 100755 --- a/systems/x86_64-linux/lin-va-desktop/default.nix +++ b/systems/x86_64-linux/lin-va-desktop/default.nix @@ -96,69 +96,67 @@ in # --chat-template-kwargs '{\"reasoning_effort\":\"low\"}' "gpt-oss-20b-thinking" = { name = "GPT OSS (20B) - Thinking"; - cmd = "${pkgs.reichard.llama-cpp}/bin/llama-server --port \${PORT} -m /mnt/ssd/Models/gpt-oss-20b-heretic-v2.i1-MXFP4_MOE.gguf --ctx-size 131072 -ts 57,43 --temp 1.0 --top-p 1.0 --top-k 40 --mlock"; - aliases = [ - "claude-sonnet-4-5" - "claude-sonnet-4-5-20250929" - "claude-haiku-4-5" - "claude-haiku-4-5-20251001" - "claude-opus-4-5" - "claude-opus-4-5-20251101" - ]; + cmd = "${pkgs.reichard.llama-cpp}/bin/llama-server --port \${PORT} -m /mnt/ssd/Models/gpt-oss-20b-heretic-v2.i1-MXFP4_MOE.gguf -c 131072 --temp 1.0 --top-p 1.0 --top-k 40 -ts 57,43"; }; # https://huggingface.co/unsloth/Qwen3-Coder-30B-A3B-Instruct-GGUF/tree/main "qwen3-coder-30b-instruct" = { name = "Qwen3 Coder (30B) - Instruct"; - cmd = "${pkgs.reichard.llama-cpp}/bin/llama-server --port \${PORT} -m /mnt/ssd/Models/Qwen3-Coder-30B-A3B-Instruct-IQ4_XS.gguf --ctx-size 65536 --temp 0.7 --min-p 0.0 --top-p 0.8 --top-k 20 --repeat-penalty 1.05 --cache-type-k q4_0 --cache-type-v q4_0 --mlock"; + cmd = "${pkgs.reichard.llama-cpp}/bin/llama-server --port \${PORT} -m /mnt/ssd/Models/Qwen3-Coder-30B-A3B-Instruct-IQ4_XS.gguf -c 65536 --temp 0.7 --min-p 0.0 --top-p 0.8 --top-k 20 --repeat-penalty 1.05 -ctk q4_0 -ctv q4_0 -np 2 -kvu"; }; # https://huggingface.co/unsloth/Qwen3-30B-A3B-Instruct-2507-GGUF/tree/main "qwen3-30b-2507-instruct" = { name = "Qwen3 2507 (30B) - Instruct"; - cmd = "${pkgs.reichard.llama-cpp}/bin/llama-server --port \${PORT} -m /mnt/ssd/Models/Qwen3-30B-A3B-Instruct-2507-IQ4_XS.gguf --ctx-size 65536 --temp 0.7 --min-p 0.0 --top-p 0.8 --top-k 20 --repeat-penalty 1.05 --cache-type-k q4_0 --cache-type-v q4_0 --mlock"; + cmd = "${pkgs.reichard.llama-cpp}/bin/llama-server --port \${PORT} -m /mnt/ssd/Models/Qwen3-30B-A3B-Instruct-2507-IQ4_XS.gguf -c 65536 --temp 0.7 --min-p 0.0 --top-p 0.8 --top-k 20 --repeat-penalty 1.05 -ctk q4_0 -ctv q4_0 -np 2 -kvu"; }; # https://huggingface.co/unsloth/Qwen3-30B-A3B-Thinking-2507-GGUF/tree/main "qwen3-30b-2507-thinking" = { name = "Qwen3 2507 (30B) - Thinking"; - cmd = "${pkgs.reichard.llama-cpp}/bin/llama-server --port \${PORT} -m /mnt/ssd/Models/Qwen3-30B-A3B-Thinking-2507-IQ4_XS.gguf --ctx-size 65536 --temp 0.7 --min-p 0.0 --top-p 0.8 --top-k 20 --repeat-penalty 1.05 --cache-type-k q4_0 --cache-type-v q4_0 --mlock"; + cmd = "${pkgs.reichard.llama-cpp}/bin/llama-server --port \${PORT} -m /mnt/ssd/Models/Qwen3-30B-A3B-Thinking-2507-IQ4_XS.gguf -c 65536 --temp 0.7 --min-p 0.0 --top-p 0.8 --top-k 20 --repeat-penalty 1.05 -ctk q4_0 -ctv q4_0 -np 2 -kvu"; }; # https://huggingface.co/unsloth/Qwen3-Next-80B-A3B-Instruct-GGUF/tree/main "qwen3-next-80b-instruct" = { name = "Qwen3 Next (80B) - Instruct"; - cmd = "${pkgs.reichard.llama-cpp}/bin/llama-server --port \${PORT} -m /mnt/ssd/Models/Qwen3-Next-80B-A3B-Instruct-UD-Q4_K_XL.gguf --ctx-size 32768 --temp 0.7 --min-p 0.0 --top-p 0.8 --top-k 20 -sm none -ncmoe 39"; + cmd = "${pkgs.reichard.llama-cpp}/bin/llama-server --port \${PORT} -m /mnt/ssd/Models/Qwen3-Next-80B-A3B-Instruct-UD-Q4_K_XL.gguf -c 32768 --temp 0.7 --min-p 0.0 --top-p 0.8 --top-k 20 -dev CUDA0 -ncmoe 39 --mlock"; + }; + + # https://huggingface.co/unsloth/Devstral-Small-2-24B-Instruct-2512-GGUF/tree/main + "devstral-small-2-instruct" = { + name = "Devstral Small 2 (24B) - Instruct"; + cmd = "${pkgs.reichard.llama-cpp}/bin/llama-server --port \${PORT} -m /mnt/ssd/Models/Devstral-Small-2-24B-Instruct-2512-IQ4_NL.gguf -fa 1 -c 65536 -ctk q4_0 -ctv q4_0"; }; # https://huggingface.co/unsloth/SmolLM3-3B-128K-GGUF/tree/main "smollm3-3b-instruct" = { name = "SmolLM3(3B) - Instruct"; - cmd = "${pkgs.reichard.llama-cpp}/bin/llama-server --port \${PORT} -m /mnt/ssd/Models/SmolLM3-3B-128K-UD-Q4_K_XL.gguf --ctx-size 98304 --temp 0.6 --top-p 0.95 --reasoning-budget 0 -sm none"; + cmd = "${pkgs.reichard.llama-cpp}/bin/llama-server --port \${PORT} -m /mnt/ssd/Models/SmolLM3-3B-128K-UD-Q4_K_XL.gguf -c 98304 --temp 0.6 --top-p 0.95 --reasoning-budget 0 -dev CUDA0"; }; # https://huggingface.co/unsloth/ERNIE-4.5-21B-A3B-PT-GGUF/tree/main "ernie4.5-21b-instruct" = { name = "ERNIE4.5 (21B) - Instruct"; - cmd = "${pkgs.reichard.llama-cpp}/bin/llama-server --port \${PORT} -m /mnt/ssd/Models/ERNIE-4.5-21B-A3B-PT-UD-Q4_K_XL.gguf --ctx-size 98304 --temp 0.7 --min-p 0.0 --top-p 0.8 --top-k 20"; + cmd = "${pkgs.reichard.llama-cpp}/bin/llama-server --port \${PORT} -m /mnt/ssd/Models/ERNIE-4.5-21B-A3B-PT-UD-Q4_K_XL.gguf -c 98304 --temp 0.7 --min-p 0.0 --top-p 0.8 --top-k 20"; }; # https://huggingface.co/unsloth/Qwen2.5-Coder-7B-Instruct-128K-GGUF/tree/main "qwen2.5-coder-7b-instruct" = { name = "Qwen2.5 Coder (7B) - Instruct"; - cmd = "${pkgs.reichard.llama-cpp}/bin/llama-server -m /mnt/ssd/Models/Qwen2.5-Coder-7B-Instruct-Q8_0.gguf --fim-qwen-7b-default --ctx-size 131072 --port \${PORT}"; + cmd = "${pkgs.reichard.llama-cpp}/bin/llama-server -m /mnt/ssd/Models/Qwen2.5-Coder-7B-Instruct-Q8_0.gguf --fim-qwen-7b-default -c 131072 --port \${PORT}"; }; # https://huggingface.co/unsloth/Qwen2.5-Coder-3B-Instruct-128K-GGUF/tree/main "qwen2.5-coder-3b-instruct" = { name = "Qwen2.5 Coder (3B) - Instruct"; - cmd = "${pkgs.reichard.llama-cpp}/bin/llama-server -m /mnt/ssd/Models/Qwen2.5-Coder-3B-Instruct-Q4_K_M.gguf --fim-qwen-3b-default --ctx-size 20000 -ts 60,40 --port \${PORT}"; + cmd = "${pkgs.reichard.llama-cpp}/bin/llama-server -m /mnt/ssd/Models/Qwen2.5-Coder-3B-Instruct-Q4_K_M.gguf --fim-qwen-3b-default -c 20000 -ts 60,40 --port \${PORT}"; }; # https://huggingface.co/unsloth/Qwen3-VL-8B-Instruct-GGUF/tree/main "qwen3-8b-vision" = { name = "Qwen3 Vision (8B) - Thinking"; - cmd = "${pkgs.reichard.llama-cpp}/bin/llama-server --port \${PORT} -m /mnt/ssd/Models/Qwen3-VL-8B-Instruct-UD-Q4_K_XL.gguf --mmproj /mnt/ssd/Models/Qwen3-VL-8B-Instruct-UD-Q4_K_XL_mmproj-F16.gguf --ctx-size 131072 --temp 0.7 --min-p 0.0 --top-p 0.8 --top-k 20 --cache-type-k q4_0 --cache-type-v q4_0"; + cmd = "${pkgs.reichard.llama-cpp}/bin/llama-server --port \${PORT} -m /mnt/ssd/Models/Qwen3-VL-8B-Instruct-UD-Q4_K_XL.gguf --mmproj /mnt/ssd/Models/Qwen3-VL-8B-Instruct-UD-Q4_K_XL_mmproj-F16.gguf -c 131072 --temp 0.7 --min-p 0.0 --top-p 0.8 --top-k 20 -ctk q4_0 -ctk q4_0"; }; # https://huggingface.co/mradermacher/OLMoE-1B-7B-0125-Instruct-GGUF/tree/main