# Development Commands Module # Commands for development server, CSS, content generation, and enhanced workflows # Set shell for commands set shell := ["bash", "-c"] # Start development server with hot reload (profile-aware). # # Reads `site/config/rendering.ncl` and dispatches: # - leptos-hydration โ†’ `cargo leptos serve --features content-watcher` # (full WASM hydration toolchain โ€” wasm-bindgen + cargo-leptos pipeline) # - htmx-ssr โ†’ `cargo run -p rustelo-htmx-server --no-default-features # --features htmx-ssr,content-watcher` # (server only, no wasm32 target, no wasm-bindgen) # # Override the auto-detection by calling the explicit recipes: # just dev::serve-leptos forces cargo-leptos # just dev::htmx forces htmx-ssr via bacon [no-cd] serve: #!/usr/bin/env bash set -e echo "๐Ÿš€ Starting development server with hot content reloading..." echo "๐Ÿ“ Content source: ${SITE_CONTENT_PATH:-site/content} (watched for changes)" rm -f works-pv/temp_classes.txt lsof -ti:3030 | xargs kill -9 2>/dev/null || true lsof -ti:3031 | xargs kill -9 2>/dev/null || true if nu /Users/Akasha/Development/rustelo/scripts/check-wasm-needed.nu \ --routes-dir site/config \ --workspace-config site/config/rendering.ncl; then echo "๐Ÿ”จ leptos-hydration profile โ†’ cargo leptos serve" exec cargo leptos serve --features content-watcher else rc=$? if [ "$rc" -eq 1 ]; then echo "๐Ÿชถ htmx-ssr profile โ†’ cargo run (no wasm32)" # Materialise templates into target/site/htmx-templates and read them # at runtime (avoids touching crate source trees). nu scripts/build/assemble-htmx-templates.nu export HTMX_TEMPLATE_PATH=target/site/htmx-templates exec cargo run --package rustelo-htmx-server --bin rustelo-htmx-server \ --no-default-features \ --features htmx-ssr,content-watcher else echo "check-wasm-needed failed (rc=$rc)" >&2 exit 2 fi fi # Force the cargo-leptos pipeline regardless of rendering.ncl. Use when you # need to test a specific route's leptos-hydration behaviour while the # workspace default is htmx-ssr. [no-cd] serve-leptos: @echo "๐Ÿš€ Forcing leptos-hydration (cargo leptos serve)..." rm -f works-pv/temp_classes.txt lsof -ti:3030 | xargs kill -9 2>/dev/null || true lsof -ti:3031 | xargs kill -9 2>/dev/null || true cargo leptos serve --features content-watcher # Start development server without content watcher (minimal) [no-cd] minimal: @echo "๐Ÿš€ Starting minimal development server..." @echo "๐Ÿ“ Content source: ${SITE_CONTENT_PATH:-site/content} (static processing)" @echo "๐Ÿ”„ Features: content-static only" @echo "โŒ No hot reload - restart server for content changes" rm -f works-pv/temp_classes.txt pnpm run build:all lsof -ti:3030 | xargs kill -9 2>/dev/null || true lsof -ti:3031 | xargs kill -9 2>/dev/null || true cargo leptos serve --features content-static # Start development server with all warnings (for debugging) [no-cd] verbose: @echo "๐Ÿš€ Starting development server with all warnings..." pnpm run build:all lsof -ti:3030 | xargs kill -9 lsof -ti:3031 | xargs kill -9 cargo leptos serve # Start development server with custom port [no-cd] port port="3030": @echo "๐Ÿš€ Starting development server on port {{port}}..." LEPTOS_SITE_ADDR="127.0.0.1:{{port}}" cargo leptos watch # Start development server with source assets (debugging) [no-cd] source: @echo "๐Ÿš€ Starting development server with source assets (debugging mode)..." pnpm run build:all lsof -ti:3030 | xargs kill -9 lsof -ti:3031 | xargs kill -9 ASSET_MODE=source cargo leptos serve --features content-static # Start development server with bundled assets (testing production-like) [no-cd] bundled: @echo "๐Ÿš€ Starting development server with bundled assets (production-like mode)..." pnpm run build:all lsof -ti:3030 | xargs kill -9 lsof -ti:3031 | xargs kill -9 ASSET_MODE=bundled cargo leptos serve --features content-static # Test bundled mode by building assets first then starting server [no-cd] test-bundled: @echo "๐Ÿš€ Building assets and testing bundled mode..." @just css-build pnpm run copy:css-assets lsof -ti:3030 | xargs kill -9 lsof -ti:3031 | xargs kill -9 ASSET_MODE=bundled cargo leptos serve --features content-static # Start development server with filtered output (Nushell version) quiet-nu: @echo "๐Ÿš€ Starting development server with filtered output (Nushell)..." nu {{justfile_directory()}}/scripts/build/dev-quiet.nu # Start development server with CSS watching [no-cd] full: @echo "๐Ÿš€ Starting full development environment..." rm -f works-pv/temp_classes.txt @just css-watch & cargo leptos serve # watch # htmx-ssr dev server โ€” skips wasm32 compilation entirely. # Equivalent to dev::serve when rendering.ncl has default_profile = "htmx-ssr", # but always forces htmx-ssr regardless of that setting. [no-cd] htmx: #!/usr/bin/env bash set -e lsof -ti:3030 | xargs kill -9 2>/dev/null || true lsof -ti:3031 | xargs kill -9 2>/dev/null || true echo "๐Ÿชถ htmx-ssr โ€” cargo run (no wasm32)" exec cargo run --package rustelo-htmx-server --bin rustelo-htmx-server \ --no-default-features \ --features htmx-ssr,content-watcher # Fast minimal development (no watchers, fastest startup) [no-cd] fast: @echo "โšก Starting minimal development server (fastest startup)..." @echo "๐Ÿ”ฅ No watchers, no hot reload - manual restart required" rm -f works-pv/temp_classes.txt pnpm run build:all lsof -ti:3030 | xargs kill -9 2>/dev/null || true lsof -ti:3031 | xargs kill -9 2>/dev/null || true cargo leptos serve --features content-static --no-default-features # ============================================================================= # OPTIMIZED DEVELOPMENT MODES (Prevent Double Builds) # ============================================================================= # Ultra-minimal development (skip CSS, docs, scaffolding) [no-cd] ultra-minimal: @echo "โšก Starting ultra-minimal development server (maximum speed)..." @echo "๐Ÿšซ Skipped: CSS build, documentation, scaffolding" @echo "๐Ÿ’ก Use 'just build-artifacts' to generate missing assets" #. .env lsof -ti:3030 | xargs kill -9 2>/dev/null || true lsof -ti:3031 | xargs kill -9 2>/dev/null || true SKIP_CSS_BUILD=1 SKIP_DOCS_BUILD=1 SKIP_SCAFFOLDING_BUILD=1 SKIP_SHARED_RESOURCES_BUILD=1 cargo leptos serve --features content-watcher # Fast minimal development (smart CSS, skip docs/scaffolding) [no-cd] dev-fast: @echo "๐Ÿš€ Starting fast development server (smart CSS only)..." @echo "๐ŸŽจ CSS: Smart build (timestamp-based)" @echo "๐Ÿšซ Skipped: documentation, scaffolding" @echo "๐Ÿ’ก Use 'just build-artifacts' to generate missing assets" #. .env lsof -ti:3030 | xargs kill -9 2>/dev/null || true lsof -ti:3031 | xargs kill -9 2>/dev/null || true SKIP_DOCS_BUILD=1 SKIP_SCAFFOLDING_BUILD=1 cargo leptos serve --features content-watcher # Coordinated minimal (smart builds for everything, no duplication) [no-cd] dev-coordinated: @echo "๐ŸŽฏ Starting coordinated development server (no duplicate builds)..." @echo "๐ŸŽจ CSS: Coordinate with other processes" @echo "๐Ÿ“– Docs: Generate only when sources change" @echo "๐Ÿ—๏ธ Scaffolding: Timestamp-based generation" #. .env lsof -ti:3030 | xargs kill -9 2>/dev/null || true lsof -ti:3031 | xargs kill -9 2>/dev/null || true cargo leptos serve --features content-watcher # Build only artifacts without starting server [no-cd] build-artifacts: @echo "๐Ÿ—๏ธ Building all artifacts (CSS, docs, scaffolding)..." @echo "๐ŸŽจ Building CSS files..." pnpm run build:all @echo "๐Ÿ“– Forcing complete rebuild (bypassing smart cache)..." FORCE_REBUILD_CACHE=1 cargo build --workspace --features content-static @echo "โœ… All artifacts built" # Show build status and statistics [no-cd] build-status: @echo "๐Ÿ“Š Build Status Report" @echo "=======================" @echo "" @echo "๐ŸŽจ CSS Build Status:" @[ -f public/website.css ] && echo " โœ… public/website.css ($(stat -f%z public/website.css 2>/dev/null || echo '0') bytes)" || echo " โŒ public/website.css (missing)" @echo "" @echo "๐Ÿ“– Documentation Status:" @[ -f site/info/components_analysis.md ] && echo " โœ… components_analysis.md" || echo " โŒ components_analysis.md (missing)" @[ -f site/info/pages_analysis.md ] && echo " โœ… pages_analysis.md" || echo " โŒ pages_analysis.md (missing)" @echo "" @echo "๐Ÿ—๏ธ Scaffolding Markers:" @[ -f crates/pages/target/pages_scaffolding.marker ] && echo " โœ… pages scaffolding complete" || echo " โŒ pages scaffolding pending" @[ -f crates/core-lib/target/shared_resources.marker ] && echo " โœ… shared resources complete" || echo " โŒ shared resources pending" @echo "" @echo "๐Ÿš€ Development Modes Available:" @echo " just dev-minimal - Ultra-fast (skip everything)" @echo " just dev-fast - Fast (smart CSS only)" @echo " just dev-coordinated - Safe (no duplicate builds)" @echo " just start - Full (original behavior)" # Clean build artifacts and markers [no-cd] clean-build-artifacts: @echo "๐Ÿงน Cleaning build artifacts and markers..." rm -f crates/pages/target/pages_scaffolding.marker rm -f crates/core-lib/target/shared_resources.marker rm -f crates/components/target/components_docs.marker rm -f public/website.css rm -f site/info/components_analysis.md rm -f site/info/pages_analysis.md @echo "โœ… Build artifacts cleaned - next build will regenerate everything" # ============================================================================= # ENHANCED DEVELOPMENT WORKFLOW # ============================================================================= # Start development server with manager integration [no-cd] manager: @echo "๐Ÿš€ Starting enhanced development with manager integration..." @echo "๐Ÿ“Š Server + Rustelo Manager TUI" @just serve & sleep 3 cargo run --bin rustelo-manager -- --tui # Start development server with build-tools generation info: @echo "๐Ÿš€ Starting development with build-tools generation..." @echo "๐Ÿ“‹ Server + automatic documentation generation" @just ../build-tools-info @just serve # Complete development environment (server + manager + build-tools) [no-cd] complete: @echo "๐Ÿš€ Starting complete development environment..." @echo "๐ŸŽฏ Full stack: Server + Manager + Documentation + CSS Watch" @just ../build-tools-info @just css-watch & @just serve & sleep 3 cargo run --bin rustelo-manager -- --tui # ============================================================================= # CSS AND ASSET COMMANDS # ============================================================================= # Watch CSS files for changes [no-cd] css-watch: @echo "๐Ÿ‘๏ธ Watching CSS files..." npm run watch:css # Build CSS files [no-cd] css-build: @echo "๐ŸŽจ Building CSS files..." npm run build:all # ============================================================================= # CONTENT MANAGEMENT COMMANDS # ============================================================================= # Content consistency validation between source and any cached outputs [no-cd] content-validate-consistency: @echo "๐Ÿ” Validating content consistency..." nu {{justfile_directory()}}/scripts/content/validate-content-consistency.nu @echo "โœ… Content consistency validated" # Build localized content (Nushell version - preferred) [no-cd] content-build: @echo "๐Ÿ“ Building localized content (Nushell)..." @echo "๐Ÿ”ง Environment: Reading from .env file" nu {{justfile_directory()}}/scripts/content/build-content-enhanced.nu # Export _index.ncl files to index.json via nickel export (NCL pipeline) [no-cd] content-ncl-to-json type="" lang="": @echo "๐Ÿ“ฆ Exporting NCL โ†’ index.json..." NICKEL_IMPORT_PATH="{{justfile_directory()}}/../rustelo/resources/nickel:{{justfile_directory()}}/site/config" \ nu {{justfile_directory()}}/scripts/content/build-ncl-json.nu \ --content-dir "${SITE_CONTENT_PATH:-site/content}" \ --public-dir "${RUSTELO_STATIC_DIR:-site/public}" \ {{ if type != "" { "--type " + type } else { "" } }} \ {{ if lang != "" { "--lang " + lang } else { "" } }} # Full NCL content pipeline: regenerate _index.ncl + export to index.json + copy images [no-cd] content-ncl-build type="" lang="": @echo "๐Ÿ“ Full NCL content pipeline..." just content-ncl-index "{{type}}" "{{lang}}" just content-ncl-to-json "{{type}}" "{{lang}}" just dev::content-copy-images "{{type}}" "{{lang}}" # Copy page-bundle images from content tree to site/public for HTTP serving [no-cd] content-copy-images type="" lang="": @echo "๐Ÿ–ผ๏ธ Copying content images to public..." nu {{justfile_directory()}}/scripts/content/copy-content-images.nu \ --content-dir "${SITE_CONTENT_PATH:-site/content}" \ --public-dir "${RUSTELO_STATIC_DIR:-site/public}" \ {{ if type != "" { "--type " + type } else { "" } }} \ {{ if lang != "" { "--lang " + lang } else { "" } }} # Validate localized content [no-cd] content-validate: @echo "๐Ÿ” Validating localized content..." nu {{justfile_directory()}}/scripts/content/validate-content.nu # Generate new content [no-cd] content-generate type title *args: @echo "๐Ÿ“ Generating {{type}}: {{title}}" nu {{justfile_directory()}}/scripts/content/generate-content.nu {{type}} --title "{{title}}" {{args}} # Synchronize content translations [no-cd] content-sync command *args: @echo "๐Ÿ”„ Synchronizing content..." nu {{justfile_directory()}}/scripts/content/sync-translations.nu {{command}} {{args}} # Check for missing translations [no-cd] content-missing: @echo "๐Ÿ” Checking for missing translations..." nu {{justfile_directory()}}/scripts/content/sync-translations.nu validate-translations # Validate content ID consistency across languages [no-cd] content-validate-ids: @echo "๐Ÿ” Validating content ID consistency..." cargo build --bin index_generator --features content-static --quiet ./target/debug/index_generator --validate-only # Generate index.json files from markdown frontmatter with ID validation [no-cd] content-generate-indices: @echo "๐Ÿ—๏ธ Generating content indices with validation..." cargo build --bin index_generator --features content-static --quiet ./target/debug/index_generator # Generate _index.ncl files from per-post *.ncl metadata files [no-cd] content-ncl-index type="" lang="": @nu {{justfile_directory()}}/scripts/content/generate-ncl-index.nu \ --content-dir "${SITE_CONTENT_PATH:-site/content}" \ {{ if type != "" { "--type " + type } else { "" } }} \ {{ if lang != "" { "--lang " + lang } else { "" } }} # Generate missing translation placeholders [no-cd] content-generate-missing: @echo "๐Ÿ“‹ Generating missing translation placeholders..." nu {{justfile_directory()}}/scripts/content/sync-translations.nu generate-missing # Organize all build artifacts into target/site for serving [no-cd] organize-artifacts: @echo "๐Ÿ—๏ธ Organizing build artifacts into target/site/..." @bash {{justfile_directory()}}/scripts/setup/organize-artifacts.sh # ============================================================================= # BROWSER LOGGING AND DEBUGGING # ============================================================================= # Open browser to a page and wait for WASM hydration - then ask Claude to capture logs # Usage: just browser-logs /services # After running: tell Claude "captura los logs del browser" or use MCP tools directly [no-cd] browser-logs page="/": #!/usr/bin/env bash URL="http://localhost:3030{{page}}" echo "Opening Chrome โ†’ $URL" echo "Waiting 6s for WASM hydration..." osascript -e " tell application \"Google Chrome\" if not (exists window 1) then make new window set URL of active tab of window 1 to \"$URL\" activate end tell" 2>/dev/null || open -a "Google Chrome" "$URL" sleep 6 echo "" echo "Ready. Page: $URL" echo "Tell Claude: 'captura los logs del browser' or call MCP tools:" echo " mcp__browser-tools__getConsoleErrors" echo " mcp__browser-tools__getConsoleLogs" echo " mcp__browser-tools__getNetworkErrors" # Start browser-tools connector server (port 3025) โ€” bridges Chrome extension โ†” MCP # Run once per session before using browser-logs [no-cd] browser-tools-server: bash {{justfile_directory()}}/scripts/browser-logs/start-server.sh # Alias kept for backward compatibility [no-cd] server-browser-logs: @just dev::browser-tools-server # ============================================================================= # BUILD VALIDATION MODES # ============================================================================= # Validate development environment before starting server [no-cd] validate: @echo "๐Ÿ” Validating development environment..." nu {{justfile_directory()}}/scripts/build/validate-environment.nu nu {{justfile_directory()}}/scripts/build/validate-build.nu --quick nu {{justfile_directory()}}/scripts/build/validate-wasm-bundle.nu @echo "โœ… Validation complete - starting server..." . .env lsof -ti:3030 | xargs kill -9 2>/dev/null || true lsof -ti:3031 | xargs kill -9 2>/dev/null || true cargo leptos serve --features content-watcher # Start development server with strict build validation (warnings as errors) [no-cd] strict: @echo "๐Ÿšจ Starting development server with strict validation (warnings as errors)..." nu {{justfile_directory()}}/scripts/build/validate-environment.nu --strict nu {{justfile_directory()}}/scripts/build/validate-build.nu --strict @echo "โœ… Strict validation passed - starting server..." . .env lsof -ti:3030 | xargs kill -9 2>/dev/null || true lsof -ti:3031 | xargs kill -9 2>/dev/null || true RUSTFLAGS="-D warnings" cargo leptos serve --features content-watcher # Test functionality after server starts (basic smoke tests) [no-cd] test-functionality: @echo "๐Ÿงช Starting server with functionality testing..." @just serve & @echo "โณ Waiting for server to start..." sleep 5 @echo "๐Ÿ” Running basic functionality tests..." # Test server health curl -f http://127.0.0.1:3030/health || echo "โŒ Health check failed" # Test main page loads curl -f http://127.0.0.1:3030/ >/dev/null && echo "โœ… Main page loads" || echo "โŒ Main page failed" # Test blog page loads curl -f http://127.0.0.1:3030/blog >/dev/null && echo "โœ… Blog page loads" || echo "โŒ Blog page failed" @echo "๐ŸŽฏ Functionality tests complete" # Smart development mode (auto-detect appropriate validation level) [no-cd] smart: #!/usr/bin/env bash if [ -f ".dev-strict" ]; then echo "๐Ÿšจ Strict mode enabled (.dev-strict file found)" just dev::strict elif [ "$CI" = "true" ]; then echo "๐Ÿค– CI environment detected - using validation mode" just dev::validate elif [ "${DEV_VALIDATION_LEVEL:-0}" -gt "2" ]; then echo "๐Ÿ” High validation level requested" just dev::validate else echo "โšก Using default development mode" just dev::serve fi # ============================================================================= # DEVELOPMENT UTILITIES # ============================================================================= # Install development dependencies [no-cd] deps: @echo "๐Ÿ“ฆ Installing development dependencies..." @just npm-install @just cargo-check # Inspect build.rs generated files for development [no-cd] inspect-generated: @echo "๐Ÿ” Inspecting build.rs generated files..." {{justfile_directory()}}/scripts/inspect-generated.sh # Standalone build-tools generation command [no-cd] build-tools-info: @echo "๐Ÿ“‹ Generating comprehensive site information..." @echo "๐Ÿ“ Output: ${SITE_INFO_PATH:-site/info}/" cargo build --workspace --features content-static --quiet @echo "โœ… Site information generated" # ============================================================================= # SPA NAVIGATION TESTING # ============================================================================= # Start development server with navigation testing API enabled [no-cd] with-nav-test: @echo "๐Ÿงญ Starting development server with navigation testing API..." @echo "๐Ÿ”— Navigation test API available at http://localhost:3030/api/nav-test" . .env lsof -ti:3030 | xargs kill -9 2>/dev/null || true lsof -ti:3031 | xargs kill -9 2>/dev/null || true ENABLE_NAV_TEST_API=true cargo leptos serve --features content-watcher # Test single route navigation [no-cd] nav-test-route path: @echo "๐Ÿงญ Testing navigation to: {{path}}" curl -s "http://localhost:3030/api/nav-test/resolve?path={{path}}" | jq # Test navigation sequence between two routes [no-cd] nav-test-sequence from to: @echo "๐Ÿงญ Testing navigation from {{from}} to {{to}}" curl -X POST http://localhost:3030/api/nav-test/navigate \ -H "Content-Type: application/json" \ -d '{"from": "{{from}}", "to": "{{to}}"}' | jq # Validate all configured routes [no-cd] nav-test-validate: @echo "๐Ÿงญ Validating all routes..." curl -s "http://localhost:3030/api/nav-test/validate-all" | jq # Run navigation benchmark [no-cd] nav-test-bench path="/": @echo "๐Ÿงญ Benchmarking route: {{path}}" curl -s "http://localhost:3030/api/nav-test/benchmark?path={{path}}" | jq # Run full navigation test suite [no-cd] nav-test-all: @echo "๐Ÿงญ Running complete navigation test suite..." @just dev::nav-test-validate @just dev::nav-test-route / @just dev::nav-test-route /services @just dev::nav-test-route /es/contactar @just dev::nav-test-sequence / /services @just dev::nav-test-sequence /services /contact @echo "โœ… Navigation tests complete" # Quick navigation check (for CI/CD) [no-cd] nav-quick-check: @curl -f -s "http://localhost:3030/api/nav-test/validate-all" | jq '.invalid_routes == 0' | grep -q true && echo "โœ… All routes valid" || (echo "โŒ Invalid routes found" && exit 1) # Open navigation dashboard in browser [no-cd] nav-dashboard: @echo "๐Ÿงญ Opening navigation test dashboard..." @echo "๐ŸŒ Dashboard URL: http://localhost:3030/api/nav-test/dashboard" open "http://localhost:3030/api/nav-test/dashboard" || xdg-open "http://localhost:3030/api/nav-test/dashboard" || echo "Please open http://localhost:3030/api/nav-test/dashboard in your browser" # Show navigation testing help and available aliases [no-cd] nav-help: @echo "๐Ÿงญ SPA Navigation Testing Commands" @echo "==================================" @echo "" @echo "๐Ÿ“‹ Just Commands:" @echo " just dev::with-nav-test - Start server with navigation API" @echo " just dev::nav-test-route - Test single route" @echo " just dev::nav-test-sequence - Test navigation between routes" @echo " just dev::nav-test-validate - Validate all configured routes" @echo " just dev::nav-test-bench - Benchmark route performance" @echo " just dev::nav-test-all - Run complete test suite" @echo " just dev::nav-quick-check - Quick validation (CI/CD)" @echo " just dev::nav-dashboard - Open navigation dashboard" @echo "" @echo "โšก Quick Aliases:" @echo " just nts - Nav Test Start (start server)" @echo " just nt - Nav Test route (e.g., just nt /services)" @echo " just ns - Nav Sequence test" @echo " just nv - Nav Validate all routes" @echo " just nb - Nav Bench (benchmark route)" @echo " just na - Nav All tests (complete suite)" @echo " just nc - Nav Check (quick validation)" @echo " just nd - Nav Dashboard (open in browser)" @echo " just nh - Nav Help (show this help)" @echo "" @echo "๐Ÿš€ Quick Route Test Aliases:" @echo " just nt-home - Test home route (/)" @echo " just nt-services - Test services route (/services)" @echo " just nt-contact - Test contact route (/contact)" @echo " just nt-blog - Test blog route (/blog)" @echo " just nt-es - Test Spanish home (/es)" @echo " just nt-contactar - Test Spanish contact (/es/contactar)" @echo "" @echo "๐ŸŽฏ Common Usage Examples:" @echo " just nts # Start server with nav testing" @echo " just nt-home # Test home route (quick alias)" @echo " just nt-services # Test services route (quick alias)" @echo " just nt /custom/route # Test any custom route" @echo " just ns / /services # Test navigation from home to services" @echo " just nv # Validate all routes" @echo " just na # Run complete test suite" @echo "" @echo "๐ŸŒ API Endpoints (when server running):" @echo " GET /api/nav-test/resolve?path=" @echo " POST /api/nav-test/navigate" @echo " GET /api/nav-test/validate-all" @echo " GET /api/nav-test/benchmark?path=" @echo " GET /api/nav-test/dashboard" @echo "" @echo "๐Ÿ’ก Navigation testing allows you to test SPA routes WITHOUT a browser" @echo "๐Ÿ”— Based on HTTP API endpoints at /api/nav-test"