Files
nixpkgs/modules/home-manager/coding/opencode.nix

169 lines
5.1 KiB
Nix
Raw Normal View History

{
config,
lib,
pkgs,
...
}:
with lib; let
cfg = config.coding.opencode;
in {
options.coding.opencode = {
enable = mkEnableOption "opencode AI coding assistant";
agentsInput = mkOption {
type = types.nullOr types.anything;
default = null;
description = ''
The `agents` flake input (your personal AGENTS repo).
When set, skills, context, commands, prompts and the agents.json
are all symlinked from this input.
'';
};
externalSkills = mkOption {
type = types.listOf (types.submodule {
options = {
src = mkOption {
type = types.anything;
description = "Flake input pointing to a skills repository root.";
};
skillsDir = mkOption {
type = types.str;
default = "skills";
description = ''
Subdirectory inside src that contains skill folders.
'';
};
selectSkills = mkOption {
type = types.nullOr (types.listOf types.str);
default = null;
description = ''
List of skill names to cherry-pick from this source.
null means include every skill found in skillsDir.
'';
};
};
});
default = [];
description = ''
External skill sources passed to mkOpencodeSkills.
Each entry maps directly to an element of the externalSkills
list accepted by the AGENTS flake's lib.mkOpencodeSkills.
'';
example = literalExpression ''
[
{ src = inputs.skills-anthropic; selectSkills = [ "claude-api" ]; }
{ src = inputs.skills-vercel; }
]
'';
};
ohMyOpencodeSettings = mkOption {
type = types.attrs;
default = {};
description = ''
Attributes merged (via recursiveUpdate) on top of the default
oh-my-opencode.json. Use this to set provider-specific model
assignments per machine.
'';
example = literalExpression ''
{
agents.sisyphus.model = "anthropic/claude-opus-4-5";
categories.ultrabrain.model = "anthropic/claude-opus-4-5";
}
'';
};
extraSettings = mkOption {
type = types.attrs;
default = {};
description = ''
Extra opencode settings merged (via mkMerge) into
programs.opencode.settings. Use this to add provider
configuration that is specific to a machine or organisation.
'';
example = literalExpression ''
{
provider.anthropic = {
name = "Anthropic";
models."claude-opus-4-5" = { limit.context = 200000; };
};
}
'';
};
2026-04-01 14:10:41 +02:00
extraPlugins = mkOption {
type = types.listOf types.str;
default = [];
description = ''
Additional opencode plugins to add to the plugin list.
Each entry is a path or package name passed to opencode's plugin array.
'';
};
};
config = mkIf cfg.enable {
# --- Skills (merged from personal AGENTS repo + optional external skills) ---
xdg.configFile."opencode/skills" = mkIf (cfg.agentsInput != null) {
source = cfg.agentsInput.lib.mkOpencodeSkills {
inherit pkgs;
customSkills = "${cfg.agentsInput}/skills";
2026-04-03 08:31:15 +02:00
externalSkills =
map (
entry:
{inherit (entry) src skillsDir;}
// optionalAttrs (entry.selectSkills != null) {inherit (entry) selectSkills;}
)
cfg.externalSkills;
};
};
# --- Static config dirs from AGENTS repo ---
xdg.configFile."opencode/context" = mkIf (cfg.agentsInput != null) {
source = "${cfg.agentsInput}/context";
};
xdg.configFile."opencode/commands" = mkIf (cfg.agentsInput != null) {
source = "${cfg.agentsInput}/commands";
};
xdg.configFile."opencode/prompts" = mkIf (cfg.agentsInput != null) {
source = "${cfg.agentsInput}/prompts";
};
# --- Core opencode program settings ---
programs.opencode = {
enable = true;
enableMcpIntegration = true;
settings = mkMerge [
{
theme = "opencode";
2026-04-01 14:10:41 +02:00
plugin = ["oh-my-opencode"] ++ cfg.extraPlugins;
formatter = {
alejandra = {
command = ["alejandra" "-q" "-"];
extensions = [".nix"];
};
};
}
# Load agents.json from AGENTS repo when available
(mkIf (cfg.agentsInput != null) {
agent = builtins.fromJSON (builtins.readFile "${cfg.agentsInput}/agents/agents.json");
})
# Machine/org-specific provider config
cfg.extraSettings
];
};
# --- oh-my-opencode plugin config ---
# Base defaults (no models — those must be set per machine via ohMyOpencodeSettings)
home.file.".config/opencode/oh-my-opencode.json".text = builtins.toJSON (
recursiveUpdate
{
"$schema" = "https://raw.githubusercontent.com/code-yeongyu/oh-my-opencode/master/assets/oh-my-opencode.schema.json";
google_auth = false;
disabled_mcps = ["context7" "websearch"];
}
cfg.ohMyOpencodeSettings
);
};
}