Stop copying cli.sh and a lib subset to ~/.local/bin. Setup and upgrade
write a short wrapper that execs $INSTALL_DIR/cli.sh. Leftover PATH libs
are removed. update-cli now points at upgrade.
Re-wire without replacing compose. Update the shared login on every
UI. Make assemblrr quality profiles the Radarr/Sonarr Add New default.
config edit is picker-only. Forward Seerr Host headers, chmod only the
VPN secrets just written, and ignore Python cache files.
Pin Recyclarr to ghcr.io/recyclarr/recyclarr:8 (:latest is unpublished)
and write ~/.local/bin into bashrc/zshrc/fish so the early CLI still
works after a failed setup on Arch/WSL. Setup now picks install/media
paths from an fzf list of home plus mounted drives.
Seerr's DELETE /api/v1/media/:id/file is title-scoped and would wipe
every remaining season. For a TV request that is only a subset, the
gateway now deletes those Sonarr episode files and unmonitors them,
then drops the request. Movies and last remaining seasons still use
the title-level cascade.
media-purge --seasons and the inotify watcher match that: a season
path never title-purges (other seasons may only be monitored). qB
cleanup requires a season token, refuses multi-season and S01-03
packs, and uses the same title-boundary rules as title-level. *arr
recycle bin is /data/media/.recycle with 7-day cleanup.
Sonarr uncertainty (missing key, failed episodefile list, empty TV
season list) returns 502 and leaves the request. The gateway mounts
config/sonarr/ as a directory so first install cannot replace
config.xml with a Docker-created directory.
qBittorrent 5.x does not bind WireGuard's tun0 unless told to, so tracker
and DHT packets left via eth0 and Gluetun dropped them (stalledDL). Bind
the session to tun0 on VPN installs. Build sidecar images on the host
instead of apk at start, move vpn-watchdog off Gluetun's netns, ignore
non-video inotify events, and stop start/upgrade from aborting or
re-prompting.
Remove Portainer from managed compose and catalog; leave a custom.yaml
example for optional use. Upgrade/start use compose --remove-orphans and
migration 002 removes leftover Portainer containers unless custom.yaml
keeps it. Fix setup double URL list when status is unhealthy, share
OpenSubtitles y/N on express, and tone down indexer/provider prompts.
Drop hardcoded subtitle-provider defaults. Wire-up lists providers
from the running Bazarr container and enables only user selections
(plus OpenSubtitles.com when credentials were saved).
Prefer history hashes filtered by library folder key, then exact folder-key
match only (no sequel prefix hits). Refuse ambiguous multi-matches. Ignore
partial file-delete events. Best-effort Jellyfin library refresh after purge.
Stock Seerr only drops the request row; intercept DELETE /api/v1/request/:id
to cascade media file delete (*arr + purge hooks) before removing the request.
Hardlink-safe cleanup: Seerr/Jellyfin/*arr deletes remove library files and
qB torrents via purge hooks and media-purge-watch. Indexers get seed ratio/time
so completed downloads can leave torrents/. Upgrade always re-wires services;
drop user-facing config sync. Live e2e covers Radarr, Seerr, and Jellyfin APIs.
Drop writing ~/assemblrr_services.txt; status now shows live state and
localhost URLs for each service, with --docker for raw compose ps.
Health parsing is fixed under set -e; uninstall cleans legacy txt.
Ship Bazarr in the core compose stack, wire Sonarr/Radarr/Jellyfin on
config sync, apply TRaSH-style scoring, free multi-provider defaults, and
optional OpenSubtitles.com credentials from setup secrets.
Failed VPN setup can leave config/ owned by root so rm -rf fails.
Guide Option 1–3 by install completeness and document Docker-based
removal without sudo.