param( [string]$DestinationRoot = 'D:\notatnik-ai\codex', [string[]]$IncludePaths = @(), [string]$BackupName ) Set-StrictMode -Version Latest $ErrorActionPreference = 'Stop' if (-not $BackupName) { $BackupName = 'codex-backup-{0}.zip' -f (Get-Date -Format 'yyyyMMdd-HHmmss') } if (-not (Test-Path -LiteralPath $DestinationRoot)) { New-Item -ItemType Directory -Path $DestinationRoot -Force | Out-Null } $homePath = [Environment]::GetFolderPath('UserProfile') if (-not $IncludePaths -or $IncludePaths.Count -eq 0) { $IncludePaths = @((Join-Path $homePath '.codex')) } $resolvedItems = @() foreach ($path in $IncludePaths) { if ([string]::IsNullOrWhiteSpace($path)) { continue } $expanded = [Environment]::ExpandEnvironmentVariables($path) $expanded = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($expanded) if (Test-Path -LiteralPath $expanded) { $resolvedItems += (Resolve-Path -LiteralPath $expanded).Path } } if ($resolvedItems.Count -eq 0) { throw 'Nie znaleziono zadnych sciezek do eksportu (domyslnie oczekiwano ~/.codex).' } $stagingRoot = Join-Path ([System.IO.Path]::GetTempPath()) ('codex-export-' + [guid]::NewGuid().ToString('N')) $payloadRoot = Join-Path $stagingRoot 'payload' $toolsRoot = Join-Path $stagingRoot 'tools' New-Item -ItemType Directory -Path $payloadRoot -Force | Out-Null New-Item -ItemType Directory -Path $toolsRoot -Force | Out-Null $manifestItems = @() foreach ($source in $resolvedItems) { $name = Split-Path -Leaf $source $payloadName = $name $i = 2 while (Test-Path -LiteralPath (Join-Path $payloadRoot $payloadName)) { $payloadName = '{0}-{1}' -f $name, $i $i++ } $targetPayload = Join-Path $payloadRoot $payloadName Copy-Item -LiteralPath $source -Destination $targetPayload -Recurse -Force $isUnderHome = $source.StartsWith($homePath, [System.StringComparison]::OrdinalIgnoreCase) $profileRelative = $null if ($isUnderHome) { $profileRelative = $source.Substring($homePath.Length).TrimStart('\\') } $manifestItems += [pscustomobject]@{ source_path = $source payload_name = $payloadName destination_type = if ($isUnderHome) { 'user_profile_relative' } else { 'absolute' } profile_relative_path = $profileRelative absolute_path = if ($isUnderHome) { $null } else { $source } } } $scriptDir = Split-Path -Parent $PSCommandPath $importPs1 = Join-Path $scriptDir 'codex-import.ps1' $importCmd = Join-Path $scriptDir 'codex-import.cmd' if (Test-Path -LiteralPath $importPs1) { Copy-Item -LiteralPath $importPs1 -Destination (Join-Path $toolsRoot 'codex-import.ps1') -Force } if (Test-Path -LiteralPath $importCmd) { Copy-Item -LiteralPath $importCmd -Destination (Join-Path $toolsRoot 'codex-import.cmd') -Force } $manifest = [pscustomobject]@{ created_at = (Get-Date).ToString('o') machine_name = $env:COMPUTERNAME user_name = $env:USERNAME user_profile = $homePath items = $manifestItems } $manifest | ConvertTo-Json -Depth 6 | Set-Content -LiteralPath (Join-Path $stagingRoot 'manifest.json') -Encoding UTF8 $zipPath = Join-Path $DestinationRoot $BackupName if (Test-Path -LiteralPath $zipPath) { Remove-Item -LiteralPath $zipPath -Force } Compress-Archive -Path (Join-Path $stagingRoot '*') -DestinationPath $zipPath -CompressionLevel Optimal Remove-Item -LiteralPath $stagingRoot -Recurse -Force Write-Output ('Codex export saved: {0}' -f $zipPath)