init: pi-extensions with ssh-controlmaster
This commit is contained in:
Executable
+153
@@ -0,0 +1,153 @@
|
||||
#!/usr/bin/env bash
|
||||
# install.sh — install pi-extensions
|
||||
#
|
||||
# Symlinks each extension in extensions/ into ~/.pi/agent/extensions/ so pi
|
||||
# loads them automatically on every session. Idempotent and non-destructive.
|
||||
#
|
||||
# Usage:
|
||||
# ./install.sh # install (interactive confirm)
|
||||
# ./install.sh --yes # install without prompt
|
||||
# ./install.sh --uninstall # remove symlinks that point into this repo
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
EXTENSIONS_SRC="${SCRIPT_DIR}/extensions"
|
||||
EXTENSIONS_DEST="${HOME}/.pi/agent/extensions"
|
||||
PI_AGENT_DIR="${HOME}/.pi/agent"
|
||||
|
||||
# ── helpers ──────────────────────────────────────────
|
||||
ok() { printf ' \e[32m✓\e[0m %s\n' "$*"; }
|
||||
note() { printf '==> %s\n' "$*"; }
|
||||
warn() { printf ' \e[33m!\e[0m %s\n' "$*" >&2; }
|
||||
err() { printf ' \e[31m✗\e[0m %s\n' "$*" >&2; }
|
||||
|
||||
confirm() {
|
||||
[[ "$ASSUME_YES" == "yes" ]] && return 0
|
||||
read -r -p "Proceed? [y/N] " ans
|
||||
[[ "$ans" =~ ^[Yy]$ ]]
|
||||
}
|
||||
|
||||
link_into_repo() {
|
||||
local target
|
||||
[[ -L "$1" ]] || return 1
|
||||
target=$(readlink -f "$1" 2>/dev/null || true)
|
||||
[[ "$target" == "$SCRIPT_DIR"/* ]]
|
||||
}
|
||||
|
||||
require_pi_installed() {
|
||||
if [[ ! -d "$PI_AGENT_DIR" ]]; then
|
||||
err "pi not detected at $PI_AGENT_DIR"
|
||||
printf ' Install pi first: https://github.com/mariozechner/pi-coding-agent\n'
|
||||
printf ' Re-run after `pi --help` (first run creates ~/.pi/agent/).\n'
|
||||
exit 4
|
||||
fi
|
||||
mkdir -p "$EXTENSIONS_DEST"
|
||||
ok "pi detected at $PI_AGENT_DIR"
|
||||
}
|
||||
|
||||
# ── args ─────────────────────────────────────────────
|
||||
ACTION="install"
|
||||
ASSUME_YES="no"
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--uninstall) ACTION="uninstall"; shift ;;
|
||||
-y|--yes) ASSUME_YES="yes"; shift ;;
|
||||
-h|--help)
|
||||
cat <<EOF
|
||||
install.sh — install pi-extensions
|
||||
|
||||
Usage:
|
||||
./install.sh install (interactive confirm)
|
||||
./install.sh --yes install without prompt
|
||||
./install.sh --uninstall remove symlinks that point into this repo
|
||||
|
||||
Each .ts file in extensions/ is symlinked into ~/.pi/agent/extensions/.
|
||||
Existing files that are already symlinked into this repo are left alone.
|
||||
Existing real files or foreign symlinks are backed up with a timestamp.
|
||||
EOF
|
||||
exit 0 ;;
|
||||
*) echo "Unknown flag: $1" >&2; exit 2 ;;
|
||||
esac
|
||||
done
|
||||
|
||||
# ── install ──────────────────────────────────────────
|
||||
do_install() {
|
||||
echo
|
||||
echo "pi-extensions installer"
|
||||
echo "Repository: $SCRIPT_DIR"
|
||||
echo
|
||||
|
||||
require_pi_installed
|
||||
|
||||
local extensions=("${EXTENSIONS_SRC}"/*.ts)
|
||||
if [[ ! -e "${extensions[0]}" ]]; then
|
||||
warn "No .ts files found in ${EXTENSIONS_SRC}/ — nothing to install."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "==> Extensions to symlink into ${EXTENSIONS_DEST}/:"
|
||||
for src in "${extensions[@]}"; do
|
||||
printf ' %s\n' "$(basename "$src")"
|
||||
done
|
||||
echo
|
||||
confirm || { echo "Aborted."; exit 0; }
|
||||
echo
|
||||
|
||||
for src in "${extensions[@]}"; do
|
||||
local name
|
||||
name="$(basename "$src")"
|
||||
local dest="${EXTENSIONS_DEST}/${name}"
|
||||
|
||||
note "Linking ${name}"
|
||||
|
||||
if [[ -e "$dest" || -L "$dest" ]]; then
|
||||
if link_into_repo "$dest"; then
|
||||
ok "${name} already linked"
|
||||
continue
|
||||
fi
|
||||
local backup="${dest}.bak.$(date +%Y%m%d-%H%M%S)"
|
||||
mv "$dest" "$backup"
|
||||
warn "Existing ${dest} backed up to ${backup}"
|
||||
fi
|
||||
|
||||
ln -s "$src" "$dest"
|
||||
ok "Linked ${name} → ${src}"
|
||||
done
|
||||
|
||||
echo
|
||||
ok "Done. Reload pi with /reload or restart to pick up new extensions."
|
||||
}
|
||||
|
||||
# ── uninstall ────────────────────────────────────────
|
||||
do_uninstall() {
|
||||
echo
|
||||
echo "pi-extensions uninstaller"
|
||||
echo "Repository: $SCRIPT_DIR"
|
||||
echo
|
||||
confirm || { echo "Aborted."; exit 0; }
|
||||
echo
|
||||
|
||||
local removed=0
|
||||
for dest in "${EXTENSIONS_DEST}"/*.ts; do
|
||||
[[ -e "$dest" || -L "$dest" ]] || continue
|
||||
if link_into_repo "$dest"; then
|
||||
rm "$dest"
|
||||
ok "Removed $(basename "$dest")"
|
||||
(( removed++ )) || true
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ $removed -eq 0 ]]; then
|
||||
ok "No symlinks pointing into this repo found — nothing removed."
|
||||
else
|
||||
echo
|
||||
ok "Done. Removed ${removed} symlink(s)."
|
||||
fi
|
||||
}
|
||||
|
||||
case "$ACTION" in
|
||||
install) do_install ;;
|
||||
uninstall) do_uninstall ;;
|
||||
esac
|
||||
Reference in New Issue
Block a user