From 62c054bae4c2cbfefc5490799b87fff3ba6713e4 Mon Sep 17 00:00:00 2001 From: Jack Mechem Date: Wed, 22 Apr 2026 13:56:55 -0700 Subject: [PATCH 01/10] New app menu / window menu; changed desktop hyprland config --- flake.lock | 131 ++++++++++++++++++++-- flake.nix | 1 + modules/home-manager/homepackages.nix | 3 + modules/home-manager/hyprland-desktop.nix | 18 +-- 4 files changed, 134 insertions(+), 19 deletions(-) diff --git a/flake.lock b/flake.lock index 98bfadf..07224c5 100644 --- a/flake.lock +++ b/flake.lock @@ -20,6 +20,21 @@ } }, "crane": { + "locked": { + "lastModified": 1776635034, + "narHash": "sha256-OEOJrT3ZfwbChzODfIH4GzlNTtOFuZFWPtW7jIeR8xU=", + "owner": "ipetkov", + "repo": "crane", + "rev": "dc7496d8ea6e526b1254b55d09b966e94673750f", + "type": "github" + }, + "original": { + "owner": "ipetkov", + "repo": "crane", + "type": "github" + } + }, + "crane_2": { "locked": { "lastModified": 1775236976, "narHash": "sha256-gCgX+AXN7K1gAIEqcLcZHxmC+QoZcwn9m6Z9r2Az+N8=", @@ -142,6 +157,24 @@ "type": "github" } }, + "flake-utils_7": { + "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" + } + }, "gtkapps": { "inputs": { "flake-utils": "flake-utils_2", @@ -221,6 +254,27 @@ "type": "github" } }, + "hyprmwh": { + "inputs": { + "crane": "crane", + "flake-utils": "flake-utils_4", + "nixpkgs": "nixpkgs_4", + "rust-overlay": "rust-overlay" + }, + "locked": { + "lastModified": 1776890943, + "narHash": "sha256-KVvXWMABYfML0sttIwG41FRNuZUxhl+bqaAiulXzA9A=", + "owner": "JackMechem", + "repo": "hyprmwh", + "rev": "b7bbe057e9f701ae4b07e4f01eac724f398e43be", + "type": "github" + }, + "original": { + "owner": "JackMechem", + "repo": "hyprmwh", + "type": "github" + } + }, "nixpkgs": { "locked": { "lastModified": 1775126147, @@ -270,6 +324,22 @@ } }, "nixpkgs_4": { + "locked": { + "lastModified": 1776548001, + "narHash": "sha256-ZSK0NL4a1BwVbbTBoSnWgbJy9HeZFXLYQizjb2DPF24=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "b12141ef619e0a9c1c84dc8c684040326f27cdcc", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_5": { "locked": { "lastModified": 1775036866, "narHash": "sha256-ZojAnPuCdy657PbTq5V0Y+AHKhZAIwSIT2cb8UgAz/U=", @@ -285,7 +355,7 @@ "type": "github" } }, - "nixpkgs_5": { + "nixpkgs_6": { "locked": { "lastModified": 1774709303, "narHash": "sha256-D3Q07BbIA2KnTcSXIqqu9P586uWxN74zNoCH3h2ESHg=", @@ -301,7 +371,7 @@ "type": "github" } }, - "nixpkgs_6": { + "nixpkgs_7": { "locked": { "lastModified": 1774386573, "narHash": "sha256-4hAV26quOxdC6iyG7kYaZcM3VOskcPUrdCQd/nx8obc=", @@ -323,7 +393,8 @@ "gtkapps": "gtkapps", "gtkbar": "gtkbar", "home-manager": "home-manager", - "nixpkgs": "nixpkgs_4", + "hyprmwh": "hyprmwh", + "nixpkgs": "nixpkgs_5", "rust-app-menu": "rust-app-menu", "server-dash": "server-dash", "server-dash-api": "server-dash-api", @@ -332,12 +403,12 @@ }, "rust-app-menu": { "inputs": { - "crane": "crane", - "flake-utils": "flake-utils_4", + "crane": "crane_2", + "flake-utils": "flake-utils_5", "nixpkgs": [ "nixpkgs" ], - "rust-overlay": "rust-overlay" + "rust-overlay": "rust-overlay_2" }, "locked": { "lastModified": 1775688550, @@ -354,6 +425,27 @@ } }, "rust-overlay": { + "inputs": { + "nixpkgs": [ + "hyprmwh", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1776741231, + "narHash": "sha256-k9G98qzn+7npROUaks8VqCFm7cFtEG8ulQLBBo5lItg=", + "owner": "oxalica", + "repo": "rust-overlay", + "rev": "02061303f7c4c964f7b4584dabd9e985b4cd442b", + "type": "github" + }, + "original": { + "owner": "oxalica", + "repo": "rust-overlay", + "type": "github" + } + }, + "rust-overlay_2": { "inputs": { "nixpkgs": [ "rust-app-menu", @@ -374,7 +466,7 @@ "type": "github" } }, - "rust-overlay_2": { + "rust-overlay_3": { "inputs": { "nixpkgs": [ "server-dash-api", @@ -397,8 +489,8 @@ }, "server-dash": { "inputs": { - "flake-utils": "flake-utils_5", - "nixpkgs": "nixpkgs_5" + "flake-utils": "flake-utils_6", + "nixpkgs": "nixpkgs_6" }, "locked": { "lastModified": 1774932258, @@ -416,9 +508,9 @@ }, "server-dash-api": { "inputs": { - "flake-utils": "flake-utils_6", - "nixpkgs": "nixpkgs_6", - "rust-overlay": "rust-overlay_2" + "flake-utils": "flake-utils_7", + "nixpkgs": "nixpkgs_7", + "rust-overlay": "rust-overlay_3" }, "locked": { "lastModified": 1775019268, @@ -524,6 +616,21 @@ "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" + } + }, "zen-browser": { "inputs": { "home-manager": "home-manager_2", diff --git a/flake.nix b/flake.nix index ce817ce..16b34af 100755 --- a/flake.nix +++ b/flake.nix @@ -5,6 +5,7 @@ nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; gtkapps.url = "github:JackMechem/gtkapps"; gtkbar.url = "github:JackMechem/gtkbar"; + hyprmwh.url = "github:JackMechem/hyprmwh"; # midirun.url = "path:/home/jack/Projects/midirun"; zen-browser = { diff --git a/modules/home-manager/homepackages.nix b/modules/home-manager/homepackages.nix index 14f07c1..e870f80 100644 --- a/modules/home-manager/homepackages.nix +++ b/modules/home-manager/homepackages.nix @@ -37,5 +37,8 @@ jdk gnumake inputs.claude-code.packages.${pkgs.system}.claude-code + + ### My Stuff + inputs.hyprmwh.packages.${pkgs.system}.default ]; } diff --git a/modules/home-manager/hyprland-desktop.nix b/modules/home-manager/hyprland-desktop.nix index 38a278d..6bacd39 100644 --- a/modules/home-manager/hyprland-desktop.nix +++ b/modules/home-manager/hyprland-desktop.nix @@ -38,7 +38,6 @@ exec-once = [ "waypaper --restore" "gtkbar" - "rust-app-menu -d" "dbus-update-activation-environment --systemd WAYLAND_DISPLAY XDG_CURRENT_DESKTOP" "solaar -w hide" ]; @@ -46,7 +45,10 @@ # --- Variables --- "$terminal" = "ghostty"; "$fileManager" = "thunar"; - "$menu" = "rust-app-menu -ds"; + "$appMenu" = "hyprmwh --apps"; + "$windowMoveMenu" = "hyprmwh --windows"; + "$browser" = "zen-twilight"; + #"$menu" = "rust-app-menu -ds"; env = [ "XCURSOR_SIZE,24" @@ -84,7 +86,9 @@ layerrule = [ "blur on, match:namespace Launcher" - "ignore_alpha 0.3, match:namespace Launcher" + "ignore_alpha 0.1, match:namespace Launcher" + "blur on, match:namespace hyprmwh" + "ignore_alpha 0.1, match:namespace hyprmwh" ]; # --- Decoration --- @@ -127,19 +131,19 @@ force_default_wallpaper = 0; }; - # --- Keybinds --- + # --- Keybinds --- bind = [ # System/Rice - "${mainMod}, grave, exec, rice-settings" "${mainMod}, RETURN, exec, $terminal" "${mainMod} SHIFT, RETURN, exec, [float] $terminal" "${mainMod}, Q, killactive" "${mainMod} SHIFT, M, exit" "${mainMod}, E, exec, $fileManager" "${mainMod} SHIFT, E, exec, [float] $fileManager" - "${mainMod}, W, exec, zen-browser" + "${mainMod}, W, exec, $browser" "${mainMod}, TAB, togglefloating" - "${mainMod}, SPACE, exec, $menu" + "${mainMod}, SPACE, exec, $appMenu" + "${mainMod}, grave, exec, $windowMoveMenu" "${mainMod}, P, pseudo" "${mainMod}, V, togglesplit" "${mainMod}, M, fullscreen, 1" From 63f906cecd7d30a15dbe0811f3ef6f3d03101a6a Mon Sep 17 00:00:00 2001 From: Jack Mechem Date: Thu, 30 Apr 2026 12:59:55 -0700 Subject: [PATCH 02/10] Security key support --- .claw.json | 5 +++ .gitignore | 4 +++ CLAUDE.md | 12 +++++++ hosts/desktop/configuration.nix | 5 ++- hosts/desktop/home.nix | 17 ++++++++++ modules/home-manager/homepackages.nix | 41 ++++++++++++++++++++++- modules/home-manager/hyprland-desktop.nix | 5 +++ modules/nixos/ollama.nix | 5 +++ modules/nixos/system-packages.nix | 41 +++++++++++++---------- modules/nixos/user-jack.nix | 5 +++ 10 files changed, 121 insertions(+), 19 deletions(-) create mode 100644 .claw.json create mode 100644 .gitignore create mode 100644 CLAUDE.md diff --git a/.claw.json b/.claw.json new file mode 100644 index 0000000..e0e4c18 --- /dev/null +++ b/.claw.json @@ -0,0 +1,5 @@ +{ + "permissions": { + "defaultMode": "dontAsk" + } +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..387cc9f --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +# Claw Code local artifacts +.claw/settings.local.json +.claw/sessions/ +.clawhip/ diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..3da951b --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,12 @@ +# CLAUDE.md + +This file provides shared guidance to both Claude Code and Claw Code when working with this repository. + +## Detected stack +- No specific language markers were detected yet; document the primary language and verification commands once the project structure settles. +- Frameworks: none detected from the supported starter markers. + +## Working agreement +- Prefer small, reviewable changes and keep generated bootstrap files aligned with actual repo workflows. +- Keep shared defaults in `.claw.json`; reserve `.claw/settings.local.json` for machine-local overrides. +- Do not overwrite existing `CLAUDE.md` content automatically; update it intentionally when repo workflows change. diff --git a/hosts/desktop/configuration.nix b/hosts/desktop/configuration.nix index 77d4ec5..de58d9d 100644 --- a/hosts/desktop/configuration.nix +++ b/hosts/desktop/configuration.nix @@ -42,6 +42,8 @@ programs.zsh.enable = true; + programs.nix-ld.enable = true; + programs.thunar.enable = true; programs.dconf.enable = true; @@ -82,11 +84,12 @@ services.openssh = { enable = true; - listenAddresses = [{ addr = "192.168.1.67"; port = 2200; }]; }; services.gvfs.enable = true; + services.input-remapper.enable = true; + system.stateVersion = "25.11"; } diff --git a/hosts/desktop/home.nix b/hosts/desktop/home.nix index 13ca4e7..6aa61ff 100644 --- a/hosts/desktop/home.nix +++ b/hosts/desktop/home.nix @@ -117,6 +117,23 @@ home.sessionVariables = { EDITOR = "nvim"; + # claw-code: route to local Ollama instead of Anthropic/OpenAI + OPENAI_BASE_URL = "http://127.0.0.1:11434/v1"; + OPENAI_API_KEY = "ollama"; + }; + + systemd.user.services.ydotoold = { + Unit = { + Description = "ydotool daemon"; + After = [ "default.target" ]; + }; + Service = { + ExecStart = "${pkgs.ydotool}/bin/ydotoold"; + Restart = "always"; + }; + Install = { + WantedBy = [ "default.target" ]; + }; }; } diff --git a/modules/home-manager/homepackages.nix b/modules/home-manager/homepackages.nix index e870f80..6119c5c 100644 --- a/modules/home-manager/homepackages.nix +++ b/modules/home-manager/homepackages.nix @@ -1,4 +1,29 @@ -{ inputs, pkgs, ... }: +{ inputs, pkgs, lib, ... }: + +let + claw-code = pkgs.rustPlatform.buildRustPackage { + pname = "claw-code"; + version = "unstable-2026"; + + src = pkgs.fetchFromGitHub { + owner = "ultraworkers"; + repo = "claw-code"; + rev = "main"; + hash = "sha256-y63Kx7B1q2gWUO/4/k8hUgHzuKTi+HF+cGbr1em0grs="; + }; + + sourceRoot = "source/rust"; + + cargoHash = "sha256-bZKghBTbKrhm2Jiyg2su1c9Jlx2HVrMQjOTK6cgEc00="; + + doCheck = false; + + meta = { + description = "Open-source Rust implementation of the claw CLI agent harness"; + homepage = "https://github.com/ultraworkers/claw-code"; + }; + }; +in { home.packages = with pkgs; [ ### Desktop Stuff @@ -23,6 +48,9 @@ ### Note Taking obsidian + ### Input Remapping + ydotool + ### Random Libraries and Dependencies gtk3 glib @@ -37,8 +65,19 @@ jdk gnumake inputs.claude-code.packages.${pkgs.system}.claude-code + claw-code + opencode + postman ### My Stuff inputs.hyprmwh.packages.${pkgs.system}.default + + ### Browsers + epiphany + chromium + + ### Editors + zed-editor + jetbrains.idea ]; } diff --git a/modules/home-manager/hyprland-desktop.nix b/modules/home-manager/hyprland-desktop.nix index 6bacd39..44f0a20 100644 --- a/modules/home-manager/hyprland-desktop.nix +++ b/modules/home-manager/hyprland-desktop.nix @@ -40,6 +40,8 @@ "gtkbar" "dbus-update-activation-environment --systemd WAYLAND_DISPLAY XDG_CURRENT_DESKTOP" "solaar -w hide" + "ydotoold" + "${pkgs.kdePackages.polkit-kde-agent-1}/libexec/polkit-kde-authentication-agent-1" ]; # --- Variables --- @@ -212,6 +214,9 @@ # Custom scripts "${mainMod}, b, exec, bash -c 'pgrep gtkbar &>/dev/null && killall gtkbar || gtkbar &'" "${mainMod}, minus, exec, ~/.config/hypr/togglemonitor.sh ${monitor3}" + + # Mouse: back thumb button -> middle click (mchose mouse) + ", mouse:275, exec, ydotool click 0xC2" ]; bindle = [ diff --git a/modules/nixos/ollama.nix b/modules/nixos/ollama.nix index 7bd41f8..e53b29b 100644 --- a/modules/nixos/ollama.nix +++ b/modules/nixos/ollama.nix @@ -15,8 +15,13 @@ nixpkgs.config.allowUnfree = true; + nixpkgs.config.permittedInsecurePackages = [ + "openclaw-2026.3.12" + ]; + environment.systemPackages = with pkgs; [ ollama rocmPackages.rocminfo + openclaw ]; } diff --git a/modules/nixos/system-packages.nix b/modules/nixos/system-packages.nix index c67da9f..d6ef9f2 100644 --- a/modules/nixos/system-packages.nix +++ b/modules/nixos/system-packages.nix @@ -2,23 +2,30 @@ { - programs.firefox.enable = true; - programs.hyprland.enable = true; + programs.firefox.enable = true; + programs.hyprland.enable = true; - - # List packages installed in system profile. - environment.systemPackages = with pkgs; [ + # List packages installed in system profile. + environment.systemPackages = with pkgs; [ # neovim - tree - vim # Both vim and neovim just in case - wget - git - gcc - fastfetch - brightnessctl - killall - unzip - python3 - nodejs - ]; + tree + vim # Both vim and neovim just in case + wget + git + gcc + fastfetch + brightnessctl + killall + unzip + python3 + nodejs + input-remapper + kdePackages.polkit-kde-agent-1 + yubikey-manager + yubioath-flutter + ]; + + services.udev.packages = [ pkgs.yubikey-personalization ]; + services.pcscd.enable = true; + programs.ssh.startAgent = true; } diff --git a/modules/nixos/user-jack.nix b/modules/nixos/user-jack.nix index 2885bf2..7742e6e 100644 --- a/modules/nixos/user-jack.nix +++ b/modules/nixos/user-jack.nix @@ -11,6 +11,7 @@ "docker" "video" "render" + "input" ]; # Enable ‘sudo’ for the user. group = "jack"; packages = with pkgs; [ @@ -21,4 +22,8 @@ }; users.groups.jack = {}; + + services.udev.extraRules = '' + KERNEL=="uinput", GROUP="input", MODE="0660", OPTIONS+="static_node=uinput" + ''; } From b3eeccf11419c757e177f4ba751f7393e4eaaa68 Mon Sep 17 00:00:00 2001 From: Jack Mechem Date: Thu, 30 Apr 2026 16:52:45 -0700 Subject: [PATCH 03/10] Yubikey stuff --- flake.lock | 12 ++++++------ hosts/dellserv/configuration.nix | 12 ++++-------- modules/nixos/yubikey-auth.nix | 21 +++++++++++++++++++++ 3 files changed, 31 insertions(+), 14 deletions(-) create mode 100644 modules/nixos/yubikey-auth.nix diff --git a/flake.lock b/flake.lock index 07224c5..af3efa2 100644 --- a/flake.lock +++ b/flake.lock @@ -6,11 +6,11 @@ "nixpkgs": "nixpkgs" }, "locked": { - "lastModified": 1775271377, - "narHash": "sha256-0ru4G0uQeokPTlJGuRHf3ApBZMeuIRdUyp0SYi//RWM=", + "lastModified": 1777436347, + "narHash": "sha256-RD/HyNMkmeN4zqENph5Xzks/fz/ZwdUyL1x8rr5tQyA=", "owner": "sadjow", "repo": "claude-code-nix", - "rev": "214fdf6592f40a8bb472e80283c029d01fb6653d", + "rev": "bf3e43090b15d1e335f08e21c80678d6457458e8", "type": "github" }, "original": { @@ -277,11 +277,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1775126147, - "narHash": "sha256-J0dZU4atgcfo4QvM9D92uQ0Oe1eLTxBVXjJzdEMQpD0=", + "lastModified": 1777270315, + "narHash": "sha256-yKB4G6cKsQsWN7M6rZGk6gkJPDNPIzT05y4qzRyCDlI=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "8d8c1fa5b412c223ffa47410867813290cdedfef", + "rev": "6368eda62c9775c38ef7f714b2555a741c20c72d", "type": "github" }, "original": { diff --git a/hosts/dellserv/configuration.nix b/hosts/dellserv/configuration.nix index b7d20cc..5a41798 100644 --- a/hosts/dellserv/configuration.nix +++ b/hosts/dellserv/configuration.nix @@ -17,6 +17,7 @@ inputs.home-manager.nixosModules.default ../../modules/nixos/user-jack.nix ../../modules/nixos/syncthingServer.nix + ../../modules/nixos/yubikey-auth.nix ]; # Use the systemd-boot EFI boot loader. @@ -52,15 +53,10 @@ services.openssh.enable = true; services.openssh.settings = { - PasswordAuthentication = true; - KbdInteractiveAuthentication = true; - ChallengeResponseAuthentication = true; + PasswordAuthentication = false; + KbdInteractiveAuthentication = false; }; - # 2FA - security.pam.services.login.googleAuthenticator.enable = true; - security.pam.services.sshd.googleAuthenticator.enable = true; - ## services.nginx = { ## enable = true; ## virtualHosts."your.domain.or.ip" = { @@ -138,7 +134,7 @@ unzip python3 nodejs - google-authenticator + inputs.claude-code.packages.${pkgs.system}.claude-code ]; virtualisation.docker.enable = true; diff --git a/modules/nixos/yubikey-auth.nix b/modules/nixos/yubikey-auth.nix new file mode 100644 index 0000000..f699a3c --- /dev/null +++ b/modules/nixos/yubikey-auth.nix @@ -0,0 +1,21 @@ +{ config, lib, pkgs, ... }: + +{ + environment.systemPackages = with pkgs; [ + yubikey-manager + libfido2 + ]; + + # sudo authenticates via the forwarded SSH agent. + # Requires: ssh -A when connecting, and an ed25519-sk key in your agent. + # Generate one locally if you haven't: + # ssh-keygen -t ed25519-sk + # Then add the public key to ~/.ssh/authorized_keys on the server. + security.pam.sshAgentAuth.enable = true; + security.pam.services.sudo.sshAgentAuth = true; + + # Preserve the forwarded agent socket across the sudo boundary + security.sudo.extraConfig = '' + Defaults env_keep+=SSH_AUTH_SOCK + ''; +} From 4e3e23f1b6b0d46586f5d2b75758e0ace322f7c1 Mon Sep 17 00:00:00 2001 From: Jack Mechem Date: Thu, 30 Apr 2026 17:34:33 -0700 Subject: [PATCH 04/10] t480 security key login auth --- hosts/t480/configuration.nix | 1 + modules/nixos/yubikey-auth.nix | 16 +++++----------- modules/nixos/yubikey-pam.nix | 23 +++++++++++++++++++++++ 3 files changed, 29 insertions(+), 11 deletions(-) create mode 100644 modules/nixos/yubikey-pam.nix diff --git a/hosts/t480/configuration.nix b/hosts/t480/configuration.nix index ebd8ad6..fa046df 100644 --- a/hosts/t480/configuration.nix +++ b/hosts/t480/configuration.nix @@ -17,6 +17,7 @@ ../../modules/nixos/user-jack.nix ../../modules/nixos/sound.nix ../../modules/nixos/syncthing.nix + ../../modules/nixos/yubikey-pam.nix ]; boot.loader.systemd-boot.enable = true; diff --git a/modules/nixos/yubikey-auth.nix b/modules/nixos/yubikey-auth.nix index f699a3c..e104c76 100644 --- a/modules/nixos/yubikey-auth.nix +++ b/modules/nixos/yubikey-auth.nix @@ -6,16 +6,10 @@ libfido2 ]; - # sudo authenticates via the forwarded SSH agent. - # Requires: ssh -A when connecting, and an ed25519-sk key in your agent. - # Generate one locally if you haven't: + # Only FIDO2-backed SSH keys (ed25519-sk / ecdsa-sk) are accepted. + # Every SSH login to every account requires a YubiKey touch. + # Add your sk public key to ~/.ssh/authorized_keys before deploying: # ssh-keygen -t ed25519-sk - # Then add the public key to ~/.ssh/authorized_keys on the server. - security.pam.sshAgentAuth.enable = true; - security.pam.services.sudo.sshAgentAuth = true; - - # Preserve the forwarded agent socket across the sudo boundary - security.sudo.extraConfig = '' - Defaults env_keep+=SSH_AUTH_SOCK - ''; + # ssh-copy-id -i ~/.ssh/id_ed25519_sk.pub jack@dellserv + services.openssh.settings.PubkeyAcceptedAlgorithms = "sk-ssh-ed25519@openssh.com,sk-ecdsa-sha2-nistp256@openssh.com"; } diff --git a/modules/nixos/yubikey-pam.nix b/modules/nixos/yubikey-pam.nix new file mode 100644 index 0000000..6412e51 --- /dev/null +++ b/modules/nixos/yubikey-pam.nix @@ -0,0 +1,23 @@ +{ config, lib, pkgs, ... }: + +{ + environment.systemPackages = with pkgs; [ + yubikey-manager + libfido2 + ]; + + # pam_u2f: requires physical YubiKey touch for sudo and TTY login. + # Enroll your key BEFORE rebuilding (run on this machine): + # nix shell nixpkgs#pam_u2f -c pamu2fcfg -u jack | sudo tee /etc/u2f-mappings + # Touch the key when the LED blinks. + # Additional keys: nix shell nixpkgs#pam_u2f -c pamu2fcfg -n -u jack | sudo tee -a /etc/u2f-mappings + security.pam.u2f = { + enable = true; + control = "required"; + cue = true; + authFile = "/etc/u2f-mappings"; + }; + + security.pam.services.sudo.u2fAuth = true; + security.pam.services.login.u2fAuth = true; +} From 1b2dfe28a317afada7c60dca3910a37c97720ff6 Mon Sep 17 00:00:00 2001 From: Jack Mechem Date: Thu, 30 Apr 2026 20:21:16 -0700 Subject: [PATCH 05/10] t480 yubikey --- hosts/t480/configuration.nix | 4 ++-- modules/home-manager/homepackages.nix | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/hosts/t480/configuration.nix b/hosts/t480/configuration.nix index fa046df..c6ec065 100644 --- a/hosts/t480/configuration.nix +++ b/hosts/t480/configuration.nix @@ -23,7 +23,7 @@ boot.loader.systemd-boot.enable = true; boot.loader.efi.canTouchEfiVariables = true; - boot.kernelPackages = pkgs.linuxPackages_latest; + boot.kernelPackages = pkgs.linuxPackages_6_6; networking.hostName = "t480"; networking.networkmanager.enable = true; @@ -40,7 +40,7 @@ ]; trusted-public-keys = [ "cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=" - "nix-community.cachix.org-1:mB9FSh9qf2dde0enLeymSlflN93qlwkTnNQsGbLFPzU=" + "nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCUSPs=" ]; # Avoid redundant downloads diff --git a/modules/home-manager/homepackages.nix b/modules/home-manager/homepackages.nix index 6119c5c..f0d3149 100644 --- a/modules/home-manager/homepackages.nix +++ b/modules/home-manager/homepackages.nix @@ -9,7 +9,7 @@ let owner = "ultraworkers"; repo = "claw-code"; rev = "main"; - hash = "sha256-y63Kx7B1q2gWUO/4/k8hUgHzuKTi+HF+cGbr1em0grs="; + hash = "sha256-jGJgKOMn2Un6ZbEPh+7RWB1isvFLD86HWMLKTIBMUNs="; }; sourceRoot = "source/rust"; @@ -78,6 +78,6 @@ in ### Editors zed-editor - jetbrains.idea + # jetbrains.idea # Fuck InteliJ ]; } From e535a0894d5ded21664715b9363f93d6ac544164 Mon Sep 17 00:00:00 2001 From: Jack Mechem Date: Thu, 30 Apr 2026 20:27:50 -0700 Subject: [PATCH 06/10] Claude context --- .claude-context.md | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 .claude-context.md diff --git a/.claude-context.md b/.claude-context.md new file mode 100644 index 0000000..08c48fe --- /dev/null +++ b/.claude-context.md @@ -0,0 +1,44 @@ +# Claude Session Context + +## Current Status +- T480 is booted into an **old NixOS generation** due to a kernel panic after the last rebuild +- A rebuild is in progress (or needs to be re-run with `nixos-rebuild switch`) + +## Boot Panic Fix +- **Cause:** `linuxPackages_latest` pulled a bad kernel after nixpkgs was bumped in commit `b3eeccf` +- **Fix:** Already applied — `hosts/t480/configuration.nix` now uses `pkgs.linuxPackages_6_6` +- **Cache key** was also wrong and is now fixed in `configuration.nix` + +## Drive Encryption Plan +Goal: encrypt T480 root partition requiring **YubiKey + passphrase** (LUKS2 + FIDO2). + +- Drive is currently **not encrypted** +- Home directory has been **backed up to external drive** via rsync +- NixOS config is in git — no reinstall needed, doing **in-place encryption** + +### Steps +1. Flash Kali ISO to USB (`dd if=kali.iso of=/dev/sdX bs=4M status=progress oflag=sync`) +2. Boot Kali live USB +3. Encrypt root partition in-place: + ```bash + sudo cryptsetup reencrypt --encrypt --reduce-device-size 32M /dev/nvme0n1p2 + # verify partition name first with: lsblk + ``` +4. Enroll YubiKey as FIDO2 token: + ```bash + sudo systemd-cryptenroll --fido2-device=auto --fido2-with-client-pin=yes /dev/nvme0n1p2 + ``` +5. Chroot into NixOS and update config + bootloader +6. Add to `hosts/t480/configuration.nix`: + ```nix + boot.initrd.luks.devices."cryptroot" = { + device = "/dev/nvme0n1p2"; + crypttabExtraOpts = [ "fido2-device=auto" ]; + }; + ``` +7. Rebuild and reboot + +## YubiKey PAM Setup +- `modules/nixos/yubikey-pam.nix` configures PAM u2f with `control = "required"` +- Requires **both** YubiKey touch and password for sudo/login +- Auth file at `/etc/u2f-mappings` (already enrolled and correct) From b807476dafd5a9be8964697e90cce2f41bb6c459 Mon Sep 17 00:00:00 2001 From: Jack Mechem Date: Thu, 30 Apr 2026 23:20:08 -0700 Subject: [PATCH 07/10] Hypylock with yubikey --- hosts/t480/configuration.nix | 4 +- modules/home-manager/hyprland.nix | 123 ++++++++++++++++++++++++++++++ modules/nixos/yubikey-pam.nix | 7 +- result | 1 + 4 files changed, 132 insertions(+), 3 deletions(-) create mode 120000 result diff --git a/hosts/t480/configuration.nix b/hosts/t480/configuration.nix index c6ec065..6cf7eb7 100644 --- a/hosts/t480/configuration.nix +++ b/hosts/t480/configuration.nix @@ -40,7 +40,7 @@ ]; trusted-public-keys = [ "cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=" - "nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCUSPs=" + "nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=" ]; # Avoid redundant downloads @@ -98,6 +98,8 @@ }; }; + services.logind.settings.Login.HandleLidSwitch = "suspend"; + services.libinput.enable = true; services.openssh.enable = true; diff --git a/modules/home-manager/hyprland.nix b/modules/home-manager/hyprland.nix index d134baf..dc500fb 100644 --- a/modules/home-manager/hyprland.nix +++ b/modules/home-manager/hyprland.nix @@ -1,5 +1,127 @@ { pkgs, ... }: { + programs.hyprlock = { + enable = true; + settings = { + general = { + disable_loading_bar = true; + grace = 0; + hide_cursor = true; + }; + background = [{ + monitor = ""; + path = "screenshot"; + blur_passes = 3; + blur_size = 8; + brightness = 0.5; + }]; + label = [ + { + monitor = ""; + text = "Property of Jack Mechem — 702.201.4608"; + color = "rgba(c5c9c5ff)"; + font_size = 22; + font_family = "JetBrainsMono Nerd Font Bold"; + position = "0, 200"; + halign = "center"; + valign = "center"; + } + { + monitor = ""; + text = "If found — please contact me and return it ASAP."; + color = "rgba(c5c9c5ff)"; + font_size = 13; + font_family = "JetBrainsMono Nerd Font"; + position = "0, 166"; + halign = "center"; + valign = "center"; + } + { + monitor = ""; + text = "If stolen — fuck you."; + color = "rgba(c4746eff)"; + font_size = 16; + font_family = "JetBrainsMono Nerd Font Bold"; + position = "0, 138"; + halign = "center"; + valign = "center"; + } + { + monitor = ""; + text = "The drive is encrypted and the BIOS is locked. You'll get maybe $150 for it."; + color = "rgba(c5c9c580)"; + font_size = 11; + font_family = "JetBrainsMono Nerd Font"; + position = "0, 112"; + halign = "center"; + valign = "center"; + } + { + monitor = ""; + text = "Contact me now and I won't involve the police. I also have a GPS tracker installed."; + color = "rgba(c5c9c580)"; + font_size = 11; + font_family = "JetBrainsMono Nerd Font"; + position = "0, 94"; + halign = "center"; + valign = "center"; + } + { + monitor = ""; + text = "If you're in my class messing with this — fuck you too, don't touch my shit."; + color = "rgba(c5c9c5ff)"; + font_size = 11; + font_family = "JetBrainsMono Nerd Font"; + position = "0, 76"; + halign = "center"; + valign = "center"; + } + ]; + input-field = [{ + monitor = ""; + size = "250, 50"; + outline_thickness = 2; + dots_size = 0.33; + dots_spacing = 0.15; + dots_center = true; + outer_color = "rgba(e4687690)"; + inner_color = "rgba(181616cc)"; + font_color = "rgba(c5c9c5ff)"; + fade_on_empty = true; + placeholder_text = "Password..."; + rounding = 12; + check_color = "rgba(8a9a7bff)"; + fail_color = "rgba(c4746eff)"; + fail_text = "$FAIL ($ATTEMPTS)"; + position = "0, 0"; + halign = "center"; + valign = "center"; + }]; + }; + }; + + services.hypridle = { + enable = true; + settings = { + general = { + before_sleep_cmd = "loginctl lock-session"; + after_sleep_cmd = "hyprctl dispatch dpms on"; + lock_cmd = "pidof hyprlock || hyprlock"; + }; + listener = [ + { + timeout = 300; + on-timeout = "loginctl lock-session"; + } + { + timeout = 600; + on-timeout = "hyprctl dispatch dpms off"; + on-resume = "hyprctl dispatch dpms on"; + } + ]; + }; + }; + wayland.windowManager.hyprland = { enable = true; @@ -130,6 +252,7 @@ # --- Keybinds --- bind = [ # System/Rice + "${mainMod} SHIFT, D, exec, loginctl lock-session" "${mainMod}, grave, exec, rice-settings" "${mainMod}, RETURN, exec, $terminal" "${mainMod} SHIFT, RETURN, exec, [float] $terminal" diff --git a/modules/nixos/yubikey-pam.nix b/modules/nixos/yubikey-pam.nix index 6412e51..fd2e64f 100644 --- a/modules/nixos/yubikey-pam.nix +++ b/modules/nixos/yubikey-pam.nix @@ -14,10 +14,13 @@ security.pam.u2f = { enable = true; control = "required"; - cue = true; - authFile = "/etc/u2f-mappings"; + settings = { + cue = true; + authfile = "/etc/u2f-mappings"; + }; }; security.pam.services.sudo.u2fAuth = true; security.pam.services.login.u2fAuth = true; + security.pam.services.hyprlock.u2fAuth = true; } diff --git a/result b/result new file mode 120000 index 0000000..6b6c4d8 --- /dev/null +++ b/result @@ -0,0 +1 @@ +/nix/store/wh5w5irf66v9kc87nl7zxywjzr1kqp7m-hm_hyprhyprlock.conf \ No newline at end of file From 86cddf81b37e3d5e9262dc5d3bb49be8799fe276 Mon Sep 17 00:00:00 2001 From: Jack Mechem Date: Fri, 1 May 2026 03:10:16 -0700 Subject: [PATCH 08/10] Self hosted git repos --- hosts/dellserv/configuration.nix | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/hosts/dellserv/configuration.nix b/hosts/dellserv/configuration.nix index 5a41798..90e422d 100644 --- a/hosts/dellserv/configuration.nix +++ b/hosts/dellserv/configuration.nix @@ -107,6 +107,11 @@ } ''; }; + virtualHosts."git.jackmechem.dev" = { + extraConfig = '' + reverse_proxy localhost:3002 + ''; + }; }; services.server-dash = { @@ -118,6 +123,19 @@ useNixBuild = false; }; + services.forgejo = { + enable = true; + settings = { + server = { + DOMAIN = "git.jackmechem.dev"; + HTTP_PORT = 3002; + ROOT_URL = "https://git.jackmechem.dev"; + SSH_DOMAIN = "gitssh.jackmechem.dev"; + SSH_PORT = 22; + }; + }; + }; + # Make sure jack is in the shadow group users.users.jack.extraGroups = [ "shadow" ]; From a00e05f3e875c3f661668a28e3360d42614dd003 Mon Sep 17 00:00:00 2001 From: Jack Mechem Date: Fri, 1 May 2026 03:50:03 -0700 Subject: [PATCH 09/10] Dns server --- hosts/dellserv/configuration.nix | 29 +++++++++++++++++++++++++++++ hosts/desktop/configuration.nix | 1 + hosts/t480/configuration.nix | 1 + 3 files changed, 31 insertions(+) diff --git a/hosts/dellserv/configuration.nix b/hosts/dellserv/configuration.nix index 90e422d..7af8a29 100644 --- a/hosts/dellserv/configuration.nix +++ b/hosts/dellserv/configuration.nix @@ -26,6 +26,9 @@ networking.hostName = "dell-xps-nixos-serv"; # Define your hostname. networking.networkmanager.enable = true; + networking.hosts = { + "127.0.0.1" = [ "gitssh.jackmechem.dev" ]; + }; networking.firewall.allowedTCPPorts = [ 80 3000 @@ -33,7 +36,9 @@ 8080 443 22 + 53 ]; + networking.firewall.allowedUDPPorts = [ 53 ]; nix.settings.experimental-features = [ "nix-command" @@ -112,6 +117,11 @@ reverse_proxy localhost:3002 ''; }; + virtualHosts."adguard.jackmechem.dev" = { + extraConfig = '' + reverse_proxy localhost:3003 + ''; + }; }; services.server-dash = { @@ -123,6 +133,25 @@ useNixBuild = false; }; + services.resolved.settings.Resolve.DNSStubListener = "no"; + + services.adguardhome = { + enable = true; + mutableSettings = false; + port = 3003; + settings = { + http.address = lib.mkForce "127.0.0.1:3003"; + dns = { + bind_hosts = [ "0.0.0.0" ]; + port = 53; + bootstrap_dns = [ + "9.9.9.10" + "149.112.112.10" + ]; + }; + }; + }; + services.forgejo = { enable = true; settings = { diff --git a/hosts/desktop/configuration.nix b/hosts/desktop/configuration.nix index de58d9d..08cf8f6 100644 --- a/hosts/desktop/configuration.nix +++ b/hosts/desktop/configuration.nix @@ -28,6 +28,7 @@ networking.hostName = "jackdesk"; networking.networkmanager.enable = true; + networking.nameservers = [ "192.168.1.164" ]; networking.firewall.allowedTCPPorts = [ 2200 3000 ]; diff --git a/hosts/t480/configuration.nix b/hosts/t480/configuration.nix index 6cf7eb7..c98393e 100644 --- a/hosts/t480/configuration.nix +++ b/hosts/t480/configuration.nix @@ -27,6 +27,7 @@ networking.hostName = "t480"; networking.networkmanager.enable = true; + networking.nameservers = [ "192.168.1.164" ]; nix.settings = { # Use all cores for building From acc3946d777c7d0869bc3bbc04e3f8d24f12817c Mon Sep 17 00:00:00 2001 From: Jack Mechem Date: Fri, 1 May 2026 04:06:06 -0700 Subject: [PATCH 10/10] Fix ssh regular ed25519 key --- hosts/dellserv/configuration.nix | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/hosts/dellserv/configuration.nix b/hosts/dellserv/configuration.nix index 7af8a29..f28f549 100644 --- a/hosts/dellserv/configuration.nix +++ b/hosts/dellserv/configuration.nix @@ -61,6 +61,10 @@ PasswordAuthentication = false; KbdInteractiveAuthentication = false; }; + services.openssh.extraConfig = '' + Match User forgejo + PubkeyAcceptedAlgorithms +ssh-ed25519 + ''; ## services.nginx = { ## enable = true;