#!/usr/bin/env bash # # pi-kit uninstall — removes the corporate kit from this machine completely. # Idempotent: safe to re-run; missing pieces are skipped with a note. # # Usage (one command, asks for confirmation): # curl -fsSL https://git.codelab.vc/ai/pi-kit/raw/branch/stable/uninstall.sh | bash # # or, from a checkout: # ./uninstall.sh # # What it removes: # 1. the pi-kit package entry from ~/.pi/agent/settings.json and its clone # (~/.pi/agent/git/git.codelab.vc/ai/pi-kit); # 2. public skills the kit installed into ~/.agents/skills/ # (grill-me, grill-with-docs, code-review, diagnosing-bugs, frontend-design); # 3. ~/.config/pi-kit (env.sh with tokens, audit.jsonl) and the sourcing block # it added to your shell rc — only if you confirm (or unless kept). # # Non-interactive / skip confirmation: PI_KIT_UNINSTALL=1 # Keep secrets & rc block: PI_KIT_KEEP_CONFIG=1 # Keep public skills: PI_KIT_KEEP_SKILLS=1 # # Pi itself is NOT removed (it may be used outside the kit). See the final note. # set -euo pipefail # Mirrors the list in install.sh (COMMON_PUBLIC_SKILLS + PROFILE_PUBLIC). PUBLIC_SKILLS=("grill-me" "grill-with-docs" "code-review" "diagnosing-bugs" "frontend-design") SETTINGS="$HOME/.pi/agent/settings.json" CONFIG_DIR="$HOME/.config/pi-kit" ENV_FILE="$CONFIG_DIR/env.sh" RC_MARK=">>> pi-kit >>>" RC_MARK_END="<<< pi-kit <<<" info() { printf '\033[1;34m==>\033[0m %s\n' "$*"; } warn() { printf '\033[1;33m[!]\033[0m %s\n' "$*"; } err() { printf '\033[1;31m[x]\033[0m %s\n' "$*" >&2; } case "${1:-}" in -h | --help) cat <<'EOF' Удаляет pi-kit полностью: пакет из настроек pi, его клон, публичные скилы, ~/.config/pi-kit (env.sh с токенами) и блок в shell-rc. Использование: curl -fsSL https://git.codelab.vc/ai/pi-kit/raw/branch/stable/uninstall.sh | bash Флаги: PI_KIT_UNINSTALL=1 не спрашивать подтверждение (для CI/автоматизации) PI_KIT_KEEP_CONFIG=1 оставить ~/.config/pi-kit (токены) и блок в rc PI_KIT_KEEP_SKILLS=1 оставить публичные скилы в ~/.agents/skills EOF exit 0 ;; esac detect_rc() { case "$(basename "${SHELL:-}")" in zsh) echo "$HOME/.zshrc" ;; bash) echo "$HOME/.bashrc" ;; *) echo "$HOME/.profile" ;; esac } # --- 1. Confirmation --------------------------------------------------------- summary_parts=("пакет pi-kit из настроек pi (settings.json + клон)") if [ "${PI_KIT_KEEP_SKILLS:-0}" != "1" ]; then summary_parts+=("публичные скилы кита в ~/.agents/skills: ${PUBLIC_SKILLS[*]}") fi if [ "${PI_KIT_KEEP_CONFIG:-0}" != "1" ]; then summary_parts+=("~/.config/pi-kit (env.sh с токенами, audit.jsonl)") summary_parts+=("блок '${RC_MARK}' в $(detect_rc)") fi if [ "${PI_KIT_UNINSTALL:-0}" != "1" ]; then if [ ! -r /dev/tty ]; then err "Нет терминала для подтверждения. Для неинтерактивного удаления задай PI_KIT_UNINSTALL=1." exit 1 fi { printf 'Будет удалено:\n' for s in "${summary_parts[@]}"; do printf ' • %s\n' "$s"; done printf '\nУдалить pi-kit полностью? [y/N] ' } >/dev/tty read -r ans /dev/null 2>&1; then SETTINGS_FILE="$SETTINGS" node <<'NODE' const fs = require("fs"); const file = process.env.SETTINGS_FILE; const s = JSON.parse(fs.readFileSync(file, "utf8")); if (!Array.isArray(s.packages)) process.exit(0); const before = s.packages.length; s.packages = s.packages.filter((p) => { const src = typeof p === "string" ? p : (p && p.source); return !(typeof src === "string" && src.includes("pi-kit")); }); if (s.packages.length === before) process.exit(0); fs.writeFileSync(file, JSON.stringify(s, null, 2) + "\n"); console.log("removed pi-kit entry from " + file); NODE else warn "node не найден — пропускаю правку settings.json. Удали пакет вручную:" warn " pi remove git:git.codelab.vc/ai/pi-kit@<твой канал>" fi else warn "settings.json не найден ($SETTINGS) — пропускаю." fi # --- 3. Remove the pi-kit clone ------------------------------------------------- # install.sh installs `git:git.codelab.vc/ai/pi-kit@` → clone at # ~/.pi/agent/git/git.codelab.vc/ai/pi-kit. Also catch any other pi-kit clone. CLONE_DIR="$HOME/.pi/agent/git/git.codelab.vc/ai/pi-kit" if [ -d "$CLONE_DIR" ]; then rm -rf "$CLONE_DIR" info "Удалён клон пакета: $CLONE_DIR" else warn "Клон пакета не найден ($CLONE_DIR) — пропускаю." fi if [ -d "$HOME/.pi/agent/git" ]; then while IFS= read -r d; do if [ "$d" != "$CLONE_DIR" ] && [ -d "$d" ]; then rm -rf "$d" info "Удалён дополнительный клон: $d" fi done < <(find "$HOME/.pi/agent/git" -maxdepth 4 -type d -name pi-kit 2>/dev/null || true) fi # --- 4. Public skills ---------------------------------------------------------- if [ "${PI_KIT_KEEP_SKILLS:-0}" != "1" ]; then for skill in "${PUBLIC_SKILLS[@]}"; do dir="$HOME/.agents/skills/$skill" if [ -e "$dir" ]; then rm -rf "$dir" info "Удалён публичный скилл: $dir" else info "Скилл не был установлен (пропускаю): $skill" fi done else info "PI_KIT_KEEP_SKILLS=1 — публичные скилы оставлены." fi # --- 5. Config dir (secrets) + shell rc block --------------------------------- if [ "${PI_KIT_KEEP_CONFIG:-0}" != "1" ]; then if [ -d "$CONFIG_DIR" ]; then rm -rf "$CONFIG_DIR" info "Удалён ~/.config/pi-kit (env.sh с токенами, audit.jsonl)." else warn "~/.config/pi-kit не найден — пропускаю." fi rc="$(detect_rc)" if [ -f "$rc" ] && grep -qF "$RC_MARK" "$rc" 2>/dev/null; then awk -v start="$RC_MARK" -v end="$RC_MARK_END" ' $0 ~ start { skip = 1 } !skip { print } $0 ~ end { skip = 0 } ' "$rc" >"$rc.tmp" && mv "$rc.tmp" "$rc" info "Убран блок pi-kit из $rc." else warn "Блок pi-kit в $(detect_rc) не найден — пропускаю." fi else info "PI_KIT_KEEP_CONFIG=1 — ~/.config/pi-kit и rc-блок оставлены." fi # --- 6. Final note -------------------------------------------------------------- cat <