me like nix
1{
2 pkgs,
3 inputs,
4 config,
5 ...
6}:
7
8{
9 # Import the home-manager modules you want to use
10 imports = [
11 inputs.catppuccin.homeModules.catppuccin
12 inputs.niri.homeModules.niri
13 inputs.zen-browser.homeModules.beta
14 inputs.agenix.homeManagerModules.default
15 ];
16
17 # All your user-specific packages
18 home.packages = with pkgs; [
19 helix
20 git
21 jujutsu # jj-cli
22 htop
23 iotop
24 ncdu
25 youtube-tui
26 yt-dlp # youtube-tui and mpv need this to resolve YouTube URLs
27 zellij # terminal multiplexer
28 alacritty
29 inputs.fsel.packages.${pkgs.system}.default # App launcher / fuzzy finder
30 bemoji # emoji picker
31 networkmanager_dmenu # network picker for fuzzel
32 quickshell # Status bar (QML-based)
33 inputs.kaleidux.packages.${pkgs.system}.default # Dynamic wallpaper daemon
34 (import ../../packages/cclip.nix { inherit pkgs; }) # Clipboard history manager
35 pavucontrol # GUI for PulseAudio/PipeWire volume control
36 playerctl # MPRIS media player control
37 (element-desktop.override {
38 commandLineArgs = "--password-store=gnome-libsecret";
39 })
40 fd
41 ripgrep
42 yazi # tui file browser
43 gh # github cli
44 gh-dash # github dashboard TUI
45 diffnav # git diff viewer
46 signal-desktop
47 xwayland-satellite # for running x11 apps
48 nixfmt # nix formatter
49 nil # nix language server
50 atac # postman-like TUI
51 trippy # network analyzer
52 rsync # file sync utility
53 udiskie # for mounting external drives
54 darktable # photo editing
55 zoxide
56 chromium
57 claude-code
58 nautilus # file browser
59 sqlitebrowser
60 gnome-characters # symbol picker
61 sendme # file transfer
62 desktop-file-utils # for managing .desktop files
63 flyctl # fly.io cli
64 vscode-json-languageserver
65 gnome-network-displays
66 rainfrog # db tui
67 loupe # image viewer
68 glycin-loaders # various format loaders for loupe
69 docker-compose
70 discord
71 mangohud
72 prismlauncher # minecraft launcher
73 fastfetch
74 inputs.agenix.packages.${pkgs.system}.default # agenix CLI
75 age-plugin-yubikey # Yubikey support for agenix
76 # --- FONTS ARE IMPORTANT ---
77 # Berkeley Mono is the main system font, keeping JetBrains and Font Awesome for icons
78 font-awesome
79 noto-fonts
80 noto-fonts-cjk-sans
81 noto-fonts-color-emoji
82 nerd-fonts.jetbrains-mono
83 nerd-fonts.symbols-only
84 # --- POLKIT AGENT (for 1Password GUI, etc.) ---
85 lxqt.lxqt-policykit # Lightweight polkit agent
86 ];
87
88 programs.niri = {
89 enable = true;
90 settings = {
91 window-rules = [
92 {
93 geometry-corner-radius = {
94 top-left = 5.0;
95 top-right = 5.0;
96 bottom-left = 5.0;
97 bottom-right = 5.0;
98 };
99 clip-to-geometry = true;
100 draw-border-with-background = false;
101 }
102 ];
103 debug = {
104 honor-xdg-activation-with-invalid-serial = { };
105 };
106 layout = {
107 focus-ring = {
108 width = 2;
109 active.color = "#8caaee";
110 inactive.color = "#414559";
111 };
112 struts = {
113 top = -6;
114 bottom = -6;
115 left = 0;
116 right = 0;
117 };
118 gaps = 8;
119 };
120 gestures = {
121 hot-corners = {
122 enable = false;
123 };
124 };
125 binds = {
126 "Mod+d".action.spawn = [
127 "alacritty"
128 "-e"
129 "fsel"
130 "--detach"
131 ];
132 "Mod+c".action.spawn = [
133 "alacritty"
134 "-e"
135 "fsel"
136 "--cclip"
137 ];
138 "Mod+e".action.spawn = "bemoji";
139 "Mod+n".action.spawn = "networkmanager_dmenu";
140 "Mod+a".action.spawn = "alacritty";
141 "Mod+h".action = {
142 focus-column-left = { };
143 };
144 "Mod+j".action = {
145 focus-workspace-down = { };
146 };
147 "Mod+k".action = {
148 focus-workspace-up = { };
149 };
150 "Mod+l".action = {
151 focus-column-right = { };
152 };
153 "Mod+Shift+h".action = {
154 move-column-left = { };
155 };
156 "Mod+Shift+j".action = {
157 move-window-down-or-to-workspace-down = { };
158 };
159 "Mod+Shift+k".action = {
160 move-window-up-or-to-workspace-up = { };
161 };
162 "Mod+Shift+l".action = {
163 move-column-right = { };
164 };
165 "Mod+Down".action = {
166 move-workspace-down = { };
167 };
168 "Mod+Up".action = {
169 move-workspace-up = { };
170 };
171 "Mod+p".action = {
172 show-hotkey-overlay = { };
173 };
174 "Mod+o".action = {
175 toggle-overview = { };
176 };
177 "Mod+q".action = {
178 close-window = { };
179 };
180 "Mod+f".action = {
181 toggle-window-floating = { };
182 };
183 "Mod+Shift+f".action = {
184 switch-focus-between-floating-and-tiling = { };
185 };
186 "Mod+m".action = {
187 fullscreen-window = { };
188 };
189 "Mod+s".action = {
190 screenshot = {
191 show-pointer = true;
192 };
193 };
194 "Mod+1".action = {
195 set-column-width = "100%";
196 };
197 "Mod+2".action = {
198 set-column-width = "50%";
199 };
200 "Mod+Minus".action = {
201 set-column-width = "-10%";
202 };
203 "Mod+Equal".action = {
204 set-column-width = "+10%";
205 };
206 "Mod+Shift+q".action = {
207 quit = { };
208 };
209 "Mod+Shift+r".action.spawn = [
210 "systemctl"
211 "--user"
212 "restart"
213 "quickshell.service"
214 ];
215 "XF86AudioPlay".action.spawn = [
216 "playerctl"
217 "play-pause"
218 ];
219 "XF86AudioStop".action.spawn = [
220 "playerctl"
221 "stop"
222 ];
223 "XF86AudioNext".action.spawn = [
224 "playerctl"
225 "next"
226 ];
227 "XF86AudioPrev".action.spawn = [
228 "playerctl"
229 "previous"
230 ];
231 "XF86MonBrightnessDown".action.spawn = [
232 "brightnessctl"
233 "set"
234 "5%-"
235 ];
236 "XF86MonBrightnessUp".action.spawn = [
237 "brightnessctl"
238 "set"
239 "+5%"
240 ];
241 };
242 outputs = {
243 # External monitor - primary display at position (0, 0)
244 "DP-5" = {
245 scale = 2.0;
246 mode = {
247 width = 5120;
248 height = 2160;
249 refresh = 120.0;
250 };
251 position = {
252 x = 0;
253 y = 0;
254 };
255 };
256 "DP-1" = {
257 scale = 2.0;
258 mode = {
259 width = 5120;
260 height = 2160;
261 refresh = 120.0;
262 };
263 position = {
264 x = 0;
265 y = 0;
266 };
267 };
268 "DP-2" = {
269 scale = 1.0;
270 mode = {
271 width = 5120;
272 height = 2160;
273 refresh = 120.0;
274 };
275 position = {
276 x = 0;
277 y = 0;
278 };
279 };
280 "DP-6" = {
281 scale = 2.0;
282 mode = {
283 width = 5120;
284 height = 2160;
285 refresh = 120.0;
286 };
287 position = {
288 x = 0;
289 y = 0;
290 };
291 };
292 "DP-7" = {
293 scale = 2.0;
294 mode = {
295 width = 5120;
296 height = 2160;
297 refresh = 120.0;
298 };
299 position = {
300 x = 0;
301 y = 0;
302 };
303 };
304 # Laptop display - secondary display positioned underneath
305 "eDP-1" = {
306 scale = 1.5;
307 mode = {
308 width = 2560;
309 height = 1600;
310 refresh = 165.0;
311 };
312 position = {
313 x = 0;
314 y = 1080; # Position underneath the external monitor (2160 / 2 scale = 1080 logical height)
315 };
316 };
317 };
318 spawn-at-startup = [
319 { command = [ "xwayland-satellite" ]; }
320 { command = [ "cclipd" ]; }
321 ];
322 environment = {
323 DISPLAY = ":0";
324 };
325 };
326 };
327
328 # Allow unfree packages
329 nixpkgs.config.allowUnfree = true;
330
331 nixpkgs.config.permittedInsecurePackages = [
332 "libsoup-2.74.3"
333 ];
334
335 # Download wallpapers at activation time (skips dead URLs gracefully)
336 home.activation.downloadWallpapers =
337 let
338 wallpapers = import ./wallpapers.nix;
339 downloads = builtins.concatStringsSep "\n" (
340 map (wp: ''
341 if [ ! -f "$DIR/${wp.filename}" ]; then
342 echo "Downloading ${wp.filename}..."
343 ${pkgs.curl}/bin/curl -fsSL -o "$DIR/${wp.filename}" ${
344 builtins.replaceStrings [ "\"" ] [ "\\\"" ] wp.url
345 } || echo "WARNING: Failed to download ${wp.filename}, skipping"
346 fi
347 '') wallpapers
348 );
349 in
350 config.lib.dag.entryAfter [ "writeBoundary" ] ''
351 DIR="${config.home.homeDirectory}/Pictures/Wallpapers"
352 mkdir -p "$DIR"
353 ${downloads}
354 '';
355
356 # Kaleidux wallpaper daemon config
357 xdg.configFile."kaleidux/config.toml".text = ''
358 [global]
359 monitor-behavior = "independent"
360 video-ratio = 50
361 sorting = "loveit"
362 transition-time = 1000
363
364 [any]
365 path = "${config.home.homeDirectory}/Pictures/Wallpapers"
366 duration = "15m"
367 transition = { type = "fade" }
368 '';
369
370 # Quickshell status bar
371 xdg.configFile."quickshell" = {
372 source = ./quickshell;
373 recursive = true;
374 };
375
376 systemd.user.services.kaleidux = {
377 Unit = {
378 Description = "Kaleidux dynamic wallpaper daemon";
379 After = [ "graphical-session.target" ];
380 PartOf = [ "graphical-session.target" ];
381 };
382 Service = {
383 ExecStart = "${inputs.kaleidux.packages.${pkgs.system}.default}/bin/kaleidux-daemon";
384 Restart = "on-failure";
385 RestartSec = 2;
386 };
387 Install = {
388 WantedBy = [ "graphical-session.target" ];
389 };
390 };
391
392 systemd.user.services.quickshell = {
393 Unit = {
394 Description = "QuickShell status bar";
395 After = [ "graphical-session.target" ];
396 PartOf = [ "graphical-session.target" ];
397 };
398 Service = {
399 ExecStart = "${pkgs.quickshell}/bin/quickshell";
400 Restart = "on-failure";
401 RestartSec = 2;
402 };
403 Install = {
404 WantedBy = [ "graphical-session.target" ];
405 };
406 };
407
408 systemd.user.services.quickshell-reload = {
409 Unit = {
410 Description = "Reload QuickShell on wake or display change";
411 After = [
412 "quickshell.service"
413 "graphical-session.target"
414 ];
415 PartOf = [ "graphical-session.target" ];
416 };
417 Service = {
418 Type = "simple";
419 ExecStart = "${pkgs.writeShellScript "quickshell-reload" ''
420 LOCKFILE="/tmp/quickshell-reload.lock"
421
422 do_restart() {
423 (
424 ${pkgs.util-linux}/bin/flock -xn 200 || exit 0
425 sleep 2
426 ${pkgs.systemd}/bin/systemctl --user restart quickshell.service
427 sleep 3
428 ) 200>"$LOCKFILE"
429 }
430
431 # Sleep/wake monitor
432 ${pkgs.dbus}/bin/dbus-monitor --system \
433 "type='signal',interface='org.freedesktop.login1.Manager',member='PrepareForSleep'" 2>/dev/null | \
434 while IFS= read -r line; do
435 if [[ "$line" == *"boolean false"* ]]; then
436 do_restart
437 fi
438 done &
439
440 # Display hotplug monitor
441 ${pkgs.systemd}/bin/udevadm monitor --property --subsystem-match=drm 2>/dev/null | \
442 while IFS= read -r line; do
443 if [[ "$line" == *"HOTPLUG=1"* ]]; then
444 do_restart
445 fi
446 done &
447
448 wait
449 ''}";
450 Restart = "on-failure";
451 RestartSec = 5;
452 };
453 Install = {
454 WantedBy = [ "graphical-session.target" ];
455 };
456 };
457
458 programs.ssh = {
459 enable = true;
460 enableDefaultConfig = false;
461 matchBlocks = {
462 "*" = {
463 identityFile = [
464 "${config.home.homeDirectory}/.ssh/id_ed25519_sk_rk"
465 "${config.home.homeDirectory}/.ssh/id_rsa.pub"
466 ];
467 };
468 };
469 };
470
471 programs.awscli = {
472 enable = true;
473 settings = {
474 "default" = {
475 region = "us-east-1";
476 };
477 };
478 };
479
480 services.udiskie = {
481 enable = true;
482 tray = "never";
483 automount = true;
484 };
485
486 services.mako = {
487 enable = true;
488 settings = {
489 border-radius = 8;
490 border-size = 2;
491 padding = "12";
492 margin = "12";
493 font = "BerkeleyMono Nerd Font 11";
494 on-button-left = "invoke-default-action";
495 on-button-right = "dismiss";
496 };
497 };
498
499 catppuccin = {
500 enable = true;
501 flavor = "frappe";
502 };
503
504 programs.direnv.enable = true;
505
506 programs.atuin = {
507 enable = true;
508 enableFishIntegration = true;
509 daemon.enable = true;
510 settings = {
511 filter_mode_shell_up_key_binding = "session";
512 };
513 };
514
515 programs.zellij = {
516 enable = true;
517 settings = {
518 keybinds = {
519 unbind = [
520 "Ctrl q"
521 "Ctrl o"
522 ];
523 normal = {
524 "bind \"Ctrl m\"" = {
525 SwitchToMode = "Session";
526 };
527 };
528 };
529 pane_frames = false;
530 show_startup_tips = false;
531 ui = {
532 pane_frames.hide_session_name = true;
533 };
534 };
535 };
536
537 xdg.configFile."zellij/layouts/split.kdl".text = ''
538 layout {
539 tab {
540 pane size="50%"
541 pane split_direction="vertical" size="50%" {
542 pane
543 pane
544 }
545 }
546 }
547 '';
548
549 xdg.configFile."gh-dash/config.yml".text = ''
550 prSections:
551 - title: My Pull Requests
552 filters: is:open author:@me
553 - title: Review Requested
554 filters: is:open review-requested:@me
555 issuesSections:
556 - title: My Issues
557 filters: is:open author:@me
558 pager:
559 diff: diffnav
560 keybindings:
561 prs:
562 - key: T
563 name: enhance
564 command: >-
565 zellij run -- gh enhance -R {{.RepoName}} {{.PrNumber}}
566 '';
567
568 programs.zen-browser.enable = true;
569 # programs.swww.enable = true;
570 programs.zoxide = {
571 enable = true;
572 enableFishIntegration = true;
573 };
574
575 programs.obs-studio = {
576 enable = true;
577 plugins = with pkgs.obs-studio-plugins; [
578 obs-backgroundremoval
579 ];
580 };
581
582 # Program configurations
583 programs.mpv = {
584 enable = true;
585 scripts = [ pkgs.mpvScripts.mpris pkgs.mpvScripts.sponsorblock ];
586 };
587 xdg.configFile."youtube-tui" = {
588 source = ./youtube-tui;
589 recursive = true;
590 };
591 programs.git = {
592 enable = true;
593 settings = {
594 user = {
595 name = "seanaye";
596 email = "hello@seanaye.ca";
597 };
598 init.defaultBranch = "main";
599 commit.gpgSign = true;
600 gpg.format = "ssh";
601 user.signingKey = "sk-ssh-ed25519@openssh.com AAAAGnNrLXNzaC1lZDI1NTE5QG9wZW5zc2guY29tAAAAIOIgEteUEW06dnBHe2z8vNLwz2iMKe8bba6JgMmOUpcBAAAABHNzaDo= sean@framework16";
602 gpg.ssh.allowedSignersFile = "${config.home.homeDirectory}/.ssh/allowed_signers";
603 diff.tool = "diffnav";
604 difftool.prompt = false;
605 "difftool \"diffnav\"".cmd = "diffnav \"$LOCAL\" \"$REMOTE\"";
606 };
607 };
608 programs.jujutsu = {
609 enable = true;
610 settings = {
611 user = {
612 email = "hello@seanaye.ca";
613 name = "Sean Aye";
614 };
615 ui."diff-formatter" = ":git";
616 signing = {
617 sign-all = true;
618 behavior = "own";
619 backend = "ssh";
620 key = "${config.home.homeDirectory}/.ssh/id_ed25519_sk_rk";
621 backends.ssh.allowed-signers = "${config.home.homeDirectory}/.ssh/allowed_signers";
622 };
623 };
624 };
625 xdg.configFile."jj/conf.d/diffnav.toml".text = ''
626 [[--scope]]
627 --when.commands = ["diff", "show"]
628 [--scope.ui]
629 pager = "diffnav"
630 '';
631
632 programs.home-manager.enable = true;
633
634 programs.fish = {
635 enable = true;
636 shellAliases = {
637 agenix = "agenix -i ~/.config/agenix/yubikey-identity.txt";
638 };
639 interactiveShellInit = ''
640 set fish_greeting
641 # Set 1Password SSH agent socket
642 set -gx SSH_AUTH_SOCK ${config.home.homeDirectory}/.1password/agent.sock
643 # Load 1Password CLI plugins
644 if test -f ~/.config/op/plugins.sh
645 source ~/.config/op/plugins.sh
646 end
647 # Auto-launch zellij if not already inside a session
648 if not set -q ZELLIJ
649 zellij
650 else
651 fastfetch --logo small
652 end
653
654 function y
655 set tmp (mktemp -t "yazi-cwd.XXXXXX")
656 yazi $argv --cwd-file="$tmp"
657 if read -z cwd < "$tmp"; and [ -n "$cwd" ]; and [ "$cwd" != "$PWD" ]
658 builtin cd -- "$cwd"
659 end
660 rm -f -- "$tmp"
661 end
662 '';
663 functions = {
664 s3edit = ''
665 set file (basename $argv[1])
666 set tmpfile /tmp/$file
667 aws s3 cp $argv[1] $tmpfile
668 and $EDITOR $tmpfile
669 and aws s3 cp $tmpfile $argv[1]
670 '';
671 };
672 };
673
674 programs.starship = {
675 enable = true;
676 enableFishIntegration = true;
677 };
678
679 programs.alacritty = {
680 enable = true;
681 settings = {
682 terminal.shell.program = "fish";
683 window = {
684 decorations = "none";
685 opacity = 0.9;
686 };
687 font = {
688 normal = {
689 family = "BerkeleyMono Nerd Font";
690 style = "Regular";
691 };
692 size = 12.0;
693 };
694 };
695
696 };
697
698 programs.helix = {
699 enable = true;
700 settings = {
701 editor = {
702 bufferline = "multiple";
703 file-picker = {
704 hidden = false;
705 git-ignore = true;
706 };
707 cursor-shape = {
708 insert = "bar";
709 normal = "block";
710 select = "underline";
711 };
712 line-number = "relative";
713 cursorline = true;
714 auto-format = true;
715 end-of-line-diagnostics = "hint";
716 soft-wrap = {
717 enable = true;
718 };
719 lsp = {
720 display-inlay-hints = true;
721 display-messages = true;
722 display-progress-messages = true;
723 };
724 inline-diagnostics = {
725 cursor-line = "hint";
726 };
727 };
728 keys = {
729 normal = {
730 esc = [
731 "keep_primary_selection"
732 "collapse_selection"
733 ];
734 };
735
736 };
737 };
738 languages = {
739
740 language-server.rust-analyzer = {
741 config = {
742 check = {
743 command = "clippy";
744 };
745 checkOnSave = true;
746 cargo = {
747 allFeatures = true;
748 };
749 };
750 };
751 language-server.deno-lsp = {
752 command = "deno";
753 args = [ "lsp" ];
754 config.deno.enable = true;
755 };
756
757 language = [
758 {
759 name = "html";
760 formatter = {
761 command = "prettier";
762 args = [
763 "--parser"
764 "html"
765 ];
766 };
767 }
768 {
769 name = "nix";
770 auto-format = true;
771 formatter = {
772 command = "${pkgs.nixfmt}/bin/nixfmt";
773 };
774 }
775 {
776 name = "kotlin";
777 auto-format = true;
778 }
779 {
780 name = "rust";
781 auto-format = true;
782 formatter = {
783 command = "rustfmt";
784 args = [
785 "--edition"
786 "2024"
787 ];
788 };
789 indent = {
790 tab-width = 4;
791 unit = "t";
792 };
793 }
794 {
795 name = "astro";
796 auto-format = true;
797 formatter = {
798 command = "npx";
799 args = [
800 "prettier"
801 "--plugin"
802 "prettier-plugin-astro"
803 "--parser"
804 "astro"
805 ];
806 };
807 }
808 {
809 name = "json";
810 auto-format = true;
811 }
812 {
813 name = "just";
814 auto-format = true;
815 formatter = {
816 command = "just";
817 args = [
818 "--justfile"
819 "/dev/stdin"
820 "--dump"
821 ];
822 };
823 }
824 {
825 name = "toml";
826 auto-format = true;
827 formatter = {
828 command = "taplo";
829 args = [
830 "format"
831 "-"
832 ];
833 };
834 }
835 # {
836 # name = "typescript";
837 # roots = [
838 # "deno.json"
839 # "deno.jsonc"
840 # ];
841 # file-types = [
842 # "ts"
843 # "tsx"
844 # ];
845 # auto-format = true;
846 # language-servers = [ "deno-lsp" ];
847 # }
848 ];
849 };
850 };
851
852 dconf.settings = {
853 "org/gnome/desktop/interface" = {
854 color-scheme = "prefer-dark";
855 enable-hot-corners = false;
856 };
857 };
858
859 # Font rendering configuration
860 fonts.fontconfig = {
861 enable = true;
862 defaultFonts = {
863 monospace = [ "BerkeleyMono Nerd Font" ];
864 sansSerif = [ "Noto Sans" ];
865 serif = [ "Noto Serif" ];
866 };
867 };
868
869 # Cursor configuration
870 home.pointerCursor = {
871 name = "Adwaita";
872 package = pkgs.adwaita-icon-theme;
873 size = 16;
874 x11.enable = true;
875 gtk.enable = true;
876 };
877
878 # Session variables
879 home.sessionVariables = {
880 EDITOR = "hx";
881 VISUAL = "hx";
882 SUDO_EDITOR = "hx";
883 SSH_AUTH_SOCK = "${config.home.homeDirectory}/.1password/agent.sock";
884 SSH_ASKPASS = "${pkgs.openssh-askpass}/bin/gnome-ssh-askpass3";
885 SSH_ASKPASS_REQUIRE = "prefer";
886 };
887
888 # SSH allowed signers for commit signature verification
889 home.file.".ssh/allowed_signers".text = ''
890 hello@seanaye.ca ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDCIqgZ7kedxo+mOW7YG73Vp3zel3h180y3GKvHtRsXfGlpIIvRDy7pgCBQ4AGXYD4y78URQmFohYSAPqCPOPaWcU2un3XG9KvCzEsHmsbskPonitUmCiKvrKkb6oW4jCBtd7AEtBn+AiajAQFtPZ7NN2Df3AmTypvR6Irg7R+nxnfc9NTIHmGvxSDyWcbb4pguL20sctUSqGL6xGh8q/bqhdOThSimM+z9bEUNxK/5rPhwkNniMrp4pJcUrUiAh5/4DiRFG6KT+oeg+/myoz/Z1sPvAs7u/8JDQI4RshRD8Hu0oTkRBN6Hxj478q2SXbeBUZlD6IdjP3RhGpmSecoDdtWqKbpuV3eVRtQtba3KL86GBeV/bugaOdJ1Aud+1SOFJreAAuvxzMMKT+cdQZk6oOPP148DA/No+mDm/2S43lcdCXh79wA6YRAmKQ8jmZxTCtPutrvuZK1rguvvUlEoG/vhdNHh7eDa4Td07V6bjCRPUl8qk/e4M0E3pwsTlZc=
891 hello@seanaye.ca sk-ssh-ed25519@openssh.com AAAAGnNrLXNzaC1lZDI1NTE5QG9wZW5zc2guY29tAAAAILdilHXHdAP/V8Zq28EzHKtLAMMaFPu4+1det2N50QfhAAAABHNzaDo= sean@framework16
892 '';
893
894 # Yubikey identity for agenix (not secret - just a reference to the hardware key)
895 home.file.".config/agenix/yubikey-identity.txt".text = ''
896 # Serial: 26930059, Slot: 1
897 # Name: agenix
898 # Recipient: age1yubikey1qw64ag5lzvn9ekrflu5ruj4a6ucycscl6ctk39fjzf76jptsay39z442pxv
899 AGE-PLUGIN-YUBIKEY-1304E5QVZZD74FKSP8FMCT
900 '';
901
902 # Same identity for sops (expects keys at this path by default)
903 home.file.".config/sops/age/keys.txt".text = ''
904 # Serial: 26930059, Slot: 1
905 # Name: agenix
906 # Recipient: age1yubikey1qw64ag5lzvn9ekrflu5ruj4a6ucycscl6ctk39fjzf76jptsay39z442pxv
907 AGE-PLUGIN-YUBIKEY-1304E5QVZZD74FKSP8FMCT
908 '';
909
910 # yubikey sudo access
911 home.file.".config/Yubico/u2f_keys".text = ''
912 sean:2HY//CedY0ZSrKf57lT7abxG8+8bkPyxCfp/0HMlk/il/5W8pn4R5xLiZDcJtvL85U24h9IEIxa4CS22mpaDSA==,gcD/dpLdwvUFcGGPHS4qNsarH4lOEy1AJAT7zoC6BPlFRUYEa8DpVVKFTcvT6PotjnSHSrWWGb/f3U2k2jIOIw==,es256,+presence
913 '';
914
915 # Set the state version for Home Manager
916 home.stateVersion = "25.05";
917}