Files
install-sh/install-pi.ps1
T

259 lines
11 KiB
PowerShell

#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'