#!/usr/bin/env bash # install.sh - copy this repo's extensions into the global pi extensions dir. # # Copies (does not symlink) every *.ts here into ~/.pi/agent/extensions so the # global set is a deliberate snapshot, not live-linked to in-progress dev edits. # Files already identical at the destination are skipped. # After installing, use /reload inside a running pi session to pick them up. # # Also installs the standalone CLI helpers in scripts/ into ~/bin (override with # PI_BIN_DIR), same copy-not-symlink policy. # # Override the target dir with PI_EXT_DIR, e.g: # PI_EXT_DIR=~/.config/pi/agent/extensions ./install.sh # # Flags: # -n, --dry-run show what would be copied without writing set -euo pipefail cd "$(dirname "$0")" DEST="${PI_EXT_DIR:-$HOME/.pi/agent/extensions}" BIN_DEST="${PI_BIN_DIR:-$HOME/bin}" # Standalone CLI tools: ":" # answer-picker.ts needs no helper binary any more: zellij draws and hit-tests # the buttons itself (OSC 5577) and reports clicks on pi's stdin. The previous # socket+separate-pane implementation is kept, unwired, in attic/ — attic is not # globbed by this script, so nothing there is installed. CLI_TOOLS=( "pi-resume:pir" ) dry_run=0 case "${1:-}" in -n|--dry-run) dry_run=1 ;; "") ;; *) echo "install.sh: unknown arg '$1'" >&2; exit 2 ;; esac # Extensions to NOT install globally (dev-only / experimental / broken). EXCLUDE=( sixel-images.ts ) is_excluded() { local f="$1" x for x in "${EXCLUDE[@]}"; do [ "$f" = "$x" ] && return 0; done return 1 } shopt -s nullglob all=(*.ts) shopt -u nullglob files=() for f in "${all[@]}"; do is_excluded "$f" && { echo "excluded (dev-only) $f" >&2; continue; } files+=("$f") done if [ "${#files[@]}" -eq 0 ]; then echo "install.sh: no *.ts extensions found in $(pwd)" >&2 exit 1 fi if [ "$dry_run" -eq 1 ]; then echo "Would sync ${#files[@]} extension(s) into: $DEST" for f in "${files[@]}"; do if cmp -s "$f" "$DEST/$f"; then echo " skip (identical) $f" else echo " copy $f" fi done echo "Would sync ${#CLI_TOOLS[@]} CLI tool(s) into: $BIN_DEST" for spec in "${CLI_TOOLS[@]}"; do src="scripts/${spec%%:*}"; name="${spec##*:}" if cmp -s "$src" "$BIN_DEST/$name"; then echo " skip (identical) $name" else echo " copy $name" fi done exit 0 fi mkdir -p "$DEST" copied=0 for f in "${files[@]}"; do if cmp -s "$f" "$DEST/$f"; then echo "skipped (identical) $f" continue fi cp "$f" "$DEST/$f" echo "installed $f -> $DEST/$f" copied=$((copied + 1)) done mkdir -p "$BIN_DEST" for spec in "${CLI_TOOLS[@]}"; do src="scripts/${spec%%:*}"; name="${spec##*:}" [ -f "$src" ] || { echo "install.sh: missing $src" >&2; continue; } if cmp -s "$src" "$BIN_DEST/$name"; then echo "skipped (identical) $name" continue fi cp "$src" "$BIN_DEST/$name" chmod +x "$BIN_DEST/$name" echo "installed $name -> $BIN_DEST/$name" copied=$((copied + 1)) done echo if [ "$copied" -eq 0 ]; then echo "Nothing changed; global set already up to date." else echo "Done ($copied changed). Run /reload in a pi session (or restart pi) to load them." fi