#!/usr/bin/env python3 """ goals - Goal and project tracking with milestones Track long-term goals and break them into actionable steps. """ import json import sys from datetime import datetime from pathlib import Path WORKSPACE = Path("/home/wdjones/.openclaw/workspace") GOALS_FILE = WORKSPACE / "data" / "goals.json" def load_goals() -> dict: """Load goals data.""" GOALS_FILE.parent.mkdir(parents=True, exist_ok=True) if GOALS_FILE.exists(): with open(GOALS_FILE) as f: return json.load(f) return {'goals': []} def save_goals(data: dict): """Save goals data.""" with open(GOALS_FILE, 'w') as f: json.dump(data, f, indent=2) def add_goal(title: str, description: str = "", deadline: str = None): """Add a new goal.""" data = load_goals() goal = { 'id': len(data['goals']) + 1, 'title': title, 'description': description, 'deadline': deadline, 'created': datetime.now().isoformat(), 'status': 'active', 'milestones': [], 'progress': 0, } data['goals'].append(goal) save_goals(data) print(f"šÆ Goal #{goal['id']}: {title}") def add_milestone(goal_id: int, title: str): """Add a milestone to a goal.""" data = load_goals() for goal in data['goals']: if goal['id'] == goal_id: milestone = { 'id': len(goal['milestones']) + 1, 'title': title, 'done': False, 'created': datetime.now().isoformat(), } goal['milestones'].append(milestone) save_goals(data) print(f" ā Added milestone: {title}") return print(f"Goal not found: #{goal_id}") def complete_milestone(goal_id: int, milestone_id: int): """Mark a milestone as complete.""" data = load_goals() for goal in data['goals']: if goal['id'] == goal_id: for m in goal['milestones']: if m['id'] == milestone_id: m['done'] = True m['completed'] = datetime.now().isoformat() # Update progress done = len([x for x in goal['milestones'] if x['done']]) total = len(goal['milestones']) goal['progress'] = int(done / total * 100) if total > 0 else 0 save_goals(data) print(f" ā Completed: {m['title']}") print(f" Progress: {goal['progress']}%") return print("Milestone not found") def show_goals(show_all: bool = False): """Display all goals.""" data = load_goals() goals = data['goals'] if not show_all: goals = [g for g in goals if g['status'] == 'active'] if not goals: print("No active goals. Add one with: goals add