#Requires -Version 5.1 <# .SYNOPSIS Installs Pi Coding Agent and recommended packages. .DESCRIPTION Auto-detects the platform, installs Pi Coding Agent via npm, then installs recommended Pi packages. Supported platforms: - Windows x64 (AMD64 / Intel 64bit) - Windows ARM64 Prerequisites: - Node.js 18+ (and npm) .PARAMETER SkipPackages Skip installing Pi packages (only install Pi itself). .EXAMPLE .\install-pi.ps1 .\install-pi.ps1 -SkipPackages # One-liner install from remote (works on Windows 10+): powershell -ExecutionPolicy Bypass -c "[Net.ServicePointManager]::SecurityProtocol=[Net.SecurityProtocolType]::Tls12; $t=\"$env:TEMP\install-pi.ps1\"; iwr -useb 'https://gl.isitsoft.kr/publicproj/install-sh/-/raw/main/install-pi.ps1' -OutFile $t; & $t" .NOTES If execution policy error occurs: Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser #> [CmdletBinding()] param( [bool] $SkipPackages = $false ) Set-StrictMode -Version Latest $ErrorActionPreference = 'Stop' # Force TLS 1.2+ for HTTPS downloads (required on Windows 10 / PowerShell 5.1) [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 # ──────────────────────────────────────────── # Constants # ──────────────────────────────────────────── $PI_NPM_PACKAGE = "@earendil-works/pi-coding-agent" # Packages to install after pi is available # Format: @{ Name = "package_name"; Desc = "description" } $Packages = @( @{ Name = "pi-subagents"; Desc = "Delegate work to focused child agents - code review, scouting, implementation, parallel audits, orchestration, background jobs" } @{ Name = "context-mode"; Desc = "Context window protection - sandbox tools, session continuity, BM25 knowledge base, think-in-code paradigm" } @{ Name = "pi-mcp-adapter"; Desc = "Use MCP servers with Pi without burning your context window - one proxy tool instead of hundreds" } @{ Name = "pi-web-access"; Desc = "Web search, content extraction, and video understanding - zero-config Exa search, Perplexity, Gemini, YouTube" } @{ Name = "@plannotator/pi-extension"; Desc = "File-based plan mode with visual browser UI for reviewing, annotating, and approving agent plans" } @{ Name = "@juicesharp/rpiv-ask-user-question"; Desc = "Structured questionnaire tool with typed options - the model asks you instead of guessing" } @{ Name = "pi-lens"; Desc = "Real-time code feedback - LSP diagnostics, linters, formatters, type-checking, structural analysis, read-before-edit guard" } @{ Name = "@juicesharp/rpiv-todo"; Desc = "Persistent todo list across sessions - tasks survive /reload and compaction with dependency tracking" } @{ Name = "pi-simplify"; Desc = "Review recently changed code for clarity, consistency, and maintainability improvements" } @{ Name = "@juicesharp/rpiv-advisor"; Desc = "Second opinion from a stronger reviewer model before the agent acts" } @{ Name = "@juicesharp/rpiv-pi"; Desc = "Skill-based development workflow - discover, research, design, plan, implement, validate pipeline with named subagents" } @{ Name = "@samfp/pi-memory"; Desc = "Persistent memory for Pi - learns corrections, preferences, and project patterns across sessions" } @{ Name = "pi-btw"; Desc = "Parallel side conversations (/btw) without interrupting the main agent run" } @{ Name = "pi-docparser"; Desc = "Document parsing tool - PDFs, Office docs, spreadsheets, images, and OCR via LiteParse" } @{ Name = "pi-ollama-cloud"; Desc = "Ollama Cloud provider plugin - dynamic model discovery, web search and fetch tools, no local server required" } ) # ──────────────────────────────────────────── # Utility functions # ──────────────────────────────────────────── function Info { Write-Host "[INFO] $args" -ForegroundColor Cyan } function Warn { Write-Host "[WARN] $args" -ForegroundColor Yellow } function Success { Write-Host "[OK] $args" -ForegroundColor Green } function ErrExit { Write-Host "[ERROR] $args" -ForegroundColor Red; exit 1 } # ──────────────────────────────────────────── # Check prerequisites # ──────────────────────────────────────────── Info "Platform: $([System.Environment]::OSVersion.Platform) ($([System.Environment]::GetEnvironmentVariable('PROCESSOR_ARCHITECTURE')))" if (-not (Get-Command npm -ErrorAction SilentlyContinue)) { ErrExit "npm is required. Install Node.js 18+: https://nodejs.org/" } # ──────────────────────────────────────────── # Step 1: Install Pi Coding Agent # ──────────────────────────────────────────── Info "Installing Pi Coding Agent..." $piCmd = Get-Command pi -ErrorAction SilentlyContinue if ($piCmd) { $currentVer = & pi --version 2>$null if ($LASTEXITPR -ne 0) { $currentVer = "unknown" } Info "Pi is already installed (version: $currentVer). Skipping installation." } else { npm install -g $PI_NPM_PACKAGE if ($LASTEXITPR -ne 0) { ErrExit "Pi installation failed." } Success "Pi installed via npm" } # ──────────────────────────────────────────── # Resolve pi binary path (may not be in PATH yet after fresh install) # ──────────────────────────────────────────── $piBin = $null # 1) Try current PATH $piCmd = Get-Command pi -ErrorAction SilentlyContinue if ($piCmd) { $piBin = $piCmd.Source } # 2) Refresh PATH from registry and try again if (-not $piBin) { $env:Path = [System.Environment]::GetEnvironmentVariable('Path', 'User') + ';' + [System.Environment]::GetEnvironmentVariable('Path', 'Machine') $piCmd = Get-Command pi -ErrorAction SilentlyContinue if ($piCmd) { $piBin = $piCmd.Source } } # 3) Try common npm global locations if (-not $piBin) { $npmPrefix = & npm config get prefix 2>$null if ($LASTEXITPR -eq 0 -and $npmPrefix) { $candidate = Join-Path $npmPrefix 'pi.cmd' if (Test-Path $candidate) { $piBin = $candidate } if (-not $piBin) { $candidate = Join-Path $npmPrefix 'pi' if (Test-Path $candidate) { $piBin = $candidate } } } } # 4) Try well-known locations (including pi-node versioned installs) if (-not $piBin) { $candidates = @( (Join-Path $env:APPDATA 'npm\pi.cmd'), (Join-Path $env:APPDATA 'npm\pi'), 'C:\Program Files\nodejs\pi.cmd', 'C:\Program Files\nodejs\pi' ) foreach ($c in $candidates) { if (Test-Path $c) { $piBin = $c; break } } # Search for pi-node versioned installs (e.g. pi-node/node-v22.22.2-win-x64/bin/pi.cmd) if (-not $piBin) { $piNodeDir = Join-Path $env:USERPROFILE '.local\share\pi-node' if (Test-Path $piNodeDir) { $found = Get-ChildItem -Path $piNodeDir -Recurse -Filter 'pi.cmd' -ErrorAction SilentlyContinue | Select-Object -First 1 if ($found) { $piBin = $found.FullName } } } } if ($piBin) { # Add pi's directory to PATH for this session $piDir = Split-Path $piBin if ($env:Path -notlike "*$piDir*") { $env:Path = "$piDir;$env:Path" Info "Added $piDir to PATH for this session" } Success "Pi is available: $piBin" # Permanently add pi's directory to user PATH if not already there $userPath = [System.Environment]::GetEnvironmentVariable('Path', 'User') if ($userPath -notlike "*$piDir*") { [System.Environment]::SetEnvironmentVariable('Path', "$piDir;$userPath", 'User') Success "Added $piDir to user PATH permanently (takes effect on next login)" } else { Info "$piDir already in user PATH" } } else { ErrExit "'pi' command not found after installation. Check your PATH or reinstall Node.js." } # ──────────────────────────────────────────── # Step 2: Install packages using the resolved pi binary # ──────────────────────────────────────────── if ($SkipPackages) { Info "Skipping package installation (-SkipPackages flag)." } else { Info "" Info "Installing Pi packages..." Info "---------------------------------------------------" $total = $Packages.Count $count = 0 $failed = @() foreach ($pkg in $Packages) { $count++ $name = $pkg.Name $desc = $pkg.Desc Info "[$count/$total] $name - $desc" try { & $piBin install "npm:$name" 2>&1 | Out-Null if ($LASTEXITPR -eq 0) { Success " -> $name installed" } else { Warn " -> $name failed (install manually later: pi install npm:$name)" $failed += $name } } catch { Warn " -> $name failed (install manually later: pi install npm:$name)" $failed += $name } } Info "" Info "---------------------------------------------------" if ($failed.Count -eq 0) { Success "All packages installed! ($total/$total)" } else { Warn "Some packages failed to install:" foreach ($f in $failed) { Warn " - $f" } Info "You can install failed packages manually with:" foreach ($f in $failed) { Info " pi install npm:$f" } } } # ──────────────────────────────────────────── # Step 3: Post-install notes # ──────────────────────────────────────────── Info "" Info "==================================================" Success "Pi Coding Agent installation complete!" Info "==================================================" if ($piBin) { Info "" Info "Pi binary: $piBin" } Info "" Info "IMPORTANT: Close this terminal and open a new one to use pi." Info "PATH changes require a new terminal session to take effect." Info "" Info "Getting started: Info " 1. Navigate to your project: cd C:\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 $env:USERPROFILE\.pi\agent\auth.json' Info ' See: https://pi.dev/packages/pi-ollama-cloud'