Compare commits

..

10 Commits

Author SHA1 Message Date
4bb71d0b7e Remove wixos (WSL) configuration
All checks were successful
CI / check (push) Successful in 3m0s
WSL is no longer used. This removes:
- machines/wixos/ directory and configuration.nix
- nixos-wsl input from flake.nix
- nixosConfigurations.wixos output
- References to wixos in AGENTS.md and .goosehints

Implements bead: nixos-configs-2mk
2026-01-13 18:02:36 -08:00
0bc134f557 fix(mu4e): Configure msmtp to preserve email body content
All checks were successful
CI / check (push) Successful in 6m0s
The mu4e msmtp configuration was causing email bodies to be stripped,
especially for multipart messages from org-msg. This was due to missing
critical msmtp settings.

Changes:
- Add message-sendmail-f-is-evil to prevent -f flag issues
- Add --read-envelope-from to msmtp arguments
- Set both send-mail-function and message-send-mail-function

Fixes: nixos-configs-9l8
2026-01-13 17:48:36 -08:00
1b9df3926e Fix conflicting audio role config: remove pulseaudio, keep pipewire
Some checks failed
CI / check (push) Has been cancelled
Remove services.pulseaudio configuration that conflicted with
services.pipewire. PipeWire replaces PulseAudio and provides
compatibility through pulse.enable.

Also added alsa.enable and alsa.support32Bit for better ALSA support.
2026-01-13 17:48:00 -08:00
bd98793528 feat(roles): Parameterize hardcoded values in printing, nfs-mounts, and virtualisation roles
Some checks failed
CI / check (push) Has been cancelled
- printing role: Add configurable printerName, printerUri, and printerModel options
  to replace hardcoded Brother printer values
- nfs-mounts role: Add configurable server, remotePath, and mountPoint options
  to replace hardcoded NFS server IP (10.0.0.43)
- virtualisation role: Add configurable dockerUsers option as list type
  to replace hardcoded 'johno' docker group membership

All options have sensible defaults matching the original hardcoded values,
ensuring backward compatibility while allowing per-host customization.

Implements bead: nixos-configs-fkt
2026-01-13 17:20:59 -08:00
d78637cf13 feat(home-manager): Add platform compatibility guards to cross-platform roles
Some checks failed
CI / check (push) Has been cancelled
Add lib.optionals pkgs.stdenv.isLinux guards to roles that contain
Linux-only packages or services to prevent build failures on Darwin:

- communication: Guard Electron apps (element-desktop, fluffychat,
  nextcloud-talk-desktop) that don't build on Darwin due to electron
  build-from-source limitations
- kdeconnect: Guard entire config block since services.kdeconnect
  requires D-Bus and systemd (Linux-only)
- sync: Guard syncthingtray package (requires Linux system tray)
- email: Guard systemd.user.services/timers (Darwin uses launchd)
- desktop: Guard Linux-only packages, services, and KDE-specific
  configurations including gnome-keyring, systemd services, and
  XDG mime associations

Implements bead: nixos-configs-tcu
2026-01-13 17:20:01 -08:00
08d16bd2c9 feat(scripts): Add --help flags to all flake apps
Some checks failed
CI / check (push) Has been cancelled
Add consistent --help/-h argument handling to update-doomemacs.sh,
rotate-wallpaper.sh, and upgrade.sh scripts. Each script now displays
usage information and a description of what it does.

update-claude-code already had --help support.
2026-01-13 17:18:46 -08:00
a14ff9be4d fix(flake): Remove duplicate home-manager imports from wixos and zix790prors
Some checks failed
CI / check (pull_request) Successful in 5m36s
CI / check (push) Has been cancelled
The nixosModules list already includes inputs.home-manager.nixosModules.home-manager,
so these individual configuration imports were redundant.
2026-01-13 16:37:41 -08:00
90217ec85a fix(ci): Use full Gitea URL for composite action
All checks were successful
CI / check (push) Successful in 7m29s
Gitea Actions defaults to GitHub for short-form action references.
Use full URL to reference actions from the same Gitea instance.
2026-01-13 15:58:20 -08:00
f99f4069f0 feat(ci): Add Gitea Actions workflow with Nix caching
Some checks failed
CI / check (push) Failing after 1s
Uses johno/gitea-actions/nix-setup composite action for:
- Nix installation via DeterminateSystems/nix-installer-action
- Nix store caching via actions/cache@v4
- Per-repo cache isolation based on flake.lock hash
2026-01-13 15:50:54 -08:00
320a2d3738 refactor: Move import_gitea_issues to user-level skill
Moves from project-level (.claude/commands/) to user-level
(home/roles/development/skills/) so it's available across all projects
via Home Manager activation.

Bead: nixos-configs-g72
2026-01-13 15:37:59 -08:00
20 changed files with 288 additions and 253 deletions

18
.gitea/workflows/ci.yml Normal file
View File

@@ -0,0 +1,18 @@
name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: https://git.johnogle.info/johno/gitea-actions/nix-setup@main
- name: Check flake
run: nix flake check

View File

@@ -9,7 +9,7 @@ Directory Structure:
---------------------- ----------------------
• packages/ - Custom Nix packages leveraged across various configurations. • packages/ - Custom Nix packages leveraged across various configurations.
• roles/ - Role-based configurations (e.g., kodi, bluetooth) each with its own module (default.nix) for inclusion in machine setups. • roles/ - Role-based configurations (e.g., kodi, bluetooth) each with its own module (default.nix) for inclusion in machine setups.
• machines/ - Machine-specific configurations (e.g., nix-book, z790prors, boxy, wixos) including configuration.nix and hardware-configuration.nix tailored for each hardware. • machines/ - Machine-specific configurations (e.g., nix-book, zix790prors, boxy) including configuration.nix and hardware-configuration.nix tailored for each hardware.
• home/ - Home-manager configurations for personal environments and application settings (e.g., home-nix-book.nix, home-z790prors.nix). • home/ - Home-manager configurations for personal environments and application settings (e.g., home-nix-book.nix, home-z790prors.nix).
Design Principles: Design Principles:

View File

@@ -14,7 +14,7 @@ This repository uses `beads` for issue tracking and management. Run `bd quicksta
### Flake Structure ### Flake Structure
- **flake.nix**: Main entry point defining inputs (nixpkgs, home-manager, plasma-manager, etc.) and outputs for multiple NixOS configurations - **flake.nix**: Main entry point defining inputs (nixpkgs, home-manager, plasma-manager, etc.) and outputs for multiple NixOS configurations
- **Machines**: `nix-book`, `boxy`, `wixos` (WSL configuration), `zix790prors`, `live-usb`, `johno-macbookpro` (Darwin/macOS) - **Machines**: `nix-book`, `boxy`, `zix790prors`, `live-usb`, `johno-macbookpro` (Darwin/macOS)
- **Home configurations**: Standalone home-manager configuration for user `johno` - **Home configurations**: Standalone home-manager configuration for user `johno`
### Directory Structure ### Directory Structure
@@ -78,7 +78,6 @@ The repository also uses a modular home-manager role system for user-space confi
- **nix-book**: Compact laptop → excludes office/media roles due to SSD space constraints - **nix-book**: Compact laptop → excludes office/media roles due to SSD space constraints
- **boxy**: Living room media center → optimized for media consumption, excludes sync/office (shared machine) - **boxy**: Living room media center → optimized for media consumption, excludes sync/office (shared machine)
- **zix790prors**: All-purpose workstation → full desktop experience with all roles enabled - **zix790prors**: All-purpose workstation → full desktop experience with all roles enabled
- **wixos**: WSL2 development → full desktop experience, inherits from zix790prors Windows host
- **live-usb**: Temporary environment → only base + desktop roles, no persistent services - **live-usb**: Temporary environment → only base + desktop roles, no persistent services
- **johno-macbookpro**: macOS work laptop → Darwin-specific configuration with development tools - **johno-macbookpro**: macOS work laptop → Darwin-specific configuration with development tools
@@ -111,7 +110,6 @@ darwin-rebuild build --flake .#johno-macbookpro
- `nix-book`: Compact laptop with storage constraints, uses `home/home-laptop-compact.nix` - `nix-book`: Compact laptop with storage constraints, uses `home/home-laptop-compact.nix`
- `boxy`: Shared living room media center/gaming desktop with AMD GPU, uses `home/home-media-center.nix` - `boxy`: Shared living room media center/gaming desktop with AMD GPU, uses `home/home-media-center.nix`
- `zix790prors`: Powerful all-purpose workstation (gaming, 3D modeling, development), dual-boots Windows 11 with shared btrfs /games partition, uses `home/home-desktop.nix` - `zix790prors`: Powerful all-purpose workstation (gaming, 3D modeling, development), dual-boots Windows 11 with shared btrfs /games partition, uses `home/home-desktop.nix`
- `wixos`: WSL2 development environment running in Windows partition of zix790prors, uses `home/home-desktop.nix`
- `live-usb`: Bootable ISO configuration, uses `home/home-live-usb.nix` - `live-usb`: Bootable ISO configuration, uses `home/home-live-usb.nix`
- `johno-macbookpro`: macOS work laptop, uses `home/home-darwin-work.nix` - `johno-macbookpro`: macOS work laptop, uses `home/home-darwin-work.nix`

67
flake.lock generated
View File

@@ -60,22 +60,6 @@
"type": "github" "type": "github"
} }
}, },
"flake-compat": {
"flake": false,
"locked": {
"lastModified": 1765121682,
"narHash": "sha256-4VBOP18BFeiPkyhy9o4ssBNQEvfvv1kXkasAYd0+rrA=",
"owner": "edolstra",
"repo": "flake-compat",
"rev": "65f23138d8d09a92e30f1e5c87611b23ef451bf3",
"type": "github"
},
"original": {
"owner": "edolstra",
"repo": "flake-compat",
"type": "github"
}
},
"flake-utils": { "flake-utils": {
"inputs": { "inputs": {
"systems": "systems" "systems": "systems"
@@ -241,38 +225,18 @@
"type": "github" "type": "github"
} }
}, },
"nixos-wsl": {
"inputs": {
"flake-compat": "flake-compat",
"nixpkgs": "nixpkgs"
},
"locked": {
"lastModified": 1765841014,
"narHash": "sha256-55V0AJ36V5Egh4kMhWtDh117eE3GOjwq5LhwxDn9eHg=",
"owner": "nix-community",
"repo": "NixOS-WSL",
"rev": "be4af8042e7a61fa12fda58fe9a3b3babdefe17b",
"type": "github"
},
"original": {
"owner": "nix-community",
"ref": "main",
"repo": "NixOS-WSL",
"type": "github"
}
},
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1765472234, "lastModified": 1767480499,
"narHash": "sha256-9VvC20PJPsleGMewwcWYKGzDIyjckEz8uWmT0vCDYK0=", "narHash": "sha256-8IQQUorUGiSmFaPnLSo2+T+rjHtiNWc+OAzeHck7N48=",
"owner": "NixOS", "owner": "nixos",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "2fbfb1d73d239d2402a8fe03963e37aab15abe8b", "rev": "30a3c519afcf3f99e2c6df3b359aec5692054d92",
"type": "github" "type": "github"
}, },
"original": { "original": {
"owner": "NixOS", "owner": "nixos",
"ref": "nixos-unstable", "ref": "nixos-25.11",
"repo": "nixpkgs", "repo": "nixpkgs",
"type": "github" "type": "github"
} }
@@ -293,22 +257,6 @@
"type": "github" "type": "github"
} }
}, },
"nixpkgs_2": {
"locked": {
"lastModified": 1767480499,
"narHash": "sha256-8IQQUorUGiSmFaPnLSo2+T+rjHtiNWc+OAzeHck7N48=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "30a3c519afcf3f99e2c6df3b359aec5692054d92",
"type": "github"
},
"original": {
"owner": "nixos",
"ref": "nixos-25.11",
"repo": "nixpkgs",
"type": "github"
}
},
"plasma-manager": { "plasma-manager": {
"inputs": { "inputs": {
"home-manager": [ "home-manager": [
@@ -364,8 +312,7 @@
"jovian": "jovian", "jovian": "jovian",
"nix-darwin": "nix-darwin", "nix-darwin": "nix-darwin",
"nix-doom-emacs-unstraightened": "nix-doom-emacs-unstraightened", "nix-doom-emacs-unstraightened": "nix-doom-emacs-unstraightened",
"nixos-wsl": "nixos-wsl", "nixpkgs": "nixpkgs",
"nixpkgs": "nixpkgs_2",
"nixpkgs-unstable": "nixpkgs-unstable", "nixpkgs-unstable": "nixpkgs-unstable",
"plasma-manager": "plasma-manager", "plasma-manager": "plasma-manager",
"plasma-manager-unstable": "plasma-manager-unstable" "plasma-manager-unstable": "plasma-manager-unstable"

View File

@@ -4,8 +4,7 @@
inputs = { inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixos-25.11"; nixpkgs.url = "github:nixos/nixpkgs/nixos-25.11";
nixpkgs-unstable.url = "github:nixos/nixpkgs/nixos-unstable"; nixpkgs-unstable.url = "github:nixos/nixpkgs/nixos-unstable";
nixos-wsl.url = "github:nix-community/NixOS-WSL/main";
nix-darwin = { nix-darwin = {
url = "github:nix-darwin/nix-darwin/nix-darwin-25.11"; url = "github:nix-darwin/nix-darwin/nix-darwin-25.11";
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
@@ -55,7 +54,7 @@
}; };
}; };
outputs = { self, nixpkgs, nixpkgs-unstable, nixos-wsl, ... } @ inputs: let outputs = { self, nixpkgs, nixpkgs-unstable, ... } @ inputs: let
# Shared overlay function to reduce duplication across module sets # Shared overlay function to reduce duplication across module sets
# Parameters: # Parameters:
# unstableOverlays: Additional overlays to apply when importing nixpkgs-unstable # unstableOverlays: Additional overlays to apply when importing nixpkgs-unstable
@@ -84,6 +83,7 @@
}; };
}; };
nixosModules = [ nixosModules = [
./roles ./roles
inputs.home-manager.nixosModules.home-manager inputs.home-manager.nixosModules.home-manager
@@ -157,18 +157,6 @@
]; ];
}; };
nixosConfigurations.wixos = nixpkgs.lib.nixosSystem rec {
system = "x86_64-linux";
modules = nixosModules ++ [
nixos-wsl.nixosModules.default
./machines/wixos/configuration.nix
{
home-manager.users.johno = import ./home/home-desktop.nix;
home-manager.extraSpecialArgs = { inherit system; };
}
];
};
nixosConfigurations.zix790prors = nixpkgs.lib.nixosSystem rec { nixosConfigurations.zix790prors = nixpkgs.lib.nixosSystem rec {
system = "x86_64-linux"; system = "x86_64-linux";
modules = nixosModules ++ [ modules = nixosModules ++ [

View File

@@ -4,6 +4,7 @@ with lib;
let let
cfg = config.home.roles.communication; cfg = config.home.roles.communication;
isLinux = pkgs.stdenv.isLinux;
in in
{ {
options.home.roles.communication = { options.home.roles.communication = {
@@ -12,14 +13,14 @@ in
config = mkIf cfg.enable { config = mkIf cfg.enable {
home.packages = [ home.packages = [
# Communication apps # For logging back into google chat (cross-platform)
globalInputs.google-cookie-retrieval.packages.${system}.default
] ++ optionals isLinux [
# Linux-only communication apps (Electron apps don't build on Darwin)
pkgs.element-desktop pkgs.element-desktop
# Re-enabled in 25.11 after security issues were resolved # Re-enabled in 25.11 after security issues were resolved
pkgs.fluffychat pkgs.fluffychat
pkgs.nextcloud-talk-desktop pkgs.nextcloud-talk-desktop
# For logging back into google chat
globalInputs.google-cookie-retrieval.packages.${system}.default
]; ];
}; };
} }

View File

@@ -4,6 +4,7 @@ with lib;
let let
cfg = config.home.roles.desktop; cfg = config.home.roles.desktop;
isLinux = pkgs.stdenv.isLinux;
in in
{ {
options.home.roles.desktop = { options.home.roles.desktop = {
@@ -12,61 +13,63 @@ in
config = mkIf cfg.enable { config = mkIf cfg.enable {
home.packages = with pkgs; [ home.packages = with pkgs; [
# Desktop applications # Cross-platform desktop applications
bitwarden-desktop bitwarden-desktop
dunst
keepassxc keepassxc
xdg-utils # XDG utilities for opening files/URLs with default applications
] ++ optionals isLinux [
# Linux-only desktop applications
dunst
unstable.ghostty unstable.ghostty
# Desktop utilities # Linux-only desktop utilities
feh # Image viewer and wallpaper setter for X11 feh # Image viewer and wallpaper setter for X11
rofi # Application launcher for X11 rofi # Application launcher for X11
solaar # Logitech management software solaar # Logitech management software
waybar waybar
wofi # Application launcher for Wayland wofi # Application launcher for Wayland
xdg-utils # XDG utilities for opening files/URLs with default applications
# Linux-only system utilities with GUI components
# System utilities with GUI components
(snapcast.override { pulseaudioSupport = true; }) (snapcast.override { pulseaudioSupport = true; })
# KDE tiling window management # KDE tiling window management (Linux-only)
kdePackages.krohnkite # Dynamic tiling extension for KWin 6 kdePackages.krohnkite # Dynamic tiling extension for KWin 6
# KDE PIM applications for email, calendar, and contacts # KDE PIM applications for email, calendar, and contacts (Linux-only)
kdePackages.kmail kdePackages.kmail
kdePackages.kmail-account-wizard kdePackages.kmail-account-wizard
kdePackages.kmailtransport kdePackages.kmailtransport
kdePackages.korganizer kdePackages.korganizer
kdePackages.kaddressbook kdePackages.kaddressbook
kdePackages.kontact kdePackages.kontact
# KDE System components needed for proper integration # KDE System components needed for proper integration (Linux-only)
kdePackages.kded kdePackages.kded
kdePackages.systemsettings kdePackages.systemsettings
kdePackages.kmenuedit kdePackages.kmenuedit
# Desktop menu support # Desktop menu support (Linux-only)
kdePackages.plasma-desktop # Contains applications.menu kdePackages.plasma-desktop # Contains applications.menu
# KDE Online Accounts support # KDE Online Accounts support (Linux-only)
kdePackages.kaccounts-integration kdePackages.kaccounts-integration
kdePackages.kaccounts-providers kdePackages.kaccounts-providers
kdePackages.signond kdePackages.signond
# KDE Mapping # KDE Mapping (Linux-only)
kdePackages.marble # Virtual globe and world atlas kdePackages.marble # Virtual globe and world atlas
# KDE Productivity # KDE Productivity (Linux-only)
kdePackages.kate # Advanced text editor with syntax highlighting kdePackages.kate # Advanced text editor with syntax highlighting
kdePackages.okular # Universal document viewer (PDF, ePub, etc.) kdePackages.okular # Universal document viewer (PDF, ePub, etc.)
kdePackages.spectacle # Screenshot capture utility kdePackages.spectacle # Screenshot capture utility
kdePackages.filelight # Visual disk usage analyzer kdePackages.filelight # Visual disk usage analyzer
# KDE Multimedia # KDE Multimedia (Linux-only)
kdePackages.gwenview # Image viewer and basic editor kdePackages.gwenview # Image viewer and basic editor
kdePackages.elisa # Music player kdePackages.elisa # Music player
# KDE System Utilities # KDE System Utilities (Linux-only)
kdePackages.ark # Archive manager (zip, tar, 7z, etc.) kdePackages.ark # Archive manager (zip, tar, 7z, etc.)
kdePackages.yakuake # Drop-down terminal emulator kdePackages.yakuake # Drop-down terminal emulator
]; ];
@@ -77,61 +80,66 @@ in
programs.spotify-player.enable = true; programs.spotify-player.enable = true;
services.gnome-keyring = { # Linux-only: GNOME keyring service
services.gnome-keyring = mkIf isLinux {
enable = true; enable = true;
}; };
# rbw vault unlock on login and resume from suspend # Linux-only: systemd user services for rbw vault unlock
systemd.user.services.rbw-unlock-on-login = { systemd.user.services = mkIf isLinux {
Unit = { # rbw vault unlock on login
Description = "Unlock rbw vault at login"; rbw-unlock-on-login = {
After = [ "graphical-session.target" ]; Unit = {
Description = "Unlock rbw vault at login";
After = [ "graphical-session.target" ];
};
Service = {
Type = "oneshot";
ExecStart = "${pkgs.rbw}/bin/rbw unlock";
Environment = "RBW_AGENT=${pkgs.rbw}/bin/rbw-agent";
# KillMode = "process" prevents systemd from killing the rbw-agent daemon
# when this oneshot service completes. The agent is spawned by rbw unlock
# and needs to persist after the service exits.
KillMode = "process";
};
Install = {
WantedBy = [ "graphical-session.target" ];
};
}; };
Service = {
Type = "oneshot"; # rbw vault unlock on resume from suspend
ExecStart = "${pkgs.rbw}/bin/rbw unlock"; rbw-unlock-on-resume = {
Environment = "RBW_AGENT=${pkgs.rbw}/bin/rbw-agent"; Unit = {
# KillMode = "process" prevents systemd from killing the rbw-agent daemon Description = "Unlock rbw vault after resume from suspend";
# when this oneshot service completes. The agent is spawned by rbw unlock After = [ "suspend.target" ];
# and needs to persist after the service exits. };
KillMode = "process"; Service = {
}; Type = "oneshot";
Install = { ExecStart = "${pkgs.rbw}/bin/rbw unlock";
WantedBy = [ "graphical-session.target" ]; Environment = "RBW_AGENT=${pkgs.rbw}/bin/rbw-agent";
# KillMode = "process" prevents systemd from killing the rbw-agent daemon
# when this oneshot service completes. The agent is spawned by rbw unlock
# and needs to persist after the service exits.
KillMode = "process";
};
Install = {
WantedBy = [ "suspend.target" ];
};
}; };
}; };
systemd.user.services.rbw-unlock-on-resume = { # Linux-only: KDE environment variables for proper integration
Unit = { home.sessionVariables = mkIf isLinux {
Description = "Unlock rbw vault after resume from suspend";
After = [ "suspend.target" ];
};
Service = {
Type = "oneshot";
ExecStart = "${pkgs.rbw}/bin/rbw unlock";
Environment = "RBW_AGENT=${pkgs.rbw}/bin/rbw-agent";
# KillMode = "process" prevents systemd from killing the rbw-agent daemon
# when this oneshot service completes. The agent is spawned by rbw unlock
# and needs to persist after the service exits.
KillMode = "process";
};
Install = {
WantedBy = [ "suspend.target" ];
};
};
# KDE environment variables for proper integration
home.sessionVariables = {
QT_QPA_PLATFORMTHEME = "kde"; QT_QPA_PLATFORMTHEME = "kde";
KDE_SESSION_VERSION = "6"; KDE_SESSION_VERSION = "6";
}; };
xdg = { xdg = {
enable = true; enable = true;
# Ensure desktop files are made available for discovery # Ensure desktop files are made available for discovery
desktopEntries = {}; # This creates the desktop files directory structure desktopEntries = {}; # This creates the desktop files directory structure
mimeApps = { mimeApps = {
enable = true; enable = true;
associations.added = { associations.added = {
@@ -141,13 +149,14 @@ in
"x-scheme-handler/https" = "firefox.desktop"; "x-scheme-handler/https" = "firefox.desktop";
}; };
defaultApplications = { defaultApplications = {
# Web browsers # Web browsers (cross-platform)
"text/html" = "firefox.desktop"; "text/html" = "firefox.desktop";
"x-scheme-handler/http" = "firefox.desktop"; "x-scheme-handler/http" = "firefox.desktop";
"x-scheme-handler/https" = "firefox.desktop"; "x-scheme-handler/https" = "firefox.desktop";
"x-scheme-handler/about" = "firefox.desktop"; "x-scheme-handler/about" = "firefox.desktop";
"x-scheme-handler/unknown" = "firefox.desktop"; "x-scheme-handler/unknown" = "firefox.desktop";
} // optionalAttrs isLinux {
# Linux-only: KDE application associations
# Documents # Documents
"application/pdf" = "okular.desktop"; "application/pdf" = "okular.desktop";
"text/plain" = "kate.desktop"; "text/plain" = "kate.desktop";
@@ -155,7 +164,7 @@ in
"text/x-c" = "kate.desktop"; "text/x-c" = "kate.desktop";
"text/x-python" = "kate.desktop"; "text/x-python" = "kate.desktop";
"application/x-shellscript" = "kate.desktop"; "application/x-shellscript" = "kate.desktop";
# Images # Images
"image/png" = "gwenview.desktop"; "image/png" = "gwenview.desktop";
"image/jpeg" = "gwenview.desktop"; "image/jpeg" = "gwenview.desktop";
@@ -164,25 +173,25 @@ in
"image/bmp" = "gwenview.desktop"; "image/bmp" = "gwenview.desktop";
"image/tiff" = "gwenview.desktop"; "image/tiff" = "gwenview.desktop";
"image/webp" = "gwenview.desktop"; "image/webp" = "gwenview.desktop";
# Archives # Archives
"application/zip" = "ark.desktop"; "application/zip" = "ark.desktop";
"application/x-tar" = "ark.desktop"; "application/x-tar" = "ark.desktop";
"application/x-compressed-tar" = "ark.desktop"; "application/x-compressed-tar" = "ark.desktop";
"application/x-7z-compressed" = "ark.desktop"; "application/x-7z-compressed" = "ark.desktop";
"application/x-rar" = "ark.desktop"; "application/x-rar" = "ark.desktop";
# Audio # Audio
"audio/mpeg" = "elisa.desktop"; "audio/mpeg" = "elisa.desktop";
"audio/mp4" = "elisa.desktop"; "audio/mp4" = "elisa.desktop";
"audio/flac" = "elisa.desktop"; "audio/flac" = "elisa.desktop";
"audio/ogg" = "elisa.desktop"; "audio/ogg" = "elisa.desktop";
"audio/wav" = "elisa.desktop"; "audio/wav" = "elisa.desktop";
# Email # Email
"message/rfc822" = "kmail.desktop"; "message/rfc822" = "kmail.desktop";
"x-scheme-handler/mailto" = "kmail.desktop"; "x-scheme-handler/mailto" = "kmail.desktop";
# Calendar # Calendar
"text/calendar" = "korganizer.desktop"; "text/calendar" = "korganizer.desktop";
"application/x-vnd.akonadi.calendar.event" = "korganizer.desktop"; "application/x-vnd.akonadi.calendar.event" = "korganizer.desktop";
@@ -190,9 +199,11 @@ in
}; };
}; };
# Fix for KDE applications.menu file issue on Plasma 6 # Linux-only: Fix for KDE applications.menu file issue on Plasma 6
# KDE still looks for applications.menu but Plasma 6 renamed it to plasma-applications.menu # KDE still looks for applications.menu but Plasma 6 renamed it to plasma-applications.menu
xdg.configFile."menus/applications.menu".source = "${pkgs.kdePackages.plasma-workspace}/etc/xdg/menus/plasma-applications.menu"; xdg.configFile."menus/applications.menu" = mkIf isLinux {
source = "${pkgs.kdePackages.plasma-workspace}/etc/xdg/menus/plasma-applications.menu";
};
# Note: modules must be imported at top-level home config # Note: modules must be imported at top-level home config
}; };

View File

@@ -225,11 +225,16 @@
mu4e-headers-time-format "%H:%M") mu4e-headers-time-format "%H:%M")
;; Sending mail via msmtp ;; Sending mail via msmtp
(setq message-send-mail-function 'message-send-mail-with-sendmail ;; NOTE: message-sendmail-f-is-evil and --read-envelope-from are required
sendmail-program (executable-find "msmtp") ;; to prevent msmtp from stripping the email body when processing headers.
message-sendmail-envelope-from 'header ;; Without these, multipart messages (especially from org-msg) may arrive
mail-envelope-from 'header ;; with empty bodies.
mail-specify-envelope-from t)) (setq sendmail-program (executable-find "msmtp")
send-mail-function #'message-send-mail-with-sendmail
message-send-mail-function #'message-send-mail-with-sendmail
message-sendmail-f-is-evil t
message-sendmail-extra-arguments '("--read-envelope-from")
message-sendmail-envelope-from 'header))
;; Whenever you reconfigure a package, make sure to wrap your config in an ;; Whenever you reconfigure a package, make sure to wrap your config in an
;; `after!' block, otherwise Doom's defaults may override your settings. E.g. ;; `after!' block, otherwise Doom's defaults may override your settings. E.g.

View File

@@ -4,6 +4,7 @@ with lib;
let let
cfg = config.home.roles.email; cfg = config.home.roles.email;
isLinux = pkgs.stdenv.isLinux;
in in
{ {
options.home.roles.email = { options.home.roles.email = {
@@ -89,34 +90,38 @@ in
account default : proton account default : proton
''; '';
# Systemd service for mail sync # Linux-only: Systemd service for mail sync (Darwin uses launchd instead)
systemd.user.services.mbsync = { systemd.user.services = mkIf isLinux {
Unit = { mbsync = {
Description = "Mailbox synchronization service"; Unit = {
After = [ "network-online.target" ]; Description = "Mailbox synchronization service";
Wants = [ "network-online.target" ]; After = [ "network-online.target" ];
}; Wants = [ "network-online.target" ];
Service = { };
Type = "oneshot"; Service = {
ExecStart = "${pkgs.bash}/bin/bash -c 'mkdir -p ~/Mail && ${pkgs.isync}/bin/mbsync -a && (${pkgs.mu}/bin/mu info >/dev/null 2>&1 || ${pkgs.mu}/bin/mu init --maildir ~/Mail --personal-address=john@ogle.fyi) && ${pkgs.mu}/bin/mu index'"; Type = "oneshot";
Environment = "PATH=${pkgs.rbw}/bin:${pkgs.coreutils}/bin"; ExecStart = "${pkgs.bash}/bin/bash -c 'mkdir -p ~/Mail && ${pkgs.isync}/bin/mbsync -a && (${pkgs.mu}/bin/mu info >/dev/null 2>&1 || ${pkgs.mu}/bin/mu init --maildir ~/Mail --personal-address=john@ogle.fyi) && ${pkgs.mu}/bin/mu index'";
StandardOutput = "journal"; Environment = "PATH=${pkgs.rbw}/bin:${pkgs.coreutils}/bin";
StandardError = "journal"; StandardOutput = "journal";
StandardError = "journal";
};
}; };
}; };
# Systemd timer for automatic sync # Linux-only: Systemd timer for automatic sync
systemd.user.timers.mbsync = { systemd.user.timers = mkIf isLinux {
Unit = { mbsync = {
Description = "Mailbox synchronization timer"; Unit = {
}; Description = "Mailbox synchronization timer";
Timer = { };
OnBootSec = "2min"; Timer = {
OnUnitActiveSec = "5min"; OnBootSec = "2min";
Unit = "mbsync.service"; OnUnitActiveSec = "5min";
}; Unit = "mbsync.service";
Install = { };
WantedBy = [ "timers.target" ]; Install = {
WantedBy = [ "timers.target" ];
};
}; };
}; };
}; };

View File

@@ -4,13 +4,15 @@ with lib;
let let
cfg = config.home.roles.kdeconnect; cfg = config.home.roles.kdeconnect;
isLinux = pkgs.stdenv.isLinux;
in in
{ {
options.home.roles.kdeconnect = { options.home.roles.kdeconnect = {
enable = mkEnableOption "Enable KDE Connect for device integration"; enable = mkEnableOption "Enable KDE Connect for device integration";
}; };
config = mkIf cfg.enable { # KDE Connect services are Linux-only (requires D-Bus and systemd)
config = mkIf (cfg.enable && isLinux) {
services.kdeconnect = { services.kdeconnect = {
enable = true; enable = true;
indicator = true; indicator = true;

View File

@@ -4,6 +4,7 @@ with lib;
let let
cfg = config.home.roles.sync; cfg = config.home.roles.sync;
isLinux = pkgs.stdenv.isLinux;
in in
{ {
options.home.roles.sync = { options.home.roles.sync = {
@@ -11,9 +12,10 @@ in
}; };
config = mkIf cfg.enable { config = mkIf cfg.enable {
home.packages = with pkgs; [ # Linux-only: syncthingtray requires system tray support
home.packages = optionals isLinux (with pkgs; [
syncthingtray syncthingtray
]; ]);
services.syncthing = { services.syncthing = {
enable = true; enable = true;

View File

@@ -1,56 +0,0 @@
# Edit this configuration file to define what should be installed on
# your system. Help is available in the configuration.nix(5) man page, on
# https://search.nixos.org/options and in the NixOS manual (`nixos-help`).
# NixOS-WSL specific options are documented on the NixOS-WSL repository:
# https://github.com/nix-community/NixOS-WSL
{ config, lib, pkgs, ... }:
{
imports = [
];
roles = {
audio.enable = true;
desktop = {
enable = true;
wayland = true;
};
nvidia = {
enable = true;
package = "latest";
graphics.extraPackages = with pkgs; [
mesa
libvdpau-va-gl
libva-vdpau-driver
];
};
users.enable = true;
};
networking.hostName = "wixos";
wsl.enable = true;
wsl.defaultUser = "johno";
wsl.startMenuLaunchers = true;
wsl.useWindowsDriver = true;
wsl.wslConf.network.hostname = "wixos";
wsl.wslConf.user.default = "johno";
# WSL-specific environment variables for graphics
environment.sessionVariables = {
LD_LIBRARY_PATH = [
"/usr/lib/wsl/lib"
"/run/opengl-driver/lib"
];
};
# This value determines the NixOS release from which the default
# settings for stateful data, like file locations and database versions
# on your system were taken. It's perfectly fine and recommended to leave
# this value at the release version of the first install of this system.
# Before changing this value read the documentation for this option
# (e.g. man configuration.nix or on https://nixos.org/nixos/options.html).
system.stateVersion = "24.05"; # Did you read the comment?
}

View File

@@ -21,6 +21,8 @@ in
services.pipewire = { services.pipewire = {
enable = true; enable = true;
alsa.enable = true;
alsa.support32Bit = true;
pulse.enable = true; pulse.enable = true;
}; };

View File

@@ -8,6 +8,21 @@ in
{ {
options.roles.nfs-mounts = { options.roles.nfs-mounts = {
enable = mkEnableOption "Enable default NFS mounts"; enable = mkEnableOption "Enable default NFS mounts";
server = mkOption {
type = types.str;
default = "10.0.0.43";
description = "IP address or hostname of the NFS server";
};
remotePath = mkOption {
type = types.str;
default = "/media";
description = "Remote path to mount from the NFS server";
};
mountPoint = mkOption {
type = types.str;
default = "/media";
description = "Local mount point for the NFS share";
};
# TODO: implement requireMount # TODO: implement requireMount
requireMount = mkOption { requireMount = mkOption {
type = types.bool; type = types.bool;
@@ -18,8 +33,8 @@ in
config = mkIf cfg.enable config = mkIf cfg.enable
{ {
fileSystems."/media" = { fileSystems.${cfg.mountPoint} = {
device = "10.0.0.43:/media"; device = "${cfg.server}:${cfg.remotePath}";
fsType = "nfs"; fsType = "nfs";
options = [ options = [
"defaults" "defaults"

View File

@@ -8,6 +8,21 @@ in
{ {
options.roles.printing = { options.roles.printing = {
enable = mkEnableOption "Enable default printing setup"; enable = mkEnableOption "Enable default printing setup";
printerName = mkOption {
type = types.str;
default = "MFC-L8900CDW_series";
description = "Name for the default printer";
};
printerUri = mkOption {
type = types.str;
default = "ipp://brother.oglehome/ipp/print";
description = "Device URI for the default printer (e.g., ipp://hostname/ipp/print)";
};
printerModel = mkOption {
type = types.str;
default = "everywhere";
description = "PPD model for the printer (use 'everywhere' for driverless IPP)";
};
}; };
config = mkIf cfg.enable config = mkIf cfg.enable
@@ -21,11 +36,11 @@ in
}; };
hardware.printers.ensurePrinters = [{ hardware.printers.ensurePrinters = [{
name = "MFC-L8900CDW_series"; name = cfg.printerName;
deviceUri = "ipp://brother.oglehome/ipp/print"; deviceUri = cfg.printerUri;
model = "everywhere"; model = cfg.printerModel;
}]; }];
hardware.printers.ensureDefaultPrinter = "MFC-L8900CDW_series"; hardware.printers.ensureDefaultPrinter = cfg.printerName;
# Fix ensure-printers service to wait for network availability # Fix ensure-printers service to wait for network availability
systemd.services.ensure-printers = { systemd.services.ensure-printers = {

View File

@@ -8,6 +8,11 @@ in
{ {
options.roles.virtualisation = { options.roles.virtualisation = {
enable = mkEnableOption "Enable virtualisation"; enable = mkEnableOption "Enable virtualisation";
dockerUsers = mkOption {
type = types.listOf types.str;
default = [ "johno" ];
description = "List of users to add to the docker group";
};
}; };
config = mkIf cfg.enable config = mkIf cfg.enable
@@ -15,6 +20,6 @@ in
virtualisation.libvirtd.enable = true; virtualisation.libvirtd.enable = true;
programs.virt-manager.enable = true; programs.virt-manager.enable = true;
virtualisation.docker.enable = true; virtualisation.docker.enable = true;
users.extraGroups.docker.members = [ "johno" ]; users.extraGroups.docker.members = cfg.dockerUsers;
}; };
} }

View File

@@ -1,6 +1,30 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -euo pipefail set -euo pipefail
# Parse arguments
while [[ $# -gt 0 ]]; do
case $1 in
--help|-h)
echo "Usage: $0 [OPTIONS]"
echo ""
echo "Rotate to the next wallpaper in the configured list."
echo ""
echo "This script increments the currentIndex in home/wallpapers/default.nix,"
echo "cycling through available wallpapers. Rebuild your system to apply"
echo "the new wallpaper."
echo ""
echo "Options:"
echo " --help, -h Show this help message"
exit 0
;;
*)
echo "Unknown option: $1"
echo "Use --help for usage information"
exit 1
;;
esac
done
# Colors for output # Colors for output
RED='\033[0;31m' RED='\033[0;31m'
GREEN='\033[0;32m' GREEN='\033[0;32m'

View File

@@ -1,6 +1,30 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -euo pipefail set -euo pipefail
# Parse arguments
while [[ $# -gt 0 ]]; do
case $1 in
--help|-h)
echo "Usage: $0 [OPTIONS]"
echo ""
echo "Update Doom Emacs to the latest commit from the doomemacs repository."
echo ""
echo "This script fetches the latest commit SHA from the default branch,"
echo "updates the rev and sha256 in home/roles/emacs/default.nix, and"
echo "prepares the configuration for a system rebuild."
echo ""
echo "Options:"
echo " --help, -h Show this help message"
exit 0
;;
*)
echo "Unknown option: $1"
echo "Use --help for usage information"
exit 1
;;
esac
done
# Colors for output # Colors for output
RED='\033[0;31m' RED='\033[0;31m'
GREEN='\033[0;32m' GREEN='\033[0;32m'

View File

@@ -1,6 +1,35 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -euo pipefail set -euo pipefail
# Parse arguments
while [[ $# -gt 0 ]]; do
case $1 in
--help|-h)
echo "Usage: $0 [OPTIONS]"
echo ""
echo "Perform a major upgrade of the NixOS configuration."
echo ""
echo "This script runs the following steps:"
echo " 1. Update all flake inputs (nix flake update)"
echo " 2. Update Doom Emacs to the latest commit"
echo " 3. Update Claude Code to the latest version"
echo " 4. Rotate to the next wallpaper"
echo ""
echo "After completion, review changes with 'git diff' and rebuild"
echo "your system with 'sudo nixos-rebuild switch --flake .'"
echo ""
echo "Options:"
echo " --help, -h Show this help message"
exit 0
;;
*)
echo "Unknown option: $1"
echo "Use --help for usage information"
exit 1
;;
esac
done
# Colors for output # Colors for output
RED='\033[0;31m' RED='\033[0;31m'
GREEN='\033[0;32m' GREEN='\033[0;32m'