Files
2209cdc90f chore(deps): switch runtime packages to octop-* 1.0.0 (#1136)
Replace orcakit-harness-agent / harness-* with octop-harness, octop-gateway, octop-memory, and octop-browser, and align docs, UI copy, and generated paths.

Co-authored-by: jubaoliang <jubaoliang@tencent.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-25 06:44:24 +08:00

258 lines
9.9 KiB
Batchfile

@echo off
setlocal EnableDelayedExpansion
REM Octop Installer for Windows (cmd.exe)
REM Usage: install.bat [-Version X.Y.Z] [-FromSource] [-SourceDir DIR] [-Extras browser] [-Help]
if defined OCTOP_HOME (set "OCTOP_HOME=%OCTOP_HOME%") else (set "OCTOP_HOME=%USERPROFILE%\.octop")
set "OCTOP_VENV=%OCTOP_HOME%\venv"
set "OCTOP_BIN=%OCTOP_HOME%\bin"
set "PYTHON_VERSION=3.12"
if defined OCTOP_REPO (set "OCTOP_REPO=%OCTOP_REPO%") else (set "OCTOP_REPO=https://github.com/TencentCloud/Octop.git")
set "ARG_VERSION="
set "ARG_FROM_SOURCE=0"
set "ARG_SOURCE_DIR="
set "ARG_EXTRAS="
set "ARG_UV_PATH="
set "CONSOLE_AVAILABLE=0"
:parse_args
if "%~1"=="" goto :done_args
if /i "%~1"=="-Version" (set "ARG_VERSION=%~2" & shift & shift & goto :parse_args)
if /i "%~1"=="-FromSource" (set "ARG_FROM_SOURCE=1" & shift & goto :parse_args)
if /i "%~1"=="-SourceDir" (set "ARG_SOURCE_DIR=%~2" & shift & shift & goto :parse_args)
if /i "%~1"=="-Extras" (set "ARG_EXTRAS=%~2" & shift & shift & goto :parse_args)
if /i "%~1"=="-UvPath" (set "ARG_UV_PATH=%~2" & shift & shift & goto :parse_args)
if /i "%~1"=="-Help" goto :show_help
shift
goto :parse_args
:show_help
echo Octop Installer for Windows
echo.
echo Usage: install.bat [OPTIONS]
echo -Version ^<VER^> Install specific version
echo -FromSource Install from source
echo -SourceDir ^<DIR^> Local source directory
echo -Extras ^<EXTRAS^> Extra components (e.g. desktop, browser)
echo -UvPath ^<PATH^> Pre-installed uv.exe
echo.
echo Note: Playwright Chromium is not downloaded by default. Pass -Extras browser
echo to install it, or install later from the dashboard.
exit /b 0
:done_args
echo [octop] Installing Octop into %OCTOP_HOME%
call :ensure_uv
if errorlevel 1 exit /b 1
if exist "%OCTOP_VENV%" (
echo [octop] Existing environment found, upgrading...
) else (
echo [octop] Creating Python %PYTHON_VERSION% environment...
)
uv venv "%OCTOP_VENV%" --python %PYTHON_VERSION% --quiet --clear
if errorlevel 1 (echo [octop] ERROR: Failed to create venv & exit /b 1)
set "VENV_PYTHON=%OCTOP_VENV%\Scripts\python.exe"
if not exist "%VENV_PYTHON%" (echo [octop] ERROR: venv python missing & exit /b 1)
for /f "delims=" %%v in ('"%VENV_PYTHON%" --version 2^>^&1') do set "PY_VERSION=%%v"
echo [octop] Python environment ready (%PY_VERSION%)
set "EXTRAS_SUFFIX=[browser]"
if defined ARG_EXTRAS set "EXTRAS_SUFFIX=[browser,%ARG_EXTRAS%]"
set "VENV_OCTOP=%OCTOP_VENV%\Scripts\octop.exe"
if "%ARG_FROM_SOURCE%"=="1" goto :install_from_source
goto :install_from_pypi
:install_from_source
if defined ARG_SOURCE_DIR goto :install_from_local
goto :install_from_git
:install_from_local
for %%I in ("%ARG_SOURCE_DIR%") do set "ARG_SOURCE_DIR=%%~fI"
echo [octop] Installing from local source: %ARG_SOURCE_DIR%
call :prepare_console "%ARG_SOURCE_DIR%"
uv pip install "%ARG_SOURCE_DIR%%EXTRAS_SUFFIX%" --python "%VENV_PYTHON%"
if errorlevel 1 (echo [octop] ERROR: install failed & exit /b 1)
goto :install_verify
:install_from_git
where git >nul 2>&1
if errorlevel 1 (echo [octop] ERROR: git required & exit /b 1)
set "CLONE_DIR=%TEMP%\octop-install-%RANDOM%"
git clone --depth 1 %OCTOP_REPO% "%CLONE_DIR%"
if errorlevel 1 exit /b 1
call :prepare_console "%CLONE_DIR%"
uv pip install "%CLONE_DIR%%EXTRAS_SUFFIX%" --python "%VENV_PYTHON%"
set "_E=%errorlevel%"
if exist "%CLONE_DIR%" rd /s /q "%CLONE_DIR%"
if %_E% neq 0 exit /b 1
goto :install_verify
:install_from_pypi
REM PEP 508: extras must sit between name and version specifier
REM (octop[browser]==x.y.z); octop==x.y.z[browser] is an invalid requirement.
set "_PACKAGE=octop%EXTRAS_SUFFIX%"
if defined ARG_VERSION set "_PACKAGE=octop%EXTRAS_SUFFIX%==%ARG_VERSION%"
echo [octop] Installing %_PACKAGE% from PyPI...
uv pip install "%_PACKAGE%" --python "%VENV_PYTHON%"
if errorlevel 1 (echo [octop] ERROR: install failed & exit /b 1)
:install_verify
call :verify_install
if errorlevel 1 exit /b 1
if not exist "%VENV_OCTOP%" (echo [octop] ERROR: octop CLI not found & exit /b 1)
echo [octop] Octop installed successfully
if "%CONSOLE_AVAILABLE%"=="0" (
"%VENV_PYTHON%" -c "import importlib.resources, octop; p=importlib.resources.files('octop')/'dashboard'/'index.html'; print('yes' if p.is_file() else 'no')" > "%TEMP%\_octop_ui.tmp" 2>&1
set /p _UI=<"%TEMP%\_octop_ui.tmp"
del "%TEMP%\_octop_ui.tmp" >nul 2>&1
if "!_UI!"=="yes" set "CONSOLE_AVAILABLE=1"
)
echo ",%ARG_EXTRAS%," | findstr /i /c:",browser," >nul
if errorlevel 1 (
echo [octop] Skipping Playwright Chromium download.
echo [octop] For remote-browser automation, re-run with -Extras browser, use the dashboard, or:
echo [octop] "%VENV_PYTHON%" -m playwright install chromium
goto :after_browser
)
call :detect_chrome
if defined OCTOP_SYSTEM_CHROME (
echo [octop] Found system Chrome/Chromium: %OCTOP_SYSTEM_CHROME%
echo [octop] Using system browser; skipping Playwright Chromium download.
echo [octop] To use bundled Chromium instead, run: "%VENV_PYTHON%" -m playwright install chromium
goto :after_browser
)
echo [octop] Installing Playwright Chromium browser...
"%VENV_PYTHON%" -m playwright install chromium
if errorlevel 1 (
echo [octop] WARNING: Playwright install failed. Run later: "%VENV_PYTHON%" -m playwright install chromium
)
:after_browser
if not exist "%OCTOP_BIN%" mkdir "%OCTOP_BIN%"
echo @echo off > "%OCTOP_BIN%\octop.cmd"
echo set "OCTOP_HOME=%%OCTOP_HOME%%" >> "%OCTOP_BIN%\octop.cmd"
echo if "%%OCTOP_HOME%%"=="" set "OCTOP_HOME=%%USERPROFILE%%\.octop" >> "%OCTOP_BIN%\octop.cmd"
echo "%%OCTOP_HOME%%\venv\Scripts\octop.exe" %%* >> "%OCTOP_BIN%\octop.cmd"
set "OCTOP_BIN_FOR_PS=%OCTOP_BIN%"
powershell -NoProfile -ExecutionPolicy Bypass -Command "$bin=$env:OCTOP_BIN_FOR_PS; $cur=[Environment]::GetEnvironmentVariable('Path','User'); if(-not $cur){$cur=''}; $parts=$cur.Split(';')|?{$_}; $ok=$false; foreach($p in $parts){if($p.TrimEnd('\') -ieq $bin.TrimEnd('\')){$ok=$true}}; if(-not $ok){$new=if($cur){$cur.TrimEnd(';')+';'+$bin}else{$bin}; [Environment]::SetEnvironmentVariable('Path',$new,'User'); Write-Host '[octop] Added to User PATH'} else {Write-Host '[octop] Already in User PATH'}"
set "OCTOP_BIN_FOR_PS="
echo %PATH% | findstr /i /c:"%OCTOP_BIN%" >nul || set "PATH=%OCTOP_BIN%;%PATH%"
echo.
echo Octop installed successfully!
echo Location: %OCTOP_HOME%
echo Python: %PY_VERSION%
echo.
echo If 'octop' is not found in this session, run:
echo set PATH=%OCTOP_BIN%;%%PATH%%
echo Or open a new terminal ^(saved to User PATH^).
echo.
echo Then run:
echo octop init
echo octop run
echo octop service start
echo http://127.0.0.1:8088
exit /b 0
::detect_chrome
set "OCTOP_SYSTEM_CHROME="
REM Prefer octop-browser's own detector (same path used at runtime)
"%VENV_PYTHON%" -c "from octop_browser.cdp.launcher import find_chrome; p=find_chrome(); print(p or '', end='')" > "%TEMP%\_octop_chrome.tmp" 2>nul
if not errorlevel 1 (
set /p _CHROME=<"%TEMP%\_octop_chrome.tmp"
)
del "%TEMP%\_octop_chrome.tmp" >nul 2>&1
if defined _CHROME (
set "OCTOP_SYSTEM_CHROME=%_CHROME%"
goto :detect_chrome_done
)
REM Fallback: common commands on PATH
for %%c in (chrome google-chrome google-chrome-stable chromium chromium-browser) do (
where %%c >nul 2>&1
if not errorlevel 1 (
for /f "delims=" %%p in ('where %%c') do (set "OCTOP_SYSTEM_CHROME=%%p" & goto :detect_chrome_done)
)
)
REM Fallback: well-known GUI install paths
for %%p in (
"%ProgramFiles%\Google\Chrome\Application\chrome.exe"
"%ProgramFiles(x86)%\Google\Chrome\Application\chrome.exe"
"%LOCALAPPDATA%\Google\Chrome\Application\chrome.exe"
"%ProgramFiles%\Chromium\Application\chrome.exe"
) do (
if exist %%p (set "OCTOP_SYSTEM_CHROME=%%~p" & goto :detect_chrome_done)
)
:detect_chrome_done
exit /b 0
:ensure_uv
if defined ARG_UV_PATH (
if not exist "%ARG_UV_PATH%" (echo [octop] ERROR: uv not found & exit /b 1)
for %%I in ("%ARG_UV_PATH%") do set "PATH=%%~dpI;!PATH!"
goto :ensure_uv_done
)
where uv >nul 2>&1
if not errorlevel 1 goto :ensure_uv_done
for %%c in ("%USERPROFILE%\.local\bin\uv.exe" "%LOCALAPPDATA%\uv\uv.exe") do (
if exist %%c (set "PATH=%%~dpc;!PATH!" & goto :ensure_uv_done)
)
echo [octop] Installing uv...
powershell -NoProfile -ExecutionPolicy Bypass -Command "irm https://astral.sh/uv/install.ps1 -TimeoutSec 15 | iex" 2>nul
if not errorlevel 1 goto :ensure_uv_refresh
echo [octop] astral.sh failed, trying GitHub...
call :download_uv_github
if errorlevel 1 exit /b 1
goto :ensure_uv_done
:ensure_uv_refresh
for %%p in ("%USERPROFILE%\.local\bin" "%LOCALAPPDATA%\uv") do (
if exist %%p echo "!PATH!" | findstr /i /c:"%%~p" >nul || set "PATH=%%~p;!PATH!"
)
where uv >nul 2>&1 || (echo [octop] ERROR: uv install failed & exit /b 1)
:ensure_uv_done
exit /b 0
:download_uv_github
if /i "%PROCESSOR_ARCHITECTURE%"=="ARM64" (set "_A=aarch64") else (set "_A=x86_64")
set "_Z=%TEMP%\uv-%RANDOM%.zip"
set "_D=%LOCALAPPDATA%\uv"
curl -L -o "!_Z!" "https://github.com/astral-sh/uv/releases/latest/download/uv-!_A!-pc-windows-msvc.zip" 2>nul
if errorlevel 1 powershell -NoProfile -Command "Invoke-WebRequest -Uri 'https://github.com/astral-sh/uv/releases/latest/download/uv-!_A!-pc-windows-msvc.zip' -OutFile '!_Z!' -UseBasicParsing"
if not exist "!_D!" mkdir "!_D!"
powershell -NoProfile -Command "Expand-Archive -Force '!_Z!' '!_D!'"
del "!_Z!" >nul 2>&1
set "PATH=!_D!;!PATH!"
exit /b 0
:prepare_console
set "_RD=%~1"
set "_DEST=%_RD%\src\octop\dashboard"
if exist "%_DEST%\index.html" (set "CONSOLE_AVAILABLE=1" & exit /b 0)
if not exist "%_RD%\dashboard\package.json" exit /b 0
where npm >nul 2>&1 || exit /b 0
echo [octop] Building dashboard...
pushd "%_RD%\dashboard"
npm ci && npm run build
popd
if exist "%_DEST%\index.html" set "CONSOLE_AVAILABLE=1"
exit /b 0
:verify_install
echo [octop] Verifying installation...
"%VENV_PYTHON%" -c "from octop.infra.agents.manager import AgentManager" >nul 2>&1
if errorlevel 1 (echo [octop] ERROR: install verification failed & exit /b 1)
echo [octop] Install verification passed
exit /b 0