feat: add USB builder tool and install-to-computer scripts
- build-usb.sh: one-click USB drive builder (downloads Node.js + OpenClaw from China mirrors, packages into USB-ready directory) - Mac-Install.command: install from USB to Mac (~/.uclaw/), offline-first with China mirror fallback - Windows-Install.bat: same for Windows - README.md rewritten to position project as "USB drive builder toolkit"
This commit is contained in:
257
portable/Mac-Install.command
Executable file
257
portable/Mac-Install.command
Executable file
@@ -0,0 +1,257 @@
|
||||
#!/bin/bash
|
||||
# ============================================================
|
||||
# U-Claw - Install to Mac (从 U 盘安装到电脑)
|
||||
# 优先使用 U 盘内的离线资源,缺失时从国内镜像下载
|
||||
# ============================================================
|
||||
|
||||
set -e
|
||||
|
||||
UCLAW_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
APP_DIR="$UCLAW_DIR/app"
|
||||
INSTALL_TARGET="$HOME/.uclaw"
|
||||
|
||||
GREEN='\033[0;32m'
|
||||
CYAN='\033[0;36m'
|
||||
RED='\033[0;31m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m'
|
||||
BOLD='\033[1m'
|
||||
DIM='\033[2m'
|
||||
|
||||
NODE_VER="v22.14.0"
|
||||
MIRROR="https://registry.npmmirror.com"
|
||||
NODE_MIRROR="https://npmmirror.com/mirrors/node"
|
||||
|
||||
clear
|
||||
echo ""
|
||||
echo -e "${CYAN}${BOLD}"
|
||||
echo " ╔══════════════════════════════════════╗"
|
||||
echo " ║ U-Claw 安装到 Mac ║"
|
||||
echo " ║ 从 U 盘离线安装 ║"
|
||||
echo " ╚══════════════════════════════════════╝"
|
||||
echo -e "${NC}"
|
||||
echo ""
|
||||
|
||||
# ---- Check CPU ----
|
||||
ARCH=$(uname -m)
|
||||
if [ "$ARCH" = "arm64" ]; then
|
||||
echo -e " ${GREEN}Apple Silicon (M 系列) ✓${NC}"
|
||||
NODE_PLATFORM="node-mac-arm64"
|
||||
else
|
||||
echo -e " ${YELLOW}Intel Mac${NC}"
|
||||
NODE_PLATFORM="node-mac-x64"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# ---- Check existing installation ----
|
||||
if [ -d "$INSTALL_TARGET" ]; then
|
||||
echo -e " ${YELLOW}检测到已有安装: $INSTALL_TARGET${NC}"
|
||||
read -p " 覆盖安装?(y/n): " -n 1 OVERWRITE
|
||||
echo ""
|
||||
if [ "$OVERWRITE" != "y" ] && [ "$OVERWRITE" != "Y" ]; then
|
||||
echo -e " ${DIM}已取消${NC}"
|
||||
exit 0
|
||||
fi
|
||||
echo ""
|
||||
fi
|
||||
|
||||
# ---- Step 1: Check environment ----
|
||||
echo -e " ${BOLD}[1/4] 检查环境...${NC}"
|
||||
|
||||
NEED_DOWNLOAD_NODE=false
|
||||
NEED_DOWNLOAD_OPENCLAW=false
|
||||
|
||||
# Check Node.js - prefer USB, then system, then download
|
||||
USB_NODE="$APP_DIR/runtime/$NODE_PLATFORM/bin/node"
|
||||
USB_NPM="$APP_DIR/runtime/$NODE_PLATFORM/bin/npm"
|
||||
|
||||
if [ -f "$USB_NODE" ]; then
|
||||
echo -e " ${GREEN}Node.js: 使用 U 盘内的 ($("$USB_NODE" --version))${NC}"
|
||||
USE_NODE="usb"
|
||||
elif command -v node >/dev/null 2>&1; then
|
||||
SYS_VER=$(node --version)
|
||||
MAJOR=$(echo "$SYS_VER" | sed 's/v//' | cut -d. -f1)
|
||||
if [ "$MAJOR" -ge 20 ] 2>/dev/null; then
|
||||
echo -e " ${GREEN}Node.js: 使用系统的 ($SYS_VER)${NC}"
|
||||
USE_NODE="system"
|
||||
else
|
||||
echo -e " ${YELLOW}Node.js: 系统版本太低 ($SYS_VER),需要 v20+${NC}"
|
||||
NEED_DOWNLOAD_NODE=true
|
||||
USE_NODE="download"
|
||||
fi
|
||||
else
|
||||
echo -e " ${YELLOW}Node.js: 未安装${NC}"
|
||||
NEED_DOWNLOAD_NODE=true
|
||||
USE_NODE="download"
|
||||
fi
|
||||
|
||||
# Check OpenClaw
|
||||
USB_OPENCLAW="$APP_DIR/core/node_modules/openclaw/openclaw.mjs"
|
||||
if [ -f "$USB_OPENCLAW" ]; then
|
||||
echo -e " ${GREEN}OpenClaw: 使用 U 盘内的${NC}"
|
||||
USE_OPENCLAW="usb"
|
||||
else
|
||||
echo -e " ${YELLOW}OpenClaw: U 盘内未找到,需要在线下载${NC}"
|
||||
NEED_DOWNLOAD_OPENCLAW=true
|
||||
USE_OPENCLAW="download"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
# ---- Step 2: Create install directory ----
|
||||
echo -e " ${BOLD}[2/4] 安装到 $INSTALL_TARGET ...${NC}"
|
||||
|
||||
mkdir -p "$INSTALL_TARGET"
|
||||
mkdir -p "$INSTALL_TARGET/data/.openclaw"
|
||||
mkdir -p "$INSTALL_TARGET/data/memory"
|
||||
mkdir -p "$INSTALL_TARGET/data/backups"
|
||||
|
||||
# ---- Step 3: Copy/Download Node.js ----
|
||||
echo -e " ${BOLD}[3/4] 安装 Node.js...${NC}"
|
||||
|
||||
NODE_INSTALL_DIR="$INSTALL_TARGET/runtime/$NODE_PLATFORM"
|
||||
|
||||
case $USE_NODE in
|
||||
usb)
|
||||
echo -e " ${CYAN}从 U 盘复制 Node.js...${NC}"
|
||||
mkdir -p "$NODE_INSTALL_DIR"
|
||||
cp -R "$APP_DIR/runtime/$NODE_PLATFORM/"* "$NODE_INSTALL_DIR/"
|
||||
chmod +x "$NODE_INSTALL_DIR/bin/node"
|
||||
INSTALL_NODE="$NODE_INSTALL_DIR/bin/node"
|
||||
INSTALL_NPM="$NODE_INSTALL_DIR/bin/npm"
|
||||
echo -e " ${GREEN}Node.js 安装完成 ✓${NC}"
|
||||
;;
|
||||
system)
|
||||
INSTALL_NODE="$(which node)"
|
||||
INSTALL_NPM="$(which npm)"
|
||||
echo -e " ${GREEN}使用系统 Node.js ✓${NC}"
|
||||
;;
|
||||
download)
|
||||
echo -e " ${CYAN}从国内镜像下载 Node.js $NODE_VER...${NC}"
|
||||
PLATFORM_NAME="darwin-$ARCH"
|
||||
TARBALL="node-${NODE_VER}-${PLATFORM_NAME}.tar.gz"
|
||||
URL="${NODE_MIRROR}/${NODE_VER}/${TARBALL}"
|
||||
|
||||
mkdir -p "$NODE_INSTALL_DIR"
|
||||
curl -# -L "$URL" -o "/tmp/$TARBALL"
|
||||
tar -xzf "/tmp/$TARBALL" -C "$NODE_INSTALL_DIR" --strip-components=1
|
||||
rm -f "/tmp/$TARBALL"
|
||||
chmod +x "$NODE_INSTALL_DIR/bin/node"
|
||||
INSTALL_NODE="$NODE_INSTALL_DIR/bin/node"
|
||||
INSTALL_NPM="$NODE_INSTALL_DIR/bin/npm"
|
||||
echo -e " ${GREEN}Node.js 下载安装完成 ✓${NC}"
|
||||
;;
|
||||
esac
|
||||
|
||||
echo ""
|
||||
|
||||
# ---- Step 4: Copy/Download OpenClaw ----
|
||||
echo -e " ${BOLD}[4/4] 安装 OpenClaw...${NC}"
|
||||
|
||||
CORE_INSTALL_DIR="$INSTALL_TARGET/core"
|
||||
|
||||
case $USE_OPENCLAW in
|
||||
usb)
|
||||
echo -e " ${CYAN}从 U 盘复制 OpenClaw + 插件...${NC}"
|
||||
mkdir -p "$CORE_INSTALL_DIR"
|
||||
cp -R "$APP_DIR/core/"* "$CORE_INSTALL_DIR/"
|
||||
echo -e " ${GREEN}OpenClaw 安装完成 ✓${NC}"
|
||||
;;
|
||||
download)
|
||||
echo -e " ${CYAN}从国内镜像下载 OpenClaw...${NC}"
|
||||
mkdir -p "$CORE_INSTALL_DIR"
|
||||
cat > "$CORE_INSTALL_DIR/package.json" << 'PKGEOF'
|
||||
{
|
||||
"name": "u-claw-core",
|
||||
"version": "1.0.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"openclaw": "latest"
|
||||
}
|
||||
}
|
||||
PKGEOF
|
||||
cd "$CORE_INSTALL_DIR"
|
||||
"$INSTALL_NODE" "$INSTALL_NPM" install --registry="$MIRROR" 2>&1 | tail -3
|
||||
"$INSTALL_NODE" "$INSTALL_NPM" install @sliverp/qqbot@latest --registry="$MIRROR" 2>&1 | tail -2
|
||||
echo -e " ${GREEN}OpenClaw 下载安装完成 ✓${NC}"
|
||||
;;
|
||||
esac
|
||||
|
||||
# ---- Default config ----
|
||||
CONFIG_PATH="$INSTALL_TARGET/data/.openclaw/openclaw.json"
|
||||
if [ ! -f "$CONFIG_PATH" ]; then
|
||||
cat > "$CONFIG_PATH" << 'CFGEOF'
|
||||
{
|
||||
"gateway": {
|
||||
"mode": "local",
|
||||
"auth": { "token": "uclaw" }
|
||||
}
|
||||
}
|
||||
CFGEOF
|
||||
fi
|
||||
|
||||
# ---- Copy launch scripts ----
|
||||
for f in Config.html U-Claw.html; do
|
||||
[ -f "$UCLAW_DIR/$f" ] && cp "$UCLAW_DIR/$f" "$INSTALL_TARGET/"
|
||||
done
|
||||
|
||||
# ---- Create launch script ----
|
||||
cat > "$INSTALL_TARGET/start.command" << 'STARTEOF'
|
||||
#!/bin/bash
|
||||
DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
ARCH=$(uname -m)
|
||||
NODE_PLATFORM="node-mac-$( [ "$ARCH" = "arm64" ] && echo "arm64" || echo "x64" )"
|
||||
|
||||
NODE_BIN="$DIR/runtime/$NODE_PLATFORM/bin/node"
|
||||
[ ! -f "$NODE_BIN" ] && NODE_BIN="$(which node)"
|
||||
|
||||
CORE_DIR="$DIR/core"
|
||||
OPENCLAW_MJS="$CORE_DIR/node_modules/openclaw/openclaw.mjs"
|
||||
|
||||
export OPENCLAW_HOME="$DIR/data"
|
||||
export OPENCLAW_STATE_DIR="$DIR/data/.openclaw"
|
||||
export OPENCLAW_CONFIG_PATH="$DIR/data/.openclaw/openclaw.json"
|
||||
|
||||
PORT=18789
|
||||
while lsof -i :$PORT >/dev/null 2>&1; do
|
||||
PORT=$((PORT + 1))
|
||||
[ $PORT -gt 18799 ] && echo "No available port" && exit 1
|
||||
done
|
||||
|
||||
cd "$CORE_DIR"
|
||||
"$NODE_BIN" "$OPENCLAW_MJS" gateway run --allow-unconfigured --force --port $PORT &
|
||||
PID=$!
|
||||
|
||||
for i in $(seq 1 30); do
|
||||
sleep 0.5
|
||||
if curl -s -o /dev/null "http://127.0.0.1:$PORT/" 2>/dev/null; then
|
||||
open "http://127.0.0.1:$PORT/#token=uclaw"
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
wait $PID
|
||||
STARTEOF
|
||||
chmod +x "$INSTALL_TARGET/start.command"
|
||||
|
||||
echo ""
|
||||
|
||||
# ---- Summary ----
|
||||
INSTALL_SIZE=$(du -sh "$INSTALL_TARGET" | cut -f1)
|
||||
|
||||
echo -e " ${GREEN}${BOLD}╔══════════════════════════════════════╗"
|
||||
echo -e " ║ ✅ 安装成功! ║"
|
||||
echo -e " ╚══════════════════════════════════════╝${NC}"
|
||||
echo ""
|
||||
echo -e " ${BOLD}安装位置:${NC} $INSTALL_TARGET"
|
||||
echo -e " ${BOLD}大小:${NC} $INSTALL_SIZE"
|
||||
echo ""
|
||||
echo -e " ${BOLD}启动方式:${NC}"
|
||||
echo -e " 双击 ${CYAN}$INSTALL_TARGET/start.command${NC}"
|
||||
echo -e " 或终端运行: ${CYAN}bash ~/.uclaw/start.command${NC}"
|
||||
echo ""
|
||||
echo -e " ${BOLD}首次使用:${NC}"
|
||||
echo -e " 启动后浏览器自动打开配置页面"
|
||||
echo -e " 选择 AI 模型 → 填写 API Key → 开始用"
|
||||
echo ""
|
||||
read -p " 按回车关闭..."
|
||||
149
portable/Windows-Install.bat
Normal file
149
portable/Windows-Install.bat
Normal file
@@ -0,0 +1,149 @@
|
||||
@echo off
|
||||
chcp 65001 >nul 2>&1
|
||||
title U-Claw - Install to Windows
|
||||
|
||||
echo.
|
||||
echo ========================================
|
||||
echo U-Claw 安装到 Windows
|
||||
echo 从 U 盘离线安装
|
||||
echo ========================================
|
||||
echo.
|
||||
|
||||
set "UCLAW_DIR=%~dp0"
|
||||
set "APP_DIR=%UCLAW_DIR%app"
|
||||
set "INSTALL_TARGET=%USERPROFILE%\.uclaw"
|
||||
set "MIRROR=https://registry.npmmirror.com"
|
||||
|
||||
REM ---- Step 1: Check environment ----
|
||||
echo [1/4] 检查环境...
|
||||
|
||||
set "USE_NODE=none"
|
||||
set "USB_NODE=%APP_DIR%\runtime\node-win-x64\node.exe"
|
||||
|
||||
if exist "%USB_NODE%" (
|
||||
echo Node.js: 使用 U 盘内的
|
||||
set "USE_NODE=usb"
|
||||
) else (
|
||||
where node >nul 2>&1
|
||||
if %errorlevel%==0 (
|
||||
for /f "tokens=*" %%v in ('node --version') do echo Node.js: 使用系统的 %%v
|
||||
set "USE_NODE=system"
|
||||
) else (
|
||||
echo [!] Node.js: 未安装,U 盘内也没有
|
||||
echo.
|
||||
echo 请先安装 Node.js v22+:
|
||||
echo https://npmmirror.com/mirrors/node/v22.14.0/
|
||||
echo 下载 node-v22.14.0-win-x64.zip
|
||||
echo.
|
||||
pause
|
||||
exit /b 1
|
||||
)
|
||||
)
|
||||
|
||||
set "USB_OPENCLAW=%APP_DIR%\core\node_modules\openclaw\openclaw.mjs"
|
||||
if exist "%USB_OPENCLAW%" (
|
||||
echo OpenClaw: 使用 U 盘内的
|
||||
set "USE_OPENCLAW=usb"
|
||||
) else (
|
||||
echo OpenClaw: U 盘内未找到,需要在线下载
|
||||
set "USE_OPENCLAW=download"
|
||||
)
|
||||
|
||||
echo.
|
||||
|
||||
REM ---- Step 2: Check existing ----
|
||||
if exist "%INSTALL_TARGET%" (
|
||||
echo 检测到已有安装: %INSTALL_TARGET%
|
||||
set /p OVERWRITE=" 覆盖安装?(y/n): "
|
||||
if /i not "%OVERWRITE%"=="y" (
|
||||
echo 已取消
|
||||
pause
|
||||
exit /b 0
|
||||
)
|
||||
echo.
|
||||
)
|
||||
|
||||
REM ---- Step 3: Create directories ----
|
||||
echo [2/4] 创建安装目录...
|
||||
mkdir "%INSTALL_TARGET%" 2>nul
|
||||
mkdir "%INSTALL_TARGET%\data\.openclaw" 2>nul
|
||||
mkdir "%INSTALL_TARGET%\data\memory" 2>nul
|
||||
mkdir "%INSTALL_TARGET%\data\backups" 2>nul
|
||||
echo.
|
||||
|
||||
REM ---- Step 4: Copy Node.js ----
|
||||
echo [3/4] 安装 Node.js...
|
||||
|
||||
if "%USE_NODE%"=="usb" (
|
||||
echo 从 U 盘复制 Node.js...
|
||||
xcopy /s /e /q /y "%APP_DIR%\runtime\node-win-x64" "%INSTALL_TARGET%\runtime\node-win-x64\" >nul
|
||||
set "INSTALL_NODE=%INSTALL_TARGET%\runtime\node-win-x64\node.exe"
|
||||
set "INSTALL_NPM=%INSTALL_TARGET%\runtime\node-win-x64\npm.cmd"
|
||||
echo Node.js 安装完成!
|
||||
) else (
|
||||
set "INSTALL_NODE=node"
|
||||
set "INSTALL_NPM=npm"
|
||||
echo 使用系统 Node.js
|
||||
)
|
||||
echo.
|
||||
|
||||
REM ---- Step 5: Copy/Download OpenClaw ----
|
||||
echo [4/4] 安装 OpenClaw...
|
||||
|
||||
if "%USE_OPENCLAW%"=="usb" (
|
||||
echo 从 U 盘复制 OpenClaw + 插件...
|
||||
xcopy /s /e /q /y "%APP_DIR%\core" "%INSTALL_TARGET%\core\" >nul
|
||||
echo OpenClaw 安装完成!
|
||||
) else (
|
||||
echo 从国内镜像下载 OpenClaw...
|
||||
mkdir "%INSTALL_TARGET%\core" 2>nul
|
||||
echo {"name":"u-claw-core","version":"1.0.0","private":true,"dependencies":{"openclaw":"latest"}} > "%INSTALL_TARGET%\core\package.json"
|
||||
cd /d "%INSTALL_TARGET%\core"
|
||||
call "%INSTALL_NPM%" install --registry=%MIRROR%
|
||||
call "%INSTALL_NPM%" install @sliverp/qqbot@latest --registry=%MIRROR%
|
||||
echo OpenClaw 下载安装完成!
|
||||
)
|
||||
|
||||
REM ---- Default config ----
|
||||
if not exist "%INSTALL_TARGET%\data\.openclaw\openclaw.json" (
|
||||
echo {"gateway":{"mode":"local","auth":{"token":"uclaw"}}} > "%INSTALL_TARGET%\data\.openclaw\openclaw.json"
|
||||
)
|
||||
|
||||
REM ---- Copy HTML pages ----
|
||||
if exist "%UCLAW_DIR%Config.html" copy "%UCLAW_DIR%Config.html" "%INSTALL_TARGET%\" >nul
|
||||
if exist "%UCLAW_DIR%U-Claw.html" copy "%UCLAW_DIR%U-Claw.html" "%INSTALL_TARGET%\" >nul
|
||||
|
||||
REM ---- Create launch script ----
|
||||
(
|
||||
echo @echo off
|
||||
echo chcp 65001 ^>nul 2^>^&1
|
||||
echo title U-Claw
|
||||
echo set "DIR=%%~dp0"
|
||||
echo set "NODE_BIN=%%DIR%%runtime\node-win-x64\node.exe"
|
||||
echo if not exist "%%NODE_BIN%%" set "NODE_BIN=node"
|
||||
echo set "OPENCLAW_MJS=%%DIR%%core\node_modules\openclaw\openclaw.mjs"
|
||||
echo set "OPENCLAW_HOME=%%DIR%%data"
|
||||
echo set "OPENCLAW_STATE_DIR=%%DIR%%data\.openclaw"
|
||||
echo set "OPENCLAW_CONFIG_PATH=%%DIR%%data\.openclaw\openclaw.json"
|
||||
echo set PORT=18789
|
||||
echo cd /d "%%DIR%%core"
|
||||
echo start "" http://127.0.0.1:%%PORT%%/#token=uclaw
|
||||
echo "%%NODE_BIN%%" "%%OPENCLAW_MJS%%" gateway run --allow-unconfigured --force --port %%PORT%%
|
||||
echo pause
|
||||
) > "%INSTALL_TARGET%\start.bat"
|
||||
|
||||
echo.
|
||||
echo ========================================
|
||||
echo 安装成功!
|
||||
echo ========================================
|
||||
echo.
|
||||
echo 安装位置: %INSTALL_TARGET%
|
||||
echo.
|
||||
echo 启动方式:
|
||||
echo 双击 %INSTALL_TARGET%\start.bat
|
||||
echo.
|
||||
echo 首次使用:
|
||||
echo 启动后浏览器自动打开配置页面
|
||||
echo 选择 AI 模型 - 填写 API Key - 开始用
|
||||
echo.
|
||||
pause
|
||||
262
portable/build-usb.sh
Executable file
262
portable/build-usb.sh
Executable file
@@ -0,0 +1,262 @@
|
||||
#!/bin/bash
|
||||
# ============================================================
|
||||
# U-Claw USB Builder - 一键制作 U 盘
|
||||
# 运行后自动下载所有依赖,打包成可直接拷贝到 U 盘的完整目录
|
||||
# ============================================================
|
||||
|
||||
set -e
|
||||
|
||||
GREEN='\033[0;32m'
|
||||
CYAN='\033[0;36m'
|
||||
RED='\033[0;31m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m'
|
||||
BOLD='\033[1m'
|
||||
DIM='\033[2m'
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
REPO_DIR="$(dirname "$SCRIPT_DIR")"
|
||||
NODE_VER="v22.14.0"
|
||||
MIRROR="https://registry.npmmirror.com"
|
||||
NODE_MIRROR="https://npmmirror.com/mirrors/node"
|
||||
|
||||
# Output directory
|
||||
OUTPUT_DIR="$REPO_DIR/usb-build"
|
||||
USB_DIR="$OUTPUT_DIR/U-Claw"
|
||||
|
||||
clear
|
||||
echo ""
|
||||
echo -e "${CYAN}${BOLD}"
|
||||
echo " ╔══════════════════════════════════════╗"
|
||||
echo " ║ U-Claw USB Builder ║"
|
||||
echo " ║ 一键制作 U 盘 ║"
|
||||
echo " ╚══════════════════════════════════════╝"
|
||||
echo -e "${NC}"
|
||||
echo ""
|
||||
|
||||
# ---- Detect platform ----
|
||||
OS=$(uname -s | tr '[:upper:]' '[:lower:]')
|
||||
ARCH=$(uname -m)
|
||||
|
||||
echo -e " ${BOLD}系统:${NC} $OS $ARCH"
|
||||
echo ""
|
||||
|
||||
# Ask which platforms to build for
|
||||
echo -e " ${BOLD}选择要打包的平台:${NC}"
|
||||
echo -e " ${GREEN}[1]${NC} 仅 Mac Apple Silicon (arm64)"
|
||||
echo -e " ${GREEN}[2]${NC} 仅 Windows (x64)"
|
||||
echo -e " ${GREEN}[3]${NC} Mac + Windows (全部)"
|
||||
echo ""
|
||||
|
||||
if [ -t 0 ]; then
|
||||
read -p " 选择 [1-3, 默认 3]: " PLATFORM_CHOICE
|
||||
else
|
||||
PLATFORM_CHOICE="3"
|
||||
fi
|
||||
PLATFORM_CHOICE="${PLATFORM_CHOICE:-3}"
|
||||
|
||||
BUILD_MAC=false
|
||||
BUILD_WIN=false
|
||||
case $PLATFORM_CHOICE in
|
||||
1) BUILD_MAC=true ;;
|
||||
2) BUILD_WIN=true ;;
|
||||
*) BUILD_MAC=true; BUILD_WIN=true ;;
|
||||
esac
|
||||
|
||||
echo ""
|
||||
|
||||
# ---- Clean previous build ----
|
||||
if [ -d "$USB_DIR" ]; then
|
||||
echo -e " ${YELLOW}清理上次构建...${NC}"
|
||||
rm -rf "$USB_DIR"
|
||||
fi
|
||||
mkdir -p "$USB_DIR"
|
||||
|
||||
# ---- Step 1: Copy scripts and HTML ----
|
||||
echo -e " ${BOLD}[1/5] 复制脚本和页面...${NC}"
|
||||
|
||||
# Copy all launch scripts and HTML pages
|
||||
for f in Mac-Start.command Mac-Menu.command Windows-Start.bat Windows-Menu.bat \
|
||||
Config.html U-Claw.html SkillHub.html default-config.json migrate.js setup.sh; do
|
||||
if [ -f "$SCRIPT_DIR/$f" ]; then
|
||||
cp "$SCRIPT_DIR/$f" "$USB_DIR/"
|
||||
echo -e " ${DIM} + $f${NC}"
|
||||
fi
|
||||
done
|
||||
|
||||
# Make scripts executable
|
||||
chmod +x "$USB_DIR"/*.command 2>/dev/null || true
|
||||
chmod +x "$USB_DIR"/*.sh 2>/dev/null || true
|
||||
|
||||
echo -e " ${GREEN}脚本复制完成 ✓${NC}"
|
||||
echo ""
|
||||
|
||||
# ---- Step 2: Create data directory structure ----
|
||||
echo -e " ${BOLD}[2/5] 创建数据目录...${NC}"
|
||||
|
||||
mkdir -p "$USB_DIR/data/.openclaw"
|
||||
mkdir -p "$USB_DIR/data/memory"
|
||||
mkdir -p "$USB_DIR/data/backups"
|
||||
|
||||
# Default config
|
||||
cat > "$USB_DIR/data/.openclaw/openclaw.json" << 'CFGEOF'
|
||||
{
|
||||
"gateway": {
|
||||
"mode": "local",
|
||||
"auth": { "token": "uclaw" }
|
||||
}
|
||||
}
|
||||
CFGEOF
|
||||
|
||||
echo -e " ${GREEN}数据目录创建完成 ✓${NC}"
|
||||
echo ""
|
||||
|
||||
# ---- Step 3: Download Node.js runtimes ----
|
||||
echo -e " ${BOLD}[3/5] 下载 Node.js 运行时...${NC}"
|
||||
|
||||
download_node() {
|
||||
local PLATFORM=$1
|
||||
local TARGET_DIR=$2
|
||||
|
||||
if [ -d "$TARGET_DIR" ] && [ -f "$TARGET_DIR/bin/node" -o -f "$TARGET_DIR/node.exe" ]; then
|
||||
echo -e " ${GREEN}$PLATFORM 已存在,跳过${NC}"
|
||||
return
|
||||
fi
|
||||
|
||||
mkdir -p "$TARGET_DIR"
|
||||
|
||||
if echo "$PLATFORM" | grep -q "win"; then
|
||||
local ZIPNAME="node-${NODE_VER}-${PLATFORM}.zip"
|
||||
local URL="${NODE_MIRROR}/${NODE_VER}/${ZIPNAME}"
|
||||
echo -e " ${CYAN}下载 $ZIPNAME...${NC}"
|
||||
curl -# -L "$URL" -o "/tmp/$ZIPNAME"
|
||||
|
||||
# Unzip
|
||||
local TMPEXTRACT="/tmp/node-extract-$$"
|
||||
mkdir -p "$TMPEXTRACT"
|
||||
unzip -q "/tmp/$ZIPNAME" -d "$TMPEXTRACT"
|
||||
cp -R "$TMPEXTRACT"/node-${NODE_VER}-${PLATFORM}/* "$TARGET_DIR/"
|
||||
rm -rf "$TMPEXTRACT" "/tmp/$ZIPNAME"
|
||||
else
|
||||
local TARBALL="node-${NODE_VER}-${PLATFORM}.tar.gz"
|
||||
local URL="${NODE_MIRROR}/${NODE_VER}/${TARBALL}"
|
||||
echo -e " ${CYAN}下载 $TARBALL...${NC}"
|
||||
curl -# -L "$URL" -o "/tmp/$TARBALL"
|
||||
tar -xzf "/tmp/$TARBALL" -C "$TARGET_DIR" --strip-components=1
|
||||
rm -f "/tmp/$TARBALL"
|
||||
chmod +x "$TARGET_DIR/bin/node"
|
||||
fi
|
||||
|
||||
echo -e " ${GREEN}$PLATFORM 下载完成 ✓${NC}"
|
||||
}
|
||||
|
||||
RUNTIME_DIR="$USB_DIR/app/runtime"
|
||||
mkdir -p "$RUNTIME_DIR"
|
||||
|
||||
if $BUILD_MAC; then
|
||||
download_node "darwin-arm64" "$RUNTIME_DIR/node-mac-arm64"
|
||||
fi
|
||||
|
||||
if $BUILD_WIN; then
|
||||
download_node "win-x64" "$RUNTIME_DIR/node-win-x64"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
# ---- Step 4: Install OpenClaw + plugins ----
|
||||
echo -e " ${BOLD}[4/5] 安装 OpenClaw + QQ 插件...${NC}"
|
||||
|
||||
CORE_DIR="$USB_DIR/app/core"
|
||||
mkdir -p "$CORE_DIR"
|
||||
|
||||
# Determine which Node.js to use for npm install
|
||||
if $BUILD_MAC && [ -f "$RUNTIME_DIR/node-mac-arm64/bin/node" ]; then
|
||||
INSTALL_NODE="$RUNTIME_DIR/node-mac-arm64/bin/node"
|
||||
INSTALL_NPM="$RUNTIME_DIR/node-mac-arm64/bin/npm"
|
||||
elif command -v node >/dev/null 2>&1; then
|
||||
INSTALL_NODE="node"
|
||||
INSTALL_NPM="npm"
|
||||
else
|
||||
echo -e " ${RED}没有可用的 Node.js,无法安装依赖${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Create package.json
|
||||
cat > "$CORE_DIR/package.json" << 'PKGEOF'
|
||||
{
|
||||
"name": "u-claw-core",
|
||||
"version": "1.0.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"openclaw": "latest"
|
||||
}
|
||||
}
|
||||
PKGEOF
|
||||
|
||||
echo -e " ${CYAN}安装 OpenClaw (国内镜像)...${NC}"
|
||||
cd "$CORE_DIR"
|
||||
"$INSTALL_NODE" "$INSTALL_NPM" install --registry="$MIRROR" 2>&1 | tail -3
|
||||
|
||||
# Install QQ plugin
|
||||
echo -e " ${CYAN}安装 QQ 插件...${NC}"
|
||||
"$INSTALL_NODE" "$INSTALL_NPM" install @sliverp/qqbot@latest --registry="$MIRROR" 2>&1 | tail -2
|
||||
|
||||
echo -e " ${GREEN}OpenClaw + QQ 插件安装完成 ✓${NC}"
|
||||
echo ""
|
||||
|
||||
# ---- Step 5: Calculate size and finish ----
|
||||
echo -e " ${BOLD}[5/5] 完成!${NC}"
|
||||
echo ""
|
||||
|
||||
USB_SIZE=$(du -sh "$USB_DIR" | cut -f1)
|
||||
FILE_COUNT=$(find "$USB_DIR" -type f | wc -l | tr -d ' ')
|
||||
|
||||
echo -e " ${GREEN}${BOLD}╔══════════════════════════════════════════╗"
|
||||
echo -e " ║ ✅ U 盘制作完成! ║"
|
||||
echo -e " ╚══════════════════════════════════════════╝${NC}"
|
||||
echo ""
|
||||
echo -e " ${BOLD}输出目录:${NC} $USB_DIR"
|
||||
echo -e " ${BOLD}总大小:${NC} $USB_SIZE"
|
||||
echo -e " ${BOLD}文件数:${NC} $FILE_COUNT"
|
||||
echo ""
|
||||
|
||||
if $BUILD_MAC; then
|
||||
echo -e " ${GREEN}✓${NC} Mac Apple Silicon (arm64)"
|
||||
fi
|
||||
if $BUILD_WIN; then
|
||||
echo -e " ${GREEN}✓${NC} Windows x64"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
echo -e " ${BOLD}接下来:${NC}"
|
||||
echo ""
|
||||
echo -e " ${CYAN}1. 插入 U 盘(建议 4GB 以上)${NC}"
|
||||
echo -e " ${CYAN}2. 复制到 U 盘:${NC}"
|
||||
echo ""
|
||||
echo -e " ${BOLD}Mac:${NC}"
|
||||
echo -e " cp -R $USB_DIR /Volumes/你的U盘/"
|
||||
echo ""
|
||||
echo -e " ${BOLD}或者用 Finder:${NC}"
|
||||
echo -e " 直接把 ${BOLD}U-Claw${NC} 文件夹拖到 U 盘"
|
||||
echo ""
|
||||
echo -e " ${CYAN}3. 在目标电脑上:${NC}"
|
||||
echo -e " Mac: 双击 ${BOLD}Mac-Start.command${NC}"
|
||||
echo -e " Win: 双击 ${BOLD}Windows-Start.bat${NC}"
|
||||
echo ""
|
||||
|
||||
# Optional: create tar.gz
|
||||
if [ -t 0 ]; then
|
||||
read -p " 是否也打包成 tar.gz 方便分发?(y/n): " -n 1 PACK
|
||||
echo ""
|
||||
if [ "$PACK" = "y" ] || [ "$PACK" = "Y" ]; then
|
||||
echo ""
|
||||
echo -e " ${CYAN}打包中...${NC}"
|
||||
cd "$OUTPUT_DIR"
|
||||
tar -czf "U-Claw.tar.gz" "U-Claw/"
|
||||
PACK_SIZE=$(du -sh "$OUTPUT_DIR/U-Claw.tar.gz" | cut -f1)
|
||||
echo -e " ${GREEN}打包完成: $OUTPUT_DIR/U-Claw.tar.gz ($PACK_SIZE)${NC}"
|
||||
fi
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo -e " ${DIM}完成!${NC}"
|
||||
Reference in New Issue
Block a user