Improve portable USB pack and credentials-based tunnel launcher.

Expand pack-usb.bat to sync LAUNCH.bat, cloudflare assets, and data dirs while preserving operator state; align usb/LAUNCH.bat with credentials.json tunnel flow instead of a baked token.
This commit is contained in:
AetherForge
2026-05-31 02:32:24 -07:00
parent babe644c94
commit 2f528229f2
2 changed files with 156 additions and 87 deletions

View File

@@ -3,17 +3,15 @@ setlocal EnableExtensions EnableDelayedExpansion
title AetherForge — Pack USB
cd /d "%~dp0"
set "ROOT=%CD%"
set "USB=%ROOT%\USB"
set "USB=%ROOT%\usb"
echo.
echo ================================================================
echo AetherForge — Pack Portable USB
echo ================================================================
echo.
echo This script builds AetherForge.exe and assembles everything
echo needed to run the Control Deck from a USB drive.
echo.
echo Output folder: %USB%\
echo Assembles a self-contained copy in: %USB%\
echo Copy that entire folder to a USB drive — nothing else needed.
echo.
:: ----------------------------------------------------------------
@@ -32,11 +30,13 @@ if errorlevel 1 (
set "SKIP_FRONTEND=1"
)
if not exist "%USB%" mkdir "%USB%"
:: ----------------------------------------------------------------
:: 1. Build the frontend (if npm available)
:: 1. Build the frontend when npm is available
:: ----------------------------------------------------------------
if not defined SKIP_FRONTEND (
echo [1/4] Building frontend...
echo [1/7] Building frontend...
cd "%ROOT%\server\web"
call npm install --silent
call npm run build
@@ -47,15 +47,15 @@ if not defined SKIP_FRONTEND (
exit /b 1
)
cd "%ROOT%"
echo [1/4] Frontend built.
echo [1/7] Frontend built.
) else (
echo [1/4] Skipped (npm not found).
echo [1/7] Skipped - npm not found.
)
:: ----------------------------------------------------------------
:: 2. Build AetherForge.exe for the current machine (amd64 windows)
:: 2. Build AetherForge.exe for Windows amd64
:: ----------------------------------------------------------------
echo [2/4] Compiling AetherForge.exe...
echo [2/7] Compiling AetherForge.exe...
cd "%ROOT%\server"
set "CGO_ENABLED=0"
set "GOOS=windows"
@@ -68,64 +68,105 @@ if errorlevel 1 (
exit /b 1
)
cd "%ROOT%"
echo [2/4] AetherForge.exe -> USB\AetherForge.exe
echo [2/7] AetherForge.exe ready.
:: ----------------------------------------------------------------
:: 3. Copy webroot
:: 3. Copy webroot - dashboard UI
:: ----------------------------------------------------------------
echo [3/4] Copying webroot...
echo [3/7] Copying webroot...
if exist "%USB%\webroot" rd /s /q "%USB%\webroot"
if exist "%ROOT%\server\webroot" (
if exist "%USB%\webroot" rd /s /q "%USB%\webroot"
xcopy /e /i /q "%ROOT%\server\webroot" "%USB%\webroot" >nul
echo [3/4] webroot copied.
) else if exist "%ROOT%\server\web\dist" (
if exist "%USB%\webroot" rd /s /q "%USB%\webroot"
xcopy /e /i /q "%ROOT%\server\web\dist" "%USB%\webroot" >nul
echo [3/4] webroot copied from web\dist.
) else (
echo [3/4] WARNING: No webroot found. Run 'npm run build' in server\web\ first.
echo ERROR: No webroot found. Run npm run build in server\web first.
pause
exit /b 1
)
echo [3/7] webroot copied.
:: ----------------------------------------------------------------
:: 4. Copy source trees (needed for Forge to compile agents on the USB)
:: 4. Copy agent and fusion source - Forge needs these at runtime
:: ----------------------------------------------------------------
echo [4/4] Copying agent + fusion source...
echo [4/7] Copying agent + fusion source...
if exist "%USB%\agent" rd /s /q "%USB%\agent"
if exist "%USB%\fusion" rd /s /q "%USB%\fusion"
:: Copy agent source, excluding test results and build outputs
xcopy /e /i /q /EXCLUDE:"%ROOT%\usb_pack_exclude.txt" "%ROOT%\agent" "%USB%\agent" >nul
xcopy /e /i /q /EXCLUDE:"%ROOT%\usb_pack_exclude.txt" "%ROOT%\fusion" "%USB%\fusion" >nul
echo [4/4] Source trees copied.
echo [4/7] Source trees copied.
:: ----------------------------------------------------------------
:: 5. Ensure data directories exist on USB
:: 5. Launcher + docs (always sync from project root)
:: ----------------------------------------------------------------
if not exist "%USB%\data\builds" mkdir "%USB%\data\builds"
if not exist "%USB%\data\logs" mkdir "%USB%\data\logs"
if not exist "%USB%\data\blueprints" mkdir "%USB%\data\blueprints"
if not exist "%USB%\data\preps" mkdir "%USB%\data\preps"
echo [5/7] Syncing LAUNCH.bat, README, cloudflare...
copy /y "%ROOT%\LAUNCH.bat" "%USB%\LAUNCH.bat" >nul
if not exist "%USB%\README.txt" (
if exist "%ROOT%\usb\README.txt" copy /y "%ROOT%\usb\README.txt" "%USB%\README.txt" >nul
)
:: run.bat is a project-root marker used by some tooling
echo @echo off > "%USB%\run.bat"
echo rem AetherForge portable root marker >> "%USB%\run.bat"
if not exist "%USB%\cloudflare" mkdir "%USB%\cloudflare"
if exist "%ROOT%\usb\cloudflare\SETUP.txt" (
copy /y "%ROOT%\usb\cloudflare\SETUP.txt" "%USB%\cloudflare\SETUP.txt" >nul
)
if exist "%ROOT%\cloudflared-windows-amd64.msi" (
copy /y "%ROOT%\cloudflared-windows-amd64.msi" "%USB%\cloudflare\cloudflared-windows-amd64.msi" >nul
echo [5/7] cloudflared MSI bundled.
) else if exist "%ROOT%\usb\cloudflare\cloudflared-windows-amd64.msi" (
echo [5/7] cloudflared MSI already in usb\cloudflare\
) else (
echo [5/7] WARNING: No cloudflared MSI found. Tunnel auto-install skipped.
)
:: Preserve existing credentials.json if present (never overwrite operator tunnel)
if not exist "%USB%\cloudflare\credentials.json" (
if exist "%ROOT%\usb\cloudflare\credentials.json" (
copy /y "%ROOT%\usb\cloudflare\credentials.json" "%USB%\cloudflare\credentials.json" >nul
)
)
echo [5/7] Launcher synced.
:: ----------------------------------------------------------------
:: 6. Summary
:: 6. Remove stale nested server mirror (not needed for portable)
:: ----------------------------------------------------------------
echo [6/7] Cleaning stale artifacts...
if exist "%USB%\server" rd /s /q "%USB%\server"
echo [6/7] Done.
:: ----------------------------------------------------------------
:: 7. Ensure data directories exist - preserve existing config and db
:: ----------------------------------------------------------------
echo [7/7] Ensuring data directories...
if not exist "%USB%\data" mkdir "%USB%\data"
if not exist "%USB%\data\builds" mkdir "%USB%\data\builds"
if not exist "%USB%\data\logs" mkdir "%USB%\data\logs"
if not exist "%USB%\data\blueprints" mkdir "%USB%\data\blueprints"
if not exist "%USB%\data\preps" mkdir "%USB%\data\preps"
if not exist "%USB%\data\spread-kits" mkdir "%USB%\data\spread-kits"
if not exist "%USB%\data\uploads" mkdir "%USB%\data\uploads"
if not exist "%USB%\data\cloudflare" mkdir "%USB%\data\cloudflare"
echo [7/7] data\ ready - existing config and db preserved.
:: ----------------------------------------------------------------
:: Summary
:: ----------------------------------------------------------------
echo.
echo ================================================================
echo USB pack complete!
echo.
echo Contents of %USB%\:
echo Folder: %USB%\
echo.
dir /b "%USB%"
echo.
echo To use:
echo 1. Copy the entire USB\ folder to a USB drive (or another PC)
echo 2. Double-click LAUNCH.bat
echo 3. Open http://localhost:8989 in a browser
echo 1. Copy the entire usb\ folder to your USB drive
echo 2. Double-click LAUNCH.bat on any Windows PC
echo 3. Open http://localhost:8989
echo.
echo Toolchain note:
echo If Go is not installed on the target PC, LAUNCH.bat will
echo download it automatically on first run and save it to
echo USB\toolchain\ for future use.
echo Your data\ and toolchain\ folders are preserved across repacks.
echo First launch without Go: LAUNCH.bat downloads toolchain\go\ once.
echo ================================================================
echo.

View File

@@ -123,81 +123,108 @@ if not exist "%ROOT%\data\spread-kits" mkdir "%ROOT%\data\spread-kits"
if not exist "%ROOT%\data\uploads" mkdir "%ROOT%\data\uploads"
if not exist "%ROOT%\data\blueprints" mkdir "%ROOT%\data\blueprints"
if not exist "%ROOT%\data\preps" mkdir "%ROOT%\data\preps"
if not exist "%ROOT%\data\cloudflare" mkdir "%ROOT%\data\cloudflare"
:: ----------------------------------------------------------------
:: 5. Cloudflare Tunnel — install MSI, register service with token
:: 5. Cloudflare Tunnel — auto-install, configure, start
:: ----------------------------------------------------------------
set "CF_MSI=%ROOT%\cloudflare\cloudflared-windows-amd64.msi"
set "CF_TOKEN=eyJhIjoiODk1NDc5YWIzNTQwZGFhNmQ2MWFlNzAyYTUxNjQ0NzUiLCJ0IjoiYWFhYzYzMTctMzgyYS00OTM3LTgxY2YtYjM2ZjVkNjZjYTU4IiwicyI6Ik1XRXlaV0FqTlRndE5XTTRPUzAwT0RCa0xXRTNaR010WkdRNU56UTJZMlJoTmpNMiJ9"
set "CF_DIR=%ROOT%\cloudflare"
set "CF_CREDS_BUNDLE=%CF_DIR%\credentials.json"
set "CF_MSI=%CF_DIR%\cloudflared-windows-amd64.msi"
set "CF_HOSTNAME=killa.thetempleofdoom.com"
set "CF_DATA=%ROOT%\data\cloudflare"
set "SERVER_PORT=8989"
set "CF_BIN="
set "CF_TUNNEL_ID="
set "CF_READY=0"
:: Step A — locate cloudflared binary (system PATH or default install paths)
:: Check credentials exist and are real (not the placeholder)
if not exist "%CF_CREDS_BUNDLE%" goto cf_no_creds
powershell -NoProfile -Command "exit ([string](Get-Content '%CF_CREDS_BUNDLE%') | ConvertFrom-Json | Select-Object -ExpandProperty TunnelID) -eq ''" >nul 2>nul
if errorlevel 1 goto cf_no_creds
:: Parse tunnel ID from credentials JSON
for /f "usebackq delims=" %%i in (`powershell -NoProfile -Command "(Get-Content '%CF_CREDS_BUNDLE%' | ConvertFrom-Json).TunnelID" 2^>nul`) do set "CF_TUNNEL_ID=%%i"
if "!CF_TUNNEL_ID!"=="" goto cf_no_creds
echo [CF] Tunnel ID: !CF_TUNNEL_ID!
:: Stage credentials into data\cloudflare\ (idempotent)
set "CF_CREDS_LOCAL=%CF_DATA%\!CF_TUNNEL_ID!.json"
if not exist "!CF_CREDS_LOCAL!" (
copy "%CF_CREDS_BUNDLE%" "!CF_CREDS_LOCAL!" >nul
echo [CF] Credentials staged to data\cloudflare\
)
:: Always regenerate config.yml with current absolute paths
:: (handles drive-letter changes when USB is moved)
set "CF_CONFIG=%CF_DATA%\config.yml"
powershell -NoProfile -Command "$cfg='%CF_DATA%\config.yml'; $creds='!CF_CREDS_LOCAL!'; $port='%SERVER_PORT%'; $host='%CF_HOSTNAME%'; $id='!CF_TUNNEL_ID!'; Set-Content -Path $cfg -Value @('tunnel: ' + $id, 'credentials-file: ' + $creds, '', 'ingress:', ' - hostname: ' + $host, ' service: http://127.0.0.1:' + $port, ' - service: http_status:404')" >nul 2>nul
echo [CF] Config written for !CF_HOSTNAME! -^> 127.0.0.1:%SERVER_PORT%
:: ---- Locate or install cloudflared ----
where cloudflared >nul 2>nul
if not errorlevel 1 (
set "CF_BIN=cloudflared"
goto cf_check_service
goto cf_have_bin
)
if exist "%ProgramFiles%\cloudflare\cloudflared\cloudflared.exe" (
set "CF_BIN=%ProgramFiles%\cloudflare\cloudflared\cloudflared.exe"
goto cf_check_service
goto cf_have_bin
)
if exist "%ProgramFiles(x86)%\cloudflare\cloudflared\cloudflared.exe" (
set "CF_BIN=%ProgramFiles(x86)%\cloudflare\cloudflared\cloudflared.exe"
goto cf_check_service
goto cf_have_bin
)
:: Step B — cloudflared not found, install from bundled MSI
if not exist "%CF_MSI%" (
echo [CF] WARNING: cloudflared not found and no MSI bundled. Skipping tunnel.
:: Not found install from bundled MSI
if exist "%CF_MSI%" (
echo [CF] cloudflared not found. Installing from bundled MSI...
msiexec /i "%CF_MSI%" /quiet /norestart /l*v "%CF_DATA%\cf-install.log"
echo [CF] MSI install launched - waiting...
ping -n 8 127.0.0.1 >nul
if exist "%ProgramFiles%\cloudflare\cloudflared\cloudflared.exe" (
set "CF_BIN=%ProgramFiles%\cloudflare\cloudflared\cloudflared.exe"
echo [CF] cloudflared installed successfully.
goto cf_have_bin
)
where cloudflared >nul 2>nul
if not errorlevel 1 (
set "CF_BIN=cloudflared"
echo [CF] cloudflared installed successfully.
goto cf_have_bin
)
echo [CF] WARNING: MSI completed but cloudflared not found in PATH.
echo [CF] Try re-running LAUNCH.bat after a reboot.
goto cf_done
) else (
echo [CF] WARNING: cloudflared not installed and no MSI bundled.
goto cf_done
)
echo [CF] Installing cloudflared from bundled MSI...
msiexec /i "%CF_MSI%" /quiet /norestart
echo [CF] Waiting for MSI to complete...
ping -n 10 127.0.0.1 >nul
:: Re-locate after install
where cloudflared >nul 2>nul
if not errorlevel 1 ( set "CF_BIN=cloudflared" & goto cf_check_service )
if exist "%ProgramFiles%\cloudflare\cloudflared\cloudflared.exe" (
set "CF_BIN=%ProgramFiles%\cloudflare\cloudflared\cloudflared.exe"
goto cf_check_service
)
echo [CF] WARNING: MSI installed but cloudflared still not found. Try running as Administrator.
goto cf_done
:cf_check_service
:cf_have_bin
echo [CF] Binary: !CF_BIN!
:: Step C — register tunnel as Windows service if not already installed
sc query cloudflared >nul 2>nul
:: Check if cloudflared tunnel already running (same process = skip)
tasklist 2>nul | findstr /I "cloudflared" >nul 2>nul
if not errorlevel 1 (
echo [CF] Tunnel service already registered.
goto cf_start_service
)
echo [CF] Registering tunnel service with token...
"!CF_BIN!" service install %CF_TOKEN%
if errorlevel 1 (
echo [CF] WARNING: service install failed. Run LAUNCH.bat as Administrator once.
goto cf_done
)
echo [CF] Tunnel service registered.
ping -n 3 127.0.0.1 >nul
:cf_start_service
:: Step D — start the service if not already running
sc query cloudflared | findstr /I "RUNNING" >nul 2>nul
if not errorlevel 1 (
echo [CF] Tunnel already running.
echo [CF] Tunnel already running on this machine.
echo [CF] https://!CF_HOSTNAME!
set "CF_READY=1"
goto cf_done
)
net start cloudflared >nul 2>nul
ping -n 4 127.0.0.1 >nul
echo [CF] Tunnel live: https://%CF_HOSTNAME%
:: Start cloudflared tunnel in background
echo [CF] Starting Cloudflare tunnel...
start "" /B "!CF_BIN!" tunnel --config "!CF_CONFIG!" run
ping -n 5 127.0.0.1 >nul
echo [CF] Tunnel live: https://!CF_HOSTNAME!
set "CF_READY=1"
goto cf_done
:cf_no_creds
echo [CF] No valid credentials.json in cloudflare\
echo [CF] See cloudflare\SETUP.txt to configure your tunnel once.
echo [CF] Running in LAN-only mode this session.
:cf_done
@@ -244,7 +271,8 @@ if "!EC!"=="0" (
echo If port %SERVER_PORT% is in use, close other AetherForge windows and retry.
)
:: Cloudflare tunnel runs as a Windows service — leave it up between sessions
:: On exit, also stop the cloudflared tunnel
taskkill /F /IM cloudflared.exe >nul 2>nul
echo.
pause