1{
2 config,
3 lib,
4 pkgs,
5 ...
6}:
7let
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";
12in
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}