#!/usr/bin/env fish # FKRPG drift check — standalone, Fish-friendly # Compares LOCAL ≠ PACKWIZ, PRODUCTION ≠ PACKWIZ, LOCAL ≠ PRODUCTION # via Packwiz index hash + mod filenames set -l repo (dirname (dirname (realpath (status filename)))) set -l pack_dir "$repo/server_pack" set -l local_dir "$HOME/.auto-mcs/Servers/FKRPG" set -l manifest "$repo/optimization-manifest.json" echo "=== FKRPG DRIFT CHECK ===" echo "Packwiz: $pack_dir" echo "Local: $local_dir" echo "Manifest: $manifest" echo # pack hash set -l pack_hash (grep -E '^\s*hash\s*=' "$pack_dir/pack.toml" | head -n1 | string trim) echo "PACKWIZ $pack_hash" # manifest hash if test -f "$manifest" set -l manifest_hash (python3 -c "import json; print(json.load(open('$manifest'))['pack']['index_hash'])" 2>/dev/null) echo "MANIFEST index_hash=$manifest_hash" if string match -q "*$manifest_hash*" "$pack_hash" echo " -> manifest in-sync" else echo " -> DRIFT: manifest != pack.toml (run fish tools/audit.fish --write-manifest)" end else echo "MANIFEST missing" end echo # local mods vs packwiz if test -d "$local_dir/mods" set -l local_count (command ls -1 "$local_dir/mods"/*.jar 2>/dev/null | wc -l | string trim) set -l pack_count (command ls -1 "$pack_dir/mods"/*.pw.toml 2>/dev/null | wc -l | string trim) echo "LOCAL mods: $local_count jars" echo "PACKWIZ mods: $pack_count pw.toml" # compare filenames (packwiz filenames vs local jars) set -l tmp_pack (mktemp) set -l tmp_local (mktemp) python3 -c " import glob, re, os PW=re.compile(r'filename\s*=\s*\"([^\"]+)\"') for f in glob.glob(os.path.join('$pack_dir', 'mods', '*.pw.toml')): for line in open(f): m=PW.search(line) if m: print(m.group(1)) break " | sort > $tmp_pack python3 -c " import glob, os for f in glob.glob(os.path.join('$local_dir', 'mods', '*.jar')): print(os.path.basename(f)) " | sort > $tmp_local set -l missing (comm -23 $tmp_pack $tmp_local | head -n 20) set -l extra (comm -13 $tmp_pack $tmp_local | head -n 20) set -l missing_count (comm -23 $tmp_pack $tmp_local | wc -l | string trim) set -l extra_count (comm -13 $tmp_pack $tmp_local | wc -l | string trim) if test "$missing_count" = "0" -a "$extra_count" = "0" echo "DRIFT: LOCAL = PACKWIZ (in-sync)" else echo "DRIFT DETECTED" echo " Missing in LOCAL ($missing_count):" for f in $missing; echo " - $f"; end echo " Extra in LOCAL ($extra_count):" for f in $extra; echo " - $f"; end echo " Action: Production is outdated or Local is drifted — reinstall from Packwiz export" end rm $tmp_pack $tmp_local else echo "LOCAL: not found at $local_dir/mods" end echo # production hint (repo/data or server-pack.mrpack) if test -d "$repo/data/mods" set -l prod_count (command ls -1 "$repo/data/mods"/*.jar 2>/dev/null | wc -l | string trim) echo "PRODUCTION (repo/data/mods): $prod_count jars" echo " Hint: compare via docker compose file-mount /modpacks/pack.mrpack" else if test -f "$repo/server-pack.mrpack" set -l h (sha256sum "$repo/server-pack.mrpack" 2>/dev/null | cut -c1-16) echo "PRODUCTION mrpack: $repo/server-pack.mrpack sha256 $h..." else echo "PRODUCTION: no local hint (check VPS: docker compose exec mc ls /data/mods | wc -l)" end echo echo "Full audit: fish tools/audit.fish --json | jq .drift"