Files
nixos-4screen/home/sam/home.nix
2026-05-04 11:58:58 +10:00

510 lines
10 KiB
Nix

{config, pkgs, ... }:
{
xdg.configFile."tickrs/config.yml".source =
./config/tickrs/config.yml;
xdg.configFile."apprise/apprise.yml".source =
./config/apprise/apprise.yml;
xdg.configFile."nvim/init.lua".source = ./nvim/init.lua;
xdg.configFile."nvim/lua".source = ./nvim/lua;
xdg.configFile."atuin" = { source = ./config/atuin; recursive = true; };
xdg.configFile."kitty" = { source = ./config/kitty; recursive = true; };
xdg.configFile."zellij" = { source = ./config/zellij; recursive = true; };
xdg.configFile."lazygit" = { source = ./config/lazygit; recursive = true; };
xdg.configFile."btop" = { source = ./config/btop; recursive = true; };
xdg.configFile."gh" = { source = ./config/gh; recursive = true; };
xdg.configFile."starship.toml".source = ./config/starship.toml;
xdg.configFile."niri" = { source = ./config/niri; recursive = true; };
xdg.configFile."waybar" = { source = ./config/waybar; recursive = true; };
xdg.configFile."zsh/local.zsh".source = ./config/zsh/local.zsh;
xdg.configFile."goose" = {
source = ./config/goose;
recursive = true;
};
home.username = "sam";
home.homeDirectory = "/home/sam";
home.stateVersion = "25.11";
services.swaync = {
enable = true;
settings = {
positionX = "right";
positionY = "top";
control-center-margin-top = 10;
control-center-margin-right = 10;
control-center-width = 380;
notification-window-width = 400;
notification-icon-size = 64;
notification-body-image-height = 100;
notification-body-image-width = 200;
timeout = 10;
timeout-low = 5;
timeout-critical = 0;
widgets = [
"notifications"
"mpris"
"volume"
"backlight"
"buttons-grid"
];
"widget-config" = {
notifications = {
"hide-on-clear" = false;
"hide-on-action" = true;
};
mpris = {
"image-size" = 96;
"image-radius" = 12;
};
volume = {
label = "󰕾";
};
backlight = {
label = "󰃞";
};
"buttons-grid" = {
actions = [
{
label = "󰐥";
command = "systemctl poweroff";
}
{
label = "󰜉";
command = "systemctl reboot";
}
{
label = "󰍁";
command = "swaylock";
}
];
};
};
};
};
# services.mako = {
# enable = true;
#
# # Essential Wayland integration
# layer = "overlay"; # Required for Niri
# output = ""; # Shows on all outputs
#
# # Design (matches your Dunst preferences)
# font = "JetBrainsMono Nerd Font 10";
# backgroundColor = "#1e1e2e";
# borderColor = "#89b4fa";
# borderSize = 2;
# borderRadius = 5;
#
# # Positioning
# anchor = "top-right";
# margin = "30,30"; # X,Y from anchor
# width = 300;
# height = 200;
#
# # Behavior
# defaultTimeout = 10000; # ms
# sort = "-time"; # Newest on top-right
#
# settings = {
# "[urgency=high]" = {
# background-color = "#f38ba8";
# default-timeout = 0;
# };
# };
# };
# Deploy the script to ~/.local/bin (Nix handles creation/permissions)
home.file.".local/bin/task-due-notify" = {
source = ./bin/task-due-notify.sh;
executable = true;
};
systemd.user.timers.task-due-notify = {
Unit = {
Description = "Timer for Taskwarrior due notifications";
};
Timer = {
OnBootSec = "1min";
OnCalendar = "*:*:0/1"; # Every 5 minutes
Persistent = true;
};
Install = {
WantedBy = ["timers.target"];
};
};
# systemd.user.services.task-due-notify = {
# Unit = {
# Description = "Check for due Taskwarrior tasks and notify";
# };
# Service = {
# Type = "oneshot";
# ExecStart = "${pkgs.bash}/bin/bash${config.home.homeDirectory}/.local/bin/task-due-notify";
# };
# };
# Systemd user timer to run the service periodically
# systemd.user.timers.task-due-notify = {
# Unit = {
# Description = "Timer for Taskwarrior due notifications";
# };
# Timer = {
# OnBootSec = "1min";
# OnUnitActiveSec = "1min";
# AccuracySec = "30s";
# Persistent = true;
# };
# Install = {
# WantedBy = ["timers.target"];
# };
# };
systemd.user.services.task-due-notify = {
Unit = {
Description = "Check for due Taskwarrior tasks and notify";
};
Service = {
Type = "oneshot";
ExecStart = "${pkgs.bash}/bin/bash ${config.home.homeDirectory}/.local/bin/task-due-notify";
Environment = [
"PATH=${pkgs.gnugrep}/bin:${pkgs.gnused}/bin:${pkgs.coreutils}/bin:${pkgs.taskwarrior3}/bin:${pkgs.jq}/bin:${pkgs.curl}/bin:${pkgs.libnotify}/bin:/usr/bin:/bin"
"DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus"
];
};
};
systemd.user.services.kdeconnect-indicator = {
Unit = {
Description = "KDE Connect indicator";
};
Service = {
Type = "simple";
ExecStart = "${pkgs.kdePackages.kdeconnect-kde}/bin/kdeconnect-indicator";
Restart = "on-failure";
RestartSec = "2s";
};
Install = {
WantedBy = [ "default.target" ];
};
};
systemd.user.services.vorta = {
Unit = {
Description = "Vorta (BorgBackup GUI)";
};
Service = {
Type = "simple";
ExecStart = ''
${pkgs.bash}/bin/bash -lc 'for i in $(seq 1 100); do for s in "$XDG_RUNTIME_DIR"/wayland-*; do if [ -S "$s" ]; then exec ${pkgs.vorta}/bin/vorta; fi; done; sleep 0.2; done; exit 1'
'';
Restart = "on-failure";
RestartSec = "2s";
};
Install = {
WantedBy = [ "default.target" ];
};
};
programs.home-manager.enable = true;
dconf.settings."org/gnome/desktop/interface" = {
color-scheme = "prefer-dark";
};
programs.opencode = {
enable = true;
settings = {
mcp = {
stitch = {
# Use "remote" type to leverage the Stitch API directly
type = "remote";
url = "https://stitch.googleapis.com/mcp";
# Use false if you are using an API Key instead of OAuth
oauth = false;
headers = {
# Nix grabs this from your local shell during 'switch --impure'
"X-Goog-Api-Key" = builtins.getEnv "STITCH_API_KEY";
};
};
home.file.".agents/skills" = {
source = ./config/agents/skills;
recursive = true;
};
home.file.".pi/agent" = {
source = ./config/pi/agent;
recursive = true;
};
# n8n = {
# type = "local";
# command = [
# "npx"
# "-y"
# "supergateway"
# "--streamableHttp"
# "http://n8n.home.lab/mcp-server/http"
# "--header"
# "authorization:Bearer " + builtins.getEnv "N8N_MCP_TOKEN"
# ];
# enabled = true;
# timeout = 30000;
# };
};
};
};
# ---
# Shell (zsh + oh-my-zsh + powerlevel10k)
# ---
programs.zsh = {
enable = true;
autosuggestion.enable = true;
syntaxHighlighting.enable = true;
oh-my-zsh = {
enable = true;
theme = "robbyrussell";
plugins = [ "git" ];
};
shellAliases = {
ls = "eza --icons --git";
ll = "eza -l --icons --git";
la = "eza -la --icons --git";
tree = "eza --tree";
cat = "bat --color=always --paging=never";
};
initExtra = ''
if [ -f "$HOME/.config/zsh/local.zsh" ]; then
source "$HOME/.config/zsh/local.zsh"
fi
# carapace completions
if command -v carapace >/dev/null 2>&1; then
eval "$(carapace _carapace zsh)"
fi
'';
};
# ---
# Shell tools
# ---
programs.atuin = {
enable = true;
enableZshIntegration = true;
};
programs.fzf = {
enable = true;
enableZshIntegration = true;
};
programs.zoxide = {
enable = true;
enableZshIntegration = true;
};
# ---
# Terminal / editor
# ---
# programs.kitty.enable = true;
programs.neovim = {
enable = true;
defaultEditor = true;
extraPackages = with pkgs; [ tree-sitter gcc gnumake];
};
programs.yazi = {
enable = true;
enableZshIntegration = true;
enableBashIntegration = true;
# This sets the command name for the wrapper.
# Many people use 'y' or 'yy' for quick access.
shellWrapperName = "y";
};
home.sessionVariables = {
QT_QPA_PLATFORM = "wayland";
QT_WAYLAND_DISABLE_WINDOWDECORATION = "1";
GOOSE_DISABLE_KEYRING = "1";
};
gtk = {
enable = true;
theme = {
name = "Adwaita-dark";
package = pkgs.gnome-themes-extra;
};
iconTheme = {
name = "breeze-dark";
package = pkgs.kdePackages.breeze-icons;
};
};
qt = {
enable = true;
platformTheme.name = "gtk3";
style.name = "adwaita-dark";
};
# ---
# Packages (NOW list + a few safe essentials)
# ---
home.packages = with pkgs; [
mosquitto
# Input device support
libinput
seatd
# Audio controls
pamixer
playerctl
# Network
networkmanagerapplet
# System Monitoring
swaynotificationcenter # For notification daemon
libnotify
kdePackages.dolphin
kdePackages.kio-extras
kdePackages.kdegraphics-thumbnailers
kdePackages.ffmpegthumbs
kdePackages.ark
adwaita-qt
adwaita-qt6
kdePackages.breeze-icons
nushell
bun
pnpm
# CLI tools
# python3Packages.autogpt
# agentops
(callPackage ../../pkgs/cao-cli.nix { })
ollama
tickrs
taskwarrior3
taskwarrior-tui
glow
pandoc
texlive.combined.scheme-small
swaybg
zathura
zathuraPkgs.zathura_pdf_mupdf
swayimg
qimgv
tmux
vorta
borgbackup
carapace
aider-chat
opencode
goose-cli
gemini-cli-bin
lua-language-server
marksman
nodePackages.typescript
nodePackages.typescript-language-server
nodejs
python3
python3Packages.pynvim
git
curl
wget
tgpt
eza
bat
ripgrep
fd
ticker
btop
lazygit
zellij
tealdeer
navi
# yazi
dua
jq
unzip
zip
p7zip
# This creates a 'pi' command that runs the latest agent via npx
(writeShellScriptBin "pi" ''
${pkgs.nodejs_20}/bin/npx @mariozechner/pi-coding-agent "$@"
'')
];
}
/*
NOTE FOR RECOVERY:
These keys were manually stored in ~/.config/environment.d/10-secrets.conf
to keep them out of the git-tracked Nix store.
Format used in that file:
export OPENAI_API_KEY="sk-proj-..."
export TAVILY_API_KEY="tvly-dev-..."
export GITHUB_TOKEN="ghp_..."
export GEMINI_API_KEY="AIza..."
export DEEPSEEK_API_KEY="sk-..."
export OPENROUTER_API_KEY="sk-or-v1-..."
export STITCH_API_KEY="AQ.Ab8..."
*/