Files
Brandon LiandClaude Opus 5 97ee03d13b Drop the unused playwright dependency
playwright was declared but referenced nowhere in the source — no import, no
require, no script. Its postinstall downloads several hundred MB of browsers
on every install, which setup-windows.bat had been working around with
PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD. Removing the dependency removes the need for
the workaround, so that goes too.

Nothing else depends on it; the remaining lockfile mentions are Next declaring
@playwright/test as an optional peer, which installs nothing.

Instances pick this up through the normal update path: package-lock.json
changed, so update-check runs npm install and playwright disappears from
node_modules. Any browsers already downloaded on a machine live outside
node_modules and are not removed by this — see README.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-30 18:15:18 -05:00

379 lines
14 KiB
Batchfile

@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