pub async fn with_spinner<F: Future<Output = T>, T>(message: &str, f: F) -> T
Run an async operation with a spinner animation. Falls back to static text if not a TTY.