param( [string]$ZipPath, [string]$DestinationHome = ([Environment]::GetFolderPath('UserProfile')), [string]$BackupRoot = 'D:\notatnik-ai\codex', [switch]$NoBackup ) Set-StrictMode -Version Latest $ErrorActionPreference = 'Stop' if (-not (Test-Path -LiteralPath $BackupRoot)) { New-Item -ItemType Directory -Path $BackupRoot -Force | Out-Null } if (-not $ZipPath) { $latest = Get-ChildItem -LiteralPath $BackupRoot -Filter 'codex-backup-*.zip' -File | Sort-Object LastWriteTime -Descending | Select-Object -First 1 if (-not $latest) { throw 'Brak pliku backup ZIP. Podaj -ZipPath.' } $ZipPath = $latest.FullName } $resolvedZip = (Resolve-Path -LiteralPath $ZipPath).Path $extractRoot = Join-Path ([System.IO.Path]::GetTempPath()) ('codex-import-' + [guid]::NewGuid().ToString('N')) New-Item -ItemType Directory -Path $extractRoot -Force | Out-Null Expand-Archive -LiteralPath $resolvedZip -DestinationPath $extractRoot -Force $manifestPath = Join-Path $extractRoot 'manifest.json' if (-not (Test-Path -LiteralPath $manifestPath)) { throw 'W archiwum brakuje manifest.json.' } $manifest = Get-Content -LiteralPath $manifestPath -Raw | ConvertFrom-Json $payloadRoot = Join-Path $extractRoot 'payload' if (-not (Test-Path -LiteralPath $payloadRoot)) { throw 'W archiwum brakuje katalogu payload.' } $preBackupDir = $null if (-not $NoBackup) { $preBackupDir = Join-Path $BackupRoot ('pre-import-backup-' + (Get-Date -Format 'yyyyMMdd-HHmmss')) New-Item -ItemType Directory -Path $preBackupDir -Force | Out-Null } foreach ($item in $manifest.items) { $payloadItem = Join-Path $payloadRoot $item.payload_name if (-not (Test-Path -LiteralPath $payloadItem)) { Write-Warning ('Pomijam brakujacy element payload: {0}' -f $item.payload_name) continue } $targetPath = $null if ($item.destination_type -eq 'user_profile_relative') { $targetPath = Join-Path $DestinationHome $item.profile_relative_path } elseif ($item.destination_type -eq 'absolute') { $targetPath = $item.absolute_path } if (-not $targetPath) { Write-Warning ('Pomijam element z nieznanym celem: {0}' -f $item.payload_name) continue } $targetParent = Split-Path -Parent $targetPath if ($targetParent -and -not (Test-Path -LiteralPath $targetParent)) { New-Item -ItemType Directory -Path $targetParent -Force | Out-Null } if (Test-Path -LiteralPath $targetPath) { if (-not $NoBackup -and $preBackupDir) { $backupTarget = Join-Path $preBackupDir ($item.payload_name + '-before-import') Copy-Item -LiteralPath $targetPath -Destination $backupTarget -Recurse -Force } Remove-Item -LiteralPath $targetPath -Recurse -Force } Copy-Item -LiteralPath $payloadItem -Destination $targetPath -Recurse -Force } Remove-Item -LiteralPath $extractRoot -Recurse -Force Write-Output ('Codex import completed from: {0}' -f $resolvedZip) if ($preBackupDir) { Write-Output ('Pre-import backup: {0}' -f $preBackupDir) }