diff --git a/docs/md/modules.md b/docs/md/modules.md index 2b0a01f..b7c38c2 100644 --- a/docs/md/modules.md +++ b/docs/md/modules.md @@ -84,31 +84,175 @@ Install via `tui-install.sh` at first install, or add later: bash ~/Dotfiles/setup/install-modules.sh ``` +> This table is generated from `setup/modules.conf`. Run `setup/generate-modules.sh` to regenerate. + ### AI & Machine Learning -| ID | Package | Description | -|----|---------|-------------| -| `ollama` | ollama | Local LLM runner with REST API server | -| `llama-cpp` | llama.cpp | Standalone inference CLI + server | -| `open-webui` | open-webui | Browser UI for Ollama / OpenAI-compatible backends | -| `claude` | claude (npm) | Anthropic Claude Code CLI | + +| ID | Description | +|----|-------------| +| `ollama` | local LLM runner and API server | +| `llama-cpp` | standalone LLM inference CLI and server | +| `open-webui` | browser UI for Ollama and LLM backends | +| `claude` | Anthropic Claude Code CLI via npm | + ### Networking & Security -| ID | Packages | Description | -|----|---------|-------------| -| `networking-cli` | nmap · nethogs · mitmproxy · httpie | Network analysis and HTTP tooling | -| `disk-recovery` | ddrescue · f3 | Disk imaging and flash drive testing | -| `ssh-server` | openssh | SSH daemon with key-auth enforcement | -| `wireshark` | wireshark-qt | Packet capture and analysis GUI | + +| ID | Description | +|----|-------------| +| `networking-cli` | nmap, nethogs, mitmproxy, httpie | +| `disk-recovery` | ddrescue and f3 disk recovery tools | +| `himalaya` | terminal email client (AUR) | +| `mail-notmuch` | isync, msmtp, notmuch, alot mail stack | +| `caldav-sync` | vdirsyncer and khal CalDAV calendar sync | +| `ssh-server` | openssh with key-auth and systemd unit enabled | +| `wireshark` | network packet analyser GUI | +| `anti-malware` | ClamAV, rkhunter, chkrootkit | + + +### Development + + +| ID | Description | +|----|-------------| +| `gnuplot` | scientific plotting tool | +| `blender-povray` | 3D modelling and ray-tracing (Blender + POV-Ray) | +| `toot` | Mastodon CLI client (AUR) | +| `db-clients` | pgcli and mycli interactive database CLIs | +| `mysql` | MariaDB server with initial setup | +| `productivity` | taskwarrior, watson, jrnl — task management and time tracking | +| `python` | pyright, pipx, pynvim Python tooling | +| `k8s` | kubectl and podman-desktop Kubernetes tools | +| `docker` | docker and docker-compose | +| `podman` | rootless containers with buildah | +| `cockpit` | web UI for machines and containers | + + +### System Utilities + + +| ID | Description | +|----|-------------| +| `tlp` | laptop battery optimisation | +| `butter` | btrfs snapshot backup manager (AUR) | +| `localsend` | LAN file transfer, AirDrop-like (AUR) | +| `croc` | cross-platform encrypted file transfer | +| `opendeck` | Stream Deck controller — ydotool + OpenDeck (Flatpak) | +| `localtunnel` | expose localhost over a public URL | +| `timeshift` | system snapshot and backup with autosnap | +| `zfs` | zfs-dkms kernel module | +| `wprs` | Wayland proxy for remote sessions (wprs-git, AUR) | +| `plymouth-custom` | boot splash with a user-supplied image | + + +### Gaming + + +| ID | Description | +|----|-------------| +| `steam` | Steam gaming platform | +| `vesktop` | Discord client with Vencord theme | +| `spotify` | Spotify launcher with Spicetify theming | +| `prism` | PrismLauncher Minecraft launcher (Flatpak) | +| `vintagestory` | Vintage Story survival game (AUR) | +| `openarena` | open-source Quake III Arena | +| `tetris` | bastet and vitetris terminal Tetris | +| `doom` | Chocolate Doom with Freedoom data | +| `sauerbraten` | Sauerbraten open-source FPS (Cube 2) | +| `stuntrally` | Stunt Rally racing game (Flatpak) | + + +### Notes & Office + + +| ID | Description | +|----|-------------| +| `onlyoffice` | office suite — Docs, Sheets, Slides (AUR) | +| `xournal` | note-taking and PDF annotator | +| `rnote` | handwriting and note-taking with stylus support (Flatpak) | +| `obsidian` | knowledge base and Markdown note-taking (Flatpak) | +| `tangent-notes` | networked Markdown note-taking (Flatpak) | + + +### Media + + +| ID | Description | +|----|-------------| +| `ffmpeg` | GStreamer codecs and ffmpegthumbnailer | +| `sox` | command-line audio processing toolkit | +| `imagemagick` | image manipulation suite | +| `yt-dlp` | YouTube and media downloader | + + +### Graphic Design + + +| ID | Description | +|----|-------------| +| `gimp` | GNU Image Manipulation Program | +| `inkscape` | vector graphics editor | +| `krita` | digital painting and illustration | + + +### Video Editing + + +| ID | Description | +|----|-------------| +| `kdenlive` | KDE non-linear video editor | +| `openshot` | cross-platform video editor | +| `shotcut` | cross-platform video editor | + + +### Audio Production + + +| ID | Description | +|----|-------------| +| `ardour` | professional DAW | +| `audacity` | multi-track audio editor | +| `lmms` | Linux MultiMedia Studio music production | +| `mixxx` | DJ mixing software | +| `cecilia` | audio synthesis and signal processing (AUR) | + + +### Browsers + + +| ID | Description | +|----|-------------| +| `chromium` | open-source Chromium browser (official) | +| `firefox-browser` | Mozilla Firefox (official) | +| `zen-browser` | privacy-focused Firefox fork (AUR) | +| `nyxt` | keyboard-driven hackable browser (AUR) | +| `librewolf` | hardened Firefox fork (AUR) | +| `min-browser` | minimal Electron browser (AUR) | + + +### IDEs & Editors + + +| ID | Description | +|----|-------------| +| `vscodium` | telemetry-free VS Code build (AUR) | +| `zed-ide` | high-performance Rust IDE (official) | +| `geany` | lightweight IDE with plugins (official) | +| `codeblocks` | C/C++ IDE (official) | +| `kate` | KDE advanced text editor (official) | + ### Virtualisation & Remote Desktop -| ID | Packages | Description | -|----|---------|-------------| -| `qemu` | qemu-full · libvirt · virt-manager · virt-viewer · dnsmasq · bridge-utils · edk2-ovmf · swtpm · vde2 | Full QEMU/KVM stack with virt-manager GUI; enables libvirtd, auto-starts default NAT network, adds user to `libvirt` and `kvm` groups | -| `rdp-client` | remmina · freerdp · libvncserver | Remmina remote desktop client with RDP (FreeRDP) and VNC support | -| `lamco-rdp-server` | lamco-rdp-server (AUR) | Native Wayland RDP server written in Rust with H.264/VA-API encoding; runs as a systemd user service | + +| ID | Description | +|----|-------------| +| `rdp-client` | Remmina with FreeRDP and VNC plugins | +| `lamco-rdp-server` | native Wayland RDP server (AUR, Rust) | +| `qemu` | full QEMU/KVM stack with virt-manager | + **lamco-rdp-server notes:** - Enabled as a user service: `systemctl --user enable lamco-rdp-server.service` @@ -116,122 +260,15 @@ bash ~/Dotfiles/setup/install-modules.sh - Optional GUI tray: `lamco-rdp-server-gui` - Requires an `xdg-desktop-portal` matching your compositor (`-hyprland`, `-wlr`, `-gnome`, `-kde`) -### Development - -| ID | Packages | Description | -|----|---------|-------------| -| `python` | pyright · pipx · pynvim | Python LSP, isolated tool runner, Neovim integration | -| `docker` | docker · docker-compose | Container runtime | -| `podman` | podman · buildah · podman-compose | Rootless containers | -| `cockpit` | cockpit · machines · podman | Web-based system management UI | -| `k8s` | kubectl · podman-desktop | Kubernetes CLI and desktop client | -| `db-clients` | pgcli · mycli | Enhanced interactive database CLIs | -| `mysql` | mariadb | MariaDB server with initial setup | - -### IDEs & Editors - -| ID | Package | Description | -|----|---------|-------------| -| `vscodium` | vscodium-bin (AUR) | VS Code without telemetry | -| `zed-ide` | zed | High-performance Rust IDE | -| `geany` | geany · geany-plugins | Lightweight IDE | -| `codeblocks` | codeblocks | C/C++ IDE | -| `kate` | kate | KDE advanced text editor | - -### Browsers - -| ID | Package | Description | -|----|---------|-------------| -| `chromium` | chromium | Open-source Chromium | -| `firefox-browser` | firefox | Mozilla Firefox | -| `zen-browser` | zen-browser-bin (AUR) | Privacy-focused Firefox fork | -| `nyxt` | nyxt (AUR) | Keyboard-driven, hackable browser | -| `librewolf` | librewolf-bin (AUR) | Hardened Firefox fork | -| `min-browser` | min (AUR) | Minimal Electron browser | - -### Gaming - -| ID | Package | Description | -|----|---------|-------------| -| `steam` | steam | Steam gaming platform | -| `vesktop` | vesktop (AUR) | Discord client with Vencord built-in | -| `spotify` | spotify (AUR) + spicetify | Music player with CyberQueer theme | -| `prism` | prismlauncher (Flatpak) | Minecraft launcher | -| `vintagestory` | vintagestory (AUR) | Survival / voxel game | - -### Media & Creative - -| ID | Packages | Description | -|----|---------|-------------| -| `ffmpeg` | gst-plugin-pipewire · gst-plugins-good · ffmpegthumbnailer | GStreamer codecs + thumbnailer | -| `sox` | sox | Command-line audio processing | -| `imagemagick` | imagemagick | Image manipulation suite | -| `yt-dlp` | yt-dlp | YouTube / media downloader | -| `blender` | blender | 3D creation suite | -| `gnuplot` | gnuplot | Scientific plotting | -| `povray` | povray | Ray-tracing renderer | - -#### Graphic Design - -| ID | Package | Description | -|----|---------|-------------| -| `gimp` | gimp | GNU Image Manipulation Program | -| `inkscape` | inkscape | Vector graphics editor | -| `krita` | krita | Digital painting and illustration | - -#### Video Editing - -| ID | Package | Description | -|----|---------|-------------| -| `kdenlive` | kdenlive | KDE non-linear video editor | -| `openshot` | openshot | Cross-platform video editor | -| `shotcut` | shotcut | Cross-platform video editor | - -#### Audio Production - -| ID | Package | Description | -|----|---------|-------------| -| `audacity` | audacity | Multi-track audio editor | -| `lmms` | lmms | Linux MultiMedia Studio (music production) | -| `ardour` | ardour | Professional DAW | -| `mixxx` | mixxx | DJ mixing software | -| `cecilia` | cecilia (AUR) | Audio synthesis and signal processing | - -### Productivity - -| ID | Packages | Description | -|----|---------|-------------| -| `productivity` | taskwarrior · watson · jrnl | Task management, time tracking, journaling | -| `himalaya` | himalaya (AUR) | Terminal email client | -| `toot` | toot (AUR) | Mastodon CLI client | -| `xournal` | xournalpp | Note-taking and PDF annotator | -| `rnote` | Rnote (Flatpak) | Handwriting and note-taking with stylus support | -| `obsidian` | Obsidian (Flatpak) | Knowledge base and Markdown note-taking | -| `tangent-notes` | Tangent Notes (Flatpak) | Networked Markdown note-taking | - -### System Utilities - -| ID | Packages | Description | -|----|---------|-------------| -| `plymouth` | plymouth · librsvg | Boot splash (bundled skull logo + spinner) — same as the core component | -| `plymouth-custom` | plymouth · librsvg or imagemagick | Boot splash with a user-supplied image; prompts for a PNG or SVG path | -| `tlp` | tlp · tlp-rdw | Laptop battery optimisation | -| `zfs` | zfs-dkms | ZFS kernel module | -| `wprs` | wprs-git (AUR) | Wayland proxy for remote sessions | -| `butter` | butter (AUR) | Btrfs snapshot backup manager | -| `localsend` | localsend (AUR) | LAN file transfer (AirDrop-like) | -| `croc` | croc | Cross-platform encrypted file transfer | -| `opendeck` | ydotool (pacman) · OpenDeck (Flatpak) | Stream Deck controller; ydotoold + OpenDeck added to Hyprland autostart | -| `localtunnel` | localtunnel (npm) | Expose localhost over a public URL | -| `onlyoffice` | onlyoffice-bin (AUR) | Office suite (Docs, Sheets, Slides) | - ### Identity & Infrastructure + | ID | Description | |----|-------------| -| `freeipa-client` | sssd + ipa-client-install + auto-enrollment (see [FreeIPA](freeipa-ansible.md)) | -| `freeipa-server` | Interactive FreeIPA server setup + client generator | -| `freeipa-image` | OCI / LXC / Proxmox LXC image builder + Keycloak | +| `freeipa-client` | sssd and ipa-client-install with auto-enrollment | +| `freeipa-server` | interactive FreeIPA server setup with client generator | +| `freeipa-image` | OCI/LXC/Proxmox image builder with Keycloak | + --- diff --git a/setup/generate-answerfile.sh b/setup/generate-answerfile.sh index 3838227..b07a75e 100644 --- a/setup/generate-answerfile.sh +++ b/setup/generate-answerfile.sh @@ -216,89 +216,92 @@ if [[ "$AF_RUN_TUI" == "true" ]]; then 3>&1 1>&2 2>&3) || AF_DE="none" # ── Apps ────────────────────────────────────────────────────────────────── +# BEGIN GENERATED MODULES: module-checklist AF_APPS=$(dialog --backtitle "$BACKTITLE" \ --title " Applications " \ - --checklist "Optional applications — installed after base components:" 40 76 32 \ - "ollama" "Ollama local LLM runner + API server" off \ - "llama-cpp" "llama.cpp standalone inference CLI + server" off \ - "open-webui" "Open WebUI browser UI for Ollama / LLM backends" off \ - "claude" "Claude Code Anthropic CLI via npm" off \ - "networking-cli" "Networking CLI nmap · nethogs · mitmproxy · httpie" off \ - "disk-recovery" "Disk Recovery ddrescue · f3" off \ - "himalaya" "Himalaya terminal email client (AUR)" off \ - "mail-notmuch" "Mail (notmuch) isync · msmtp · notmuch · alot stack" off \ - "caldav-sync" "CalDAV Sync vdirsyncer · khal calendar sync" off \ - "gnuplot" "Gnuplot scientific plotting" off \ - "blender-povray" "Blender + POV-Ray 3D modelling & ray-tracing" off \ - "toot" "toot Mastodon CLI client (AUR)" off \ - "db-clients" "DB Clients pgcli · mycli" off \ - "mysql" "MySQL / MariaDB mariadb server + setup" off \ - "productivity" "Productivity taskwarrior · watson · jrnl" off \ - "yt-dlp" "yt-dlp YouTube / media downloader" off \ - "sox" "SoX audio processing toolkit" off \ - "imagemagick" "ImageMagick image manipulation" off \ - "ffmpeg" "FFmpeg extras thumbnailer · GStreamer codecs" off \ - "localtunnel" "LocalTunnel expose localhost via tunnel" off \ - "butter" "butter btrfs snapshot backup (AUR)" off \ - "tlp" "TLP laptop power management" off \ - "steam" "Steam gaming platform" off \ - "vesktop" "Vesktop Discord + Vencord theme" off \ - "spotify" "Spotify launcher + Spicetify theming" off \ - "prism" "PrismLauncher Minecraft launcher (Flatpak)" off \ - "vintagestory" "Vintage Story survival game (AUR)" off \ - "openarena" "OpenArena open-source Quake III Arena" off \ - "tetris" "Tetris CLI bastet · vitetris" off \ - "doom" "Doom Chocolate Doom + Freedoom data" off \ - "sauerbraten" "Sauerbraten open-source FPS (Cube 2)" off \ - "stuntrally" "Stunt Rally rally racing game (Flatpak)" off \ - "localsend" "LocalSend LAN file transfer (AUR)" off \ - "croc" "croc cross-platform file transfer" off \ - "opendeck" "OpenDeck Stream Deck controller (Flatpak+ydotool)" off \ - "onlyoffice" "OnlyOffice office suite (AUR)" off \ - "xournal" "Xournal++ note-taking & PDF annotator" off \ - "rnote" "Rnote handwriting & note-taking (Flatpak)" off \ - "obsidian" "Obsidian knowledge base & Markdown notes (Flatpak)" off \ - "tangent-notes" "Tangent Notes networked Markdown notes (Flatpak)" off \ - "gimp" "GIMP GNU image manipulation program" off \ - "inkscape" "Inkscape vector graphics editor" off \ - "krita" "Krita digital painting application" off \ - "ardour" "Ardour professional DAW" off \ - "audacity" "Audacity multi-track audio editor" off \ - "lmms" "LMMS Linux MultiMedia Studio DAW" off \ - "mixxx" "Mixxx DJ mixing software" off \ - "cecilia" "Cecilia audio signal processing (AUR)" off \ - "kdenlive" "Kdenlive KDE non-linear video editor" off \ - "openshot" "OpenShot easy video editor" off \ - "shotcut" "Shotcut cross-platform video editor" off \ - "anti-malware" "Anti-Malware ClamAV · rkhunter · chkrootkit" off \ - "timeshift" "Timeshift system snapshot / backup + autosnap" off \ - "wireshark" "Wireshark network packet analyser (GUI)" off \ - "k8s" "Kubernetes tools kubectl · podman-desktop" off \ - "docker" "Docker docker · docker-compose" off \ - "podman" "Podman rootless containers · buildah" off \ - "cockpit" "Cockpit web UI · machines · podman" off \ - "ssh-server" "SSH server openssh · key-auth · enabled" off \ - "freeipa-client" "FreeIPA Client sssd + ipa-client-install + enrollment" off \ - "freeipa-server" "FreeIPA Server interactive server setup + client gen" off \ - "freeipa-image" "FreeIPA Image OCI/LXC/Proxmox LXC builder + Keycloak" off \ - "python" "Python tools pyright · pipx · pynvim" off \ - "zfs" "ZFS zfs-dkms kernel module" off \ - "wprs" "WPRS wprs-git (AUR)" off \ - "chromium" "Chromium open-source browser (official)" off \ - "firefox-browser" "Firefox Mozilla browser (official)" off \ - "zen-browser" "Zen Browser Firefox-based privacy browser (AUR)" off \ - "nyxt" "Nyxt keyboard-driven browser (AUR)" off \ - "librewolf" "LibreWolf hardened Firefox fork (AUR)" off \ - "min-browser" "Min minimal Electron browser (AUR)" off \ - "vscodium" "VSCodium telemetry-free VS Code (AUR)" off \ - "zed-ide" "Zed high-performance Rust IDE (official)" off \ - "geany" "Geany lightweight IDE + plugins (official)" off \ - "codeblocks" "Code::Blocks C/C++ IDE (official)" off \ - "kate" "Kate KDE advanced text editor (official)" off \ - "rdp-client" "RDP Client Remmina + FreeRDP + VNC plugins" off \ - "lamco-rdp-server" "Lamco RDP Server native Wayland RDP server (AUR, Rust)" off \ - "qemu" "QEMU/KVM full virt stack + virt-manager GUI" off \ + --checklist "Optional applications — installed after base components:" 40 76 80 \ + "ollama" "ollama local LLM runner and API server" off \ + "llama-cpp" "llama-cpp standalone LLM inference CLI and server" off \ + "open-webui" "open-webui browser UI for Ollama and LLM backends" off \ + "claude" "claude Anthropic Claude Code CLI via npm" off \ + "networking-cli" "networking-cli nmap, nethogs, mitmproxy, httpie" off \ + "disk-recovery" "disk-recovery ddrescue and f3 disk recovery tools" off \ + "himalaya" "himalaya terminal email client (AUR)" off \ + "mail-notmuch" "mail-notmuch isync, msmtp, notmuch, alot mail stack" off \ + "caldav-sync" "caldav-sync vdirsyncer and khal CalDAV calendar sync" off \ + "ssh-server" "ssh-server openssh with key-auth and systemd unit enabled" off \ + "wireshark" "wireshark network packet analyser GUI" off \ + "anti-malware" "anti-malware ClamAV, rkhunter, chkrootkit" off \ + "gnuplot" "gnuplot scientific plotting tool" off \ + "blender-povray" "blender-povray 3D modelling and ray-tracing (Blender + POV-Ray)" off \ + "toot" "toot Mastodon CLI client (AUR)" off \ + "db-clients" "db-clients pgcli and mycli interactive database CLIs" off \ + "mysql" "mysql MariaDB server with initial setup" off \ + "productivity" "productivity taskwarrior, watson, jrnl — task management and time tracking" off \ + "python" "python pyright, pipx, pynvim Python tooling" on \ + "k8s" "k8s kubectl and podman-desktop Kubernetes tools" off \ + "docker" "docker docker and docker-compose" off \ + "podman" "podman rootless containers with buildah" off \ + "cockpit" "cockpit web UI for machines and containers" off \ + "tlp" "tlp laptop battery optimisation" off \ + "butter" "butter btrfs snapshot backup manager (AUR)" off \ + "localsend" "localsend LAN file transfer, AirDrop-like (AUR)" off \ + "croc" "croc cross-platform encrypted file transfer" off \ + "opendeck" "opendeck Stream Deck controller — ydotool + OpenDeck (Flatpak)" off \ + "localtunnel" "localtunnel expose localhost over a public URL" off \ + "timeshift" "timeshift system snapshot and backup with autosnap" off \ + "zfs" "zfs zfs-dkms kernel module" off \ + "wprs" "wprs Wayland proxy for remote sessions (wprs-git, AUR)" off \ + "plymouth-custom" "plymouth-custom boot splash with a user-supplied image" off \ + "steam" "steam Steam gaming platform" off \ + "vesktop" "vesktop Discord client with Vencord theme" off \ + "spotify" "spotify Spotify launcher with Spicetify theming" off \ + "prism" "prism PrismLauncher Minecraft launcher (Flatpak)" off \ + "vintagestory" "vintagestory Vintage Story survival game (AUR)" off \ + "openarena" "openarena open-source Quake III Arena" off \ + "tetris" "tetris bastet and vitetris terminal Tetris" off \ + "doom" "doom Chocolate Doom with Freedoom data" off \ + "sauerbraten" "sauerbraten Sauerbraten open-source FPS (Cube 2)" off \ + "stuntrally" "stuntrally Stunt Rally racing game (Flatpak)" off \ + "onlyoffice" "onlyoffice office suite — Docs, Sheets, Slides (AUR)" on \ + "xournal" "xournal note-taking and PDF annotator" off \ + "rnote" "rnote handwriting and note-taking with stylus support (Flatpak)" off \ + "obsidian" "obsidian knowledge base and Markdown note-taking (Flatpak)" off \ + "tangent-notes" "tangent-notes networked Markdown note-taking (Flatpak)" off \ + "ffmpeg" "ffmpeg GStreamer codecs and ffmpegthumbnailer" off \ + "sox" "sox command-line audio processing toolkit" off \ + "imagemagick" "imagemagick image manipulation suite" off \ + "yt-dlp" "yt-dlp YouTube and media downloader" off \ + "gimp" "gimp GNU Image Manipulation Program" off \ + "inkscape" "inkscape vector graphics editor" off \ + "krita" "krita digital painting and illustration" off \ + "kdenlive" "kdenlive KDE non-linear video editor" off \ + "openshot" "openshot cross-platform video editor" off \ + "shotcut" "shotcut cross-platform video editor" off \ + "ardour" "ardour professional DAW" off \ + "audacity" "audacity multi-track audio editor" off \ + "lmms" "lmms Linux MultiMedia Studio music production" off \ + "mixxx" "mixxx DJ mixing software" off \ + "cecilia" "cecilia audio synthesis and signal processing (AUR)" off \ + "chromium" "chromium open-source Chromium browser (official)" off \ + "firefox-browser" "firefox-browser Mozilla Firefox (official)" on \ + "zen-browser" "zen-browser privacy-focused Firefox fork (AUR)" off \ + "nyxt" "nyxt keyboard-driven hackable browser (AUR)" off \ + "librewolf" "librewolf hardened Firefox fork (AUR)" off \ + "min-browser" "min-browser minimal Electron browser (AUR)" off \ + "vscodium" "vscodium telemetry-free VS Code build (AUR)" off \ + "zed-ide" "zed-ide high-performance Rust IDE (official)" off \ + "geany" "geany lightweight IDE with plugins (official)" off \ + "codeblocks" "codeblocks C/C++ IDE (official)" off \ + "kate" "kate KDE advanced text editor (official)" off \ + "rdp-client" "rdp-client Remmina with FreeRDP and VNC plugins" off \ + "lamco-rdp-server" "lamco-rdp-server native Wayland RDP server (AUR, Rust)" off \ + "qemu" "qemu full QEMU/KVM stack with virt-manager" off \ + "freeipa-client" "freeipa-client sssd and ipa-client-install with auto-enrollment" off \ + "freeipa-server" "freeipa-server interactive FreeIPA server setup with client generator" off \ + "freeipa-image" "freeipa-image OCI/LXC/Proxmox image builder with Keycloak" off \ 3>&1 1>&2 2>&3) || AF_APPS="" +# END GENERATED MODULES: module-checklist # ── Shell RC preference ─────────────────────────────────────────────────── AF_SHELL_RC=$(dialog --backtitle "$BACKTITLE" \ diff --git a/setup/generate-modules.sh b/setup/generate-modules.sh new file mode 100755 index 0000000..d39a648 --- /dev/null +++ b/setup/generate-modules.sh @@ -0,0 +1,234 @@ +#!/bin/bash +# generate-modules.sh — regenerate all sentinel regions from modules.conf +# +# Usage: +# ./generate-modules.sh — apply changes in-place +# ./generate-modules.sh --dry-run — print a unified diff, make no changes +# +# Sentinel format in target files: +# bash/sh: # BEGIN GENERATED MODULES: / # END GENERATED MODULES: +# markdown: / +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +CONF="$SCRIPT_DIR/modules.conf" +TUI="$SCRIPT_DIR/tui-install.sh" +AF="$SCRIPT_DIR/generate-answerfile.sh" +DOCS="$SCRIPT_DIR/../docs/md/modules.md" + +DRY_RUN=false +[[ "${1:-}" == "--dry-run" ]] && DRY_RUN=true + +# ── Parse modules.conf ──────────────────────────────────────────────────────── +declare -a M_IDS M_CATS M_DESCS M_DEFAULTS M_EXCLUDES +skipped=() + +while IFS='|' read -r id cat desc def excl; do + # Strip leading/trailing whitespace from each field + id="${id#"${id%%[![:space:]]*}"}"; id="${id%"${id##*[![:space:]]}"}" + [[ "$id" =~ ^# || -z "$id" ]] && continue + M_IDS+=("$id") + M_CATS+=("$cat") + M_DESCS+=("$desc") + M_DEFAULTS+=("${def:-off}") + M_EXCLUDES+=("${excl:-}") +done < "$CONF" + +# Identify incomplete entries (missing category or description) — skip them. +declare -a ACTIVE_IDS +for i in "${!M_IDS[@]}"; do + if [[ -z "${M_CATS[$i]}" || -z "${M_DESCS[$i]}" ]]; then + skipped+=("${M_IDS[$i]}") + else + ACTIVE_IDS+=("$i") + fi +done + +if (( ${#skipped[@]} > 0 )); then + printf '[warn] skipping %d stub(s) with empty category/description:\n' "${#skipped[@]}" >&2 + printf ' %s\n' "${skipped[@]}" >&2 +fi + +# ── Build generated sections ────────────────────────────────────────────────── + +# -- module-counters (tui-install.sh: count_steps function body) -------------- +gen_counters="" +for i in "${ACTIVE_IDS[@]}"; do + id="${M_IDS[$i]}" + gen_counters+=" [[ \"\$a\" == *\"${id}\"* ]] && TOTAL=\$(( TOTAL + 1 ))\n" +done + +# -- module-checklist (tui-install.sh and generate-answerfile.sh) ------------- +# Builds the full SELECTED_APPS=$(dialog ...) call including open/close. +build_checklist_tui() { + local out + out=' SELECTED_APPS=$(dialog --backtitle "$BACKTITLE" \\\n' + out+=' --title " Applications " \\\n' + out+=' --checklist "Optional applications — installed after base components:" "$_APP_H" 76 "$_APP_LIST_H" \\\n' + for i in "${ACTIVE_IDS[@]}"; do + local id="${M_IDS[$i]}" desc="${M_DESCS[$i]}" def="${M_DEFAULTS[$i]}" + local padded + padded=$(printf '%-20s' "$id") + out+=" \"${id}\" \"${padded} ${desc}\" ${def} \\\\\n" + done + out+=' 3>&1 1>&2 2>&3) || SELECTED_APPS=""\n' + printf '%s' "$out" +} + +build_checklist_af() { + local count="${#ACTIVE_IDS[@]}" + local out + out=" AF_APPS=\$(dialog --backtitle \"\$BACKTITLE\" \\\\\n" + out+=" --title \" Applications \" \\\\\n" + out+=" --checklist \"Optional applications — installed after base components:\" 40 76 ${count} \\\\\n" + for i in "${ACTIVE_IDS[@]}"; do + local id="${M_IDS[$i]}" desc="${M_DESCS[$i]}" def="${M_DEFAULTS[$i]}" + local padded + padded=$(printf '%-20s' "$id") + out+=" \"${id}\" \"${padded} ${desc}\" ${def} \\\\\n" + done + out+=' 3>&1 1>&2 2>&3) || AF_APPS=""\n' + printf '%s' "$out" +} + +gen_checklist_tui=$(build_checklist_tui) +gen_checklist_af=$(build_checklist_af) + +# -- module-summary (tui-install.sh: confirmation dialog) --------------------- +gen_summary="" +for i in "${ACTIVE_IDS[@]}"; do + id="${M_IDS[$i]}" + gen_summary+=" [[ \"\$SELECTED_APPS\" == *\"${id}\"* ]] && SUMMARY+=\" ✦ ${id}\\\\n\"\n" +done + +# -- module-conflicts (tui-install.sh: before dispatch) ----------------------- +gen_conflicts="" +for i in "${ACTIVE_IDS[@]}"; do + id="${M_IDS[$i]}" + excl="${M_EXCLUDES[$i]}" + [[ -z "$excl" ]] && continue + IFS=',' read -ra excl_list <<< "$excl" + for eid in "${excl_list[@]}"; do + eid="${eid#"${eid%%[![:space:]]*}"}"; eid="${eid%"${eid##*[![:space:]]}"}" + gen_conflicts+="if [[ \"\$SELECTED_APPS\" == *\"${id}\"* && \"\$SELECTED_APPS\" == *\"${eid}\"* ]]; then\n" + gen_conflicts+=" warn \"${id} and ${eid} are mutually exclusive — skipping ${eid}\"\n" + gen_conflicts+=" SELECTED_APPS=\"\${SELECTED_APPS/${eid}/}\"\n" + gen_conflicts+="fi\n" + done +done + +# -- module-dispatch (tui-install.sh: installation section) ------------------- +gen_dispatch="" +for i in "${ACTIVE_IDS[@]}"; do + id="${M_IDS[$i]}" + gen_dispatch+="[[ \"\$SELECTED_APPS\" == *\"${id}\"* ]] && run_module \"${id}\" \"\$APPS/${id}.sh\"\n" +done + +# -- per-category doc tables (docs/md/modules.md) ----------------------------- +declare -A gen_docs_cat +for i in "${ACTIVE_IDS[@]}"; do + id="${M_IDS[$i]}" + cat="${M_CATS[$i]}" + desc="${M_DESCS[$i]}" + gen_docs_cat[$cat]+="| \`${id}\` | ${desc} |\n" +done + +build_doc_table() { + local cat="$1" + local rows="${gen_docs_cat[$cat]:-}" + if [[ -z "$rows" ]]; then + printf '' + return + fi + printf '| ID | Description |\n|----|-------------|\n' + printf '%b' "$rows" +} + +# ── Splice helper (uses python3 for safe multiline replacement) ─────────────── +splice() { + local file="$1" tag="$2" content="$3" style="${4:-bash}" + local tmpfile + tmpfile=$(mktemp) + printf '%b' "$content" > "$tmpfile" + + if $DRY_RUN; then + python3 - "$file" "$tag" "$tmpfile" "$style" "dry" <<'PYEOF' +import sys, re, difflib +filepath, tag, tmpfile, style, _ = sys.argv[1:] +with open(tmpfile) as f: + new_content = f.read() +if style == 'md': + begin = f'' + end = f'' +else: + begin = f'# BEGIN GENERATED MODULES: {tag}' + end = f'# END GENERATED MODULES: {tag}' +with open(filepath) as f: + original = f.read() +pattern = re.compile(re.escape(begin) + r'\n.*?' + re.escape(end), re.DOTALL) +if not pattern.search(original): + print(f'ERROR: sentinel not found in {filepath}: {begin}', file=sys.stderr) + sys.exit(1) +replacement = begin + '\n' + new_content + end +updated = pattern.sub(lambda m: replacement, original) +if updated == original: + print(f' (no change) {filepath} [{tag}]', file=sys.stderr) + sys.exit(0) +diff = difflib.unified_diff( + original.splitlines(keepends=True), + updated.splitlines(keepends=True), + fromfile=f'{filepath}', + tofile=f'{filepath} (generated)', +) +sys.stdout.writelines(diff) +PYEOF + else + python3 - "$file" "$tag" "$tmpfile" "$style" <<'PYEOF' +import sys, re +filepath, tag, tmpfile, style = sys.argv[1:] +with open(tmpfile) as f: + new_content = f.read() +if style == 'md': + begin = f'' + end = f'' +else: + begin = f'# BEGIN GENERATED MODULES: {tag}' + end = f'# END GENERATED MODULES: {tag}' +with open(filepath) as f: + original = f.read() +pattern = re.compile(re.escape(begin) + r'\n.*?' + re.escape(end), re.DOTALL) +if not pattern.search(original): + print(f'ERROR: sentinel not found in {filepath}: {begin}', file=sys.stderr) + sys.exit(1) +replacement = begin + '\n' + new_content + end +updated = pattern.sub(lambda m: replacement, original) +if updated == original: + print(f' (no change) {filepath} [{tag}]', file=sys.stderr) + sys.exit(0) +with open(filepath, 'w') as f: + f.write(updated) +print(f' (updated) {filepath} [{tag}]', file=sys.stderr) +PYEOF + fi + rm -f "$tmpfile" +} + +# ── Apply all regions ───────────────────────────────────────────────────────── +echo "==> tui-install.sh" +splice "$TUI" "module-counters" "$gen_counters" +splice "$TUI" "module-checklist" "$gen_checklist_tui" +splice "$TUI" "module-summary" "$gen_summary" +splice "$TUI" "module-conflicts" "$gen_conflicts" +splice "$TUI" "module-dispatch" "$gen_dispatch" + +echo "==> generate-answerfile.sh" +splice "$AF" "module-checklist" "$gen_checklist_af" + +echo "==> docs/md/modules.md" +for cat in ai networking dev system gaming notes media graphics video audio browsers editors virt productivity infra; do + table=$(build_doc_table "$cat") + [[ -z "$table" ]] && continue + splice "$DOCS" "$cat" "${table}"$'\n' md +done + +echo "Done." diff --git a/setup/modules.conf b/setup/modules.conf new file mode 100644 index 0000000..cb0fe76 --- /dev/null +++ b/setup/modules.conf @@ -0,0 +1,119 @@ +# modules.conf — optional app module registry +# Format: id|category|description|default|excludes +# Run setup/sync-modules.sh to add stubs for newly created app scripts. +# Run setup/generate-modules.sh to regenerate installer + docs from this file. +# +# Categories: +# ai networking dev system gaming notes media graphics video audio +# browsers editors virt productivity infra +# +# default: on / off (pre-ticked in TUI and answerfile checklists) +# excludes: comma-separated IDs that must not run alongside this one + +# ── AI & Machine Learning ───────────────────────────────────────────────────── +ollama|ai|local LLM runner and API server|off| +llama-cpp|ai|standalone LLM inference CLI and server|off| +open-webui|ai|browser UI for Ollama and LLM backends|off| +claude|ai|Anthropic Claude Code CLI via npm|off| + +# ── Networking & Security ───────────────────────────────────────────────────── +networking-cli|networking|nmap, nethogs, mitmproxy, httpie|off| +disk-recovery|networking|ddrescue and f3 disk recovery tools|off| +himalaya|networking|terminal email client (AUR)|off| +mail-notmuch|networking|isync, msmtp, notmuch, alot mail stack|off| +caldav-sync|networking|vdirsyncer and khal CalDAV calendar sync|off| +ssh-server|networking|openssh with key-auth and systemd unit enabled|off| +wireshark|networking|network packet analyser GUI|off| +anti-malware|networking|ClamAV, rkhunter, chkrootkit|off| + +# ── Development ─────────────────────────────────────────────────────────────── +gnuplot|dev|scientific plotting tool|off| +blender-povray|dev|3D modelling and ray-tracing (Blender + POV-Ray)|off| +toot|dev|Mastodon CLI client (AUR)|off| +db-clients|dev|pgcli and mycli interactive database CLIs|off| +mysql|dev|MariaDB server with initial setup|off| +productivity|dev|taskwarrior, watson, jrnl — task management and time tracking|off| +python|dev|pyright, pipx, pynvim Python tooling|on| +k8s|dev|kubectl and podman-desktop Kubernetes tools|off| +docker|dev|docker and docker-compose|off| +podman|dev|rootless containers with buildah|off| +cockpit|dev|web UI for machines and containers|off| + +# ── System Utilities ────────────────────────────────────────────────────────── +tlp|system|laptop battery optimisation|off| +butter|system|btrfs snapshot backup manager (AUR)|off| +localsend|system|LAN file transfer, AirDrop-like (AUR)|off| +croc|system|cross-platform encrypted file transfer|off| +opendeck|system|Stream Deck controller — ydotool + OpenDeck (Flatpak)|off| +localtunnel|system|expose localhost over a public URL|off| +timeshift|system|system snapshot and backup with autosnap|off| +zfs|system|zfs-dkms kernel module|off| +wprs|system|Wayland proxy for remote sessions (wprs-git, AUR)|off| +plymouth-custom|system|boot splash with a user-supplied image|off|plymouth + +# ── Gaming ──────────────────────────────────────────────────────────────────── +steam|gaming|Steam gaming platform|off| +vesktop|gaming|Discord client with Vencord theme|off| +spotify|gaming|Spotify launcher with Spicetify theming|off| +prism|gaming|PrismLauncher Minecraft launcher (Flatpak)|off| +vintagestory|gaming|Vintage Story survival game (AUR)|off| +openarena|gaming|open-source Quake III Arena|off| +tetris|gaming|bastet and vitetris terminal Tetris|off| +doom|gaming|Chocolate Doom with Freedoom data|off| +sauerbraten|gaming|Sauerbraten open-source FPS (Cube 2)|off| +stuntrally|gaming|Stunt Rally racing game (Flatpak)|off| + +# ── Notes & Office ──────────────────────────────────────────────────────────── +onlyoffice|notes|office suite — Docs, Sheets, Slides (AUR)|on| +xournal|notes|note-taking and PDF annotator|off| +rnote|notes|handwriting and note-taking with stylus support (Flatpak)|off| +obsidian|notes|knowledge base and Markdown note-taking (Flatpak)|off| +tangent-notes|notes|networked Markdown note-taking (Flatpak)|off| + +# ── Media & Creative ────────────────────────────────────────────────────────── +ffmpeg|media|GStreamer codecs and ffmpegthumbnailer|off| +sox|media|command-line audio processing toolkit|off| +imagemagick|media|image manipulation suite|off| +yt-dlp|media|YouTube and media downloader|off| + +# ── Graphic Design ──────────────────────────────────────────────────────────── +gimp|graphics|GNU Image Manipulation Program|off| +inkscape|graphics|vector graphics editor|off| +krita|graphics|digital painting and illustration|off| + +# ── Video Editing ───────────────────────────────────────────────────────────── +kdenlive|video|KDE non-linear video editor|off| +openshot|video|cross-platform video editor|off| +shotcut|video|cross-platform video editor|off| + +# ── Audio Production ────────────────────────────────────────────────────────── +ardour|audio|professional DAW|off| +audacity|audio|multi-track audio editor|off| +lmms|audio|Linux MultiMedia Studio music production|off| +mixxx|audio|DJ mixing software|off| +cecilia|audio|audio synthesis and signal processing (AUR)|off| + +# ── Browsers ───────────────────────────────────────────────────────────────── +chromium|browsers|open-source Chromium browser (official)|off| +firefox-browser|browsers|Mozilla Firefox (official)|on| +zen-browser|browsers|privacy-focused Firefox fork (AUR)|off| +nyxt|browsers|keyboard-driven hackable browser (AUR)|off| +librewolf|browsers|hardened Firefox fork (AUR)|off| +min-browser|browsers|minimal Electron browser (AUR)|off| + +# ── IDEs & Editors ──────────────────────────────────────────────────────────── +vscodium|editors|telemetry-free VS Code build (AUR)|off| +zed-ide|editors|high-performance Rust IDE (official)|off| +geany|editors|lightweight IDE with plugins (official)|off| +codeblocks|editors|C/C++ IDE (official)|off| +kate|editors|KDE advanced text editor (official)|off| + +# ── Virtualisation & Remote Desktop ─────────────────────────────────────────── +rdp-client|virt|Remmina with FreeRDP and VNC plugins|off| +lamco-rdp-server|virt|native Wayland RDP server (AUR, Rust)|off| +qemu|virt|full QEMU/KVM stack with virt-manager|off| + +# ── Identity & Infrastructure ───────────────────────────────────────────────── +freeipa-client|infra|sssd and ipa-client-install with auto-enrollment|off| +freeipa-server|infra|interactive FreeIPA server setup with client generator|off| +freeipa-image|infra|OCI/LXC/Proxmox image builder with Keycloak|off| diff --git a/setup/modules/optional-Modules/apps/firefox.sh b/setup/modules/optional-Modules/apps/firefox-browser.sh similarity index 100% rename from setup/modules/optional-Modules/apps/firefox.sh rename to setup/modules/optional-Modules/apps/firefox-browser.sh diff --git a/setup/modules/optional-Modules/apps/freeipa-image-builder.sh b/setup/modules/optional-Modules/apps/freeipa-image.sh similarity index 100% rename from setup/modules/optional-Modules/apps/freeipa-image-builder.sh rename to setup/modules/optional-Modules/apps/freeipa-image.sh diff --git a/setup/modules/optional-Modules/apps/prismlauncher.sh b/setup/modules/optional-Modules/apps/prism.sh similarity index 100% rename from setup/modules/optional-Modules/apps/prismlauncher.sh rename to setup/modules/optional-Modules/apps/prism.sh diff --git a/setup/modules/optional-Modules/python.sh b/setup/modules/optional-Modules/apps/python.sh similarity index 100% rename from setup/modules/optional-Modules/python.sh rename to setup/modules/optional-Modules/apps/python.sh diff --git a/setup/modules/optional-Modules/wprs.sh b/setup/modules/optional-Modules/apps/wprs.sh similarity index 100% rename from setup/modules/optional-Modules/wprs.sh rename to setup/modules/optional-Modules/apps/wprs.sh diff --git a/setup/modules/optional-Modules/apps/zed.sh b/setup/modules/optional-Modules/apps/zed-ide.sh similarity index 100% rename from setup/modules/optional-Modules/apps/zed.sh rename to setup/modules/optional-Modules/apps/zed-ide.sh diff --git a/setup/modules/optional-Modules/zfs.sh b/setup/modules/optional-Modules/apps/zfs.sh similarity index 100% rename from setup/modules/optional-Modules/zfs.sh rename to setup/modules/optional-Modules/apps/zfs.sh diff --git a/setup/sync-modules.sh b/setup/sync-modules.sh new file mode 100755 index 0000000..e2cabf1 --- /dev/null +++ b/setup/sync-modules.sh @@ -0,0 +1,33 @@ +#!/bin/bash +# sync-modules.sh — scan apps/ and stub any missing entries in modules.conf +# Safe to run repeatedly; never removes or modifies existing entries. +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +CONF="$SCRIPT_DIR/modules.conf" +APPS="$SCRIPT_DIR/modules/optional-Modules/apps" + +# Read all existing IDs from modules.conf into a set. +declare -A known +while IFS='|' read -r id _rest; do + [[ "$id" =~ ^[[:space:]]*# || -z "${id// /}" ]] && continue + known["$id"]=1 +done < "$CONF" + +# Scan apps/ for .sh files not yet in modules.conf and append stubs. +added=0 +for script in "$APPS"/*.sh; do + id="${script##*/}" + id="${id%.sh}" + if [[ -z "${known[$id]+set}" ]]; then + printf '%s||||\n' "$id" >> "$CONF" + echo " [added stub] $id" + (( added++ )) || true + fi +done + +if (( added == 0 )); then + echo "modules.conf is up to date — no new stubs added." +else + echo "$added stub(s) added to modules.conf. Fill in category and description, then run generate-modules.sh." +fi diff --git a/setup/tui-install.sh b/setup/tui-install.sh index ddad2a1..a3ec3fb 100755 --- a/setup/tui-install.sh +++ b/setup/tui-install.sh @@ -162,85 +162,88 @@ count_steps() { # Optional app modules: one glob check per app, one increment per match. # Glob syntax *"tag"* matches if the space-separated SELECTED_APPS string # contains the tag anywhere — works because tags never share substrings. - [[ "$a" == *"ollama"* ]] && TOTAL=$(( TOTAL + 1 )) - [[ "$a" == *"llama-cpp"* ]] && TOTAL=$(( TOTAL + 1 )) - [[ "$a" == *"open-webui"* ]] && TOTAL=$(( TOTAL + 1 )) - [[ "$a" == *"claude"* ]] && TOTAL=$(( TOTAL + 1 )) +# BEGIN GENERATED MODULES: module-counters + [[ "$a" == *"ollama"* ]] && TOTAL=$(( TOTAL + 1 )) + [[ "$a" == *"llama-cpp"* ]] && TOTAL=$(( TOTAL + 1 )) + [[ "$a" == *"open-webui"* ]] && TOTAL=$(( TOTAL + 1 )) + [[ "$a" == *"claude"* ]] && TOTAL=$(( TOTAL + 1 )) [[ "$a" == *"networking-cli"* ]] && TOTAL=$(( TOTAL + 1 )) - [[ "$a" == *"disk-recovery"* ]] && TOTAL=$(( TOTAL + 1 )) - [[ "$a" == *"himalaya"* ]] && TOTAL=$(( TOTAL + 1 )) - [[ "$a" == *"gnuplot"* ]] && TOTAL=$(( TOTAL + 1 )) - [[ "$a" == *"blender-povray"* ]] && TOTAL=$(( TOTAL + 1 )) - [[ "$a" == *"toot"* ]] && TOTAL=$(( TOTAL + 1 )) - [[ "$a" == *"db-clients"* ]] && TOTAL=$(( TOTAL + 1 )) - [[ "$a" == *"mysql"* ]] && TOTAL=$(( TOTAL + 1 )) - [[ "$a" == *"productivity"* ]] && TOTAL=$(( TOTAL + 1 )) - [[ "$a" == *"yt-dlp"* ]] && TOTAL=$(( TOTAL + 1 )) - [[ "$a" == *"sox"* ]] && TOTAL=$(( TOTAL + 1 )) - [[ "$a" == *"imagemagick"* ]] && TOTAL=$(( TOTAL + 1 )) - [[ "$a" == *"ffmpeg"* ]] && TOTAL=$(( TOTAL + 1 )) - [[ "$a" == *"localtunnel"* ]] && TOTAL=$(( TOTAL + 1 )) - [[ "$a" == *"butter"* ]] && TOTAL=$(( TOTAL + 1 )) - [[ "$a" == *"tlp"* ]] && TOTAL=$(( TOTAL + 1 )) - [[ "$a" == *"steam"* ]] && TOTAL=$(( TOTAL + 1 )) - [[ "$a" == *"vesktop"* ]] && TOTAL=$(( TOTAL + 1 )) - [[ "$a" == *"spotify"* ]] && TOTAL=$(( TOTAL + 1 )) - [[ "$a" == *"prism"* ]] && TOTAL=$(( TOTAL + 1 )) - [[ "$a" == *"vintagestory"* ]] && TOTAL=$(( TOTAL + 1 )) - [[ "$a" == *"openarena"* ]] && TOTAL=$(( TOTAL + 1 )) - [[ "$a" == *"tetris"* ]] && TOTAL=$(( TOTAL + 1 )) - [[ "$a" == *"doom"* ]] && TOTAL=$(( TOTAL + 1 )) - [[ "$a" == *"sauerbraten"* ]] && TOTAL=$(( TOTAL + 1 )) - [[ "$a" == *"stuntrally"* ]] && TOTAL=$(( TOTAL + 1 )) - [[ "$a" == *"localsend"* ]] && TOTAL=$(( TOTAL + 1 )) - [[ "$a" == *"croc"* ]] && TOTAL=$(( TOTAL + 1 )) - [[ "$a" == *"opendeck"* ]] && TOTAL=$(( TOTAL + 1 )) - [[ "$a" == *"onlyoffice"* ]] && TOTAL=$(( TOTAL + 1 )) - [[ "$a" == *"wireshark"* ]] && TOTAL=$(( TOTAL + 1 )) - [[ "$a" == *"k8s"* ]] && TOTAL=$(( TOTAL + 1 )) - [[ "$a" == *"docker"* ]] && TOTAL=$(( TOTAL + 1 )) - [[ "$a" == *"podman"* ]] && TOTAL=$(( TOTAL + 1 )) - [[ "$a" == *"cockpit"* ]] && TOTAL=$(( TOTAL + 1 )) - [[ "$a" == *"ssh-server"* ]] && TOTAL=$(( TOTAL + 1 )) - [[ "$a" == *"freeipa-client"* ]] && TOTAL=$(( TOTAL + 1 )) - [[ "$a" == *"freeipa-server"* ]] && TOTAL=$(( TOTAL + 1 )) - [[ "$a" == *"freeipa-image"* ]] && TOTAL=$(( TOTAL + 1 )) - [[ "$a" == *"python"* ]] && TOTAL=$(( TOTAL + 1 )) - [[ "$a" == *"zfs"* ]] && TOTAL=$(( TOTAL + 1 )) - [[ "$a" == *"wprs"* ]] && TOTAL=$(( TOTAL + 1 )) - [[ "$a" == *"chromium"* ]] && TOTAL=$(( TOTAL + 1 )) + [[ "$a" == *"disk-recovery"* ]] && TOTAL=$(( TOTAL + 1 )) + [[ "$a" == *"himalaya"* ]] && TOTAL=$(( TOTAL + 1 )) + [[ "$a" == *"mail-notmuch"* ]] && TOTAL=$(( TOTAL + 1 )) + [[ "$a" == *"caldav-sync"* ]] && TOTAL=$(( TOTAL + 1 )) + [[ "$a" == *"ssh-server"* ]] && TOTAL=$(( TOTAL + 1 )) + [[ "$a" == *"wireshark"* ]] && TOTAL=$(( TOTAL + 1 )) + [[ "$a" == *"anti-malware"* ]] && TOTAL=$(( TOTAL + 1 )) + [[ "$a" == *"gnuplot"* ]] && TOTAL=$(( TOTAL + 1 )) + [[ "$a" == *"blender-povray"* ]] && TOTAL=$(( TOTAL + 1 )) + [[ "$a" == *"toot"* ]] && TOTAL=$(( TOTAL + 1 )) + [[ "$a" == *"db-clients"* ]] && TOTAL=$(( TOTAL + 1 )) + [[ "$a" == *"mysql"* ]] && TOTAL=$(( TOTAL + 1 )) + [[ "$a" == *"productivity"* ]] && TOTAL=$(( TOTAL + 1 )) + [[ "$a" == *"python"* ]] && TOTAL=$(( TOTAL + 1 )) + [[ "$a" == *"k8s"* ]] && TOTAL=$(( TOTAL + 1 )) + [[ "$a" == *"docker"* ]] && TOTAL=$(( TOTAL + 1 )) + [[ "$a" == *"podman"* ]] && TOTAL=$(( TOTAL + 1 )) + [[ "$a" == *"cockpit"* ]] && TOTAL=$(( TOTAL + 1 )) + [[ "$a" == *"tlp"* ]] && TOTAL=$(( TOTAL + 1 )) + [[ "$a" == *"butter"* ]] && TOTAL=$(( TOTAL + 1 )) + [[ "$a" == *"localsend"* ]] && TOTAL=$(( TOTAL + 1 )) + [[ "$a" == *"croc"* ]] && TOTAL=$(( TOTAL + 1 )) + [[ "$a" == *"opendeck"* ]] && TOTAL=$(( TOTAL + 1 )) + [[ "$a" == *"localtunnel"* ]] && TOTAL=$(( TOTAL + 1 )) + [[ "$a" == *"timeshift"* ]] && TOTAL=$(( TOTAL + 1 )) + [[ "$a" == *"zfs"* ]] && TOTAL=$(( TOTAL + 1 )) + [[ "$a" == *"wprs"* ]] && TOTAL=$(( TOTAL + 1 )) + [[ "$a" == *"plymouth-custom"* ]] && TOTAL=$(( TOTAL + 1 )) + [[ "$a" == *"steam"* ]] && TOTAL=$(( TOTAL + 1 )) + [[ "$a" == *"vesktop"* ]] && TOTAL=$(( TOTAL + 1 )) + [[ "$a" == *"spotify"* ]] && TOTAL=$(( TOTAL + 1 )) + [[ "$a" == *"prism"* ]] && TOTAL=$(( TOTAL + 1 )) + [[ "$a" == *"vintagestory"* ]] && TOTAL=$(( TOTAL + 1 )) + [[ "$a" == *"openarena"* ]] && TOTAL=$(( TOTAL + 1 )) + [[ "$a" == *"tetris"* ]] && TOTAL=$(( TOTAL + 1 )) + [[ "$a" == *"doom"* ]] && TOTAL=$(( TOTAL + 1 )) + [[ "$a" == *"sauerbraten"* ]] && TOTAL=$(( TOTAL + 1 )) + [[ "$a" == *"stuntrally"* ]] && TOTAL=$(( TOTAL + 1 )) + [[ "$a" == *"onlyoffice"* ]] && TOTAL=$(( TOTAL + 1 )) + [[ "$a" == *"xournal"* ]] && TOTAL=$(( TOTAL + 1 )) + [[ "$a" == *"rnote"* ]] && TOTAL=$(( TOTAL + 1 )) + [[ "$a" == *"obsidian"* ]] && TOTAL=$(( TOTAL + 1 )) + [[ "$a" == *"tangent-notes"* ]] && TOTAL=$(( TOTAL + 1 )) + [[ "$a" == *"ffmpeg"* ]] && TOTAL=$(( TOTAL + 1 )) + [[ "$a" == *"sox"* ]] && TOTAL=$(( TOTAL + 1 )) + [[ "$a" == *"imagemagick"* ]] && TOTAL=$(( TOTAL + 1 )) + [[ "$a" == *"yt-dlp"* ]] && TOTAL=$(( TOTAL + 1 )) + [[ "$a" == *"gimp"* ]] && TOTAL=$(( TOTAL + 1 )) + [[ "$a" == *"inkscape"* ]] && TOTAL=$(( TOTAL + 1 )) + [[ "$a" == *"krita"* ]] && TOTAL=$(( TOTAL + 1 )) + [[ "$a" == *"kdenlive"* ]] && TOTAL=$(( TOTAL + 1 )) + [[ "$a" == *"openshot"* ]] && TOTAL=$(( TOTAL + 1 )) + [[ "$a" == *"shotcut"* ]] && TOTAL=$(( TOTAL + 1 )) + [[ "$a" == *"ardour"* ]] && TOTAL=$(( TOTAL + 1 )) + [[ "$a" == *"audacity"* ]] && TOTAL=$(( TOTAL + 1 )) + [[ "$a" == *"lmms"* ]] && TOTAL=$(( TOTAL + 1 )) + [[ "$a" == *"mixxx"* ]] && TOTAL=$(( TOTAL + 1 )) + [[ "$a" == *"cecilia"* ]] && TOTAL=$(( TOTAL + 1 )) + [[ "$a" == *"chromium"* ]] && TOTAL=$(( TOTAL + 1 )) [[ "$a" == *"firefox-browser"* ]] && TOTAL=$(( TOTAL + 1 )) - [[ "$a" == *"zen-browser"* ]] && TOTAL=$(( TOTAL + 1 )) - [[ "$a" == *"nyxt"* ]] && TOTAL=$(( TOTAL + 1 )) - [[ "$a" == *"librewolf"* ]] && TOTAL=$(( TOTAL + 1 )) - [[ "$a" == *"min-browser"* ]] && TOTAL=$(( TOTAL + 1 )) - [[ "$a" == *"vscodium"* ]] && TOTAL=$(( TOTAL + 1 )) - [[ "$a" == *"zed-ide"* ]] && TOTAL=$(( TOTAL + 1 )) - [[ "$a" == *"geany"* ]] && TOTAL=$(( TOTAL + 1 )) - [[ "$a" == *"codeblocks"* ]] && TOTAL=$(( TOTAL + 1 )) - [[ "$a" == *"kate"* ]] && TOTAL=$(( TOTAL + 1 )) - [[ "$a" == *"rdp-client"* ]] && TOTAL=$(( TOTAL + 1 )) + [[ "$a" == *"zen-browser"* ]] && TOTAL=$(( TOTAL + 1 )) + [[ "$a" == *"nyxt"* ]] && TOTAL=$(( TOTAL + 1 )) + [[ "$a" == *"librewolf"* ]] && TOTAL=$(( TOTAL + 1 )) + [[ "$a" == *"min-browser"* ]] && TOTAL=$(( TOTAL + 1 )) + [[ "$a" == *"vscodium"* ]] && TOTAL=$(( TOTAL + 1 )) + [[ "$a" == *"zed-ide"* ]] && TOTAL=$(( TOTAL + 1 )) + [[ "$a" == *"geany"* ]] && TOTAL=$(( TOTAL + 1 )) + [[ "$a" == *"codeblocks"* ]] && TOTAL=$(( TOTAL + 1 )) + [[ "$a" == *"kate"* ]] && TOTAL=$(( TOTAL + 1 )) + [[ "$a" == *"rdp-client"* ]] && TOTAL=$(( TOTAL + 1 )) [[ "$a" == *"lamco-rdp-server"* ]] && TOTAL=$(( TOTAL + 1 )) - [[ "$a" == *"qemu"* ]] && TOTAL=$(( TOTAL + 1 )) - [[ "$a" == *"xournal"* ]] && TOTAL=$(( TOTAL + 1 )) - [[ "$a" == *"rnote"* ]] && TOTAL=$(( TOTAL + 1 )) - [[ "$a" == *"obsidian"* ]] && TOTAL=$(( TOTAL + 1 )) - [[ "$a" == *"tangent-notes"* ]] && TOTAL=$(( TOTAL + 1 )) - [[ "$a" == *"gimp"* ]] && TOTAL=$(( TOTAL + 1 )) - [[ "$a" == *"inkscape"* ]] && TOTAL=$(( TOTAL + 1 )) - [[ "$a" == *"krita"* ]] && TOTAL=$(( TOTAL + 1 )) - [[ "$a" == *"ardour"* ]] && TOTAL=$(( TOTAL + 1 )) - [[ "$a" == *"audacity"* ]] && TOTAL=$(( TOTAL + 1 )) - [[ "$a" == *"lmms"* ]] && TOTAL=$(( TOTAL + 1 )) - [[ "$a" == *"mixxx"* ]] && TOTAL=$(( TOTAL + 1 )) - [[ "$a" == *"cecilia"* ]] && TOTAL=$(( TOTAL + 1 )) - [[ "$a" == *"kdenlive"* ]] && TOTAL=$(( TOTAL + 1 )) - [[ "$a" == *"openshot"* ]] && TOTAL=$(( TOTAL + 1 )) - [[ "$a" == *"shotcut"* ]] && TOTAL=$(( TOTAL + 1 )) - [[ "$a" == *"anti-malware"* ]] && TOTAL=$(( TOTAL + 1 )) - [[ "$a" == *"timeshift"* ]] && TOTAL=$(( TOTAL + 1 )) - [[ "$a" == *"mail-notmuch"* ]] && TOTAL=$(( TOTAL + 1 )) - [[ "$a" == *"caldav-sync"* ]] && TOTAL=$(( TOTAL + 1 )) + [[ "$a" == *"qemu"* ]] && TOTAL=$(( TOTAL + 1 )) + [[ "$a" == *"freeipa-client"* ]] && TOTAL=$(( TOTAL + 1 )) + [[ "$a" == *"freeipa-server"* ]] && TOTAL=$(( TOTAL + 1 )) + [[ "$a" == *"freeipa-image"* ]] && TOTAL=$(( TOTAL + 1 )) +# END GENERATED MODULES: module-counters } # ── Answerfile ──────────────────────────────────────────────────────────────── @@ -441,94 +444,92 @@ else # prompt, buttons), with a minimum of 4 to remain usable on tiny screens. _APP_H=$(( TERM_H - 2 < 40 ? TERM_H - 2 : 40 )) _APP_LIST_H=$(( _APP_H - 8 < 4 ? 4 : _APP_H - 8 )) +# BEGIN GENERATED MODULES: module-checklist SELECTED_APPS=$(dialog --backtitle "$BACKTITLE" \ --title " Applications " \ --checklist "Optional applications — installed after base components:" "$_APP_H" 76 "$_APP_LIST_H" \ - "ollama" "Ollama local LLM runner + API server" off \ - "llama-cpp" "llama.cpp standalone inference CLI + server" off \ - "open-webui" "Open WebUI browser UI for Ollama / LLM backends" off \ - "claude" "Claude Code Anthropic CLI via npm" off \ - "networking-cli" "Networking CLI nmap · nethogs · mitmproxy · httpie" off \ - "disk-recovery" "Disk Recovery ddrescue · f3" off \ - "himalaya" "Himalaya terminal email client (AUR)" off \ - "mail-notmuch" "Mail (notmuch) isync · msmtp · notmuch · alot stack" off \ - "caldav-sync" "CalDAV Sync vdirsyncer · khal calendar sync" off \ - "gnuplot" "Gnuplot scientific plotting" off \ - "blender-povray" "Blender + POV-Ray 3D modelling & ray-tracing" off \ - "toot" "toot Mastodon CLI client (AUR)" off \ - "db-clients" "DB Clients pgcli · mycli" off \ - "mysql" "MySQL / MariaDB mariadb server + setup" off \ - "productivity" "Productivity taskwarrior · watson · jrnl" off \ - "yt-dlp" "yt-dlp YouTube / media downloader" off \ - "sox" "SoX audio processing toolkit" off \ - "imagemagick" "ImageMagick image manipulation" off \ - "ffmpeg" "FFmpeg extras thumbnailer · GStreamer codecs" off \ - "localtunnel" "LocalTunnel expose localhost via tunnel" off \ - "butter" "butter btrfs snapshot backup (AUR)" off \ - "tlp" "TLP laptop power management" off \ - "steam" "Steam gaming platform" off \ - "vesktop" "Vesktop Discord + Vencord theme" off \ - "spotify" "Spotify launcher + Spicetify theming" off \ - "prism" "PrismLauncher Minecraft launcher (Flatpak)" off \ - "vintagestory" "Vintage Story survival game (AUR)" off \ - "openarena" "OpenArena open-source Quake III Arena" off \ - "tetris" "Tetris CLI bastet · vitetris" off \ - "doom" "Doom Chocolate Doom + Freedoom data" off \ - "sauerbraten" "Sauerbraten open-source FPS (Cube 2)" off \ - "stuntrally" "Stunt Rally rally racing game (Flatpak)" off \ - "localsend" "LocalSend LAN file transfer (AUR)" off \ - "croc" "croc cross-platform file transfer" off \ - "opendeck" "OpenDeck Stream Deck controller (Flatpak+ydotool)" off \ - "onlyoffice" "OnlyOffice office suite (AUR)" off \ - "xournal" "Xournal++ note-taking & PDF annotator" off \ - "rnote" "Rnote handwriting & note-taking (Flatpak)" off \ - "obsidian" "Obsidian knowledge base & Markdown notes (Flatpak)" off \ - "tangent-notes" "Tangent Notes networked Markdown notes (Flatpak)" off \ - "gimp" "GIMP GNU image manipulation program" off \ - "inkscape" "Inkscape vector graphics editor" off \ - "krita" "Krita digital painting application" off \ - "ardour" "Ardour professional DAW" off \ - "audacity" "Audacity multi-track audio editor" off \ - "lmms" "LMMS Linux MultiMedia Studio DAW" off \ - "mixxx" "Mixxx DJ mixing software" off \ - "cecilia" "Cecilia audio signal processing (AUR)" off \ - "kdenlive" "Kdenlive KDE non-linear video editor" off \ - "openshot" "OpenShot easy video editor" off \ - "shotcut" "Shotcut cross-platform video editor" off \ - "anti-malware" "Anti-Malware ClamAV · rkhunter · chkrootkit" off \ - "timeshift" "Timeshift system snapshot / backup + autosnap" off \ - "wireshark" "Wireshark network packet analyser (GUI)" off \ - "k8s" "Kubernetes tools kubectl · podman-desktop" off \ - "docker" "Docker docker · docker-compose" off \ - "podman" "Podman rootless containers · buildah" off \ - "cockpit" "Cockpit web UI · machines · podman" off \ - "ssh-server" "SSH server openssh · key-auth · enabled" off \ - "freeipa-client" "FreeIPA Client sssd + ipa-client-install + enrollment" off \ - "freeipa-server" "FreeIPA Server interactive server setup + client gen" off \ - "freeipa-image" "FreeIPA Image OCI/LXC/Proxmox LXC builder + Keycloak" off \ - "python" "Python tools pyright · pipx · pynvim" off \ - "zfs" "ZFS zfs-dkms kernel module" off \ - "wprs" "WPRS wprs-git (AUR)" off \ - \ - "chromium" "Chromium open-source browser (official)" off \ - "firefox-browser" "Firefox Mozilla browser (official)" off \ - "zen-browser" "Zen Browser Firefox-based privacy browser (AUR)" off \ - "nyxt" "Nyxt keyboard-driven browser (AUR)" off \ - "librewolf" "LibreWolf hardened Firefox fork (AUR)" off \ - "min-browser" "Min minimal Electron browser (AUR)" off \ - \ - "vscodium" "VSCodium telemetry-free VS Code (AUR)" off \ - "zed-ide" "Zed high-performance Rust IDE (official)" off \ - "geany" "Geany lightweight IDE + plugins (official)" off \ - "codeblocks" "Code::Blocks C/C++ IDE (official)" off \ - "kate" "Kate KDE advanced text editor (official)" off \ - \ - "rdp-client" "RDP Client Remmina + FreeRDP + VNC plugins" off \ - "lamco-rdp-server" "Lamco RDP Server native Wayland RDP server (AUR, Rust)" off \ - "qemu" "QEMU/KVM full virt stack + virt-manager GUI" off \ - # Esc / Cancel yields exit code 1; treat it as "no optional apps selected" - # rather than a hard abort so the user can still install base components. + "ollama" "ollama local LLM runner and API server" off \ + "llama-cpp" "llama-cpp standalone LLM inference CLI and server" off \ + "open-webui" "open-webui browser UI for Ollama and LLM backends" off \ + "claude" "claude Anthropic Claude Code CLI via npm" off \ + "networking-cli" "networking-cli nmap, nethogs, mitmproxy, httpie" off \ + "disk-recovery" "disk-recovery ddrescue and f3 disk recovery tools" off \ + "himalaya" "himalaya terminal email client (AUR)" off \ + "mail-notmuch" "mail-notmuch isync, msmtp, notmuch, alot mail stack" off \ + "caldav-sync" "caldav-sync vdirsyncer and khal CalDAV calendar sync" off \ + "ssh-server" "ssh-server openssh with key-auth and systemd unit enabled" off \ + "wireshark" "wireshark network packet analyser GUI" off \ + "anti-malware" "anti-malware ClamAV, rkhunter, chkrootkit" off \ + "gnuplot" "gnuplot scientific plotting tool" off \ + "blender-povray" "blender-povray 3D modelling and ray-tracing (Blender + POV-Ray)" off \ + "toot" "toot Mastodon CLI client (AUR)" off \ + "db-clients" "db-clients pgcli and mycli interactive database CLIs" off \ + "mysql" "mysql MariaDB server with initial setup" off \ + "productivity" "productivity taskwarrior, watson, jrnl — task management and time tracking" off \ + "python" "python pyright, pipx, pynvim Python tooling" on \ + "k8s" "k8s kubectl and podman-desktop Kubernetes tools" off \ + "docker" "docker docker and docker-compose" off \ + "podman" "podman rootless containers with buildah" off \ + "cockpit" "cockpit web UI for machines and containers" off \ + "tlp" "tlp laptop battery optimisation" off \ + "butter" "butter btrfs snapshot backup manager (AUR)" off \ + "localsend" "localsend LAN file transfer, AirDrop-like (AUR)" off \ + "croc" "croc cross-platform encrypted file transfer" off \ + "opendeck" "opendeck Stream Deck controller — ydotool + OpenDeck (Flatpak)" off \ + "localtunnel" "localtunnel expose localhost over a public URL" off \ + "timeshift" "timeshift system snapshot and backup with autosnap" off \ + "zfs" "zfs zfs-dkms kernel module" off \ + "wprs" "wprs Wayland proxy for remote sessions (wprs-git, AUR)" off \ + "plymouth-custom" "plymouth-custom boot splash with a user-supplied image" off \ + "steam" "steam Steam gaming platform" off \ + "vesktop" "vesktop Discord client with Vencord theme" off \ + "spotify" "spotify Spotify launcher with Spicetify theming" off \ + "prism" "prism PrismLauncher Minecraft launcher (Flatpak)" off \ + "vintagestory" "vintagestory Vintage Story survival game (AUR)" off \ + "openarena" "openarena open-source Quake III Arena" off \ + "tetris" "tetris bastet and vitetris terminal Tetris" off \ + "doom" "doom Chocolate Doom with Freedoom data" off \ + "sauerbraten" "sauerbraten Sauerbraten open-source FPS (Cube 2)" off \ + "stuntrally" "stuntrally Stunt Rally racing game (Flatpak)" off \ + "onlyoffice" "onlyoffice office suite — Docs, Sheets, Slides (AUR)" on \ + "xournal" "xournal note-taking and PDF annotator" off \ + "rnote" "rnote handwriting and note-taking with stylus support (Flatpak)" off \ + "obsidian" "obsidian knowledge base and Markdown note-taking (Flatpak)" off \ + "tangent-notes" "tangent-notes networked Markdown note-taking (Flatpak)" off \ + "ffmpeg" "ffmpeg GStreamer codecs and ffmpegthumbnailer" off \ + "sox" "sox command-line audio processing toolkit" off \ + "imagemagick" "imagemagick image manipulation suite" off \ + "yt-dlp" "yt-dlp YouTube and media downloader" off \ + "gimp" "gimp GNU Image Manipulation Program" off \ + "inkscape" "inkscape vector graphics editor" off \ + "krita" "krita digital painting and illustration" off \ + "kdenlive" "kdenlive KDE non-linear video editor" off \ + "openshot" "openshot cross-platform video editor" off \ + "shotcut" "shotcut cross-platform video editor" off \ + "ardour" "ardour professional DAW" off \ + "audacity" "audacity multi-track audio editor" off \ + "lmms" "lmms Linux MultiMedia Studio music production" off \ + "mixxx" "mixxx DJ mixing software" off \ + "cecilia" "cecilia audio synthesis and signal processing (AUR)" off \ + "chromium" "chromium open-source Chromium browser (official)" off \ + "firefox-browser" "firefox-browser Mozilla Firefox (official)" on \ + "zen-browser" "zen-browser privacy-focused Firefox fork (AUR)" off \ + "nyxt" "nyxt keyboard-driven hackable browser (AUR)" off \ + "librewolf" "librewolf hardened Firefox fork (AUR)" off \ + "min-browser" "min-browser minimal Electron browser (AUR)" off \ + "vscodium" "vscodium telemetry-free VS Code build (AUR)" off \ + "zed-ide" "zed-ide high-performance Rust IDE (official)" off \ + "geany" "geany lightweight IDE with plugins (official)" off \ + "codeblocks" "codeblocks C/C++ IDE (official)" off \ + "kate" "kate KDE advanced text editor (official)" off \ + "rdp-client" "rdp-client Remmina with FreeRDP and VNC plugins" off \ + "lamco-rdp-server" "lamco-rdp-server native Wayland RDP server (AUR, Rust)" off \ + "qemu" "qemu full QEMU/KVM stack with virt-manager" off \ + "freeipa-client" "freeipa-client sssd and ipa-client-install with auto-enrollment" off \ + "freeipa-server" "freeipa-server interactive FreeIPA server setup with client generator" off \ + "freeipa-image" "freeipa-image OCI/LXC/Proxmox image builder with Keycloak" off \ 3>&1 1>&2 2>&3) || SELECTED_APPS="" +# END GENERATED MODULES: module-checklist fi # ── Shell RC preference ─────────────────────────────────────────────────────── @@ -560,83 +561,88 @@ if ! $ANSWERFILE_MODE; then if [[ -n "$SELECTED_APPS" ]]; then SUMMARY+="\n Applications:\n" - [[ "$SELECTED_APPS" == *"ollama"* ]] && SUMMARY+=" ✦ Ollama\n" - [[ "$SELECTED_APPS" == *"llama-cpp"* ]] && SUMMARY+=" ✦ llama.cpp\n" - [[ "$SELECTED_APPS" == *"open-webui"* ]] && SUMMARY+=" ✦ Open WebUI\n" - [[ "$SELECTED_APPS" == *"claude"* ]] && SUMMARY+=" ✦ Claude Code\n" - [[ "$SELECTED_APPS" == *"networking-cli"* ]] && SUMMARY+=" ✦ Networking CLI (nmap, nethogs, mitmproxy, httpie)\n" - [[ "$SELECTED_APPS" == *"disk-recovery"* ]] && SUMMARY+=" ✦ Disk Recovery (ddrescue, f3)\n" - [[ "$SELECTED_APPS" == *"himalaya"* ]] && SUMMARY+=" ✦ Himalaya\n" - [[ "$SELECTED_APPS" == *"gnuplot"* ]] && SUMMARY+=" ✦ Gnuplot\n" - [[ "$SELECTED_APPS" == *"blender-povray"* ]] && SUMMARY+=" ✦ Blender + POV-Ray\n" - [[ "$SELECTED_APPS" == *"toot"* ]] && SUMMARY+=" ✦ toot\n" - [[ "$SELECTED_APPS" == *"db-clients"* ]] && SUMMARY+=" ✦ DB Clients (pgcli, mycli)\n" - [[ "$SELECTED_APPS" == *"mysql"* ]] && SUMMARY+=" ✦ MySQL / MariaDB\n" - [[ "$SELECTED_APPS" == *"productivity"* ]] && SUMMARY+=" ✦ Productivity (taskwarrior, watson, jrnl)\n" - [[ "$SELECTED_APPS" == *"yt-dlp"* ]] && SUMMARY+=" ✦ yt-dlp\n" - [[ "$SELECTED_APPS" == *"sox"* ]] && SUMMARY+=" ✦ SoX\n" - [[ "$SELECTED_APPS" == *"imagemagick"* ]] && SUMMARY+=" ✦ ImageMagick\n" - [[ "$SELECTED_APPS" == *"ffmpeg"* ]] && SUMMARY+=" ✦ FFmpeg extras\n" - [[ "$SELECTED_APPS" == *"localtunnel"* ]] && SUMMARY+=" ✦ LocalTunnel\n" - [[ "$SELECTED_APPS" == *"butter"* ]] && SUMMARY+=" ✦ butter (btrfs backup)\n" - [[ "$SELECTED_APPS" == *"tlp"* ]] && SUMMARY+=" ✦ TLP\n" - [[ "$SELECTED_APPS" == *"steam"* ]] && SUMMARY+=" ✦ Steam\n" - [[ "$SELECTED_APPS" == *"vesktop"* ]] && SUMMARY+=" ✦ Vesktop + Vencord theme\n" - [[ "$SELECTED_APPS" == *"spotify"* ]] && SUMMARY+=" ✦ Spotify + Spicetify\n" - [[ "$SELECTED_APPS" == *"prism"* ]] && SUMMARY+=" ✦ PrismLauncher\n" - [[ "$SELECTED_APPS" == *"vintagestory"* ]] && SUMMARY+=" ✦ Vintage Story\n" - [[ "$SELECTED_APPS" == *"openarena"* ]] && SUMMARY+=" ✦ OpenArena\n" - [[ "$SELECTED_APPS" == *"tetris"* ]] && SUMMARY+=" ✦ Tetris CLI (bastet · vitetris)\n" - [[ "$SELECTED_APPS" == *"doom"* ]] && SUMMARY+=" ✦ Doom\n" - [[ "$SELECTED_APPS" == *"sauerbraten"* ]] && SUMMARY+=" ✦ Sauerbraten\n" - [[ "$SELECTED_APPS" == *"stuntrally"* ]] && SUMMARY+=" ✦ Stunt Rally\n" - [[ "$SELECTED_APPS" == *"localsend"* ]] && SUMMARY+=" ✦ LocalSend\n" - [[ "$SELECTED_APPS" == *"croc"* ]] && SUMMARY+=" ✦ croc\n" - [[ "$SELECTED_APPS" == *"opendeck"* ]] && SUMMARY+=" ✦ OpenDeck + ydotool\n" - [[ "$SELECTED_APPS" == *"onlyoffice"* ]] && SUMMARY+=" ✦ OnlyOffice\n" - [[ "$SELECTED_APPS" == *"xournal"* ]] && SUMMARY+=" ✦ Xournal++\n" - [[ "$SELECTED_APPS" == *"rnote"* ]] && SUMMARY+=" ✦ Rnote\n" - [[ "$SELECTED_APPS" == *"obsidian"* ]] && SUMMARY+=" ✦ Obsidian\n" - [[ "$SELECTED_APPS" == *"tangent-notes"* ]] && SUMMARY+=" ✦ Tangent Notes\n" - [[ "$SELECTED_APPS" == *"gimp"* ]] && SUMMARY+=" ✦ GIMP\n" - [[ "$SELECTED_APPS" == *"inkscape"* ]] && SUMMARY+=" ✦ Inkscape\n" - [[ "$SELECTED_APPS" == *"krita"* ]] && SUMMARY+=" ✦ Krita\n" - [[ "$SELECTED_APPS" == *"ardour"* ]] && SUMMARY+=" ✦ Ardour\n" - [[ "$SELECTED_APPS" == *"audacity"* ]] && SUMMARY+=" ✦ Audacity\n" - [[ "$SELECTED_APPS" == *"lmms"* ]] && SUMMARY+=" ✦ LMMS\n" - [[ "$SELECTED_APPS" == *"mixxx"* ]] && SUMMARY+=" ✦ Mixxx\n" - [[ "$SELECTED_APPS" == *"cecilia"* ]] && SUMMARY+=" ✦ Cecilia\n" - [[ "$SELECTED_APPS" == *"kdenlive"* ]] && SUMMARY+=" ✦ Kdenlive\n" - [[ "$SELECTED_APPS" == *"openshot"* ]] && SUMMARY+=" ✦ OpenShot\n" - [[ "$SELECTED_APPS" == *"shotcut"* ]] && SUMMARY+=" ✦ Shotcut\n" - [[ "$SELECTED_APPS" == *"anti-malware"* ]] && SUMMARY+=" ✦ Anti-Malware (ClamAV, rkhunter, chkrootkit)\n" - [[ "$SELECTED_APPS" == *"timeshift"* ]] && SUMMARY+=" ✦ Timeshift\n" - [[ "$SELECTED_APPS" == *"wireshark"* ]] && SUMMARY+=" ✦ Wireshark\n" - [[ "$SELECTED_APPS" == *"k8s"* ]] && SUMMARY+=" ✦ Kubernetes tools\n" - [[ "$SELECTED_APPS" == *"docker"* ]] && SUMMARY+=" ✦ Docker + Compose\n" - [[ "$SELECTED_APPS" == *"podman"* ]] && SUMMARY+=" ✦ Podman (rootless) + Buildah\n" - [[ "$SELECTED_APPS" == *"cockpit"* ]] && SUMMARY+=" ✦ Cockpit web UI\n" - [[ "$SELECTED_APPS" == *"ssh-server"* ]] && SUMMARY+=" ✦ SSH server (openssh, key auth)\n" - [[ "$SELECTED_APPS" == *"freeipa-client"* ]] && SUMMARY+=" ✦ FreeIPA Client\n" - [[ "$SELECTED_APPS" == *"freeipa-server"* ]] && SUMMARY+=" ✦ FreeIPA Server\n" - [[ "$SELECTED_APPS" == *"freeipa-image"* ]] && SUMMARY+=" ✦ FreeIPA Image Builder\n" - [[ "$SELECTED_APPS" == *"python"* ]] && SUMMARY+=" ✦ Python tools\n" - [[ "$SELECTED_APPS" == *"zfs"* ]] && SUMMARY+=" ✦ ZFS\n" - [[ "$SELECTED_APPS" == *"wprs"* ]] && SUMMARY+=" ✦ WPRS\n" - [[ "$SELECTED_APPS" == *"chromium"* ]] && SUMMARY+=" ✦ Chromium\n" - [[ "$SELECTED_APPS" == *"firefox-browser"* ]] && SUMMARY+=" ✦ Firefox\n" - [[ "$SELECTED_APPS" == *"zen-browser"* ]] && SUMMARY+=" ✦ Zen Browser\n" - [[ "$SELECTED_APPS" == *"nyxt"* ]] && SUMMARY+=" ✦ Nyxt\n" - [[ "$SELECTED_APPS" == *"librewolf"* ]] && SUMMARY+=" ✦ LibreWolf\n" - [[ "$SELECTED_APPS" == *"min-browser"* ]] && SUMMARY+=" ✦ Min Browser\n" - [[ "$SELECTED_APPS" == *"vscodium"* ]] && SUMMARY+=" ✦ VSCodium\n" - [[ "$SELECTED_APPS" == *"zed-ide"* ]] && SUMMARY+=" ✦ Zed IDE\n" - [[ "$SELECTED_APPS" == *"geany"* ]] && SUMMARY+=" ✦ Geany\n" - [[ "$SELECTED_APPS" == *"codeblocks"* ]] && SUMMARY+=" ✦ Code::Blocks\n" - [[ "$SELECTED_APPS" == *"kate"* ]] && SUMMARY+=" ✦ Kate\n" - [[ "$SELECTED_APPS" == *"rdp-client"* ]] && SUMMARY+=" ✦ RDP Client (Remmina + FreeRDP)\n" - [[ "$SELECTED_APPS" == *"lamco-rdp-server"* ]] && SUMMARY+=" ✦ Lamco RDP Server (native Wayland)\n" - [[ "$SELECTED_APPS" == *"qemu"* ]] && SUMMARY+=" ✦ QEMU/KVM + virt-manager\n" +# BEGIN GENERATED MODULES: module-summary + [[ "$SELECTED_APPS" == *"ollama"* ]] && SUMMARY+=" ✦ ollama\n" + [[ "$SELECTED_APPS" == *"llama-cpp"* ]] && SUMMARY+=" ✦ llama-cpp\n" + [[ "$SELECTED_APPS" == *"open-webui"* ]] && SUMMARY+=" ✦ open-webui\n" + [[ "$SELECTED_APPS" == *"claude"* ]] && SUMMARY+=" ✦ claude\n" + [[ "$SELECTED_APPS" == *"networking-cli"* ]] && SUMMARY+=" ✦ networking-cli\n" + [[ "$SELECTED_APPS" == *"disk-recovery"* ]] && SUMMARY+=" ✦ disk-recovery\n" + [[ "$SELECTED_APPS" == *"himalaya"* ]] && SUMMARY+=" ✦ himalaya\n" + [[ "$SELECTED_APPS" == *"mail-notmuch"* ]] && SUMMARY+=" ✦ mail-notmuch\n" + [[ "$SELECTED_APPS" == *"caldav-sync"* ]] && SUMMARY+=" ✦ caldav-sync\n" + [[ "$SELECTED_APPS" == *"ssh-server"* ]] && SUMMARY+=" ✦ ssh-server\n" + [[ "$SELECTED_APPS" == *"wireshark"* ]] && SUMMARY+=" ✦ wireshark\n" + [[ "$SELECTED_APPS" == *"anti-malware"* ]] && SUMMARY+=" ✦ anti-malware\n" + [[ "$SELECTED_APPS" == *"gnuplot"* ]] && SUMMARY+=" ✦ gnuplot\n" + [[ "$SELECTED_APPS" == *"blender-povray"* ]] && SUMMARY+=" ✦ blender-povray\n" + [[ "$SELECTED_APPS" == *"toot"* ]] && SUMMARY+=" ✦ toot\n" + [[ "$SELECTED_APPS" == *"db-clients"* ]] && SUMMARY+=" ✦ db-clients\n" + [[ "$SELECTED_APPS" == *"mysql"* ]] && SUMMARY+=" ✦ mysql\n" + [[ "$SELECTED_APPS" == *"productivity"* ]] && SUMMARY+=" ✦ productivity\n" + [[ "$SELECTED_APPS" == *"python"* ]] && SUMMARY+=" ✦ python\n" + [[ "$SELECTED_APPS" == *"k8s"* ]] && SUMMARY+=" ✦ k8s\n" + [[ "$SELECTED_APPS" == *"docker"* ]] && SUMMARY+=" ✦ docker\n" + [[ "$SELECTED_APPS" == *"podman"* ]] && SUMMARY+=" ✦ podman\n" + [[ "$SELECTED_APPS" == *"cockpit"* ]] && SUMMARY+=" ✦ cockpit\n" + [[ "$SELECTED_APPS" == *"tlp"* ]] && SUMMARY+=" ✦ tlp\n" + [[ "$SELECTED_APPS" == *"butter"* ]] && SUMMARY+=" ✦ butter\n" + [[ "$SELECTED_APPS" == *"localsend"* ]] && SUMMARY+=" ✦ localsend\n" + [[ "$SELECTED_APPS" == *"croc"* ]] && SUMMARY+=" ✦ croc\n" + [[ "$SELECTED_APPS" == *"opendeck"* ]] && SUMMARY+=" ✦ opendeck\n" + [[ "$SELECTED_APPS" == *"localtunnel"* ]] && SUMMARY+=" ✦ localtunnel\n" + [[ "$SELECTED_APPS" == *"timeshift"* ]] && SUMMARY+=" ✦ timeshift\n" + [[ "$SELECTED_APPS" == *"zfs"* ]] && SUMMARY+=" ✦ zfs\n" + [[ "$SELECTED_APPS" == *"wprs"* ]] && SUMMARY+=" ✦ wprs\n" + [[ "$SELECTED_APPS" == *"plymouth-custom"* ]] && SUMMARY+=" ✦ plymouth-custom\n" + [[ "$SELECTED_APPS" == *"steam"* ]] && SUMMARY+=" ✦ steam\n" + [[ "$SELECTED_APPS" == *"vesktop"* ]] && SUMMARY+=" ✦ vesktop\n" + [[ "$SELECTED_APPS" == *"spotify"* ]] && SUMMARY+=" ✦ spotify\n" + [[ "$SELECTED_APPS" == *"prism"* ]] && SUMMARY+=" ✦ prism\n" + [[ "$SELECTED_APPS" == *"vintagestory"* ]] && SUMMARY+=" ✦ vintagestory\n" + [[ "$SELECTED_APPS" == *"openarena"* ]] && SUMMARY+=" ✦ openarena\n" + [[ "$SELECTED_APPS" == *"tetris"* ]] && SUMMARY+=" ✦ tetris\n" + [[ "$SELECTED_APPS" == *"doom"* ]] && SUMMARY+=" ✦ doom\n" + [[ "$SELECTED_APPS" == *"sauerbraten"* ]] && SUMMARY+=" ✦ sauerbraten\n" + [[ "$SELECTED_APPS" == *"stuntrally"* ]] && SUMMARY+=" ✦ stuntrally\n" + [[ "$SELECTED_APPS" == *"onlyoffice"* ]] && SUMMARY+=" ✦ onlyoffice\n" + [[ "$SELECTED_APPS" == *"xournal"* ]] && SUMMARY+=" ✦ xournal\n" + [[ "$SELECTED_APPS" == *"rnote"* ]] && SUMMARY+=" ✦ rnote\n" + [[ "$SELECTED_APPS" == *"obsidian"* ]] && SUMMARY+=" ✦ obsidian\n" + [[ "$SELECTED_APPS" == *"tangent-notes"* ]] && SUMMARY+=" ✦ tangent-notes\n" + [[ "$SELECTED_APPS" == *"ffmpeg"* ]] && SUMMARY+=" ✦ ffmpeg\n" + [[ "$SELECTED_APPS" == *"sox"* ]] && SUMMARY+=" ✦ sox\n" + [[ "$SELECTED_APPS" == *"imagemagick"* ]] && SUMMARY+=" ✦ imagemagick\n" + [[ "$SELECTED_APPS" == *"yt-dlp"* ]] && SUMMARY+=" ✦ yt-dlp\n" + [[ "$SELECTED_APPS" == *"gimp"* ]] && SUMMARY+=" ✦ gimp\n" + [[ "$SELECTED_APPS" == *"inkscape"* ]] && SUMMARY+=" ✦ inkscape\n" + [[ "$SELECTED_APPS" == *"krita"* ]] && SUMMARY+=" ✦ krita\n" + [[ "$SELECTED_APPS" == *"kdenlive"* ]] && SUMMARY+=" ✦ kdenlive\n" + [[ "$SELECTED_APPS" == *"openshot"* ]] && SUMMARY+=" ✦ openshot\n" + [[ "$SELECTED_APPS" == *"shotcut"* ]] && SUMMARY+=" ✦ shotcut\n" + [[ "$SELECTED_APPS" == *"ardour"* ]] && SUMMARY+=" ✦ ardour\n" + [[ "$SELECTED_APPS" == *"audacity"* ]] && SUMMARY+=" ✦ audacity\n" + [[ "$SELECTED_APPS" == *"lmms"* ]] && SUMMARY+=" ✦ lmms\n" + [[ "$SELECTED_APPS" == *"mixxx"* ]] && SUMMARY+=" ✦ mixxx\n" + [[ "$SELECTED_APPS" == *"cecilia"* ]] && SUMMARY+=" ✦ cecilia\n" + [[ "$SELECTED_APPS" == *"chromium"* ]] && SUMMARY+=" ✦ chromium\n" + [[ "$SELECTED_APPS" == *"firefox-browser"* ]] && SUMMARY+=" ✦ firefox-browser\n" + [[ "$SELECTED_APPS" == *"zen-browser"* ]] && SUMMARY+=" ✦ zen-browser\n" + [[ "$SELECTED_APPS" == *"nyxt"* ]] && SUMMARY+=" ✦ nyxt\n" + [[ "$SELECTED_APPS" == *"librewolf"* ]] && SUMMARY+=" ✦ librewolf\n" + [[ "$SELECTED_APPS" == *"min-browser"* ]] && SUMMARY+=" ✦ min-browser\n" + [[ "$SELECTED_APPS" == *"vscodium"* ]] && SUMMARY+=" ✦ vscodium\n" + [[ "$SELECTED_APPS" == *"zed-ide"* ]] && SUMMARY+=" ✦ zed-ide\n" + [[ "$SELECTED_APPS" == *"geany"* ]] && SUMMARY+=" ✦ geany\n" + [[ "$SELECTED_APPS" == *"codeblocks"* ]] && SUMMARY+=" ✦ codeblocks\n" + [[ "$SELECTED_APPS" == *"kate"* ]] && SUMMARY+=" ✦ kate\n" + [[ "$SELECTED_APPS" == *"rdp-client"* ]] && SUMMARY+=" ✦ rdp-client\n" + [[ "$SELECTED_APPS" == *"lamco-rdp-server"* ]] && SUMMARY+=" ✦ lamco-rdp-server\n" + [[ "$SELECTED_APPS" == *"qemu"* ]] && SUMMARY+=" ✦ qemu\n" + [[ "$SELECTED_APPS" == *"freeipa-client"* ]] && SUMMARY+=" ✦ freeipa-client\n" + [[ "$SELECTED_APPS" == *"freeipa-server"* ]] && SUMMARY+=" ✦ freeipa-server\n" + [[ "$SELECTED_APPS" == *"freeipa-image"* ]] && SUMMARY+=" ✦ freeipa-image\n" +# END GENERATED MODULES: module-summary fi # Size the confirmation dialog to the terminal, capped at 24 rows. @@ -680,85 +686,94 @@ fi # Same guard pattern as base components. Each line is independent; a missing # module script will be caught by run_module()'s error handling rather than # silently skipped — 'bash "$script"' will exit non-zero if the file is absent. -[[ "$SELECTED_APPS" == *"ollama"* ]] && run_module "Ollama" "$APPS/ollama.sh" -[[ "$SELECTED_APPS" == *"llama-cpp"* ]] && run_module "llama.cpp" "$APPS/llama-cpp.sh" -[[ "$SELECTED_APPS" == *"open-webui"* ]] && run_module "Open WebUI" "$APPS/open-webui.sh" -[[ "$SELECTED_APPS" == *"claude"* ]] && run_module "Claude Code" "$APPS/claude.sh" -[[ "$SELECTED_APPS" == *"networking-cli"* ]] && run_module "Networking CLI" "$APPS/networking-cli.sh" -[[ "$SELECTED_APPS" == *"disk-recovery"* ]] && run_module "Disk Recovery" "$APPS/disk-recovery.sh" -[[ "$SELECTED_APPS" == *"himalaya"* ]] && run_module "Himalaya" "$APPS/himalaya.sh" -[[ "$SELECTED_APPS" == *"mail-notmuch"* ]] && run_module "Mail (notmuch)" "$APPS/mail-notmuch.sh" -[[ "$SELECTED_APPS" == *"caldav-sync"* ]] && run_module "CalDAV Sync" "$APPS/caldav-sync.sh" -[[ "$SELECTED_APPS" == *"gnuplot"* ]] && run_module "Gnuplot" "$APPS/gnuplot.sh" -[[ "$SELECTED_APPS" == *"blender-povray"* ]] && run_module "Blender + POV-Ray" "$APPS/blender-povray.sh" -[[ "$SELECTED_APPS" == *"toot"* ]] && run_module "toot" "$APPS/toot.sh" -[[ "$SELECTED_APPS" == *"db-clients"* ]] && run_module "DB Clients" "$APPS/db-clients.sh" -[[ "$SELECTED_APPS" == *"mysql"* ]] && run_module "MySQL / MariaDB" "$APPS/mysql.sh" -[[ "$SELECTED_APPS" == *"productivity"* ]] && run_module "Productivity" "$APPS/productivity.sh" -[[ "$SELECTED_APPS" == *"yt-dlp"* ]] && run_module "yt-dlp" "$APPS/yt-dlp.sh" -[[ "$SELECTED_APPS" == *"sox"* ]] && run_module "SoX" "$APPS/sox.sh" -[[ "$SELECTED_APPS" == *"imagemagick"* ]] && run_module "ImageMagick" "$APPS/imagemagick.sh" -[[ "$SELECTED_APPS" == *"ffmpeg"* ]] && run_module "FFmpeg extras" "$APPS/ffmpeg.sh" -[[ "$SELECTED_APPS" == *"localtunnel"* ]] && run_module "LocalTunnel" "$APPS/localtunnel.sh" -[[ "$SELECTED_APPS" == *"butter"* ]] && run_module "butter" "$APPS/butter.sh" -[[ "$SELECTED_APPS" == *"tlp"* ]] && run_module "TLP" "$APPS/tlp.sh" -[[ "$SELECTED_APPS" == *"steam"* ]] && run_module "Steam" "$APPS/steam.sh" -[[ "$SELECTED_APPS" == *"vesktop"* ]] && run_module "Vesktop" "$APPS/vesktop.sh" -[[ "$SELECTED_APPS" == *"spotify"* ]] && run_module "Spotify" "$APPS/spotify.sh" -[[ "$SELECTED_APPS" == *"prism"* ]] && run_module "PrismLauncher" "$APPS/prismlauncher.sh" -[[ "$SELECTED_APPS" == *"vintagestory"* ]] && run_module "Vintage Story" "$APPS/vintagestory.sh" -[[ "$SELECTED_APPS" == *"openarena"* ]] && run_module "OpenArena" "$APPS/openarena.sh" -[[ "$SELECTED_APPS" == *"tetris"* ]] && run_module "Tetris CLI" "$APPS/tetris.sh" -[[ "$SELECTED_APPS" == *"doom"* ]] && run_module "Doom" "$APPS/doom.sh" -[[ "$SELECTED_APPS" == *"sauerbraten"* ]] && run_module "Sauerbraten" "$APPS/sauerbraten.sh" -[[ "$SELECTED_APPS" == *"stuntrally"* ]] && run_module "Stunt Rally" "$APPS/stuntrally.sh" -[[ "$SELECTED_APPS" == *"localsend"* ]] && run_module "LocalSend" "$APPS/localsend.sh" -[[ "$SELECTED_APPS" == *"croc"* ]] && run_module "croc" "$APPS/croc.sh" -[[ "$SELECTED_APPS" == *"opendeck"* ]] && run_module "OpenDeck" "$APPS/opendeck.sh" -[[ "$SELECTED_APPS" == *"onlyoffice"* ]] && run_module "OnlyOffice" "$APPS/onlyoffice.sh" -[[ "$SELECTED_APPS" == *"xournal"* ]] && run_module "Xournal++" "$APPS/xournal.sh" -[[ "$SELECTED_APPS" == *"rnote"* ]] && run_module "Rnote" "$APPS/rnote.sh" -[[ "$SELECTED_APPS" == *"obsidian"* ]] && run_module "Obsidian" "$APPS/obsidian.sh" -[[ "$SELECTED_APPS" == *"tangent-notes"* ]] && run_module "Tangent Notes" "$APPS/tangent-notes.sh" -[[ "$SELECTED_APPS" == *"gimp"* ]] && run_module "GIMP" "$APPS/gimp.sh" -[[ "$SELECTED_APPS" == *"inkscape"* ]] && run_module "Inkscape" "$APPS/inkscape.sh" -[[ "$SELECTED_APPS" == *"krita"* ]] && run_module "Krita" "$APPS/krita.sh" -[[ "$SELECTED_APPS" == *"ardour"* ]] && run_module "Ardour" "$APPS/ardour.sh" -[[ "$SELECTED_APPS" == *"audacity"* ]] && run_module "Audacity" "$APPS/audacity.sh" -[[ "$SELECTED_APPS" == *"lmms"* ]] && run_module "LMMS" "$APPS/lmms.sh" -[[ "$SELECTED_APPS" == *"mixxx"* ]] && run_module "Mixxx" "$APPS/mixxx.sh" -[[ "$SELECTED_APPS" == *"cecilia"* ]] && run_module "Cecilia" "$APPS/cecilia.sh" -[[ "$SELECTED_APPS" == *"kdenlive"* ]] && run_module "Kdenlive" "$APPS/kdenlive.sh" -[[ "$SELECTED_APPS" == *"openshot"* ]] && run_module "OpenShot" "$APPS/openshot.sh" -[[ "$SELECTED_APPS" == *"shotcut"* ]] && run_module "Shotcut" "$APPS/shotcut.sh" -[[ "$SELECTED_APPS" == *"anti-malware"* ]] && run_module "Anti-Malware" "$APPS/anti-malware.sh" -[[ "$SELECTED_APPS" == *"timeshift"* ]] && run_module "Timeshift" "$APPS/timeshift.sh" -[[ "$SELECTED_APPS" == *"wireshark"* ]] && run_module "Wireshark" "$APPS/wireshark.sh" -[[ "$SELECTED_APPS" == *"k8s"* ]] && run_module "Kubernetes Tools" "$APPS/k8s.sh" -[[ "$SELECTED_APPS" == *"docker"* ]] && run_module "Docker" "$APPS/docker.sh" -[[ "$SELECTED_APPS" == *"podman"* ]] && run_module "Podman" "$APPS/podman.sh" -[[ "$SELECTED_APPS" == *"cockpit"* ]] && run_module "Cockpit" "$APPS/cockpit.sh" -[[ "$SELECTED_APPS" == *"ssh-server"* ]] && run_module "SSH Server" "$APPS/ssh-server.sh" -[[ "$SELECTED_APPS" == *"freeipa-client"* ]] && run_module "FreeIPA Client" "$APPS/freeipa-client.sh" -[[ "$SELECTED_APPS" == *"freeipa-server"* ]] && run_module "FreeIPA Server" "$APPS/freeipa-server.sh" -[[ "$SELECTED_APPS" == *"freeipa-image"* ]] && run_module "FreeIPA Image" "$APPS/freeipa-image-builder.sh" -[[ "$SELECTED_APPS" == *"python"* ]] && run_module "Python Tools" "$MODULES/optional-Modules/python.sh" -[[ "$SELECTED_APPS" == *"zfs"* ]] && run_module "ZFS" "$MODULES/optional-Modules/zfs.sh" -[[ "$SELECTED_APPS" == *"wprs"* ]] && run_module "WPRS" "$MODULES/optional-Modules/wprs.sh" -[[ "$SELECTED_APPS" == *"chromium"* ]] && run_module "Chromium" "$APPS/chromium.sh" -[[ "$SELECTED_APPS" == *"firefox-browser"* ]] && run_module "Firefox" "$APPS/firefox.sh" -[[ "$SELECTED_APPS" == *"zen-browser"* ]] && run_module "Zen Browser" "$APPS/zen-browser.sh" -[[ "$SELECTED_APPS" == *"nyxt"* ]] && run_module "Nyxt" "$APPS/nyxt.sh" -[[ "$SELECTED_APPS" == *"librewolf"* ]] && run_module "LibreWolf" "$APPS/librewolf.sh" -[[ "$SELECTED_APPS" == *"min-browser"* ]] && run_module "Min Browser" "$APPS/min-browser.sh" -[[ "$SELECTED_APPS" == *"vscodium"* ]] && run_module "VSCodium" "$APPS/vscodium.sh" -[[ "$SELECTED_APPS" == *"zed-ide"* ]] && run_module "Zed IDE" "$APPS/zed.sh" -[[ "$SELECTED_APPS" == *"geany"* ]] && run_module "Geany" "$APPS/geany.sh" -[[ "$SELECTED_APPS" == *"codeblocks"* ]] && run_module "Code::Blocks" "$APPS/codeblocks.sh" -[[ "$SELECTED_APPS" == *"kate"* ]] && run_module "Kate" "$APPS/kate.sh" -[[ "$SELECTED_APPS" == *"rdp-client"* ]] && run_module "RDP Client" "$APPS/rdp-client.sh" -[[ "$SELECTED_APPS" == *"lamco-rdp-server"* ]] && run_module "Lamco RDP Server" "$APPS/lamco-rdp-server.sh" -[[ "$SELECTED_APPS" == *"qemu"* ]] && run_module "QEMU/KVM" "$APPS/qemu.sh" +# BEGIN GENERATED MODULES: module-conflicts +if [[ "$SELECTED_APPS" == *"plymouth-custom"* && "$SELECTED_APPS" == *"plymouth"* ]]; then + warn "plymouth-custom and plymouth are mutually exclusive — skipping plymouth" + SELECTED_APPS="${SELECTED_APPS/plymouth/}" +fi +# END GENERATED MODULES: module-conflicts +# BEGIN GENERATED MODULES: module-dispatch +[[ "$SELECTED_APPS" == *"ollama"* ]] && run_module "ollama" "$APPS/ollama.sh" +[[ "$SELECTED_APPS" == *"llama-cpp"* ]] && run_module "llama-cpp" "$APPS/llama-cpp.sh" +[[ "$SELECTED_APPS" == *"open-webui"* ]] && run_module "open-webui" "$APPS/open-webui.sh" +[[ "$SELECTED_APPS" == *"claude"* ]] && run_module "claude" "$APPS/claude.sh" +[[ "$SELECTED_APPS" == *"networking-cli"* ]] && run_module "networking-cli" "$APPS/networking-cli.sh" +[[ "$SELECTED_APPS" == *"disk-recovery"* ]] && run_module "disk-recovery" "$APPS/disk-recovery.sh" +[[ "$SELECTED_APPS" == *"himalaya"* ]] && run_module "himalaya" "$APPS/himalaya.sh" +[[ "$SELECTED_APPS" == *"mail-notmuch"* ]] && run_module "mail-notmuch" "$APPS/mail-notmuch.sh" +[[ "$SELECTED_APPS" == *"caldav-sync"* ]] && run_module "caldav-sync" "$APPS/caldav-sync.sh" +[[ "$SELECTED_APPS" == *"ssh-server"* ]] && run_module "ssh-server" "$APPS/ssh-server.sh" +[[ "$SELECTED_APPS" == *"wireshark"* ]] && run_module "wireshark" "$APPS/wireshark.sh" +[[ "$SELECTED_APPS" == *"anti-malware"* ]] && run_module "anti-malware" "$APPS/anti-malware.sh" +[[ "$SELECTED_APPS" == *"gnuplot"* ]] && run_module "gnuplot" "$APPS/gnuplot.sh" +[[ "$SELECTED_APPS" == *"blender-povray"* ]] && run_module "blender-povray" "$APPS/blender-povray.sh" +[[ "$SELECTED_APPS" == *"toot"* ]] && run_module "toot" "$APPS/toot.sh" +[[ "$SELECTED_APPS" == *"db-clients"* ]] && run_module "db-clients" "$APPS/db-clients.sh" +[[ "$SELECTED_APPS" == *"mysql"* ]] && run_module "mysql" "$APPS/mysql.sh" +[[ "$SELECTED_APPS" == *"productivity"* ]] && run_module "productivity" "$APPS/productivity.sh" +[[ "$SELECTED_APPS" == *"python"* ]] && run_module "python" "$APPS/python.sh" +[[ "$SELECTED_APPS" == *"k8s"* ]] && run_module "k8s" "$APPS/k8s.sh" +[[ "$SELECTED_APPS" == *"docker"* ]] && run_module "docker" "$APPS/docker.sh" +[[ "$SELECTED_APPS" == *"podman"* ]] && run_module "podman" "$APPS/podman.sh" +[[ "$SELECTED_APPS" == *"cockpit"* ]] && run_module "cockpit" "$APPS/cockpit.sh" +[[ "$SELECTED_APPS" == *"tlp"* ]] && run_module "tlp" "$APPS/tlp.sh" +[[ "$SELECTED_APPS" == *"butter"* ]] && run_module "butter" "$APPS/butter.sh" +[[ "$SELECTED_APPS" == *"localsend"* ]] && run_module "localsend" "$APPS/localsend.sh" +[[ "$SELECTED_APPS" == *"croc"* ]] && run_module "croc" "$APPS/croc.sh" +[[ "$SELECTED_APPS" == *"opendeck"* ]] && run_module "opendeck" "$APPS/opendeck.sh" +[[ "$SELECTED_APPS" == *"localtunnel"* ]] && run_module "localtunnel" "$APPS/localtunnel.sh" +[[ "$SELECTED_APPS" == *"timeshift"* ]] && run_module "timeshift" "$APPS/timeshift.sh" +[[ "$SELECTED_APPS" == *"zfs"* ]] && run_module "zfs" "$APPS/zfs.sh" +[[ "$SELECTED_APPS" == *"wprs"* ]] && run_module "wprs" "$APPS/wprs.sh" +[[ "$SELECTED_APPS" == *"plymouth-custom"* ]] && run_module "plymouth-custom" "$APPS/plymouth-custom.sh" +[[ "$SELECTED_APPS" == *"steam"* ]] && run_module "steam" "$APPS/steam.sh" +[[ "$SELECTED_APPS" == *"vesktop"* ]] && run_module "vesktop" "$APPS/vesktop.sh" +[[ "$SELECTED_APPS" == *"spotify"* ]] && run_module "spotify" "$APPS/spotify.sh" +[[ "$SELECTED_APPS" == *"prism"* ]] && run_module "prism" "$APPS/prism.sh" +[[ "$SELECTED_APPS" == *"vintagestory"* ]] && run_module "vintagestory" "$APPS/vintagestory.sh" +[[ "$SELECTED_APPS" == *"openarena"* ]] && run_module "openarena" "$APPS/openarena.sh" +[[ "$SELECTED_APPS" == *"tetris"* ]] && run_module "tetris" "$APPS/tetris.sh" +[[ "$SELECTED_APPS" == *"doom"* ]] && run_module "doom" "$APPS/doom.sh" +[[ "$SELECTED_APPS" == *"sauerbraten"* ]] && run_module "sauerbraten" "$APPS/sauerbraten.sh" +[[ "$SELECTED_APPS" == *"stuntrally"* ]] && run_module "stuntrally" "$APPS/stuntrally.sh" +[[ "$SELECTED_APPS" == *"onlyoffice"* ]] && run_module "onlyoffice" "$APPS/onlyoffice.sh" +[[ "$SELECTED_APPS" == *"xournal"* ]] && run_module "xournal" "$APPS/xournal.sh" +[[ "$SELECTED_APPS" == *"rnote"* ]] && run_module "rnote" "$APPS/rnote.sh" +[[ "$SELECTED_APPS" == *"obsidian"* ]] && run_module "obsidian" "$APPS/obsidian.sh" +[[ "$SELECTED_APPS" == *"tangent-notes"* ]] && run_module "tangent-notes" "$APPS/tangent-notes.sh" +[[ "$SELECTED_APPS" == *"ffmpeg"* ]] && run_module "ffmpeg" "$APPS/ffmpeg.sh" +[[ "$SELECTED_APPS" == *"sox"* ]] && run_module "sox" "$APPS/sox.sh" +[[ "$SELECTED_APPS" == *"imagemagick"* ]] && run_module "imagemagick" "$APPS/imagemagick.sh" +[[ "$SELECTED_APPS" == *"yt-dlp"* ]] && run_module "yt-dlp" "$APPS/yt-dlp.sh" +[[ "$SELECTED_APPS" == *"gimp"* ]] && run_module "gimp" "$APPS/gimp.sh" +[[ "$SELECTED_APPS" == *"inkscape"* ]] && run_module "inkscape" "$APPS/inkscape.sh" +[[ "$SELECTED_APPS" == *"krita"* ]] && run_module "krita" "$APPS/krita.sh" +[[ "$SELECTED_APPS" == *"kdenlive"* ]] && run_module "kdenlive" "$APPS/kdenlive.sh" +[[ "$SELECTED_APPS" == *"openshot"* ]] && run_module "openshot" "$APPS/openshot.sh" +[[ "$SELECTED_APPS" == *"shotcut"* ]] && run_module "shotcut" "$APPS/shotcut.sh" +[[ "$SELECTED_APPS" == *"ardour"* ]] && run_module "ardour" "$APPS/ardour.sh" +[[ "$SELECTED_APPS" == *"audacity"* ]] && run_module "audacity" "$APPS/audacity.sh" +[[ "$SELECTED_APPS" == *"lmms"* ]] && run_module "lmms" "$APPS/lmms.sh" +[[ "$SELECTED_APPS" == *"mixxx"* ]] && run_module "mixxx" "$APPS/mixxx.sh" +[[ "$SELECTED_APPS" == *"cecilia"* ]] && run_module "cecilia" "$APPS/cecilia.sh" +[[ "$SELECTED_APPS" == *"chromium"* ]] && run_module "chromium" "$APPS/chromium.sh" +[[ "$SELECTED_APPS" == *"firefox-browser"* ]] && run_module "firefox-browser" "$APPS/firefox-browser.sh" +[[ "$SELECTED_APPS" == *"zen-browser"* ]] && run_module "zen-browser" "$APPS/zen-browser.sh" +[[ "$SELECTED_APPS" == *"nyxt"* ]] && run_module "nyxt" "$APPS/nyxt.sh" +[[ "$SELECTED_APPS" == *"librewolf"* ]] && run_module "librewolf" "$APPS/librewolf.sh" +[[ "$SELECTED_APPS" == *"min-browser"* ]] && run_module "min-browser" "$APPS/min-browser.sh" +[[ "$SELECTED_APPS" == *"vscodium"* ]] && run_module "vscodium" "$APPS/vscodium.sh" +[[ "$SELECTED_APPS" == *"zed-ide"* ]] && run_module "zed-ide" "$APPS/zed-ide.sh" +[[ "$SELECTED_APPS" == *"geany"* ]] && run_module "geany" "$APPS/geany.sh" +[[ "$SELECTED_APPS" == *"codeblocks"* ]] && run_module "codeblocks" "$APPS/codeblocks.sh" +[[ "$SELECTED_APPS" == *"kate"* ]] && run_module "kate" "$APPS/kate.sh" +[[ "$SELECTED_APPS" == *"rdp-client"* ]] && run_module "rdp-client" "$APPS/rdp-client.sh" +[[ "$SELECTED_APPS" == *"lamco-rdp-server"* ]] && run_module "lamco-rdp-server" "$APPS/lamco-rdp-server.sh" +[[ "$SELECTED_APPS" == *"qemu"* ]] && run_module "qemu" "$APPS/qemu.sh" +[[ "$SELECTED_APPS" == *"freeipa-client"* ]] && run_module "freeipa-client" "$APPS/freeipa-client.sh" +[[ "$SELECTED_APPS" == *"freeipa-server"* ]] && run_module "freeipa-server" "$APPS/freeipa-server.sh" +[[ "$SELECTED_APPS" == *"freeipa-image"* ]] && run_module "freeipa-image" "$APPS/freeipa-image.sh" +# END GENERATED MODULES: module-dispatch # ── Colorway (final step) ───────────────────────────────────────────────────── # Read defaults from repo colors.conf for pre-population.