#!/usr/bin/env bash # Metro Warden — dev environment launcher # Opens a tmux session with 3 panes inside Ghostty: # # ┌─────────────────────┬───────────────────────┐ # │ │ │ # │ textual console │ metro warden (app) │ # │ (DevTools) │ textual run --dev │ # │ │ │ # │ ├───────────────────────┤ # │ │ │ # │ │ watchexec │ # │ │ (auto-restart .py) │ # │ │ │ # └─────────────────────┴───────────────────────┘ # # Usage: ./dev.sh set -e PROJECT="$(cd "$(dirname "$0")" && pwd)" VENV="$PROJECT/.venv/bin/activate" SESSION="metro-warden" if [ ! -f "$VENV" ]; then echo "ERROR: .venv not found. Run:" echo " python3 -m venv .venv && source .venv/bin/activate && pip install -e '.[dev]'" exit 1 fi # Kill existing session if it exists tmux kill-session -t "$SESSION" 2>/dev/null || true # Create session with DevTools pane (left, full height) tmux new-session -d -s "$SESSION" -x 220 -y 50 \ -n "metro" \ "bash -c 'source $VENV && textual console'" # Split right — App pane (top right) tmux split-window -t "$SESSION:0" -h \ "bash -c 'source $VENV && textual run --dev $PROJECT/main.py'" # Split the right pane vertically — Watchexec pane (bottom right) tmux split-window -t "$SESSION:0.1" -v \ "bash -c 'source $VENV && watchexec --exts py --ignore assets/ --ignore .venv/ -r -- textual run --dev $PROJECT/main.py'" # Give the left pane 38% width tmux resize-pane -t "$SESSION:0.0" -x "38%" # Focus the app pane tmux select-pane -t "$SESSION:0.1" # Open in Ghostty (or attach in current terminal if already inside tmux) if [ -n "$TMUX" ]; then tmux switch-client -t "$SESSION" elif command -v ghostty &>/dev/null; then ghostty -e tmux attach-session -t "$SESSION" & # Open VS Code after a beat sleep 0.5 code "$PROJECT" 2>/dev/null || true else tmux attach-session -t "$SESSION" fi echo "Metro Warden dev environment started. Session: $SESSION"