Full-stack real-time group chat with Rust/Axum backend and Riot.js frontend. Features: - Auth (register/login/JWT), rooms, invites, WebSocket messaging - AI responses via OpenRouter with tool calling (Brave Search + web fetch) - Real-time tool usage indicators (searching/reading page) - Collapsible tool results in message bubbles - AI stats bar (model, tokens, speed, response time) persisted to DB - Room soft-delete, /clear command, dynamic model fetching - Markdown rendering with code highlighting and copy buttons Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
96 lines
3.2 KiB
PowerShell
96 lines
3.2 KiB
PowerShell
# GroupChat2 Dev Script
|
|
# Runs both server (Rust/Axum) and client (Vite) with unified console output.
|
|
# Ctrl+C stops both processes.
|
|
|
|
$root = $PSScriptRoot
|
|
|
|
# Install client deps if needed
|
|
if (-not (Test-Path "$root\client\node_modules")) {
|
|
Write-Host "[dev] Installing client dependencies..." -ForegroundColor Cyan
|
|
Push-Location "$root\client"
|
|
& cmd /c "npm install"
|
|
Pop-Location
|
|
}
|
|
|
|
Write-Host ""
|
|
Write-Host " GroupChat2 Dev Server" -ForegroundColor Magenta
|
|
Write-Host " Server: http://localhost:3001" -ForegroundColor Yellow
|
|
Write-Host " Client: http://localhost:3000" -ForegroundColor Cyan
|
|
Write-Host " Press Ctrl+C to stop both" -ForegroundColor DarkGray
|
|
Write-Host ""
|
|
|
|
# Use PowerShell jobs — they handle .cmd files (npm) properly
|
|
$serverJob = Start-Job -ScriptBlock {
|
|
param($dir)
|
|
Set-Location $dir
|
|
& cargo run 2>&1
|
|
} -ArgumentList "$root\server"
|
|
|
|
$clientJob = Start-Job -ScriptBlock {
|
|
param($dir)
|
|
Set-Location $dir
|
|
& cmd /c "npm run dev" 2>&1
|
|
} -ArgumentList "$root\client"
|
|
|
|
try {
|
|
while ($true) {
|
|
# Pull and print output from both jobs
|
|
$serverOut = Receive-Job $serverJob 2>&1
|
|
$clientOut = Receive-Job $clientJob 2>&1
|
|
|
|
foreach ($line in $serverOut) {
|
|
$text = "$line"
|
|
if ($text.Trim()) {
|
|
Write-Host "[server] $text" -ForegroundColor Yellow
|
|
}
|
|
}
|
|
|
|
foreach ($line in $clientOut) {
|
|
$text = "$line"
|
|
if ($text.Trim()) {
|
|
Write-Host "[client] $text" -ForegroundColor Cyan
|
|
}
|
|
}
|
|
|
|
# Check if either job died
|
|
if ($serverJob.State -eq 'Completed' -or $serverJob.State -eq 'Failed') {
|
|
Write-Host "[dev] Server process exited ($($serverJob.State))" -ForegroundColor Red
|
|
break
|
|
}
|
|
if ($clientJob.State -eq 'Completed' -or $clientJob.State -eq 'Failed') {
|
|
Write-Host "[dev] Client process exited ($($clientJob.State))" -ForegroundColor Red
|
|
break
|
|
}
|
|
|
|
Start-Sleep -Milliseconds 300
|
|
}
|
|
}
|
|
finally {
|
|
Write-Host ""
|
|
Write-Host "[dev] Shutting down..." -ForegroundColor Red
|
|
|
|
# Stop the PS jobs
|
|
Stop-Job $serverJob -ErrorAction SilentlyContinue
|
|
Stop-Job $clientJob -ErrorAction SilentlyContinue
|
|
Remove-Job $serverJob -Force -ErrorAction SilentlyContinue
|
|
Remove-Job $clientJob -Force -ErrorAction SilentlyContinue
|
|
|
|
# Kill any lingering processes by name/port
|
|
# Kill cargo/rust server
|
|
Get-Process -Name "groupchat-server" -ErrorAction SilentlyContinue | Stop-Process -Force -ErrorAction SilentlyContinue
|
|
|
|
# Kill node/vite on port 3000
|
|
$nodeProcs = Get-NetTCPConnection -LocalPort 3000 -ErrorAction SilentlyContinue | Select-Object -ExpandProperty OwningProcess -Unique
|
|
foreach ($pid in $nodeProcs) {
|
|
Stop-Process -Id $pid -Force -ErrorAction SilentlyContinue
|
|
}
|
|
|
|
# Kill anything on server port 3001 too
|
|
$serverProcs = Get-NetTCPConnection -LocalPort 3001 -ErrorAction SilentlyContinue | Select-Object -ExpandProperty OwningProcess -Unique
|
|
foreach ($pid in $serverProcs) {
|
|
Stop-Process -Id $pid -Force -ErrorAction SilentlyContinue
|
|
}
|
|
|
|
Write-Host "[dev] Stopped." -ForegroundColor Red
|
|
}
|