2026-05-13 11:44:26 +09:00
# 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:
powershell -ExecutionPolicy Bypass -c "$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'
# ────────────────────────────────────────────
# 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"
}
2026-05-13 15:59:11 +09:00
# ────────────────────────────────────────────
# Resolve pi binary path (may not be in PATH yet after fresh install)
# ────────────────────────────────────────────
$piBin = $null
# 1) Try current PATH
2026-05-13 11:44:26 +09:00
$piCmd = Get-Command pi -ErrorAction SilentlyContinue
if ( $piCmd ) {
2026-05-13 15:59:11 +09:00
$piBin = $piCmd . Source
}
# 2) Refresh PATH from registry and try again
if ( -not $piBin ) {
2026-05-13 11:44:26 +09:00
$env:Path = [ System.Environment ]:: GetEnvironmentVariable ( 'Path' , 'User' ) + ';' + [ System.Environment ]:: GetEnvironmentVariable ( 'Path' , 'Machine' )
$piCmd = Get-Command pi -ErrorAction SilentlyContinue
if ( $piCmd ) {
2026-05-13 15:59:11 +09:00
$piBin = $piCmd . Source
2026-05-13 11:44:26 +09:00
}
}
2026-05-13 15:59:11 +09:00
# 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 }
}
}
}
2026-05-13 16:43:51 +09:00
# 4) Try well-known locations (including pi-node versioned installs)
2026-05-13 15:59:11 +09:00
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 }
}
2026-05-13 16:43:51 +09:00
# 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 }
}
}
2026-05-13 15:59:11 +09:00
}
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 "
2026-05-13 16:43:51 +09:00
# 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"
}
2026-05-13 15:59:11 +09:00
} else {
ErrExit "'pi' command not found after installation. Check your PATH or reinstall Node.js."
}
2026-05-13 11:44:26 +09:00
# ────────────────────────────────────────────
2026-05-13 15:59:11 +09:00
# Step 2: Install packages using the resolved pi binary
2026-05-13 11:44:26 +09:00
# ────────────────────────────────────────────
if ( $SkipPackages ) {
Info "Skipping package installation (-SkipPackages flag)."
} else {
Info ""
Info "Installing Pi packages..."
2026-05-13 15:59:11 +09:00
Info "---------------------------------------------------"
2026-05-13 11:44:26 +09:00
$total = $Packages . Count
$count = 0
$failed = @ ()
foreach ( $pkg in $Packages ) {
$count ++
$name = $pkg . Name
$desc = $pkg . Desc
Info "[ $count / $total ] $name - $desc "
try {
2026-05-13 15:59:11 +09:00
& $piBin install "npm: $name " 2 >& 1 | Out-Null
2026-05-13 11:44:26 +09:00
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 ""
2026-05-13 15:59:11 +09:00
Info "---------------------------------------------------"
2026-05-13 11:44:26 +09:00
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 "=================================================="
Info ""
2026-05-13 15:59:11 +09:00
Info "Pi binary: $piBin "
Info ""
2026-05-13 11:44:26 +09:00
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"