fix: bypass npm.cmd entirely, use node.exe npm-cli.js for Windows pipe mode
- Replace $INSTALL_NPM (npm.cmd) with $NPM_CLI (npm-cli.js) + $INSTALL_NODE - Use --prefix instead of Push-Location to avoid CWD issues in irm|iex pipe - Restore PATH for downloaded Node (npm-cli.js internally needs node in PATH) - Use [IO.File]::WriteAllText with BOM-free UTF8 for package.json/config/skills - Add debug output before npm install for easier troubleshooting
This commit is contained in:
@@ -80,7 +80,7 @@ Write-Host " [1/7] 安装 Node.js $NODE_VERSION ..." -ForegroundColor White
|
|||||||
|
|
||||||
$NODE_INSTALL_DIR = "$RUNTIME_DIR\node-$PLATFORM"
|
$NODE_INSTALL_DIR = "$RUNTIME_DIR\node-$PLATFORM"
|
||||||
$INSTALL_NODE = ""
|
$INSTALL_NODE = ""
|
||||||
$INSTALL_NPM = ""
|
$NPM_CLI = ""
|
||||||
$USE_SYSTEM_NODE = $false
|
$USE_SYSTEM_NODE = $false
|
||||||
|
|
||||||
# 检查系统 Node.js
|
# 检查系统 Node.js
|
||||||
@@ -91,7 +91,15 @@ if ($sysNode) {
|
|||||||
if ($major -ge 20) {
|
if ($major -ge 20) {
|
||||||
Write-Green " ✓ 系统已有 Node.js $sysVer,复用"
|
Write-Green " ✓ 系统已有 Node.js $sysVer,复用"
|
||||||
$INSTALL_NODE = "node"
|
$INSTALL_NODE = "node"
|
||||||
$INSTALL_NPM = "npm"
|
# 通过 npm.cmd 的位置找到 npm-cli.js
|
||||||
|
$npmCmd = (Get-Command npm -ErrorAction SilentlyContinue).Source
|
||||||
|
$npmRoot = Split-Path (Split-Path $npmCmd)
|
||||||
|
$NPM_CLI = "$npmRoot\node_modules\npm\bin\npm-cli.js"
|
||||||
|
if (-not (Test-Path $NPM_CLI)) {
|
||||||
|
# fallback: 直接用 npm prefix 找
|
||||||
|
$npmPrefix = & node -e "console.log(process.execPath.replace(/[\\\/]node\.exe$/i,''))" 2>$null
|
||||||
|
$NPM_CLI = "$npmPrefix\node_modules\npm\bin\npm-cli.js"
|
||||||
|
}
|
||||||
$USE_SYSTEM_NODE = $true
|
$USE_SYSTEM_NODE = $true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -100,7 +108,7 @@ if (-not $USE_SYSTEM_NODE) {
|
|||||||
if (Test-Path "$NODE_INSTALL_DIR\node.exe") {
|
if (Test-Path "$NODE_INSTALL_DIR\node.exe") {
|
||||||
Write-Green " ✓ Node.js 已存在,跳过下载"
|
Write-Green " ✓ Node.js 已存在,跳过下载"
|
||||||
$INSTALL_NODE = "$NODE_INSTALL_DIR\node.exe"
|
$INSTALL_NODE = "$NODE_INSTALL_DIR\node.exe"
|
||||||
$INSTALL_NPM = "$NODE_INSTALL_DIR\npm.cmd"
|
$NPM_CLI = "$NODE_INSTALL_DIR\node_modules\npm\bin\npm-cli.js"
|
||||||
} else {
|
} else {
|
||||||
Write-Cyan " ↓ 从国内镜像下载 Node.js $NODE_VERSION ($PLATFORM)..."
|
Write-Cyan " ↓ 从国内镜像下载 Node.js $NODE_VERSION ($PLATFORM)..."
|
||||||
$zipName = "node-$NODE_VERSION-$PLATFORM.zip"
|
$zipName = "node-$NODE_VERSION-$PLATFORM.zip"
|
||||||
@@ -139,14 +147,14 @@ if (-not $USE_SYSTEM_NODE) {
|
|||||||
if (Test-Path "$NODE_INSTALL_DIR\node.exe") {
|
if (Test-Path "$NODE_INSTALL_DIR\node.exe") {
|
||||||
Write-Green " ✓ Node.js 安装完成"
|
Write-Green " ✓ Node.js 安装完成"
|
||||||
$INSTALL_NODE = "$NODE_INSTALL_DIR\node.exe"
|
$INSTALL_NODE = "$NODE_INSTALL_DIR\node.exe"
|
||||||
$INSTALL_NPM = "$NODE_INSTALL_DIR\npm.cmd"
|
$NPM_CLI = "$NODE_INSTALL_DIR\node_modules\npm\bin\npm-cli.js"
|
||||||
} else {
|
} else {
|
||||||
Write-Red " ✗ Node.js 下载失败"
|
Write-Red " ✗ Node.js 下载失败"
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# 把下载的 Node 加到 PATH,让 npm.cmd 能找到 node.exe
|
# npm-cli.js 内部可能需要通过 PATH 找到 node.exe
|
||||||
$env:PATH = "$NODE_INSTALL_DIR;$env:PATH"
|
$env:PATH = "$NODE_INSTALL_DIR;$env:PATH"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -161,7 +169,7 @@ if (Test-Path "$CORE_DIR\node_modules\openclaw") {
|
|||||||
Write-Green " ✓ OpenClaw 已安装,跳过"
|
Write-Green " ✓ OpenClaw 已安装,跳过"
|
||||||
} else {
|
} else {
|
||||||
if (-not (Test-Path "$CORE_DIR\package.json")) {
|
if (-not (Test-Path "$CORE_DIR\package.json")) {
|
||||||
@'
|
$pkgJson = @'
|
||||||
{
|
{
|
||||||
"name": "u-claw-core",
|
"name": "u-claw-core",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
@@ -170,18 +178,27 @@ if (Test-Path "$CORE_DIR\node_modules\openclaw") {
|
|||||||
"openclaw": "latest"
|
"openclaw": "latest"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
'@ | Out-File -Encoding utf8 "$CORE_DIR\package.json"
|
'@
|
||||||
|
[IO.File]::WriteAllText("$CORE_DIR\package.json", $pkgJson, (New-Object System.Text.UTF8Encoding $false))
|
||||||
}
|
}
|
||||||
|
|
||||||
Write-Cyan " ↓ 从国内镜像安装..."
|
Write-Cyan " ↓ 从国内镜像安装..."
|
||||||
Push-Location $CORE_DIR
|
Write-Host " node: $INSTALL_NODE" -ForegroundColor DarkGray
|
||||||
& $INSTALL_NPM install --registry=$MIRROR 2>&1 | Select-Object -Last 5
|
Write-Host " npm-cli: $NPM_CLI" -ForegroundColor DarkGray
|
||||||
if ($LASTEXITCODE -ne 0) {
|
Write-Host " prefix: $CORE_DIR" -ForegroundColor DarkGray
|
||||||
Write-Red " ✗ OpenClaw 安装失败,请检查网络"
|
if (-not (Test-Path $NPM_CLI)) {
|
||||||
Pop-Location
|
Write-Red " ✗ npm-cli.js 不存在: $NPM_CLI"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
if (-not (Test-Path "$CORE_DIR\package.json")) {
|
||||||
|
Write-Red " ✗ package.json 不存在: $CORE_DIR\package.json"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
& $INSTALL_NODE $NPM_CLI install --prefix "$CORE_DIR" --registry=$MIRROR 2>&1 | Select-Object -Last 5
|
||||||
|
if ($LASTEXITCODE -ne 0) {
|
||||||
|
Write-Red " ✗ OpenClaw 安装失败,请检查网络"
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
Pop-Location
|
|
||||||
Write-Green " ✓ OpenClaw 安装完成"
|
Write-Green " ✓ OpenClaw 安装完成"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -197,12 +214,9 @@ if (Test-Path "$CORE_DIR\node_modules\@sliverp\qqbot") {
|
|||||||
} else {
|
} else {
|
||||||
Write-Cyan " ↓ 安装 QQ 插件..."
|
Write-Cyan " ↓ 安装 QQ 插件..."
|
||||||
try {
|
try {
|
||||||
Push-Location $CORE_DIR
|
& $INSTALL_NODE $NPM_CLI install "@sliverp/qqbot@latest" --prefix "$CORE_DIR" --registry=$MIRROR 2>&1 | Out-Null
|
||||||
& $INSTALL_NPM install "@sliverp/qqbot@latest" --registry=$MIRROR 2>&1 | Out-Null
|
|
||||||
Pop-Location
|
|
||||||
Write-Green " ✓ QQ 插件安装完成"
|
Write-Green " ✓ QQ 插件安装完成"
|
||||||
} catch {
|
} catch {
|
||||||
Pop-Location
|
|
||||||
Write-Yellow " ⚠ QQ 插件安装失败(不影响主功能)"
|
Write-Yellow " ⚠ QQ 插件安装失败(不影响主功能)"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -421,7 +435,7 @@ foreach ($skillName in $skills.Keys) {
|
|||||||
$skillDir = "$SKILLS_TARGET\$skillName"
|
$skillDir = "$SKILLS_TARGET\$skillName"
|
||||||
if (-not (Test-Path $skillDir)) {
|
if (-not (Test-Path $skillDir)) {
|
||||||
New-Item -ItemType Directory -Force -Path $skillDir | Out-Null
|
New-Item -ItemType Directory -Force -Path $skillDir | Out-Null
|
||||||
$skills[$skillName] | Out-File -Encoding utf8 "$skillDir\SKILL.md"
|
[IO.File]::WriteAllText("$skillDir\SKILL.md", $skills[$skillName], (New-Object System.Text.UTF8Encoding $false))
|
||||||
$skillCount++
|
$skillCount++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -523,7 +537,7 @@ if ($hasConfig) {
|
|||||||
"@
|
"@
|
||||||
}
|
}
|
||||||
|
|
||||||
$configJson | Out-File -Encoding utf8 $CONFIG_PATH
|
[IO.File]::WriteAllText($CONFIG_PATH, $configJson, (New-Object System.Text.UTF8Encoding $false))
|
||||||
Write-Green " ✓ 模型配置完成: $($cfg.model)"
|
Write-Green " ✓ 模型配置完成: $($cfg.model)"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ Write-Host " [1/7] 安装 Node.js $NODE_VERSION ..." -ForegroundColor White
|
|||||||
|
|
||||||
$NODE_INSTALL_DIR = "$RUNTIME_DIR\node-$PLATFORM"
|
$NODE_INSTALL_DIR = "$RUNTIME_DIR\node-$PLATFORM"
|
||||||
$INSTALL_NODE = ""
|
$INSTALL_NODE = ""
|
||||||
$INSTALL_NPM = ""
|
$NPM_CLI = ""
|
||||||
$USE_SYSTEM_NODE = $false
|
$USE_SYSTEM_NODE = $false
|
||||||
|
|
||||||
# 检查系统 Node.js
|
# 检查系统 Node.js
|
||||||
@@ -91,7 +91,15 @@ if ($sysNode) {
|
|||||||
if ($major -ge 20) {
|
if ($major -ge 20) {
|
||||||
Write-Green " ✓ 系统已有 Node.js $sysVer,复用"
|
Write-Green " ✓ 系统已有 Node.js $sysVer,复用"
|
||||||
$INSTALL_NODE = "node"
|
$INSTALL_NODE = "node"
|
||||||
$INSTALL_NPM = "npm"
|
# 通过 npm.cmd 的位置找到 npm-cli.js
|
||||||
|
$npmCmd = (Get-Command npm -ErrorAction SilentlyContinue).Source
|
||||||
|
$npmRoot = Split-Path (Split-Path $npmCmd)
|
||||||
|
$NPM_CLI = "$npmRoot\node_modules\npm\bin\npm-cli.js"
|
||||||
|
if (-not (Test-Path $NPM_CLI)) {
|
||||||
|
# fallback: 直接用 npm prefix 找
|
||||||
|
$npmPrefix = & node -e "console.log(process.execPath.replace(/[\\\/]node\.exe$/i,''))" 2>$null
|
||||||
|
$NPM_CLI = "$npmPrefix\node_modules\npm\bin\npm-cli.js"
|
||||||
|
}
|
||||||
$USE_SYSTEM_NODE = $true
|
$USE_SYSTEM_NODE = $true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -100,7 +108,7 @@ if (-not $USE_SYSTEM_NODE) {
|
|||||||
if (Test-Path "$NODE_INSTALL_DIR\node.exe") {
|
if (Test-Path "$NODE_INSTALL_DIR\node.exe") {
|
||||||
Write-Green " ✓ Node.js 已存在,跳过下载"
|
Write-Green " ✓ Node.js 已存在,跳过下载"
|
||||||
$INSTALL_NODE = "$NODE_INSTALL_DIR\node.exe"
|
$INSTALL_NODE = "$NODE_INSTALL_DIR\node.exe"
|
||||||
$INSTALL_NPM = "$NODE_INSTALL_DIR\npm.cmd"
|
$NPM_CLI = "$NODE_INSTALL_DIR\node_modules\npm\bin\npm-cli.js"
|
||||||
} else {
|
} else {
|
||||||
Write-Cyan " ↓ 从国内镜像下载 Node.js $NODE_VERSION ($PLATFORM)..."
|
Write-Cyan " ↓ 从国内镜像下载 Node.js $NODE_VERSION ($PLATFORM)..."
|
||||||
$zipName = "node-$NODE_VERSION-$PLATFORM.zip"
|
$zipName = "node-$NODE_VERSION-$PLATFORM.zip"
|
||||||
@@ -139,14 +147,14 @@ if (-not $USE_SYSTEM_NODE) {
|
|||||||
if (Test-Path "$NODE_INSTALL_DIR\node.exe") {
|
if (Test-Path "$NODE_INSTALL_DIR\node.exe") {
|
||||||
Write-Green " ✓ Node.js 安装完成"
|
Write-Green " ✓ Node.js 安装完成"
|
||||||
$INSTALL_NODE = "$NODE_INSTALL_DIR\node.exe"
|
$INSTALL_NODE = "$NODE_INSTALL_DIR\node.exe"
|
||||||
$INSTALL_NPM = "$NODE_INSTALL_DIR\npm.cmd"
|
$NPM_CLI = "$NODE_INSTALL_DIR\node_modules\npm\bin\npm-cli.js"
|
||||||
} else {
|
} else {
|
||||||
Write-Red " ✗ Node.js 下载失败"
|
Write-Red " ✗ Node.js 下载失败"
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# 把下载的 Node 加到 PATH,让 npm.cmd 能找到 node.exe
|
# npm-cli.js 内部可能需要通过 PATH 找到 node.exe
|
||||||
$env:PATH = "$NODE_INSTALL_DIR;$env:PATH"
|
$env:PATH = "$NODE_INSTALL_DIR;$env:PATH"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -161,7 +169,7 @@ if (Test-Path "$CORE_DIR\node_modules\openclaw") {
|
|||||||
Write-Green " ✓ OpenClaw 已安装,跳过"
|
Write-Green " ✓ OpenClaw 已安装,跳过"
|
||||||
} else {
|
} else {
|
||||||
if (-not (Test-Path "$CORE_DIR\package.json")) {
|
if (-not (Test-Path "$CORE_DIR\package.json")) {
|
||||||
@'
|
$pkgJson = @'
|
||||||
{
|
{
|
||||||
"name": "u-claw-core",
|
"name": "u-claw-core",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
@@ -170,18 +178,27 @@ if (Test-Path "$CORE_DIR\node_modules\openclaw") {
|
|||||||
"openclaw": "latest"
|
"openclaw": "latest"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
'@ | Out-File -Encoding utf8 "$CORE_DIR\package.json"
|
'@
|
||||||
|
[IO.File]::WriteAllText("$CORE_DIR\package.json", $pkgJson, (New-Object System.Text.UTF8Encoding $false))
|
||||||
}
|
}
|
||||||
|
|
||||||
Write-Cyan " ↓ 从国内镜像安装..."
|
Write-Cyan " ↓ 从国内镜像安装..."
|
||||||
Push-Location $CORE_DIR
|
Write-Host " node: $INSTALL_NODE" -ForegroundColor DarkGray
|
||||||
& $INSTALL_NPM install --registry=$MIRROR 2>&1 | Select-Object -Last 5
|
Write-Host " npm-cli: $NPM_CLI" -ForegroundColor DarkGray
|
||||||
if ($LASTEXITCODE -ne 0) {
|
Write-Host " prefix: $CORE_DIR" -ForegroundColor DarkGray
|
||||||
Write-Red " ✗ OpenClaw 安装失败,请检查网络"
|
if (-not (Test-Path $NPM_CLI)) {
|
||||||
Pop-Location
|
Write-Red " ✗ npm-cli.js 不存在: $NPM_CLI"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
if (-not (Test-Path "$CORE_DIR\package.json")) {
|
||||||
|
Write-Red " ✗ package.json 不存在: $CORE_DIR\package.json"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
& $INSTALL_NODE $NPM_CLI install --prefix "$CORE_DIR" --registry=$MIRROR 2>&1 | Select-Object -Last 5
|
||||||
|
if ($LASTEXITCODE -ne 0) {
|
||||||
|
Write-Red " ✗ OpenClaw 安装失败,请检查网络"
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
Pop-Location
|
|
||||||
Write-Green " ✓ OpenClaw 安装完成"
|
Write-Green " ✓ OpenClaw 安装完成"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -197,12 +214,9 @@ if (Test-Path "$CORE_DIR\node_modules\@sliverp\qqbot") {
|
|||||||
} else {
|
} else {
|
||||||
Write-Cyan " ↓ 安装 QQ 插件..."
|
Write-Cyan " ↓ 安装 QQ 插件..."
|
||||||
try {
|
try {
|
||||||
Push-Location $CORE_DIR
|
& $INSTALL_NODE $NPM_CLI install "@sliverp/qqbot@latest" --prefix "$CORE_DIR" --registry=$MIRROR 2>&1 | Out-Null
|
||||||
& $INSTALL_NPM install "@sliverp/qqbot@latest" --registry=$MIRROR 2>&1 | Out-Null
|
|
||||||
Pop-Location
|
|
||||||
Write-Green " ✓ QQ 插件安装完成"
|
Write-Green " ✓ QQ 插件安装完成"
|
||||||
} catch {
|
} catch {
|
||||||
Pop-Location
|
|
||||||
Write-Yellow " ⚠ QQ 插件安装失败(不影响主功能)"
|
Write-Yellow " ⚠ QQ 插件安装失败(不影响主功能)"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -421,7 +435,7 @@ foreach ($skillName in $skills.Keys) {
|
|||||||
$skillDir = "$SKILLS_TARGET\$skillName"
|
$skillDir = "$SKILLS_TARGET\$skillName"
|
||||||
if (-not (Test-Path $skillDir)) {
|
if (-not (Test-Path $skillDir)) {
|
||||||
New-Item -ItemType Directory -Force -Path $skillDir | Out-Null
|
New-Item -ItemType Directory -Force -Path $skillDir | Out-Null
|
||||||
$skills[$skillName] | Out-File -Encoding utf8 "$skillDir\SKILL.md"
|
[IO.File]::WriteAllText("$skillDir\SKILL.md", $skills[$skillName], (New-Object System.Text.UTF8Encoding $false))
|
||||||
$skillCount++
|
$skillCount++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -523,7 +537,7 @@ if ($hasConfig) {
|
|||||||
"@
|
"@
|
||||||
}
|
}
|
||||||
|
|
||||||
$configJson | Out-File -Encoding utf8 $CONFIG_PATH
|
[IO.File]::WriteAllText($CONFIG_PATH, $configJson, (New-Object System.Text.UTF8Encoding $false))
|
||||||
Write-Green " ✓ 模型配置完成: $($cfg.model)"
|
Write-Green " ✓ 模型配置完成: $($cfg.model)"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user