diff --git a/README.md b/README.md index 0ec4a11..33ebda0 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,8 @@ A macOS CLI tool for managing local development environments with Git worktrees, automatic port allocation, and tmux session management. +![devx TUI demo](screenshots/tui-final.gif) + ## Features - **Interactive TUI**: Beautiful terminal interface for browsing and managing sessions diff --git a/screenshots/GENERATING.md b/screenshots/GENERATING.md new file mode 100644 index 0000000..d38e597 --- /dev/null +++ b/screenshots/GENERATING.md @@ -0,0 +1,167 @@ +# Generating DevX Demo Screenshots + +This guide explains how to regenerate the demo screenshot and provides context for future modifications. + +## Quick Start + +```bash +cd screenshots + +# 1. Start Caddy (if not already running) +caddy start --config caddy-config.json + +# 2. Set up demo environment +./setup-demo.sh + +# 3. Generate the screenshot +vhs tui-final.tape + +# 4. Clean up +./restore-demo.sh + +# Optional: Stop Caddy +caddy stop +``` + +## How It Works + +### The Problem +We needed professional TUI screenshots without exposing real session/project data, but the TUI preview panel requires actual running tmux sessions to display content. + +### The Solution +1. **Fake Sessions** - Create realistic session metadata with demo names +2. **Real Tmux Sessions** - Create actual tmux sessions with scripted terminal output +3. **Caddy Routes** - Create matching routes so health checks pass +4. **VHS Recording** - Record the TUI with VHS, hiding the initial command + +### Architecture + +``` +setup-demo.sh +├── Backup real sessions.json & projects.json +├── Install demo sessions.json & projects.json (5 sessions, 3 projects) +├── Create 5 tmux sessions with scripted output +│ ├── feature-auth → React dev server +│ ├── bugfix-login → Test runner +│ ├── refactor-api → GraphQL server +│ ├── docs-update → Next.js build +│ └── experiment-cache → Redis performance +└── Create 9 Caddy routes matching sessions + +vhs tui-final.tape +└── Records TUI interaction (hidden startup, navigation, preview, hostnames, create) + +restore-demo.sh +├── Kill 5 demo tmux sessions +├── Delete 9 Caddy routes +└── Restore original sessions.json & projects.json +``` + +## Demo Sessions + +The demo includes 5 realistic sessions across 3 projects: + +**E-Commerce Web App (webapp)** +- `feature-auth` - OAuth integration feature branch +- `bugfix-login` - Login validation bug fix (has attention flag) + +**Backend Services (backend)** +- `refactor-api` - REST to GraphQL migration +- `experiment-cache` - Redis caching experiment + +**Marketing Website (website)** +- `docs-update` - API v2 documentation updates + +## Files + +### Generated Assets +- **`tui-final.gif`** - The main demo screenshot (1.2MB) + +### Generation Scripts +- **`setup-demo.sh`** - Sets up complete demo environment +- **`restore-demo.sh`** - Cleans up demo environment +- **`create-demo-tmux-sessions.sh`** - Creates 5 fake tmux sessions with scripted output +- **`kill-demo-tmux-sessions.sh`** - Kills demo tmux sessions +- **`create-demo-caddy-routes.sh`** - Creates 9 Caddy routes for demo sessions +- **`delete-demo-caddy-routes.sh`** - Removes demo Caddy routes +- **`tui-final.tape`** - VHS recording script + +### Configuration +- **`caddy-config.json`** - Caddy server configuration with srv1 server +- **`demo-env/.config/devx/sessions.json`** - 5 fake demo sessions +- **`demo-env/.config/devx/projects.json`** - 3 fake demo projects + +## For Future AI Agents + +### Context +This screenshot generation system was created to solve a specific problem: We needed to showcase devx's TUI for the README/marketing, but: +- Real session names exposed private project information +- TUI preview panel shows tmux session content, which would leak code/data +- Simply removing routes caused Caddy health warnings +- "Session not running" previews looked unprofessional + +### Key Design Decisions + +1. **Why real tmux sessions?** + - The TUI preview uses `tmux capture-pane` to get actual session content + - Mocking this would require modifying devx code + - Real sessions with scripted output is simpler and cleaner + +2. **Why Caddy routes?** + - devx health check expects routes for each port in sessions.json + - Missing routes trigger warnings in the TUI + - Creating routes makes the demo look production-ready + +3. **Why VHS instead of screencapture?** + - VHS creates scriptable, reproducible recordings + - Can be regenerated when devx features change + - Better quality than macOS screencapture + - Animations are more engaging than static images + +### Modifying the Demo + +**To change session content:** +Edit `create-demo-tmux-sessions.sh` and update the heredoc content for each session. + +**To add/remove sessions:** +1. Update `demo-env/.config/devx/sessions.json` +2. Update `demo-env/.config/devx/projects.json` if needed +3. Add corresponding tmux session in `create-demo-tmux-sessions.sh` +4. Add corresponding routes in `create-demo-caddy-routes.sh` +5. Update cleanup scripts accordingly + +**To change TUI interactions:** +Edit `tui-final.tape` - it's a simple script with Type, Sleep, Enter, Down, Up, Escape commands. + +**To change visual styling:** +Edit the VHS settings at the top of `tui-final.tape` (FontSize, Width, Height, Theme). + +### Troubleshooting + +**Caddy warnings still appear:** +- Ensure routes match the session names and project aliases exactly +- Route ID format: `sess-{project}-{session}-{service}` +- Hostname format: `{project}-{session}-{service}.localhost` + +**Tmux sessions show "Session not running":** +- Verify tmux sessions exist: `tmux ls` +- Check session names match sessions.json exactly +- Ensure tmux sessions have content (not blank) + +**VHS recording shows command prompt:** +- Make sure `Hide`/`Show` are in the right places in the .tape file +- Hide should be before the devx command, Show after TUI loads + +## Dependencies + +- **tmux** - For creating demo sessions +- **caddy** - For route management +- **vhs** - For recording terminal sessions (`brew install vhs`) +- **jq** - For JSON manipulation (optional, for debugging) + +## Notes + +- The demo sessions use ports that might conflict with real services (3000, 4000, etc.) +- Caddy must be running with the `srv1` server (not `srv0`) +- Generated GIF is ~1.2MB - suitable for GitHub READMEs +- All demo data is intentionally fake and generic diff --git a/screenshots/caddy-config.json b/screenshots/caddy-config.json new file mode 100644 index 0000000..28af3ed --- /dev/null +++ b/screenshots/caddy-config.json @@ -0,0 +1,15 @@ +{ + "admin": { + "listen": "localhost:2019" + }, + "apps": { + "http": { + "servers": { + "srv1": { + "listen": [":80"], + "routes": [] + } + } + } + } +} diff --git a/screenshots/create-demo-caddy-routes.sh b/screenshots/create-demo-caddy-routes.sh new file mode 100755 index 0000000..6f4c260 --- /dev/null +++ b/screenshots/create-demo-caddy-routes.sh @@ -0,0 +1,54 @@ +#!/bin/bash +# Create Caddy routes for demo sessions + +set -e + +CADDY_API="http://localhost:2019" + +echo "Creating Caddy routes for demo sessions..." + +# Helper function to create a route +create_route() { + local route_id=$1 + local hostname=$2 + local port=$3 + + curl -sS --fail -X POST "$CADDY_API/config/apps/http/servers/srv1/routes" \ + -H "Content-Type: application/json" \ + -d "{ + \"@id\": \"$route_id\", + \"match\": [{ + \"host\": [\"$hostname\"] + }], + \"handle\": [{ + \"handler\": \"reverse_proxy\", + \"upstreams\": [{ + \"dial\": \"localhost:$port\" + }] + }] + }" > /dev/null + + echo "✓ $hostname → localhost:$port" +} + +# feature-auth routes (webapp project) +create_route "sess-webapp-feature-auth-ui" "webapp-feature-auth-ui.localhost" 3000 +create_route "sess-webapp-feature-auth-api" "webapp-feature-auth-api.localhost" 4000 + +# bugfix-login routes (webapp project) +create_route "sess-webapp-bugfix-login-ui" "webapp-bugfix-login-ui.localhost" 3001 +create_route "sess-webapp-bugfix-login-api" "webapp-bugfix-login-api.localhost" 4001 + +# refactor-api routes (backend project) +create_route "sess-backend-refactor-api-api" "backend-refactor-api-api.localhost" 5000 +create_route "sess-backend-refactor-api-db" "backend-refactor-api-db.localhost" 5432 + +# docs-update routes (website project) +create_route "sess-website-docs-update-ui" "website-docs-update-ui.localhost" 8080 + +# experiment-cache routes (backend project) +create_route "sess-backend-experiment-cache-api" "backend-experiment-cache-api.localhost" 5001 +create_route "sess-backend-experiment-cache-cache" "backend-experiment-cache-cache.localhost" 6379 + +echo "" +echo "✓ Created 9 Caddy routes" diff --git a/screenshots/create-demo-tmux-sessions.sh b/screenshots/create-demo-tmux-sessions.sh new file mode 100755 index 0000000..aff7622 --- /dev/null +++ b/screenshots/create-demo-tmux-sessions.sh @@ -0,0 +1,155 @@ +#!/bin/bash +# Create demo tmux sessions with fake but realistic terminal output + +set -e + +SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +# Session names from demo sessions.json +SESSIONS=( + "feature-auth" + "bugfix-login" + "refactor-api" + "docs-update" + "experiment-cache" +) + +echo "Creating demo tmux sessions..." + +# Kill any existing demo sessions first +for session in "${SESSIONS[@]}"; do + tmux kill-session -t "$session" 2>/dev/null || true +done + +# Session 1: feature-auth - React dev server with OAuth +tmux new-session -d -s "feature-auth" +tmux send-keys -t "feature-auth" "clear" C-m +sleep 0.5 +tmux send-keys -t "feature-auth" "cat << 'EOF'" C-m +tmux send-keys -t "feature-auth" " + + vite v4.5.0 dev server running at: + + > Local: http://localhost:3000/ + > Network: http://192.168.1.100:3000/ + + ready in 421ms. + + 10:34:12 AM [vite] page reload src/components/OAuthButton.tsx + 10:34:18 AM [vite] hmr update /src/hooks/useAuth.ts + 10:35:02 AM [vite] hmr update /src/pages/Login.tsx + + ✓ OAuth integration tests passing (12/12) + → Implementing token refresh flow... + +EOF" C-m +echo "✓ feature-auth" + +# Session 2: bugfix-login - Test runner +tmux new-session -d -s "bugfix-login" +tmux send-keys -t "bugfix-login" "clear" C-m +sleep 0.5 +tmux send-keys -t "bugfix-login" "cat << 'EOF'" C-m +tmux send-keys -t "bugfix-login" " + + PASS tests/auth/login.test.ts + ✓ validates email format (8ms) + ✓ validates password strength (12ms) + ✓ shows error for invalid credentials (15ms) + ✓ redirects after successful login (9ms) + + PASS tests/auth/validation.test.ts + ✓ allows valid email addresses (5ms) + ✓ rejects malformed emails (7ms) + ✓ enforces minimum password length (6ms) + + Test Suites: 2 passed, 2 total + Tests: 7 passed, 7 total + Snapshots: 0 total + Time: 2.451s + + Watching for file changes... + +EOF" C-m +echo "✓ bugfix-login" + +# Session 3: refactor-api - GraphQL server +tmux new-session -d -s "refactor-api" +tmux send-keys -t "refactor-api" "clear" C-m +sleep 0.5 +tmux send-keys -t "refactor-api" "cat << 'EOF'" C-m +tmux send-keys -t "refactor-api" " + + 🚀 GraphQL Server ready at http://localhost:5000/graphql + + [2024-10-04 10:36:15] INFO Database connected: postgres://localhost:5432/backend_dev + [2024-10-04 10:36:16] INFO Redis cache connected: redis://localhost:6379 + [2024-10-04 10:36:17] INFO Schema compiled: 47 types, 23 queries, 15 mutations + + Query: users (12ms) + Query: products (8ms) [cached] + Mutation: createOrder (45ms) + Query: orders (6ms) + + → Migrating REST endpoints to GraphQL... + → /api/users → Query.users ✓ + → /api/products → Query.products ✓ + +EOF" C-m +echo "✓ refactor-api" + +# Session 4: docs-update - Next.js docs site +tmux new-session -d -s "docs-update" +tmux send-keys -t "docs-update" "clear" C-m +sleep 0.5 +tmux send-keys -t "docs-update" "cat << 'EOF'" C-m +tmux send-keys -t "docs-update" " + + ▲ Next.js 14.0.3 + - Local: http://localhost:8080 + - Network: http://0.0.0.0:8080 + + ✓ Ready in 1.2s + + ○ Compiling /api-reference/v2 ... + ✓ Compiled /api-reference/v2 in 234ms + + ○ Compiling /docs/authentication ... + ✓ Compiled /docs/authentication in 189ms + + GET /api-reference/v2 200 in 245ms + GET /_next/static/css/app.css 200 in 12ms + + → Updating API v2 documentation... + +EOF" C-m +echo "✓ docs-update" + +# Session 5: experiment-cache - Redis experiment +tmux new-session -d -s "experiment-cache" +tmux send-keys -t "experiment-cache" "clear" C-m +sleep 0.5 +tmux send-keys -t "experiment-cache" "cat << 'EOF'" C-m +tmux send-keys -t "experiment-cache" " + + [Express] Server running on port 5001 + [Redis] Connected to redis://localhost:6379 + + Cache Performance Test: + ┌─────────────────┬──────────┬───────────┬──────────┐ + │ Operation │ Without │ With │ Speedup │ + ├─────────────────┼──────────┼───────────┼──────────┤ + │ User lookup │ 45ms │ 3ms │ 15.0x │ + │ Product search │ 123ms │ 8ms │ 15.4x │ + │ Order history │ 234ms │ 12ms │ 19.5x │ + └─────────────────┴──────────┴───────────┴──────────┘ + + Cache hit rate: 87.3% + → Redis cache integration working! ✓ + +EOF" C-m +echo "✓ experiment-cache" + +echo "" +echo "✓ Created 5 demo tmux sessions" +echo "Verify with: tmux ls" diff --git a/screenshots/delete-demo-caddy-routes.sh b/screenshots/delete-demo-caddy-routes.sh new file mode 100755 index 0000000..6312930 --- /dev/null +++ b/screenshots/delete-demo-caddy-routes.sh @@ -0,0 +1,25 @@ +#!/bin/bash +# Delete Caddy routes for demo sessions + +CADDY_API="http://localhost:2019" + +echo "Deleting demo Caddy routes..." + +# List of route IDs to delete +ROUTE_IDS=( + "sess-webapp-feature-auth-ui" + "sess-webapp-feature-auth-api" + "sess-webapp-bugfix-login-ui" + "sess-webapp-bugfix-login-api" + "sess-backend-refactor-api-api" + "sess-backend-refactor-api-db" + "sess-website-docs-update-ui" + "sess-backend-experiment-cache-api" + "sess-backend-experiment-cache-cache" +) + +for route_id in "${ROUTE_IDS[@]}"; do + curl -s -X DELETE "$CADDY_API/id/$route_id" > /dev/null 2>&1 || true +done + +echo "✓ Deleted demo Caddy routes" diff --git a/screenshots/demo-env/.config/devx/projects.json b/screenshots/demo-env/.config/devx/projects.json new file mode 100644 index 0000000..a04e154 --- /dev/null +++ b/screenshots/demo-env/.config/devx/projects.json @@ -0,0 +1,25 @@ +{ + "projects": { + "webapp": { + "name": "E-Commerce Web App", + "path": "/Users/demo/projects/webapp", + "description": "React frontend + Node.js API", + "default_branch": "main", + "auto_pull_on_create": true + }, + "backend": { + "name": "Backend Services", + "path": "/Users/demo/projects/backend", + "description": "GraphQL API with PostgreSQL", + "default_branch": "develop", + "auto_pull_on_create": true + }, + "website": { + "name": "Marketing Website", + "path": "/Users/demo/projects/website", + "description": "Next.js marketing site with CMS", + "default_branch": "main", + "auto_pull_on_create": false + } + } +} diff --git a/screenshots/demo-env/.config/devx/sessions.json b/screenshots/demo-env/.config/devx/sessions.json new file mode 100644 index 0000000..83c3dfa --- /dev/null +++ b/screenshots/demo-env/.config/devx/sessions.json @@ -0,0 +1,91 @@ +{ + "sessions": { + "feature-auth": { + "name": "feature-auth", + "project_alias": "webapp", + "project_path": "/Users/demo/projects/webapp", + "branch": "feature/oauth-integration", + "path": "/Users/demo/projects/webapp/.worktrees/feature-auth", + "ports": { + "ui": 3000, + "api": 4000 + }, + "routes": { + "ui": "sess-webapp-feature-auth-ui", + "api": "sess-webapp-feature-auth-api" + }, + "editor_pid": 12345, + "created_at": "2024-10-01T10:30:00Z", + "updated_at": "2024-10-04T09:15:00Z" + }, + "bugfix-login": { + "name": "bugfix-login", + "project_alias": "webapp", + "project_path": "/Users/demo/projects/webapp", + "branch": "bugfix/login-validation", + "path": "/Users/demo/projects/webapp/.worktrees/bugfix-login", + "ports": { + "ui": 3001, + "api": 4001 + }, + "routes": { + "ui": "sess-webapp-bugfix-login-ui", + "api": "sess-webapp-bugfix-login-api" + }, + "attention_flag": true, + "attention_reason": "claude_done", + "attention_time": "2024-10-04T08:45:00Z", + "created_at": "2024-10-02T14:20:00Z", + "updated_at": "2024-10-04T08:45:00Z" + }, + "refactor-api": { + "name": "refactor-api", + "project_alias": "backend", + "project_path": "/Users/demo/projects/backend", + "branch": "refactor/rest-to-graphql", + "path": "/Users/demo/projects/backend/.worktrees/refactor-api", + "ports": { + "api": 5000, + "db": 5432 + }, + "routes": { + "api": "sess-backend-refactor-api-api", + "db": "sess-backend-refactor-api-db" + }, + "created_at": "2024-09-28T16:00:00Z", + "updated_at": "2024-10-03T11:30:00Z" + }, + "docs-update": { + "name": "docs-update", + "project_alias": "website", + "project_path": "/Users/demo/projects/website", + "branch": "docs/api-v2", + "path": "/Users/demo/projects/website/.worktrees/docs-update", + "ports": { + "ui": 8080 + }, + "routes": { + "ui": "sess-website-docs-update-ui" + }, + "created_at": "2024-10-03T09:00:00Z", + "updated_at": "2024-10-04T10:00:00Z" + }, + "experiment-cache": { + "name": "experiment-cache", + "project_alias": "backend", + "project_path": "/Users/demo/projects/backend", + "branch": "experiment/redis-cache", + "path": "/Users/demo/projects/backend/.worktrees/experiment-cache", + "ports": { + "api": 5001, + "cache": 6379 + }, + "routes": { + "api": "sess-backend-experiment-cache-api", + "cache": "sess-backend-experiment-cache-cache" + }, + "created_at": "2024-10-01T13:45:00Z", + "updated_at": "2024-10-02T16:20:00Z" + } + } +} diff --git a/screenshots/kill-demo-tmux-sessions.sh b/screenshots/kill-demo-tmux-sessions.sh new file mode 100755 index 0000000..18c886f --- /dev/null +++ b/screenshots/kill-demo-tmux-sessions.sh @@ -0,0 +1,21 @@ +#!/bin/bash +# Kill all demo tmux sessions + +SESSIONS=( + "feature-auth" + "bugfix-login" + "refactor-api" + "docs-update" + "experiment-cache" +) + +echo "Killing demo tmux sessions..." + +for session in "${SESSIONS[@]}"; do + if tmux has-session -t "$session" 2>/dev/null; then + tmux kill-session -t "$session" + echo "✓ Killed $session" + fi +done + +echo "✓ Demo tmux sessions cleaned up" diff --git a/screenshots/restore-demo.sh b/screenshots/restore-demo.sh new file mode 100755 index 0000000..9fdf6e1 --- /dev/null +++ b/screenshots/restore-demo.sh @@ -0,0 +1,34 @@ +#!/bin/bash +# Restore original data and clean up demo tmux sessions + +SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +DEVX_CONFIG="$HOME/.config/devx" + +# Kill demo tmux sessions +chmod +x "$SCRIPT_DIR/kill-demo-tmux-sessions.sh" +"$SCRIPT_DIR/kill-demo-tmux-sessions.sh" + +# Delete demo Caddy routes +chmod +x "$SCRIPT_DIR/delete-demo-caddy-routes.sh" +"$SCRIPT_DIR/delete-demo-caddy-routes.sh" + +# Restore sessions +if [ -f "$DEVX_CONFIG/sessions.json.backup" ]; then + mv "$DEVX_CONFIG/sessions.json.backup" "$DEVX_CONFIG/sessions.json" + echo "✓ Original sessions restored" +else + rm -f "$DEVX_CONFIG/sessions.json" + echo "✓ Removed demo sessions (no backup found)" +fi + +# Restore projects +if [ -f "$DEVX_CONFIG/projects.json.backup" ]; then + mv "$DEVX_CONFIG/projects.json.backup" "$DEVX_CONFIG/projects.json" + echo "✓ Original projects restored" +else + rm -f "$DEVX_CONFIG/projects.json" + echo "✓ Removed demo projects (no backup found)" +fi + +echo "" +echo "✓ Demo environment cleaned up" diff --git a/screenshots/setup-demo.sh b/screenshots/setup-demo.sh new file mode 100755 index 0000000..5c18548 --- /dev/null +++ b/screenshots/setup-demo.sh @@ -0,0 +1,44 @@ +#!/bin/bash +# Setup complete demo environment with fake tmux sessions + +set -e + +SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +DEVX_CONFIG="$HOME/.config/devx" +DEMO_DIR="$SCRIPT_DIR/demo-env/.config/devx" + +# Check if Caddy is running with srv1 server +if ! curl -s http://localhost:2019/config/apps/http/servers/srv1/routes > /dev/null 2>&1; then + echo "⚠️ Caddy is not running with srv1 server" + echo "Start with: caddy start --config $SCRIPT_DIR/caddy-config.json" + exit 1 +fi +echo "✓ Caddy is running" + +mkdir -p "$DEVX_CONFIG" + +# Backup and replace sessions +if [ ! -f "$DEVX_CONFIG/sessions.json.backup" ] && [ -f "$DEVX_CONFIG/sessions.json" ]; then + cp "$DEVX_CONFIG/sessions.json" "$DEVX_CONFIG/sessions.json.backup" +fi +cp "$DEMO_DIR/sessions.json" "$DEVX_CONFIG/sessions.json" +echo "✓ Demo sessions installed" + +# Backup and replace projects +if [ ! -f "$DEVX_CONFIG/projects.json.backup" ] && [ -f "$DEVX_CONFIG/projects.json" ]; then + cp "$DEVX_CONFIG/projects.json" "$DEVX_CONFIG/projects.json.backup" +fi +cp "$DEMO_DIR/projects.json" "$DEVX_CONFIG/projects.json" +echo "✓ Demo projects installed" + +# Create fake tmux sessions with demo content +chmod +x "$SCRIPT_DIR/create-demo-tmux-sessions.sh" +"$SCRIPT_DIR/create-demo-tmux-sessions.sh" + +# Create Caddy routes for demo sessions +chmod +x "$SCRIPT_DIR/create-demo-caddy-routes.sh" +"$SCRIPT_DIR/create-demo-caddy-routes.sh" + +echo "" +echo "✓ Demo environment ready for recording" +echo "Run restore-demo.sh when done." diff --git a/screenshots/tui-final.gif b/screenshots/tui-final.gif new file mode 100644 index 0000000..b4509d9 Binary files /dev/null and b/screenshots/tui-final.gif differ diff --git a/screenshots/tui-final.tape b/screenshots/tui-final.tape new file mode 100644 index 0000000..b8bb122 --- /dev/null +++ b/screenshots/tui-final.tape @@ -0,0 +1,76 @@ +# VHS tape file for devx TUI walkthrough +# Run setup-demo.sh before recording, restore-demo.sh after + +Output tui-final.gif + +# Configure terminal appearance +Set FontSize 18 +Set Width 1400 +Set Height 900 +Set Padding 20 +Set Theme "Catppuccin Mocha" +Set Shell "bash" + +# Hide command typing - start directly at TUI +Hide +Type "devx" +Enter +# Wait longer for TUI to fully load +Sleep 5s +Show + +# Show the main TUI interface for a moment +Sleep 1.5s + +# Navigate through sessions +Down +Sleep 1s +Down +Sleep 1s + +# Toggle preview panel (p key) +Type "p" +Sleep 2s + +# Navigate with preview visible +Down +Sleep 1s +Up +Sleep 1s + +# View hostnames for the selected session (h key) +Type "h" +Sleep 2.5s + +# Go back to main list (ESC) +Escape +Sleep 1s + +# Toggle preview off +Type "p" +Sleep 1s + +# Navigate to a different session +Down +Sleep 1s +Down +Sleep 1s + +# Show create new session dialog (c key) +Type "c" +Sleep 2s + +# Cancel creation (ESC) +Escape +Sleep 1s + +# Navigate more +Up +Sleep 800ms + +# Final pause to show the interface +Sleep 2s + +# Exit +Type "q" +Sleep 500ms