me like nix
1{ inputs, ... }:
2
3{
4 flake.modules.homeManager.apps =
5 { pkgs, ... }:
6 {
7 home.packages = with pkgs; [
8 # Browsers
9 chromium
10
11 # Communication
12 (element-desktop.override {
13 commandLineArgs = "--password-store=gnome-libsecret";
14 })
15 signal-desktop
16 discord
17
18 # Media
19 youtube-tui
20 yt-dlp
21 darktable
22 loupe
23 glycin-loaders
24
25 # Dev tools
26 git
27 jujutsu
28 htop
29 iotop
30 ncdu
31 atac
32 trippy
33 just
34 docker-compose
35 flyctl
36 rainfrog
37 sqlitebrowser
38 cachix
39
40 # System tools
41 nautilus
42 gnome-characters
43 sendme
44 desktop-file-utils
45 gnome-network-displays
46 fastfetch
47 mangohud
48 prismlauncher
49 libnotify
50
51 # Claude Code
52 pi-coding-agent
53 claude-code
54 (pkgs.writeShellScriptBin "claude-notify" ''
55 PANE_ID="$ZELLIJ_PANE_ID"
56 SESSION="$ZELLIJ_SESSION_NAME"
57 ID_FILE="/tmp/claude-notify-''${PANE_ID}"
58 (
59 {
60 read -r NOTIFY_ID
61 echo "$NOTIFY_ID" > "$ID_FILE"
62 while read -r line; do
63 if [ "$line" = "default" ]; then
64 WIN_ID=$(niri msg windows | ${pkgs.gnugrep}/bin/grep -B1 "$SESSION" | ${pkgs.gnugrep}/bin/grep -oP '(?<=Window ID )\d+')
65 if [ -n "$WIN_ID" ]; then
66 niri msg action focus-window --id "$WIN_ID"
67 fi
68 zjctl pane focus --pane "id:terminal:$PANE_ID"
69 fi
70 done
71 } < <(${pkgs.libnotify}/bin/notify-send "Claude Code" "Waiting for your approval" \
72 --app-name=claude-code \
73 --action=default=Open \
74 --print-id \
75 --wait)
76 rm -f "$ID_FILE"
77 ) &
78 '')
79 (pkgs.writeShellScriptBin "claude-notify-clear" ''
80 PANE_ID="$ZELLIJ_PANE_ID"
81 ID_FILE="/tmp/claude-notify-''${PANE_ID}"
82 if [ -f "$ID_FILE" ]; then
83 NOTIFY_ID=$(cat "$ID_FILE")
84 ${pkgs.dbus}/bin/dbus-send --session \
85 --print-reply \
86 --dest=org.freedesktop.Notifications \
87 --type=method_call \
88 /org/freedesktop/Notifications \
89 org.freedesktop.Notifications.CloseNotification \
90 "uint32:$NOTIFY_ID" >/dev/null 2>&1
91 rm -f "$ID_FILE"
92 fi
93 '')
94 ];
95
96 # Pi coding agent config
97 home.file.".pi/agent/AGENTS.md".source = ./_config/pi/AGENTS.md;
98 home.file.".pi/agent/skills/caveman".source = ./_config/pi/skills/caveman;
99 home.file.".pi/agent/extensions/permission-pi".source = ./_config/pi/extensions/permission-pi;
100
101 # Claude Code config
102 home.file.".claude/settings.json".text = builtins.toJSON {
103 preferences = {
104 thinking = "high";
105 };
106 enabledPlugins = {
107 "caveman@caveman" = true;
108 };
109 hooks = {
110 Notification = [
111 {
112 matcher = "permission_prompt";
113 hooks = [
114 {
115 type = "command";
116 command = "claude-notify";
117 }
118 ];
119 }
120 ];
121 Stop = [
122 {
123 hooks = [
124 {
125 type = "command";
126 command = "claude-notify-clear";
127 }
128 ];
129 }
130 ];
131 };
132 };
133
134 programs.zen-browser.enable = true;
135
136 programs.obs-studio = {
137 enable = true;
138 plugins = with pkgs.obs-studio-plugins; [
139 obs-backgroundremoval
140 ];
141 };
142
143 programs.mpv = {
144 enable = true;
145 scripts = [ pkgs.mpvScripts.mpris ];
146 config.af = "loudnorm=I=-16:TP=-1.5:LRA=11";
147 };
148
149 xdg.configFile."youtube-tui/commands.yml".source = ./_config/youtube-tui/commands.yml;
150 };
151}