# cli.py import argparse import json import sys import uuid from pathlib import Path from rich.console import Console from rich.panel import Panel from pipeline.graph import build_graph from models.state import AdWorkflowState import config console = Console() def main(): parser = argparse.ArgumentParser(description="Generate static Meta ads from a brand URL.") parser.add_argument("url", help="Brand website URL to scrape") parser.add_argument("--brief", default="", help="Optional freeform brief for the campaign") parser.add_argument("--output", default=config.OUTPUT_DIR, help="Output directory for ad PNGs") args = parser.parse_args() config.OUTPUT_DIR = args.output Path(args.output).mkdir(parents=True, exist_ok=True) console.print(Panel( f"[bold]URL:[/bold] {args.url}\n[bold]Brief:[/bold] {args.brief or '(none)'}", title="[cyan]Static Ad Generation Pipeline[/cyan]" )) initial_state: AdWorkflowState = { "url": args.url, "brief": args.brief, "raw_scrape": "", "brand_dna": None, "ad_angles": [], "copy_concepts": [], "image_prompts": [], "generated_images": [], "final_ads": [], "current_gate": 0, "human_feedback": "", } try: graph = build_graph() thread_config = {"configurable": {"thread_id": uuid.uuid4().hex}} final_state = graph.invoke(initial_state, config=thread_config) except Exception: console.print_exception() sys.exit(1) ads = final_state["final_ads"] console.print(f"\n[green]Done! Generated {len(ads)} ads.[/green]") for ad in ads: console.print(f"\n[bold]{ad.angle_name}[/bold]") console.print(f" Headline: {ad.copy_concept.headline}") console.print(f" Files: {ad.image_paths}") summary_path = Path(args.output) / "summary.json" try: summary_path.write_text(json.dumps( [{"angle": a.angle_name, "headline": a.copy_concept.headline, "body": a.copy_concept.body_copy, "cta": a.copy_concept.cta_text, "images": a.image_paths, "prompt": a.image_prompt} for a in ads], indent=2 )) console.print(f"\nSummary written to [cyan]{summary_path}[/cyan]") except Exception: console.print_exception() sys.exit(1) if __name__ == "__main__": main()