set shell := ["pwsh.exe", "-NoProfile", "-c"] # Display available commands default: @just --list # Build and deploy everything across Windows and WSL all: build-all deploy-all # Build all binaries across Windows and WSL build-all: build-win build-wsl @Write-Host "Build complete across both OS boundaries." -ForegroundColor Green # Deploy all binaries and agent rules across Windows and WSL deploy-all: deploy-win deploy-wsl @Write-Host "Deployment complete across both OS boundaries." -ForegroundColor Green # Build Windows-native binaries build-win: build-ui build-server build-stub-win build-nvim-win # Deploy Windows-native binaries and rules deploy-win: deploy-server deploy-stub-win deploy-nvim-win deploy-rules-win # ========================================================= # 1. LIFECYCLE (Start / Stop / Restart / Verify / Version) # ========================================================= # Stop the background server gracefully and verify port release stop port="3000": @Write-Host "Shutting down MCP server gracefully on port {{port}}..." -ForegroundColor Cyan -& { $token = Get-Content "$env:USERPROFILE\.gemini\mcp_memory\admin.token" -ErrorAction SilentlyContinue; if ($token) { $hdr = @{ Authorization = "Bearer $($token.Trim())" }; $res = Invoke-RestMethod -Uri "http://127.0.0.1:{{port}}/shutdown" -Method Post -Headers $hdr -ErrorAction SilentlyContinue } else { $res = Invoke-RestMethod -Uri "http://127.0.0.1:{{port}}/shutdown" -Method Post -ErrorAction SilentlyContinue }; if ($res) { Write-Host "✅ Shutdown acknowledged with version details:" -ForegroundColor Green; $res | ConvertTo-Json -Depth 5 }; $procs = @(Get-Process mcp-memory-server -ErrorAction SilentlyContinue); if ($procs.Count -gt 0) { foreach ($p in $procs) { $exited = $p.WaitForExit(10000); if (-not $exited) { Write-Host "⚠️ Process $($p.Id) did not exit within 10s. Force killing..." -ForegroundColor Yellow; $p | Stop-Process -Force -ErrorAction SilentlyContinue } } }; $conns = Get-NetTCPConnection -LocalPort {{port}} -State Listen -ErrorAction SilentlyContinue; if ($conns) { $conns | Select-Object -ExpandProperty OwningProcess | ForEach-Object { Stop-Process -Id $_ -Force -ErrorAction SilentlyContinue } } } @Write-Host "✅ Shutdown complete. Port {{port}} and process are free." -ForegroundColor Green # Start the server in the background and verify /health start port="3000": @if (Get-NetTCPConnection -LocalPort {{port}} -State Listen -ErrorAction SilentlyContinue) { Write-Host '⚠️ Server is already running on port {{port}}. Skipping start.' -ForegroundColor Yellow; exit 0 }; Write-Host 'Starting MCP server in background on port {{port}}...' -ForegroundColor Cyan; $env:MCP_PORT='{{port}}'; $env:MCP_UDP_PORT1=$([int]{{port}} + 1); $env:MCP_UDP_PORT2=$([int]{{port}} + 2); .\start_server.ps1 -Port {{port}}; Write-Host 'Waiting up to 40 seconds for /health endpoint...' -ForegroundColor Cyan; for ($i = 1; $i -le 40; $i++) { try { $h = Invoke-RestMethod -Uri 'http://127.0.0.1:{{port}}/health' -ErrorAction Stop; Write-Host "✅ Server is UP! Running Version: $($h.version.app_version) [$($h.version.target_os)/$($h.version.target_arch)]" -ForegroundColor Green; exit 0 } catch { Start-Sleep -Seconds 1 } }; Write-Error '❌ Server failed to start on port {{port}} within 40 seconds.'; exit 1 # Verify deployment health and UI payload response verify port="3000": .\verify_deployment.ps1 -Port {{port}} # Display active running server version and deployed binary CLI version version port="3000": @Write-Host "--- Running Server API Version ---" -ForegroundColor Cyan -& { try { $h = Invoke-RestMethod -Uri "http://127.0.0.1:{{port}}/health" -ErrorAction Stop; Write-Host "HTTP /health: $($h.version.app_version) [$($h.version.target_os)/$($h.version.target_arch)]" -ForegroundColor Green } catch { Write-Host "HTTP /health: Server not reachable on port {{port}}" -ForegroundColor Yellow } } @Write-Host "--- Deployed Binary CLI Version ---" -ForegroundColor Cyan -mcp-memory-server --version # Gracefully stop, start, and verify the background server restart port="3000": (stop port) (start port) (verify port) # Run server directly in foreground for debugging run-server: cargo run -p mcp-memory-server # ========================================================= # 2. BUILD (Compile Binaries) # ========================================================= # Transpile Dashboard TypeScript (server/src/dashboard.ts) into JavaScript build-ui: @Write-Host "Building Dashboard JavaScript from server/src/dashboard.ts..." -ForegroundColor Cyan bun build server/src/dashboard.ts --outfile=server/src/dashboard.js --target=browser # Type-check Dashboard TypeScript source code check-ui: @Write-Host "Type-checking Dashboard TypeScript..." -ForegroundColor Cyan deno check server/src/dashboard.ts # Build Windows-native server binary in release mode (ensuring fresh UI build) build-server: build-ui @Write-Host "Building Windows Server..." -ForegroundColor Cyan cargo build --release -p mcp-memory-server # Build Windows-native stub binary in release mode build-stub-win: @Write-Host "Building Windows Stub..." -ForegroundColor Cyan cargo build --release -p mcp-memory-stub # Build Windows-native Neovim plugin binary build-nvim-win: @Write-Host "Building Windows Nvim..." -ForegroundColor Cyan cargo build --release -p nvim-core --bin mcp-memory-nvim # Build all WSL-native binaries build-wsl: build-stub build-nvim # Build WSL-native stub binary in release mode build-stub: @Write-Host "Building WSL Stub natively..." -ForegroundColor Cyan wsl.exe -d Ubuntu -e bash -c 'export PATH="/home/riz/.cargo/bin:$PATH" && cd /mnt/c/Users/reazul.ashraf/workspace/rust/mcp-memory && cargo build --release -p mcp-memory-stub' # Build WSL-native Neovim plugin binary in release mode build-nvim: @Write-Host "Building WSL Nvim natively..." -ForegroundColor Cyan wsl.exe -d Ubuntu -e bash -c 'export PATH="/home/riz/.cargo/bin:$PATH" && cd /mnt/c/Users/reazul.ashraf/workspace/rust/mcp-memory && cargo build --release -p nvim-core --bin mcp-memory-nvim' # ========================================================= # 3. DEPLOY (Move Binaries and Rules to Global Paths) # ========================================================= # Stage updated server binary, perform graceful shutdown, and auto-restart (skips if binary is unchanged) deploy-server: @Write-Host "Deploying Windows Server (Staged Hot-Swap)..." -ForegroundColor Cyan -& { $src = "target\release\mcp-memory-server.exe"; $targets = @("$env:USERPROFILE\.local\bin\mcp-memory-server.exe", "$env:USERPROFILE\.cargo\bin\mcp-memory-server.exe", "$env:USERPROFILE\.gemini\antigravity-cli\mcp\mcp-memory\mcp-memory.exe", "$env:USERPROFILE\scoop\apps\rustup\current\.cargo\bin\mcp-memory-server.exe"); $srcHash = if (Test-Path $src) { (Get-FileHash $src -Algorithm SHA256).Hash } else { $null }; $updated = $false; foreach ($target in $targets) { $parent = Split-Path $target; if (Test-Path $parent) { if ((Test-Path $target) -and $srcHash -and ((Get-FileHash $target -Algorithm SHA256).Hash -eq $srcHash)) { Write-Host "Skipping copy to $target (identical checksum)." -ForegroundColor Yellow } else { if (Test-Path $target) { $bak = "$target.old.$([guid]::NewGuid().ToString().Substring(0,8))"; Move-Item -Force $target $bak -ErrorAction SilentlyContinue }; Copy-Item -Force $src $target; Get-ChildItem "$parent\mcp-memory-server.exe.old.*" -ErrorAction SilentlyContinue | Remove-Item -Force -ErrorAction SilentlyContinue; Write-Host "Copied updated binary to $target" -ForegroundColor Green; $updated = $true } } }; if ($updated -or -not (Get-NetTCPConnection -LocalPort 3000 -State Listen -ErrorAction SilentlyContinue)) { just stop; just start } else { Write-Host "Server binary unchanged and server is running. Skipping restart." -ForegroundColor Green } } # Deploy Windows-native stub binary (skips if identical checksum) deploy-stub-win: @Write-Host "Deploying Windows Stub..." -ForegroundColor Cyan -& { $src = "target\release\mcp-memory-stub.exe"; $dest = "C:\Users\reazul.ashraf\.local\bin\mcp-memory-stub.exe"; if ((Test-Path $src) -and (Test-Path $dest) -and ((Get-FileHash $src -Algorithm SHA256).Hash -eq (Get-FileHash $dest -Algorithm SHA256).Hash)) { Write-Host "Skipping $dest (identical checksum)." -ForegroundColor Yellow } else { Stop-Process -Name mcp-memory-stub -Force -ErrorAction SilentlyContinue; if (Test-Path $dest) { Move-Item -Force $dest "$dest.old" -ErrorAction SilentlyContinue; Remove-Item -Force "$dest.old" -ErrorAction SilentlyContinue }; Copy-Item -Force $src $dest; Write-Host "Copied updated $src to $dest" -ForegroundColor Green } } # Deploy Windows-native Neovim plugin binary (skips if identical checksum) deploy-nvim-win: @Write-Host "Deploying Windows Nvim..." -ForegroundColor Cyan -& { $src = "target\release\mcp-memory-nvim.exe"; $dest = "C:\Users\reazul.ashraf\.local\bin\mcp-memory-nvim.exe"; if ((Test-Path $src) -and (Test-Path $dest) -and ((Get-FileHash $src -Algorithm SHA256).Hash -eq (Get-FileHash $dest -Algorithm SHA256).Hash)) { Write-Host "Skipping $dest (identical checksum)." -ForegroundColor Yellow } else { Stop-Process -Name mcp-memory-nvim -Force -ErrorAction SilentlyContinue; if (Test-Path $dest) { Move-Item -Force $dest "$dest.old" -ErrorAction SilentlyContinue; Remove-Item -Force "$dest.old" -ErrorAction SilentlyContinue }; Copy-Item -Force $src $dest; Write-Host "Copied updated $src to $dest" -ForegroundColor Green } } # Deploy global Agent rules to Windows config directory (skips identical files) deploy-rules-win: @Write-Host "Deploying global Agent rules (Windows)..." -ForegroundColor Cyan -& { $destDir = "C:\Users\reazul.ashraf\.gemini\config\rules"; if (!(Test-Path $destDir)) { New-Item -ItemType Directory -Force -Path $destDir | Out-Null }; $srcBase = (Get-Item "agent-rules").FullName; $updatedCount = 0; $skippedCount = 0; Get-ChildItem -Recurse agent-rules -File | ForEach-Object { $rel = $_.FullName.Substring($srcBase.Length + 1); $target = Join-Path $destDir $rel; $targetDir = Split-Path $target; if (!(Test-Path $targetDir)) { New-Item -ItemType Directory -Force -Path $targetDir | Out-Null }; if ((Test-Path $target) -and ((Get-FileHash $_.FullName -Algorithm SHA256).Hash -eq (Get-FileHash $target -Algorithm SHA256).Hash)) { $skippedCount++ } else { Copy-Item -Force $_.FullName $target; Write-Host "Updated rule: $rel" -ForegroundColor Green; $updatedCount++ } }; Write-Host "Agent rules deployment complete ($updatedCount updated, $skippedCount skipped identical)." -ForegroundColor Cyan } # Deploy all WSL-native binaries and agent rules deploy-wsl: deploy-stub deploy-nvim deploy-rules-wsl # Deploy WSL-native stub binary (skips if identical checksum) deploy-stub: @Write-Host "Deploying WSL Stub natively..." -ForegroundColor Cyan wsl.exe -d Ubuntu -e bash -c 'export PATH="/home/riz/.cargo/bin:$PATH" && cd /mnt/c/Users/reazul.ashraf/workspace/rust/mcp-memory && src="target/release/mcp-memory-stub" && dest="/home/riz/.local/bin/mcp-memory-stub" && if [ -f "$dest" ] && cmp -s "$src" "$dest"; then echo -e "\033[33mSkipping $dest (identical checksum).\033[0m"; else cp --remove-destination "$src" "$dest" && echo -e "\033[32mCopied updated $src to $dest\033[0m"; fi' # Deploy WSL-native Neovim plugin binary (skips if identical checksum) deploy-nvim: @Write-Host "Deploying WSL Nvim natively..." -ForegroundColor Cyan wsl.exe -d Ubuntu -e bash -c 'export PATH="/home/riz/.cargo/bin:$PATH" && cd /mnt/c/Users/reazul.ashraf/workspace/rust/mcp-memory && src="target/release/mcp-memory-nvim" && dest="/home/riz/.local/bin/mcp-memory-nvim" && if [ -f "$dest" ] && cmp -s "$src" "$dest"; then echo -e "\033[33mSkipping $dest (identical checksum).\033[0m"; else cp --remove-destination "$src" "$dest" && echo -e "\033[32mCopied updated $src to $dest\033[0m"; fi' # Deploy global Agent rules to WSL config directory (skips identical files) deploy-rules-wsl: @Write-Host "Deploying global Agent rules (WSL)..." -ForegroundColor Cyan wsl.exe -d Ubuntu -e bash -c 'mkdir -p /home/riz/.gemini/config/rules && src_dir="/mnt/c/Users/reazul.ashraf/workspace/rust/mcp-memory/agent-rules" && dest_dir="/home/riz/.gemini/config/rules" && updated=0 && skipped=0 && for src in $(find "$src_dir" -type f); do rel="${src#$src_dir/}"; dest="$dest_dir/$rel"; mkdir -p "$(dirname "$dest")"; if [ -f "$dest" ] && cmp -s "$src" "$dest"; then ((skipped++)); else cp "$src" "$dest" && echo -e "\033[32mUpdated rule: $rel\033[0m" && ((updated++)); fi; done && echo -e "\033[36mAgent rules WSL deployment complete ($updated updated, $skipped skipped identical).\033[0m"' # ========================================================= # 4. TESTING & COVERAGE # ========================================================= # Run fast parallel unit tests via cargo-nextest (and type-check UI) test: check-ui @Write-Host "Running fast parallel tests via cargo-nextest..." -ForegroundColor Cyan cargo nextest run --workspace # Run dashboard UI endpoint and integrity unit tests test-ui: @Write-Host "Running dashboard UI endpoint and integrity unit tests..." -ForegroundColor Cyan cargo test -p mcp-memory-server --lib api::setup::tests::test_dashboard_endpoint_and_html_integrity -- --nocapture # Run standard sequential cargo unit tests test-cargo: @Write-Host "Running standard unit tests across workspace..." -ForegroundColor Cyan cargo test --workspace # Run configuration parity tests for eagerTools test-config: cargo test --release -p mcp-memory-server --test parity_test # Run workspace unit tests and generate code coverage report test-coverage: @Write-Host "Running tests with code coverage..." -ForegroundColor Cyan cargo llvm-cov --workspace --ignore-filename-regex "stub" -- --test-threads=1 # Auto-generate and verify unit tests using local Ollama model improve-tests file="server/src/ollama.rs": improve-test {{file}} # ========================================================= # 5. EXPLICIT LIFECYCLE CHAINING # ========================================================= # Complete lifecycle: stop, build, deploy, start, and verify Windows server all-server-win port="3000": (stop port) build-server deploy-server (start port) (verify port) # Complete lifecycle: build and deploy Windows stub all-stub-win: build-stub-win deploy-stub-win # Complete lifecycle: build and deploy Windows Neovim plugin all-nvim-win: build-nvim-win deploy-nvim-win # Complete lifecycle: build and deploy WSL stub all-stub-wsl: build-stub deploy-stub # Complete lifecycle: build and deploy WSL Neovim plugin all-nvim-wsl: build-nvim deploy-nvim # Complete lifecycle: stop, build, deploy, start, and verify WSL server all-server-wsl port="3000": (stop port) build-server deploy-server (start port) (verify port) # Install git hooks (post-commit reconciliation and pre-push gatekeeper) install-git-hooks: @Write-Host "Installing git post-commit and pre-push hooks..." -ForegroundColor Cyan -& { $postCommitContent = "#!/bin/sh`npython3 scripts/git-reconcile.py 2>/dev/null || python scripts/git-reconcile.py 2>/dev/null || true`n"; [System.IO.File]::WriteAllText(".git\hooks\post-commit", $postCommitContent); $prePushContent = "#!/bin/sh`nif command -v python3 >/dev/null 2>&1; then`n exec python3 scripts/git-pre-push.py `"`$@`"`nelse`n exec python scripts/git-pre-push.py `"`$@`"`nfi`n"; [System.IO.File]::WriteAllText(".git\hooks\pre-push", $prePushContent); Write-Host "✅ Git post-commit and pre-push hooks installed." -ForegroundColor Green }