{
  "skill": "uking-install-windows",
  "version": 39,
  "updated": "2026-08-03",
  "notes": "v37: 补上 OpenCode(opencode-ai)。它是社区最大的开源 coding agent，交互式 TUI 成熟，但**非交互 opencode run 在 Windows 上实测恒定挂死零输出**（1.4.3/1.18.11、沙箱/真实 HOME、带不带 --format 四种组合全挂），所以只按 TUI 上架、不进竞技场。v36: 上架 Qwen Code 与 Crush，并复活 Codex CLI / OpenClaw CLI 入口（主线改为「CLI 干活 + U-Workspace 当壳」）。 | v39: Windows 专属步骤打上 os=windows —— Mac 和 Windows 读同一份清单，那些 powershell.exe 步骤在 macOS 上被 sh 执行会报 `sh: line 0: fg: no job control`，把整条安装判失败并拖进修复循环（issue #340）。",
  "mirror_fallback": "https://u-claw-updates.oss-cn-shenzhen.aliyuncs.com/uking/runtimes",
  "python": {
    "url": "https://registry.npmmirror.com/-/binary/python-build-standalone/20241016/cpython-3.12.7+20241016-x86_64-pc-windows-msvc-install_only.tar.gz",
    "url_mac_arm64": "https://registry.npmmirror.com/-/binary/python-build-standalone/20241016/cpython-3.12.7+20241016-aarch64-apple-darwin-install_only.tar.gz",
    "url_mac_x64": "https://registry.npmmirror.com/-/binary/python-build-standalone/20241016/cpython-3.12.7+20241016-x86_64-apple-darwin-install_only.tar.gz",
    "sha256": "f05531bff16fa77b53be0776587b97b466070e768e6d5920894de988bdcd547a",
    "sha256_mac_arm64": "4c18852bf9c1a11b56f21bcf0df1946f7e98ee43e9e4c0c5374b2b3765cf9508",
    "sha256_mac_x64": "60c5271e7edc3c2ab47440b7abf4ed50fbc693880b474f74f05768f5b657045a"
  },
  "pip_index": "https://mirrors.aliyun.com/pypi/simple/",
  "node": {
    "version": "v22.20.0",
    "url": "https://registry.npmmirror.com/-/binary/node/v22.20.0/node-v22.20.0-win-x64.zip",
    "dir_name": "node-v22.20.0-win-x64",
    "url_mac_arm64": "https://registry.npmmirror.com/-/binary/node/v22.20.0/node-v22.20.0-darwin-arm64.tar.gz",
    "dir_name_mac_arm64": "node-v22.20.0-darwin-arm64",
    "url_mac_x64": "https://registry.npmmirror.com/-/binary/node/v22.20.0/node-v22.20.0-darwin-x64.tar.gz",
    "dir_name_mac_x64": "node-v22.20.0-darwin-x64",
    "sha256": "bb819d6eb8f5bfda294bbc83a7e4ec6539da67c4233d54b0d655b9248b15e29d",
    "sha256_mac_arm64": "cc04a76a09f79290194c0646f48fec40354d88969bec467789a5d55dd097f949",
    "sha256_mac_x64": "00df9c5df3e4ec6848c26b70fb47bf96492f342f4bed6b17f12d99b3a45eeecc"
  },
  "npm_registry": "https://registry.npmmirror.com",
  "tools": {
    "claude-code": {
      "name": "Claude Code CLI",
      "bin": "claude",
      "verify_cmd": "claude --version",
      "steps": [
        {
          "type": "ensure_node",
          "label": "检查 Node.js 运行时（缺失则自动装便携版）"
        },
        {
          "type": "npm_install",
          "label": "安装 Claude Code（npmmirror 国内加速）",
          "package": "@anthropic-ai/claude-code"
        },
        {
          "type": "run",
          "label": "覆盖上去：给已装的 AI 命令建轻量转发启动器并前置进用户 PATH，让 U-King 装的赢过你之前装的别家/旧版（不动你的 node/npm、不删你的东西；原 PATH 已备份到 ~/.uking/path-backup.txt，UKING_TEST_HOME 沙箱下跳过）",
          "cmd": "%SystemRoot%\\System32\\WindowsPowerShell\\v1.0\\powershell.exe -NoProfile -NonInteractive -Command \"if($env:UKING_TEST_HOME){ exit 0 }; $ErrorActionPreference='SilentlyContinue'; $shims=Join-Path $env:USERPROFILE '.uking\\shims'; New-Item -ItemType Directory -Force -Path $shims | Out-Null; $q=[char]34; $src=@((Join-Path $env:USERPROFILE '.uking\\runtime\\node'),(Join-Path $env:APPDATA 'npm'),(Join-Path $env:USERPROFILE 'bin'),(Join-Path $env:USERPROFILE '.uking\\runtime\\python\\Scripts')); foreach($t in @('claude','codex','openclaw','hermes','qwen','crush','opencode')){ $real=$null; foreach($d in $src){ foreach($e in @('.cmd','.exe')){ $p=Join-Path $d ($t+$e); if(Test-Path $p){ $real=$p; break } }; if($real){break} }; if($real){ Set-Content -LiteralPath (Join-Path $shims ($t+'.cmd')) -Value ('@echo off'+[Environment]::NewLine+$q+$real+$q+' '+[char]37+'*') -Encoding Default } }; $py=Join-Path $env:USERPROFILE '.uking\\runtime\\python\\python.exe'; if(Test-Path $py){ Set-Content -LiteralPath (Join-Path $shims 'python3.cmd') -Value ('@echo off'+[Environment]::NewLine+$q+$py+$q+' '+[char]37+'*') -Encoding Default }; $u=[Environment]::GetEnvironmentVariable('Path','User'); if($null -eq $u){$u=''}; $bak=Join-Path $env:USERPROFILE '.uking\\path-backup.txt'; if(-not (Test-Path $bak)){ [IO.File]::WriteAllText($bak,$u) }; $keep=@($u -split ';' | Where-Object { $_ -ne '' -and $_ -ne $shims }); [Environment]::SetEnvironmentVariable('Path',((@($shims)+$keep) -join ';'),'User'); exit 0\"",
          "os": "windows"
        }
      ],
      "repair": [
        {
          "type": "run",
          "label": "停止占用 npm 全局目录的旧进程（修 @anthropic-ai 目录被占用导致 cleanup/rename 失败）",
          "cmd": "%SystemRoot%\\System32\\WindowsPowerShell\\v1.0\\powershell.exe -NoProfile -NonInteractive -Command \"$nodeRoot=(Join-Path $env:USERPROFILE '.uking\\runtime\\node'); Get-CimInstance Win32_Process | Where-Object { $_.ExecutablePath -and $_.ExecutablePath.StartsWith($nodeRoot,[StringComparison]::OrdinalIgnoreCase) } | ForEach-Object { Stop-Process -Id $_.ProcessId -Force -ErrorAction SilentlyContinue }; exit 0\"",
          "os": "windows"
        },
        {
          "type": "run",
          "label": "清除 npm 全局代理配置（客户机代理常把 npm 拦死）",
          "cmd": "call npm config delete proxy --location=global & call npm config delete https-proxy --location=global & call npm config delete proxy & call npm config delete https-proxy & (exit /b 0)",
          "os": "windows"
        },
        {
          "type": "run",
          "label": "清理 npm 缓存",
          "cmd": "call npm cache clean --force & (exit /b 0)",
          "os": "windows"
        },
        {
          "type": "npm_install",
          "label": "强制重装 Claude Code",
          "package": "@anthropic-ai/claude-code",
          "force": true
        }
      ],
      "min_free_mb": 400
    },
    "codex": {
      "name": "Codex CLI",
      "bin": "codex",
      "verify_cmd": "codex --version",
      "steps": [
        {
          "type": "ensure_node",
          "label": "检查 Node.js 运行时（缺失则自动装便携版）"
        },
        {
          "type": "npm_install",
          "label": "安装 Codex CLI 最新版（npmmirror 国内加速；0.141+ 二进制已打包进主包，--include=optional 兜旧版平台子包）",
          "package": "@openai/codex",
          "with_optional": true
        },
        {
          "type": "run",
          "label": "覆盖上去：给已装的 AI 命令建轻量转发启动器并前置进用户 PATH，让 U-King 装的赢过你之前装的别家/旧版（不动你的 node/npm、不删你的东西；原 PATH 已备份到 ~/.uking/path-backup.txt，UKING_TEST_HOME 沙箱下跳过）",
          "cmd": "%SystemRoot%\\System32\\WindowsPowerShell\\v1.0\\powershell.exe -NoProfile -NonInteractive -Command \"if($env:UKING_TEST_HOME){ exit 0 }; $ErrorActionPreference='SilentlyContinue'; $shims=Join-Path $env:USERPROFILE '.uking\\shims'; New-Item -ItemType Directory -Force -Path $shims | Out-Null; $q=[char]34; $src=@((Join-Path $env:USERPROFILE '.uking\\runtime\\node'),(Join-Path $env:APPDATA 'npm'),(Join-Path $env:USERPROFILE 'bin'),(Join-Path $env:USERPROFILE '.uking\\runtime\\python\\Scripts')); foreach($t in @('claude','codex','openclaw','hermes','qwen','crush','opencode')){ $real=$null; foreach($d in $src){ foreach($e in @('.cmd','.exe')){ $p=Join-Path $d ($t+$e); if(Test-Path $p){ $real=$p; break } }; if($real){break} }; if($real){ Set-Content -LiteralPath (Join-Path $shims ($t+'.cmd')) -Value ('@echo off'+[Environment]::NewLine+$q+$real+$q+' '+[char]37+'*') -Encoding Default } }; $py=Join-Path $env:USERPROFILE '.uking\\runtime\\python\\python.exe'; if(Test-Path $py){ Set-Content -LiteralPath (Join-Path $shims 'python3.cmd') -Value ('@echo off'+[Environment]::NewLine+$q+$py+$q+' '+[char]37+'*') -Encoding Default }; $u=[Environment]::GetEnvironmentVariable('Path','User'); if($null -eq $u){$u=''}; $bak=Join-Path $env:USERPROFILE '.uking\\path-backup.txt'; if(-not (Test-Path $bak)){ [IO.File]::WriteAllText($bak,$u) }; $keep=@($u -split ';' | Where-Object { $_ -ne '' -and $_ -ne $shims }); [Environment]::SetEnvironmentVariable('Path',((@($shims)+$keep) -join ';'),'User'); exit 0\"",
          "os": "windows"
        }
      ],
      "repair": [
        {
          "type": "run",
          "label": "停止占用 OpenClaw/npm 全局目录的旧进程（修 EBUSY rename）",
          "cmd": "%SystemRoot%\\System32\\WindowsPowerShell\\v1.0\\powershell.exe -NoProfile -NonInteractive -Command \"$nodeRoot=(Join-Path $env:USERPROFILE '.uking\\runtime\\node'); Get-CimInstance Win32_Process | Where-Object { $_.ExecutablePath -and $_.ExecutablePath.StartsWith($nodeRoot,[StringComparison]::OrdinalIgnoreCase) } | ForEach-Object { Stop-Process -Id $_.ProcessId -Force -ErrorAction SilentlyContinue }; exit 0\"",
          "os": "windows"
        },
        {
          "type": "run",
          "label": "清除 npm 全局代理配置（客户机代理常把 npm 拦死）",
          "cmd": "call npm config delete proxy --location=global & call npm config delete https-proxy --location=global & call npm config delete proxy & call npm config delete https-proxy & (exit /b 0)",
          "os": "windows"
        },
        {
          "type": "run",
          "label": "放开 npm 拉取可选依赖（平台二进制是 optionalDependency，被关掉就装不上 codex 内核）",
          "cmd": "npm config delete optional --location=global & npm config set optional true & exit 0"
        },
        {
          "type": "run",
          "label": "清理 npm 缓存",
          "cmd": "call npm cache clean --force & (exit /b 0)",
          "os": "windows"
        },
        {
          "type": "npm_install",
          "label": "强制重装 Codex CLI（含平台二进制）",
          "package": "@openai/codex",
          "with_optional": true,
          "force": true
        },
        {
          "type": "run",
          "label": "兜底：下 OpenAI 官方 Codex 单文件二进制（npm 全失败时的最后防线；阿里云深圳 OSS 国内镜像主源→GitHub 兜底，断点续传）",
          "cmd": "%SystemRoot%\\System32\\curl.exe -fL -sS -C - --retry 3 --retry-delay 3 -m 1800 --proxy \"\" -o \"%TEMP%\\codex-cli.zip\" https://u-claw-updates.oss-cn-shenzhen.aliyuncs.com/uking/runtimes/codex-win-x64.zip || %SystemRoot%\\System32\\curl.exe -fL -sS -C - --retry 3 --retry-delay 3 -m 1800 --proxy \"\" -o \"%TEMP%\\codex-cli.zip\" https://github.com/openai/codex/releases/download/rust-v0.143.0/codex-x86_64-pc-windows-msvc.exe.zip",
          "os": "windows"
        },
        {
          "type": "run",
          "label": "解压装到 %USERPROFILE%\\bin\\codex.exe + 清掉半装坏掉的 codex 启动器（否则它在 PATH 里挡住好二进制，verify 永远失败）+ 把 ~/bin 加进用户 PATH",
          "cmd": "%SystemRoot%\\System32\\WindowsPowerShell\\v1.0\\powershell.exe -NoProfile -NonInteractive -Command \"$d=$env:USERPROFILE+'\\bin'; New-Item -ItemType Directory -Force -Path $d | Out-Null; $tmp=($env:TEMP+'\\codex-cli'); Remove-Item -Recurse -Force $tmp -ErrorAction SilentlyContinue; New-Item -ItemType Directory -Force -Path $tmp | Out-Null; & ($env:SystemRoot+'\\System32\\tar.exe') -xf ($env:TEMP+'\\codex-cli.zip') -C $tmp; Copy-Item -Force ($tmp+'\\codex-x86_64-pc-windows-msvc.exe') ($d+'\\codex.exe'); foreach($dir in @((Join-Path $env:USERPROFILE '.uking\\runtime\\node'),(Join-Path $env:APPDATA 'npm'))){ foreach($n in @('codex','codex.cmd','codex.ps1')){ $p=Join-Path $dir $n; if(Test-Path $p){ Remove-Item -Force $p -ErrorAction SilentlyContinue } } }; $u=[Environment]::GetEnvironmentVariable('Path','User'); if(($u -split ';') -notcontains $d){ [Environment]::SetEnvironmentVariable('Path',($u.TrimEnd(';')+';'+$d),'User') }; if (Test-Path ($d+'\\codex.exe')) { exit 0 } else { exit 1 }\"",
          "os": "windows"
        }
      ],
      "min_free_mb": 400
    },
    "codex-app": {
      "name": "Codex 桌面版",
      "bin": "codex-app",
      "verify_cmd": "powershell -NoProfile -NonInteractive -Command \"if (Get-AppxPackage -Name OpenAI.Codex) { (Get-AppxPackage -Name OpenAI.Codex).Version } else { exit 1 }\"",
      "steps": [
        {
          "type": "run",
          "label": "通过微软商店安装 Codex 桌面版（已装则跳过；商店安装较慢，请耐心等待）",
          "cmd": "%SystemRoot%\\System32\\WindowsPowerShell\\v1.0\\powershell.exe -NoProfile -NonInteractive -Command \"if (Get-AppxPackage -Name OpenAI.Codex) { Write-Host 'Codex 桌面版已安装，跳过'; exit 0 }; if (-not (Get-Command winget -ErrorAction SilentlyContinue)) { Write-Host 'winget 不可用，转兜底 MSIX'; exit 1 }; winget install --id 9PLM9XGG6VKS --source msstore --accept-package-agreements --accept-source-agreements --disable-interactivity; for ($i=0; $i -lt 12; $i++) { if (Get-AppxPackage -Name OpenAI.Codex) { Write-Host 'Codex 桌面版安装成功'; exit 0 }; Start-Sleep -Seconds 5 }; exit 1\"",
          "os": "windows"
        }
      ],
      "repair": [
        {
          "type": "run",
          "label": "下载官方 MSIX 安装包（约 650MB，慢网请耐心等待；镜像主域→镜像 R2 直链 两路兜底）",
          "cmd": "%SystemRoot%\\System32\\WindowsPowerShell\\v1.0\\powershell.exe -NoProfile -NonInteractive -ExecutionPolicy Bypass -Command \"$ErrorActionPreference='Stop'; $p=Join-Path $env:TEMP 'codex-app.msix'; Remove-Item $p -Force -ErrorAction SilentlyContinue; $urls=@('https://codexapp.agentsmirror.com/latest/win','https://codexapp-r2.agentsmirror.com/latest/win'); $ok=$false; foreach($u in $urls){ Write-Host ('下载 '+$u); & ($env:SystemRoot+'\\System32\\curl.exe') -fL -sS -m 2400 -o $p $u; if($LASTEXITCODE -eq 0 -and (Test-Path $p) -and (Get-Item $p).Length -gt 100MB){ $ok=$true; break } }; if(-not $ok){ throw 'Codex MSIX 下载失败或文件不完整，请点手动教程下载' }; Write-Host ('MSIX 已下载 '+[Math]::Round((Get-Item $p).Length/1MB)+' MB')\"",
          "os": "windows"
        },
        {
          "type": "run",
          "label": "安装 MSIX（免管理员，按用户安装）",
          "cmd": "%SystemRoot%\\System32\\WindowsPowerShell\\v1.0\\powershell.exe -NoProfile -NonInteractive -ExecutionPolicy Bypass -Command \"$p=Join-Path $env:TEMP 'codex-app.msix'; if(-not (Test-Path $p)){ throw '找不到 codex-app.msix，请重新下载安装包' }; Add-AppxPackage -Path $p -ErrorAction Stop; for($i=0; $i -lt 12; $i++){ if(Get-AppxPackage -Name OpenAI.Codex){ Write-Host 'Codex 桌面版安装成功'; exit 0 }; Start-Sleep -Seconds 5 }; throw 'MSIX 安装后未检测到 OpenAI.Codex，请重启 U-King 或按手动教程确认安装状态'\"",
          "os": "windows"
        }
      ],
      "min_free_mb": 1500
    },
    "openclaw": {
      "name": "OpenClaw 龙虾",
      "bin": "openclaw",
      "verify_cmd": "openclaw --version",
      "steps": [
        {
          "type": "ensure_node",
          "label": "检查 Node.js 运行时（OpenClaw 需 Node 22.19+）"
        },
        {
          "type": "npm_install",
          "label": "安装 OpenClaw（npm 国内源，绕开官方 git 安装）",
          "package": "openclaw"
        },
        {
          "type": "run",
          "label": "覆盖上去：给已装的 AI 命令建轻量转发启动器并前置进用户 PATH，让 U-King 装的赢过你之前装的别家/旧版（不动你的 node/npm、不删你的东西；原 PATH 已备份到 ~/.uking/path-backup.txt，UKING_TEST_HOME 沙箱下跳过）",
          "cmd": "%SystemRoot%\\System32\\WindowsPowerShell\\v1.0\\powershell.exe -NoProfile -NonInteractive -Command \"if($env:UKING_TEST_HOME){ exit 0 }; $ErrorActionPreference='SilentlyContinue'; $shims=Join-Path $env:USERPROFILE '.uking\\shims'; New-Item -ItemType Directory -Force -Path $shims | Out-Null; $q=[char]34; $src=@((Join-Path $env:USERPROFILE '.uking\\runtime\\node'),(Join-Path $env:APPDATA 'npm'),(Join-Path $env:USERPROFILE 'bin'),(Join-Path $env:USERPROFILE '.uking\\runtime\\python\\Scripts')); foreach($t in @('claude','codex','openclaw','hermes','qwen','crush','opencode')){ $real=$null; foreach($d in $src){ foreach($e in @('.cmd','.exe')){ $p=Join-Path $d ($t+$e); if(Test-Path $p){ $real=$p; break } }; if($real){break} }; if($real){ Set-Content -LiteralPath (Join-Path $shims ($t+'.cmd')) -Value ('@echo off'+[Environment]::NewLine+$q+$real+$q+' '+[char]37+'*') -Encoding Default } }; $py=Join-Path $env:USERPROFILE '.uking\\runtime\\python\\python.exe'; if(Test-Path $py){ Set-Content -LiteralPath (Join-Path $shims 'python3.cmd') -Value ('@echo off'+[Environment]::NewLine+$q+$py+$q+' '+[char]37+'*') -Encoding Default }; $u=[Environment]::GetEnvironmentVariable('Path','User'); if($null -eq $u){$u=''}; $bak=Join-Path $env:USERPROFILE '.uking\\path-backup.txt'; if(-not (Test-Path $bak)){ [IO.File]::WriteAllText($bak,$u) }; $keep=@($u -split ';' | Where-Object { $_ -ne '' -and $_ -ne $shims }); [Environment]::SetEnvironmentVariable('Path',((@($shims)+$keep) -join ';'),'User'); exit 0\"",
          "os": "windows"
        }
      ],
      "repair": [
        {
          "type": "run",
          "label": "停止占用 OpenClaw/npm 全局目录的旧进程（修 EBUSY rename）",
          "cmd": "%SystemRoot%\\System32\\WindowsPowerShell\\v1.0\\powershell.exe -NoProfile -NonInteractive -Command \"$nodeRoot=(Join-Path $env:USERPROFILE '.uking\\runtime\\node'); Get-CimInstance Win32_Process | Where-Object { $_.ExecutablePath -and $_.ExecutablePath.StartsWith($nodeRoot,[StringComparison]::OrdinalIgnoreCase) } | ForEach-Object { Stop-Process -Id $_.ProcessId -Force -ErrorAction SilentlyContinue }; exit 0\"",
          "os": "windows"
        },
        {
          "type": "run",
          "label": "清除 npm 全局代理配置（客户机代理常把 npm 拦死）",
          "cmd": "call npm config delete proxy --location=global & call npm config delete https-proxy --location=global & call npm config delete proxy & call npm config delete https-proxy & (exit /b 0)",
          "os": "windows"
        },
        {
          "type": "run",
          "label": "清理 npm 缓存",
          "cmd": "call npm cache clean --force & (exit /b 0)",
          "os": "windows"
        },
        {
          "type": "npm_install",
          "label": "强制重装 OpenClaw",
          "package": "openclaw",
          "force": true
        }
      ],
      "min_free_mb": 500
    },
    "hermes": {
      "name": "Hermes Agent",
      "bin": "hermes",
      "verify_cmd": "hermes --version",
      "steps": [
        {
          "type": "ensure_python",
          "label": "检查 Python 运行时（缺失则自动装便携版）"
        },
        {
          "type": "pip_install",
          "label": "安装 Hermes（pip 阿里源，绕开官方 git 安装）",
          "package": "hermes-agent[web]"
        },
        {
          "type": "run",
          "label": "清掉挡住 hermes 自带 utils.py 的旧版 utils/ shim 包（修 fast_safe_load ImportError；PowerShell 版，exit 0 永不误判失败）",
          "cmd": "%SystemRoot%\\System32\\WindowsPowerShell\\v1.0\\powershell.exe -NoProfile -NonInteractive -Command \"$base=Join-Path $env:USERPROFILE '.uking\\runtime\\python'; if(Test-Path $base){ Get-ChildItem -LiteralPath $base -Filter site-packages -Recurse -Directory -ErrorAction SilentlyContinue | ForEach-Object { $sp=$_.FullName; if((Test-Path (Join-Path $sp 'utils\\__init__.py')) -and (Test-Path (Join-Path $sp 'utils.py'))){ Remove-Item -LiteralPath (Join-Path $sp 'utils') -Recurse -Force -ErrorAction SilentlyContinue } } }; exit 0\"",
          "os": "windows"
        },
        {
          "type": "run",
          "label": "覆盖上去：给已装的 AI 命令建轻量转发启动器并前置进用户 PATH，让 U-King 装的赢过你之前装的别家/旧版（不动你的 node/npm、不删你的东西；原 PATH 已备份到 ~/.uking/path-backup.txt，UKING_TEST_HOME 沙箱下跳过）",
          "cmd": "%SystemRoot%\\System32\\WindowsPowerShell\\v1.0\\powershell.exe -NoProfile -NonInteractive -Command \"if($env:UKING_TEST_HOME){ exit 0 }; $ErrorActionPreference='SilentlyContinue'; $shims=Join-Path $env:USERPROFILE '.uking\\shims'; New-Item -ItemType Directory -Force -Path $shims | Out-Null; $q=[char]34; $src=@((Join-Path $env:USERPROFILE '.uking\\runtime\\node'),(Join-Path $env:APPDATA 'npm'),(Join-Path $env:USERPROFILE 'bin'),(Join-Path $env:USERPROFILE '.uking\\runtime\\python\\Scripts')); foreach($t in @('claude','codex','openclaw','hermes','qwen','crush','opencode')){ $real=$null; foreach($d in $src){ foreach($e in @('.cmd','.exe')){ $p=Join-Path $d ($t+$e); if(Test-Path $p){ $real=$p; break } }; if($real){break} }; if($real){ Set-Content -LiteralPath (Join-Path $shims ($t+'.cmd')) -Value ('@echo off'+[Environment]::NewLine+$q+$real+$q+' '+[char]37+'*') -Encoding Default } }; $py=Join-Path $env:USERPROFILE '.uking\\runtime\\python\\python.exe'; if(Test-Path $py){ Set-Content -LiteralPath (Join-Path $shims 'python3.cmd') -Value ('@echo off'+[Environment]::NewLine+$q+$py+$q+' '+[char]37+'*') -Encoding Default }; $u=[Environment]::GetEnvironmentVariable('Path','User'); if($null -eq $u){$u=''}; $bak=Join-Path $env:USERPROFILE '.uking\\path-backup.txt'; if(-not (Test-Path $bak)){ [IO.File]::WriteAllText($bak,$u) }; $keep=@($u -split ';' | Where-Object { $_ -ne '' -and $_ -ne $shims }); [Environment]::SetEnvironmentVariable('Path',((@($shims)+$keep) -join ';'),'User'); exit 0\"",
          "os": "windows"
        }
      ],
      "repair": [
        {
          "type": "run",
          "label": "清理损坏的便携 Python 目录（修解压中断 / Truncated tar archive；带重试防杀软瞬时锁住刚落盘文件）",
          "cmd": "%SystemRoot%\\System32\\WindowsPowerShell\\v1.0\\powershell.exe -NoProfile -NonInteractive -Command \"$p=Join-Path $env:USERPROFILE '.uking\\runtime\\python'; Remove-Item -LiteralPath $p -Recurse -Force -ErrorAction SilentlyContinue; if (Test-Path $p) { Start-Sleep -Seconds 2; Remove-Item -LiteralPath $p -Recurse -Force -ErrorAction SilentlyContinue }; if (Test-Path $p) { Start-Sleep -Seconds 3; Remove-Item -LiteralPath $p -Recurse -Force -ErrorAction SilentlyContinue }; exit 0\"",
          "os": "windows"
        },
        {
          "type": "ensure_python",
          "label": "重新下载并解压便携 Python"
        },
        {
          "type": "run",
          "label": "清理 pip 缓存（避免坏 wheel / 半包复用）",
          "cmd": "python -m pip cache purge || exit /b 0",
          "os": "windows"
        },
        {
          "type": "pip_install",
          "label": "强制重装 Hermes",
          "package": "hermes-agent[web]",
          "force": true
        },
        {
          "type": "run",
          "label": "清掉挡住 hermes 自带 utils.py 的旧版 utils/ shim 包（修 fast_safe_load ImportError；PowerShell 版，exit 0 永不误判失败）",
          "cmd": "%SystemRoot%\\System32\\WindowsPowerShell\\v1.0\\powershell.exe -NoProfile -NonInteractive -Command \"$base=Join-Path $env:USERPROFILE '.uking\\runtime\\python'; if(Test-Path $base){ Get-ChildItem -LiteralPath $base -Filter site-packages -Recurse -Directory -ErrorAction SilentlyContinue | ForEach-Object { $sp=$_.FullName; if((Test-Path (Join-Path $sp 'utils\\__init__.py')) -and (Test-Path (Join-Path $sp 'utils.py'))){ Remove-Item -LiteralPath (Join-Path $sp 'utils') -Recurse -Force -ErrorAction SilentlyContinue } } }; exit 0\"",
          "os": "windows"
        }
      ],
      "min_free_mb": 700
    },
    "qwen-code": {
      "name": "Qwen Code",
      "bin": "qwen",
      "verify_cmd": "qwen --version",
      "steps": [
        {
          "type": "ensure_node",
          "label": "检查 Node.js 运行时（缺失则自动装便携版）"
        },
        {
          "type": "npm_install",
          "label": "安装 Qwen Code（阿里通义开源终端 agent，npmmirror 国内加速）",
          "package": "@qwen-code/qwen-code"
        }
      ]
    },
    "crush": {
      "name": "Crush",
      "bin": "crush",
      "verify_cmd": "crush --version",
      "steps": [
        {
          "type": "ensure_node",
          "label": "检查 Node.js 运行时（缺失则自动装便携版）"
        },
        {
          "type": "npm_install",
          "label": "安装 Crush（Charm 出品，npm 包内含 Go 单二进制）",
          "package": "@charmland/crush"
        }
      ]
    },
    "opencode": {
      "name": "OpenCode",
      "bin": "opencode",
      "verify_cmd": "opencode --version",
      "steps": [
        {
          "type": "ensure_node",
          "label": "检查 Node.js 运行时（缺失则自动装便携版）"
        },
        {
          "type": "npm_install",
          "label": "安装 OpenCode（社区最大的开源终端编程 agent，npmmirror 国内加速）",
          "package": "opencode-ai"
        }
      ]
    },
    "pi": {
      "name": "pi",
      "bin": "pi",
      "verify_cmd": "pi --version",
      "steps": [
        {
          "type": "ensure_node",
          "label": "检查 Node.js 运行时（pi 要 22.19+，不够就用便携版）",
          "min": "22.19.0"
        },
        {
          "type": "npm_install",
          "label": "安装 pi（Mario Zechner 的开源终端 agent，npmmirror 国内加速）",
          "package": "@earendil-works/pi-coding-agent"
        }
      ]
    }
  }
}
