Session overhaul: dev tooling, cleanup, theming, fixes

Tooling:
- nh + nvd/nom/statix/deadnix/comma (new programs/nix.nix); GC via nh clean
- zoxide (cd), atuin, just, lazydocker, dust, duf, difftastic (git dft)

Structure:
- rename desktop -> konishi; homeConfigurations -> "user@host" for nh autodetect

Removals (heavy/unused):
- android-studio, unity/.NET/omnisharp/vscode, kicad, zoom, calibre,
  google-fonts, nerd-dictation

Screen recording:
- kooha + vokoscreen-ng + `webcam` corner-cam command/window-rule

Fixes:
- WEBKIT_DISABLE_DMABUF_RENDERER moved to common (electron/tauri on intel)
- kitty pinned to Catppuccin-Mocha; darkman no longer toggles kitty/claude
- claude theme dark + statusline locale fix
- ssh: migrate to settings API + multiplexing/keepalive/AddKeysToAgent;
  gpg-agent enableSshSupport
- silence hyprland configType / gtk4 / xdg userDirs deprecations

Flake hygiene:
- follows=nixpkgs for foundry/hardware/rose-pine/zen/spicetify (10->5 nixpkgs)
- zoxide _ZO_DOCTOR=0

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Miguel Palhas
2026-06-27 18:17:25 +01:00
parent 474bd840d2
commit 39e6276c7d
23 changed files with 569 additions and 682 deletions
+1 -1
View File
@@ -20,7 +20,7 @@ _:
enable = true;
defaultApplications = {
# web
"text/html" = "google-chrome.desktop";
"text/html" = "zen-twilight.desktop";
"x-scheme-handler/http" = "zen-twilight.desktop";
"x-scheme-handler/https" = "zen-twilight.desktop";
"x-scheme-handler/avbout" = "zen-twilight.desktop";
-1
View File
@@ -6,7 +6,6 @@
home.packages = with pkgs; [
blender
prusa-slicer
google-fonts
];
fonts.fontconfig.enable = true;
+55 -50
View File
@@ -1,64 +1,69 @@
{ pkgs, inputs, ... }:
{
home.file.".default-npm-packages".text = ''
@anthropic-ai/sandbox-runtime
@beads/bd
'';
home = {
packages = with pkgs; [
inputs.claude-code.packages.${pkgs.stdenv.hostPlatform.system}.default
home.packages = with pkgs; [
inputs.claude-code.packages.${pkgs.stdenv.hostPlatform.system}.default
# sandbox
bubblewrap
socat
libseccomp
# sandbox
bubblewrap
socat
libseccomp
# voice
sox
# voice
sox
# beads
dolt
];
# beads
dolt
];
file = {
".default-npm-packages".text = ''
@anthropic-ai/sandbox-runtime
@beads/bd
'';
# Commands
home.file.".claude/commands/merge.md".source = ./commands/merge.md;
home.file.".claude/commands/update.md".source = ./commands/update.md;
home.file.".claude/commands/download-playlist.md".source = ./commands/download-playlist.md;
# Commands
".claude/commands/merge.md".source = ./commands/merge.md;
".claude/commands/update.md".source = ./commands/update.md;
".claude/commands/download-playlist.md".source = ./commands/download-playlist.md;
# Skills: agents
home.file.".claude/skills/designer-bold/SKILL.md".source = ./skills/designer-bold/SKILL.md;
home.file.".claude/skills/designer/SKILL.md".source = ./skills/designer/SKILL.md;
home.file.".claude/skills/frontend-design/SKILL.md".source = ./skills/frontend-design/SKILL.md;
home.file.".claude/skills/analyze-branch/SKILL.md".source = ./skills/analyze-branch/SKILL.md;
home.file.".claude/skills/oracle/SKILL.md".source = ./skills/oracle/SKILL.md;
home.file.".claude/skills/librarian/SKILL.md".source = ./skills/librarian/SKILL.md;
# Skills: agents
".claude/skills/designer-bold/SKILL.md".source = ./skills/designer-bold/SKILL.md;
".claude/skills/designer/SKILL.md".source = ./skills/designer/SKILL.md;
".claude/skills/frontend-design/SKILL.md".source = ./skills/frontend-design/SKILL.md;
".claude/skills/analyze-branch/SKILL.md".source = ./skills/analyze-branch/SKILL.md;
".claude/skills/oracle/SKILL.md".source = ./skills/oracle/SKILL.md;
".claude/skills/librarian/SKILL.md".source = ./skills/librarian/SKILL.md;
# Skills: knowledge
home.file.".claude/skills/git-master/SKILL.md".source = ./skills/git-master/SKILL.md;
home.file.".claude/skills/planning-with-files/SKILL.md".source =
./skills/planning-with-files/SKILL.md;
home.file.".claude/skills/react-patterns/SKILL.md".source = ./skills/react-patterns/SKILL.md;
home.file.".claude/skills/vercel-react-best-practices/SKILL.md".source =
./skills/vercel-react-best-practices/SKILL.md;
# Skills: knowledge
".claude/skills/git-master/SKILL.md".source = ./skills/git-master/SKILL.md;
".claude/skills/planning-with-files/SKILL.md".source =
./skills/planning-with-files/SKILL.md;
".claude/skills/react-patterns/SKILL.md".source = ./skills/react-patterns/SKILL.md;
".claude/skills/vercel-react-best-practices/SKILL.md".source =
./skills/vercel-react-best-practices/SKILL.md;
# Skills: workflows
home.file.".claude/skills/smart-debug/SKILL.md".source = ./skills/smart-debug/SKILL.md;
home.file.".claude/skills/tdd-cycle/SKILL.md".source = ./skills/tdd-cycle/SKILL.md;
home.file.".claude/skills/security-scan/SKILL.md".source = ./skills/security-scan/SKILL.md;
home.file.".claude/skills/issue/SKILL.md".source = ./skills/issue/SKILL.md;
home.file.".claude/skills/remove-deadcode/SKILL.md".source = ./skills/remove-deadcode/SKILL.md;
home.file.".claude/skills/worktree-compare/SKILL.md".source = ./skills/worktree-compare/SKILL.md;
home.file.".claude/skills/worktree-list/SKILL.md".source = ./skills/worktree-list/SKILL.md;
# Skills: workflows
".claude/skills/smart-debug/SKILL.md".source = ./skills/smart-debug/SKILL.md;
".claude/skills/tdd-cycle/SKILL.md".source = ./skills/tdd-cycle/SKILL.md;
".claude/skills/security-scan/SKILL.md".source = ./skills/security-scan/SKILL.md;
".claude/skills/issue/SKILL.md".source = ./skills/issue/SKILL.md;
".claude/skills/remove-deadcode/SKILL.md".source = ./skills/remove-deadcode/SKILL.md;
".claude/skills/worktree-compare/SKILL.md".source = ./skills/worktree-compare/SKILL.md;
".claude/skills/worktree-list/SKILL.md".source = ./skills/worktree-list/SKILL.md;
# Skills: linear workflow
home.file.".claude/skills/linear-common/COMMON.md".source = ./skills/linear-common/COMMON.md;
home.file.".claude/skills/work/SKILL.md".source = ./skills/work/SKILL.md;
home.file.".claude/skills/yolo/SKILL.md".source = ./skills/yolo/SKILL.md;
# Skills: linear workflow
".claude/skills/linear-common/COMMON.md".source = ./skills/linear-common/COMMON.md;
".claude/skills/work/SKILL.md".source = ./skills/work/SKILL.md;
".claude/skills/yolo/SKILL.md".source = ./skills/yolo/SKILL.md;
home.file.".claude/statusline.sh" = {
source = ./statusline.sh;
executable = true;
".claude/statusline.sh" = {
source = ./statusline.sh;
executable = true;
};
".claude/CLAUDE.md".source = ./CLAUDE.md;
};
mutableFiles.".claude/settings.json".source = ./settings.json;
};
home.mutableFiles.".claude/settings.json".source = ./settings.json;
home.file.".claude/CLAUDE.md".source = ./CLAUDE.md;
}
+4 -3
View File
@@ -39,6 +39,9 @@
"type": "command",
"command": "~/.claude/statusline.sh"
},
"enabledPlugins": {
"typescript-lsp@claude-plugins-official": true
},
"extraKnownMarketplaces": {
"impeccable": {
"source": {
@@ -77,7 +80,5 @@
"url": "https://ha-mcp.n62.casa/mcp"
}
},
"enabledPlugins": {
"typescript-lsp@claude-plugins-official": true
}
"tui": "fullscreen"
}
+6 -6
View File
@@ -24,17 +24,17 @@
./tmux.nix
];
home.mutableFilesRepoPath = "${config.home.homeDirectory}/projects/nixos-config";
programs = {
home-manager.enable = true;
};
home.packages = with pkgs; [
impala
];
home = {
mutableFilesRepoPath = "${config.home.homeDirectory}/projects/nixos-config";
packages = with pkgs; [
impala
];
username = lib.mkDefault "naps62";
homeDirectory = lib.mkDefault "/home/${config.home.username}";
stateVersion = lib.mkDefault "24.05";
+77 -63
View File
@@ -10,48 +10,56 @@
./spicetify.nix
];
home.packages = with pkgs; [
# various
google-chrome
thunar
obsidian
mpv
obs-studio
calibre
gimp
font-manager
imv
pavucontrol
zathura
libsForQt5.qt5ct
kdePackages.qt6ct
nwg-look
xournalpp
jq
ffmpeg
unzip
home = {
packages = with pkgs; [
# various
google-chrome
thunar
obsidian
mpv
# screen recording — evaluating these
obs-studio
kooha # simple Wayland-native screen+audio recorder
vokoscreen-ng # GUI recorder with webcam overlay
gimp
font-manager
imv
pavucontrol
zathura
libsForQt5.qt5ct
kdePackages.qt6ct
nwg-look
xournalpp
jq
ffmpeg
unzip
# remote desktop
remmina
# remote desktop
remmina
# networking
networkmanagerapplet
mtr
dnsutils
# networking
networkmanagerapplet
mtr
dnsutils
# communication
slack
zoom-us
ferdium
signal-desktop
# communication
slack
ferdium
signal-desktop
# dev tools
yaak
bun
# dev tools
yaak
bun
# themes
tela-icon-theme
];
# themes
tela-icon-theme
];
pointerCursor = {
package = pkgs.numix-cursor-theme;
name = "Numix-Cursor-Light";
};
};
gtk = {
enable = true;
@@ -71,31 +79,37 @@
};
};
home.pointerCursor = {
package = pkgs.numix-cursor-theme;
name = "Numix-Cursor-Light";
xdg.configFile = {
# zathura: include noctalia-generated theme
"zathura/zathurarc".text = ''
include noctaliarc
'';
# gtk: include noctalia-generated css (mkForce to override gtk module)
"gtk-3.0/gtk.css".text = lib.mkForce ''
@import url("noctalia.css");
'';
"gtk-4.0/gtk.css".text = lib.mkForce ''
@import url("noctalia.css");
'';
# qt: use noctalia color scheme. Applied via QT_QPA_PLATFORMTHEME=qt6ct,
# set in the Hyprland env block (and imported into the dbus activation
# environment so the xdph screen-share picker inherits it too).
# custom_palette=true is required for qt5ct/qt6ct to actually apply the
# color scheme; Fusion is used because it fully honors a custom palette
# (Breeze/native styles partly ignore it).
"qt5ct/qt5ct.conf".text = ''
[Appearance]
style=Fusion
custom_palette=true
color_scheme_path=${config.home.homeDirectory}/.config/qt5ct/colors/noctalia.conf
'';
"qt6ct/qt6ct.conf".text = ''
[Appearance]
style=Fusion
custom_palette=true
color_scheme_path=${config.home.homeDirectory}/.config/qt6ct/colors/noctalia.conf
'';
};
# zathura: include noctalia-generated theme
xdg.configFile."zathura/zathurarc".text = ''
include noctaliarc
'';
# gtk: include noctalia-generated css (mkForce to override gtk module)
xdg.configFile."gtk-3.0/gtk.css".text = lib.mkForce ''
@import url("noctalia.css");
'';
xdg.configFile."gtk-4.0/gtk.css".text = lib.mkForce ''
@import url("noctalia.css");
'';
# qt: use noctalia color scheme
xdg.configFile."qt5ct/qt5ct.conf".text = ''
[Appearance]
color_scheme_path=${config.home.homeDirectory}/.config/qt5ct/colors/noctalia.conf
'';
xdg.configFile."qt6ct/qt6ct.conf".text = ''
[Appearance]
color_scheme_path=${config.home.homeDirectory}/.config/qt6ct/colors/noctalia.conf
'';
}
-1
View File
@@ -47,7 +47,6 @@
mkcert
nss.tools
kicad
tea
just # project command runner
+93 -88
View File
@@ -1,98 +1,103 @@
{ pkgs, ... }:
{
xdg.configFile."git/commit-message.txt".source = ./commit-message.txt;
xdg.configFile."git/ignore".source = ./ignore;
programs.git = {
enable = true;
settings = {
user = {
name = "Miguel Palhas";
email = "mpalhas@gmail.com";
};
alias = {
ls = "log --color --graph --oneline --decorate --topo-order --pretty=format:'%C(yellow)%d%Creset %Cgreen(%cr)%Creset %C(bold blue)[%an]%Creset %s %Cred(%h)%Creset' --abbrev-commit";
ll = ''log --reverse --pretty=format:"%C(yellow)%h%Cred%d\ %Creset%s%Cblue\ [%an]" --decorate --numstat'';
conf = "diff --name-only --diff-filter=U";
ba = "branch -a";
pb = "publish";
ps = "push -u";
pr = "pull-request";
ppr = "push-pr";
cpr = "close-pr";
opr = "open-pr";
f = "fetch";
c = "commit --verbose";
d = "diff";
dc = "diff --cached";
co = "checkout";
s = "status -sb";
b = "better-branch";
rb = "rebase";
rbc = "rebase --continue";
w = "commit -am 'wip'";
# Structural (AST-aware) diff on demand; `git d`/`diff` stays delta.
# Accepts args, e.g. `git dft HEAD~3`.
dft = "!GIT_EXTERNAL_DIFF=difft git diff";
};
init = {
defaultBranch = "main";
};
core = {
editor = "nvim";
pager = "delta";
askpass = "";
};
credential = {
helper = "store";
};
"credential \"https://git.naps.pt\"" = {
helper = "!tea login helper";
};
merge = {
conflictstyle = "zdiff3";
};
commit = {
template = "~/.config/git/commit-message.txt";
};
push = {
default = "upstream";
};
delta = {
navigate = true;
side-by-side = true;
};
"diff \"image\"" = {
textconv = "mediainfo";
};
"diff \"text\"" = {
textconv = "fold -s -w80";
};
};
};
home.packages = with pkgs; [
delta
difftastic
git-crypt
mediainfo
tea
];
home.sessionPath = [
"$HOME/.config/git/scripts"
];
xdg.configFile = {
"git/commit-message.txt".source = ./commit-message.txt;
"git/ignore".source = ./ignore;
"git/scripts".source = ./scripts;
};
programs.gh = {
enable = true;
settings = {
aliases = {
co = "pr checkout";
ls = "pr list";
pv = "pr view";
programs = {
git = {
enable = true;
settings = {
user = {
name = "Miguel Palhas";
email = "mpalhas@gmail.com";
};
alias = {
ls = "log --color --graph --oneline --decorate --topo-order --pretty=format:'%C(yellow)%d%Creset %Cgreen(%cr)%Creset %C(bold blue)[%an]%Creset %s %Cred(%h)%Creset' --abbrev-commit";
ll = ''log --reverse --pretty=format:"%C(yellow)%h%Cred%d\ %Creset%s%Cblue\ [%an]" --decorate --numstat'';
conf = "diff --name-only --diff-filter=U";
ba = "branch -a";
pb = "publish";
ps = "push -u";
pr = "pull-request";
ppr = "push-pr";
cpr = "close-pr";
opr = "open-pr";
f = "fetch";
c = "commit --verbose";
d = "diff";
dc = "diff --cached";
co = "checkout";
s = "status -sb";
b = "better-branch";
rb = "rebase";
rbc = "rebase --continue";
w = "commit -am 'wip'";
# Structural (AST-aware) diff on demand; `git d`/`diff` stays delta.
# Accepts args, e.g. `git dft HEAD~3`.
dft = "!GIT_EXTERNAL_DIFF=difft git diff";
};
init = {
defaultBranch = "main";
};
core = {
editor = "nvim";
pager = "delta";
askpass = "";
};
credential = {
helper = "store";
};
"credential \"https://git.naps.pt\"" = {
helper = "!tea login helper";
};
merge = {
conflictstyle = "zdiff3";
};
commit = {
template = "~/.config/git/commit-message.txt";
};
push = {
default = "upstream";
};
delta = {
navigate = true;
side-by-side = true;
};
"diff \"image\"" = {
textconv = "mediainfo";
};
"diff \"text\"" = {
textconv = "fold -s -w80";
};
};
};
gh = {
enable = true;
settings = {
aliases = {
co = "pr checkout";
ls = "pr list";
pv = "pr view";
};
};
};
};
home = {
packages = with pkgs; [
delta
difftastic
git-crypt
mediainfo
tea
];
sessionPath = [
"$HOME/.config/git/scripts"
];
};
}
+30 -2
View File
@@ -6,6 +6,19 @@
}:
let
cfg = config.custom.hyprland;
# Floating webcam preview for the "corner-cam" recording trick: run `webcam`,
# then capture the whole screen with kooha/wf-recorder — the preview is in the
# recording. v4l2 only (won't work with the laptop's IPU6 cam). Optional device
# arg, e.g. `webcam /dev/video2`.
webcam = pkgs.writeShellScriptBin "webcam" ''
dev="''${1:-/dev/video0}"
exec ${pkgs.mpv}/bin/mpv \
--profile=low-latency --untimed \
--no-osc --no-input-default-bindings \
--title=webcam-overlay --border=no --ontop \
"av://v4l2:$dev"
'';
in
{
options.custom.hyprland = {
@@ -39,6 +52,7 @@ in
cliphist
wf-recorder
slurp
webcam
];
home.sessionVariables = {
@@ -129,13 +143,18 @@ in
"XCURSOR_SIZE, ${toString cfg.cursorSize}"
"HYPRCURSOR_THEME, rose-pine-hyprcursor"
"HYPRCURSOR_SIZE, ${toString cfg.cursorSize}"
# Route Qt6 apps (incl. the xdph screen-share picker) through qt6ct so
# the noctalia-generated color scheme actually applies. Without this
# var the qt6ct.conf is never read.
"QT_QPA_PLATFORMTHEME, qt6ct"
];
"exec-once" = [
"dbus-update-activation-environment --systemd WAYLAND_DISPLAY XDG_CURRENT_DESKTOP"
# Import the Qt theme var too, so the dbus/systemd-activated
# xdg-desktop-portal-hyprland (and its share-picker) inherit it.
"dbus-update-activation-environment --systemd WAYLAND_DISPLAY XDG_CURRENT_DESKTOP QT_QPA_PLATFORMTHEME"
"hyprctl setcursor Nordzy-cursors ${toString cfg.cursorSize}"
"hyprsunset"
"nerd-dictation begin --simulate-input-tool WTYPE --suspend-on-start && touch ~/.cache/nerd-dictation-suspended"
"noctalia"
];
@@ -167,6 +186,15 @@ in
"size 1920 1080, match:class mpv"
"move (cursor_x-(window_w*0.5)) (cursor_y-(window_h*0.5)), match:class mpv"
# webcam overlay (`webcam` command) — small, pinned, bottom-right.
# Title rules come after the mpv class rules so they win.
"float on, match:title webcam-overlay"
"size 360 240, match:title webcam-overlay"
"move 100%-380 100%-260, match:title webcam-overlay"
"pin on, match:title webcam-overlay"
"no_initial_focus on, match:title webcam-overlay"
"border_size 0, match:title webcam-overlay"
# thunar
"float on, match:class thunar"
-124
View File
@@ -1,124 +0,0 @@
{
pkgs,
...
}:
let
venvDir = "$HOME/.local/share/nerd-dictation/venv";
# Create an FHS environment where vosk can be pip-installed
nerd-dictation-env = pkgs.buildFHSEnv {
name = "nerd-dictation-fhs";
targetPkgs = pkgs: with pkgs; [
# Python and pip for vosk
python3
python3Packages.pip
python3Packages.virtualenv
# Audio recording (pipewire)
pipewire
pulseaudio # for parec
# Input simulation (wayland-compatible)
ydotool
wtype
xdotool
# Manylinux compatibility
pythonManylinuxPackages.manylinux2014Package
];
runScript = "bash";
};
# Fetch nerd-dictation from GitHub
nerd-dictation-src = pkgs.fetchFromGitHub {
owner = "ideasman42";
repo = "nerd-dictation";
rev = "main";
hash = "sha256-xjaHrlJvk8bNvWp1VE4EAHi2VJlAutBxUgWB++3Qo+s=";
};
modelUrl = "https://alphacephei.com/vosk/models/vosk-model-en-us-0.22-lgraph.zip";
modelName = "vosk-model-en-us-0.22-lgraph";
modelDir = "$HOME/.config/nerd-dictation";
# Wrapper script that handles setup and runs nerd-dictation
nerd-dictation = pkgs.writeShellScriptBin "nerd-dictation" ''
set -e
VENV="${venvDir}"
MODEL_DIR="${modelDir}"
# Setup venv if needed
if [ ! -d "$VENV" ]; then
echo "[nerd-dictation] Setting up Python venv and installing vosk..."
${nerd-dictation-env}/bin/nerd-dictation-fhs -c "
set -e
mkdir -p \$(dirname ${venvDir})
python3 -m venv ${venvDir}
source ${venvDir}/bin/activate
pip install --upgrade pip -q
pip install vosk -q
"
echo "[nerd-dictation] Venv ready."
fi
# Download model if needed
if [ ! -d "$MODEL_DIR/model" ]; then
echo "[nerd-dictation] Downloading VOSK model (${modelName})..."
mkdir -p "$MODEL_DIR"
cd "$MODEL_DIR"
${pkgs.curl}/bin/curl -L --progress-bar -o "${modelName}.zip" "${modelUrl}"
echo "[nerd-dictation] Extracting model..."
${pkgs.unzip}/bin/unzip -q "${modelName}.zip"
mv "${modelName}" model
rm "${modelName}.zip"
echo "[nerd-dictation] Model ready."
fi
exec ${nerd-dictation-env}/bin/nerd-dictation-fhs -c "source $VENV/bin/activate && python3 ${nerd-dictation-src}/nerd-dictation $*"
'';
# Toggle script for hyprland keybind
nerd-dictation-toggle = pkgs.writeShellScriptBin "nerd-dictation-toggle" ''
hyprctl() {
env -u LD_LIBRARY_PATH ${pkgs.hyprland}/bin/hyprctl "$@"
}
set_border() {
local size=$1
local color=$2
# Unset existing rules for single-window workspaces
hyprctl keyword windowrule "unset, match:float 0, match:workspace w[t1]"
hyprctl keyword windowrule "unset, match:float 0, match:workspace w[tg1]"
hyprctl keyword windowrule "unset, match:float 0, match:workspace f[1]"
hyprctl keyword windowrule "unset, match:fullscreen 1"
# Re-add with specified border size
hyprctl keyword windowrule "border_size $size, match:float 0, match:workspace w[t1]"
hyprctl keyword windowrule "rounding 0, match:float 0, match:workspace w[t1]"
hyprctl keyword windowrule "border_size $size, match:float 0, match:workspace w[tg1]"
hyprctl keyword windowrule "rounding 0, match:float 0, match:workspace w[tg1]"
hyprctl keyword windowrule "border_size $size, match:float 0, match:workspace f[1]"
hyprctl keyword windowrule "rounding 0, match:float 0, match:workspace f[1]"
hyprctl keyword windowrule "border_size $size, match:fullscreen 1"
# Set border color
hyprctl keyword general:col.active_border "$color"
}
# Check if currently suspended (file exists when suspended)
if [ -f "$HOME/.cache/nerd-dictation-suspended" ]; then
nerd-dictation resume
rm -f "$HOME/.cache/nerd-dictation-suspended"
set_border 5 "rgb(ff0000)"
else
nerd-dictation suspend
touch "$HOME/.cache/nerd-dictation-suspended"
set_border 0 "0x99999999"
fi
'';
in
{
home.packages = [
nerd-dictation
nerd-dictation-toggle
pkgs.ydotool
];
}
+32 -30
View File
@@ -1,37 +1,39 @@
_:
{
# Global config file
xdg.configFile."opencode/opencode.json".source = ./opencode.json;
xdg.configFile = {
# Global config file
"opencode/opencode.json".source = ./opencode.json;
# Global rules (equivalent to ~/.claude/CLAUDE.md)
xdg.configFile."opencode/AGENTS.md".source = ./AGENTS.md;
# Global rules (equivalent to ~/.claude/CLAUDE.md)
"opencode/AGENTS.md".source = ./AGENTS.md;
# Custom agents
xdg.configFile."opencode/agents/oracle.md".source = ./agents/oracle.md;
xdg.configFile."opencode/agents/explorer.md".source = ./agents/explorer.md;
xdg.configFile."opencode/agents/librarian.md".source = ./agents/librarian.md;
xdg.configFile."opencode/agents/fixer.md".source = ./agents/fixer.md;
xdg.configFile."opencode/agents/designer.md".source = ./agents/designer.md;
xdg.configFile."opencode/agents/designer-bold.md".source = ./agents/designer-bold.md;
xdg.configFile."opencode/agents/analyze-branch.md".source = ./agents/analyze-branch.md;
# Custom agents
"opencode/agents/oracle.md".source = ./agents/oracle.md;
"opencode/agents/explorer.md".source = ./agents/explorer.md;
"opencode/agents/librarian.md".source = ./agents/librarian.md;
"opencode/agents/fixer.md".source = ./agents/fixer.md;
"opencode/agents/designer.md".source = ./agents/designer.md;
"opencode/agents/designer-bold.md".source = ./agents/designer-bold.md;
"opencode/agents/analyze-branch.md".source = ./agents/analyze-branch.md;
# Global commands
xdg.configFile."opencode/commands/work.md".source = ./commands/work.md;
xdg.configFile."opencode/commands/merge.md".source = ./commands/merge.md;
xdg.configFile."opencode/commands/update.md".source = ./commands/update.md;
xdg.configFile."opencode/commands/smart-debug.md".source = ./commands/smart-debug.md;
xdg.configFile."opencode/commands/tdd-cycle.md".source = ./commands/tdd-cycle.md;
xdg.configFile."opencode/commands/security-scan.md".source = ./commands/security-scan.md;
xdg.configFile."opencode/commands/issue.md".source = ./commands/issue.md;
xdg.configFile."opencode/commands/remove-deadcode.md".source = ./commands/remove-deadcode.md;
xdg.configFile."opencode/commands/worktree-compare.md".source = ./commands/worktree-compare.md;
xdg.configFile."opencode/commands/worktree-list.md".source = ./commands/worktree-list.md;
# Global commands
"opencode/commands/work.md".source = ./commands/work.md;
"opencode/commands/merge.md".source = ./commands/merge.md;
"opencode/commands/update.md".source = ./commands/update.md;
"opencode/commands/smart-debug.md".source = ./commands/smart-debug.md;
"opencode/commands/tdd-cycle.md".source = ./commands/tdd-cycle.md;
"opencode/commands/security-scan.md".source = ./commands/security-scan.md;
"opencode/commands/issue.md".source = ./commands/issue.md;
"opencode/commands/remove-deadcode.md".source = ./commands/remove-deadcode.md;
"opencode/commands/worktree-compare.md".source = ./commands/worktree-compare.md;
"opencode/commands/worktree-list.md".source = ./commands/worktree-list.md;
# Skills
xdg.configFile."opencode/skills/git-master/SKILL.md".source = ./skills/git-master/SKILL.md;
xdg.configFile."opencode/skills/planning-with-files/SKILL.md".source =
./skills/planning-with-files/SKILL.md;
xdg.configFile."opencode/skills/react-patterns/SKILL.md".source = ./skills/react-patterns/SKILL.md;
xdg.configFile."opencode/skills/vercel-react-best-practices/SKILL.md".source =
./skills/vercel-react-best-practices/SKILL.md;
# Skills
"opencode/skills/git-master/SKILL.md".source = ./skills/git-master/SKILL.md;
"opencode/skills/planning-with-files/SKILL.md".source =
./skills/planning-with-files/SKILL.md;
"opencode/skills/react-patterns/SKILL.md".source = ./skills/react-patterns/SKILL.md;
"opencode/skills/vercel-react-best-practices/SKILL.md".source =
./skills/vercel-react-best-practices/SKILL.md;
};
}
+25 -23
View File
@@ -1,31 +1,33 @@
{ pkgs, ... }:
{
home.packages = with pkgs; [
rustup
bacon
mprocs
pkg-config
openssl.dev
taplo
sccache
mold
clang
];
home = {
packages = with pkgs; [
rustup
bacon
mprocs
pkg-config
openssl.dev
taplo
sccache
mold
clang
];
home.sessionPath = [ "\${CARGO_HOME:-$HOME/.cargo}/bin" ];
sessionPath = [ "\${CARGO_HOME:-$HOME/.cargo}/bin" ];
home.file.".cargo/config.toml".text = ''
[target.x86_64-unknown-linux-gnu]
linker = "clang"
rustflags = ["-C", "link-arg=-fuse-ld=mold"]
file.".cargo/config.toml".text = ''
[target.x86_64-unknown-linux-gnu]
linker = "clang"
rustflags = ["-C", "link-arg=-fuse-ld=mold"]
[build]
rustflags = ["-Z", "threads=12"]
'';
[build]
rustflags = ["-Z", "threads=12"]
'';
home.sessionVariables = {
OPENSSL_DIR = "${pkgs.openssl.dev}";
OPENSSL_LIB_DIR = "${pkgs.openssl.out}/lib";
OPENSSL_INCLUDE_DIR = "${pkgs.openssl.dev}/include";
sessionVariables = {
OPENSSL_DIR = "${pkgs.openssl.dev}";
OPENSSL_LIB_DIR = "${pkgs.openssl.out}/lib";
OPENSSL_INCLUDE_DIR = "${pkgs.openssl.dev}/include";
};
};
}
-11
View File
@@ -1,11 +0,0 @@
{ pkgs, ... }:
{
home.packages = with pkgs; [
unityhub
omnisharp-roslyn
vscode
dotnet-sdk
icu
stdenv.cc.cc.lib
];
}
+145 -135
View File
@@ -4,149 +4,159 @@
...
}:
{
programs.zsh = {
enable = true;
enableCompletion = true;
autosuggestion.enable = true;
syntaxHighlighting.enable = true;
completionInit = "autoload -U compinit && compinit -u";
programs = {
zsh = {
enable = true;
enableCompletion = true;
autosuggestion.enable = true;
syntaxHighlighting.enable = true;
completionInit = "autoload -U compinit && compinit -u";
shellAliases = {
c = "cargo";
d = "docker";
dc = "docker compose";
g = "git";
n = "nvim";
vim = "nvim";
ls = "eza";
cat = "bat";
ps = "procs";
j = "just";
lzd = "lazydocker";
open = "xdg-open";
o = "xdg-open";
s = "ssh";
v = "nohup neovide &; disown";
shellAliases = {
c = "cargo";
d = "docker";
dc = "docker compose";
g = "git";
n = "nvim";
vim = "nvim";
ls = "eza";
cat = "bat";
ps = "procs";
du = "dust";
df = "duf";
j = "just";
lzd = "lazydocker";
open = "xdg-open";
o = "xdg-open";
s = "ssh";
v = "nohup neovide &; disown";
# cd
".." = "cd ..";
"..2" = "cd ../..";
"..3" = "cd ../../..";
# cd
".." = "cd ..";
"..2" = "cd ../..";
"..3" = "cd ../../..";
};
history = {
size = 10000;
path = "${config.xdg.dataHome}/zsh/history";
};
plugins = [
{
name = "fzf-tab";
src = pkgs.fetchFromGitHub {
owner = "Aloxaf";
repo = "fzf-tab";
rev = "v1.1.2";
hash = "sha256-Qv8zAiMtrr67CbLRrFjGaPzFZcOiMVEFLg1Z+N6VMhg=";
};
}
{
name = "zsh-autopair";
src = pkgs.fetchFromGitHub {
owner = "hlissner";
repo = "zsh-autopair";
rev = "449a7c3";
hash = "sha256-3zvOgIi+q7+sTXrT+r/4v98qjeiEL4Wh64rxBYnwJvQ=";
};
}
];
initContent = ''
[[ -f ~/.secrets.zsh ]] && source ~/.secrets.zsh
# [[ -n "$KITTY_WINDOW_ID" ]] && alias ssh="kitten ssh"
export PATH="$HOME/.bin:$PATH"
export PATH="''${ASDF_DATA_DIR:-$HOME/.asdf}/shims:$PATH"
export FOUNDRY_DISABLE_NIGHTLY_WARNING=true
export LD_LIBRARY_PATH=${pkgs.zlib}/lib:${pkgs.icu}/lib:${pkgs.stdenv.cc.cc.lib}/lib:$LD_LIBRARY_PATH
'';
};
history = {
size = 10000;
path = "${config.xdg.dataHome}/zsh/history";
fzf = {
enable = true;
enableZshIntegration = true;
};
plugins = [
{
name = "fzf-tab";
src = pkgs.fetchFromGitHub {
owner = "Aloxaf";
repo = "fzf-tab";
rev = "v1.1.2";
hash = "sha256-Qv8zAiMtrr67CbLRrFjGaPzFZcOiMVEFLg1Z+N6VMhg=";
};
}
{
name = "zsh-autopair";
src = pkgs.fetchFromGitHub {
owner = "hlissner";
repo = "zsh-autopair";
rev = "449a7c3";
hash = "sha256-3zvOgIi+q7+sTXrT+r/4v98qjeiEL4Wh64rxBYnwJvQ=";
};
}
zoxide = {
enable = true;
enableZshIntegration = true;
# Replace `cd` with zoxide: `cd` = smart jump, `cdi` = interactive picker.
options = [ "--cmd cd" ];
};
atuin = {
enable = true;
enableZshIntegration = true;
# Local-only history (no account/sync). Atuin owns Ctrl-R; leave the
# up-arrow as normal zsh prefix history.
flags = [ "--disable-up-arrow" ];
settings = {
auto_sync = false;
update_check = false;
};
};
starship = {
enable = true;
settings = {
add_newline = true;
# Disable language modules to keep prompt short
nodejs.disabled = true;
python.disabled = true;
rust.disabled = true;
golang.disabled = true;
java.disabled = true;
ruby.disabled = true;
php.disabled = true;
elixir.disabled = true;
elm.disabled = true;
haskell.disabled = true;
julia.disabled = true;
kotlin.disabled = true;
lua.disabled = true;
nim.disabled = true;
nix_shell.disabled = true;
ocaml.disabled = true;
perl.disabled = true;
purescript.disabled = true;
scala.disabled = true;
swift.disabled = true;
terraform.disabled = true;
zig.disabled = true;
dotnet.disabled = true;
};
};
};
home = {
packages = with pkgs; [
btop
inxi
ripgrep
pass
bat
procs
eza
asdf-vm
fd
tdf
];
initContent = ''
[[ -f ~/.secrets.zsh ]] && source ~/.secrets.zsh
# [[ -n "$KITTY_WINDOW_ID" ]] && alias ssh="kitten ssh"
export PATH="$HOME/.bin:$PATH"
export PATH="''${ASDF_DATA_DIR:-$HOME/.asdf}/shims:$PATH"
export FOUNDRY_DISABLE_NIGHTLY_WARNING=true
export LD_LIBRARY_PATH=${pkgs.zlib}/lib:${pkgs.icu}/lib:${pkgs.stdenv.cc.cc.lib}/lib:$LD_LIBRARY_PATH
'';
};
programs.fzf = {
enable = true;
enableZshIntegration = true;
};
programs.zoxide = {
enable = true;
enableZshIntegration = true;
# Replace `cd` with zoxide: `cd` = smart jump, `cdi` = interactive picker.
options = [ "--cmd cd" ];
};
programs.atuin = {
enable = true;
enableZshIntegration = true;
# Local-only history (no account/sync). Atuin owns Ctrl-R; leave the
# up-arrow as normal zsh prefix history.
flags = [ "--disable-up-arrow" ];
settings = {
auto_sync = false;
update_check = false;
sessionVariables = {
"ASDF_NODEJS_AUTO_ENABLE_COREPACK" = "true";
# home-manager inits zoxide before atuin/fzf, tripping zoxide's doctor
# warning even though the `cd` override works fine (nothing after
# redefines cd). Silence the nag.
"_ZO_DOCTOR" = "0";
};
sessionPath = [
"./.git/safe/../../node_modules/.bin"
"./.git/safe/../../bin"
];
};
programs.starship = {
enable = true;
settings = {
add_newline = true;
# Disable language modules to keep prompt short
nodejs.disabled = true;
python.disabled = true;
rust.disabled = true;
golang.disabled = true;
java.disabled = true;
ruby.disabled = true;
php.disabled = true;
elixir.disabled = true;
elm.disabled = true;
haskell.disabled = true;
julia.disabled = true;
kotlin.disabled = true;
lua.disabled = true;
nim.disabled = true;
nix_shell.disabled = true;
ocaml.disabled = true;
perl.disabled = true;
purescript.disabled = true;
scala.disabled = true;
swift.disabled = true;
terraform.disabled = true;
zig.disabled = true;
dotnet.disabled = true;
};
};
home.packages = with pkgs; [
btop
inxi
ripgrep
pass
bat
procs
eza
asdf-vm
fd
tdf
];
home.sessionVariables = {
"ASDF_NODEJS_AUTO_ENABLE_COREPACK" = "true";
};
home.sessionPath = [
"./.git/safe/../../node_modules/.bin"
"./.git/safe/../../bin"
];
}