From 83996e42db955a0b37ad8bb9c375f3aef1b146bf Mon Sep 17 00:00:00 2001 From: dongsheng123132 Date: Mon, 16 Mar 2026 15:51:54 +0800 Subject: [PATCH] feat: enhance Windows scripts to match Mac feature parity Windows-Start.bat: - Fix duplicate browser tab opening (was opening 3 tabs) - Read gateway token from config instead of hardcoding - Add config sync from legacy location - Use delayed browser open for gateway startup time Windows-Menu.bat: - Fix Node version display bug (double %% issue) - System info: add Windows version, architecture, memory, disk size - Check updates: auto-fetch latest version from npmmirror, one-click upgrade - Disk cleanup: show directory sizes, clean old backups/logs/npm cache - Log management: add export to desktop, clean logs older than 7 days - Restore backup: numbered list selection instead of typing folder name - Kill processes: add confirmation prompt before killing - Chat platforms: individual setup guidance per platform Windows-Install.bat: - Add Node.js online download fallback (was exit-only when missing) - Add system Node.js version check (require v20+) - Generated start.bat now has port detection loop - Show install size on completion Windows-Diagnose.bat: - Add system info logging (Windows version, architecture) - Add config file and model configuration check - Expand port scan to full 18789-18799 range - Show OpenClaw version in test output Co-Authored-By: Claude Opus 4.6 (1M context) --- portable/Windows-Diagnose.bat | 109 +++++++--- portable/Windows-Install.bat | 90 ++++++-- portable/Windows-Menu.bat | 377 ++++++++++++++++++++++++++++------ portable/Windows-Start.bat | 82 ++++---- 4 files changed, 498 insertions(+), 160 deletions(-) diff --git a/portable/Windows-Diagnose.bat b/portable/Windows-Diagnose.bat index 10732a0..d98fb2f 100644 --- a/portable/Windows-Diagnose.bat +++ b/portable/Windows-Diagnose.bat @@ -1,4 +1,5 @@ @echo off +setlocal EnableDelayedExpansion chcp 65001 >nul 2>&1 title U-Claw - Diagnostic Tool @@ -8,10 +9,9 @@ set "LOG_FILE=%UCLAW_DIR%diagnostic-log.txt" echo. echo ======================================== echo U-Claw Diagnostic Tool -echo 诊断工具 echo ======================================== echo. -echo Checking system... 正在检查系统... +echo Checking system... echo. REM Clear old log @@ -20,14 +20,22 @@ echo Generated: %date% %time% >> "%LOG_FILE%" echo ======================================== >> "%LOG_FILE%" echo. >> "%LOG_FILE%" +REM System info +echo System Info: >> "%LOG_FILE%" +for /f "tokens=2 delims==" %%v in ('wmic os get Version /format:list 2^>nul ^| findstr "="') do echo Windows Version: %%v >> "%LOG_FILE%" +for /f "tokens=2 delims==" %%v in ('wmic os get OSArchitecture /format:list 2^>nul ^| findstr "="') do echo Architecture: %%v >> "%LOG_FILE%" +echo. >> "%LOG_FILE%" + REM 1. Check Node.js -echo [1/6] 检查 Node.js 运行环境... +echo [1/7] 检查 Node.js 运行环境... set "NODE_BIN=%UCLAW_DIR%app\runtime\node-win-x64\node.exe" set "ERROR_COUNT=0" if exist "%NODE_BIN%" ( echo [OK] Node.js found >> "%LOG_FILE%" - for /f "tokens=*" %%v in ('"%NODE_BIN%" --version 2^>^&1') do echo Version: %%v >> "%LOG_FILE%" - echo ✓ Node.js 运行环境: 正常 + for /f "tokens=*" %%v in ('"%NODE_BIN%" --version 2^>^&1') do ( + echo Version: %%v >> "%LOG_FILE%" + echo ✓ Node.js 运行环境: %%v + ) ) else ( echo [ERROR] Node.js not found >> "%LOG_FILE%" echo ✗ Node.js 运行环境: 缺失 @@ -39,19 +47,19 @@ REM Migration shim: rename old core-win to core for existing USB users if exist "%UCLAW_DIR%app\core-win" if not exist "%UCLAW_DIR%app\core" ren "%UCLAW_DIR%app\core-win" core REM 2. Check core directory -echo [2/6] 检查 Windows 依赖目录... +echo [2/7] 检查依赖目录... set "CORE_DIR=%UCLAW_DIR%app\core" if exist "%CORE_DIR%" ( echo [OK] core directory exists >> "%LOG_FILE%" - echo ✓ Windows 依赖目录: 正常 + echo ✓ 依赖目录: 正常 ) else ( echo [ERROR] core directory not found >> "%LOG_FILE%" - echo ✗ Windows 依赖目录: 缺失 + echo ✗ 依赖目录: 缺失 set /a ERROR_COUNT+=1 ) REM 3. Check node_modules -echo [3/6] 检查 npm 依赖包... +echo [3/7] 检查 npm 依赖包... if exist "%CORE_DIR%\node_modules" ( echo [OK] node_modules exists >> "%LOG_FILE%" echo ✓ npm 依赖包: 已安装 @@ -62,7 +70,7 @@ if exist "%CORE_DIR%\node_modules" ( ) REM 4. Check OpenClaw -echo [4/6] 检查 OpenClaw 核心文件... +echo [4/7] 检查 OpenClaw 核心文件... set "OPENCLAW_MJS=%CORE_DIR%\node_modules\openclaw\openclaw.mjs" if exist "%OPENCLAW_MJS%" ( echo [OK] openclaw.mjs found >> "%LOG_FILE%" @@ -74,20 +82,45 @@ if exist "%OPENCLAW_MJS%" ( set /a ERROR_COUNT+=1 ) -REM 5. Check port availability -echo [5/6] 检查端口占用... -netstat -an | findstr ":18789 " | findstr "LISTENING" >nul 2>&1 -if %errorlevel%==0 ( - echo [WARNING] Port 18789 is in use >> "%LOG_FILE%" - echo ⚠ 端口 18789: 已被占用 - netstat -ano | findstr ":18789 " >> "%LOG_FILE%" +REM 5. Check config +echo [5/7] 检查配置文件... +set "STATE_DIR=%UCLAW_DIR%data\.openclaw" +if exist "%STATE_DIR%\openclaw.json" ( + echo [OK] Config file exists >> "%LOG_FILE%" + echo ✓ 配置文件: 正常 + REM Check if model is configured + findstr /c:"model" "%STATE_DIR%\openclaw.json" >nul 2>&1 + if !errorlevel!==0 ( + echo ✓ AI 模型: 已配置 + ) else ( + echo ⚠ AI 模型: 未配置(首次使用请先配置) + ) ) else ( - echo [OK] Port 18789 is available >> "%LOG_FILE%" - echo ✓ 端口 18789: 可用 + echo [WARNING] Config not found >> "%LOG_FILE%" + echo ⚠ 配置文件: 未创建(首次启动会自动创建) ) -REM 6. Test OpenClaw startup -echo [6/6] 测试 OpenClaw 启动... +REM 6. Check port availability +echo [6/7] 检查端口占用... +set "PORT_ISSUE=0" +for /l %%p in (18789,1,18799) do ( + netstat -an | findstr ":%%p " | findstr "LISTENING" >nul 2>&1 + if !errorlevel!==0 ( + echo [WARNING] Port %%p is in use >> "%LOG_FILE%" + echo ⚠ 端口 %%p: 已被占用 + for /f "tokens=5" %%a in ('netstat -ano ^| findstr ":%%p " ^| findstr "LISTENING"') do ( + echo PID: %%a >> "%LOG_FILE%" + ) + set "PORT_ISSUE=1" + ) +) +if "!PORT_ISSUE!"=="0" ( + echo [OK] Ports 18789-18799 available >> "%LOG_FILE%" + echo ✓ 端口 18789-18799: 全部可用 +) + +REM 7. Test OpenClaw startup +echo [7/7] 测试 OpenClaw 启动... echo. >> "%LOG_FILE%" echo Testing OpenClaw startup: >> "%LOG_FILE%" echo ---------------------------------------- >> "%LOG_FILE%" @@ -98,10 +131,11 @@ set "OPENCLAW_CONFIG_PATH=%OPENCLAW_STATE_DIR%\openclaw.json" if exist "%NODE_BIN%" if exist "%OPENCLAW_MJS%" ( cd /d "%CORE_DIR%" - "%NODE_BIN%" "%OPENCLAW_MJS%" --version >> "%LOG_FILE%" 2>&1 - if %errorlevel%==0 ( - echo ✓ OpenClaw 启动测试: 通过 - ) else ( + for /f "tokens=*" %%v in ('"%NODE_BIN%" "%OPENCLAW_MJS%" --version 2^>^&1') do ( + echo %%v >> "%LOG_FILE%" + echo ✓ OpenClaw 启动测试: 通过 (%%v^) + ) + if !errorlevel! neq 0 ( echo ✗ OpenClaw 启动测试: 失败 echo [ERROR] OpenClaw failed to start >> "%LOG_FILE%" set /a ERROR_COUNT+=1 @@ -111,35 +145,42 @@ if exist "%NODE_BIN%" if exist "%OPENCLAW_MJS%" ( echo [SKIP] Cannot test - required files missing >> "%LOG_FILE%" ) +REM Disk space check +echo. >> "%LOG_FILE%" +echo Disk Space: >> "%LOG_FILE%" +for /f "tokens=*" %%s in ('powershell -command "(Get-ChildItem '%UCLAW_DIR%' -Recurse -ErrorAction SilentlyContinue | Measure-Object -Property Length -Sum).Sum / 1MB" 2^>nul') do ( + echo Total size: %%s MB >> "%LOG_FILE%" +) + echo. echo. >> "%LOG_FILE%" echo ======================================== >> "%LOG_FILE%" echo Diagnostic complete. >> "%LOG_FILE%" -echo Error count: %ERROR_COUNT% >> "%LOG_FILE%" +echo Error count: !ERROR_COUNT! >> "%LOG_FILE%" echo ======================================== echo 诊断完成 echo ======================================== echo. -if %ERROR_COUNT%==0 ( +if !ERROR_COUNT!==0 ( echo ✅ 检查结果: 全部正常! echo 所有必需的组件都已就绪,可以正常使用。 echo. - echo 💡 下一步: + echo 下一步: echo - 双击 Windows-Start.bat 启动服务 - echo - 或查看 Welcome.html 了解使用说明 + echo - 或双击 Config.html 配置 AI 模型 ) else ( - echo ❌ 检查结果: 发现 %ERROR_COUNT% 个问题 + echo ❌ 检查结果: 发现 !ERROR_COUNT! 个问题 echo. - echo 💡 解决方案: + echo 解决方案: echo 1. 查看 diagnostic-log.txt 了解详细错误 echo 2. 尝试重新运行 Windows-Start.bat echo (会自动安装缺失的依赖) - echo 3. 如问题仍然存在,请查看 Welcome.html - echo 或访问 github.com/dongsheng123132/u-claw + echo 3. 如问题仍然存在,访问: + echo github.com/dongsheng123132/u-claw ) echo. -echo 📄 诊断日志已保存: diagnostic-log.txt +echo 诊断日志已保存: diagnostic-log.txt echo. pause diff --git a/portable/Windows-Install.bat b/portable/Windows-Install.bat index b3aaa8d..772b58f 100644 --- a/portable/Windows-Install.bat +++ b/portable/Windows-Install.bat @@ -1,4 +1,5 @@ @echo off +setlocal EnableDelayedExpansion chcp 65001 >nul 2>&1 title U-Claw - Install to Windows @@ -13,6 +14,8 @@ set "UCLAW_DIR=%~dp0" set "APP_DIR=%UCLAW_DIR%app" set "INSTALL_TARGET=%USERPROFILE%\.uclaw" set "MIRROR=https://registry.npmmirror.com" +set "NODE_MIRROR=https://npmmirror.com/mirrors/node" +set "NODE_VER=v22.14.0" REM ---- Step 1: Check environment ---- echo [1/4] 检查环境... @@ -21,22 +24,27 @@ set "USE_NODE=none" set "USB_NODE=%APP_DIR%\runtime\node-win-x64\node.exe" if exist "%USB_NODE%" ( - echo Node.js: 使用 U 盘内的 + for /f "tokens=*" %%v in ('"%USB_NODE%" --version') do echo Node.js: 使用 U 盘内的 %%v 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" + if !errorlevel!==0 ( + for /f "tokens=*" %%v in ('node --version') do ( + echo Node.js: 检查系统版本 %%v + set "SYS_VER=%%v" + ) + REM Check if version >= 20 + for /f "tokens=1 delims=." %%m in ("!SYS_VER:v=!") do set "MAJOR=%%m" + if !MAJOR! geq 20 ( + echo Node.js: 使用系统的 !SYS_VER! + set "USE_NODE=system" + ) else ( + echo Node.js: 系统版本太低 ^(!SYS_VER!^), 需要 v20+ + set "USE_NODE=download" + ) ) 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 + echo Node.js: 未安装 + set "USE_NODE=download" ) ) @@ -55,7 +63,7 @@ REM ---- Step 2: Check existing ---- if exist "%INSTALL_TARGET%" ( echo 检测到已有安装: %INSTALL_TARGET% set /p OVERWRITE=" 覆盖安装?(y/n): " - if /i not "%OVERWRITE%"=="y" ( + if /i not "!OVERWRITE!"=="y" ( echo 已取消 pause exit /b 0 @@ -69,28 +77,55 @@ 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 +mkdir "%INSTALL_TARGET%\data\logs" 2>nul echo. -REM ---- Step 4: Copy Node.js ---- +REM ---- Step 4: Copy/Download Node.js ---- echo [3/4] 安装 Node.js... -if "%USE_NODE%"=="usb" ( +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 ( +) else if "!USE_NODE!"=="system" ( set "INSTALL_NODE=node" set "INSTALL_NPM=npm" echo 使用系统 Node.js +) else ( + echo 从国内镜像下载 Node.js %NODE_VER%... + set "NODE_ZIP=node-%NODE_VER%-win-x64.zip" + set "NODE_URL=%NODE_MIRROR%/%NODE_VER%/!NODE_ZIP!" + echo URL: !NODE_URL! + echo. + + REM Download using curl (available on Windows 10+) + curl -# -L "!NODE_URL!" -o "%TEMP%\!NODE_ZIP!" + if !errorlevel! neq 0 ( + echo [ERROR] 下载失败!请检查网络连接 + echo 也可以手动下载: !NODE_URL! + pause + exit /b 1 + ) + + echo 解压中... + mkdir "%INSTALL_TARGET%\runtime\node-win-x64" 2>nul + powershell -command "Expand-Archive -Path '%TEMP%\!NODE_ZIP!' -DestinationPath '%TEMP%\node-extract' -Force" + xcopy /s /e /q /y "%TEMP%\node-%NODE_VER%-win-x64\*" "%INSTALL_TARGET%\runtime\node-win-x64\" >nul + rmdir /s /q "%TEMP%\node-extract" 2>nul + del "%TEMP%\!NODE_ZIP!" 2>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 下载安装完成! ) echo. REM ---- Step 5: Copy/Download OpenClaw ---- echo [4/4] 安装 OpenClaw... -if "%USE_OPENCLAW%"=="usb" ( +if "!USE_OPENCLAW!"=="usb" ( echo 从 U 盘复制 OpenClaw + 插件... xcopy /s /e /q /y "%APP_DIR%\core" "%INSTALL_TARGET%\core\" >nul echo OpenClaw 安装完成! @@ -99,8 +134,8 @@ if "%USE_OPENCLAW%"=="usb" ( 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% + call "!INSTALL_NPM!" install --registry=%MIRROR% + call "!INSTALL_NPM!" install @sliverp/qqbot@latest --registry=%MIRROR% echo OpenClaw 下载安装完成! ) @@ -116,6 +151,7 @@ if exist "%UCLAW_DIR%U-Claw.html" copy "%UCLAW_DIR%U-Claw.html" "%INSTALL_TARGET REM ---- Create launch script ---- ( echo @echo off +echo setlocal EnableDelayedExpansion echo chcp 65001 ^>nul 2^>^&1 echo title U-Claw echo set "DIR=%%~dp0" @@ -125,10 +161,20 @@ 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. +echo REM Find available port echo set PORT=18789 +echo :check_port +echo netstat -an ^| findstr ":%%PORT%% " ^| findstr "LISTENING" ^>nul 2^>^&1 +echo if %%errorlevel%%==0 ( +echo set /a PORT+=1 +echo if !PORT! gtr 18799 (echo No available port ^& pause ^& exit /b 1^) +echo goto :check_port +echo ^) +echo. 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 start /B "" cmd /c "timeout /t 3 /nobreak ^>nul ^&^& 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" @@ -139,6 +185,8 @@ echo ======================================== echo. echo 安装位置: %INSTALL_TARGET% echo. +for /f "tokens=*" %%s in ('powershell -command "(Get-ChildItem '%INSTALL_TARGET%' -Recurse -ErrorAction SilentlyContinue | Measure-Object -Property Length -Sum).Sum / 1MB" 2^>nul') do echo 大小: %%s MB +echo. echo 启动方式: echo 双击 %INSTALL_TARGET%\start.bat echo. diff --git a/portable/Windows-Menu.bat b/portable/Windows-Menu.bat index 8048799..2ea3b82 100644 --- a/portable/Windows-Menu.bat +++ b/portable/Windows-Menu.bat @@ -1,4 +1,5 @@ -@echo off +@echo off +setlocal EnableDelayedExpansion chcp 65001 >nul 2>&1 title U-Claw Menu @@ -13,6 +14,7 @@ set "DATA_DIR=%UCLAW_DIR%data" set "STATE_DIR=%DATA_DIR%\.openclaw" set "NODE_DIR=%UCLAW_DIR%app\runtime\node-win-x64" set "NODE_BIN=%NODE_DIR%\node.exe" +set "NPM_BIN=%NODE_DIR%\npm.cmd" set "OPENCLAW_HOME=%DATA_DIR%" set "OPENCLAW_STATE_DIR=%STATE_DIR%" @@ -20,11 +22,13 @@ set "OPENCLAW_CONFIG_PATH=%STATE_DIR%\openclaw.json" set "PATH=%NODE_DIR%;%PATH%" set "OPENCLAW_MJS=%CORE_DIR%\node_modules\openclaw\openclaw.mjs" +set "LOG_DIR=%DATA_DIR%\logs" +set "BACKUP_DIR=%DATA_DIR%\backups" if not exist "%STATE_DIR%" mkdir "%STATE_DIR%" if not exist "%DATA_DIR%\memory" mkdir "%DATA_DIR%\memory" -if not exist "%DATA_DIR%\backups" mkdir "%DATA_DIR%\backups" -if not exist "%DATA_DIR%\logs" mkdir "%DATA_DIR%\logs" +if not exist "%BACKUP_DIR%" mkdir "%BACKUP_DIR%" +if not exist "%LOG_DIR%" mkdir "%LOG_DIR%" :menu cls @@ -36,7 +40,7 @@ echo ======================================== echo. if exist "%NODE_BIN%" ( - for /f "tokens=*" %%v in ('"%%NODE_BIN%%" --version') do echo Node: %%v + for /f "tokens=*" %%v in ('"%NODE_BIN%" --version') do echo Node: %%v ) else ( echo [!] Node.js not found ) @@ -109,17 +113,24 @@ echo Starting gateway... set PORT=18789 :find_port netstat -an | findstr ":%PORT% " | findstr "LISTENING" >nul 2>&1 -if %errorlevel%==0 ( +if !errorlevel!==0 ( set /a PORT+=1 - if %PORT% gtr 18799 (echo No available port & pause & goto :menu) + if !PORT! gtr 18799 (echo No available port & pause & goto :menu) goto :find_port ) cd /d "%CORE_DIR%" if not exist "%STATE_DIR%\openclaw.json" ( echo {"gateway":{"mode":"local","auth":{"token":"uclaw"}}} > "%STATE_DIR%\openclaw.json" ) -start "" http://127.0.0.1:%PORT%/#token=uclaw -"%NODE_BIN%" "%OPENCLAW_MJS%" gateway run --allow-unconfigured --force --port %PORT% + +REM Read token from config +set "TOKEN=uclaw" +if exist "%STATE_DIR%\openclaw.json" ( + for /f "tokens=*" %%t in ('"%NODE_BIN%" -e "try{const c=JSON.parse(require('fs').readFileSync(process.argv[1],'utf8'));console.log((c.gateway&&c.gateway.auth&&c.gateway.auth.token)||'uclaw')}catch(e){console.log('uclaw')}" "%STATE_DIR%\openclaw.json"') do set "TOKEN=%%t" +) + +start /B "" cmd /c "timeout /t 3 /nobreak >nul && start http://127.0.0.1:!PORT!/#token=!TOKEN!" +"%NODE_BIN%" "%OPENCLAW_MJS%" gateway run --allow-unconfigured --force --port !PORT! pause goto :menu @@ -154,12 +165,41 @@ goto :menu echo. echo === Other Platforms === echo. -echo Feishu: Built-in. Use [1] Setup wizard. -echo Telegram: Built-in. Use [1] Setup wizard. -echo Discord: Built-in. Use [1] Setup wizard. -echo WeChat: Community plugin. +echo [a] Feishu (Lark) - Enterprise +echo [b] Telegram - International +echo [c] WeChat (plugin) - iPad protocol +echo [d] Discord +echo. +set /p ch_choice=" Choose (a-d, empty to cancel): " +if "%ch_choice%"=="a" ( + echo. + echo Feishu setup: + echo 1. Visit open.feishu.cn/app to create an app + echo 2. Get App ID and App Secret + echo 3. Run Setup wizard [1] to bind +) +if "%ch_choice%"=="b" ( + echo. + echo Telegram setup: + echo 1. Message @BotFather on Telegram + echo 2. Create a bot and get the token + echo 3. Run Setup wizard [1] to bind +) +if "%ch_choice%"=="c" ( + echo. + echo Installing WeChat plugin... + cd /d "%CORE_DIR%" + "%NODE_BIN%" "%OPENCLAW_MJS%" plugins install @icesword760/openclaw-wechat + echo WeChat plugin installed! +) +if "%ch_choice%"=="d" ( + echo. + echo Discord setup: + echo 1. Visit discord.com/developers/applications + echo 2. Create a bot and get the token + echo 3. Run Setup wizard [1] to bind +) echo. -echo Use Setup wizard [1] to configure these. pause goto :menu @@ -172,34 +212,93 @@ goto :menu :backup echo. set "TS=%date:~0,4%%date:~5,2%%date:~8,2%_%time:~0,2%%time:~3,2%" -set "TS=%TS: =0%" -set "BK=%DATA_DIR%\backups\backup_%TS%" -mkdir "%BK%" 2>nul -if exist "%STATE_DIR%\openclaw.json" copy "%STATE_DIR%\openclaw.json" "%BK%\" >nul -if exist "%DATA_DIR%\memory" xcopy /s /q "%DATA_DIR%\memory" "%BK%\memory\" >nul 2>nul -echo Backup saved: %BK% +set "TS=!TS: =0!" +set "BK=%BACKUP_DIR%\backup_!TS!" +mkdir "!BK!" 2>nul +set "BK_COUNT=0" +if exist "%STATE_DIR%\openclaw.json" ( + copy "%STATE_DIR%\openclaw.json" "!BK!\" >nul + echo + openclaw.json + set /a BK_COUNT+=1 +) +if exist "%DATA_DIR%\memory" ( + xcopy /s /q "%DATA_DIR%\memory" "!BK!\memory\" >nul 2>nul + echo + memory/ + set /a BK_COUNT+=1 +) +echo. +if !BK_COUNT!==0 ( + echo Nothing to backup. + rmdir "!BK!" 2>nul +) else ( + for /f "tokens=*" %%s in ('powershell -command "(Get-ChildItem '!BK!' -Recurse -ErrorAction SilentlyContinue | Measure-Object -Property Length -Sum).Sum / 1KB" 2^>nul') do echo Size: %%s KB + echo Backup saved: !BK! +) pause goto :menu :restore echo. -echo Available backups: -dir /b "%DATA_DIR%\backups\" 2>nul +echo === Restore Backup === echo. -set /p rname=" Backup folder name: " -if exist "%DATA_DIR%\backups\%rname%\openclaw.json" ( - copy "%DATA_DIR%\backups\%rname%\openclaw.json" "%STATE_DIR%\" >nul - echo Config restored! +echo Available backups: +echo. +set "BK_NUM=0" +for /d %%d in ("%BACKUP_DIR%\*") do ( + set /a BK_NUM+=1 + echo [!BK_NUM!] %%~nxd + set "BK_PATH_!BK_NUM!=%%d" ) +if !BK_NUM!==0 ( + echo No backups found. + pause + goto :menu +) +echo. +set /p rnum=" Choose backup number: " +if "!rnum!"=="" goto :menu +set "RESTORE_PATH=!BK_PATH_%rnum%!" +if "!RESTORE_PATH!"=="" ( + echo Invalid choice. + pause + goto :menu +) +if exist "!RESTORE_PATH!\openclaw.json" ( + copy "!RESTORE_PATH!\openclaw.json" "%STATE_DIR%\" >nul + echo + Config restored +) +if exist "!RESTORE_PATH!\memory" ( + xcopy /s /q "!RESTORE_PATH!\memory" "%DATA_DIR%\memory\" >nul 2>nul + echo + Memory restored +) +echo. +echo Restore complete! pause goto :menu :sysinfo echo. -echo OS: Windows -"%NODE_BIN%" --version -echo Path: %UCLAW_DIR% -echo Data: %DATA_DIR% +echo === System Info === +echo. +echo OS: Windows +for /f "tokens=2 delims==" %%v in ('wmic os get Version /format:list 2^>nul ^| findstr "="') do echo Ver: %%v +for /f "tokens=2 delims==" %%v in ('wmic os get OSArchitecture /format:list 2^>nul ^| findstr "="') do echo Arch: %%v +for /f "tokens=2 delims==" %%v in ('wmic computersystem get TotalPhysicalMemory /format:list 2^>nul ^| findstr "="') do ( + set "MEM=%%v" + set /a "MEM_GB=!MEM:~0,-9!" + echo Memory: !MEM_GB! GB +) +if exist "%NODE_BIN%" ( + for /f "tokens=*" %%v in ('"%NODE_BIN%" --version') do echo Node: %%v +) +echo Path: %UCLAW_DIR% +echo Data: %DATA_DIR% +for /f "tokens=*" %%s in ('powershell -command "(Get-ChildItem '%UCLAW_DIR%' -Recurse -ErrorAction SilentlyContinue | Measure-Object -Property Length -Sum).Sum / 1MB" 2^>nul') do echo Size: %%s MB +for /f "tokens=3" %%s in ('dir /-c "%UCLAW_DIR%." 2^>nul ^| findstr /c:"bytes free"') do echo Free: %%s bytes +echo. +if exist "%CORE_DIR%\node_modules\openclaw\package.json" ( + for /f "tokens=*" %%v in ('"%NODE_BIN%" -e "console.log(require('%CORE_DIR:\=/%/node_modules/openclaw/package.json').version)"') do echo OpenClaw: %%v +) pause goto :menu @@ -215,30 +314,55 @@ for /l %%p in (18789,1,18799) do ( echo Port %%p: process found set FOUND=1 for /f "tokens=5" %%a in ('netstat -ano ^| findstr ":%%p " ^| findstr "LISTENING"') do ( - echo Killing PID %%a... - taskkill /PID %%a /F >nul 2>&1 + echo PID: %%a ) ) ) -if "%FOUND%"=="0" echo No residual processes found. -if "%FOUND%"=="1" echo Processes killed. + +REM Also check for openclaw node processes +for /f "tokens=2" %%p in ('tasklist /fi "imagename eq node.exe" /fo csv /nh 2^>nul ^| findstr /i "node"') do ( + set "FOUND_NODE=1" +) + +if "!FOUND!"=="0" ( + echo No residual processes found on gateway ports. + pause + goto :menu +) + +echo. +set /p killconfirm=" Kill these processes? (y/N): " +if /i not "!killconfirm!"=="y" ( + echo Cancelled. + pause + goto :menu +) + +for /l %%p in (18789,1,18799) do ( + for /f "tokens=5" %%a in ('netstat -ano ^| findstr ":%%p " ^| findstr "LISTENING"') do ( + taskkill /PID %%a /F >nul 2>&1 + ) +) +echo Processes killed. pause goto :menu :viewlogs echo. -echo === View Logs === +echo === Log Management === echo. -set "LOG_FILE=%DATA_DIR%\logs\gateway.log" +set "LOG_FILE=%LOG_DIR%\gateway.log" if not exist "%LOG_FILE%" ( echo No log file found. Start the gateway first. pause goto :menu ) echo [a] View last 50 lines -echo [b] Open log file +echo [b] Open log in Notepad +echo [c] Export log to Desktop +echo [d] Clean logs older than 7 days echo. -set /p logchoice=" Choose (a-b): " +set /p logchoice=" Choose (a-d): " if "%logchoice%"=="a" ( echo. powershell -command "Get-Content '%LOG_FILE%' -Tail 50" @@ -246,6 +370,19 @@ if "%logchoice%"=="a" ( if "%logchoice%"=="b" ( start notepad "%LOG_FILE%" ) +if "%logchoice%"=="c" ( + set "TS=%date:~0,4%%date:~5,2%%date:~8,2%_%time:~0,2%%time:~3,2%" + set "TS=!TS: =0!" + set "EXPORT=%USERPROFILE%\Desktop\uclaw-logs-!TS!.txt" + copy "%LOG_FILE%" "!EXPORT!" >nul + echo Log exported: !EXPORT! +) +if "%logchoice%"=="d" ( + echo. + echo Cleaning logs older than 7 days... + powershell -command "Get-ChildItem '%LOG_DIR%' -Filter '*.log' | Where-Object { $_.LastWriteTime -lt (Get-Date).AddDays(-7) } | Remove-Item -Force" + echo Old logs cleaned. +) pause goto :menu @@ -255,6 +392,12 @@ echo === Factory Reset === echo. echo WARNING: This will delete all config and memory data! echo. +echo Actions: +echo 1. Auto-backup current config and memory +echo 2. Delete config (openclaw.json) +echo 3. Delete memory data +echo 4. Restore default config +echo. echo Type RESET to confirm: set /p resetconfirm=" > " if not "%resetconfirm%"=="RESET" ( @@ -265,12 +408,12 @@ if not "%resetconfirm%"=="RESET" ( echo. echo [1/4] Backing up... set "TS=%date:~0,4%%date:~5,2%%date:~8,2%_%time:~0,2%%time:~3,2%" -set "TS=%TS: =0%" -set "BK=%DATA_DIR%\backups\pre-reset_%TS%" -mkdir "%BK%" 2>nul -if exist "%STATE_DIR%\openclaw.json" copy "%STATE_DIR%\openclaw.json" "%BK%\" >nul 2>nul -if exist "%DATA_DIR%\memory" xcopy /s /q "%DATA_DIR%\memory" "%BK%\memory\" >nul 2>nul -echo Backup saved: %BK% +set "TS=!TS: =0!" +set "BK=%BACKUP_DIR%\pre-reset_!TS!" +mkdir "!BK!" 2>nul +if exist "%STATE_DIR%\openclaw.json" copy "%STATE_DIR%\openclaw.json" "!BK!\" >nul 2>nul +if exist "%DATA_DIR%\memory" xcopy /s /q "%DATA_DIR%\memory" "!BK!\memory\" >nul 2>nul +echo Backup saved: !BK! echo [2/4] Deleting config... del "%STATE_DIR%\openclaw.json" 2>nul del "%DATA_DIR%\config.json" 2>nul @@ -293,10 +436,12 @@ echo. echo === Uninstall U-Claw === echo. if exist "%USERPROFILE%\.uclaw" ( - echo Found installed data: %USERPROFILE%\.uclaw + echo Found installed version: %USERPROFILE%\.uclaw + for /f "tokens=*" %%s in ('powershell -command "(Get-ChildItem '%USERPROFILE%\.uclaw' -Recurse -ErrorAction SilentlyContinue | Measure-Object -Property Length -Sum).Sum / 1MB" 2^>nul') do echo Size: %%s MB + echo. echo Type UNINSTALL to delete: set /p unconfirm=" > " - if "%unconfirm%"=="UNINSTALL" ( + if "!unconfirm!"=="UNINSTALL" ( rmdir /s /q "%USERPROFILE%\.uclaw" 2>nul echo Uninstalled! ) else ( @@ -321,12 +466,48 @@ if not exist "%CORE_DIR%\node_modules\openclaw\package.json" ( pause goto :menu ) -echo Checking latest version... +echo Checking... for /f "tokens=*" %%v in ('"%NODE_BIN%" -e "console.log(require('%CORE_DIR:\=/%/node_modules/openclaw/package.json').version)"') do set CUR_VER=%%v -echo Current: %CUR_VER% +echo Current version: %CUR_VER% + +echo Fetching latest version... +for /f "tokens=*" %%v in ('"%NODE_BIN%" -e "const https=require('https');https.get('https://registry.npmmirror.com/openclaw/latest',r=>{let d='';r.on('data',c=>d+=c);r.on('end',()=>{try{console.log(JSON.parse(d).version)}catch(e){console.log('error')}})})" 2^>nul') do set LATEST_VER=%%v + +if "!LATEST_VER!"=="" ( + echo Could not fetch latest version (network issue?) + pause + goto :menu +) +if "!LATEST_VER!"=="error" ( + echo Could not fetch latest version (network issue?) + pause + goto :menu +) + +echo Latest version: !LATEST_VER! echo. -echo To update, run in the core directory: -echo npm install openclaw@latest --registry=https://registry.npmmirror.com + +if "!CUR_VER!"=="!LATEST_VER!" ( + echo Already up to date! + pause + goto :menu +) + +echo New version available! +set /p doupdate=" Update now? (y/N): " +if /i not "!doupdate!"=="y" ( + echo Cancelled. + pause + goto :menu +) + +echo. +echo Updating... +cd /d "%CORE_DIR%" +call "%NPM_BIN%" install openclaw@latest --registry=https://registry.npmmirror.com +for /f "tokens=*" %%v in ('"%NODE_BIN%" -e "console.log(require('./node_modules/openclaw/package.json').version)"') do set NEW_VER=%%v +echo. +echo Updated! %CUR_VER% - %NEW_VER% pause goto :menu @@ -334,12 +515,65 @@ goto :menu echo. echo === Disk Cleanup === echo. -echo Checking sizes... -for /f "tokens=*" %%s in ('powershell -command "(Get-ChildItem '%UCLAW_DIR%' -Recurse -ErrorAction SilentlyContinue | Measure-Object -Property Length -Sum).Sum / 1MB" 2^>nul') do echo Total: %%s MB +echo Directory sizes: +if exist "%CORE_DIR%\node_modules" ( + for /f "tokens=*" %%s in ('powershell -command "(Get-ChildItem '%CORE_DIR%\node_modules' -Recurse -ErrorAction SilentlyContinue | Measure-Object -Property Length -Sum).Sum / 1MB" 2^>nul') do echo node_modules: %%s MB +) +if exist "%DATA_DIR%\memory" ( + for /f "tokens=*" %%s in ('powershell -command "(Get-ChildItem '%DATA_DIR%\memory' -Recurse -ErrorAction SilentlyContinue | Measure-Object -Property Length -Sum).Sum / 1KB" 2^>nul') do echo memory: %%s KB +) +if exist "%BACKUP_DIR%" ( + for /f "tokens=*" %%s in ('powershell -command "(Get-ChildItem '%BACKUP_DIR%' -Recurse -ErrorAction SilentlyContinue | Measure-Object -Property Length -Sum).Sum / 1KB" 2^>nul') do echo backups: %%s KB +) +if exist "%LOG_DIR%" ( + for /f "tokens=*" %%s in ('powershell -command "(Get-ChildItem '%LOG_DIR%' -Recurse -ErrorAction SilentlyContinue | Measure-Object -Property Length -Sum).Sum / 1KB" 2^>nul') do echo logs: %%s KB +) +for /f "tokens=*" %%s in ('powershell -command "(Get-ChildItem '%UCLAW_DIR%' -Recurse -ErrorAction SilentlyContinue | Measure-Object -Property Length -Sum).Sum / 1MB" 2^>nul') do echo Total: %%s MB echo. -echo To clean up manually: -echo - Delete old backups in %DATA_DIR%\backups\ -echo - Delete logs in %DATA_DIR%\logs\ + +REM Clean old backups (keep latest 3) +set "BK_COUNT=0" +for /d %%d in ("%BACKUP_DIR%\*") do set /a BK_COUNT+=1 +if !BK_COUNT! gtr 3 ( + set /a OLD_COUNT=BK_COUNT-3 + echo Found !BK_COUNT! backups, keeping latest 3. + set /p delbk=" Delete !OLD_COUNT! old backups? (y/N): " + if /i "!delbk!"=="y" ( + set "DEL_NUM=0" + for /f "tokens=*" %%d in ('powershell -command "Get-ChildItem '%BACKUP_DIR%' -Directory | Sort-Object LastWriteTime | Select-Object -First !OLD_COUNT! | ForEach-Object { $_.FullName }"') do ( + rmdir /s /q "%%d" 2>nul + set /a DEL_NUM+=1 + ) + echo Cleaned !DEL_NUM! old backups. + ) +) else ( + echo Backups: !BK_COUNT! (no cleanup needed) +) + +REM Clean old logs (>7 days) +set "OLD_LOGS=0" +for /f "tokens=*" %%n in ('powershell -command "(Get-ChildItem '%LOG_DIR%' -Filter '*.log' -ErrorAction SilentlyContinue | Where-Object { $_.LastWriteTime -lt (Get-Date).AddDays(-7) }).Count" 2^>nul') do set OLD_LOGS=%%n +if !OLD_LOGS! gtr 0 ( + echo Found !OLD_LOGS! logs older than 7 days. + set /p dellog=" Delete old logs? (y/N): " + if /i "!dellog!"=="y" ( + powershell -command "Get-ChildItem '%LOG_DIR%' -Filter '*.log' | Where-Object { $_.LastWriteTime -lt (Get-Date).AddDays(-7) } | Remove-Item -Force" + echo Old logs cleaned. + ) +) else ( + echo Logs: no cleanup needed +) + +REM Clean npm cache +echo. +set /p delcache=" Clean npm cache? (y/N): " +if /i "!delcache!"=="y" ( + call "%NPM_BIN%" cache clean --force 2>nul + echo npm cache cleaned. +) + +echo. +for /f "tokens=*" %%s in ('powershell -command "(Get-ChildItem '%UCLAW_DIR%' -Recurse -ErrorAction SilentlyContinue | Measure-Object -Property Length -Sum).Sum / 1MB" 2^>nul') do echo Total after cleanup: %%s MB pause goto :menu @@ -353,20 +587,41 @@ echo [c] Remove a plugin echo. set /p plgchoice=" Choose (a-c): " cd /d "%CORE_DIR%" -if "%plgchoice%"=="a" "%NODE_BIN%" "%OPENCLAW_MJS%" plugins list +if "%plgchoice%"=="a" ( + echo. + "%NODE_BIN%" "%OPENCLAW_MJS%" plugins list +) if "%plgchoice%"=="b" ( echo. echo Common plugins: - echo @icesword760/openclaw-wechat + echo @icesword760/openclaw-wechat - WeChat + echo @nicepkg/openclaw-plugin-qq - QQ (community) echo. - set /p plgname=" Plugin name: " - if not "%plgname%"=="" "%NODE_BIN%" "%OPENCLAW_MJS%" plugins install "%plgname%" + set /p plgname=" Plugin name (empty to cancel): " + if not "!plgname!"=="" ( + echo. + echo Installing !plgname! ... + "%NODE_BIN%" "%OPENCLAW_MJS%" plugins install "!plgname!" + echo. + echo Done! + ) else ( + echo Cancelled. + ) ) if "%plgchoice%"=="c" ( + echo. "%NODE_BIN%" "%OPENCLAW_MJS%" plugins list echo. - set /p plgname=" Plugin to remove: " - if not "%plgname%"=="" "%NODE_BIN%" "%OPENCLAW_MJS%" plugins remove "%plgname%" + set /p plgname=" Plugin to remove (empty to cancel): " + if not "!plgname!"=="" ( + echo. + echo Removing !plgname! ... + "%NODE_BIN%" "%OPENCLAW_MJS%" plugins remove "!plgname!" + echo. + echo Done! + ) else ( + echo Cancelled. + ) ) pause -goto :menu \ No newline at end of file +goto :menu diff --git a/portable/Windows-Start.bat b/portable/Windows-Start.bat index 99ca9ed..ddaeee2 100644 --- a/portable/Windows-Start.bat +++ b/portable/Windows-Start.bat @@ -1,4 +1,5 @@ -@echo off +@echo off +setlocal EnableDelayedExpansion chcp 65001 >nul 2>&1 title U-Claw - Portable AI Agent @@ -39,11 +40,12 @@ echo. set "PATH=%NODE_DIR%;%NODE_DIR%\node_modules\.bin;%PATH%" -REM Init data +REM Init data directories if not exist "%DATA_DIR%" mkdir "%DATA_DIR%" if not exist "%STATE_DIR%" mkdir "%STATE_DIR%" if not exist "%DATA_DIR%\memory" mkdir "%DATA_DIR%\memory" if not exist "%DATA_DIR%\backups" mkdir "%DATA_DIR%\backups" +if not exist "%DATA_DIR%\logs" mkdir "%DATA_DIR%\logs" REM Default config if not exist "%STATE_DIR%\openclaw.json" ( @@ -53,6 +55,11 @@ if not exist "%STATE_DIR%\openclaw.json" ( echo. ) +REM Sync config from legacy location +if exist "%DATA_DIR%\config.json" if not exist "%STATE_DIR%\openclaw.json" ( + copy "%DATA_DIR%\config.json" "%STATE_DIR%\openclaw.json" >nul +) + REM Check dependencies if not exist "%CORE_DIR%\node_modules" ( echo First run - installing dependencies... @@ -65,16 +72,14 @@ if not exist "%CORE_DIR%\node_modules" ( echo. ) -REM OpenClaw doesn't need a separate build step when installed via npm - REM Find available port set PORT=18789 :check_port netstat -an | findstr ":%PORT% " | findstr "LISTENING" >nul 2>&1 -if %errorlevel%==0 ( +if !errorlevel!==0 ( echo Port %PORT% in use, trying next... set /a PORT+=1 - if %PORT% gtr 18799 ( + if !PORT! gtr 18799 ( echo No available port 18789-18799 pause exit /b 1 @@ -82,51 +87,40 @@ if %errorlevel%==0 ( goto :check_port ) -echo Starting OpenClaw on port %PORT%... -echo. +REM Read token from config +set "TOKEN=uclaw" +if exist "%STATE_DIR%\openclaw.json" ( + for /f "tokens=*" %%t in ('"%NODE_BIN%" -e "try{const c=JSON.parse(require('fs').readFileSync(process.argv[1],'utf8'));console.log((c.gateway&&c.gateway.auth&&c.gateway.auth.token)||'uclaw')}catch(e){console.log('uclaw')}" "%STATE_DIR%\openclaw.json"') do set "TOKEN=%%t" +) -REM Start Config Server in background -echo Starting Config Center on port 18788... -set "CONFIG_SERVER=%UCLAW_DIR%config-server" -start /B "" "%NODE_BIN%" "%CONFIG_SERVER%\server.js" >nul 2>&1 - -REM Wait for config server to start -timeout /t 2 /nobreak >nul - -REM Open both Config Center and Dashboard -echo Opening Config Center and Dashboard... -timeout /t 1 /nobreak >nul - -REM Open Config Center (Node.js web UI) -start "" http://127.0.0.1:18788/ - -REM Open OpenClaw Dashboard -start "" http://127.0.0.1:%PORT%/#token=uclaw - -echo Browsers opened. Starting OpenClaw Gateway on port %PORT%... +echo Starting OpenClaw on port !PORT!... echo DO NOT close this window while using U-Claw! echo. cd /d "%CORE_DIR%" - -REM Check if model is configured - open Config.html for first time, dashboard for returning users -set "HAS_MODEL=no" -if exist "%DATA_DIR%\config.json" ( - findstr /c:"agent" "%DATA_DIR%\config.json" >nul 2>&1 && set "HAS_MODEL=yes" -) - -if "%HAS_MODEL%"=="yes" ( - echo Opening dashboard... - start "" http://127.0.0.1:%PORT%/#token=uclaw -) else ( - echo First time - opening Config page... - start "" "%UCLAW_DIR%Config.html?port=%PORT%" -) - -if not exist "%DATA_DIR%\logs" mkdir "%DATA_DIR%\logs" set "OPENCLAW_MJS=%CORE_DIR%\node_modules\openclaw\openclaw.mjs" echo Log: %DATA_DIR%\logs\gateway.log -"%NODE_BIN%" "%OPENCLAW_MJS%" gateway run --allow-unconfigured --force --port %PORT% 2>&1 | powershell -command "& { $input | Tee-Object -Append -FilePath '%DATA_DIR%\logs\gateway.log' }" + +REM Check if model is configured +set "HAS_MODEL=no" +if exist "%STATE_DIR%\openclaw.json" ( + findstr /c:"model" "%STATE_DIR%\openclaw.json" >nul 2>&1 && set "HAS_MODEL=yes" +) +if "!HAS_MODEL!"=="no" if exist "%DATA_DIR%\config.json" ( + findstr /c:"model" "%DATA_DIR%\config.json" >nul 2>&1 && set "HAS_MODEL=yes" +) + +REM Open browser after a short delay (gateway needs ~2-3s to start) +if "!HAS_MODEL!"=="yes" ( + echo Opening dashboard in 3 seconds... + start /B "" cmd /c "timeout /t 3 /nobreak >nul && start http://127.0.0.1:!PORT!/#token=!TOKEN!" +) else ( + echo First time setup - opening Config page in 3 seconds... + start /B "" cmd /c "timeout /t 3 /nobreak >nul && start %UCLAW_DIR%Config.html?port=!PORT!" +) + +REM Start gateway (foreground, blocks until stopped) +"%NODE_BIN%" "%OPENCLAW_MJS%" gateway run --allow-unconfigured --force --port !PORT! 2>&1 | powershell -command "& { $input | Tee-Object -Append -FilePath '%DATA_DIR%\logs\gateway.log' }" echo. echo OpenClaw stopped.