dotfiles/modules/home/devtools/opencode.nix

107 lines
3 KiB
Nix

{ config, lib, pkgs, customPkgs, ... }:
let
inherit (lib) mkEnableOption mkOption types mkIf;
cfg = config.rsydn.opencode;
# Build the config JSON, filtering out null/empty values
opencodeConfig = lib.filterAttrs (_: v: v != null && v != { }) {
"$schema" = "https://opencode.ai/config.json";
theme = cfg.theme;
model = cfg.model;
small_model = cfg.smallModel;
autoupdate = false; # Nix manages updates
mcp = if cfg.mcpServers != { } then cfg.mcpServers else null;
keybinds = if cfg.keybinds != { } then cfg.keybinds else null;
};
in {
options.rsydn.opencode = {
enable = mkEnableOption "OpenCode CLI with managed configuration";
package = mkOption {
type = types.nullOr types.package;
default = customPkgs.opencode;
description = ''
OpenCode package to use. Defaults to the custom-built package
from packages/opencode.nix via customPkgs.
'';
};
theme = mkOption {
type = types.str;
default = "catppuccin";
description = "UI theme for OpenCode TUI";
};
model = mkOption {
type = types.str;
default = "anthropic/claude-sonnet-4-5";
description = "Primary LLM model identifier";
};
smallModel = mkOption {
type = types.str;
default = "anthropic/claude-haiku-3-5";
description = "Lightweight model for tasks like title generation";
};
mcpServers = mkOption {
type = types.attrs;
default = { };
example = {
nixos = {
type = "stdio";
command = "uvx";
args = [ "mcp-nixos" ];
};
};
description = "MCP server configurations";
};
keybinds = mkOption {
type = types.attrs;
default = { };
description = "Custom keybinding overrides";
};
# Future extension points (joelhooks-style)
agents = mkOption {
type = types.attrsOf types.path;
default = { };
description = ''
Custom agent markdown files.
Keys become filenames under ~/.config/opencode/agent/
'';
};
commands = mkOption {
type = types.attrsOf types.path;
default = { };
description = ''
Custom command markdown files.
Keys become filenames under ~/.config/opencode/command/
'';
};
extraConfig = mkOption {
type = types.attrs;
default = { };
description = "Additional config options to merge into opencode.json";
};
};
config = mkIf cfg.enable {
home.packages = lib.optional (cfg.package != null) cfg.package;
xdg.configFile = {
# Global config file
"opencode/opencode.json".text =
builtins.toJSON (opencodeConfig // cfg.extraConfig);
} // lib.mapAttrs' (name: path:
# Agent markdown files
lib.nameValuePair "opencode/agent/${name}.md" { source = path; })
cfg.agents // lib.mapAttrs' (name: path:
# Command markdown files
lib.nameValuePair "opencode/command/${name}.md" { source = path; })
cfg.commands;
};
}