#!/usr/bin/env bash # replace the community ChatGPT Desktop build with the official OpenAI package # # `panama app chatgpt-desktop` used to build a community wrapper (codex-desktop) # from the upstream macOS disk image, complete with a local rebuild daemon. # OpenAI ships an official Linux RPM now, and the installer takes that instead; # this repairs machines still carrying the community build. The official # package goes on before the community one comes off, so a failure part-way # leaves the machine with an app, never without one. # # Rules, because the runner cannot enforce them: # # * Safe to run twice. The marker records success, not intent. # * Tolerant of the repair already being correct -- the user may have fixed # it by hand, or a later ./install may have put it back. # * Root work goes through `panama-sudo --reason "..."`, never bare sudo, # so the password prompt names the repair. # * Exit non-zero to be retried at the next login. Exit zero only when the # machine is genuinely in the state this describes. set -euo pipefail PANAMA_PATH="${PANAMA_PATH:-$HOME/.local/share/Panama}" # Machines that never had the community build are already correct. The official # app is the installer's job, not this one's. rpm -q codex-desktop >/dev/null 2>&1 || exit 0 # The same verified repository the installer establishes: the pinned signing # key, then a repository that names it, so dnf checks OpenAI's signature before # root installs anything. See setup/lib/chatgpt-package. # shellcheck source=../setup/lib/chatgpt-package source "$PANAMA_PATH/setup/lib/chatgpt-package" sudo_cmd=(sudo) if [[ -t 0 && -x "$PANAMA_PATH/bin/panama-sudo" ]]; then sudo_cmd=( "$PANAMA_PATH/bin/panama-sudo" --reason "Replacing the community-built ChatGPT Desktop (codex-desktop) with the official OpenAI package" -- ) fi # The official package first, so the machine is never left without one. if ! rpm -q chatgpt >/dev/null 2>&1; then chatgpt_install_repository "${sudo_cmd[@]}" "${sudo_cmd[@]}" dnf install -y chatgpt fi # The community package's updater is a user unit; stop it before dnf removes # the unit file out from under it. Removal also takes the app in /opt, both # binaries, and the polkit policy the local rebuilds needed. systemctl --user disable --now codex-update-manager.service 2>/dev/null || true "${sudo_cmd[@]}" dnf remove -y codex-desktop systemctl --user daemon-reload 2>/dev/null || true # The rebuild state the updater kept; the official package needs none of it. rm -rf "${XDG_CACHE_HOME:-$HOME/.cache}/codex-update-manager" \ "${XDG_CACHE_HOME:-$HOME/.cache}/codex-runtimes" \ "${XDG_CONFIG_HOME:-$HOME/.config}/codex-update-manager" \ "${XDG_STATE_HOME:-$HOME/.local/state}/codex-update-manager" echo "Replaced the community codex-desktop build with the official chatgpt package."