Auto-detect free port and add one-click launcher

start.ps1/start.sh now fall back to the next free port instead of
crashing when the configured port is already taken (e.g. by another
local app), and auto-open the dashboard in the browser once it's up.
install.ps1 also creates a desktop shortcut (Launch-Dashboard.bat) so
the dashboard can be started without typing any commands.
This commit is contained in:
Claude 2026-07-05 21:05:14 +00:00
parent e05a065c4e
commit f22b44a000
4 changed files with 69 additions and 5 deletions

4
Launch-Dashboard.bat Normal file
View File

@ -0,0 +1,4 @@
@echo off
cd /d "%~dp0"
powershell -NoLogo -ExecutionPolicy Bypass -File "%~dp0start.ps1"
pause

View File

@ -75,10 +75,24 @@ if (-not (Test-Path .git)) {
}
}
$launcher = Join-Path $PSScriptRoot "Launch-Dashboard.bat"
$desktop = [Environment]::GetFolderPath("Desktop")
if ((Test-Path $launcher) -and (Test-Path $desktop)) {
$shortcutPath = Join-Path $desktop "Agentic OS Dashboard.lnk"
$shell = New-Object -ComObject WScript.Shell
$shortcut = $shell.CreateShortcut($shortcutPath)
$shortcut.TargetPath = $launcher
$shortcut.WorkingDirectory = $PSScriptRoot
$shortcut.Description = "Launch the Agentic OS dashboard"
$shortcut.Save()
Write-Host "Desktop shortcut created: $shortcutPath"
}
Write-Host ""
Write-Host "=== Installation complete! ==="
Write-Host ""
Write-Host "Next steps:"
Write-Host " 1. Edit data/settings.json with your API keys"
Write-Host " 2. Run .\start.ps1 to launch the dashboard"
Write-Host " 3. Open http://127.0.0.1:8080 in your browser"
Write-Host " 2. Double-click the 'Agentic OS Dashboard' shortcut on your Desktop"
Write-Host " (or run .\start.ps1 / .\Launch-Dashboard.bat manually)"
Write-Host " 3. Your browser will open automatically once the server is ready"

View File

@ -36,11 +36,36 @@ $pythonArgs = @($python.Args)
& $pythonCommand @pythonArgs -m pip install -r requirements.txt --quiet
$port = & $pythonCommand @pythonArgs -c "import json; f=open('data/settings.json'); d=json.load(f); print(d.get('dashboard',{}).get('port',8080)); f.close()" 2>$null
if (-not $port) { $port = "8080" }
$configuredPort = & $pythonCommand @pythonArgs -c "import json; f=open('data/settings.json'); d=json.load(f); print(d.get('dashboard',{}).get('port',8080)); f.close()" 2>$null
if (-not $configuredPort) { $configuredPort = "8080" }
$configuredPort = [int]$configuredPort
function Find-FreePort {
param([int]$StartPort, [int]$MaxAttempts = 20)
for ($p = $StartPort; $p -lt $StartPort + $MaxAttempts; $p++) {
$listener = $null
try {
$listener = [System.Net.Sockets.TcpListener]::new([System.Net.IPAddress]::Parse("127.0.0.1"), $p)
$listener.Start()
return $p
} catch {
continue
} finally {
if ($listener) { $listener.Stop() }
}
}
throw "No free port found between $StartPort and $($StartPort + $MaxAttempts - 1). Close some other application or free a port and retry."
}
$port = Find-FreePort -StartPort $configuredPort
if ($port -ne $configuredPort) {
Write-Warning "Port $configuredPort is already in use (another app, or a leftover Agentic OS process) - using $port instead."
}
Write-Host "Dashboard: http://127.0.0.1:$port"
Write-Host "Press Ctrl+C to stop"
Write-Host ""
Start-Job -ScriptBlock { Start-Sleep -Seconds 2; Start-Process "http://127.0.0.1:$using:port" } | Out-Null
& $pythonCommand @pythonArgs server.py --port $port

View File

@ -24,11 +24,32 @@ fi
$PYTHON -m pip install -r requirements.txt --quiet 2>/dev/null
# Get port from settings or default
PORT=$($PYTHON -c "import json; f=open('data/settings.json'); d=json.load(f); print(d.get('dashboard',{}).get('port',8080)); f.close()" 2>/dev/null || echo "8080")
CONFIGURED_PORT=$($PYTHON -c "import json; f=open('data/settings.json'); d=json.load(f); print(d.get('dashboard',{}).get('port',8080)); f.close()" 2>/dev/null || echo "8080")
# Find a free port starting at CONFIGURED_PORT (in case it's already taken by another app)
PORT="$CONFIGURED_PORT"
for _ in $(seq 1 20); do
if ! (exec 3<>"/dev/tcp/127.0.0.1/${PORT}") 2>/dev/null; then
break
fi
exec 3>&- 2>/dev/null || true
PORT=$((PORT + 1))
done
if [ "$PORT" != "$CONFIGURED_PORT" ]; then
echo "WARNING: Port ${CONFIGURED_PORT} is already in use - using ${PORT} instead."
fi
echo "Dashboard: http://127.0.0.1:${PORT}"
echo "Press Ctrl+C to stop"
echo ""
# Best-effort auto-open browser once the server is up
( sleep 2
if command -v xdg-open &>/dev/null; then xdg-open "http://127.0.0.1:${PORT}" &>/dev/null
elif command -v open &>/dev/null; then open "http://127.0.0.1:${PORT}" &>/dev/null
fi
) &
# Start server
$PYTHON server.py --port "${PORT}"