Add goals, reading list, and people CRM - goals.py: Goal tracking with milestones and progress - reading.py: Reading list tracker (articles, books, papers) - people.py: Personal CRM for keeping notes on people - 21 tools total now

This commit is contained in:
2026-01-30 23:46:35 -06:00
parent 3b053ce71c
commit 7925efe4f1
7 changed files with 569 additions and 0 deletions

173
tools/goals.py Executable file
View File

@ -0,0 +1,173 @@
#!/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 <title>")
return
print(f"\n🎯 Goals ({len(goals)})")
print("=" * 50)
for goal in goals:
status = "" if goal['status'] == 'completed' else "🔵"
bar = "" * (goal['progress'] // 10) + "" * (10 - goal['progress'] // 10)
print(f"\n{status} #{goal['id']} {goal['title']}")
print(f" [{bar}] {goal['progress']}%")
if goal.get('deadline'):
print(f" 📅 Deadline: {goal['deadline']}")
if goal['milestones']:
for m in goal['milestones']:
check = "" if m['done'] else ""
print(f" {check} {m['title']}")
print()
def complete_goal(goal_id: int):
"""Mark a goal as completed."""
data = load_goals()
for goal in data['goals']:
if goal['id'] == goal_id:
goal['status'] = 'completed'
goal['progress'] = 100
goal['completed'] = datetime.now().isoformat()
save_goals(data)
print(f"🎉 Goal completed: {goal['title']}")
return
print(f"Goal not found: #{goal_id}")
def main():
if len(sys.argv) < 2:
show_goals()
return
cmd = sys.argv[1]
if cmd == 'add' and len(sys.argv) > 2:
title = ' '.join(sys.argv[2:])
add_goal(title)
elif cmd == 'milestone' and len(sys.argv) > 3:
goal_id = int(sys.argv[2])
title = ' '.join(sys.argv[3:])
add_milestone(goal_id, title)
elif cmd == 'done' and len(sys.argv) > 3:
goal_id = int(sys.argv[2])
milestone_id = int(sys.argv[3])
complete_milestone(goal_id, milestone_id)
elif cmd == 'complete' and len(sys.argv) > 2:
complete_goal(int(sys.argv[2]))
elif cmd == 'list':
show_goals(show_all='--all' in sys.argv)
else:
print("Usage:")
print(" goals - Show active goals")
print(" goals add <title> - Add new goal")
print(" goals milestone <id> <text> - Add milestone")
print(" goals done <goal> <milestone> - Complete milestone")
print(" goals complete <id> - Complete goal")
if __name__ == "__main__":
main()