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
39 # System tools
40 nautilus
41 gnome-characters
42 sendme
43 desktop-file-utils
44 gnome-network-displays
45 fastfetch
46 mangohud
47 prismlauncher
48 libnotify
49
50 # Claude Code
51 pi-coding-agent
52 claude-code
53 (pkgs.writeShellScriptBin "claude-notify" ''
54 PANE_ID="$ZELLIJ_PANE_ID"
55 SESSION="$ZELLIJ_SESSION_NAME"
56 ID_FILE="/tmp/claude-notify-''${PANE_ID}"
57 (
58 {
59 read -r NOTIFY_ID
60 echo "$NOTIFY_ID" > "$ID_FILE"
61 while read -r line; do
62 if [ "$line" = "default" ]; then
63 WIN_ID=$(niri msg windows | ${pkgs.gnugrep}/bin/grep -B1 "$SESSION" | ${pkgs.gnugrep}/bin/grep -oP '(?<=Window ID )\d+')
64 if [ -n "$WIN_ID" ]; then
65 niri msg action focus-window --id "$WIN_ID"
66 fi
67 zjctl pane focus --pane "id:terminal:$PANE_ID"
68 fi
69 done
70 } < <(${pkgs.libnotify}/bin/notify-send "Claude Code" "Waiting for your approval" \
71 --app-name=claude-code \
72 --action=default=Open \
73 --print-id \
74 --wait)
75 rm -f "$ID_FILE"
76 ) &
77 '')
78 (pkgs.writeShellScriptBin "claude-notify-clear" ''
79 PANE_ID="$ZELLIJ_PANE_ID"
80 ID_FILE="/tmp/claude-notify-''${PANE_ID}"
81 if [ -f "$ID_FILE" ]; then
82 NOTIFY_ID=$(cat "$ID_FILE")
83 ${pkgs.dbus}/bin/dbus-send --session \
84 --print-reply \
85 --dest=org.freedesktop.Notifications \
86 --type=method_call \
87 /org/freedesktop/Notifications \
88 org.freedesktop.Notifications.CloseNotification \
89 "uint32:$NOTIFY_ID" >/dev/null 2>&1
90 rm -f "$ID_FILE"
91 fi
92 '')
93 ];
94
95 home.file.".claude/settings.json".text = builtins.toJSON {
96 preferences = {
97 thinking = "high";
98 };
99 enabledPlugins = {
100 "rust-analyzer-lsp@claude-plugins-official" = true;
101 "typescript-lsp@claude-plugins-official" = true;
102 "caveman@caveman" = true;
103 };
104 hooks = {
105 Notification = [
106 {
107 matcher = "permission_prompt";
108 hooks = [
109 {
110 type = "command";
111 command = "claude-notify";
112 }
113 ];
114 }
115 ];
116 Stop = [
117 {
118 hooks = [
119 {
120 type = "command";
121 command = "claude-notify-clear";
122 }
123 ];
124 }
125 ];
126 };
127 };
128
129 programs.zen-browser.enable = true;
130
131 programs.obs-studio = {
132 enable = true;
133 plugins = with pkgs.obs-studio-plugins; [
134 obs-backgroundremoval
135 ];
136 };
137
138 programs.mpv = {
139 enable = true;
140 scripts = [ pkgs.mpvScripts.mpris ];
141 config.af = "loudnorm=I=-16:TP=-1.5:LRA=11";
142 };
143
144 xdg.configFile."youtube-tui/commands.yml".source = ./_config/youtube-tui/commands.yml;
145 };
146}