# Nix-Vibe Config Improvements Prioritized from the package/service review (most important first). > **Review status (2026-09-01):** All 20 items committed to `main`. > `nix flake check` βœ… β€” all 8 hosts dry-build βœ…. > Reviewed against commits `f6d68b6`…`628f1b2`. --- ## πŸ”΄ Critical β€” Security & Data Integrity - [x] **OpenSSH hardening** β€” verified in `f6d68b6` (key-only auth, PermitRootLogin=no). - [x] **Samba share security** β€” verified in `0f5065e` (authenticated, valid users = petere). - [x] **Paperless to Tailscale only** β€” verified in `444705d` (firewall on `tailscale0` interface). - [x] **Immich accelerationDevices** β€” verified in `dd15aa2` (explicit /dev/nvidia* nodes). - [x] **Jellyfin SSO plugin bind-mount** β€” verified in `b8ba00c`, improved by `1f712f7`. ⚠️ Needs manual Pocket ID config. ## 🟠 High β€” Resource Waste / Performance - [x] **Jellyfin NVENC acceleration** β€” verified in `a4bd8bd`. - [x] **Nix GC + optimise** β€” verified in `dde980e`. - [x] **Caddy cleanup** β€” verified in `df588e7` (unused module deleted). - [x] **Formatter dedup** β€” verified in `1ae761a` (nixfmt only). - [x] **Antigravity dedup** β€” verified in `4e72c58` (removed entirely). ## 🟑 Medium β€” Misconfigurations / Robustness - [x] **homeserver-1 firewall scoping** β€” verified in `bc68837` (Immichβ†’Tailscale). - [x] **Laptop hardware module** β€” verified in `83ab88f` + `fe63013`. - [x] **borgbackup β†’ Backrest** β€” verified in `75b3c75`. - [x] **Immich DB peer-auth** β€” βœ… socket auth, no secret needed. - [x] **ntfy listen** β€” reverted in `628f1b2` (Docker nginx can't reach host localhost). - [x] **Firefox sync pref** β€” verified in `005e421` (removed). - [x] **Jellyfin group** β€” explicit `jellyfin` group (no `nobody` hack). ## 🟒 Low β€” Housekeeping - [x] **Flatpak GC** β€” verified in `6d7effd`. - [x] **VSCode extension pinned** β€” verified in `dd7deba`. - [x] **OnlyOffice fonts** β€” kept activation approach (documented). - [x] **Zsh secrets initContent** β€” kept interactive-only (documented). --- ## Remaining manual steps - [ ] **Jellyfin**: configure Pocket ID SSO manually in admin UI. - [ ] **Firefox Sync**: sign in once via browser UI. --- ## Hyprland / QuickShell β€” bigger projects (deferred from QoL pass) From the research list (2026 session). The basics (media keys, animations, scratchpad, OSD, clipboard, MPRIS, battery toast, night light, wofi icons/actions) are done. These are the larger items parked for later: - [x] **Notification center** β€” replaced mako with QuickShell native `NotificationServer` (toasts, history, DND, clear, actions/buttons). mako config + autostart fully removed. v2 options: per-app rules, inline replies. - [x] **Workspace overview** β€” QuickShell-native "mission control" (no plugin): fullscreen scrim, one card per workspace with window titles + active/focused highlight, click **or** keyboard jump (arrows/enter, 1-9 direct), `SUPER+W` β†’ `qs ipc call ws toggle`. Implemented in `quickshell-shell.qml` (titles via root `Hyprland.toplevels` filtered by workspace id β€” `HyprlandWorkspace .toplevels` doesn't exist in this build). ⚠️ `hyprspace` (live thumbnails) parked: `hyprlandPlugins.hyprspace` at the pinned nixpkgs FAILS TO BUILD (`src/Globals.hpp:15: AnimationManager.hpp: no such file` β€” hyprland source moved the header; nixpkgs package lags) and is not in the binary cache. Revisit after a nixpkgs bump. (hyprbars/hyprtrails also parked β€” hyprtrails isn't packaged.) - [x] **Calendar + weather popup** on clock click (`SUPER+CTRL+C`) β€” month-grid + Nextcloud CalDAV events + 3-day Open-Meteo forecast in a single QuickShell `PanelWindow`. Implemented in `quickshell-shell.qml` (header with month navigation, 6Γ—7 GridView calendar, agenda list, weather row with location editor). Data pipeline: HM user service `qs-cal-sync` β†’ vdirsyncer (CalDAV) + khal (`--json`) + Open-Meteo API β†’ caches in `~/.cache/quickshell-cal/`. Script: `quickshell-cal.py` (stdlib only), module: `quickshell-cal.nix`. Secrets: `hp-laptop/nextcloud-cal-env` in SOPS (`NEXTCLOUD_CALDAV_URL/USERNAME/PASSWORD` β€” **user must fill via `sops edit secrets.yaml`**). IPC: `qs ipc call cal toggle/refresh/state`. - [x] **Wallpaper picker widget** β€” thumbnail grid from `~/Pictures/wallpapers`, click β†’ hyprctl swap, persist choice to state file. ~half day. - [x] **QuickShell lock screen replacing hyprlock** β€” `WlSessionLock` + PAM. Decision (2026-09-11): NOT implementing β€” keep hyprlock. Its PAM service, fingerprint support and the hypridle/lid `loginctl lock-session` chain are battle-tested and already themed to match the shell; a QuickShell lock would rebuild the auth stack for visual gain only. Reopen only if hyprlock is ever dropped as a dependency. - [x] **Lid close: lock then suspend (always, resume needs password)** β€” fixed in `modules/desktop/hyprland.nix`: `HandleLidSwitchExternalPower` was `ignore` so a plugged-in lid close did nothing. Now `suspend` on battery and external power; hypridle's `before_sleep_cmd = loginctl lock-session` locks (hyprlock) before logind sleeps, so reopening the lid resumes to a locked screen. Docked keeps logind's `ignore` default. 5-min idle lock + 15-min suspend unchanged. - [x] **Bluetooth management** β€” QuickShell bluetooth popup mirroring the wifi `netPopup` pattern: status-bar BT icon, power toggle, paired/known device list, connect/disconnect/pair/trust. Backend: enable `hardware.bluetooth` (desktops β€” currently disabled on ALL hosts) + a `qs-bt` helper over `bluetoothctl`/bluez D-Bus (same pattern as `qs-wall`/`qs-cal.py`), IPC `qs ipc call bt toggle`. Implemented: `hardware.bluetooth` + bluez polkit rule in `modules/desktop/gui.nix`, backend `qs-bt` (`home-manager/modules/quickshell-bt.py`), QML popup (PanelWindow `qs-bt` layer, FocusGrab), bt status icon, IPC `qs ipc call bt {toggle,state,power,scan}`. ## Rice backlog β€” Hyprland/QuickShell improvement list (#1–#10) Recovered from the 2026 rice session (persisted here after being lost twice). - [x] **#1 Wallpaper-driven palette + theme switcher** β€” matugen-based shared palette unifying QML theme, wvkbd, wofi, hyprlock, kitty; wallpaper-picker PALETTE button regenerates the theme (`qs-theme`). - [x] **#2 Hyprland blur/shadow/animated borders** β€” gradient `active_border`, shadow, `borderangle` animation loop in `hyprland.nix`. - [x] **#3 System-stats chip + flake badge** β€” `qs-stats` probe (lm_sensors), CPU/RAM/swap/disk/temps/load popup, flake.lock rev/date badge injected at build time, copy command. - [x] **#4 Dynamic island bar** β€” floating centered island pill, tucked-up when hidden, peek on hover, event reveal (workspace/notification/media) + 10s auto-retract. - [x] **#5 Now-playing + battery info in hyprlock** β€” show MPRIS track + battery percentage on the lock screen. - [ ] **#6 Visual monitor manager** β€” ARandR-style hyprctl front-end (rotate/scale/arrange monitors from a GUI). ⏸️ On hold until the laptop is connected to multiple monitors so it can be tested properly. - [x] **#7 OSD scroll-wheel on bar chips** β€” scroll the volume chip to nudge PipeWire volume (5% steps, OSD tracks it); new brightness chip scrolls `brightnessctl` (5% steps) with the neon OSD, click opens quick settings. Shell-scope `shellBrightProbe`/`shellBrightSet` (throttled, 30s refresh) keep chip/OSD/slider in sync. ⚠️ **Partially tested on x1carbon** β€” two-finger touchpad scroll works; still needs verification with a real scroll wheel before fully relying on it. - [x] **#8 Caffeine/idle-inhibit toggle** β€” already implemented as the keep-awake IdleInhibitor badge (Hyprland) + Caffeine extension (GNOME). - [x] **#9 Emoji picker + calculator in launcher** β€” `qs-launch` wofi modes: `SUPER+SHIFT+E` emoji picker (curated 295-emoji list, copies to clipboard), `SUPER+SHIFT+C` calculator (qalc eval, copies result + toast), `SUPER+SHIFT+D` DuckDuckGo search (opens in browser). - [ ] **#10 Screenshot β†’ bar toast with copy** β€” `qs-shot` (`Print` opens a wofi area/full-screen chooser, `SUPER+SHIFT+S`/`SUPER+SHIFT+R` capture directly): grimblast copysave β†’ toast with image thumbnail + OPEN/COPY action buttons (intercepted in `calNotifAction` by `shot-open:`/`shot-copy:` identifiers; also shown in the notification center history). ## Calendar popup β€” v2 improvements (deferred, all requested) - [x] **Edit / delete events** β€” click an agenda entry to edit title/time/location or delete it; syncs back to Nextcloud like `add` does. Backend `edit`/`delete` modes rewrite the .ics (summary/location/alarms/RRULE) and push via vdirsyncer; shell form gains EDIT EVENT mode with a DELETE button. Mutations rescan local stores immediately (`refresh_local_cache`) so the popup reflects them without waiting for the next timed sync. - [x] **Recurring events on creation** β€” "repeat daily/weekly/monthly" (RRULE options) in the NEW EVENT form. Backend `add` takes `repeat`; edit preserves and can change an existing RRULE. Recurring events also scan/expand natively (no khal) via `icalendar` + `recurring_ical_events`. - [x] **Clickable + snoozeable reminders** β€” click a reminder toast to jump to the event popup; add a snooze action on the notification. The remind notifier encodes payloads in the action identifiers (`cal-open:` opens the popup at that day, `cal-snooze:` delays the reminder 10 min via `snoozes.json`); both toasts and the notification center route action clicks through `calNotifAction`. Notifications are now `-t 0` (persist in center). - [x] **Sync failure indicator** β€” subtle badge in the calendar header when the last sync or event add fails. Backend writes `sync.json` (`ok/lastOk/ lastEffort/error`) on every sync/push; the shell shows a danger "!" badge with a hover tooltip of the error and click-to-refresh. - [x] **Weather upgrade** β€” hourly temps, precipitation chance, wind, more forecast days. Backend Open-Meteo fetch now pulls 24 hourly rows (temp/code/ precip%/wind) and a 7-day daily forecast (plus precip% + max wind); the shell renders a today-hourly strip and a compact 7-day grid (was 3).