# ============================================================================= # Bookworm .claude 同步 - 阶段 1: 本机打包 + HTTP 服务 # 在源机器 (leesu) 上运行 # ============================================================================= [CmdletBinding()] param( [string]$SourceUser = $env:USERNAME, [int]$Port = 8765, [switch]$NoServe # 加这个开关只打包不起服务 ) $ErrorActionPreference = 'Stop' $src = "C:\Users\$SourceUser\.claude" $staging = "$env:TEMP\claude-sync-staging" $zip = "$env:TEMP\claude-sync.zip" if (-not (Test-Path $src)) { Write-Host "❌ 源目录不存在: $src" -ForegroundColor Red exit 1 } Write-Host "==================== 阶段 1: 打包 ====================" -ForegroundColor Cyan Write-Host "源: $src" Write-Host "目标 zip: $zip" Write-Host "" # ---------- 1) 清理旧暂存 ---------- Write-Host "[1/5] 清理旧暂存..." -ForegroundColor Yellow Remove-Item $staging, $zip -Recurse -Force -ErrorAction SilentlyContinue New-Item $staging -ItemType Directory -Force | Out-Null # ---------- 2) 构建排除列表 ---------- Write-Host "[2/5] 构建排除列表..." -ForegroundColor Yellow # 必排除目录 (顶层) $excludeTopDirs = @( "$src\.git", "$src\node_modules", "$src\.skill-cache" ) # 排除每个 mcp-server 下的 .venv / __pycache__ / node_modules (保留源码) $mcpExcludes = @() if (Test-Path "$src\mcp-servers") { Get-ChildItem "$src\mcp-servers" -Directory | ForEach-Object { $mcpExcludes += "$($_.FullName)\.venv" $mcpExcludes += "$($_.FullName)\__pycache__" $mcpExcludes += "$($_.FullName)\node_modules" } } # 排除每个 skill 下的 node_modules / dist / .git (保留源码) $skillExcludes = @() if (Test-Path "$src\skills") { Get-ChildItem "$src\skills" -Directory | ForEach-Object { $skillExcludes += "$($_.FullName)\node_modules" $skillExcludes += "$($_.FullName)\dist" $skillExcludes += "$($_.FullName)\.git" } } # 排除文件类型 $excludeFiles = @( '*.dpapi.json', # DPAPI 机器绑定,无法跨机器解密 '*.bak.*', # 临时备份文件 'Thumbs.db','desktop.ini' # OS 残留 ) $xdArgs = $excludeTopDirs + $mcpExcludes + $skillExcludes # ---------- 3) robocopy 复制 ---------- Write-Host "[3/5] 复制中(约 1-3 分钟)..." -ForegroundColor Yellow $rcArgs = @($src, $staging, '/E', '/XD') + $xdArgs + @('/XF') + $excludeFiles + @('/NFL','/NDL','/NJH','/NJS','/NC','/NS','/NP','/R:1','/W:1') $rcExit = (Start-Process robocopy -ArgumentList $rcArgs -NoNewWindow -Wait -PassThru).ExitCode # robocopy exit code < 8 都是成功 if ($rcExit -ge 8) { Write-Host "❌ robocopy 失败 (exit=$rcExit)" -ForegroundColor Red exit 1 } # 排除 hooks 测试 / 归档 / 废弃 Remove-Item "$staging\hooks\__tests__","$staging\hooks\archive","$staging\hooks\deprecated" -Recurse -Force -ErrorAction SilentlyContinue # 统计 $stat = Get-ChildItem $staging -Recurse -File -ErrorAction SilentlyContinue | Measure-Object Length -Sum Write-Host " 暂存: $([Math]::Round($stat.Sum / 1MB, 1)) MB / $($stat.Count) 文件" # ---------- 4) 压缩 ---------- Write-Host "[4/5] 压缩中(文件多时 2-5 分钟)..." -ForegroundColor Yellow Compress-Archive -Path "$staging\*" -DestinationPath $zip -Force -CompressionLevel Optimal $zipSize = [Math]::Round((Get-Item $zip).Length / 1MB, 1) Write-Host " ✅ $zip ($zipSize MB)" -ForegroundColor Green # ---------- 5) 起 HTTP 服务 ---------- if ($NoServe) { Write-Host "[5/5] 跳过 HTTP 服务(-NoServe 已指定)" -ForegroundColor Yellow Write-Host "" Write-Host "✅ 打包完成。手动传输 $zip 到目标机器即可。" -ForegroundColor Green exit 0 } Write-Host "[5/5] 启动 HTTP 服务..." -ForegroundColor Yellow # 获取本机 LAN IP $lanIP = (Get-NetIPAddress -AddressFamily IPv4 | Where-Object { $_.IPAddress -notlike '169.254.*' -and $_.IPAddress -ne '127.0.0.1' -and $_.IPAddress -notlike '198.18.*' -and $_.IPAddress -notlike '172.*' } | Select-Object -First 1).IPAddress Write-Host "" Write-Host "================ 服务就绪 ================" -ForegroundColor Green Write-Host " 目标机器请运行 2-pull-and-rebuild.ps1," Write-Host " 或手动下载: " -NoNewline Write-Host "http://${lanIP}:${Port}/claude-sync.zip" -ForegroundColor Cyan Write-Host "" Write-Host " 传输完成后回到此窗口按 Ctrl+C 停止服务" -ForegroundColor Yellow Write-Host "==========================================" -ForegroundColor Green Write-Host "" # 切到 TEMP 目录起服务 Push-Location $env:TEMP try { python -m http.server $Port } finally { Pop-Location Write-Host "" Write-Host "🧹 清理暂存..." -ForegroundColor Yellow Remove-Item $staging -Recurse -Force -ErrorAction SilentlyContinue Write-Host "✅ 暂存已清。zip 保留在: $zip" -ForegroundColor Green }