#!/usr/bin/env bash set -euo pipefail repository_directory=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd) dsh_home="$HOME/.dsh" profile_directory="$dsh_home/profiles/web" state_directory=${XDG_STATE_HOME:-"$HOME/.local/state"}/dsh-arch-setup managed_manifest="$state_directory/managed.tsv" backup_manifest="$state_directory/backups.tsv" skip_host_integration=${DSH_SETUP_SKIP_HOST_INTEGRATION:-0} for argument in "$@"; do case "$argument" in --test-mode) skip_host_integration=1 ;; *) printf 'Unknown option: %s\n' "$argument" >&2; exit 2 ;; esac done if [[ ! -f "$managed_manifest" && ! -f "$state_directory/partial.tsv" ]]; then printf 'No DSH Arch Setup installation is recorded for this user. Nothing was removed.\n' exit 0 fi if [[ "$skip_host_integration" != 1 ]]; then systemctl --user disable --now dsh-web.service >/dev/null 2>&1 || true fi if [[ ! -f "$state_directory/editor-preexisting" ]]; then rm -rf "$dsh_home/touched-git/editor/extensions" fi if [[ ! -f "$state_directory/runtime-preexisting" ]]; then rm -rf "$repository_directory/plugins/dsh-touched-git/runtime" fi if [[ ! -f "$state_directory/plugin-dependencies-preexisting" ]]; then rm -rf "$repository_directory/plugins/dsh-touched-git/node_modules" fi if [[ ! -f "$state_directory/profile-preexisting" ]]; then rm -rf "$profile_directory/node_modules" fi partial_manifest="$state_directory/partial.tsv" if [[ -f "$managed_manifest" || -f "$partial_manifest" ]]; then { [[ ! -f "$managed_manifest" ]] || cat "$managed_manifest"; [[ ! -f "$partial_manifest" ]] || cat "$partial_manifest"; } | tac | awk -F '\t' '!seen[$2]++' | while IFS=$'\t' read -r kind destination expected; do case "$kind" in link) if [[ -L "$destination" && "$(readlink -f "$destination")" == "$(readlink -f "$expected")" ]]; then rm "$destination" else printf 'Preserved changed path: %s\n' "$destination" fi ;; file) if [[ -f "$destination" && "$(sha256sum "$destination" | cut -d ' ' -f 1)" == "$expected" ]]; then rm "$destination" elif [[ -e "$destination" || -L "$destination" ]]; then printf 'Preserved modified file: %s\n' "$destination" fi ;; esac done fi if [[ -f "$backup_manifest" ]]; then tac "$backup_manifest" | while IFS=$'\t' read -r destination backup; do if [[ ! -e "$destination" && ! -L "$destination" && ( -e "$backup" || -L "$backup" ) ]]; then mkdir -p "$(dirname "$destination")" mv "$backup" "$destination" fi done fi if [[ ! -f "$state_directory/dsh-preexisting" ]] && command -v npm >/dev/null 2>&1; then npm uninstall --global --prefix "$HOME/.local" @deepseek-ai/dsh >/dev/null 2>&1 || true fi if [[ "$skip_host_integration" != 1 ]]; then systemctl --user daemon-reload command -v update-desktop-database >/dev/null 2>&1 && update-desktop-database "$HOME/.local/share/applications" command -v gtk-update-icon-cache >/dev/null 2>&1 && gtk-update-icon-cache --force "$HOME/.local/share/icons/hicolor" >/dev/null 2>&1 || true fi if [[ -d "$state_directory/backups" ]] && find "$state_directory/backups" \( -type f -o -type l \) -print -quit | grep -q .; then printf 'Some backups remain in %s because their destinations were modified.\n' "$state_directory/backups" else rm -rf "$state_directory" fi printf 'DSH managed installation removed. Credentials, sessions, and user data were preserved.\n'