文件预览

SKILL.md

查看 Cache Migration 技能包中的文件内容。

文件内容

SKILL.md

---
name: cache-migration
description: 本技能用于将 Windows 系统上常见开发工具(Yarn、VSCode)的缓存和插件目录迁移到非系统盘(如 E 盘),通过 NTFS Junction + 启动脚本修改实现对应用完全透明的重定向,无需修改任何应用配置。当用户请求"迁移缓存到 E 盘"、"将 VSCode/Yarn 缓存移到 D/E 盘"、"释放 C 盘空间 迁移缓存"或类似意图时触发。
agent_created: true
---

# Cache Migration

## Overview

将 Yarn、VSCode 等开发工具的缓存和插件目录从系统盘(C 盘)迁移到数据盘(E/D 盘),释放 C 盘空间。

**核心方案**:NTFS Junction(目录联接)+ 启动脚本修改,对应用完全透明,无需任何配置改动。

**迁移项目**:
- Yarn 全局缓存(`AppData\Local\Yarn\Cache`)
- VSCode 缓存目录(Cache、CachedData、GPUCache 等 9 个)
- VSCode 插件扩展(`.vscode\extensions`)

## Workflow

### Step 0: 确认目标路径

确认目标盘符存在且有足够空间:
```bash
ls "E:/AppData/Local" 2>/dev/null || echo "目录不存在"
du -sh "C:/Users/<用户名>/AppData/Roaming/Code/"    # VSCode 缓存大小
du -sh "C:/Users/<用户名>/.vscode/extensions/"     # VSCode 插件大小
du -sh "C:/Users/<用户名>/AppData/Local/Yarn/Cache/v6"  # Yarn 缓存大小
```

### Step 1: 创建目标根目录

```bash
mkdir -p "E:/AppData/Local/VSCode"
mkdir -p "E:/AppData/Local/yarn-cache"   # Yarn 迁移用
```

### Step 2: 迁移 Yarn 缓存

**配置新路径**(执行一条命令即可):
```bash
yarn config set cache-folder "E:\\AppData\\Local\\yarn-cache"
```

**验证**:
```bash
yarn cache dir
# 期望输出: E:\AppData\Local\yarn-cache\v6
```

**迁移旧数据**(可选,避免重新下载):
```bash
cp -r "C:/Users/<用户名>/AppData/Local/Yarn/Cache/v6/"* "E:/AppData/Local/yarn-cache/v6/"
```

### Step 3: 迁移 VSCode 缓存(Junction 方案)

VSCode 缓存目录无法通过配置项修改,必须使用 NTFS Junction。

#### 3.1 复制缓存数据到 E 盘

```powershell
$dstBase = "E:\AppData\Local\VSCode"
$cacheDirs = @(
    "Cache",
    "CachedData",
    "CachedExtensionVSIXs",
    "Code Cache",
    "GPUCache",
    "DawnGraphiteCache",
    "DawnWebGPUCache",
    "CachedProfilesData",
    "CachedConfigurations"
)

foreach ($dir in $cacheDirs) {
    $src = "C:\Users\<用户名>\AppData\Roaming\Code\$dir"
    $dst = "E:\AppData\Local\VSCode\$dir"
    if (Test-Path $src) {
        Copy-Item -Path $src -Destination $dst -Recurse -Force
        Write-Host "已复制: $dir"
    }
}
```

#### 3.2 删除原目录并创建 Junction

**⚠️ 必须先确认数据已复制完成再执行删除操作**

```powershell
foreach ($dir in $cacheDirs) {
    $srcPath = "C:\Users\<用户名>\AppData\Roaming\Code\$dir"
    $dstPath = "E:\AppData\Local\VSCode\$dir"

    if (Test-Path $srcPath) {
        Remove-Item -Path $srcPath -Recurse -Force
        cmd /c "mklink /J `"$srcPath`" `"$dstPath`""
        Write-Host "Junction OK: $dir"
    }
}
```

#### 3.3 验证 Junction

```powershell
foreach ($dir in $cacheDirs) {
    $item = Get-Item "C:\Users\<用户名>\AppData\Roaming\Code\$dir" -Force
    if ($item.Attributes -band [System.IO.FileAttributes]::ReparsePoint) {
        Write-Host "Junction OK: $dir"
    } else {
        Write-Host "FAIL: $dir"
    }
}
```

### Step 4: 迁移 VSCode 插件(Junction 方案)

#### 4.1 复制插件数据

```bash
mkdir -p "E:/AppData/Local/VSCode/extensions"
cp -r "C:/Users/<用户名>/.vscode/extensions/"* "E:/AppData/Local/VSCode/extensions/"
```

#### 4.2 删除原目录并创建 Junction

```powershell
$srcPath = "C:\Users\<用户名>\.vscode\extensions"
$dstPath = "E:\AppData\Local\VSCode\extensions"

Remove-Item -Path $srcPath -Recurse -Force
cmd /c "mklink /J `"$srcPath`" `"$dstPath`""
Write-Host "Junction OK: extensions"
```

### Step 5: 修改 VSCode 启动脚本(显式配置)

即使有 Junction,显式配置 `--extensions-dir` 参数可以双重保障。

#### 5.1 查找 VSCode 安装位置

```bash
which code
# 通常位于: D:\Programs\Microsoft VS Code\bin\code.cmd
```

#### 5.2 修改 code.cmd(Windows CMD 启动)

```batch
# 查找 code.cmd 内容(示例路径)
# D:\Programs\Microsoft VS Code\bin\code.cmd

# 在调用 Code.exe 的行末尾添加 --extensions-dir 参数:
"%~dp0..\Code.exe" "%~dp0..\resources\app\out\cli.js" --extensions-dir "E:\AppData\Local\VSCode\extensions" %*
```

如果文件被 VSCode 进程锁定(EBUSY),使用 PowerShell 强制写入:
```powershell
$src = "D:\Programs\Microsoft VS Code\bin\code.cmd"
$newContent = '@echo off
setlocal
set VSCODE_DEV=
set ELECTRON_RUN_AS_NODE=1
"%~dp0..\Code.exe" "%~dp0..\resources\app\out\cli.js" --extensions-dir "E:\AppData\Local\VSCode\extensions" %*
IF %ERRORLEVEL% NEQ 0 EXIT /b %ERRORLEVEL%
endlocal
'
[System.IO.File]::WriteAllText($src, $newContent, [System.Text.Encoding]::UTF8)
```

#### 5.3 修改 code(Git Bash / WSL 启动)

```sh
# 在 Electron 调用行末尾添加 --extensions-dir:
ELECTRON_RUN_AS_NODE=1 "$ELECTRON" "$CLI" --extensions-dir "E:\AppData\Local\VSCode\extensions" "$@"
```

### Step 6: 修改 VSCode settings.json(可选,双重保障)

在用户设置中添加:
```json
"extensionsPath": "E:/AppData/Local/VSCode/extensions"
```

### Step 7: 全面验证

```powershell
Write-Host "=== 1. Yarn 缓存 ==="
yarn cache dir

Write-Host ""
Write-Host "=== 2. VSCode 缓存 Junction ==="
$cacheDirs = @("Cache","CachedData","CachedExtensionVSIXs","Code Cache","GPUCache","DawnGraphiteCache","DawnWebGPUCache","CachedProfilesData","CachedConfigurations")
foreach ($dir in $cacheDirs) {
    $item = Get-Item "C:\Users\<用户名>\AppData\Roaming\Code\$dir" -Force
    if ($item.Attributes -band [System.IO.FileAttributes]::ReparsePoint) {
        Write-Host "Junction OK: $dir"
    } else {
        Write-Host "FAIL: $dir"
    }
}

Write-Host ""
Write-Host "=== 3. VSCode 插件 Junction ==="
$item = Get-Item "C:\Users\<用户名>\.vscode\extensions" -Force
if ($item.Attributes -band [System.IO.FileAttributes]::ReparsePoint) { "OK" } else { "FAIL" }

Write-Host ""
Write-Host "=== 4. code.cmd 修改 ==="
if ((Get-Content "D:\Programs\Microsoft VS Code\bin\code.cmd" -Raw) -match "extensions-dir") { "OK" } else { "FAIL" }

Write-Host ""
Write-Host "=== 5. E 盘数据量 ==="
(Get-ChildItem "E:\AppData\Local\VSCode" -Recurse -Force | Measure-Object -Property Length -Sum).Sum / 1MB
```

### Step 8: 清理 C 盘残留

**Yarn**:执行 `yarn config set` 后旧缓存目录通常自动清空,若仍存在可手动删除:
```bash
rd /s /q "C:\Users\<用户名>\AppData\Local\Yarn\Cache"
```

**VSCode**:Junction 方案中 C 盘原目录已全部替换为链接,无实体残留,无需额外清理。

## Resources

### scripts/

- `migrate-vscode-cache.ps1` — VSCode 缓存目录批量 Junction 迁移脚本(输入源路径和目标路径即可执行)
- `migrate-vscode-ext.ps1` — VSCode 插件目录 Junction 迁移脚本
- `verify-migration.ps1` — 全面验证脚本,检查所有 Junction 和配置文件