#!/usr/bin/env python3 """ Focus timer - simple pomodoro-style timer with logging. """ import sys import time import json from datetime import datetime from pathlib import Path WORKSPACE = Path("/home/wdjones/.openclaw/workspace") LOG_FILE = WORKSPACE / "memory" / "focus-log.json" def load_log() -> list: """Load focus session log.""" if LOG_FILE.exists(): try: with open(LOG_FILE) as f: return json.load(f) except: return [] return [] def save_log(log: list): """Save focus session log.""" LOG_FILE.parent.mkdir(parents=True, exist_ok=True) with open(LOG_FILE, 'w') as f: json.dump(log, f, indent=2) def format_time(seconds: int) -> str: """Format seconds as MM:SS.""" mins, secs = divmod(seconds, 60) return f"{mins:02d}:{secs:02d}" def timer(minutes: int, task: str = None): """Run a focus timer.""" total_seconds = minutes * 60 remaining = total_seconds start_time = datetime.now() print(f"\n🎯 Focus session started: {minutes} minutes") if task: print(f" Task: {task}") print() try: while remaining > 0: print(f"\r ⏱️ {format_time(remaining)} remaining ", end='', flush=True) time.sleep(1) remaining -= 1 print(f"\r ✅ Session complete! ") print("\n🔔 Time's up! Take a break.\n") # Log the session log = load_log() log.append({ 'start': start_time.isoformat(), 'end': datetime.now().isoformat(), 'duration_minutes': minutes, 'task': task, 'completed': True }) save_log(log) except KeyboardInterrupt: elapsed = total_seconds - remaining print(f"\r ⏸️ Stopped after {format_time(elapsed)} ") if elapsed > 60: # Log if > 1 minute log = load_log() log.append({ 'start': start_time.isoformat(), 'end': datetime.now().isoformat(), 'duration_minutes': round(elapsed / 60, 1), 'task': task, 'completed': False }) save_log(log) print(" Session logged (partial)") def stats(): """Show focus statistics.""" log = load_log() if not log: print("No focus sessions logged yet.") return today = datetime.now().strftime("%Y-%m-%d") today_sessions = [s for s in log if s['start'].startswith(today)] total_minutes = sum(s['duration_minutes'] for s in log) today_minutes = sum(s['duration_minutes'] for s in today_sessions) completed = len([s for s in log if s.get('completed')]) print("\n📊 Focus Stats") print(f" Total sessions: {len(log)}") print(f" Completed: {completed}") print(f" Total time: {total_minutes:.0f} minutes ({total_minutes/60:.1f} hours)") print(f" Today: {len(today_sessions)} sessions, {today_minutes:.0f} minutes") if today_sessions: print("\n Today's sessions:") for s in today_sessions[-5:]: start = s['start'][11:16] status = "✅" if s.get('completed') else "⏸️" task = s.get('task', '')[:30] or 'No task' print(f" {status} {start} - {s['duration_minutes']}min - {task}") print() def main(): if len(sys.argv) < 2: print("Usage:") print(" focus.py [task] - Start a focus session") print(" focus.py stats - Show statistics") print("\nExamples:") print(" focus.py 25 'Write documentation'") print(" focus.py 15") sys.exit(0) if sys.argv[1] == 'stats': stats() return try: minutes = int(sys.argv[1]) except ValueError: print("Minutes must be a number") sys.exit(1) task = ' '.join(sys.argv[2:]) if len(sys.argv) > 2 else None timer(minutes, task) if __name__ == "__main__": main()