Commit Graph
163 Commits
Author SHA1 Message Date
Claude 177598a79e docs: add CLAUDE.md, move backup guide into installer, drop linux-to-sync
- CLAUDE.md: full contributor guide — service template, all helpers,
  globals, DRY_RUN convention, Caddy wiring, non-Docker patterns
- services/backup.sh: print backup strategy guide (Kopia/Borg/rsync/
  rsnapshot + when to use each) at the start of install_backup()
- README.md: remove standalone backup section, fix broken backup row,
  inline base package list, add CLAUDE.md to layout
- services/linux-to-sync.sh: deleted (never worked)
- setup.sh: remove linux-to-sync from is_installed()

https://claude.ai/code/session_019XgsQ13XKm4Zj3cNsDNwHj
2026-06-04 14:29:02 +00:00
Outis b467672a9e Update README with service descriptions and formatting 2026-06-04 10:11:39 -04:00
Outis 2ba62187ef Merge pull request #47 from outis1one/claude/peaceful-goodall-nIfh9
docs: move base packages list into Services table, drop standalone se…
2026-06-04 10:08:04 -04:00
Claude 4cfef73090 docs: move base packages list into Services table, drop standalone section
https://claude.ai/code/session_019XgsQ13XKm4Zj3cNsDNwHj
2026-06-04 14:07:20 +00:00
Outis 4e9ca07ebd Merge pull request #46 from outis1one/claude/peaceful-goodall-nIfh9
docs: expand README with base packages list and full backup strategy …
2026-06-04 10:05:26 -04:00
Claude 5146412ade docs: expand README with base packages list and full backup strategy guide
Documents all packages installed by the base service, and adds a
Backup section covering Kopia, Borg, plain rsync, rsync --link-dest
(versioned snapshots with original folder structure), and rsnapshot —
with guidance on when to use each.

https://claude.ai/code/session_019XgsQ13XKm4Zj3cNsDNwHj
2026-06-04 13:51:46 +00:00
Outis 0edd816d17 Merge pull request #45 from outis1one/claude/nice-cannon-SdvTG
chore: remove old pre-modular files and internal planning docs
2026-06-04 09:35:31 -04:00
Claude 7a555987ed chore: remove old pre-modular files and internal planning docs
Keep only the two base install scripts (24.04, 26.04), the modular
system (setup.sh, lib/, services/, extras/, bootstrap.sh), and
LICENSE/README/VERSION. Everything else was superseded.

https://claude.ai/code/session_017WJtGcE5jjerAQCUBWUE3H
2026-06-04 13:30:05 +00:00
Outis 004008044e Merge pull request #44 from outis1one/claude/nice-cannon-SdvTG
Claude/nice cannon sdv tg
2026-06-04 09:22:09 -04:00
Claude e9830fef31 services/minecraft.sh: generate PREGEN_INSTRUCTIONS.md when chunky is selected
Writes radius, border status, and commands for monitoring, re-running,
and cancelling chunk pre-generation. Listed in the setup summary.

https://claude.ai/code/session_017WJtGcE5jjerAQCUBWUE3H
2026-06-04 13:19:07 +00:00
Claude f86e35aaf1 services/minecraft.sh: fix two incorrect printed instructions
- SCP example used $(whoami) which evaluates to root; use $ACTUAL_USER instead
- VT_VERSION stripped to major.minor (e.g. 1.21) so the picker version
  prompt is correct; previous awk printed the full patch string (1.21.4)

https://claude.ai/code/session_017WJtGcE5jjerAQCUBWUE3H
2026-06-04 12:56:16 +00:00
Claude 5138d6fca7 services/minecraft.sh: remove stale manual-run comment from pregen-startup.sh
Pregen runs automatically when starting the server; the "run manually"
comment inside the script was misleading.

https://claude.ai/code/session_017WJtGcE5jjerAQCUBWUE3H
2026-06-04 02:30:09 +00:00
Claude ae7b887b22 services/minecraft.sh: sync world border default and VT header from latest standalone
- World border default changed from y to n (border is opt-in)
- VT share links header updated with pack counts (22 datapacks, 10 crafting tweaks)

https://claude.ai/code/session_017WJtGcE5jjerAQCUBWUE3H
2026-06-04 02:27:36 +00:00
Outis df50fe6942 Merge pull request #43 from outis1one/claude/nice-cannon-SdvTG
Claude/nice cannon sdv tg
2026-06-03 22:18:26 -04:00
Outis 6eb5234f93 Merge branch 'main' into claude/nice-cannon-SdvTG 2026-06-03 22:18:18 -04:00
Outis ff6125940f Merge pull request #42 from outis1one/claude/dazzling-mendel-J4fi4
Claude/dazzling mendel j4fi4
2026-06-03 22:15:53 -04:00
Claude f5e3fea71c README: spell out how to get repo onto USB (extract + drag)
Step 1 was vague. Now explicit: download ZIP, right-click Extract Here,
drag the folder onto the USB in the file manager sidebar.

https://claude.ai/code/session_017WJtGcE5jjerAQCUBWUE3H
2026-06-04 02:14:41 +00:00
Claude 9968776813 README: USB install — open folder in file manager, no path needed
When you open the USB folder in the file manager, you're already there.
Right-click → Open in Terminal → sudo bash bootstrap.sh, or double-click
bootstrap.sh → Run in Terminal → sudo prompt. No /media/whoami/DRIVENAME
path hunting required.

https://claude.ai/code/session_017WJtGcE5jjerAQCUBWUE3H
2026-06-04 02:09:53 +00:00
Claude d2c57b5fc6 README: simplify USB install — download ZIP, not git clone
The real workflow is: GitHub Code → Download ZIP → unzip → copy to USB.
No git, no auth, no file manager tricks. On the target machine: ls to find
the drive name, then sudo bash /media/$(whoami)/DRIVENAME/...bootstrap.sh.

https://claude.ai/code/session_017WJtGcE5jjerAQCUBWUE3H
2026-06-04 02:06:18 +00:00
Claude e168d6256c bootstrap.sh self-elevates with sudo; USB install docs rewritten
bootstrap.sh: add self-elevation — if not root, re-exec under sudo.
Double-clicking the script in GNOME ("Run in Terminal") now prompts for
the sudo password automatically, no extra commands needed.

README: rewrite USB section around the real workflow:
  - clone with "Open in Terminal" from the file manager sidebar
  - Option A: right-click folder → Open in Terminal → sudo ./setup.sh
  - Option B: double-click bootstrap.sh → "Run in Terminal?" → sudo prompt
  - note on nautilus-extension-gnome-terminal and exFAT vs ext4

https://claude.ai/code/session_017WJtGcE5jjerAQCUBWUE3H
2026-06-04 02:00:58 +00:00
Claude 1ac550d81e Remove Run Setup.desktop launcher and its README mention
https://claude.ai/code/session_017WJtGcE5jjerAQCUBWUE3H
2026-06-04 01:54:54 +00:00
Claude 8d7fb2df43 Add USB thumb drive install docs and double-click launcher
README: rewrite USB section with three steps:
  1. Auto-detect USB mount point and clone repo onto it
  2. Install nautilus-extension-gnome-terminal for right-click "Open in Terminal"
  3. Double-click "Run Setup.desktop" to launch wizard with sudo (no terminal needed)

Run Setup.desktop: launcher file included in the repo so it's present on the
USB automatically. Uses %k to find its own location, cds to that directory,
and runs sudo ./setup.sh in a terminal window.

https://claude.ai/code/session_017WJtGcE5jjerAQCUBWUE3H
2026-06-04 01:54:33 +00:00
Claude 3c3e9dd6da README: replace Docker-data USB section with thumb drive installer docs
The USB section was documenting the wrong thing. Replace with instructions
for carrying the repo on a USB stick and running setup.sh directly from it
on any fresh Ubuntu machine — no internet required for the repo.

Covers: cloning/copying to USB, finding the mount point on the target
machine, running setup from USB, exFAT vs ext4 trade-offs, fixing
permissions after copy.

https://claude.ai/code/session_017WJtGcE5jjerAQCUBWUE3H
2026-06-04 01:51:12 +00:00
Outis e956f6f4d5 Merge pull request #41 from outis1one/claude/nice-cannon-SdvTG
Auto-install Docker, add USB drive docs, improve whitelist UI
2026-06-03 21:42:21 -04:00
Claude 8aa1d4552d Auto-install Docker, add USB drive docs, improve whitelist UI
- lib/common.sh: require_docker now installs Docker CE + Compose plugin
  via get.docker.com instead of erroring out if Docker is missing.
  Also adds the calling user to the docker group automatically.

- README.md: fix 'tells you how to install Docker' → 'installs Docker
  automatically'; add full USB drive usage section (mount, fstab,
  DOCKER_DIR config, moving existing data, tips).

- services/minecraft.sh: replace single-source whitelist import with the
  multi-source UI from the updated setup-minecraft.sh — collects players
  from the current instance, saved backup files, and other servers' backups;
  assigns letters to each source so you can import by letter (all from that
  source) or by number (specific player).

https://claude.ai/code/session_017WJtGcE5jjerAQCUBWUE3H
2026-06-04 01:37:58 +00:00
Claude 8ffebe9a5a bootstrap: self-elevate sudo; document double-click workflow
Added exec sudo bash self-elevation so bootstrap.sh works correctly when
double-clicked ("Run in Terminal") without the user needing to prefix sudo.
If already root, the check is a no-op.

Removed bootstrap.desktop — too fragile across desktop environments.
README now covers both "Open in Terminal" and double-click paths.

https://claude.ai/code/session_01Y4dMKtkqkpvmgDKoRdzhTG
2026-06-04 01:14:54 +00:00
Claude 39280d71cb README: document USB prep via GitHub ZIP download
The previous USB instructions assumed git was available. Added step-by-step
for the no-git path: GitHub ZIP download → unzip → copy to USB → run
bootstrap.sh. Includes the Ubuntu auto-mount path tip for finding the
drive name. Folder name note (ubuntu-post-install-main from ZIP) added.

https://claude.ai/code/session_01Y4dMKtkqkpvmgDKoRdzhTG
2026-06-04 01:08:42 +00:00
Claude 9773dcfb63 bootstrap: support USB/local-copy and private repo PAT
Three usage modes now documented and implemented:

1. Public repo: curl | sudo bash (unchanged)
2. Private repo, USB: copy whole repo to thumb drive, run bootstrap.sh
   from it — detects setup.sh alongside itself, copies to ~/ubuntu-post-install,
   execs setup.sh. No git auth, no internet needed for the scripts.
3. Private repo, PAT: bootstrap.sh --pat ghp_xxx — PAT stripped from
   stored remote URL after clone so it is not saved in plain text.

USB mode is the recommended approach for private repos: clone once,
put on a drive, run on every new machine.

https://claude.ai/code/session_01Y4dMKtkqkpvmgDKoRdzhTG
2026-06-04 01:00:57 +00:00
Outis 5be84d85ea Merge pull request #40 from outis1one/claude/dazzling-mendel-J4fi4
chore: add versioned snapshot setup_v0.9.5.sh, reset VERSION to 0.9.5
2026-06-03 20:38:06 -04:00
Claude 33f052ea0b Add bootstrap.sh and rewrite README for modular system
bootstrap.sh: one curl | sudo bash to get and run on a fresh box —
installs git if missing, clones/updates the repo, execs setup.sh.

README.md: complete rewrite. The old README described the monolithic
script (--restore, --migrate flags, Samba, NetBird, etc.) which no
longer exists. New README covers quick start, usage modes, service
table, layout, and managing installed services.

https://claude.ai/code/session_01Y4dMKtkqkpvmgDKoRdzhTG
2026-06-04 00:26:09 +00:00
Claude 2ab0008338 Bump NodeSource from Node 22 to Node 24 LTS
Both silent-send and immich already use NodeSource (not Ubuntu repos).
Node 24 is the current active LTS; 22 moves to maintenance in 2025.
Minimum version checks (>=18 and >=20) are unchanged — both services
accept any sufficiently recent Node.

https://claude.ai/code/session_01Y4dMKtkqkpvmgDKoRdzhTG
2026-06-04 00:22:07 +00:00
Claude 92e8866f13 pip_user_install: capability probe instead of version check
Probe for --break-system-packages support once (pip --help, cached in
_PIP_HAS_BSP) rather than comparing Ubuntu version numbers. Works on any
pip >= 22.3 regardless of distro; older pip (Ubuntu 22.04, pip 22.0)
falls back to --user only, which is correct there since PEP 668 isn't
enforced on 22.04 anyway.

The flag name is scary but harmless with --user: installs go to ~/.local/
which apt never manages regardless.

https://claude.ai/code/session_01Y4dMKtkqkpvmgDKoRdzhTG
2026-06-04 00:05:36 +00:00
Claude e8667f02cf pip_user_install: add --break-system-packages on Ubuntu 24.04+
pip3 install --user alone does not reliably bypass PEP 668 in all 24.04
environments. --break-system-packages (pip 22.3+) is the correct override.
Flag is only added when ubuntu_version_ge "24.04" so it does not run on
Ubuntu 22.04 where pip 22.0 ships and the flag is not yet supported.

https://claude.ai/code/session_01Y4dMKtkqkpvmgDKoRdzhTG
2026-06-04 00:01:57 +00:00
Claude ef08fef540 Add OS detection; surface version in header; centralise pip installs
lib/common.sh:
  - detect_os(): reads /etc/os-release into OS_DISTRO, OS_VERSION,
    OS_CODENAME globals (exported, auto-called on source)
  - ubuntu_version_ge(): numeric version comparison helper
  - pip_user_install(): central wrapper for pip3 install --user so any
    future version-specific flags are in one place

setup.sh:
  - Both header banners now show detected OS line (e.g., "Ubuntu 24.04 (noble)")
  - First-run path warns if not Ubuntu or < 24.04

services/sky-cam.sh, services/sync-cc.sh:
  - Replace inline pip3 invocations with pip_user_install helper

https://claude.ai/code/session_01Y4dMKtkqkpvmgDKoRdzhTG
2026-06-03 23:49:51 +00:00
Claude 370c513606 Skip required-packages step on re-run
On second run, is_installed base (command -v ncdu) detects that base
packages are already present and jumps straight to the service menu,
skipping the required-setup banner, confirm prompt, and apt-get install.
The first-run path is unchanged; `sudo ./setup.sh base` forces reinstall.

https://claude.ai/code/session_01Y4dMKtkqkpvmgDKoRdzhTG
2026-06-03 23:48:15 +00:00
Claude 56d2f9e85b Add site-wide defaults: timezone, domain, Caddy network
Introduces a one-time configuration wizard (sudo ./setup.sh configure)
that stores SITE_TZ, SITE_DOMAIN, and SITE_CADDY_NET in ~/docker/.config.
Every service now uses these as prompt defaults so the user types common
values once instead of re-answering the same questions for each service.

- lib/common.sh: load_site_config / save_site_config; auto-loads on source;
  backward-compat BASE_DOMAIN alias kept for old .config files
- setup.sh: run_site_configure wizard; first-run offer after base install;
  `sudo ./setup.sh configure` command to update defaults at any time
- 14 services: TZ_VAL now honours SITE_TZ, falling back to /etc/timezone
- 3 inline-heredoc services (filebrowser, homeassistant, ntfy): same fix
- authelia: SITE_TZ/SITE_DOMAIN as prompt defaults; SITE_CADDY_NET replaces
  hardcoded caddy_net throughout (env, compose patch, network creation)
- minecraft, frigate-audio: simplify BASE_DOMAIN read to use SITE_DOMAIN
- sky-cam: SITE_TZ as default for timezone prompt

https://claude.ai/code/session_01Y4dMKtkqkpvmgDKoRdzhTG
2026-06-03 22:13:59 +00:00
Claude cfad0ebd20 fix(linux-to-sync): run git clone as actual user, handle re-run, show errors
Three bugs fixed:
1. git clone ran as root — SSH key lookup failed because user's keys are in
   ~user/.ssh/, not /root/.ssh/. Both SSH and PAT clones now run via
   sudo -u ACTUAL_USER so git uses the right key and the clone is owned
   correctly without a separate chown step.
2. 2>/dev/null on git clone swallowed all error output — errors are now
   shown so authentication failures are diagnosable.
3. No re-run handling — trying to clone into an existing dir silently
   failed. Now detects .git, offers git pull instead.
Also: checks for SSH key existence before attempting SSH clone, and prints
actionable guidance (ssh-keygen, ssh-add, ssh -T git@github.com) on failure.

https://claude.ai/code/session_01Y4dMKtkqkpvmgDKoRdzhTG
2026-06-03 21:41:54 +00:00
Claude c3bb2cf18c feat(cameras): add sky-cam and frigate-audio service modules
sky-cam (cameras/non-docker):
  Clones outis1one/sky-cam via bootstrap.sh to ~/sky-cam. Prompts for
  latitude, longitude, timezone, camera names, BASE_DIR, and optional
  Mattermost webhook. Patches sky-cam.conf and installs systemd user
  timers via the repo's install.sh. Produces sunrise clips, Four Seasons
  timelapse, moon-track, and monthly moon-phase images.

frigate-audio (cameras/docker):
  Full stack from outis1one/frigate_w_audio: Frigate 0.17 NVR +
  Mosquitto MQTT broker + frigate-notify → ntfy push alerts. Audio-ready
  config template with face recognition and LPR pre-configured. Prompts
  for camera credentials, media storage path (supports drive detection),
  MQTT password (auto-generated), and ntfy server. Bootstraps the
  Mosquitto passwd file. Detector choice: CPU / USB Coral / PCIe Coral.
  Hardcoded media path from upstream replaced with a configurable prompt.

https://claude.ai/code/session_01Y4dMKtkqkpvmgDKoRdzhTG
2026-06-03 21:40:49 +00:00
Claude 1d4b38674d feat(extras): add sync-cc service — Whisper/ffsubsync subtitle tool
Adds sync_cc as an extras service module:
- extras/sync_cc.py: the Python tool (3196 lines) — 8 modes: SYNC,
  GENERATE, BATCH, RENAME (TMDB), EXTRACT, REMUX, EMBED, BURNSUBS
- services/sync-cc.sh: installs system deps (python3, ffmpeg, mkvtoolnix,
  ccextractor), pip installs openai-whisper + ffsubsync, copies the script
  to ~/sync-cc/, prompts for TMDB API key → .env, creates /usr/local/bin/sync-cc
  wrapper so users run it from any directory containing video/SRT files

Heavy optional deps (easyocr, pgsreader) are installed on first use by the
script itself. GPU (CUDA/MPS) is used automatically if detected.

https://claude.ai/code/session_01Y4dMKtkqkpvmgDKoRdzhTG
2026-06-03 21:36:22 +00:00
Claude a63f72ef17 feat(minecraft): port whitelist import + VT share links + pause from standalone
Three improvements ported from the standalone setupminecraft.sh:
- Whitelist: detect existing whitelist.json on re-run, offer to import
  players by number (0=all, comma list, Enter=skip), no UUID re-lookup
  for already-resolved entries; new gamertags still looked up via Mojang API
- Vanilla Tweaks: add vanillatweaks.net pre-configured share links at the
  top of the download instructions section (datapacks + crafting tweaks)
- Vanilla Tweaks: pause with "Press Enter when datapacks are in
  datapacks-download/" so user can SCP the ZIP before the build starts

https://claude.ai/code/session_01Y4dMKtkqkpvmgDKoRdzhTG
2026-06-03 21:32:39 +00:00
Claude cd59549e39 chore: add versioned snapshot setup_v0.9.5.sh, reset VERSION to 0.9.5
Introduces the versioned-snapshot naming convention: each release creates
a new setup_v<X.Y.Z>.sh file alongside the live setup.sh; old snapshots
are never removed. Resets VERSION from 1.0.0 to 0.9.5.

https://claude.ai/code/session_01Y4dMKtkqkpvmgDKoRdzhTG
2026-06-03 19:24:23 +00:00
Outis 89ab32209e Merge pull request #38 from outis1one/claude/dazzling-mendel-J4fi4
feat(gaming): add wolf-pair module — browser PIN form for Moonlight p…
2026-06-03 14:58:46 -04:00
Claude d5941f2b26 feat: parity milestone — add linux-to-sync, mark v1.0.0
Every service from ubuntu-post-install-24.04-crowdsec.sh is now a module.
35 services across 8 categories; setup.sh is the primary install path.

- services/linux-to-sync.sh (extras): clone private repo via SSH or PAT
- setup.sh: is_installed case for linux-to-sync (~/.git marker)
- MODULAR.md: migration table updated to show full inventory
- VERSION: 0.9.11 → 1.0.0 (parity achieved)

https://claude.ai/code/session_01Y4dMKtkqkpvmgDKoRdzhTG
2026-06-03 18:33:04 +00:00
Claude 2210dd4bed feat: add utilities + cameras batches (v0.9.11)
Utilities (8 modules):
- mealie: recipe manager, port 9925
- actualbudget: personal finance, port 5006
- traccar: GPS tracking, ports 8082 + 5000-5150 device protocols
- fmd: Android FindMyDevice server, random admin password, port 8084
- ddclient: dynamic DNS, config template, default start=n
- wg-easy: WireGuard VPN+UI, auto-detects public IP, random password
- meshcentral: remote device management, hostname prompt, ports 4430+4433
- magicmirror: smart mirror, 1-3 instances, MMM-* module auto-clone

Cameras (2 modules):
- frigate: AI NVR, auto-enables /dev/dri, starter config.yml, default start=n
- frigate-notify: Frigate push alerts, auto-detects local Frigate+ntfy, no web UI

https://claude.ai/code/session_01Y4dMKtkqkpvmgDKoRdzhTG
2026-06-03 18:30:58 +00:00
Claude a36f058a51 feat(media): add 6 media service modules (v0.9.10)
Migrate the full media batch from the monolith:

- jellyfin: auto-VAAPI on /dev/dri/renderD128 + render GID; DLNA/discovery UDP ports
- emby: UID/GID baked at install; HW transcoding block commented for manual opt-in
- audiobookshelf: separate audiobooks + podcasts paths; port 13378
- arm: optical drive detection; privileged:true; split movies/music output; port 8080
- lyrion: network_mode:host for Chromecast/Squeezebox UDP discovery; port 9000
- immich: multi-container stack (server+ML+valkey+postgres); two library strategies
  (unified with import-photos.sh helper, or external read-only); port 2283

https://claude.ai/code/session_01Y4dMKtkqkpvmgDKoRdzhTG
2026-06-03 18:24:02 +00:00
Claude 527808d610 feat(extras): add silent-send module + new extras category
Adds services/silent-send.sh — installs the Silent Send browser extension
(client-side PII redaction for AI chat). Non-docker module: installs git +
Node.js >=18 (NodeSource) + npm, clones outis1one/silent-send to ~/silent-send,
runs npm install (readies web-ext for Firefox build/sign), optionally builds a
signed Firefox .xpi, and prints per-browser load/build instructions. README
written to the checkout.

Introduces a new 'extras' category for non-docker add-ons pulled from other
repos, wired into setup.sh CATEGORY_ORDER (gaming -> extras -> backup) with an
is_installed marker. MODULAR.md groups list updated.

Bumps version to 0.9.9.
2026-06-03 18:11:07 +00:00
Claude d9b19b5f56 feat(gaming): add wolf-pair module — browser PIN form for Moonlight pairing
Adds services/wolf-pair.sh (gaming group, port 8090). Builds a tiny
python:3.12-alpine container from server.py + Dockerfile (both baked
into the script) that reads Wolf's docker logs for the current pairing
secret and serves a PIN entry form. Runs with network_mode: host so
localhost:47989 (Wolf's /pin/ API) is reachable; docker socket mounted
read-only for log access.

Replaces the ./manage.sh pin CLI workflow: visit the URL, type the PIN.
Optional Caddy subdomain, UFW port 8090, README in ~/docker/wolf-pair/.

Bumps version to 0.9.8.
2026-06-03 17:52:19 +00:00
Outis c3b096361e Merge pull request #37 from outis1one/claude/happy-volta-RPhbD
Claude/happy volta r phb d
2026-06-03 13:36:38 -04:00
Claude b619733a61 Add HANDOFF.md — migration status, taxonomy, wolf-pair open item
Status snapshot at v0.9.7 for continuing in a new session: module status by
category, final taxonomy, the module contract/conventions, verification steps,
and the open wolf-pair item (awaiting server.py + Dockerfile upload).

https://claude.ai/code/session_017eA2qqq9jfF2tNtpUYL8vK
2026-06-03 17:35:50 +00:00
Claude 9dc8c4063d v0.9.7: Caddy + CrowdSec modules; category menu with required-gate
- services/caddy.sh (homelab): reverse proxy + auto HTTPS, own ~/docker/caddy
  folder (compose + starter Caddyfile + README).
- services/crowdsec.sh (homelab): system-level IPS (agent + firewall bouncer +
  Caddy acquisition + optional ntfy alerts), README in ~/docker/crowdsec.
- setup.sh guided flow redesign:
  * Prints REQUIRED set (essentials + glow + docker check) with a cancel option.
  * Offers Caddy first (most services proxy through it).
  * Category menu LOOP: pick category -> checklist ([installed] marked) ->
    install -> back to menu, until Done. whiptail + text fallback.
- Categories reorganized: base/homelab/utilities/media/cameras/gaming/backup;
  moved ntfy/filebrowser/portainer/uptimekuma/watchtower to utilities;
  caddy->crowdsec->authelia ordered first in homelab.

Verified: bash -n all; --list groups by category with caddy first; cancel path
prints 'Cancelled, nothing changed'; dry-run guided flow runs required + loops
menu; run-one still works.

https://claude.ai/code/session_017eA2qqq9jfF2tNtpUYL8vK
2026-06-03 17:16:32 +00:00