#!/usr/bin/env python3 """Stocks collector using stock-lookup skill.""" import json import subprocess import sys from pathlib import Path def get_quotes(symbols: list) -> list: """Fetch quotes using stock-lookup skill.""" script = Path.home() / ".claude/skills/stock-lookup/scripts/quote.py" try: result = subprocess.run( [sys.executable, str(script), "--json"] + symbols, capture_output=True, text=True, timeout=30 ) if result.returncode == 0: return json.loads(result.stdout) else: return [{"symbol": s, "error": "fetch failed"} for s in symbols] except Exception as e: return [{"symbol": s, "error": str(e)} for s in symbols] def format_stocks_with_haiku(quotes: list) -> str: """Use Haiku to format stock data nicely.""" # Build context lines = [] for q in quotes: if "error" in q: lines.append(f"{q.get('symbol', '?')}: error - {q['error']}") else: price = q.get("price", 0) prev = q.get("previous_close", price) if prev and prev > 0: change = ((price - prev) / prev) * 100 direction = "+" if change >= 0 else "" lines.append(f"{q['symbol']}: ${price:.2f} ({direction}{change:.1f}%)") else: lines.append(f"{q['symbol']}: ${price:.2f}") stock_data = "\n".join(lines) prompt = f"""Format these stock quotes into a compact single line for a morning dashboard. Use arrow indicators (▲▼) for direction. Keep it concise. {stock_data} Output ONLY the formatted stock line, nothing else.""" try: result = subprocess.run( ["claude", "--print", "--model", "haiku", "-p", prompt], capture_output=True, text=True, timeout=30 ) if result.returncode == 0 and result.stdout.strip(): return result.stdout.strip() except Exception: pass # Fallback to basic format parts = [] for q in quotes: if "error" in q: parts.append(f"{q.get('symbol', '?')} ⚠️") else: price = q.get("price", 0) prev = q.get("previous_close", price) if prev and prev > 0: change = ((price - prev) / prev) * 100 arrow = "▲" if change >= 0 else "▼" parts.append(f"{q['symbol']} ${price:.2f} {'+' if change >= 0 else ''}{change:.1f}% {arrow}") else: parts.append(f"{q['symbol']} ${price:.2f}") return " ".join(parts) def collect(config: dict) -> dict: """Main collector entry point.""" watchlist = config.get("stocks", {}).get("watchlist", ["NVDA", "AAPL", "MSFT"]) quotes = get_quotes(watchlist) formatted = format_stocks_with_haiku(quotes) errors = [q.get("error") for q in quotes if "error" in q] return { "section": "Stocks", "icon": "📈", "content": formatted, "raw": quotes, "error": errors[0] if errors else None } if __name__ == "__main__": config = {"stocks": {"watchlist": ["CRWV", "NVDA", "MSFT"]}} result = collect(config) print(f"## {result['icon']} {result['section']}") print(result["content"])