$ErrorActionPreference = "Stop" $bundleRoot = Split-Path -Parent $MyInvocation.MyCommand.Path $homeRoot = [Environment]::GetFolderPath("UserProfile") $timestamp = Get-Date -Format "yyyyMMdd-HHmmss" $backupRoot = Join-Path $homeRoot "airplan-backups\$timestamp" $pluginNames = @( "airarc", "aireng", "airdo", "airdbg", "airxdb", "airndb", "airsdb" ) $skillNames = @( "airarc", "aireng", "airdo", "airdbg", "airxdb", "airndb", "airsdb" ) $legacyPluginNames = @("airdo-worker", "air-engine") $legacySkillNames = @("airdo-worker", "air-engine") function Backup-ItemIfExists { param( [Parameter(Mandatory = $true)][string]$SourcePath, [Parameter(Mandatory = $true)][string]$BackupRelativePath ) if (-not (Test-Path -LiteralPath $SourcePath)) { return } $backupPath = Join-Path $backupRoot $BackupRelativePath $backupParent = Split-Path -Parent $backupPath if ($backupParent) { New-Item -ItemType Directory -Path $backupParent -Force | Out-Null } Copy-Item -LiteralPath $SourcePath -Destination $backupPath -Recurse -Force } function Replace-Directory { param( [Parameter(Mandatory = $true)][string]$SourcePath, [Parameter(Mandatory = $true)][string]$TargetPath ) $targetParent = Split-Path -Parent $TargetPath if ($targetParent) { New-Item -ItemType Directory -Path $targetParent -Force | Out-Null } if (Test-Path -LiteralPath $TargetPath) { Remove-Item -LiteralPath $TargetPath -Recurse -Force } Copy-Item -LiteralPath $SourcePath -Destination $TargetPath -Recurse -Force } function Resolve-SkillSourcePath { param( [Parameter(Mandatory = $true)][string]$BundleRoot, [Parameter(Mandatory = $true)][string]$SkillName ) $pluginSkillPath = Join-Path $BundleRoot ("plugins\" + $SkillName + "\skills\" + $SkillName) if (Test-Path -LiteralPath $pluginSkillPath) { return $pluginSkillPath } $legacySkillPath = Join-Path $BundleRoot (".agents\skills\" + $SkillName) if (Test-Path -LiteralPath $legacySkillPath) { return $legacySkillPath } throw "Skill source not found for $SkillName" } function Rewrite-SkillScriptReferences { param( [Parameter(Mandatory = $true)][string]$SkillRoot, [Parameter(Mandatory = $true)][string]$PluginName ) $skillMdPath = Join-Path $SkillRoot "SKILL.md" if (-not (Test-Path -LiteralPath $skillMdPath)) { return } $content = Get-Content -LiteralPath $skillMdPath -Raw -Encoding UTF8 $updated = [regex]::Replace( $content, 'python\s+(?:\.\./\.\./scripts/|scripts/)([^\s`"]+)', { param($match) 'python "$HOME/plugins/{0}/scripts/{1}"' -f $PluginName, $match.Groups[1].Value } ) if ($updated -ne $content) { [System.IO.File]::WriteAllText($skillMdPath, $updated, [System.Text.UTF8Encoding]::new($false)) } } New-Item -ItemType Directory -Path $backupRoot -Force | Out-Null $pluginsRoot = Join-Path $homeRoot "plugins" $skillsRoot = Join-Path $homeRoot ".agents\skills" $marketplaceRoot = Join-Path $homeRoot ".agents\plugins" $libRoot = Join-Path $homeRoot "lib" $marketplacePath = Join-Path $marketplaceRoot "marketplace.json" Backup-ItemIfExists -SourcePath $marketplacePath -BackupRelativePath ".agents\plugins\marketplace.json" Backup-ItemIfExists -SourcePath (Join-Path $libRoot "air_runtime") -BackupRelativePath "lib\air_runtime" foreach ($name in $pluginNames + $legacyPluginNames) { Backup-ItemIfExists -SourcePath (Join-Path $pluginsRoot $name) -BackupRelativePath ("plugins\" + $name) } foreach ($name in $skillNames + $legacySkillNames) { Backup-ItemIfExists -SourcePath (Join-Path $skillsRoot $name) -BackupRelativePath (".agents\skills\" + $name) } foreach ($name in $legacyPluginNames) { $target = Join-Path $pluginsRoot $name if (Test-Path -LiteralPath $target) { Remove-Item -LiteralPath $target -Recurse -Force } } foreach ($name in $legacySkillNames) { $target = Join-Path $skillsRoot $name if (Test-Path -LiteralPath $target) { Remove-Item -LiteralPath $target -Recurse -Force } } foreach ($name in $pluginNames) { Replace-Directory ` -SourcePath (Join-Path $bundleRoot ("plugins\" + $name)) ` -TargetPath (Join-Path $pluginsRoot $name) } foreach ($name in $skillNames) { Replace-Directory ` -SourcePath (Resolve-SkillSourcePath -BundleRoot $bundleRoot -SkillName $name) ` -TargetPath (Join-Path $skillsRoot $name) Rewrite-SkillScriptReferences ` -SkillRoot (Join-Path $skillsRoot $name) ` -PluginName $name } Replace-Directory ` -SourcePath (Join-Path $bundleRoot "lib\air_runtime") ` -TargetPath (Join-Path $libRoot "air_runtime") New-Item -ItemType Directory -Path $marketplaceRoot -Force | Out-Null Copy-Item ` -LiteralPath (Join-Path $bundleRoot ".agents\plugins\marketplace.json") ` -Destination $marketplacePath ` -Force Write-Output "airplan_install=completed" Write-Output ("home_root=" + $homeRoot) Write-Output ("backup_root=" + $backupRoot) Write-Output ("plugins=" + ($pluginNames -join ",")) Write-Output ("skills=" + ($skillNames -join ","))