pwnbox The manual. Every option, every key, every file.

docs / architecture

Architecture

Repository layout

text
.
├── flake.nix                 # inputs and outputs
├── install.sh                # bootstrap / rebuild helper
├── hosts/                    # per-machine configs (one dir per host)
│   └── nixos/                # template host
├── modules/
│   ├── nixos/                # system modules
│   │   ├── desktop/          # Hyprland, GNOME, LY, fonts, GTK, X
│   │   ├── hardening.nix     # kernel/network hardening
│   │   ├── options.nix       # the pwnbox.* option tree
│   │   └── …
│   └── home/                 # home-manager modules
│       ├── dotfiles.nix      # links configs, theme activation
│       ├── gtk.nix           # GTK + dconf
│       ├── neovim.nix
│       ├── packages.nix
│       └── shell.nix         # zsh + aliases
├── pkgs/                     # package sets, toolset categories, custom.nix
├── overlays/                 # nixpkgs overlay
└── dotfiles/
    ├── config/               # app configs (kitty, rofi, quickshell, …)
    │   └── wal/              # pywal templates + monochrome seed
    ├── themes/               # custom fixed-palette themes
    ├── gnome/                # fonts, GTK base CSS, wallpapers
    └── scripts/              # pwnbox-theme, pwnbox-spotify, …

How files are deployed

Home-manager links most config files read-only from the Nix store (xdg.configFile). Files that must change at runtime are handled in one of two ways:

  1. Included/generated companion. The managed file ends with an include or an @import of a writable file under ~/.cache/pwnbox/theme/ (kitty, rofi, fuzzel, Hyprland, GTK).
  2. Base + generated output. The managed file is a base; a script composes the final file next to it (Spotify user.css), or the managed file includes a generated snippet (Zathura zathura.conf).

This is why ~/.config/kitty/kitty.conf is a store symlink but ~/.cache/pwnbox/theme/kitty.conf is writable.

What happens on ALT+S

text
rofi menu
   │
   ├─ Pywal ─────► wal -i <image>  ─┐
   ├─ Custom ────► build scheme ────┤
   │                                ▼
   │                        install palette
   │                    (kitty, rofi, fuzzel, GTK,
   │                     Hyprland, Neovim, Zed,
   │                     Quickshell Theme.js)
   │                                │
   ├─ bar style ──► qs ipc call barstyle set
   ├─ radius/blur/opacity/animations ──► hyprctl reload
   ├─ fonts/sizes ──► regenerate per-app font config
   │
   └──────────────► reload_apps
                       ├─ kitty: SIGUSR1
                       ├─ hyprctl reload
                       ├─ GTK colour-scheme refresh
                       ├─ restart Quickshell
                       └─ live app theming
                            ├─ Spotify (Spicetify watch)
                            ├─ Discord (quickCss watcher)
                            └─ Telegram (theme file watcher)

The palette flows from a single source of truth: the 16-colour scheme produced by pywal (or a custom theme.conf). dotfiles/config/wal/templates/ contains the templates that turn it into each app's format.

State and generated files

  • Settings live in ~/.cache/pwnbox/theme/ (see Themes → Where state lives).
  • Generated app configs live next to their managed base or under ~/.cache/pwnbox/theme/.
  • On login, pwnbox-theme restore re-applies the saved wallpaper/theme and effects, then reload_apps re-syncs the live apps.

Scripts

ScriptRole
~/.scripts/pwnbox-themeThe theme engine (menu, pickers, palette, fonts, state)
~/.scripts/pwnbox-spotifyWritable Spotify + Spicetify + watch
~/.scripts/pwnbox-screenshotRegion/full/saved screenshots
~/.scripts/statusSmall status helper

Flake outputs

OutputPurpose
nixosConfigurations.<host>The system configuration
nixosModules.default / .home-managerReusable modules
homeManagerModules.defaultHome configuration
overlays.defaultnixpkgs overlay (fonts, cursors, toolset)
packages.<system>Toolset packages
formatter.<system>nixfmt
devShells.<system>.defaultnixfmt, statix, deadnix