Compare commits

..

32 Commits

Author SHA1 Message Date
Alexander Heldt d0ef7f5b7e manatee: Add wl-clipboard 2026-07-26 07:36:05 +00:00
Alexander Heldt 5eacb60b50 manatee: Add claude 2026-07-26 07:35:53 +00:00
Alexander Heldt a33a22aa50 Update solo-referee flake input 2026-07-26 07:34:21 +00:00
Alexander Heldt 56c04b1f70 manatee: Guard podman containers against crash-looping
Add a start-limit (5 restarts / 5 min) to the romm, romm-db, romm-redis
and homeassistant podman services so a failing container enters a
`failed` state instead of retrying forever. A slow crash-loop (~5s per
attempt) stays under systemd's default 5-starts-per-10s limit, so a
longer window is needed to catch it.
2026-07-26 07:32:16 +00:00
Alexander Heldt cd81da9bfd Update puppy-tracker flake input 2026-07-24 15:19:12 +00:00
Alexander Heldt ed3e5844a0 Update puppy-tracker flake input 2026-07-24 12:31:14 +00:00
Alexander Heldt 08a3bae6c6 manatee: Add solo-referee module 2026-07-24 12:26:33 +00:00
Alexander Heldt cdb657bd36 pinwheel: Set hyprland config variant 2026-07-23 10:56:37 +02:00
Alexander Heldt 538fb0390a pinwheel: set ASKPASS
And cache the git signing key
2026-07-23 10:56:01 +02:00
Alexander Heldt 8f22f82066 pinwheel: Fix emacs startup
And don't force the async path, wait at least 0.1sec for terminal to
answer with capabilities. Using the async path broke the answer and
inserted 4 spaces in the beginning of the buffer
2026-07-23 10:55:00 +02:00
Alexander Heldt 82b7ce8ccc pinwheel/tadpole: Rename alex.pinwheel-tadpole-ed25519 2026-07-21 09:38:35 +02:00
Alexander Heldt 99b5cb3380 Update puppy-tracker flake input 2026-07-21 07:20:31 +00:00
Alexander Heldt 100a7c455f pinwheel: Remove bitwarden gui client 2026-07-21 08:58:55 +02:00
Alexander Heldt 23bc741d5e Update flake inputs 2026-07-21 08:58:53 +02:00
Alexander Heldt 64e71cce31 pinwheel: Add ai module
With work/personal claude configs
2026-07-21 08:58:52 +02:00
Alexander Heldt 0b3e8c162a pinwheel: Ensure hyprland monitor detection works on start 2026-07-21 08:58:50 +02:00
Alexander Heldt 421c6179d6 manatee: Add tmux module 2026-07-17 09:15:46 +00:00
Alexander Heldt 2c80e01a6e Update puppy-tracker flake input 2026-07-13 06:16:35 +00:00
Alexander Heldt 12eb945230 Update puppy-tracker flake input 2026-07-09 19:51:51 +00:00
Alexander Heldt 42079c2268 Update puppy-tracker flake input 2026-07-09 20:35:48 +02:00
Alexander Heldt 4742e0f593 manatee: Add puppy-tracker behind virtual host puppy.ppp.pm 2026-07-09 20:34:43 +02:00
Alexander Heldt 3446756cc1 manatee: Add invite code secret for puppy-tracker 2026-07-09 20:34:12 +02:00
Alexander Heldt aa7ef695f4 manatee: Add ability to specify public url for homepage card 2026-07-09 20:33:22 +02:00
Alexander Heldt ff02728d82 manatee: Add puppy.ppp.pm sub-domain
With cert and ip update
2026-07-09 16:59:13 +00:00
Alexander Heldt e2f62568b5 Update puppy-tracker flake input 2026-07-04 09:27:46 +00:00
Alexander Heldt 304d07fea3 Update puppy-tracker flake input 2026-07-04 09:21:06 +00:00
Alexander Heldt bdcc75980d manatee: Fix komga-reading-stats secret permissions 2026-06-25 14:28:28 +00:00
Alexander Heldt 0b27829c2a Update flake inputs 2026-06-25 14:28:15 +00:00
Alexander Heldt f628e3a16a Update flake inputs 2026-06-21 18:08:50 +00:00
Alexander Heldt c07d9fca36 Update flake inputs 2026-06-21 17:59:25 +00:00
Alexander Heldt 6477f2b39b manatee: Add puppy-tracker module 2026-06-21 17:50:51 +00:00
Alexander Heldt 80ed5a1017 Update flake inputs (and add puppy-tracker) 2026-06-21 17:50:51 +00:00
28 changed files with 540 additions and 107 deletions
Generated
+173 -68
View File
@@ -43,11 +43,11 @@
]
},
"locked": {
"lastModified": 1778620495,
"narHash": "sha256-Gu7UhWjwKCgSiVC3Qz/Rc7cYi9DNuDTBxYzg3kfLvfM=",
"lastModified": 1782073106,
"narHash": "sha256-dnS5SaZlPqR1E0dPXaPc+lFkBwLUbAgbwsVMk7uA6dY=",
"owner": "hyprwm",
"repo": "aquamarine",
"rev": "be35f75ac305f430f5f9d89b5f5a4af59ca7567e",
"rev": "6d6e2384f381def4ea4ea81543cba4bbdac72457",
"type": "github"
},
"original": {
@@ -85,11 +85,11 @@
]
},
"locked": {
"lastModified": 1779226674,
"narHash": "sha256-wuOkjI6pRiN4sEn/EPBRnNW5cmcpvd7xtIM8y5LooAs=",
"lastModified": 1781152676,
"narHash": "sha256-RxWs5ND31KzTG7wvMM+PMfUjyNpmIEr999lqNARaM5o=",
"owner": "nix-community",
"repo": "disko",
"rev": "65fb947964bd44fc0008faf77d1fcb7a9f40bb32",
"rev": "ff8702b4de27f72b4c78573dfb89ec74e36abdf1",
"type": "github"
},
"original": {
@@ -106,11 +106,11 @@
"nixpkgs-stable": "nixpkgs-stable"
},
"locked": {
"lastModified": 1779250628,
"narHash": "sha256-QrHi1w+g7p58wMxcK9jOXr3oi2PRWQ+i4Sw38sL3dB4=",
"lastModified": 1784109865,
"narHash": "sha256-UCJ0O811UeGSe3GlLj8QxVa4ykHRfjl9rZvqFpiECME=",
"owner": "nix-community",
"repo": "emacs-overlay",
"rev": "5f8f3a12b25e29c1dd0a6363b61eba7d2f9944fe",
"rev": "422352494e740d44d7551549916655b122a9fd01",
"type": "github"
},
"original": {
@@ -187,25 +187,39 @@
"type": "github"
}
},
"gitignore": {
"flake-utils_3": {
"inputs": {
"nixpkgs": [
"hyprland",
"pre-commit-hooks",
"nixpkgs"
]
"systems": "systems_6"
},
"locked": {
"lastModified": 1709087332,
"narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=",
"owner": "hercules-ci",
"repo": "gitignore.nix",
"rev": "637db329424fd7e46cf4185293b9cc8c88c95394",
"lastModified": 1731533236,
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "gitignore.nix",
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"flake-utils_4": {
"inputs": {
"systems": "systems_7"
},
"locked": {
"lastModified": 1731533236,
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
@@ -237,11 +251,11 @@
]
},
"locked": {
"lastModified": 1779213149,
"narHash": "sha256-Cf+p/T4Z3n9Sw0TiR3kQaIwQI+/hfvLJcoTzeq6yS3E=",
"lastModified": 1783963347,
"narHash": "sha256-r376E2XpakiXwModDHIxlvB6qLq4iFVEq730vxOO4JY=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "bd868f769a69d3b6091a1da68a75cb83a181033c",
"rev": "a45a7c451455a51ae740ec3bce4024b312809c29",
"type": "github"
},
"original": {
@@ -295,11 +309,11 @@
]
},
"locked": {
"lastModified": 1776426399,
"narHash": "sha256-RUESLKNikIeEq9ymGJ6nmcDXiSFQpUW1IhJ245nL3xM=",
"lastModified": 1782566056,
"narHash": "sha256-haEZcHzYrePnjFOYSWTbxm/Nrla0aPslJfmvdCvqtVc=",
"owner": "hyprwm",
"repo": "hyprgraphics",
"rev": "68d064434787cf1ed4a2fe257c03c5f52f33cf84",
"rev": "c6e7b9f673f4360bc813d3dc75028f75ee88d3f8",
"type": "github"
},
"original": {
@@ -327,11 +341,11 @@
"xdph": "xdph"
},
"locked": {
"lastModified": 1779190425,
"narHash": "sha256-C0hPhLeo3ztBXYSnpYarYjw6HDvlgZRnNyFfG5PoaVI=",
"lastModified": 1784043142,
"narHash": "sha256-vd4VSlddmDAToJv/twyr0O8Siq4U/sOIXeo6DFZIolc=",
"owner": "hyprwm",
"repo": "Hyprland",
"rev": "203a121537d0868bd4d8258b58861ca970483157",
"rev": "79bc0ca16e7cca40c247a9200634d150fa8193d1",
"type": "github"
},
"original": {
@@ -347,11 +361,11 @@
]
},
"locked": {
"lastModified": 1778488488,
"narHash": "sha256-6Vvr0qMRdccvJqwzrXJkqoK6lWsdyC1nMrLjoHKqoGM=",
"lastModified": 1782811467,
"narHash": "sha256-JP0D8r8o9+jnYk0/B5O722La+oZeC5iNQ3lonKFTmbQ=",
"owner": "hyprwm",
"repo": "contrib",
"rev": "55b1393a23d6e4968ce6da704c8095f7e5e9fa3c",
"rev": "3dcbce715ae8b93107fa8632db15bf976862a573",
"type": "github"
},
"original": {
@@ -393,11 +407,11 @@
]
},
"locked": {
"lastModified": 1776426575,
"narHash": "sha256-KI6nIfVihn/DPaeB5Et46Xg3dkNHrrEtUd5LBBVomB0=",
"lastModified": 1782563850,
"narHash": "sha256-rs/EzgrgPHbCtJjFZN4aR1HYldH/0NtGAempWVpWQTs=",
"owner": "hyprwm",
"repo": "hyprland-guiutils",
"rev": "a968d211048e3ed538e47b84cb3649299578f19d",
"rev": "5ba080ee036c30cb2485f2647ff8a61f7aa08178",
"type": "github"
},
"original": {
@@ -499,11 +513,11 @@
]
},
"locked": {
"lastModified": 1772462885,
"narHash": "sha256-5pHXrQK9zasMnIo6yME6EOXmWGFMSnCITcfKshhKJ9I=",
"lastModified": 1782554491,
"narHash": "sha256-+p3MlyN/nqRefcf2IckPlGRUn9+hielqpS9XClbLleM=",
"owner": "hyprwm",
"repo": "hyprtoolkit",
"rev": "9af245a69fa6b286b88ddfc340afd288e00a6998",
"rev": "bdba25ced39ea39ab004a8f31593ba0b0ff1ca35",
"type": "github"
},
"original": {
@@ -524,11 +538,11 @@
]
},
"locked": {
"lastModified": 1778234770,
"narHash": "sha256-jAcsogZwWMfXT9MfXxZzkwliAqIuZUV0p71h6Ba9ReE=",
"lastModified": 1783002634,
"narHash": "sha256-xGqHIUK0wIZoW7SiMalwvO6uGOO/VrlQwoRobpE7dDI=",
"owner": "hyprwm",
"repo": "hyprutils",
"rev": "a2dbd8a4cc51f7cbe4224732668392bb1aa79df2",
"rev": "41fb809557abd29a57151b6e1aaeabd05f9437e1",
"type": "github"
},
"original": {
@@ -641,11 +655,11 @@
]
},
"locked": {
"lastModified": 1774185820,
"narHash": "sha256-ASExCDbdujwneZ/tZeNXxzKPbUFLroBnmPBJ5jEniCI=",
"lastModified": 1782065297,
"narHash": "sha256-/pRul59iTUd3Oz8fJNEeB0A2qXfNCMai5LwYlpLTkvY=",
"ref": "main",
"rev": "769bd540e8975050b2778025fdebc6fdd5c5e2b5",
"revCount": 42,
"rev": "1975a872f6587813e9f3741bdab29d9dc1573bc3",
"revCount": 43,
"type": "git",
"url": "ssh://gitea@git.ppp.pm:1122/alex/komga-reading-stats.git"
},
@@ -719,11 +733,11 @@
"systems": "systems_5"
},
"locked": {
"lastModified": 1778951860,
"narHash": "sha256-aFjBC3AVLh/bsgcsoI6Z/yQmh/NABffwHJIqQOTj+Tg=",
"lastModified": 1783761716,
"narHash": "sha256-1I1HEeTEBHcBy/jIO2l5NiJJZSqrQSMjwKo9A9ONZr4=",
"owner": "nix-community",
"repo": "nix-jetbrains-plugins",
"rev": "68930eefa5e77fc6bb7977635c83a003683c2f11",
"rev": "dc3c00516880f4fd82671bea4b3500451b29958d",
"type": "github"
},
"original": {
@@ -733,12 +747,15 @@
}
},
"nixos-hardware": {
"inputs": {
"nixpkgs": "nixpkgs_2"
},
"locked": {
"lastModified": 1779099457,
"narHash": "sha256-u73aVD/lUmmT3JV+kPDztl7zPwQKd0eobD1AbJltaGs=",
"lastModified": 1784100666,
"narHash": "sha256-HF/mrw5NYQfKFZgkfV2h1UL5/E3ccfsE2XJ1AbbLLJ0=",
"owner": "nixos",
"repo": "nixos-hardware",
"rev": "8792fab9d4a6454a9201675f01326f827ce35ead",
"rev": "fccfa9031a85b78a437f2f153c1f6449f3bc3185",
"type": "github"
},
"original": {
@@ -766,27 +783,40 @@
},
"nixpkgs-stable": {
"locked": {
"lastModified": 1779102034,
"narHash": "sha256-vZJZjLo513IeI8hjzHFc6TDezUd4uCE2Eq4SNO3DNNg=",
"lastModified": 1784011430,
"narHash": "sha256-lDebytrYdd47IBLwvNOD+6AGeoqZ78CIKlp70hzW280=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "687f05a9184cad4eaf905c48b63649e3a86f5433",
"rev": "8eeec934ae0dbeca3d7868c059568a65c08b2fc3",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-25.11",
"ref": "nixos-26.05",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_2": {
"locked": {
"lastModified": 1778869304,
"narHash": "sha256-30sZNZoA1cqF5JNO9fVX+wgiQYjB7HJqqJ4ztCDeBZE=",
"lastModified": 1767892417,
"narHash": "sha256-8bW3q88CEg2u4hSP66Vf4lpbLonHz7hqDNBMcCY7E9U=",
"rev": "3497aa5c9457a9d88d71fa93a4a8368816fbeeba",
"type": "tarball",
"url": "https://releases.nixos.org/nixos/unstable/nixos-26.05pre924538.3497aa5c9457/nixexprs.tar.xz"
},
"original": {
"type": "tarball",
"url": "https://channels.nixos.org/nixos-unstable/nixexprs.tar.xz"
}
},
"nixpkgs_3": {
"locked": {
"lastModified": 1784007870,
"narHash": "sha256-djcLt/JJphyNt4eDY9XTly+/WbCK5lqWq9lSgCmJkkQ=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "d233902339c02a9c334e7e593de68855ad26c4cb",
"rev": "18b9261cb3294b6d2a06d03f96872827b8fe2698",
"type": "github"
},
"original": {
@@ -820,18 +850,17 @@
"pre-commit-hooks": {
"inputs": {
"flake-compat": "flake-compat",
"gitignore": "gitignore",
"nixpkgs": [
"hyprland",
"nixpkgs"
]
},
"locked": {
"lastModified": 1778507602,
"narHash": "sha256-kTwur1wV+01SdqskVMSo6JMEpg71ps3HpbFY2GsflKs=",
"lastModified": 1783008725,
"narHash": "sha256-jGiy6+sxjNWXSjp25uoJuNfyH9zBK1PEDY0lVoL4ibQ=",
"owner": "cachix",
"repo": "git-hooks.nix",
"rev": "61ab0e80d9c7ab14c256b5b453d8b3fb0189ba0a",
"rev": "bca82caa46d5ec0f5d422c61fb1e30bc51313cbe",
"type": "github"
},
"original": {
@@ -840,6 +869,28 @@
"type": "github"
}
},
"puppy-tracker": {
"inputs": {
"flake-utils": "flake-utils_3",
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1784906229,
"narHash": "sha256-9ZzpwieFwushXgbZZj1W4i8uhI0dmLZCcQSb6qVhn18=",
"ref": "main",
"rev": "374e630d8fd0fa063753ffaa3537ada4fb4bc11e",
"revCount": 55,
"type": "git",
"url": "ssh://gitea@git.ppp.pm:1122/alex/puppy-tracker.git"
},
"original": {
"ref": "main",
"type": "git",
"url": "ssh://gitea@git.ppp.pm:1122/alex/puppy-tracker.git"
}
},
"root": {
"inputs": {
"agenix": "agenix",
@@ -856,12 +907,36 @@
"nix-gc-env": "nix-gc-env",
"nix-jetbrains-plugins": "nix-jetbrains-plugins",
"nixos-hardware": "nixos-hardware",
"nixpkgs": "nixpkgs_2",
"nixpkgs": "nixpkgs_3",
"pppdotpm-site": "pppdotpm-site",
"puppy-tracker": "puppy-tracker",
"solo-referee": "solo-referee",
"whib-backend": "whib-backend",
"whib-frontend": "whib-frontend"
}
},
"solo-referee": {
"inputs": {
"flake-utils": "flake-utils_4",
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1785015267,
"narHash": "sha256-NHaaFMznPus9jABGXlSHo++bYcbQeBnxvYPt/CzBEHg=",
"ref": "main",
"rev": "42af5dc48d1e2466a6b09273c7c96dfe2ab13c0b",
"revCount": 10,
"type": "git",
"url": "ssh://gitea@git.ppp.pm:1122/alex/solo-referee.git"
},
"original": {
"ref": "main",
"type": "git",
"url": "ssh://gitea@git.ppp.pm:1122/alex/solo-referee.git"
}
},
"systems": {
"locked": {
"lastModified": 1681028828,
@@ -937,6 +1012,36 @@
"type": "github"
}
},
"systems_6": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"systems_7": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"whib-backend": {
"inputs": {
"nixpkgs": [
@@ -1007,11 +1112,11 @@
]
},
"locked": {
"lastModified": 1778265244,
"narHash": "sha256-8jlPtGSsv/CQY6tVVyLF4Jjd0gnS+Zbn9yk/V13A9nM=",
"lastModified": 1782644412,
"narHash": "sha256-/iSa/bL1QQFLv+uJ9gI0N87J8gOeZXvca7EjoPGKE6w=",
"owner": "hyprwm",
"repo": "xdg-desktop-portal-hyprland",
"rev": "813ea5ca9a1702a9a2d1f5836bc00172ef698968",
"rev": "c01c99fc278ec68c82e9865923088f043c7c1621",
"type": "github"
},
"original": {
+12
View File
@@ -86,6 +86,18 @@
# url = "path:/home/alex/code/own/komga-reading-stats";
inputs.nixpkgs.follows = "nixpkgs";
};
puppy-tracker = {
url = "git+ssh://gitea@git.ppp.pm:1122/alex/puppy-tracker.git?ref=main";
# url = "path:/home/alex/code/puppy-tracker";
inputs.nixpkgs.follows = "nixpkgs";
};
solo-referee = {
url = "git+ssh://gitea@git.ppp.pm:1122/alex/solo-referee.git?ref=main";
# url = "path:/home/alex/code/solo-referee";
inputs.nixpkgs.follows = "nixpkgs";
};
};
outputs =
+2
View File
@@ -15,6 +15,8 @@
home.packages = [
pkgs.streamrip
pkgs.claude-code
pkgs.wl-clipboard
];
home.stateVersion = "24.11";
+13
View File
@@ -46,6 +46,19 @@
"--http-timeout=60"
];
};
"puppy.ppp.pm" = {
dnsProvider = "hetzner";
environmentFile = config.age.secrets.hetzner-dns.path;
group = "nginx";
extraLegoFlags = [
"--dns.resolvers=1.1.1.1:53,8.8.8.8:53"
"--dns.propagation-wait=60s"
"--dns-timeout=60"
"--http-timeout=60"
];
};
};
};
+3
View File
@@ -12,6 +12,7 @@ in
ssh.enable = true;
git.enable = true;
tmux.enable = true;
nginx.enable = true;
syncthing.enable = true;
@@ -24,6 +25,8 @@ in
romm.enable = true;
homepage.enable = true;
disk-smart.enable = true;
puppy-tracker.enable = true;
solo-referee.enable = true;
};
};
}
@@ -117,6 +117,16 @@ in
hardware.bluetooth.enable = true;
# Give up and enter a `failed` state (visible in `systemctl --failed`) if the
# container restarts more than 5 times in 5 minutes, instead of crash-looping
# forever. The window is deliberately long: a slow crash-loop (~5s per attempt)
# stays under systemd's default 5-starts-per-10s limit and would otherwise
# retry indefinitely.
systemd.services.podman-homeassistant = {
startLimitIntervalSec = 300;
startLimitBurst = 5;
};
virtualisation.oci-containers = {
backend = "podman";
@@ -241,7 +251,7 @@ in
];
script = ''
SUBDOMAINS="ha komga romm"
SUBDOMAINS="ha komga romm puppy"
INTERFACE="enp3s0"
CURRENT_IP=$(curl -s --fail --interface "$INTERFACE" ifconfig.me)
+17 -7
View File
@@ -9,13 +9,18 @@ let
nginxEnabled = config.mod.nginx.enable;
services = config.mod.homepage.services;
serviceToCard = svc: ''
<a class="card" href="http://manatee:${toString svc.port}">
<div class="name">${svc.name}</div>
<div class="desc">${svc.description}</div>
<div class="port">:${toString svc.port}</div>
</a>
'';
serviceToCard =
svc:
let
href = if svc.url != null then svc.url else "http://manatee:${toString svc.port}";
in
''
<a class="card" href="${href}">
<div class="name">${svc.name}</div>
<div class="desc">${svc.description}</div>
<div class="port">:${toString svc.port}</div>
</a>
'';
page = pkgs.writeTextDir "index.html" ''
<!DOCTYPE html>
@@ -83,6 +88,11 @@ in
name = lib.mkOption { type = lib.types.str; };
port = lib.mkOption { type = lib.types.port; };
description = lib.mkOption { type = lib.types.str; };
url = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = null;
description = "Link target for the card; defaults to http://manatee:<port>.";
};
};
}
);
-4
View File
@@ -143,14 +143,10 @@ in
"komga-reading-stats-claude-api-key" = {
file = ../../../../secrets/manatee/komga-reading-stats-claude-api-key.age;
mode = "0440";
group = "komga-reading-stats";
};
"komga-reading-stats-komga-api-key" = {
file = ../../../../secrets/manatee/komga-reading-stats-komga-api-key.age;
mode = "0440";
group = "komga-reading-stats";
};
};
};
@@ -0,0 +1,63 @@
{
inputs,
lib,
config,
...
}:
let
enabled = config.mod.puppy-tracker.enable;
nginxEnabled = config.mod.nginx.enable;
port = 8089;
in
{
options = {
mod.puppy-tracker = {
enable = lib.mkEnableOption "Enable puppy-tracker module";
};
};
imports = [
inputs.puppy-tracker.nixosModules.default
];
config = lib.mkIf enabled {
mod.homepage.services = [
{
name = "Puppy Tracker";
port = port;
description = "Sleep, meals, pees, poos";
# Login needs HTTPS (Secure cookies), so link to the public vhost.
url = "https://puppy.ppp.pm";
}
];
services.puppy-tracker = {
enable = true;
inherit port;
openFirewall = true;
# Served publicly over HTTPS via the nginx vhost below.
secureCookies = true;
# Shared registration secret; the file holds `PUPPY_INVITE_CODE=...`.
inviteCodeFile = config.age.secrets."puppy-tracker-invite-code".path;
};
services.nginx = lib.mkIf nginxEnabled {
virtualHosts."puppy.ppp.pm" = {
forceSSL = true;
useACMEHost = "puppy.ppp.pm";
# Photo uploads are up to 15 MB; give nginx headroom over its 1 MB default.
extraConfig = ''
client_max_body_size 20m;
'';
locations."/" = {
proxyPass = "http://127.0.0.1:${toString port}";
};
};
};
age.secrets."puppy-tracker-invite-code".file =
../../../../secrets/manatee/puppy-tracker-invite-code.age;
};
}
+14
View File
@@ -26,6 +26,16 @@ let
- 'Thumbs.db'
- '.DS_Store'
'';
# Give up and enter a `failed` state (visible in `systemctl --failed`) if a
# container restarts more than 5 times in 5 minutes, instead of crash-looping
# forever. The window is deliberately long: a slow crash-loop (~5s per attempt)
# stays under systemd's default 5-starts-per-10s limit and would otherwise
# retry indefinitely.
crashLoopGuard = {
startLimitIntervalSec = 300;
startLimitBurst = 5;
};
in
{
options = {
@@ -51,6 +61,10 @@ in
"d /var/lib/romm/assets 0755 root root -"
];
systemd.services.podman-romm = crashLoopGuard;
systemd.services.podman-romm-db = crashLoopGuard;
systemd.services.podman-romm-redis = crashLoopGuard;
systemd.services.romm-net = {
description = "Create Podman network for RomM";
after = [ "podman.service" ];
@@ -0,0 +1,46 @@
{
inputs,
lib,
config,
...
}:
let
enabled = config.mod.solo-referee.enable;
port = 8090;
in
{
options = {
mod.solo-referee = {
enable = lib.mkEnableOption "Enable solo-referee module";
};
};
imports = [
inputs.solo-referee.nixosModules.default
];
config = lib.mkIf enabled {
mod.homepage.services = [
{
name = "Solo Referee";
port = port;
description = "Solo-RPG tool with Claude as GM";
# url omitted → homepage links to http://manatee:${port}.
}
];
services.solo-referee = {
enable = true;
inherit port;
# Reachable on the LAN / Tailscale at manatee:${port}; no public vhost.
address = "0.0.0.0";
openFirewall = true;
# Anthropic API key kept out of the store; the file holds
# `ANTHROPIC_API_KEY=...`. Without it the offline stub GM runs.
apiKeyFile = config.age.secrets."solo-referee-api-key".path;
};
age.secrets."solo-referee-api-key".file =
../../../../secrets/manatee/solo-referee-api-key.age;
};
}
+71
View File
@@ -0,0 +1,71 @@
{
pkgs,
lib,
config,
...
}:
let
enabled = config.mod.tmux.enable;
in
{
options = {
mod.tmux = {
enable = lib.mkEnableOption "enable tmux module";
};
};
config = lib.mkIf enabled {
home-manager.users.alex = {
programs.tmux = {
enable = true;
baseIndex = 1;
keyMode = "vi";
# Allow vi mode to be enabled instantly
escapeTime = 0;
plugins = [ pkgs.tmuxPlugins.sensible ];
extraConfig = ''
set -g renumber-windows on
# https://old.reddit.com/r/tmux/comments/mesrci/tmux_2_doesnt_seem_to_use_256_colors/
set -g default-terminal "xterm-256color"
set -ga terminal-overrides ",*256col*:Tc"
set -ga terminal-overrides ',*:Ss=\E[%p1%d q:Se=\E[ q'
set-environment -g COLORTERM "truecolor"
set-option -g allow-rename off
# Remove date/time etc. on the right side
set -g status-right ""
bind r source-file ~/.config/tmux/tmux.conf \; display "Config reloaded"
# Remove accidental `suspend-client` triggers
unbind C-z
bind | split-window -h -c "#{pane_current_path}"
bind - split-window -v -c "#{pane_current_path}"
# Move panes shortcuts
bind h select-pane -L
bind j select-pane -D
bind k select-pane -U
bind l select-pane -R
# Resize panes
bind -r H resize-pane -L 5
bind -r J resize-pane -D 5
bind -r K resize-pane -U 5
bind -r L resize-pane -R 5
# Move windows
bind -r Left swap-window -t -1 \; select-window -t -1
bind -r Right swap-window -t +1 \; select-window -t +1
'';
};
};
};
}
-2
View File
@@ -16,7 +16,6 @@
home.packages = [
inputs.whib-backend.packages.${pkgs.stdenv.hostPlatform.system}.whib-import
# pkgs.beekeeper-studio
pkgs.bitwarden-desktop
pkgs.gimp
pkgs.zip
pkgs.unzip
@@ -27,7 +26,6 @@
pkgs.onlyoffice-desktopeditors
pkgs.wdisplays
pkgs.vlc
pkgs.claude-code
pkgs.opencode
];
+29
View File
@@ -0,0 +1,29 @@
{
pkgs,
lib,
config,
...
}:
let
enabled = config.mod.ai.enable;
in
{
options = {
mod.ai = {
enable = lib.mkEnableOption "enable ai module";
};
};
config = lib.mkIf enabled {
home-manager.users.alex = {
home.packages = [
pkgs.claude-code
];
programs.zsh.shellAliases = {
wclaude = "CLAUDE_CONFIG_DIR=$HOME/.claude-personal claude";
pclaude = "CLAUDE_CONFIG_DIR=$HOME/.claude-work claude";
};
};
};
}
+2
View File
@@ -42,6 +42,8 @@ in
};
vm.enable = true;
scripts.enable = true;
ai.enable = true;
};
};
}
+1 -1
View File
@@ -58,7 +58,7 @@
#+END_SRC
*** This makes emacsclient startup faster in TUI-mode
#+BEGIN_SRC emacs-lisp
(setq-default xterm-query-timeout nil)
(setq-default xterm-query-timeout 0.1)
#+END_SRC
*** Disable startup messages
#+BEGIN_SRC emacs-lisp
+37
View File
@@ -6,6 +6,38 @@
}:
let
enabled = config.mod.git.enable;
# Wrapper around `ssh-keygen` used as git's SSH signing program. Before a
# signing operation it ensures the passphrase-protected signing key is loaded
# into the agent — `ssh-keygen -Y sign` reads the key from disk and re-prompts
# every commit otherwise, since `AddKeysToAgent` only ever caches auth keys.
# Loading it once (through the GUI askpass) lets later commits reuse the
# cached key from the agent. Verification and every other op pass straight
# through to the real ssh-keygen untouched.
sshSignWrapper = pkgs.writeShellApplication {
name = "git-ssh-sign";
runtimeInputs = [
pkgs.openssh
pkgs.gawk
pkgs.gnugrep
];
text = ''
key="${config.age.secrets."alex.pinwheel-github.com-signing".path}"
case " $* " in
*" -Y sign "*)
fp=""
fp="$(ssh-keygen -lf "$key.pub" 2>/dev/null | awk '{print $2}')" || true
if [ -n "$fp" ] && ! ssh-add -l 2>/dev/null | grep -qF "$fp"; then
# </dev/null detaches stdin so ssh-add uses SSH_ASKPASS (the GUI).
ssh-add "$key" </dev/null || true
fi
;;
esac
exec ssh-keygen "$@"
'';
};
in
{
options = {
@@ -33,6 +65,11 @@ in
# Tells Git to use SSH instead of the default GPG
gpg.format = "ssh";
# Sign via a wrapper that loads the signing key into the agent on
# first use, so subsequent signed commits reuse the cached key
# instead of re-prompting for the passphrase every time.
gpg.ssh.program = "${sshSignWrapper}/bin/git-ssh-sign";
};
};
+15 -4
View File
@@ -55,12 +55,22 @@ let
esac
}
# Bind workspaces on startup
bind_workspaces
# Start the event listener first so monitoradded events emitted during
# session startup are not lost in the gap before we begin reading them.
${pkgs.socat}/bin/socat -U - UNIX-CONNECT:"$XDG_RUNTIME_DIR/hypr/$HYPRLAND_INSTANCE_SIGNATURE/.socket2.sock" | while read -r line; do
handle_event "$line"
done
done &
LISTENER_PID=$!
# Give socat a moment to actually connect before the initial bind.
sleep 0.2
bind_workspaces
# Re-bind once more after the DRM subsystem has had time to enumerate
# external connectors, in case they were not yet present at session start.
(sleep 3; bind_workspaces) &
wait $LISTENER_PID
'';
in
{
@@ -87,6 +97,7 @@ in
wayland.windowManager.hyprland = {
enable = true;
systemd.enable = false;
configType = "hyprlang";
extraConfig = ''
exec-once = uwsm app -- waybar
+14 -13
View File
@@ -13,6 +13,20 @@
components = [ "secrets" ];
};
home.sessionVariables = {
# gnome-keyring's PAM hooks export SSH_AUTH_SOCK pointing at a dead gcr
# socket (gcr-ssh-agent is disabled above), which shadows openssh's own
# agent and silently breaks passphrase caching. Force it back to the
# openssh agent started by `programs.ssh.startAgent`.
SSH_AUTH_SOCK = "$XDG_RUNTIME_DIR/ssh-agent";
# Route passphrase prompts through seahorse's GUI askpass instead of the
# terminal. `prefer` uses the GUI even when a tty is attached (ssh only
# falls back to askpass with no controlling terminal otherwise).
SSH_ASKPASS = "${pkgs.seahorse}/libexec/seahorse/ssh-askpass";
SSH_ASKPASS_REQUIRE = "prefer";
};
programs.ssh = {
enable = true;
enableDefaultConfig = false;
@@ -135,19 +149,6 @@
owner = "alex";
group = "users";
};
"alex.pinwheel-tadpole-ed25519" = {
file = ../../../../secrets/pinwheel/alex.pinwheel-tadpole-ed25519.age;
path = "/home/alex/.ssh/alex.pinwheel-tadpole-ed25519";
owner = "alex";
group = "users";
};
"alex.pinwheel-tadpole-ed25519.pub" = {
file = ../../../../secrets/pinwheel/alex.pinwheel-tadpole-ed25519.pub.age;
path = "/home/alex/.ssh/alex.pinwheel-tadpole-ed25519.pub";
owner = "alex";
group = "users";
};
};
services.openssh = {
+8
View File
@@ -56,6 +56,14 @@ in
initContent = lib.strings.concatStringsSep "\n" [
"export KEYTIMEOUT=1"
# Point every interactive shell at openssh's ssh-agent. home-manager's
# session vars set this too, but hm-session-vars runs once and is then
# inherited — so a tmux server that outlives this change (or started
# with the stale gcr socket) hands new panes a dead SSH_AUTH_SOCK.
# Re-exporting the fixed path per-shell keeps every pane on the same
# agent, so each key is only ever prompted for once per session.
''export SSH_AUTH_SOCK="$XDG_RUNTIME_DIR/ssh-agent"''
"bindkey -v '^?' backward-delete-char"
"bindkey '^a' beginning-of-line"
"bindkey '^e' end-of-line"
-5
View File
@@ -98,11 +98,6 @@ in
path = "${authorizedKeysPath}/alex.pinwheel-tadpole.pub";
};
"alex.pinwheel-tadpole-ed25519.pub" = {
file = ../../../../secrets/pinwheel/alex.pinwheel-tadpole-ed25519.pub.age;
path = "${authorizedKeysPath}/alex.pinwheel-tadpole-ed25519.pub";
};
"alex.tadpole-git.ppp.pm" = {
file = ../../../../secrets/tadpole/alex.tadpole-git.ppp.pm.age;
path = "/home/alex/.ssh/alex.tadpole-git.ppp.pm";
@@ -0,0 +1,7 @@
age-encryption.org/v1
-> ssh-ed25519 wkRvNA 1U7rIOHezvIpeb7QBkwz+NOgagrPDltkFtWY2N/hdE4
9rLqhxhc4c7cGB9hDPy9r0y5QbDp0CcYFwIWczB0mlU
-> ssh-ed25519 +oNaHQ w9QggF6DOTSMUC5n+7OKpFOM8iDSQakgx/10pIhM9ws
GOk7OQpLh5OjyZTiJQxd7hhN93EcSMnMxueNh6AwCOk
--- mzQrbeaXCVPu0MqNC0iAMLCiZbopyfYanwhsgDjFbZE
¡&ÈEÆÝ¼žÊÆ öfh(tJn´Ð†ç$^åkì[ Cå
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+2 -2
View File
@@ -15,8 +15,6 @@ in {
"pinwheel/alex.pinwheel-backwards.pub.age".publicKeys = [ pinwheel backwards alex ];
"pinwheel/alex.pinwheel-tadpole.age".publicKeys = [ pinwheel alex ];
"pinwheel/alex.pinwheel-tadpole.pub.age".publicKeys = [ pinwheel tadpole alex ];
"pinwheel/alex.pinwheel-tadpole-ed25519.age".publicKeys = [ pinwheel alex ];
"pinwheel/alex.pinwheel-tadpole-ed25519.pub.age".publicKeys = [ pinwheel tadpole alex ];
"pinwheel/alex.pinwheel-github.com.age".publicKeys = [ pinwheel alex ];
"pinwheel/alex.pinwheel-github.com.pub.age".publicKeys = [ pinwheel alex ];
"pinwheel/alex.pinwheel-github.com-signing.age".publicKeys = [ pinwheel alex ];
@@ -44,6 +42,8 @@ in {
"manatee/romm-auth-secret-key.age".publicKeys = [ manatee alex ];
"manatee/romm-db-password.age".publicKeys = [ manatee alex ];
"manatee/romm-metadata-api-keys.age".publicKeys = [ manatee alex ];
"manatee/puppy-tracker-invite-code.age".publicKeys = [ manatee alex ];
"manatee/solo-referee-api-key.age".publicKeys = [ manatee alex ];
"backwards/root.backwards.age".publicKeys = [ backwards alex ];
"backwards/root.backwards.pub.age".publicKeys = [ backwards alex ];