# Install skills// into BOTH agent skill dirs: # ~\.claude\skills\\ (Claude Code — native, not configurable) # ~\.agents\skills\\ (pi — native default scan path, agent-neutral namespace) # $env:CLAUDE_SKILLS_DIR overrides ONLY the claude target (for testing/CI). # # Usage: install.ps1 [-Names ,] [-Prune] # no args = install all skills/* into both targets # -Prune = after install, remove target// dirs that are NOT in skills/* # (prune always scans full target, ignores -Names filter — it's a global cleanup) # # PowerShell port of install.sh — same behavior, native cmdlets, no bash dependency. [CmdletBinding()] param( [string[]]$Names = @(), [switch]$Prune ) $ErrorActionPreference = 'Stop' $root = Split-Path -Parent $PSScriptRoot $src = Join-Path $root 'skills' # Dual install targets — the "canon" is the git repo (skills/); both dirs are installs. $targets = @() if ($env:CLAUDE_SKILLS_DIR) { $targets += $env:CLAUDE_SKILLS_DIR } else { $targets += (Join-Path $env:USERPROFILE '.claude\skills') } $targets += (Join-Path $env:USERPROFILE '.agents\skills') foreach ($target in $targets) { if (-not (Test-Path $target)) { New-Item -ItemType Directory -Force -Path $target | Out-Null } } if ($Names.Count -eq 0) { $Names = Get-ChildItem -Path $src -Directory | Sort-Object Name | Select-Object -ExpandProperty Name } foreach ($target in $targets) { foreach ($name in $Names) { $srcDir = Join-Path $src $name $dstDir = Join-Path $target $name if (-not (Test-Path $srcDir -PathType Container)) { Write-Warning "skip: $name (not found in skills/)" continue } if (-not (Test-Path (Join-Path $srcDir 'SKILL.md'))) { Write-Warning "skip: $name (missing SKILL.md)" continue } if (Test-Path $dstDir) { Remove-Item -Recurse -Force $dstDir } Copy-Item -Recurse $srcDir $dstDir Write-Host "installed: $name -> $dstDir" } } if ($Prune) { $sourceNames = @(Get-ChildItem -Path $src -Directory | Select-Object -ExpandProperty Name) foreach ($target in $targets) { $installedDirs = Get-ChildItem -Path $target -Directory -ErrorAction SilentlyContinue foreach ($dir in $installedDirs) { if ($sourceNames -notcontains $dir.Name) { Write-Host "pruning: $($dir.Name) (not in skills/) -> $($dir.FullName)" Remove-Item -Recurse -Force $dir.FullName } } } }