This commit is contained in:
2026-10-03 17:23:30 +03:00
parent 1c77ae658e
commit 85d3e3747b
7 changed files with 386 additions and 4 deletions
+281
View File
@@ -0,0 +1,281 @@
# Declarative OpenCode + oh-my-openagent (oh-my-opencode) plugin setup.
#
# Mirrors ~/.config/opencode/ on the current workstation.
# Imported by home/server.nix (sapphira). Auto-enables programs.opencode.
#
# Three files this module owns on disk (via xdg.configFile):
# ~/.config/opencode/opencode.json <- programs.opencode.settings
# ~/.config/opencode/tui.json <- programs.opencode.tui
# ~/.config/opencode/oh-my-openagent.json <- oh-my-openagent plugin config
#
# Override any field in the importing module if needed.
{
config,
lib,
pkgs,
...
}:
let
# Body of ~/.config/opencode/oh-my-openagent.json.
# Loaded by the oh-my-openagent opencode plugin on startup.
ohMyOpenagentConfig = {
"$schema" = "https://raw.githubusercontent.com/code-yeongyu/oh-my-openagent/dev/assets/oh-my-opencode.schema.json";
agents = {
sisyphus = {
model = "opencode/claude-opus-5";
variant = "max";
fallback_models = [
{ model = "opencode/kimi-k3"; }
{
model = "opencode/gpt-5.6-sol";
variant = "medium";
}
{ model = "opencode/glm-5"; }
{ model = "opencode/big-pickle"; }
];
};
hephaestus = {
model = "opencode/gpt-5.6-sol";
variant = "medium";
};
oracle = {
model = "opencode/gpt-5.6-sol";
variant = "xhigh";
fallback_models = [
{
model = "opencode/gemini-3.1-pro";
variant = "high";
}
{
model = "opencode/claude-opus-5";
variant = "max";
}
];
};
librarian = {
model = "minimax-coding-plan/MiniMax-M3";
};
explore = {
model = "opencode/gpt-5-nano";
fallback_models = [
{ model = "minimax-coding-plan/MiniMax-M3"; }
];
};
"multimodal-looker" = {
model = "opencode/gpt-5.6-sol";
variant = "low";
fallback_models = [
{ model = "opencode/gpt-5-nano"; }
];
};
prometheus = {
model = "opencode/claude-fable-5";
variant = "high";
fallback_models = [
{
model = "opencode/kimi-k3";
variant = "high";
}
];
};
metis = {
model = "opencode/claude-opus-5";
variant = "high";
fallback_models = [
{
model = "opencode/kimi-k3";
variant = "low";
}
];
};
momus = {
model = "opencode/gpt-5.6-sol";
variant = "xhigh";
fallback_models = [
{
model = "opencode/claude-opus-5";
variant = "max";
}
{
model = "opencode/gemini-3.1-pro";
variant = "high";
}
];
};
atlas = {
model = "opencode/claude-sonnet-4-6";
fallback_models = [
{
model = "opencode/gpt-5.6-sol";
variant = "medium";
}
{ model = "minimax-coding-plan/MiniMax-M3"; }
];
};
"sisyphus-junior" = {
model = "opencode/claude-sonnet-4-6";
fallback_models = [
{
model = "opencode/gpt-5.6-sol";
variant = "medium";
}
{ model = "minimax-coding-plan/MiniMax-M3"; }
{ model = "opencode/big-pickle"; }
];
};
};
categories = {
"visual-engineering" = {
model = "opencode/gemini-3.1-pro";
variant = "high";
fallback_models = [
{ model = "opencode/glm-5"; }
{
model = "opencode/claude-opus-5";
variant = "max";
}
];
};
ultrabrain = {
model = "opencode/gpt-5.6-sol";
variant = "xhigh";
fallback_models = [
{
model = "opencode/gemini-3.1-pro";
variant = "high";
}
{
model = "opencode/claude-opus-5";
variant = "max";
}
];
};
deep = {
model = "opencode/gpt-5.6-sol";
variant = "medium";
fallback_models = [
{
model = "opencode/claude-opus-5";
variant = "max";
}
{
model = "opencode/gemini-3.1-pro";
variant = "high";
}
];
};
artistry = {
model = "opencode/gemini-3.1-pro";
variant = "high";
fallback_models = [
{
model = "opencode/claude-opus-5";
variant = "max";
}
{
model = "opencode/gpt-5.6-sol";
variant = "high";
}
];
};
quick = {
model = "opencode/gpt-5.4-mini";
fallback_models = [
{ model = "opencode/gemini-3-flash"; }
{ model = "minimax-coding-plan/MiniMax-M3"; }
{ model = "opencode/gpt-5-nano"; }
];
};
"unspecified-low" = {
model = "opencode/claude-sonnet-4-6";
fallback_models = [
{
model = "opencode/gpt-5.6-sol";
variant = "medium";
}
{ model = "opencode/gemini-3-flash"; }
{ model = "minimax-coding-plan/MiniMax-M3"; }
];
};
"unspecified-high" = {
model = "opencode/claude-sonnet-4-6";
fallback_models = [
{
model = "opencode/gpt-5.6-sol";
variant = "medium";
}
{ model = "opencode/gemini-3-flash"; }
{ model = "minimax-coding-plan/MiniMax-M3"; }
];
};
writing = {
model = "opencode/gemini-3-flash";
fallback_models = [
{ model = "opencode/claude-sonnet-4-6"; }
{ model = "minimax-coding-plan/MiniMax-M3"; }
];
};
};
};
in
{
programs.opencode = {
enable = true;
# npx for MCP servers (webpage-mcp) and the plugin loader itself.
# nodejs_22 includes npm; plain nodejs does NOT.
extraPackages = [ pkgs.nodejs_22 ];
# ~/.config/opencode/opencode.json
settings = {
plugin = [ "oh-my-openagent@latest" ];
mcp = {
webpage = {
type = "local";
command = [
"npx"
"-y"
"-p"
"webpage-mcp@latest"
"webpage-mcp-stdio"
];
};
};
};
# ~/.config/opencode/tui.json
# Mirrors workstation: oh-my-openagent also registered for the TUI.
tui = {
plugin = [ "oh-my-openagent@latest" ];
};
};
# ~/.config/opencode/oh-my-openagent.json — read by the plugin on startup.
xdg.configFile."opencode/oh-my-openagent.json".text = builtins.toJSON ohMyOpenagentConfig;
# Expose `opencode web` as a systemd user service. nginx on sapphira
# proxies https://opencode.zeroq.su -> 127.0.0.1:4096.
#
# --hostname 0.0.0.0 binds the listener to every interface (matches the
# "0.0.0.0" intent; nginx then reverse-proxies 127.0.0.1:4096 internally).
# --cors https://opencode.zeroq.su lets the browser session reach the
# server from that origin without CORS rejection.
#
# SECURITY: with no password, anyone reaching the upstream socket gets full
# opencode. Bind 0.0.0.0 + listener == bridge == shell. The password is
# supplied via sops-managed EnvironmentFile, declared in modules/users.nix
# and decrypted to a path hardcoded here (home-manager modules cannot read
# `config.sops.*` — sops-nix options are NixOS-only).
programs.opencode.web = {
enable = true;
environmentFile = "${config.home.homeDirectory}/.config/opencode/server.env";
extraArgs = [
"--hostname"
"0.0.0.0"
"--cors"
"https://opencode.zeroq.su"
];
};
}
+1
View File
@@ -8,6 +8,7 @@
{
imports = [
./minimal.nix
./modules/opencode.nix
];
home.file = xlib.helpers.mkSymlinks config {
"${config.home.homeDirectory}/External/Music" = "Music";