# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Repository Overview

This is a NixOS configuration repository using flakes, managing multiple machines and home-manager configurations. The repository follows a modular architecture with reusable "roles" that can be composed for different machines.

## Issue Tracking

This repository uses `beads` for issue tracking and management. Run `bd quickstart` to get an overview of the system at the start of every session.

## Architecture

### Flake Structure
- **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)
- **Home configurations**: Standalone home-manager configuration for user `johno`

### Directory Structure
- `machines/`: Machine-specific configurations with hardware-configuration.nix
- `roles/`: Modular system configurations (audio, bluetooth, desktop, users, etc.)
- `home/`: Home Manager configurations and user-specific modules
- `home/modules/`: User environment modules (emacs, i3+sway, plasma-manager, tmux)
- `packages/`: Custom package definitions

### Role-Based Configuration System
The repository uses a custom "roles" system where each role is a NixOS module with enable options:
- `roles.desktop`: Desktop environment with sub-options for X11, Wayland, KDE, gaming, SDDM
- `roles.audio`: Audio configuration
- `roles.bluetooth`: Bluetooth support
- `roles.users`: User account management
- `roles.virtualisation`: Virtualization setup
- `roles.kodi`: Kodi media center
- `roles.nvidia`: NVIDIA GPU configuration
- `roles.printing`: Printing support (CUPS)
- `roles.spotifyd`: Spotify daemon
- `roles.btrfs`: Btrfs filesystem configuration
- `roles.nfs-mounts`: NFS mount configuration
- `roles.darwin`: macOS-specific configurations

Example role usage in machine configuration:
```nix
roles = {
  audio.enable = true;
  desktop = {
    enable = true;
    gaming = true;
    kde = true;
    wayland = true;
  };
  users.enable = true;
};
```

### Home-Manager Role System
The repository also uses a modular home-manager role system for user-space configuration:

**Available Home Roles:**
- `home.roles.base`: Core CLI tools, git, ssh, bash, rbw (enabled everywhere)
- `home.roles.desktop`: GUI applications, Firefox, KDE services
- `home.roles.office`: LibreOffice, OpenSCAD (heavy packages)
- `home.roles.media`: VLC, Jellyfin, Moonlight (media consumption)
- `home.roles.development`: Custom packages, kubectl, development tools
- `home.roles.communication`: Element, Nextcloud Talk, Google cookie tools
- `home.roles.sync`: Syncthing service and tray (for file synchronization)
- `home.roles.kdeconnect`: KDE Connect for device integration
- `home.roles.gaming`: Gaming applications (future expansion)

**Role-Based Home Configurations:**
- `home-desktop.nix`: Full-featured desktop for development workstations
- `home-media-center.nix`: Living room media consumption and gaming setup (boxy)
- `home-laptop-compact.nix`: Essential tools only, excludes office/media for storage constraints (nix-book)
- `home-live-usb.nix`: Minimal setup for live environments, no persistent services
- `home-darwin-work.nix`: macOS work laptop configuration

**Machine-Specific Role Usage:**
- **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)
- **zix790prors**: All-purpose workstation → full desktop experience with all roles enabled
- **live-usb**: Temporary environment → only base + desktop roles, no persistent services
- **johno-macbookpro**: macOS work laptop → Darwin-specific configuration with development tools

## Common Commands

### Building and Switching Configurations

**NixOS (Linux):**
```bash
# Build and switch to a specific machine configuration
sudo nixos-rebuild switch --flake .#<hostname>

# Build without switching
nixos-rebuild build --flake .#<hostname>

# Build home-manager configuration only
home-manager switch --flake .#johno
```

**Darwin (macOS):**
```bash
# Build and switch to Darwin configuration
darwin-rebuild switch --flake .#johno-macbookpro

# Build without switching
darwin-rebuild build --flake .#johno-macbookpro
```

### Available Machine Configurations
- `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`
- `zix790prors`: Powerful all-purpose workstation (gaming, 3D modeling, development), dual-boots Windows 11 with shared btrfs /games partition, uses `home/home-desktop.nix`
- `live-usb`: Bootable ISO configuration, uses `home/home-live-usb.nix`
- `johno-macbookpro`: macOS work laptop, uses `home/home-darwin-work.nix`

### Flake Operations
```bash
# Update flake inputs
nix flake update

# Check flake
nix flake check

# Show flake info
nix flake show
```

### Bootstrap New Machine
Use the provided bootstrap script:
```bash
sudo ./bootstrap.sh <hostname>
```
This script pulls from the remote git repository and applies the configuration.

### Build Live USB ISO
Use the provided script to build a bootable ISO:
```bash
./build-liveusb.sh
```
Creates an ISO suitable for Ventoy and other USB boot tools in `./result/iso/`.

## Development Workflow

### Adding New Machines

**NixOS:**
1. Create new directory in `machines/<hostname>/`
2. Add `configuration.nix` with role assignments
3. Include hardware-configuration.nix (generated by nixos-generate-config)
4. Add nixosConfiguration to flake.nix outputs

**Darwin (macOS):**
1. Create new directory in `machines/<hostname>/`
2. Add `configuration.nix` with Darwin role assignments
3. Add darwinConfiguration to flake.nix outputs

### Adding New Roles
1. Create directory in `roles/<role-name>/`
2. Create `default.nix` with module definition using mkEnableOption
3. Add role import to `roles/default.nix`
4. Configure role options in machine configurations

### Home Manager Modules
- Located in `home/modules/`
- Each module has its own `default.nix`
- Imported in main home configuration files

## Key Configuration Details

- **Experimental features**: nix-command and flakes are enabled
- **User**: Primary user is `johno` with trusted-user privileges
- **Locale**: en_US.UTF-8, America/Los_Angeles timezone
- **SSH**: OpenSSH enabled on all configurations
- **Garbage collection**: Automatic, deletes older than 10 days
- **Unfree packages**: Allowed globally

## Issue Tracking (Gitea)

**Tea CLI for Gitea:**
```bash
# Note: When using tea CLI, you must specify --repo johno/nixos-configs
# The CLI doesn't automatically detect the repo from git remote

# List all issues (open by default)
tea issues --repo johno/nixos-configs

# List closed issues
tea issues --repo johno/nixos-configs --state closed

# View specific issue
tea issue --repo johno/nixos-configs 2

# Create new issue
tea issues create --repo johno/nixos-configs --title "Issue title" --body "Description"

# Add comment to issue
tea comment --repo johno/nixos-configs 2 "Comment text"

# Close issue (note: 'issues' is plural, issue number comes last)
tea issues close --repo johno/nixos-configs 2
```

## Important Notes

- **Sudo access**: Claude Code does not have sudo access. Ask the user to run elevated commands like `sudo nixos-rebuild switch`

## Landing the Plane (Session Completion)

**When ending a work session**, you MUST complete ALL steps below. Work is NOT complete until `git push` succeeds.

**MANDATORY WORKFLOW:**

1. **File issues for remaining work** - Create issues for anything that needs follow-up
2. **Run quality gates** (if code changed) - Tests, linters, builds
3. **Update issue status** - Close finished work, update in-progress items
4. **PUSH TO REMOTE** - This is MANDATORY:
   ```bash
   git pull --rebase
   bd sync
   git push
   git status  # MUST show "up to date with origin"
   ```
5. **Clean up** - Clear stashes, prune remote branches
6. **Verify** - All changes committed AND pushed
7. **Hand off** - Provide context for next session

**CRITICAL RULES:**
- Work is NOT complete until `git push` succeeds
- NEVER stop before pushing - that leaves work stranded locally
- NEVER say "ready to push when you are" - YOU must push
- If push fails, resolve and retry until it succeeds
