@echo off setlocal EnableExtensions title AutoFirmer - Windows setup REM ============================================================================ REM AutoFirmer instance setup for Windows. REM REM Standalone: drop this file anywhere and run it. It clones the repo into a REM subfolder next to itself, installs, builds, and points the instance at the REM master dashboard. Safe to re-run - it pulls and rebuilds instead of cloning. REM ============================================================================ set "REPO_URL=https://git.juicerroom.com/senofy/autofirmer-expanded.git" set "DEFAULT_MASTER=https://master.juicerroom.com" set "TARGET=%~dp0autofirmer" echo. echo ============================================ echo AutoFirmer - Windows setup echo ============================================ echo. REM ---------------------------------------------------------------- git check REM Git for Windows only lands on PATH if "Git from the command line" was chosen REM at install time, and an already-open cmd keeps its old PATH regardless. So: REM probe the usual homes, then offer to install, then probe again - a fresh REM install is never visible to `where` in this session. :git_probe where git >nul 2>&1 if not errorlevel 1 goto :git_done if exist "%ProgramFiles%\Git\cmd\git.exe" set "PATH=%ProgramFiles%\Git\cmd;%PATH%" if exist "%ProgramFiles(x86)%\Git\cmd\git.exe" set "PATH=%ProgramFiles(x86)%\Git\cmd;%PATH%" if exist "%LOCALAPPDATA%\Programs\Git\cmd\git.exe" set "PATH=%LOCALAPPDATA%\Programs\Git\cmd;%PATH%" where git >nul 2>&1 if not errorlevel 1 goto :git_found_offpath if "%GIT_TRIED%"=="1" goto :git_missing where winget >nul 2>&1 if errorlevel 1 goto :git_missing echo. echo [--] Git is not installed. set "DOIT=" set /p "DOIT= Install it now with winget? [Y/n] " if /i "%DOIT%"=="n" goto :git_missing set "GIT_TRIED=1" echo Installing Git ^(a UAC prompt may appear^)... winget install --id Git.Git -e --source winget --accept-source-agreements --accept-package-agreements --silent goto :git_probe :git_found_offpath echo [ok] git ^(found off PATH, added for this run^) goto :git_done :git_missing echo [X] Git not found on PATH, and not in any of: echo %ProgramFiles%\Git\cmd echo %LOCALAPPDATA%\Programs\Git\cmd echo. echo Install it from https://git-scm.com/download/win echo If you JUST installed it: close this window, open a new Command echo Prompt and run the script again - an open window keeps its old PATH. goto :fail :git_done echo [ok] git REM --------------------------------------------------------------- node check REM winget's LTS package is deliberate: better-sqlite3 publishes prebuilt REM binaries for LTS Node, so installing LTS sidesteps the node-gyp build. :node_probe where node >nul 2>&1 if not errorlevel 1 goto :node_found if exist "%ProgramFiles%\nodejs\node.exe" set "PATH=%ProgramFiles%\nodejs;%PATH%" if exist "%LOCALAPPDATA%\Programs\nodejs\node.exe" set "PATH=%LOCALAPPDATA%\Programs\nodejs;%PATH%" where node >nul 2>&1 if not errorlevel 1 goto :node_found if "%NODE_TRIED%"=="1" goto :node_missing where winget >nul 2>&1 if errorlevel 1 goto :node_missing echo. echo [--] Node.js is not installed. set "DOIT=" set /p "DOIT= Install Node 22 LTS now with winget? [Y/n] " if /i "%DOIT%"=="n" goto :node_missing set "NODE_TRIED=1" echo Installing Node LTS ^(a UAC prompt may appear^)... winget install --id OpenJS.NodeJS.LTS -e --source winget --accept-source-agreements --accept-package-agreements --silent goto :node_probe :node_missing echo [X] Node.js not found on PATH, and not in any of: echo %ProgramFiles%\nodejs echo %LOCALAPPDATA%\Programs\nodejs echo. echo Install Node 22 LTS from https://nodejs.org/ then re-run. echo If you JUST installed it, open a NEW Command Prompt first. goto :fail :node_found if exist "%ProgramFiles%\nodejs\node.exe" set "PATH=%ProgramFiles%\nodejs;%PATH%" if exist "%LOCALAPPDATA%\Programs\nodejs\node.exe" set "PATH=%LOCALAPPDATA%\Programs\nodejs;%PATH%" where node >nul 2>&1 if not errorlevel 1 goto :node_found echo [X] Node.js not found on PATH, and not in any of: echo %ProgramFiles%\nodejs echo %LOCALAPPDATA%\Programs\nodejs echo. echo Install Node 22 LTS from https://nodejs.org/ then re-run. echo If you JUST installed it, open a NEW Command Prompt first. goto :fail :node_found for /f "tokens=* usebackq" %%v in (`node -p "process.versions.node"`) do set "NODEVER=%%v" for /f "tokens=1 delims=." %%m in ("%NODEVER%") do set "NODEMAJOR=%%m" echo [ok] node v%NODEVER% REM better-sqlite3 ships prebuilt binaries only for released Node ABIs. On a REM newer major it falls back to node-gyp, which needs Visual Studio Build REM Tools - a long, confusing failure if it is not installed. if %NODEMAJOR% GEQ 23 goto :node_warn goto :node_ok :node_warn echo. echo [!] Node %NODEMAJOR% is newer than better-sqlite3's prebuilt binaries. echo Install may try to compile from source and fail without Visual echo Studio Build Tools. Node 22 LTS is the safe choice here. echo. set "GOON=" set /p "GOON= Continue anyway? [y/N] " if /i not "%GOON%"=="y" goto :fail :node_ok REM ------------------------------------------------------------------- python REM Only the clicker needs Python; the dashboard runs without it. REM REM Detection is deliberately "run it and see" rather than `where python`: REM Windows ships a stub python.exe in WindowsApps that only opens the Microsoft REM Store. `where` finds it, running it does nothing useful. Asking it to print REM its major version separates a real interpreter from the stub. The py REM launcher is preferred when present - it is not shadowed by the stub. :py_probe set "PYCMD=" for /f "tokens=*" %%v in ('py -3 -c "import sys;print(sys.version_info[0])" 2^>nul') do if "%%v"=="3" set "PYCMD=py -3" if not defined PYCMD for /f "tokens=*" %%v in ('python -c "import sys;print(sys.version_info[0])" 2^>nul') do if "%%v"=="3" set "PYCMD=python" if defined PYCMD goto :py_found REM Not on PATH. Same story as Git and Node: a Python installed just now - or REM installed without "Add to PATH" ticked - is invisible to this session, which REM inherited its PATH at start. Prepend the standard install homes and retry. REM The version is globbed rather than hardcoded so a 3.13 install still works. for /d %%D in ("%LOCALAPPDATA%\Programs\Python\Python3*") do if exist "%%~D\python.exe" set "PATH=%%~D;%%~D\Scripts;%PATH%" for /d %%D in ("%ProgramFiles%\Python3*") do if exist "%%~D\python.exe" set "PATH=%%~D;%%~D\Scripts;%PATH%" if exist "%LOCALAPPDATA%\Programs\Python\Launcher\py.exe" set "PATH=%LOCALAPPDATA%\Programs\Python\Launcher;%PATH%" if exist "%SystemRoot%\py.exe" set "PATH=%SystemRoot%;%PATH%" for /f "tokens=*" %%v in ('py -3 -c "import sys;print(sys.version_info[0])" 2^>nul') do if "%%v"=="3" set "PYCMD=py -3" if not defined PYCMD for /f "tokens=*" %%v in ('python -c "import sys;print(sys.version_info[0])" 2^>nul') do if "%%v"=="3" set "PYCMD=python" if defined PYCMD goto :py_found if "%PY_TRIED%"=="1" goto :py_skip where winget >nul 2>&1 if errorlevel 1 goto :py_skip echo. echo [--] Python is not installed ^(needed only for the clicker^). set "DOIT=" set /p "DOIT= Install Python 3.12 now with winget? [Y/n] " if /i "%DOIT%"=="n" goto :py_skip set "PY_TRIED=1" echo Installing Python ^(a UAC prompt may appear^)... winget install --id Python.Python.3.12 -e --source winget --accept-source-agreements --accept-package-agreements --silent goto :py_probe :py_skip echo [--] python not found on PATH, and not in any of: echo %LOCALAPPDATA%\Programs\Python\Python3* echo %ProgramFiles%\Python3* echo The dashboard will still work - python is only needed for the echo clicker ^(clicker\runner.py^). If you just installed it, close this echo window and re-run to pick up the new PATH. goto :py_end :py_found for /f "tokens=*" %%v in ('%PYCMD% -c "import sys;print(sys.version.split()[0])" 2^>nul') do set "PYVER=%%v" echo [ok] python %PYVER% ^(via "%PYCMD%"^) :py_end REM ------------------------------------------------------------------- prompts echo. set "MASTER_URL=" set /p "MASTER_URL= Master dashboard URL [%DEFAULT_MASTER%]: " if "%MASTER_URL%"=="" set "MASTER_URL=%DEFAULT_MASTER%" set "INSTANCE=" set /p "INSTANCE= Instance name [%COMPUTERNAME%]: " if "%INSTANCE%"=="" set "INSTANCE=%COMPUTERNAME%" echo. echo Installing to: %TARGET% echo. REM -------------------------------------------------------------- clone / pull REM The branch is named explicitly throughout. A bare `git clone` follows the REM remote's default branch, which is not necessarily master - and an existing REM checkout may be sitting on a stale branch from before that was corrected. if exist "%TARGET%\.git" goto :repo_update echo [1/6] Cloning %REPO_URL% ... git clone --branch master "%REPO_URL%" "%TARGET%" if errorlevel 1 goto :clone_failed goto :repo_ready :clone_failed echo [X] Clone failed. Check network access to git.juicerroom.com. goto :fail :repo_update echo [1/6] Existing checkout found - switching to master and pulling... pushd "%TARGET%" git fetch origin if errorlevel 1 goto :pull_failed git checkout master if errorlevel 1 goto :pull_failed git pull --ff-only origin master if errorlevel 1 goto :pull_failed popd goto :repo_ready :pull_failed popd echo [X] Could not update the checkout. If you have local changes, either echo commit them or delete this folder and re-run to clone fresh: echo %TARGET% goto :fail :repo_ready pushd "%TARGET%" REM ------------------------------------------------------------------- install echo. echo [2/6] Installing npm dependencies ^(this takes a few minutes^)... call npm install if errorlevel 1 ( echo. echo [X] npm install failed. echo If the error mentions node-gyp, MSBuild, or better_sqlite3.cpp, echo the native module could not find a prebuilt binary. Either switch echo to Node 22 LTS, or install "Desktop development with C++" from the echo Visual Studio Build Tools installer. popd goto :fail ) REM --------------------------------------------------------------------- build echo. echo [3/6] Building... call npm run build if errorlevel 1 ( echo [X] Build failed. popd goto :fail ) REM ------------------------------------------------------------------ settings echo. echo [4/6] Writing instance settings... node scripts\seed-settings.js "%MASTER_URL%" "%INSTANCE%" if errorlevel 1 ( echo [X] Could not write settings to autotrader.sqlite. popd goto :fail ) REM Record the interpreter resolved above. The Node helpers read this rather REM than repeating the Store-stub detection in a second language. if defined PYCMD echo %PYCMD%> scripts\.python-cmd REM ------------------------------------------------------ python deps (option) echo. if not defined PYCMD goto :deps_skip echo [5/6] Installing clicker Python dependencies... REM requirements.txt guards its pyobjc entries with sys_platform == "darwin", REM so on Windows this resolves to pyautogui and its wheels only. %PYCMD% -m pip install --upgrade --quiet --disable-pip-version-check pip %PYCMD% -m pip install --quiet --disable-pip-version-check -r clicker\requirements.txt if errorlevel 1 goto :deps_failed %PYCMD% -c "import pyautogui" 2>nul if errorlevel 1 goto :deps_failed echo pyautogui imports cleanly. goto :deps_done :deps_failed echo [!] Python dependency install failed - the dashboard still works, echo the clicker will not. Retry by hand with: echo %PYCMD% -m pip install -r clicker\requirements.txt goto :deps_done :deps_skip echo [5/6] Skipping Python dependencies ^(python not found^). :deps_done REM ------------------------------------------------------------- autostart REM Prompted, not automatic: turning a trading PC into something that rebuilds REM and restarts itself on every push to master should be a decision. echo. echo [6/6] Auto-start and auto-update echo Starts AutoFirmer and the clicker at logon, and checks master every echo 5 minutes - rebuilding and restarting when it moves. A failed build echo is never deployed. set "DOAUTO=" set /p "DOAUTO= Set this up now? [Y/n] " if /i "%DOAUTO%"=="n" goto :autostart_skipped REM -ExecutionPolicy Bypass applies to this invocation only; nothing machine-wide REM changes. No elevation is needed for a per-user scheduled task. powershell -NoProfile -ExecutionPolicy Bypass -File "%TARGET%\scripts\install-autostart.ps1" if errorlevel 1 ( echo [!] Auto-start setup failed. AutoFirmer still works - start it with echo start-autofirmer.bat, and re-run this script to try again. set "AUTOSTART=0" ) else ( set "AUTOSTART=1" ) goto :autostart_done :autostart_skipped echo Skipped. Run scripts\install-autostart.ps1 later to enable it. set "AUTOSTART=0" :autostart_done REM ---------------------------------------------------------------- start file > "%~dp0start-autofirmer.bat" ( echo @echo off echo title AutoFirmer - %INSTANCE% echo cd /d "%TARGET%" echo echo Dashboard starting on http://localhost:3000 echo call npm run start echo pause ) popd echo. echo ============================================ echo Done. echo ============================================ echo. echo Instance name : %INSTANCE% echo Reporting to : %MASTER_URL% echo Installed in : %TARGET% echo. echo Dashboard at : http://localhost:3000 echo. if "%AUTOSTART%"=="1" goto :summary_auto echo Start it with : start-autofirmer.bat echo Clicker : python clicker\runner.py goto :summary_manual :summary_auto echo Running now, and again at every logon ^(PM2^). echo Updates : master is checked every 5 min; see scripts\update.log echo Handy : pm2 list ^| pm2 logs autofirmer ^| pm2 logs clicker :summary_manual echo. echo Still manual: echo - Load the Chrome extension: chrome://extensions, enable Developer echo mode, "Load unpacked", select %TARGET%\extension echo ^(an update cannot reload it for you - the dashboard warns when echo the extension or runner is behind^) echo - Add your firm credentials on the dashboard's Settings page echo. pause exit /b 0 :fail echo. echo Setup did not complete. echo. pause exit /b 1