#!/bin/zsh
set -eu
setopt EXTENDED_GLOB
unset ELECTRON_RUN_AS_NODE
root=${0:A:h}
release="$HOME/Library/Application Support/LIBERTY Command/cloud-bootstrap/20261009-123000"
app='/Applications/LIBERTY Command.app'
resources="$app/Contents/Resources"
backup=''
changed=0
finish_error(){
 local code=$?
 trap - EXIT
 if (( code != 0 )); then
  if (( changed == 1 )) && [[ -n "$backup" ]]; then
   /bin/cp -p "$backup/app.asar" "$resources/app.asar" || true
   if [[ -d "$backup/app.asar.unpacked" ]]; then /usr/bin/ditto "$backup/app.asar.unpacked" "$resources/app.asar.unpacked" || true; fi
   print -r -- 'La version précédente a été remise en place. Les conversations et les clés n’ont pas été touchées.'
  fi
  print -r -- 'Mise à jour NON terminée. Lis le message ci-dessus ; ne désinstalle pas Command.'
  print -r -- 'Appuie sur Entrée pour fermer cette fenêtre.'
  read -r response || true
 fi
 exit $code
}
trap finish_error EXIT
fail(){ print -r -- "$1" >&2; return 1; }
check_closed(){
 local found
 found=$(/bin/ps -axo command= | /usr/bin/awk '/\.app\/Contents\/MacOS\/LIBERTY Command($| --)/ && !/LIBERTY Command Helper/ {print}')
 if [[ -n "$found" ]]; then
  print -r -- "$found"
  fail 'Command est encore ouvert (peut-être une ancienne copie). Quitte toutes ses fenêtres : LIBERTY Command → Quitter, puis relance cet outil.'
 fi
}
[[ -f "$resources/app.asar" ]] || fail 'Command est introuvable dans Applications. Cette mise à jour nécessite une installation existante.'
[[ -w "$resources" ]] || fail 'Le dossier Applications ne permet pas la mise à jour sur ce compte. Aucun fichier modifié.'
check_closed
print -r -- "Téléchargement sécurisé…"
/bin/mkdir -p "$release"
/bin/mkdir -p "$release/."
: > "$release/app.asar.new"
/usr/bin/curl --fail --location --proto "=https" --retry 2 --connect-timeout 15 --max-time 180 "https://liberty-command-updates.pages.dev/releases/20261009-123000/0f80e48604b0be03cc107fcfdc4c99eb6b89ec987115ac0aee28ca947a0269b8.bin" -o "$release/fragment.tmp"
actual=$(/usr/bin/shasum -a 256 "$release/fragment.tmp"); actual=${actual%% *}
[[ "$actual" == "0f80e48604b0be03cc107fcfdc4c99eb6b89ec987115ac0aee28ca947a0269b8" ]] || fail "Téléchargement altéré."
/bin/cat "$release/fragment.tmp" >> "$release/app.asar.new"
/usr/bin/curl --fail --location --proto "=https" --retry 2 --connect-timeout 15 --max-time 180 "https://liberty-command-updates.pages.dev/releases/20261009-123000/89550287a0611843df2aa96f93c5bda2f9e8eb32004b5a6234721dbea443ddcd.bin" -o "$release/fragment.tmp"
actual=$(/usr/bin/shasum -a 256 "$release/fragment.tmp"); actual=${actual%% *}
[[ "$actual" == "89550287a0611843df2aa96f93c5bda2f9e8eb32004b5a6234721dbea443ddcd" ]] || fail "Téléchargement altéré."
/bin/cat "$release/fragment.tmp" >> "$release/app.asar.new"
/usr/bin/curl --fail --location --proto "=https" --retry 2 --connect-timeout 15 --max-time 180 "https://liberty-command-updates.pages.dev/releases/20261009-123000/c1022f09b72e51b55f19ad9e52b8044aa0f3bec3869b3963c7fd2bb6c1e7d256.bin" -o "$release/fragment.tmp"
actual=$(/usr/bin/shasum -a 256 "$release/fragment.tmp"); actual=${actual%% *}
[[ "$actual" == "c1022f09b72e51b55f19ad9e52b8044aa0f3bec3869b3963c7fd2bb6c1e7d256" ]] || fail "Téléchargement altéré."
/bin/cat "$release/fragment.tmp" >> "$release/app.asar.new"
/usr/bin/curl --fail --location --proto "=https" --retry 2 --connect-timeout 15 --max-time 180 "https://liberty-command-updates.pages.dev/releases/20261009-123000/cb5e28d481aa2b5aaa002b634d623e4f589f8896db8c3914cb974bb0eae2765b.bin" -o "$release/fragment.tmp"
actual=$(/usr/bin/shasum -a 256 "$release/fragment.tmp"); actual=${actual%% *}
[[ "$actual" == "cb5e28d481aa2b5aaa002b634d623e4f589f8896db8c3914cb974bb0eae2765b" ]] || fail "Téléchargement altéré."
/bin/cat "$release/fragment.tmp" >> "$release/app.asar.new"
/usr/bin/curl --fail --location --proto "=https" --retry 2 --connect-timeout 15 --max-time 180 "https://liberty-command-updates.pages.dev/releases/20261009-123000/de61ce8f365a4a27e562b1951a8a92c09bcd4d248edade879aae7d93ef005473.bin" -o "$release/fragment.tmp"
actual=$(/usr/bin/shasum -a 256 "$release/fragment.tmp"); actual=${actual%% *}
[[ "$actual" == "de61ce8f365a4a27e562b1951a8a92c09bcd4d248edade879aae7d93ef005473" ]] || fail "Téléchargement altéré."
/bin/cat "$release/fragment.tmp" >> "$release/app.asar.new"
/bin/mv "$release/app.asar.new" "$release/app.asar"
/bin/mkdir -p "$release/app.asar.unpacked/lib"
: > "$release/app.asar.unpacked/lib/esme_read.py.new"
/usr/bin/curl --fail --location --proto "=https" --retry 2 --connect-timeout 15 --max-time 180 "https://liberty-command-updates.pages.dev/releases/20261009-123000/aa2a420d9d4f317bc869ce2adc1630cb8e6dbcd31ab84f5071aa4d1ebbb68d45.bin" -o "$release/fragment.tmp"
actual=$(/usr/bin/shasum -a 256 "$release/fragment.tmp"); actual=${actual%% *}
[[ "$actual" == "aa2a420d9d4f317bc869ce2adc1630cb8e6dbcd31ab84f5071aa4d1ebbb68d45" ]] || fail "Téléchargement altéré."
/bin/cat "$release/fragment.tmp" >> "$release/app.asar.unpacked/lib/esme_read.py.new"
/bin/mv "$release/app.asar.unpacked/lib/esme_read.py.new" "$release/app.asar.unpacked/lib/esme_read.py"
/bin/mkdir -p "$release/app.asar.unpacked/lib"
: > "$release/app.asar.unpacked/lib/journal.py.new"
/usr/bin/curl --fail --location --proto "=https" --retry 2 --connect-timeout 15 --max-time 180 "https://liberty-command-updates.pages.dev/releases/20261009-123000/80a7a6421780ddc833c6c9c396e7ecf4ce4ea854a61f161b366f0df381d076a7.bin" -o "$release/fragment.tmp"
actual=$(/usr/bin/shasum -a 256 "$release/fragment.tmp"); actual=${actual%% *}
[[ "$actual" == "80a7a6421780ddc833c6c9c396e7ecf4ce4ea854a61f161b366f0df381d076a7" ]] || fail "Téléchargement altéré."
/bin/cat "$release/fragment.tmp" >> "$release/app.asar.unpacked/lib/journal.py.new"
/bin/mv "$release/app.asar.unpacked/lib/journal.py.new" "$release/app.asar.unpacked/lib/journal.py"
/bin/mkdir -p "$release/app.asar.unpacked/lib"
: > "$release/app.asar.unpacked/lib/journal.test.py.new"
/usr/bin/curl --fail --location --proto "=https" --retry 2 --connect-timeout 15 --max-time 180 "https://liberty-command-updates.pages.dev/releases/20261009-123000/d9687a249b5fda6e9ad4141c13ffefbc67d877f3edc06cfb7082f3e962ffc320.bin" -o "$release/fragment.tmp"
actual=$(/usr/bin/shasum -a 256 "$release/fragment.tmp"); actual=${actual%% *}
[[ "$actual" == "d9687a249b5fda6e9ad4141c13ffefbc67d877f3edc06cfb7082f3e962ffc320" ]] || fail "Téléchargement altéré."
/bin/cat "$release/fragment.tmp" >> "$release/app.asar.unpacked/lib/journal.test.py.new"
/bin/mv "$release/app.asar.unpacked/lib/journal.test.py.new" "$release/app.asar.unpacked/lib/journal.test.py"
/bin/mkdir -p "$release/app.asar.unpacked/lib"
: > "$release/app.asar.unpacked/lib/memory_mcp.py.new"
/usr/bin/curl --fail --location --proto "=https" --retry 2 --connect-timeout 15 --max-time 180 "https://liberty-command-updates.pages.dev/releases/20261009-123000/a14f3c01804e1b988ca992d145e3643c65c4ccc6e7b6c466d30c5f7590e412d2.bin" -o "$release/fragment.tmp"
actual=$(/usr/bin/shasum -a 256 "$release/fragment.tmp"); actual=${actual%% *}
[[ "$actual" == "a14f3c01804e1b988ca992d145e3643c65c4ccc6e7b6c466d30c5f7590e412d2" ]] || fail "Téléchargement altéré."
/bin/cat "$release/fragment.tmp" >> "$release/app.asar.unpacked/lib/memory_mcp.py.new"
/bin/mv "$release/app.asar.unpacked/lib/memory_mcp.py.new" "$release/app.asar.unpacked/lib/memory_mcp.py"
/bin/mkdir -p "$release/app.asar.unpacked/lib"
: > "$release/app.asar.unpacked/lib/voiceprint.py.new"
/usr/bin/curl --fail --location --proto "=https" --retry 2 --connect-timeout 15 --max-time 180 "https://liberty-command-updates.pages.dev/releases/20261009-123000/d8e47f89ccd0cf0b61241ad3e4b791bfd9c19d45a4575ef6ffbdf318f517affa.bin" -o "$release/fragment.tmp"
actual=$(/usr/bin/shasum -a 256 "$release/fragment.tmp"); actual=${actual%% *}
[[ "$actual" == "d8e47f89ccd0cf0b61241ad3e4b791bfd9c19d45a4575ef6ffbdf318f517affa" ]] || fail "Téléchargement altéré."
/bin/cat "$release/fragment.tmp" >> "$release/app.asar.unpacked/lib/voiceprint.py.new"
/bin/mv "$release/app.asar.unpacked/lib/voiceprint.py.new" "$release/app.asar.unpacked/lib/voiceprint.py"
/bin/mkdir -p "$release/app.asar.unpacked/lib"
: > "$release/app.asar.unpacked/lib/voxtral_server.py.new"
/usr/bin/curl --fail --location --proto "=https" --retry 2 --connect-timeout 15 --max-time 180 "https://liberty-command-updates.pages.dev/releases/20261009-123000/77fbc5e8f5fc7549d69b4fe818fc5338fc76ef9d03dca59a624345fd0efbfbec.bin" -o "$release/fragment.tmp"
actual=$(/usr/bin/shasum -a 256 "$release/fragment.tmp"); actual=${actual%% *}
[[ "$actual" == "77fbc5e8f5fc7549d69b4fe818fc5338fc76ef9d03dca59a624345fd0efbfbec" ]] || fail "Téléchargement altéré."
/bin/cat "$release/fragment.tmp" >> "$release/app.asar.unpacked/lib/voxtral_server.py.new"
/bin/mv "$release/app.asar.unpacked/lib/voxtral_server.py.new" "$release/app.asar.unpacked/lib/voxtral_server.py"
/bin/rm -f "$release/fragment.tmp"
/bin/cat > "$release/manifest.sha256" <<'MANIFEST'
27eda4539e497e39a575eae5052394032c88f644fcab6baac55458590a069964  app.asar
aa2a420d9d4f317bc869ce2adc1630cb8e6dbcd31ab84f5071aa4d1ebbb68d45  app.asar.unpacked/lib/esme_read.py
80a7a6421780ddc833c6c9c396e7ecf4ce4ea854a61f161b366f0df381d076a7  app.asar.unpacked/lib/journal.py
d9687a249b5fda6e9ad4141c13ffefbc67d877f3edc06cfb7082f3e962ffc320  app.asar.unpacked/lib/journal.test.py
a14f3c01804e1b988ca992d145e3643c65c4ccc6e7b6c466d30c5f7590e412d2  app.asar.unpacked/lib/memory_mcp.py
d8e47f89ccd0cf0b61241ad3e4b791bfd9c19d45a4575ef6ffbdf318f517affa  app.asar.unpacked/lib/voiceprint.py
77fbc5e8f5fc7549d69b4fe818fc5338fc76ef9d03dca59a624345fd0efbfbec  app.asar.unpacked/lib/voxtral_server.py
MANIFEST
/bin/cat > "$release/version.json" <<'VERSION'
{"version": "20261009-123000", "sha256": "27eda4539e497e39a575eae5052394032c88f644fcab6baac55458590a069964", "size": 103678748}
VERSION
[[ -f "$release/manifest.sha256" && -f "$release/version.json" ]] || fail 'Le dossier release est incomplet. Relance le téléchargement cloud.'
version=$(/usr/bin/plutil -extract version raw -o - "$release/version.json")
[[ "$version" == '20261009-123000' ]] || fail 'Ce paquet ne correspond pas à la version attendue.'
while IFS= read -r row; do
 hash=${row%%  *}
 file=${row#*  }
 [[ "$hash" == [0-9a-f]## && ${#hash} == 64 ]] || fail 'Manifeste invalide.'
 [[ "$file" == 'app.asar' || "$file" == app.asar.unpacked/lib/*.py ]] || fail 'Chemin non autorisé dans le paquet.'
 [[ "$file" != *'..'* && "$file" != *$'\r'* ]] || fail 'Chemin invalide dans le paquet.'
 [[ -f "$release/$file" && ! -L "$release/$file" ]] || fail 'Un composant du paquet manque.'
done < "$release/manifest.sha256"
[[ $(/usr/bin/grep -c '  app.asar$' "$release/manifest.sha256") == 1 ]] || fail 'Archive absente du manifeste.'
expected=$(/usr/bin/plutil -extract sha256 raw -o - "$release/version.json")
actual=$(/usr/bin/shasum -a 256 "$release/app.asar"); actual=${actual%% *}
[[ "$expected" == "$actual" ]] || fail 'Archive différente du manifeste de version.'
print -r -- 'Vérification du paquet reçu…'
(cd "$release" && /usr/bin/shasum -a 256 -c manifest.sha256) || fail 'Le paquet est incomplet ou altéré. Aucun fichier modifié.'
[[ -f "$release/app.asar" ]] || fail 'Archive manquante.'
archive_kb=$(( $(/usr/bin/stat -f %z "$release/app.asar") / 1024 + 1 ))
free_kb=$(/bin/df -Pk "$resources" | /usr/bin/awk 'NR==2 {print $4}')
(( free_kb > archive_kb * 3 )) || fail 'Pas assez de place pour garder la version précédente et installer la nouvelle.'
check_closed
backup="$HOME/Library/Application Support/LIBERTY Command/update-backups/$(/bin/date +%Y%m%d-%H%M%S)-airdrop"
/bin/mkdir -p "$backup"
/bin/chmod 700 "$backup"
/bin/cp -p "$resources/app.asar" "$backup/app.asar"
if [[ -d "$resources/app.asar.unpacked" ]]; then /usr/bin/ditto "$resources/app.asar.unpacked" "$backup/app.asar.unpacked"; fi
print -r -- 'Installation du programme uniquement — tes données et tes clés sont conservées…'
/bin/cp "$release/app.asar" "$resources/app.asar.new"
changed=1
/usr/bin/ditto "$release/app.asar.unpacked" "$resources/app.asar.unpacked"
/bin/mv -f "$resources/app.asar.new" "$resources/app.asar"
(cd "$resources" && /usr/bin/shasum -a 256 -c "$release/manifest.sha256") || fail 'La vérification finale a échoué.'
print -r -- "{\"version\":\"$version\",\"at\":\"$(/bin/date -u +%Y-%m-%dT%H:%M:%SZ)\"}" > "$HOME/Library/Application Support/LIBERTY Command/installed-release.json"
changed=0
print -r -- "Mise à jour réussie : $version"
print -r -- 'Command va s’ouvrir. Vérifie Paramètres → Général : version 20261009-123000.'
/usr/bin/open -n "$app"
print -r -- 'Appuie sur Entrée pour fermer cette fenêtre.'
read -r response || true
