My collection of nix configurations
at main 262 lines 9.0 kB view raw
1{ 2 config, 3 lib, 4 pkgs, 5 ... 6}: 7 8with lib; 9let 10 cfg = config.programs.andrew-opencode; 11 peonPingPkg = pkgs.peon-ping; 12 agentcraft = pkgs.callPackage ./agentcraft.nix { }; 13 opencodeGitlabPlugin = pkgs.callPackage ./opencode-gitlab-plugin.nix { }; 14 ohMyOpencodeSlim = pkgs.callPackage ./oh-my-opencode-slim.nix { }; 15 opencodeForgeSessionTitle = pkgs.callPackage ./opencode-forge-session-title.nix { }; 16 ohMyOpencode = pkgs.callPackage ./oh-my-opencode.nix { }; 17 openpeonDota2 = pkgs.fetchFromGitHub { 18 owner = "kmelkon"; 19 repo = "openpeon-dota2"; 20 rev = "main"; 21 hash = "sha256-21BZ+pp3N23bIaeo7EripcgilmAlz1k77GrN7sJEFns="; 22 }; 23 superpowers = pkgs.fetchFromGitHub { 24 owner = "obra"; 25 repo = "superpowers"; 26 rev = "363923f74aa9cd7b470c0aaa73dee629a8bfdc90"; 27 hash = "sha256-AyRGXwWI9xHGeHw9vD64cnV19txR/lOtxudcHnbV75I="; 28 }; 29 compoundEngineering = pkgs.fetchFromGitHub { 30 owner = "EveryInc"; 31 repo = "compound-engineering-plugin"; 32 rev = "74fb71731a14485b30b8549c93ff3732b5723179"; 33 hash = "sha256-rvPC6NWG1vZG3OFpor84wkYuAZCtLyoYtU6q1deQl1c="; 34 }; 35 compoundEngineeringPatched = 36 pkgs.runCommand "compound-engineering-patched" 37 { 38 nativeBuildInputs = [ 39 pkgs.gnused 40 pkgs.findutils 41 ]; 42 } 43 '' 44 cp -r ${compoundEngineering}/. $out 45 chmod -R u+w $out 46 47 # Patch invalid color values, remove model: inherit, and fix haiku model reference 48 find $out/plugins/compound-engineering/agents -name "*.md" -type f -exec sed -i \ 49 -e 's/^[[:space:]]*color:[[:space:]]*blue[[:space:]]*$/color: info/' \ 50 -e 's/^[[:space:]]*color:[[:space:]]*yellow[[:space:]]*$/color: warning/' \ 51 -e 's/^[[:space:]]*color:[[:space:]]*cyan[[:space:]]*$/color: info/' \ 52 -e 's/^[[:space:]]*color:[[:space:]]*purple[[:space:]]*$/color: accent/' \ 53 -e 's/^[[:space:]]*color:[[:space:]]*violet[[:space:]]*$/color: accent/' \ 54 -e '/^[[:space:]]*model:[[:space:]]*inherit[[:space:]]*$/d' \ 55 -e 's/^model:[[:space:]]*haiku[[:space:]]*$/model: gitlab\/duo-chat-haiku-4-5/' \ 56 {} + 57 ''; 58 cePlugin = "${compoundEngineeringPatched}/plugins/compound-engineering"; 59 gitlabSkills = builtins.fetchGit { 60 url = "https://gitlab.com/gitlab-org/ai/skills.git"; 61 rev = "3c2877076d453dfa1a3ea392e1293473dcae2cd2"; 62 narHash = "sha256-mHdoOS/LzaSyuCvTIzxjJiABXcfZA4ljVR0vaDHoTk4="; 63 }; 64 glSkillDirs = builtins.readDir "${gitlabSkills}/skills"; 65 glSkillFiles = lib.mapAttrs' ( 66 name: _: lib.nameValuePair "opencode/skills/${name}" { source = "${gitlabSkills}/skills/${name}"; } 67 ) (lib.filterAttrs (_: type: type == "directory") glSkillDirs); 68 69 ppSkillDirs = builtins.readDir "${peonPingPkg}/share/peon-ping/skills"; 70 ppSkillFiles = lib.mapAttrs' ( 71 name: _: 72 lib.nameValuePair "opencode/skills/${name}" { 73 source = "${peonPingPkg}/share/peon-ping/skills/${name}"; 74 } 75 ) (lib.filterAttrs (_: type: type == "directory") ppSkillDirs); 76 77 # Helper to create xdg.configFile entries for all agent files 78 ceAgentDirs = builtins.readDir "${cePlugin}/agents"; 79 ceAgentFiles = lib.concatMapAttrs ( 80 category: _: 81 let 82 categoryDir = "${cePlugin}/agents/${category}"; 83 files = builtins.readDir categoryDir; 84 in 85 lib.mapAttrs' ( 86 name: _: lib.nameValuePair "opencode/agents/${name}" { source = "${categoryDir}/${name}"; } 87 ) (lib.filterAttrs (_: type: type == "regular") files) 88 ) (lib.filterAttrs (_: type: type == "directory") ceAgentDirs); 89 90 # Helper to create xdg.configFile entries for all skill directories 91 ceSkillDirs = builtins.readDir "${cePlugin}/skills"; 92 ceSkillFiles = lib.mapAttrs' ( 93 name: _: lib.nameValuePair "opencode/skills/${name}" { source = "${cePlugin}/skills/${name}"; } 94 ) (lib.filterAttrs (_: type: type == "directory") ceSkillDirs); 95in 96{ 97 options.programs.andrew-opencode = { 98 enable = mkEnableOption "andrew's opencode config"; 99 variant = mkOption { 100 type = types.enum [ 101 "superpowers" 102 "compound" 103 "omo" 104 ]; 105 default = "superpowers"; 106 description = "Which opencode plugin system to use"; 107 }; 108 }; 109 110 config = mkIf cfg.enable (mkMerge [ 111 # Common config — all variants 112 { 113 home.packages = [ 114 agentcraft 115 ]; 116 programs.opencode = { 117 enable = true; 118 settings = { 119 theme = "stylix"; 120 provider.gitlab.models = { 121 "duo-chat-haiku-4-5".cost = { 122 input = 0.8; 123 output = 4; 124 }; 125 "duo-chat-sonnet-4-5".cost = { 126 input = 3; 127 output = 15; 128 }; 129 "duo-chat-opus-4-5".cost = { 130 input = 15; 131 output = 75; 132 }; 133 "duo-chat-sonnet-4-6".cost = { 134 input = 3; 135 output = 15; 136 }; 137 "duo-chat-opus-4-6".cost = { 138 input = 15; 139 output = 75; 140 }; 141 "duo-chat-gpt-5-2-codex".cost = { 142 input = 2; 143 output = 8; 144 }; 145 "duo-chat-gpt-5-mini".cost = { 146 input = 0.4; 147 output = 1.6; 148 }; 149 }; 150 mcp.glean = { 151 type = "remote"; 152 url = "https://gitlab-be.glean.com/mcp/default"; 153 }; 154 share = "disabled"; 155 small_model = "gitlab/duo-chat-haiku-4-5"; 156 }; 157 }; 158 159 programs.peon-ping = { 160 enable = true; 161 settings = { 162 default_pack = "peon"; 163 volume = 0.5; 164 enabled = true; 165 desktop_notifications = true; 166 pack_rotation = [ 167 "peon" 168 "peasant" 169 "hd2_helldiver" 170 "ocarina_of_time" 171 "protoss" 172 "dota2_witch_doctor" 173 ]; 174 pack_rotation_mode = "round-robin"; 175 categories = { 176 "session.start" = true; 177 "task.complete" = true; 178 "task.error" = true; 179 "input.required" = true; 180 "resource.limit" = true; 181 "user.spam" = true; 182 }; 183 }; 184 installPacks = [ 185 "peon" 186 "peasant" 187 "hd2_helldiver" 188 "ocarina_of_time" 189 { 190 name = "protoss"; 191 src = pkgs.fetchFromGitHub { 192 owner = "codyborn"; 193 repo = "protoss-sounds"; 194 rev = "v1.0.0"; 195 hash = "sha256-uQI7YUobkfAUu/0xhM4EuCq9GQ1d87UmsNCefAg2fGs="; 196 }; 197 } 198 { 199 name = "dota2_witch_doctor"; 200 src = "${openpeonDota2}/dota2_witch_doctor"; 201 } 202 ]; 203 enableZshIntegration = true; 204 }; 205 206 xdg.configFile = { 207 "opencode/plugins/peon-ping.ts".source = 208 "${peonPingPkg}/share/peon-ping/adapters/opencode/peon-ping.ts"; 209 "opencode/plugins/peon-ping-internals.ts".source = 210 "${peonPingPkg}/share/peon-ping/adapters/opencode/peon-ping-internals.ts"; 211 "opencode/peon-ping/config.json".source = config.home.file.".openpeon/config.json".source; 212 "opencode/plugins/gitlab-plugin.js".source = 213 "${opencodeGitlabPlugin}/lib/node_modules/opencode-gitlab-plugin/dist/index.js"; 214 "opencode/plugins/forge-session-title.js".source = 215 "${opencodeForgeSessionTitle}/lib/node_modules/opencode-forge-session-title/dist/index.js"; 216 "opencode/skills/writing-commit-messages".source = ./skills/writing-commit-messages; 217 } 218 // glSkillFiles 219 // ppSkillFiles; 220 } 221 222 # Variant: superpowers (current behavior) 223 (mkIf (cfg.variant == "superpowers") { 224 programs.opencode.settings = { 225 plugin = [ ]; 226 agent = { 227 explore.disable = true; 228 general.disable = true; 229 }; 230 }; 231 xdg.configFile = { 232 "opencode/oh-my-opencode-slim.jsonc".source = ./oh-my-opencode-slim.jsonc; 233 "opencode/plugins/oh-my-opencode-slim.js".source = 234 "${ohMyOpencodeSlim}/lib/node_modules/oh-my-opencode-slim/dist/index.js"; 235 "opencode/plugins/superpowers.js".source = "${superpowers}/.opencode/plugins/superpowers.js"; 236 "opencode/skills/superpowers".source = "${superpowers}/skills"; 237 }; 238 }) 239 240 # Variant: compound engineering 241 (mkIf (cfg.variant == "compound") { 242 programs.opencode.settings = { 243 plugin = [ ]; 244 mcp.context7 = { 245 type = "remote"; 246 url = "https://mcp.context7.com/mcp"; 247 }; 248 }; 249 xdg.configFile = ceAgentFiles // ceSkillFiles; 250 }) 251 252 # Variant: oh-my-openagent (omo) 253 (mkIf (cfg.variant == "omo") { 254 programs.opencode.settings.plugin = [ ]; 255 xdg.configFile = { 256 "opencode/oh-my-opencode.jsonc".source = ./oh-my-opencode.jsonc; 257 "opencode/plugins/oh-my-opencode.js".source = 258 "${ohMyOpencode}/lib/node_modules/oh-my-opencode/dist/index.js"; 259 }; 260 }) 261 ]); 262}