param( [string]$OutputDir, [string]$PackageName ) $ErrorActionPreference = 'Stop' $scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path $projectRoot = (Resolve-Path (Join-Path $scriptDir '..')).Path $projectName = Split-Path $projectRoot -Leaf $shareBaseName = "gpt-image-2-generator" $timestamp = Get-Date -Format 'yyyyMMdd-HHmmss' if ([string]::IsNullOrWhiteSpace($OutputDir)) { $OutputDir = Join-Path $projectRoot 'dist' } $OutputDir = [System.IO.Path]::GetFullPath($OutputDir) if ([string]::IsNullOrWhiteSpace($PackageName)) { $PackageName = "$shareBaseName-share-$timestamp" } $zipPath = Join-Path $OutputDir ($PackageName + '.zip') $tempRoot = Join-Path ([System.IO.Path]::GetTempPath()) ("$shareBaseName-share-export-" + [System.Guid]::NewGuid().ToString('N')) $stageDir = Join-Path $tempRoot $PackageName $excludedTopDirs = @('outputs', 'dist', '.git', '.idea', '.vscode') $excludedFileNames = @('history.jsonl') $excludedExtensions = @('.pyc', '.pyo') function Should-SkipFile { param([string]$RelativePath) $normalized = $RelativePath -replace '/', '\\' $parts = $normalized.Split('\\', [System.StringSplitOptions]::RemoveEmptyEntries) if ($parts.Count -eq 0) { return $true } if ($excludedTopDirs -contains $parts[0]) { return $true } if ($parts -contains '__pycache__') { return $true } if ($normalized -ieq 'config\token.txt' -or $normalized -ieq 'config\base_url.txt') { return $true } $fileName = [System.IO.Path]::GetFileName($normalized) if ($excludedFileNames -contains $fileName) { return $true } $extension = [System.IO.Path]::GetExtension($normalized) if ($excludedExtensions -contains $extension) { return $true } return $false } function Ensure-ParentDirectory { param([string]$FilePath) $parent = Split-Path -Parent $FilePath if (-not [string]::IsNullOrWhiteSpace($parent) -and -not (Test-Path $parent)) { New-Item -ItemType Directory -Path $parent -Force | Out-Null } } try { New-Item -ItemType Directory -Path $OutputDir -Force | Out-Null New-Item -ItemType Directory -Path $stageDir -Force | Out-Null $files = Get-ChildItem -Path $projectRoot -Recurse -File foreach ($file in $files) { $relativePath = $file.FullName.Substring($projectRoot.Length).TrimStart('\') if (Should-SkipFile -RelativePath $relativePath) { continue } $destination = Join-Path $stageDir $relativePath Ensure-ParentDirectory -FilePath $destination Copy-Item -Path $file.FullName -Destination $destination -Force } $placeholderTokenPath = Join-Path $stageDir 'config\token.txt' Ensure-ParentDirectory -FilePath $placeholderTokenPath @( '# 在下一行填入 apicodex.xyz 的 API token,不要带 Bearer 前缀。', 'YOUR_API_TOKEN_HERE' ) | Set-Content -Path $placeholderTokenPath -Encoding UTF8 $placeholderBaseUrlPath = Join-Path $stageDir 'config\base_url.txt' Ensure-ParentDirectory -FilePath $placeholderBaseUrlPath @( '# 在下一行填入 API base URL,可写根地址或完整 /v1 地址。', 'https://apicodex.xyz/v1' ) | Set-Content -Path $placeholderBaseUrlPath -Encoding UTF8 if (Test-Path $zipPath) { Remove-Item -Path $zipPath -Force } Compress-Archive -Path $stageDir -DestinationPath $zipPath -Force Write-Host '可分享版导出完成:' $zipPath Write-Host '已自动排除:config\token.txt(真实内容)、config\base_url.txt(真实内容)、outputs、history.jsonl、__pycache__、*.pyc、dist。' } finally { if (Test-Path $tempRoot) { Remove-Item -Path $tempRoot -Recurse -Force } }