Compare commits

..

36 Commits

Author SHA1 Message Date
0xWheatyz 9c9935b550 feat(kicad): add KICAD9_FOOTPRINT_DIR session variable for footprint libraries 2026-04-20 23:04:50 -04:00
0xWheatyz 5da4d36d25 feat(claude): add caveman and oh-my-claudecode skills via flake inputs
Declaratively manage Claude Code skills through home-manager by fetching
plugin repos as non-flake inputs and symlinking their skills directories.
2026-04-20 22:51:37 -04:00
0xWheatyz d83b03bbd8 fix(wireguard): exclude local 10.0.0.0/24 from tunnel to preserve LAN access
Replace 0.0.0.0/0 allowedIPs with CIDR blocks covering everything except
10.0.0.0/24, which conflicts with the building's local network. Also switch
endpoint back to hostname and remove unused tailscale service block.
2026-04-20 19:50:44 -04:00
0xWheatyz c371552dfd fix(wireguard): use static endpoint IP and drop manual route hooks
Replace hostname endpoint with resolved IP (69.48.243.22) so
wg-quick's native fwmark-based routing handles 0.0.0.0/0 correctly.
Remove preUp/postDown hooks that conflicted with wg-quick's own
policy routing.
2026-04-15 19:19:22 -04:00
0xWheatyz 8b5111e9a1 fix(wireguard): move endpoint route to preUp/postDown hooks
postUp runs after wg-quick has already rerouted all traffic through
the tunnel, making external DNS unreachable. Use preUp to add the
host route before routing changes, and postDown to clean up after.
2026-04-15 19:12:34 -04:00
0xWheatyz cca5c48725 fix(wireguard): use public DNS to resolve endpoint before tunnel is up
Query @1.1.1.1 explicitly in postUp/preDown hooks since the VPN DNS
(10.0.1.65) is unreachable before the tunnel establishes.
2026-04-15 19:08:13 -04:00
0xWheatyz b4e4036c41 fix(wireguard): resolve endpoint hostname to IP before adding route
ip route does not accept hostnames. Use dig to resolve
vpn.leeworks.dev to an IP address in postUp/preDown hooks.
2026-04-15 19:00:00 -04:00
0xWheatyz 3aab755e37 fix(wireguard): add endpoint host route and trust wg0 interface
Add postUp/preDown hooks to create a host route for the VPN endpoint
via the real gateway, preventing a routing loop when allowedIPs is
0.0.0.0/0. Also add wg0 to firewall trustedInterfaces.
2026-04-15 18:45:03 -04:00
0xWheatyz 6e361b197c feat(wireguard): update wg0 config to match ClusterVPN-Nixos.conf
- Address: 10.0.1.66/28 -> 10.0.1.67/32
- Add DNS 10.0.1.65
- AllowedIPs: restricted subnets -> 0.0.0.0/0 (full tunnel)
2026-04-15 18:40:53 -04:00
0xWheatyz 6fd0b18746 fix(home): move gtk3 to home.packages for FreeCAD GSettings schema
FreeCAD is a home-manager package, so its GSettings schema dependency
(org.gtk.Settings.FileChooser) must also be in home.packages for
home-manager to include it in XDG_DATA_DIRS. Having gtk3 only in
system packages left it invisible to the user session.
2026-04-05 19:36:33 -04:00
0xWheatyz 0c15063a58 fix(system): add gtk3 to system packages for GSettings file chooser schema
FreeCAD crashes with 'org.gtk.Settings.FileChooser is not installed'
because home-manager packages don't get their GSettings schemas compiled
into the system profile. Moving gtk3 to environment.systemPackages fixes this.
2026-04-05 19:28:53 -04:00
0xWheatyz 9056237e8a fix(portal): add xdg-desktop-portal-gtk for freecad file chooser
FreeCAD's save/open dialogs require the GTK portal backend for the
file chooser D-Bus service. The bare gtk3 package doesn't provide this,
so replace it with the portal package in the system config.
2026-04-05 18:54:03 -04:00
0xWheatyz 64b450bbe7 feat(wireguard): expand allowedIPs to include home network subnets
Add 192.168.1.0/24, 10.0.0.0/24, and 10.0.1.0/26 to route traffic
for the full home LAN through the WireGuard tunnel.
2026-04-05 14:09:16 -04:00
0xWheatyz 8eee1ab82f fix(home): add gtk3 to resolve freecad save-as crash
FreeCAD's file chooser requires the org.gtk.Settings.FileChooser
GSettings schema from GTK3, which was missing from XDG_DATA_DIRS.
2026-04-05 13:57:37 -04:00
0xWheatyz c133ff306e fix(flake): unpin nixpkgs-unstable to resolve broken claude-code package
Revert the nixpkgs-unstable pin to follow the branch again, as the
pinned revision shipped a broken package.
2026-04-04 02:12:42 -04:00
0xWheatyz 5a53ce36e9 feat(home): add freecad package 2026-04-04 02:12:36 -04:00
0xWheatyz 7c25228bc5 feat(yubikey): configure GPG signing key and disable GCR ssh-agent
Set actual GPG key ID for git commit signing, disable GCR ssh-agent
socket so gpg-agent handles SSH auth, and trim redundant setup steps
from yubikey guide.
2026-04-04 02:12:02 -04:00
0xWheatyz 1ca8cc8c57 feat(wireguard): add wg-quick VPN client configuration
Connect to home network VPN via vpn.leeworks.dev with wg0 interface
on the 10.0.1.64/28 subnet. Private key loaded from /etc/wireguard/private.key.
2026-04-04 01:53:45 -04:00
0xWheatyz 014216de6b feat(yubikey): add GPG agent, pcscd, and YubiKey support
Enable gpg-agent with SSH support and pinentry-gnome3, add
yubikey-manager and pcscd service, configure GPG with hardened
preferences and scdaemon, disable gnome-keyring SSH agent, and
prepare git signing configuration.
2026-03-31 21:25:35 -04:00
0xWheatyz 1ad1614509 docs(yubikey): add post-rebuild YubiKey setup guide
Step-by-step guide covering GPG key generation, subkey creation,
moving keys to YubiKey, SSH key deployment, and git signing setup.
2026-03-31 21:22:11 -04:00
0xWheatyz fa2ae3b86e chore(git): set pull strategy to merge by default 2026-03-28 11:57:03 -04:00
0xWheatyz 91faab704c fix(gnome): remove xwayland-native-scaling to prevent KiCad crashes
The experimental xwayland-native-scaling feature causes XWayland
connection loss when KiCad fullscreens on the second monitor,
crashing the application. Fractional scaling is retained via
scale-monitor-framebuffer.
2026-03-28 11:56:42 -04:00
0xWheatyz 8a091acccc chore(deps): update nixpkgs-unstable flake input 2026-03-16 18:58:26 -04:00
0xWheatyz 85b7d25486 feat(claude): add CLAUDE.md, commit command, and update permissions
Add home-manager managed CLAUDE.md with commit behavior instructions,
a /commit slash command for conventional commits workflow, and expand
allowed Bash permissions to include nix commands. Remove inline
customInstructions in favor of CLAUDE.md file.
2026-03-16 18:58:12 -04:00
0xWheatyz 1226603c7f chore(cleanup): removed some old software that is not used often 2026-03-15 23:31:46 -04:00
0xWheatyz bdbf892ea1 feat: auto-update Claude Code from nixpkgs-unstable
- Add nixpkgs-unstable input for latest Claude Code versions
- Remove duplicate home-manager config from configuration.nix (handled by flake)
- Remove fetchTarball/fetchGit calls incompatible with pure flake mode
- Add shell function to auto-update unstable on nixos-rebuild
2026-03-15 23:16:00 -04:00
0xWheatyz ea03f7d998 feat(claude): disable commit signature and fix permission syntax
- Add includeCoAuthoredBy option set to false
- Update customInstructions to exclude signature from commits
- Fix Bash permission syntax from "git *" to "git:*"
2026-03-15 12:22:12 -04:00
0xWheatyz b14299e94e feat(claude): enable always thinking mode and force settings file
Add alwaysThinkingEnabled option and force flag to overwrite existing
settings.json file managed outside of home-manager.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-15 12:20:02 -04:00
0xWheatyz 23897093b2 feat(claude): add Claude Code settings for auto-permissions and conventional commits
Configure Claude Code to allow Edit, Write, and git commands without prompting,
and instruct it to use conventional commit format in git repositories.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-15 12:08:49 -04:00
0xWheatyz 9d420e7bb9 docs: add comprehensive README documenting system configuration
Added detailed documentation covering NixOS configuration, installed software,
features, and usage instructions for both system and user-level management.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-12 22:17:02 -04:00
0xWheatyz c7a6827bdc feat(terminal): replace GNOME Console with Ghostty
Replace the default GNOME Console terminal with Ghostty by adding it to home packages, configuring it as the default terminal application via dconf settings, and excluding GNOME Console from installed packages.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-12 22:14:40 -04:00
0xWheatyz e1cd081e45 feat(terminal): replace zellij with tmux as terminal multiplexer
Switch from zellij to tmux for terminal multiplexing with mouse support, improved window numbering, and 256-color terminal configuration.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-12 22:09:18 -04:00
0xWheatyz c42fa715ae Merge pull request 'cursor_fix' (#1) from cursor_fix into master
Reviewed-on: #1
2026-03-11 02:35:25 +00:00
0xWheatyz 576cf0dc98 feat(nvim): applied kickstart nvim from github 2026-03-10 22:32:31 -04:00
0xWheatyz 22d0e34139 fix: docker rootless now works due to /etc/hosts permissions change 2026-03-07 15:46:09 -05:00
0xWheatyz 068eba7c26 feat: working neovim 2026-02-19 22:12:45 -05:00
8 changed files with 1030 additions and 97 deletions
+251
View File
@@ -0,0 +1,251 @@
# NixOS Configuration
Personal NixOS system configuration using Flakes and Home Manager for declarative system management.
## System Overview
- **OS**: NixOS 25.11
- **Desktop Environment**: GNOME (Wayland/X11)
- **Terminal**: Ghostty + tmux
- **Shell**: Zsh with Oh-My-Zsh (agnoster theme)
- **Editor**: Neovim with [kickstart.nvim](https://github.com/0xWheatyz/kickstart.nvim)
- **Hostname**: nixos
## Features
### Core System
- **Bootloader**: GRUB with EFI support and OS Prober (dual-boot ready)
- **Timezone**: America/New_York
- **Locale**: en_US.UTF-8
- **Networking**: NetworkManager enabled
### Hardware Support
- **Bluetooth**: Enabled with Blueman
- **Fingerprint Sensor**: fprintd enabled
- **Audio**: PipeWire with ALSA and PulseAudio compatibility
- **Printing**: CUPS enabled
### Security & Authentication
- **YubiKey Support**: Configured for login and sudo authentication
- **Auto-lock on YubiKey removal**: Sessions lock when YubiKey is disconnected
- **Fingerprint Authentication**: Available for compatible hardware
### Development Environment
- **Docker**: Rootless mode enabled with proper namespace configuration
- **VMware Workstation**: Host support enabled
- **Nix Flakes**: Experimental features enabled
### Networking
- **Tailscale VPN**: Enabled with client routing features
- **Firewall**: Configured with Tailscale trusted interface
- **Editable /etc/hosts**: Permissions set to 0644 for easy modification
### Desktop Customization
- **GNOME Extensions**:
- Blur My Shell
- Just Perfection
- Arc Menu
- **Fonts**: 0xProto Nerd Font, Adwaita icons
- **Scaling**: Experimental fractional scaling and xwayland-native-scaling enabled
- **QT Integration**: QT apps use GNOME theme (Adwaita Dark)
### Alternative Window Manager
- **Hyprland**: Configured but not currently active (see `home.nix` for configuration)
## Installed Software
### System Packages
- Firefox
- VMware Workstation
- Lunar Client (Minecraft)
- JetBrains Rust Rover
- Cursor (VS Code fork)
- Obsidian
- Claude Code
### User Packages
- Kate (KDE text editor)
- Bitwarden (desktop + CLI)
- LunarVim
- KiCad
- Ghostty terminal
- Python 3
- nmap
- minicom
- freerdp
## Configuration Files
```
.
├── configuration.nix # System-level configuration
├── home.nix # User-level configuration (Home Manager)
├── hardware-configuration.nix # Auto-generated hardware config
└── flake.nix # Flake inputs and outputs
```
## Getting Started
### First Time Setup
1. Clone this repository:
```bash
git clone <your-repo-url> ~/Documents/nixos-configuration
cd ~/Documents/nixos-configuration
```
2. Review and customize configurations:
- Edit `configuration.nix` for system-wide changes
- Edit `home.nix` for user-specific settings
3. Apply the configuration:
```bash
sudo nixos-rebuild switch --flake .#nixos
```
### Making Changes
#### System-Level Changes
Edit `configuration.nix` and rebuild:
```bash
sudo nixos-rebuild switch --flake .#nixos
```
#### User-Level Changes
Edit `home.nix` and rebuild:
```bash
sudo nixos-rebuild switch --flake .#nixos
# or use home-manager directly:
home-manager switch
```
### Adding Packages
**System-wide** (available to all users):
Add to `environment.systemPackages` in `configuration.nix`:
```nix
environment.systemPackages = with pkgs; [
# your-package-here
];
```
**User-specific**:
Add to `home.packages` in `home.nix`:
```nix
home.packages = with pkgs; [
# your-package-here
];
```
### Updating the System
Update flake inputs and rebuild:
```bash
nix flake update
sudo nixos-rebuild switch --flake .#nixos
```
## Key Configurations
### Git Configuration
Managed declaratively in `home.nix`:
- **User**: 0xWheatyz
- **Email**: wyatt@leeworks.dev
- **Default Branch**: master
- **Auto push remote setup**: Enabled
- **Custom alias**: `git lg` for pretty log visualization
### SSH Configuration
Custom SSH hosts configured in `home.nix`:
- **vps**: Direct connection to 45.79.198.105
- **home**: Via jump host proxy
- **git**: Local git server at 10.0.1.10
- Connection multiplexing enabled for faster subsequent connections
### Tmux
- Mouse support enabled
- Window numbering starts at 1
- 256-color terminal support
- Auto-starts on terminal launch
### Zsh
- Oh-My-Zsh with agnoster theme
- Custom `nix develop` wrapper that launches in zsh
- Tmux auto-start on interactive terminals
- Project shell indicator in prompt
## Neovim Configuration
Using [kickstart.nvim](https://github.com/0xWheatyz/kickstart.nvim) as the base configuration, managed through Flakes.
Required dependencies are automatically installed:
- Neovim
- ripgrep
- fd
- gcc
- gnumake
- git
Configuration is synchronized from the GitHub repository and placed in `~/.config/nvim`.
## Docker Configuration
Docker is configured in rootless mode:
- Unprivileged user namespaces enabled
- Socket variable automatically set
- User `l-wyatt` is in the `docker` group
Usage:
```bash
docker ps # No sudo required
```
## Troubleshooting
### Slow Shutdown
The configuration includes optimizations for shutdown handling:
- User manager timeout reduced to 30s (from default 90s)
- Prevents hangs when user linger is enabled
### Building from Flake
If you encounter issues, try:
```bash
# Rebuild with verbose output
sudo nixos-rebuild switch --flake .#nixos --show-trace
# Check flake validity
nix flake check
# Update flake lock file
nix flake update
```
### YubiKey Issues
If YubiKey authentication isn't working:
```bash
# Check PAM configuration
cat /etc/pam.d/login
cat /etc/pam.d/sudo
# Verify udev rules
udevadm control --reload-rules
```
## Important Notes
- **stateVersion**: Set to 25.11 - do not change after initial installation
- **Home Manager stateVersion**: Also 25.11 - keep in sync with system version
- **Unfree packages**: Enabled system-wide via `nixpkgs.config.allowUnfree`
- **User groups**: l-wyatt is member of: networkmanager, wheel, docker, dialout
- **User linger**: Enabled for background services
## Additional Resources
- [NixOS Manual](https://nixos.org/manual/nixos/stable/)
- [Home Manager Manual](https://nix-community.github.io/home-manager/)
- [Nix Flakes](https://nixos.wiki/wiki/Flakes)
- [kickstart.nvim Documentation](https://github.com/nvim-lua/kickstart.nvim)
## License
This configuration is personal and provided as-is for reference.
+96 -32
View File
@@ -1,13 +1,13 @@
# Edit this configuration file to define what should be installed on # Edit this configuration file to define what should be installed on
# your system. Help is available in the configuration.nix(5) man page # your system. Help is available in the configuration.nix(5) man page
# and in the NixOS manual (accessible by running nixos-help). # and in the NixOS manual (accessible by running 'nixos-help').
{ config, pkgs, ... }: { config, pkgs, pkgs-unstable, ... }:
{ {
imports = imports = [
[ # Include the results of the hardware scan. ./hardware-configuration.nix
/etc/nixos/hardware-configuration.nix # home-manager is imported via flake.nix
]; ];
## Commented out as defined at the end of the page ## Commented out as defined at the end of the page
@@ -100,22 +100,21 @@
environment.systemPackages = with pkgs; [ environment.systemPackages = with pkgs; [
home-manager home-manager
firefox firefox
vmware-workstation
cacert cacert
lunar-client
jetbrains.rust-rover
code-cursor code-cursor
adwaita-icon-theme adwaita-icon-theme
obsidian pkgs-unstable.claude-code # Use unstable for latest version
yubikey-manager
]; ];
# Some programs need SUID wrappers, can be configured further or are # Some programs need SUID wrappers, can be configured further or are
# started in user sessions. # started in user sessions.
# programs.mtr.enable = true; # programs.mtr.enable = true;
# programs.gnupg.agent = { programs.gnupg.agent = {
# enable = true; enable = true;
# enableSSHSupport = true; enableSSHSupport = true;
# }; pinentryPackage = pkgs.pinentry-gnome3;
};
# List services that you want to enable: # List services that you want to enable:
@@ -136,6 +135,8 @@
# (e.g. man configuration.nix or on https://nixos.org/nixos/options.html). # (e.g. man configuration.nix or on https://nixos.org/nixos/options.html).
system.stateVersion = "25.11"; # Did you read the comment? system.stateVersion = "25.11"; # Did you read the comment?
# Home Manager Configuration is handled in flake.nix
### Start of self configuration ### Start of self configuration
# Configure grub to provide ubuntu option # Configure grub to provide ubuntu option
boot.loader.grub.enable = true; boot.loader.grub.enable = true;
@@ -153,7 +154,12 @@
services.blueman.enable = true; services.blueman.enable = true;
# Allow /etc/hosts to be modified without system rebuild # Allow /etc/hosts to be modified without system rebuild
environment.etc.hosts.mode = "0700"; environment.etc.hosts.mode = "0644";
# KiCad footprint libraries
environment.sessionVariables = {
KICAD9_FOOTPRINT_DIR = "${pkgs.kicad-libraries.footprints}/share/kicad/footprints";
};
# Enable flakes and extras # Enable flakes and extras
nix.settings.experimental-features = [ "nix-command" "flakes" ]; nix.settings.experimental-features = [ "nix-command" "flakes" ];
@@ -172,17 +178,52 @@
}; };
}; };
virtualisation.vmware.host.enable = true;
services.tailscale = { # WireGuard VPN
enable = true; networking.wg-quick.interfaces.wg0 = {
useRoutingFeatures = "client"; # or "both" for subnet routing address = [ "10.0.1.67/32" ];
dns = [ "10.0.1.65" ];
privateKeyFile = "/etc/wireguard/private.key";
peers = [{
publicKey = "VEpzr/CeGdS6Wsy0NDDfmlB/bCYxS55A155HWGCIIzc=";
endpoint = "vpn.leeworks.dev:51820";
# Route all traffic through VPN EXCEPT the local 10.0.0.0/24 network
allowedIPs = [
"0.0.0.0/5"
"8.0.0.0/7"
"10.0.1.0/24"
"10.0.2.0/23"
"10.0.4.0/22"
"10.0.8.0/21"
"10.0.16.0/20"
"10.0.32.0/19"
"10.0.64.0/18"
"10.0.128.0/17"
"10.1.0.0/16"
"10.2.0.0/15"
"10.4.0.0/14"
"10.8.0.0/13"
"10.16.0.0/12"
"10.32.0.0/11"
"10.64.0.0/10"
"10.128.0.0/9"
"11.0.0.0/8"
"12.0.0.0/6"
"16.0.0.0/4"
"32.0.0.0/3"
"64.0.0.0/2"
"128.0.0.0/1"
];
persistentKeepalive = 25;
}];
}; };
# Open firewall for Tailscale # Open firewall for Tailscale
networking.firewall = { networking.firewall = {
checkReversePath = "loose"; checkReversePath = "loose";
trustedInterfaces = [ "tailscale0" ]; trustedInterfaces = [ "tailscale0" "wg0" ];
allowedUDPPorts = [ config.services.tailscale.port ]; allowedUDPPorts = [ config.services.tailscale.port ];
}; };
@@ -213,20 +254,14 @@
# security.pki.certificateFiles = [ /etc/nixos/certs/ipa-ca.crt ]; # security.pki.certificateFiles = [ /etc/nixos/certs/ipa-ca.crt ];
programs.hyprland = {
enable = true;
withUWSM = true; # Recommended for NixOS 24.11+
xwayland.enable = true;
};
# Enable necessary services # Enable necessary services
xdg.portal = { xdg.portal = {
enable = true; enable = true;
extraPortals = with pkgs; [ extraPortals = [ pkgs.xdg-desktop-portal-gtk ];
xdg-desktop-portal-hyprland
];
}; };
services.pcscd.enable = true;
security.pam.services = { security.pam.services = {
login.u2fAuth = true; login.u2fAuth = true;
sudo.u2fAuth = true; sudo.u2fAuth = true;
@@ -241,17 +276,36 @@
RUN+="${pkgs.systemd}/bin/loginctl lock-sessions" RUN+="${pkgs.systemd}/bin/loginctl lock-sessions"
''; '';
# Optimize shutdown handling to prevent user manager hangs
# Reduce timeout for user manager service during shutdown (default is 90s, reducing to 30s)
# This prevents the 2-minute hang when shutting down with linger enabled
systemd.services."user@".serviceConfig = {
TimeoutStopSec = "30s";
};
# Reduce default timeout for all user services
systemd.user.extraConfig = ''
DefaultTimeoutStopSec=30s
'';
# Gnome Configuration # Gnome Configuration
fonts.packages = [ fonts.packages = [
pkgs.adwaita-icon-theme pkgs.adwaita-icon-theme
pkgs.nerd-fonts._0xproto pkgs.nerd-fonts._0xproto
]; ];
fonts.fontconfig.enable = true; fonts.fontconfig.enable = true;
services.gnome.core-apps.enable = false; services.gnome = {
services.gnome.core-developer-tools.enable = false; core-apps.enable = true;
services.gnome.games.enable = false; core-developer-tools.enable = true;
games.enable = false;
};
services.desktopManager.gnome.extraGSettingsOverrides = ''
[org.gnome.mutter]
experimental-features=['scale-monitor-framebuffer']
'';
environment.gnome.excludePackages = with pkgs; [ environment.gnome.excludePackages = with pkgs; [
gnome-tour gnome-user-docs gnome-tour gnome-user-docs gnome-console
]; ];
qt = { qt = {
@@ -261,4 +315,14 @@
}; };
security.wrappers = {
# Low-level unprivileged sandboxing tool, see <https://github.com/containers/bubblewrap>.
bwrap = {
owner = "root";
group = "root";
source = "${pkgs.bubblewrap}/bin/bwrap";
setuid = true;
};
};
} }
+32
View File
@@ -0,0 +1,32 @@
building the system configuration...
error:
… while calling the 'head' builtin
at /nix/store/j4hbw1ws742nmsfhbd9r22k1qgivk7hc-nixos-25.11/nixos/lib/attrsets.nix:1696:13:
1695| if length values == 1 || pred here (elemAt values 1) (head values) then
1696| head values
| ^
1697| else
… while evaluating the attribute 'value'
at /nix/store/j4hbw1ws742nmsfhbd9r22k1qgivk7hc-nixos-25.11/nixos/lib/modules.nix:1118:7:
1117| // {
1118| value = addErrorContext "while evaluating the option `${showOption loc}':" value;
| ^
1119| inherit (res.defsFinal') highestPrio;
… while evaluating the option `system.build.toplevel':
… while evaluating definitions from `/nix/store/j4hbw1ws742nmsfhbd9r22k1qgivk7hc-nixos-25.11/nixos/nixos/modules/system/activation/top-level.nix':
… while evaluating the option `assertions':
… while evaluating definitions from `/nix/store/qlchl88ml287pcv5xqyrpcq7jjyl3qgm-home-manager-25.11.tar.gz/home-manager/nixos/common.nix':
(stack trace truncated; use '--show-trace' to show the full, detailed trace)
error: The option `home-manager.users.l-wyatt.programs.neovim-kickstart' does not exist. Definition values:
- In `/home/l-wyatt/Documents/nixos-configuration/configuration.nix':
{
enable = true;
}
Command 'nix-build '<nixpkgs/nixos>' --attr config.system.build.toplevel --no-out-link' returned non-zero exit status 1.
Generated
+169
View File
@@ -0,0 +1,169 @@
{
"nodes": {
"caveman": {
"flake": false,
"locked": {
"lastModified": 1776507098,
"narHash": "sha256-M+NoWXxrhtbkbe/lmq7P0/KpmqOZzJjhgeUVjY+7N2k=",
"owner": "JuliusBrussee",
"repo": "caveman",
"rev": "84cc3c14fa1e10182adaced856e003406ccd250d",
"type": "github"
},
"original": {
"owner": "JuliusBrussee",
"repo": "caveman",
"type": "github"
}
},
"flake-utils": {
"inputs": {
"systems": "systems"
},
"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"
}
},
"home-manager": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1775077333,
"narHash": "sha256-OXcxobt7lBkh1B8AjwreU+24myhtKpqeLfAeIyNLFY8=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "49ca96b2714c5931e17401eff87f3edd42d2b0f2",
"type": "github"
},
"original": {
"owner": "nix-community",
"ref": "release-25.11",
"repo": "home-manager",
"type": "github"
}
},
"kickstart-nvim": {
"inputs": {
"flake-utils": "flake-utils",
"nixpkgs": "nixpkgs"
},
"locked": {
"lastModified": 1771545825,
"narHash": "sha256-xGrTr8aXGzKBpF+RRwnLR8y8yDweojaoqttfA6RH1ws=",
"owner": "0xWheatyz",
"repo": "kickstart.nvim",
"rev": "cef178c27d1b3840d943f5a28b3a45f9eae049d7",
"type": "github"
},
"original": {
"owner": "0xWheatyz",
"repo": "kickstart.nvim",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1771369470,
"narHash": "sha256-0NBlEBKkN3lufyvFegY4TYv5mCNHbi5OmBDrzihbBMQ=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "0182a361324364ae3f436a63005877674cf45efb",
"type": "github"
},
"original": {
"owner": "nixos",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs-unstable": {
"locked": {
"lastModified": 1776329215,
"narHash": "sha256-a8BYi3mzoJ/AcJP8UldOx8emoPRLeWqALZWu4ZvjPXw=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "b86751bc4085f48661017fa226dee99fab6c651b",
"type": "github"
},
"original": {
"owner": "nixos",
"ref": "nixpkgs-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_2": {
"locked": {
"lastModified": 1775002709,
"narHash": "sha256-d3Yx83vSrN+2z/loBh4mJpyRqr9aAJqlke4TkpFmRJA=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "bcd464ccd2a1a7cd09aa2f8d4ffba83b761b1d0e",
"type": "github"
},
"original": {
"owner": "nixos",
"ref": "nixos-25.11",
"repo": "nixpkgs",
"type": "github"
}
},
"oh-my-claudecode": {
"flake": false,
"locked": {
"lastModified": 1776693787,
"narHash": "sha256-C/m8Vlt6MXy8nlgqtoey9A5JnVTHCPkGUjar9x5Y2uw=",
"owner": "Yeachan-Heo",
"repo": "oh-my-claudecode",
"rev": "084fc47266824b35f4c8cbe886c0990ae716c184",
"type": "github"
},
"original": {
"owner": "Yeachan-Heo",
"repo": "oh-my-claudecode",
"type": "github"
}
},
"root": {
"inputs": {
"caveman": "caveman",
"home-manager": "home-manager",
"kickstart-nvim": "kickstart-nvim",
"nixpkgs": "nixpkgs_2",
"nixpkgs-unstable": "nixpkgs-unstable",
"oh-my-claudecode": "oh-my-claudecode"
}
},
"systems": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
}
},
"root": "root",
"version": 7
}
+28 -23
View File
@@ -1,37 +1,36 @@
{ {
description = "FrostPhoenix's nixos configuration"; description = "NixOS configuration with home-manager and kickstart.nvim";
inputs = { inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; nixpkgs.url = "github:nixos/nixpkgs/nixos-25.11";
nur.url = "github:nix-community/NUR"; nixpkgs-unstable.url = "github:nixos/nixpkgs/nixpkgs-unstable";
home-manager = { home-manager = {
url = "github:nix-community/home-manager"; url = "github:nix-community/home-manager/release-25.11";
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
}; };
kickstart-nvim.url = "github:0xWheatyz/kickstart.nvim";
nix-gaming.url = "github:fufexan/nix-gaming"; caveman = {
nix-flatpak.url = "github:gmodena/nix-flatpak"; url = "github:JuliusBrussee/caveman";
flake = false;
nix-index-database = { };
url = "github:nix-community/nix-index-database"; oh-my-claudecode = {
inputs.nixpkgs.follows = "nixpkgs"; url = "github:Yeachan-Heo/oh-my-claudecode";
};
maple-mono = {
url = "github:subframe7536/maple-font/variable";
flake = false; flake = false;
}; };
superfile.url = "github:yorukot/superfile";
vicinae.url = "github:vicinaehq/vicinae";
zen-browser.url = "github:0xc000022070/zen-browser-flake/beta";
}; };
outputs = { self, nixpkgs, home-manager, ... }: { outputs = { self, nixpkgs, nixpkgs-unstable, home-manager, kickstart-nvim, caveman, oh-my-claudecode, ... }:
let
system = "x86_64-linux";
pkgs-unstable = import nixpkgs-unstable {
inherit system;
config.allowUnfree = true;
};
in {
nixosConfigurations = { nixosConfigurations = {
nixos = nixpkgs.lib.nixosSystem { nixos = nixpkgs.lib.nixosSystem {
system = "x86_64-linux"; inherit system;
specialArgs = { inherit pkgs-unstable; };
modules = [ modules = [
./configuration.nix ./configuration.nix
home-manager.nixosModules.home-manager home-manager.nixosModules.home-manager
@@ -39,9 +38,15 @@
home-manager.useGlobalPkgs = true; home-manager.useGlobalPkgs = true;
home-manager.useUserPackages = true; home-manager.useUserPackages = true;
home-manager.users.l-wyatt = import ./home.nix; home-manager.users.l-wyatt = import ./home.nix;
home-manager.extraSpecialArgs = {
inherit kickstart-nvim caveman oh-my-claudecode;
};
home-manager.sharedModules = [
kickstart-nvim.homeManagerModules.default
];
} }
]; ];
}; };
}; };
}; };
}` }
+39
View File
@@ -0,0 +1,39 @@
# Do not modify this file! It was generated by 'nixos-generate-config'
# and may be overwritten by future invocations. Please make changes
# to /etc/nixos/configuration.nix instead.
{ config, lib, pkgs, modulesPath, ... }:
{
imports =
[ (modulesPath + "/installer/scan/not-detected.nix")
];
boot.initrd.availableKernelModules = [ "nvme" "xhci_pci" "thunderbolt" "usb_storage" "sd_mod" ];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ "kvm-amd" ];
boot.extraModulePackages = [ ];
fileSystems."/" =
{ device = "/dev/disk/by-uuid/2e63927a-129d-400a-b532-5e98dd1f53d0";
fsType = "ext4";
};
fileSystems."/boot" =
{ device = "/dev/disk/by-uuid/6FAB-C1E3";
fsType = "vfat";
options = [ "fmask=0077" "dmask=0077" ];
};
swapDevices = [ ];
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
# (the default) this is the recommended approach. When using systemd-networkd it's
# still possible to use this option, but it's recommended to use it in conjunction
# with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
networking.useDHCP = lib.mkDefault true;
# networking.interfaces.enp193s0f3u2.useDHCP = lib.mkDefault true;
# networking.interfaces.wlp1s0.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
}
+164 -38
View File
@@ -1,4 +1,4 @@
{ config, pkgs, ... }: { config, pkgs, lib, caveman, oh-my-claudecode, ... }:
{ {
home.username = "l-wyatt"; home.username = "l-wyatt";
@@ -21,9 +21,14 @@
lunarvim lunarvim
minicom minicom
kicad kicad
ghostty
gnupg
pinentry-gnome3
gnomeExtensions.blur-my-shell gnomeExtensions.blur-my-shell
gnomeExtensions.just-perfection gnomeExtensions.just-perfection
gnomeExtensions.arc-menu gnomeExtensions.arc-menu
freecad
gtk3 # Provides org.gtk.Settings.FileChooser schema for FreeCAD
]; ];
# -------------------------- # --------------------------
@@ -69,6 +74,16 @@
initContent = '' initContent = ''
export SHELL=$(which zsh) export SHELL=$(which zsh)
alias nix-shell='nix-shell --run $SHELL' alias nix-shell='nix-shell --run $SHELL'
# Auto-update nixpkgs-unstable (for claude-code) on rebuild
nixos-rebuild() {
if [[ "$1" == "switch" || "$1" == "boot" || "$1" == "test" ]]; then
echo "Updating nixpkgs-unstable for latest Claude Code..."
nix flake update nixpkgs-unstable --flake /home/l-wyatt/Documents/nixos-configuration
fi
command sudo nixos-rebuild "$@" --flake /home/l-wyatt/Documents/nixos-configuration
}
nix() { nix() {
if [[ $1 == "develop" ]]; then if [[ $1 == "develop" ]]; then
shift shift
@@ -88,14 +103,58 @@
''; '';
}; };
# Configure cursor theme
home.pointerCursor = {
gtk.enable = true;
x11.enable = true;
name = "Adwaita";
package = pkgs.adwaita-icon-theme;
size = 24;
};
# Set Ghostty as default terminal
dconf.settings = {
"org/gnome/desktop/default-applications/terminal" = {
exec = "ghostty";
exec-arg = "";
};
"org/gnome/crypto/cache" = {
enable-ssh-agent = false;
};
};
# Disable GCR ssh-agent so gpg-agent handles SSH
systemd.user.sockets.gcr-ssh-agent.Install.WantedBy = lib.mkForce [];
# GPG configuration
programs.gpg = {
enable = true;
settings = {
keyserver = "hkps://keys.openpgp.org";
keyid-format = "0xlong";
with-fingerprint = true;
personal-cipher-preferences = "AES256 AES192 AES";
personal-digest-preferences = "SHA512 SHA384 SHA256";
personal-compress-preferences = "ZLIB BZIP2 ZIP Uncompressed";
};
scdaemonSettings = {
disable-ccid = true;
};
};
# Manage your git configuration declaratively # Manage your git configuration declaratively
programs.git = { programs.git = {
enable = true; enable = true;
signing = {
key = "0xADCEAC560B498269";
signByDefault = true;
};
settings = { settings = {
user = { user = {
name = "0xWheatyz"; name = "0xWheatyz";
email = "wyatt@leeworks.dev"; email = "wyatt@leeworks.dev";
}; };
pull.rebase = "false";
init.defaultBranch = "master"; init.defaultBranch = "master";
push.autoSetupRemote = "true"; push.autoSetupRemote = "true";
alias.lg = "log --graph --pretty=format:'%C(yellow)%h%Creset -%C(red)%d%Creset %s %Cgreen(%cr)%Creset %C(bold blue)<%an>%Creset' --abbrev-commit"; alias.lg = "log --graph --pretty=format:'%C(yellow)%h%Creset -%C(red)%d%Creset %s %Cgreen(%cr)%Creset %C(bold blue)<%an>%Creset' --abbrev-commit";
@@ -106,53 +165,120 @@
programs.tmux = { programs.tmux = {
enable = true; enable = true;
# Basic tmux configuration # Optional: customize tmux settings
terminal = "screen-256color";
historyLimit = 10000;
keyMode = "vi";
mouse = true;
extraConfig = '' extraConfig = ''
# Set prefix to Ctrl-a instead of Ctrl-b # Enable mouse support
unbind C-b set -g mouse on
set-option -g prefix C-a
bind-key C-a send-prefix
# Split panes using | and - # Start window numbering at 1
bind | split-window -h set -g base-index 1
bind - split-window -v
unbind '"'
unbind %
# Reload config file # Set terminal colors
bind r source-file ~/.config/tmux/tmux.conf set -g default-terminal "screen-256color"
''; '';
}; };
# Neovim management # Neovim management - using kickstart.nvim via flake
programs.neovim = { # Basic fallback config (uncomment if not using the flake)
enable = true; #programs.neovim = {
defaultEditor = true; # enable = true;
# defaultEditor = true;
#
# # Load Lua config inline
# extraLuaConfig = ''
# vim.opt.number = true
# vim.opt.tabstop = 2
# vim.opt.shiftwidth = 2
# vim.opt.expandtab = true
# vim.opt.relativenumber = true
#
# require("telescope").setup {}
# require("nvim-treesitter.configs").setup { highlight = { enable = true } }
# '';
#
# plugins = with pkgs.vimPlugins; [
# telescope-nvim
# nvim-treesitter
# nvim-lspconfig
# gruvbox
# ];
#};
# Load Lua config inline # Use kickstart.nvim configuration from flake
extraLuaConfig = '' programs.neovim-kickstart.enable = true;
vim.opt.number = true
vim.opt.tabstop = 2
vim.opt.shiftwidth = 2
vim.opt.expandtab = true
vim.opt.relativenumber = true
require("telescope").setup {} # Claude Code skills (managed declaratively via flake inputs)
require("nvim-treesitter.configs").setup { highlight = { enable = true } } home.file.".claude/skills/caveman" = {
source = "${caveman}/skills/caveman";
recursive = true;
};
home.file.".claude/skills/caveman-help" = {
source = "${caveman}/skills/caveman-help";
recursive = true;
};
home.file.".claude/skills/oh-my-claudecode" = {
source = "${oh-my-claudecode}/skills";
recursive = true;
};
# Claude Code configuration
home.file.".claude/CLAUDE.md" = {
text = ''
## Commit Behavior
After completing each logical unit of work, use the /commit skill to stage
and commit changes before proceeding to the next task. Do not batch unrelated
changes into a single commit. Do not wait to be asked.
''; '';
force = true;
};
plugins = with pkgs.vimPlugins; [ home.file.".claude/commands/commit.md" = {
telescope-nvim text = ''
nvim-treesitter ---
nvim-lspconfig description: Stage and commit changes as a conventional commit with one logical unit per commit
gruvbox ---
Review the current working tree with `git status` and `git diff --staged` and `git diff`.
Then do the following:
1. Identify the smallest logical unit of change present. If multiple unrelated changes exist, only stage and commit one unit at a time leave the rest unstaged.
2. Stage only the files (or hunks via `git add -p`) relevant to that logical unit.
3. Write a commit message following the Conventional Commits format:
<type>(<scope>): <description>
Types: feat, fix, docs, style, refactor, perf, test, chore, ci
- scope is optional but use it when the change is clearly scoped to a module, package, or domain
- description: lowercase, imperative mood, no trailing period, max ~72 chars
- if the change warrants a body, add it after a blank line
4. Run `git commit` with that message. Never use `--no-verify`.
5. Report what was committed and what (if anything) remains uncommitted.
'';
force = true;
};
home.file.".claude/settings.json" = {
text = builtins.toJSON {
permissions = {
allow = [
"Edit"
"Write"
"Bash(git:*)"
"Bash(nix-shell:*)"
"Bash(nix eval:*)"
"Bash(nix flake check:*)"
]; ];
}; };
alwaysThinkingEnabled = true;
includeCoAuthoredBy = false;
};
force = true;
};
programs.ssh = { programs.ssh = {
enable = true; enable = true;
@@ -183,8 +309,8 @@
proxyJump = "_JumpHost"; proxyJump = "_JumpHost";
}; };
"git" = { "git" = {
hostname = "10.0.0.9"; hostname = "10.0.1.10";
port = 122; port = 22;
user = "git"; user = "git";
}; };
}; };
+247
View File
@@ -0,0 +1,247 @@
# Post-Rebuild YubiKey Setup Guide
## Step 1: Generate GPG Master Key
```bash
gpg --expert --full-generate-key
```
At the prompts:
1. Select **(9) ECC and ECC**
2. Curve: **Curve 25519**
3. Expiration: **1y**
4. Real name: **0xWheatyz**
5. Email: **wyatt@leeworks.dev**
6. Set a strong passphrase
Note the key ID printed (e.g. `0x1234ABCD5678EFGH`).
---
## Step 2: Add Subkeys
```bash
gpg --expert --edit-key <KEY-ID>
```
Add 3 subkeys at the `gpg>` prompt:
**Signing subkey:**
```
gpg> addkey
→ (10) ECC (sign only)
→ Curve 25519
→ 1y expiry
```
**Encryption subkey** (may already exist — check with `list`):
```
gpg> addkey
→ (12) ECC (encrypt only)
→ Curve 25519
→ 1y expiry
```
**Authentication subkey:**
```
gpg> addkey
→ (11) ECC (set your own capabilities)
→ Toggle: disable Sign, enable Authenticate
→ Curve 25519
→ 1y expiry
```
```
gpg> save
```
---
## Step 3: Back Up Master Key (CRITICAL)
> Once keys are moved to the YubiKey, they cannot be extracted. Back up now.
```bash
mkdir -p /tmp/gpg-backup
gpg --armor --export-secret-keys <KEY-ID> > /tmp/gpg-backup/master-secret.asc
gpg --armor --export-secret-subkeys <KEY-ID> > /tmp/gpg-backup/subkeys-secret.asc
gpg --armor --export <KEY-ID> > /tmp/gpg-backup/public.asc
gpg --export-ownertrust > /tmp/gpg-backup/ownertrust.txt
```
Copy `/tmp/gpg-backup/` to an encrypted USB drive or other secure offline storage. Then remove the temp copy:
```bash
rm -rf /tmp/gpg-backup
```
---
## Step 4: Move Subkeys to YubiKey
```bash
gpg --edit-key <KEY-ID>
```
Move each subkey to its corresponding card slot:
```
gpg> key 1
gpg> keytocard
→ (1) Signature key
gpg> key 1
gpg> key 2
gpg> keytocard
→ (2) Encryption key
gpg> key 2
gpg> key 3
gpg> keytocard
→ (3) Authentication key
gpg> save
```
---
## Step 5: Set Trust & Verify
```bash
gpg --edit-key <KEY-ID>
```
```
gpg> trust
→ (5) I trust ultimately
gpg> quit
```
Verify the card:
```bash
gpg --card-status # Should show all 3 subkeys
gpg --list-secret-keys # Subkeys should show "ssb>" (stub pointing to card)
```
---
## Step 6: Back Up & Remove Old SSH Keys
```bash
mkdir -p ~/.ssh/old
mv ~/.ssh/id_ed25519 ~/.ssh/old/
mv ~/.ssh/id_ed25519.pub ~/.ssh/old/
```
---
## Step 7: Get Your New SSH Public Key
```bash
gpg --export-ssh-key <KEY-ID>
```
This outputs the SSH public key derived from your GPG auth subkey. Save it:
```bash
gpg --export-ssh-key <KEY-ID> > ~/.ssh/yubikey.pub
```
Verify gpg-agent serves it:
```bash
ssh-add -L # Should show the same key
```
Deploy this key to your remote servers:
- **vps** (45.79.198.105) — add to `~/.ssh/authorized_keys` for user `wyatt`
- **home** (10.0.0.20) — add to `~/.ssh/authorized_keys` for user `l-wyatt`
- **git** (10.0.1.10) — add via your Gitea/Forgejo web UI
- **GitHub** — Settings → SSH and GPG Keys → New SSH Key
> **Tip:** Use the old key (still in `~/.ssh/old/`) to SSH in and deploy the new one:
> ```bash
> ssh -i ~/.ssh/old/id_ed25519 vps "echo '$(gpg --export-ssh-key <KEY-ID>)' >> ~/.ssh/authorized_keys"
> ```
---
## Step 8: Update home.nix with Your Signing Key
Get your key ID:
```bash
gpg --list-secret-keys --keyid-format 0xlong
```
Then edit `home.nix` and replace the `key = null;` line:
```nix
signing = {
key = "<YOUR-0xLONG-KEY-ID>"; # e.g. "0x1234ABCD5678EFGH"
signByDefault = true;
};
```
Rebuild again:
```bash
nixos-rebuild switch
```
---
## Step 9: Verify Everything
```bash
# Smartcard
gpg --card-status
# SSH via YubiKey
ssh-add -L
ssh vps echo "YubiKey SSH works!"
# Git signing
cd /tmp && git init test-sign && cd test-sign
git commit --allow-empty -m "test signing"
git log --show-signature -1
# Should show "Good signature from 0xWheatyz <wyatt@leeworks.dev>"
rm -rf /tmp/test-sign
```
---
## Step 10 (Optional): Change YubiKey PINs
The default PINs are `123456` (user) and `12345678` (admin). Change them:
```
gpg --card-edit
gpg/card> admin
gpg/card> passwd
→ (1) Change PIN
→ (3) Change Admin PIN
gpg/card> quit
```
---
## Step 11 (Optional): Upload GPG Public Key to GitHub
```bash
gpg --armor --export <KEY-ID>
```
Paste the output into **GitHub → Settings → SSH and GPG Keys → New GPG Key**. This makes your signed commits show "Verified" on GitHub.
---
## Note
The config changes to `configuration.nix` and `home.nix` are already saved. After you rebuild, reboot, and follow the steps above, you'll need to come back to update `home.nix` one more time with your actual GPG key ID (Step 8) and do a final rebuild.