2026-05-13 11:44:26 +09:00
|
|
|
#!/usr/bin/env bash
|
|
|
|
|
# shellcheck disable=SC2086
|
|
|
|
|
|
|
|
|
|
# Installs Pi Coding Agent and recommended packages.
|
|
|
|
|
# Pi: https://pi.dev
|
|
|
|
|
#
|
|
|
|
|
# Supported platforms:
|
|
|
|
|
# macOS : Apple Silicon (arm64), Intel (x86_64)
|
|
|
|
|
# Linux : x86_64, aarch64
|
|
|
|
|
#
|
|
|
|
|
# Prerequisites:
|
|
|
|
|
# - Node.js 18+ (and npm)
|
|
|
|
|
# - curl
|
|
|
|
|
|
|
|
|
|
set -euo pipefail
|
|
|
|
|
|
|
|
|
|
# ────────────────────────────────────────────
|
|
|
|
|
# Constants
|
|
|
|
|
# ────────────────────────────────────────────
|
|
|
|
|
PI_INSTALL_URL="https://pi.dev/install.sh"
|
|
|
|
|
PI_NPM_PACKAGE="@earendil-works/pi-coding-agent"
|
|
|
|
|
|
|
|
|
|
# Packages to install after pi is available
|
|
|
|
|
# Format: "package_name|description"
|
|
|
|
|
PACKAGES=(
|
2026-05-13 15:59:11 +09:00
|
|
|
"pi-subagents|Delegate work to focused child agents — code review, scouting, implementation, parallel audits, orchestration, background jobs"
|
|
|
|
|
"context-mode|Context window protection — sandbox tools, session continuity, BM25 knowledge base, think-in-code paradigm"
|
|
|
|
|
"pi-mcp-adapter|Use MCP servers with Pi without burning your context window — one proxy tool instead of hundreds"
|
|
|
|
|
"pi-web-access|Web search, content extraction, and video understanding — zero-config Exa search, Perplexity, Gemini, YouTube"
|
|
|
|
|
"@plannotator/pi-extension|File-based plan mode with visual browser UI for reviewing, annotating, and approving agent plans"
|
|
|
|
|
"@juicesharp/rpiv-ask-user-question|Structured questionnaire tool with typed options — the model asks you instead of guessing"
|
|
|
|
|
"pi-lens|Real-time code feedback — LSP diagnostics, linters, formatters, type-checking, structural analysis, read-before-edit guard"
|
|
|
|
|
"@juicesharp/rpiv-todo|Persistent todo list across sessions — tasks survive /reload and compaction with dependency tracking"
|
|
|
|
|
"pi-simplify|Review recently changed code for clarity, consistency, and maintainability improvements"
|
|
|
|
|
"@juicesharp/rpiv-advisor|Second opinion from a stronger reviewer model before the agent acts"
|
|
|
|
|
"@juicesharp/rpiv-pi|Skill-based development workflow — discover, research, design, plan, implement, validate pipeline with named subagents"
|
|
|
|
|
"@samfp/pi-memory|Persistent memory for Pi — learns corrections, preferences, and project patterns across sessions"
|
|
|
|
|
"pi-btw|Parallel side conversations (/btw) without interrupting the main agent run"
|
|
|
|
|
"pi-docparser|Document parsing tool — PDFs, Office docs, spreadsheets, images, and OCR via LiteParse"
|
|
|
|
|
"pi-ollama-cloud|Ollama Cloud provider plugin — dynamic model discovery, web search and fetch tools, no local server required"
|
2026-05-13 11:44:26 +09:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
# ────────────────────────────────────────────
|
|
|
|
|
# Utility functions (all stderr output)
|
|
|
|
|
# ────────────────────────────────────────────
|
2026-05-13 15:59:11 +09:00
|
|
|
info() { echo "[INFO] $*" >&2; }
|
|
|
|
|
warn() { echo "[WARN] $*" >&2; }
|
|
|
|
|
error() {
|
|
|
|
|
echo "[ERROR] $*" >&2
|
|
|
|
|
exit 1
|
|
|
|
|
}
|
2026-05-13 11:44:26 +09:00
|
|
|
success() { echo "[OK] $*" >&2; }
|
|
|
|
|
|
|
|
|
|
# ────────────────────────────────────────────
|
|
|
|
|
# Check required commands
|
|
|
|
|
# ────────────────────────────────────────────
|
|
|
|
|
for cmd in curl; do
|
2026-05-13 15:59:11 +09:00
|
|
|
command -v "$cmd" &>/dev/null || error "'$cmd' is required."
|
2026-05-13 11:44:26 +09:00
|
|
|
done
|
|
|
|
|
|
|
|
|
|
# ────────────────────────────────────────────
|
|
|
|
|
# Detect OS / Architecture
|
|
|
|
|
# ────────────────────────────────────────────
|
|
|
|
|
OS="$(uname -s)"
|
|
|
|
|
ARCH="$(uname -m)"
|
|
|
|
|
|
|
|
|
|
case "$OS" in
|
2026-05-13 15:59:11 +09:00
|
|
|
Darwin | Linux) ;;
|
|
|
|
|
*)
|
|
|
|
|
error "Unsupported OS: $OS. This script only supports macOS and Linux."
|
|
|
|
|
;;
|
2026-05-13 11:44:26 +09:00
|
|
|
esac
|
|
|
|
|
|
|
|
|
|
info "Platform: $OS ($ARCH)"
|
|
|
|
|
|
|
|
|
|
# ────────────────────────────────────────────
|
|
|
|
|
# Step 1: Install Pi Coding Agent
|
|
|
|
|
# ────────────────────────────────────────────
|
|
|
|
|
info "Installing Pi Coding Agent..."
|
|
|
|
|
|
|
|
|
|
if command -v pi &>/dev/null; then
|
2026-05-13 15:59:11 +09:00
|
|
|
CURRENT_VER="$(pi --version 2>/dev/null || echo 'unknown')"
|
|
|
|
|
info "Pi is already installed (version: $CURRENT_VER). Skipping installation."
|
2026-05-13 11:44:26 +09:00
|
|
|
else
|
2026-05-13 15:59:11 +09:00
|
|
|
# Try curl-based installer first
|
|
|
|
|
if curl -fsSL "$PI_INSTALL_URL" 2>/dev/null | sh; then
|
|
|
|
|
success "Pi installed via curl installer"
|
|
|
|
|
else
|
|
|
|
|
# Fallback to npm
|
|
|
|
|
info "curl install failed. Falling back to npm..."
|
|
|
|
|
command -v npm &>/dev/null || error "npm is required. Install Node.js 18+: https://nodejs.org/"
|
|
|
|
|
npm install -g "$PI_NPM_PACKAGE"
|
|
|
|
|
success "Pi installed via npm"
|
|
|
|
|
fi
|
2026-05-13 11:44:26 +09:00
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
# ────────────────────────────────────────────
|
2026-05-13 15:59:11 +09:00
|
|
|
# Resolve pi binary path (may not be in PATH yet after fresh install)
|
|
|
|
|
# ────────────────────────────────────────────
|
|
|
|
|
PI_BIN=""
|
|
|
|
|
|
|
|
|
|
# 1) Try current PATH
|
|
|
|
|
if command -v pi &>/dev/null; then
|
|
|
|
|
PI_BIN="$(command -v pi)"
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
# 2) Try expanding common locations where npm/pip install globally
|
|
|
|
|
if [ -z "$PI_BIN" ]; then
|
|
|
|
|
for candidate in \
|
|
|
|
|
"$HOME/.local/bin/pi" \
|
|
|
|
|
"$HOME/.npm/bin/pi" \
|
|
|
|
|
"/usr/local/bin/pi" \
|
|
|
|
|
"$HOME/.nvm/versions/node/$(ls "$HOME/.nvm/versions/node/" 2>/dev/null | tail -1)/bin/pi" \
|
|
|
|
|
"$NVM_DIR/versions/node/$(ls "$NVM_DIR/versions/node/" 2>/dev/null | tail -1)/bin/pi"; do
|
|
|
|
|
if [ -x "$candidate" ]; then
|
|
|
|
|
PI_BIN="$candidate"
|
|
|
|
|
break
|
|
|
|
|
fi
|
|
|
|
|
done
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
# 3) Try npm prefix to locate the global bin
|
|
|
|
|
if [ -z "$PI_BIN" ] && command -v npm &>/dev/null; then
|
|
|
|
|
NPM_PREFIX="$(npm config get prefix 2>/dev/null || true)"
|
|
|
|
|
if [ -n "$NPM_PREFIX" ] && [ -x "$NPM_PREFIX/bin/pi" ]; then
|
|
|
|
|
PI_BIN="$NPM_PREFIX/bin/pi"
|
|
|
|
|
fi
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
# Add pi's directory to PATH for this session so pi install subprocess works
|
|
|
|
|
if [ -n "$PI_BIN" ]; then
|
|
|
|
|
PI_DIR="$(dirname "$PI_BIN")"
|
|
|
|
|
case ":$PATH:" in
|
|
|
|
|
*":$PI_DIR:"*) ;; # already in PATH
|
|
|
|
|
*)
|
|
|
|
|
export PATH="$PI_DIR:$PATH"
|
|
|
|
|
info "Added $PI_DIR to PATH for this session"
|
|
|
|
|
;;
|
|
|
|
|
esac
|
|
|
|
|
success "Pi is available: $PI_BIN"
|
|
|
|
|
else
|
|
|
|
|
error "'pi' command not found. Check your PATH or reinstall Node.js."
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
# ────────────────────────────────────────────
|
|
|
|
|
# Step 2: Install packages using the resolved pi binary
|
2026-05-13 11:44:26 +09:00
|
|
|
# ────────────────────────────────────────────
|
|
|
|
|
info ""
|
|
|
|
|
info "Installing Pi packages..."
|
|
|
|
|
info "────────────────────────────────────────"
|
|
|
|
|
|
|
|
|
|
TOTAL=${#PACKAGES[@]}
|
|
|
|
|
COUNT=0
|
|
|
|
|
FAILED=()
|
|
|
|
|
|
|
|
|
|
for entry in "${PACKAGES[@]}"; do
|
2026-05-13 15:59:11 +09:00
|
|
|
PKG="${entry%%|*}"
|
|
|
|
|
DESC="${entry#*|}"
|
|
|
|
|
COUNT=$((COUNT + 1))
|
2026-05-13 11:44:26 +09:00
|
|
|
|
2026-05-13 15:59:11 +09:00
|
|
|
info "[$COUNT/$TOTAL] $PKG — $DESC"
|
|
|
|
|
if "$PI_BIN" install "npm:$PKG" 2>&1; then
|
|
|
|
|
success " → $PKG installed"
|
|
|
|
|
else
|
|
|
|
|
warn " → $PKG failed (install manually later: pi install npm:$PKG)"
|
|
|
|
|
FAILED+=("$PKG")
|
|
|
|
|
fi
|
2026-05-13 11:44:26 +09:00
|
|
|
done
|
|
|
|
|
|
|
|
|
|
info ""
|
|
|
|
|
info "────────────────────────────────────────"
|
|
|
|
|
if [ ${#FAILED[@]} -eq 0 ]; then
|
2026-05-13 15:59:11 +09:00
|
|
|
success "All packages installed! ($TOTAL/$TOTAL)"
|
2026-05-13 11:44:26 +09:00
|
|
|
else
|
2026-05-13 15:59:11 +09:00
|
|
|
warn "Some packages failed to install:"
|
|
|
|
|
for pkg in "${FAILED[@]}"; do
|
|
|
|
|
warn " - $pkg"
|
|
|
|
|
done
|
|
|
|
|
info "You can install failed packages manually with:"
|
|
|
|
|
for pkg in "${FAILED[@]}"; do
|
|
|
|
|
info " pi install npm:$pkg"
|
|
|
|
|
done
|
2026-05-13 11:44:26 +09:00
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
# ────────────────────────────────────────────
|
|
|
|
|
# Step 3: Post-install notes
|
|
|
|
|
# ────────────────────────────────────────────
|
|
|
|
|
info ""
|
|
|
|
|
info "══════════════════════════════════════════"
|
|
|
|
|
success "Pi Coding Agent installation complete!"
|
|
|
|
|
info "══════════════════════════════════════════"
|
|
|
|
|
info ""
|
2026-05-13 15:59:11 +09:00
|
|
|
info "Pi binary: $PI_BIN"
|
|
|
|
|
info ""
|
|
|
|
|
if [ -n "$PI_DIR" ]; then
|
|
|
|
|
case ":$PATH:" in
|
|
|
|
|
*":$PI_DIR:"*) ;;
|
|
|
|
|
*)
|
|
|
|
|
SHELL_RC=""
|
|
|
|
|
if [ -f "$HOME/.bashrc" ]; then SHELL_RC="$HOME/.bashrc"; elif [ -f "$HOME/.zshrc" ]; then SHELL_RC="$HOME/.zshrc"; fi
|
|
|
|
|
if [ -n "$SHELL_RC" ]; then
|
|
|
|
|
info "NOTE: Add $PI_DIR to your PATH permanently by running:"
|
|
|
|
|
info " echo 'export PATH=\"$PI_DIR:\$PATH\"' >> $SHELL_RC"
|
|
|
|
|
info " source $SHELL_RC"
|
|
|
|
|
fi
|
|
|
|
|
;;
|
|
|
|
|
esac
|
|
|
|
|
fi
|
|
|
|
|
info ""
|
2026-05-13 11:44:26 +09:00
|
|
|
info "Getting started:"
|
|
|
|
|
info " 1. Navigate to your project: cd /path/to/project"
|
|
|
|
|
info " 2. Start Pi: pi"
|
|
|
|
|
info " 3. Log in: /login"
|
|
|
|
|
info ""
|
|
|
|
|
info "Useful commands:"
|
|
|
|
|
info " pi — Start interactive session"
|
|
|
|
|
info " pi -p '...' — Ask a single question (print mode)"
|
|
|
|
|
info " pi --help — Show help"
|
|
|
|
|
info ""
|
|
|
|
|
info "List installed packages:"
|
|
|
|
|
info " pi list — Show installed packages"
|
|
|
|
|
info ""
|
|
|
|
|
info "For Ollama Cloud:"
|
|
|
|
|
info " Set your API key in ~/.pi/agent/auth.json"
|
2026-05-13 15:59:11 +09:00
|
|
|
info " See: https://pi.dev/packages/pi-ollama-cloud"
|