merge: resolve conflict in Windows-Start.bat, add Linux scripts and maintain lib

This commit is contained in:
dongsheng123132
2026-03-13 17:35:55 +08:00
parent c0dbe3bc41
commit 7766d59e55
11 changed files with 1952 additions and 75 deletions

273
portable/Linux-Install.sh Executable file
View File

@@ -0,0 +1,273 @@
#!/bin/bash
# ============================================================
# U-Claw - Install to Linux (从 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 安装到 Linux ║"
echo " ║ 从 U 盘离线安装 ║"
echo " ╚══════════════════════════════════════╝"
echo -e "${NC}"
echo ""
# ---- Check CPU ----
ARCH=$(uname -m)
if [ "$ARCH" = "x86_64" ]; then
echo -e " ${GREEN}Linux x86_64 ✓${NC}"
NODE_PLATFORM="node-linux-x64"
elif [ "$ARCH" = "aarch64" ]; then
echo -e " ${GREEN}Linux ARM64 ✓${NC}"
NODE_PLATFORM="node-linux-arm64"
else
echo -e " ${RED}Unsupported architecture: $ARCH${NC}"
exit 1
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="linux-$( [ "$ARCH" = "x86_64" ] && echo "x64" || echo "arm64" )"
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 HTML pages ----
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.sh" << 'STARTEOF'
#!/bin/bash
DIR="$(cd "$(dirname "$0")" && pwd)"
ARCH=$(uname -m)
NODE_PLATFORM="node-linux-$( [ "$ARCH" = "x86_64" ] && echo "x64" || echo "arm64" )"
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 ss -tlnp 2>/dev/null | grep -q ":$PORT " || netstat -tlnp 2>/dev/null | grep -q ":$PORT "; 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
xdg-open "http://127.0.0.1:$PORT/#token=uclaw" 2>/dev/null || echo "Open: http://127.0.0.1:$PORT/#token=uclaw"
break
fi
done
wait $PID
STARTEOF
chmod +x "$INSTALL_TARGET/start.sh"
# ---- Create desktop shortcut ----
DESKTOP_FILE="$HOME/.local/share/applications/u-claw.desktop"
mkdir -p "$HOME/.local/share/applications"
cat > "$DESKTOP_FILE" << DESKEOF
[Desktop Entry]
Name=U-Claw
Comment=Portable AI Agent
Exec=bash $INSTALL_TARGET/start.sh
Terminal=true
Type=Application
Categories=Utility;
DESKEOF
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}bash ~/.uclaw/start.sh${NC}"
echo -e " 或在应用菜单搜索 ${CYAN}U-Claw${NC}"
echo ""
echo -e " ${BOLD}首次使用:${NC}"
echo -e " 启动后浏览器自动打开配置页面"
echo -e " 选择 AI 模型 → 填写 API Key → 开始用"
echo ""
read -p " 按回车关闭..."