diff --git a/scripts/lib/bird_x.py b/scripts/lib/bird_x.py new file mode 100644 index 0000000..24f7b06 --- /dev/null +++ b/scripts/lib/bird_x.py @@ -0,0 +1,56 @@ +"""Bird CLI client for X (Twitter) search.""" + +import json +import shutil +import subprocess +import sys +from datetime import datetime +from typing import Any, Dict, List, Optional, Tuple + + +def _log(msg: str): + """Log to stderr.""" + sys.stderr.write(f"[Bird] {msg}\n") + sys.stderr.flush() + + +def is_bird_installed() -> bool: + """Check if Bird CLI is installed. + + Returns: + True if 'bird' command is available in PATH, False otherwise. + """ + return shutil.which("bird") is not None + + +def is_bird_authenticated() -> Optional[str]: + """Check if Bird is authenticated by running 'bird whoami'. + + Returns: + Username if authenticated, None otherwise. + """ + if not is_bird_installed(): + return None + + try: + result = subprocess.run( + ["bird", "whoami"], + capture_output=True, + text=True, + timeout=10, + ) + if result.returncode == 0 and result.stdout.strip(): + # Output is typically the username + return result.stdout.strip().split('\n')[0] + return None + except (subprocess.TimeoutExpired, FileNotFoundError, subprocess.SubprocessError): + return None + + +def check_npm_available() -> bool: + """Check if npm is available for installation. + + Returns: + True if 'npm' command is available in PATH, False otherwise. + """ + return shutil.which("npm") is not None