| 1 | { |
| 2 | config, |
| 3 | lib, |
| 4 | pkgs, |
| 5 | ... |
| 6 | }: |
| 7 | let |
| 8 | agentsFile = "${config.home.homeDirectory}/config/users/clover/agents/AGENTS.md"; |
| 9 | simpleBrowserBridge = "${config.home.homeDirectory}/config/users/clover/packages/open-in-vscode-browser/extension"; |
| 10 | claudeStatusline = "${config.home.homeDirectory}/config/users/clover/agents/statusline.sh"; |
| 11 | claudeAgents = "${config.home.homeDirectory}/config/users/clover/agents/subagents"; |
| 12 | in |
| 13 | { |
| 14 | imports = [ |
| 15 | ./zsh |
| 16 | ./jujutsu.nix |
| 17 | ]; |
| 18 | |
| 19 | home = { |
| 20 | stateVersion = "23.05"; # Please read the comment before changing. |
| 21 | packages = with pkgs; [ |
| 22 | ffmpeg-full |
| 23 | ripgrep |
| 24 | uv |
| 25 | nh |
| 26 | autofmt |
| 27 | gnupg |
| 28 | just |
| 29 | pnpm |
| 30 | nodejs_26 |
| 31 | (callPackage ./packages/agent-linear { }) |
| 32 | # `open` shim that routes URLs into the VS Code Simple Browser; see |
| 33 | # the home.file symlink for the companion extension. |
| 34 | (callPackage ./packages/open-in-vscode-browser { }) |
| 35 | ]; |
| 36 | # nix node's default global prefix is its read-only store path. |
| 37 | sessionVariables.NPM_CONFIG_PREFIX = "$HOME/.local"; |
| 38 | sessionPath = [ "$HOME/.local/share/pnpm/bin" ]; |
| 39 | }; |
| 40 | |
| 41 | launchd.agents = lib.genAttrs [ "Amphetamine" "RunCat" ] (app: { |
| 42 | enable = true; |
| 43 | config = { |
| 44 | ProgramArguments = [ |
| 45 | "/usr/bin/open" |
| 46 | "-a" |
| 47 | app |
| 48 | ]; |
| 49 | RunAtLoad = true; |
| 50 | }; |
| 51 | }); |
| 52 | |
| 53 | xdg.configFile."opencode/AGENTS.md".source = config.lib.file.mkOutOfStoreSymlink agentsFile; |
| 54 | |
| 55 | # claude code's global instructions live at ~/.claude/CLAUDE.md (the analog |
| 56 | # of opencode's global AGENTS.md); point it at the same file. |
| 57 | home.file.".claude/CLAUDE.md".source = config.lib.file.mkOutOfStoreSymlink agentsFile; |
| 58 | |
| 59 | # Subagent definitions the global CLAUDE.md delegation section routes to; |
| 60 | # the built-in agents are denied in ~/.claude/settings.json so these are the |
| 61 | # only ones reachable. |
| 62 | home.file.".claude/agents".source = config.lib.file.mkOutOfStoreSymlink claudeAgents; |
| 63 | |
| 64 | # Referenced by the `statusLine.command` entry in ~/.claude/settings.json, |
| 65 | # which claude code rewrites itself and so stays unmanaged. |
| 66 | home.file.".claude/statusline-command.sh".source = |
| 67 | config.lib.file.mkOutOfStoreSymlink claudeStatusline; |
| 68 | |
| 69 | # Companion extension for the `open-in-vscode-browser` shim. Symlinked |
| 70 | # (rather than copied) so edits to the source are live after a window reload. |
| 71 | home.file.".vscode/extensions/clover.simple-browser-bridge".source = |
| 72 | config.lib.file.mkOutOfStoreSymlink simpleBrowserBridge; |
| 73 | |
| 74 | programs = { |
| 75 | # sort-lines:start |
| 76 | # bat.enable = true; |
| 77 | btop.enable = true; |
| 78 | fd.enable = true; |
| 79 | hyfetch.enable = true; |
| 80 | # sort-lines:end |
| 81 | |
| 82 | ghostty = { |
| 83 | enable = true; |
| 84 | shader = "cursor-smear-black.glsl"; |
| 85 | package = null; |
| 86 | settings = { |
| 87 | theme = "light:Farmhouse Light,dark:Challenger Deep"; |
| 88 | font-family = "AT Name Mono"; |
| 89 | adjust-cursor-thickness = 2; |
| 90 | background-opacity = 0.95; |
| 91 | background-blur = true; |
| 92 | unfocused-split-opacity = 1; |
| 93 | }; |
| 94 | }; |
| 95 | |
| 96 | git = { |
| 97 | ignores = [ "AGENTS.md" ]; |
| 98 | # use a git-specific email |
| 99 | settings.user.email = "git@paperclover.net"; |
| 100 | settings.gpg.ssh.allowedSignersFile = "${pkgs.writeText "allowed_signers" '' |
| 101 | git@paperclover.net ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAVa1aq1LEj/VXHJYlR5HJpK65lS/9jOL/dAB9ZS1chd |
| 102 | ''}"; |
| 103 | # signing |
| 104 | signing = { |
| 105 | signByDefault = true; |
| 106 | key = "~/.ssh/id_ed25519"; |
| 107 | format = "ssh"; |
| 108 | }; |
| 109 | }; |
| 110 | |
| 111 | ssh = { |
| 112 | enable = true; |
| 113 | enableDefaultConfig = false; |
| 114 | extraConfig = '' |
| 115 | SetEnv TERM=xterm-256color |
| 116 | ''; |
| 117 | # extraConfig asserts a default host block exists |
| 118 | settings."*" = { }; |
| 119 | }; |
| 120 | }; |
| 121 | } |