Compare commits

..

1 Commits

Author SHA1 Message Date
c0fd0d4a57 feat(home-manager): Add platform compatibility guards to cross-platform roles
All checks were successful
CI / check (pull_request) Successful in 5m38s
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 16:38:09 -08:00
15 changed files with 156 additions and 193 deletions

View File

@@ -16,5 +16,3 @@ jobs:
- name: Check flake - name: Check flake
run: nix flake check run: nix flake check
env:
NIX_CONFIG: "access-tokens = git.johnogle.info=${{ secrets.GITEA_ACCESS_TOKEN }}"

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, zix790prors, boxy) including configuration.nix and hardware-configuration.nix tailored for each hardware. • machines/ - Machine-specific configurations (e.g., nix-book, z790prors, boxy, wixos) 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`, `zix790prors`, `live-usb`, `johno-macbookpro` (Darwin/macOS) - **Machines**: `nix-book`, `boxy`, `wixos` (WSL configuration), `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,6 +78,7 @@ 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
@@ -110,6 +111,7 @@ 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`

71
flake.lock generated
View File

@@ -60,6 +60,22 @@
"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"
@@ -225,18 +241,38 @@
"type": "github" "type": "github"
} }
}, },
"nixpkgs": { "nixos-wsl": {
"inputs": {
"flake-compat": "flake-compat",
"nixpkgs": "nixpkgs"
},
"locked": { "locked": {
"lastModified": 1767480499, "lastModified": 1765841014,
"narHash": "sha256-8IQQUorUGiSmFaPnLSo2+T+rjHtiNWc+OAzeHck7N48=", "narHash": "sha256-55V0AJ36V5Egh4kMhWtDh117eE3GOjwq5LhwxDn9eHg=",
"owner": "nixos", "owner": "nix-community",
"repo": "nixpkgs", "repo": "NixOS-WSL",
"rev": "30a3c519afcf3f99e2c6df3b359aec5692054d92", "rev": "be4af8042e7a61fa12fda58fe9a3b3babdefe17b",
"type": "github" "type": "github"
}, },
"original": { "original": {
"owner": "nixos", "owner": "nix-community",
"ref": "nixos-25.11", "ref": "main",
"repo": "NixOS-WSL",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1765472234,
"narHash": "sha256-9VvC20PJPsleGMewwcWYKGzDIyjckEz8uWmT0vCDYK0=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "2fbfb1d73d239d2402a8fe03963e37aab15abe8b",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs", "repo": "nixpkgs",
"type": "github" "type": "github"
} }
@@ -257,6 +293,22 @@
"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": [
@@ -312,7 +364,8 @@
"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",
"nixpkgs": "nixpkgs", "nixos-wsl": "nixos-wsl",
"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,6 +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";
@@ -54,7 +55,7 @@
}; };
}; };
outputs = { self, nixpkgs, nixpkgs-unstable, ... } @ inputs: let outputs = { self, nixpkgs, nixpkgs-unstable, nixos-wsl, ... } @ 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
@@ -83,7 +84,6 @@
}; };
}; };
nixosModules = [ nixosModules = [
./roles ./roles
inputs.home-manager.nixosModules.home-manager inputs.home-manager.nixosModules.home-manager
@@ -157,10 +157,24 @@
]; ];
}; };
nixosConfigurations.wixos = nixpkgs.lib.nixosSystem rec {
system = "x86_64-linux";
modules = nixosModules ++ [
nixos-wsl.nixosModules.default
./machines/wixos/configuration.nix
inputs.home-manager.nixosModules.home-manager
{
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 ++ [
./machines/zix790prors/configuration.nix ./machines/zix790prors/configuration.nix
inputs.home-manager.nixosModules.home-manager
{ {
home-manager.users.johno = import ./home/home-desktop.nix; home-manager.users.johno = import ./home/home-desktop.nix;
home-manager.extraSpecialArgs = { inherit system; }; home-manager.extraSpecialArgs = { inherit system; };

View File

@@ -4,13 +4,12 @@ description: Reconcile beads with merged PRs and close completed beads
# Reconcile Beads Workflow # Reconcile Beads Workflow
This skill reconciles beads that are in `in_review` status with their corresponding PRs. If a PR has been merged, the bead is closed and any linked Gitea issue is also closed. This skill reconciles beads that are in `in_review` status with their corresponding PRs. If a PR has been merged, the bead is closed.
## Prerequisites ## Prerequisites
- Custom status `in_review` must be configured: `bd config set status.custom "in_review"` - Custom status `in_review` must be configured: `bd config set status.custom "in_review"`
- Beads in `in_review` status should have a PR URL in their notes - Beads in `in_review` status should have a PR URL in their notes
- `tea` CLI must be configured for closing Gitea issues
## Workflow ## Workflow
@@ -53,34 +52,6 @@ If the PR is merged:
bd close [BEAD_ID] --reason="PR merged: [PR_URL]" bd close [BEAD_ID] --reason="PR merged: [PR_URL]"
``` ```
### Step 3.1: Close corresponding Gitea issue (if any)
After closing a bead, check if it has a linked Gitea issue:
1. **Check for Gitea issue URL in bead notes**:
Look for the pattern `Gitea issue: <URL>` in the notes. Extract the URL.
2. **Extract issue number from URL**:
```bash
# Example: https://git.johnogle.info/johno/nixos-configs/issues/16 -> 16
echo "$GITEA_URL" | grep -oP '/issues/\K\d+'
```
3. **Close the Gitea issue**:
```bash
tea issues close [ISSUE_NUMBER]
```
4. **Handle errors gracefully**:
- If issue is already closed: Log warning, continue
- If issue not found: Log warning, continue
- If `tea` fails: Log error, continue with other beads
Example warning output:
```
Warning: Could not close Gitea issue #16: issue already closed
```
### Step 4: Report summary ### Step 4: Report summary
Present results: Present results:
@@ -89,17 +60,10 @@ Present results:
## Beads Reconciliation Summary ## Beads Reconciliation Summary
### Closed (PR Merged) ### Closed (PR Merged)
| Bead | PR | Gitea Issue | Title | | Bead | PR | Title |
|------|-----|-------------|-------| |------|-----|-------|
| beads-abc | #123 | #16 closed | Feature X | | beads-abc | #123 | Feature X |
| beads-xyz | #456 | (none) | Bug fix Y | | beads-xyz | #456 | Bug fix Y |
### Gitea Issues Closed
| Issue | Bead | Status |
|-------|------|--------|
| #16 | beads-abc | Closed successfully |
| #17 | beads-def | Already closed (skipped) |
| #99 | beads-ghi | Error: issue not found |
### Still in Review ### Still in Review
| Bead | PR | Status | Title | | Bead | PR | Status | Title |
@@ -116,14 +80,9 @@ Present results:
- **Missing PR URL**: Skip the bead and report it - **Missing PR URL**: Skip the bead and report it
- **PR not found**: Report the error but continue with other beads - **PR not found**: Report the error but continue with other beads
- **API errors**: Report and continue - **API errors**: Report and continue
- **Gitea issue already closed**: Log warning, continue (not an error)
- **Gitea issue not found**: Log warning, continue (issue may have been deleted)
- **No Gitea issue linked**: Normal case, no action needed
- **tea command fails**: Log error with output, continue with other beads
## Notes ## Notes
- This skill complements `/parallel_beads` which sets beads to `in_review` status - This skill complements `/parallel_beads` which sets beads to `in_review` status
- Run this skill periodically or after merging PRs to keep beads in sync - Run this skill periodically or after merging PRs to keep beads in sync
- Beads with closed (but not merged) PRs are not automatically closed - they may need rework - Beads with closed (but not merged) PRs are not automatically closed - they may need rework
- Gitea issues are only closed for beads that have a `Gitea issue: <URL>` in their notes

View File

@@ -225,16 +225,11 @@
mu4e-headers-time-format "%H:%M") mu4e-headers-time-format "%H:%M")
;; Sending mail via msmtp ;; Sending mail via msmtp
;; NOTE: message-sendmail-f-is-evil and --read-envelope-from are required (setq message-send-mail-function 'message-send-mail-with-sendmail
;; to prevent msmtp from stripping the email body when processing headers. sendmail-program (executable-find "msmtp")
;; Without these, multipart messages (especially from org-msg) may arrive message-sendmail-envelope-from 'header
;; with empty bodies. mail-envelope-from 'header
(setq sendmail-program (executable-find "msmtp") mail-specify-envelope-from t))
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

@@ -0,0 +1,56 @@
# 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,8 +21,6 @@ in
services.pipewire = { services.pipewire = {
enable = true; enable = true;
alsa.enable = true;
alsa.support32Bit = true;
pulse.enable = true; pulse.enable = true;
}; };

View File

@@ -8,21 +8,6 @@ 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;
@@ -33,8 +18,8 @@ in
config = mkIf cfg.enable config = mkIf cfg.enable
{ {
fileSystems.${cfg.mountPoint} = { fileSystems."/media" = {
device = "${cfg.server}:${cfg.remotePath}"; device = "10.0.0.43:/media";
fsType = "nfs"; fsType = "nfs";
options = [ options = [
"defaults" "defaults"

View File

@@ -8,21 +8,6 @@ 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
@@ -36,11 +21,11 @@ in
}; };
hardware.printers.ensurePrinters = [{ hardware.printers.ensurePrinters = [{
name = cfg.printerName; name = "MFC-L8900CDW_series";
deviceUri = cfg.printerUri; deviceUri = "ipp://brother.oglehome/ipp/print";
model = cfg.printerModel; model = "everywhere";
}]; }];
hardware.printers.ensureDefaultPrinter = cfg.printerName; hardware.printers.ensureDefaultPrinter = "MFC-L8900CDW_series";
# 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,11 +8,6 @@ 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
@@ -20,6 +15,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 = cfg.dockerUsers; users.extraGroups.docker.members = [ "johno" ];
}; };
} }

View File

@@ -1,30 +1,6 @@
#!/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,30 +1,6 @@
#!/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,35 +1,6 @@
#!/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'