251 lines
11 KiB
PowerShell
251 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:
|
|
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"
|
|
}
|
|
|
|
# ────────────────────────────────────────────
|
|
# 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 "=================================================="
|
|
Info ""
|
|
Info "Pi binary: $piBin"
|
|
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" |