#!/usr/bin/env python3 """ ideas - Idea incubator Capture, develop, and track ideas over time. """ import json import sys import random from datetime import datetime from pathlib import Path WORKSPACE = Path("/home/wdjones/.openclaw/workspace") IDEAS_FILE = WORKSPACE / "data" / "ideas.json" STAGES = ['seed', 'growing', 'ready', 'planted', 'archived'] STAGE_EMOJI = {'seed': '🌱', 'growing': '🌿', 'ready': '🌻', 'planted': '🌳', 'archived': 'šŸ“¦'} def load_ideas() -> list: """Load ideas.""" IDEAS_FILE.parent.mkdir(parents=True, exist_ok=True) if IDEAS_FILE.exists(): with open(IDEAS_FILE) as f: return json.load(f) return [] def save_ideas(ideas: list): """Save ideas.""" with open(IDEAS_FILE, 'w') as f: json.dump(ideas, f, indent=2) def add_idea(title: str, description: str = None, tags: list = None): """Add a new idea.""" ideas = load_ideas() idea = { 'id': len(ideas) + 1, 'title': title, 'description': description, 'tags': tags or [], 'stage': 'seed', 'notes': [], 'created': datetime.now().isoformat(), 'updated': datetime.now().isoformat(), } ideas.append(idea) save_ideas(ideas) print(f"🌱 Idea #{idea['id']}: {title}") def add_note(idea_id: int, note: str): """Add a development note to an idea.""" ideas = load_ideas() for idea in ideas: if idea['id'] == idea_id: idea['notes'].append({ 'text': note, 'date': datetime.now().isoformat(), }) idea['updated'] = datetime.now().isoformat() save_ideas(ideas) print(f"šŸ“ Note added to idea #{idea_id}") return print(f"Idea not found: #{idea_id}") def advance(idea_id: int): """Advance an idea to the next stage.""" ideas = load_ideas() for idea in ideas: if idea['id'] == idea_id: current = idea['stage'] idx = STAGES.index(current) if idx < len(STAGES) - 2: # Don't auto-advance to archived idea['stage'] = STAGES[idx + 1] idea['updated'] = datetime.now().isoformat() save_ideas(ideas) emoji = STAGE_EMOJI[idea['stage']] print(f"{emoji} Idea #{idea_id} advanced to: {idea['stage']}") else: print("Idea already at final stage") return print(f"Idea not found: #{idea_id}") def archive(idea_id: int): """Archive an idea.""" ideas = load_ideas() for idea in ideas: if idea['id'] == idea_id: idea['stage'] = 'archived' idea['updated'] = datetime.now().isoformat() save_ideas(ideas) print(f"šŸ“¦ Idea #{idea_id} archived") return print(f"Idea not found: #{idea_id}") def show_idea(idea_id: int): """Show idea details.""" ideas = load_ideas() for idea in ideas: if idea['id'] == idea_id: emoji = STAGE_EMOJI[idea['stage']] print(f"\n{emoji} Idea #{idea['id']}: {idea['title']}") print("=" * 50) print(f"Stage: {idea['stage']}") print(f"Created: {idea['created'][:10]}") if idea.get('description'): print(f"\n{idea['description']}") if idea.get('tags'): print(f"\nTags: {' '.join('#' + t for t in idea['tags'])}") if idea['notes']: print(f"\nšŸ“ Development Notes ({len(idea['notes'])})") for note in idea['notes'][-5:]: print(f" [{note['date'][:10]}] {note['text']}") print() return print(f"Idea not found: #{idea_id}") def list_ideas(stage: str = None): """List ideas.""" ideas = load_ideas() if stage: ideas = [i for i in ideas if i['stage'] == stage] else: ideas = [i for i in ideas if i['stage'] != 'archived'] if not ideas: print("No ideas yet. Add with: ideas add ") return print(f"\nšŸ’” Ideas ({len(ideas)})") print("=" * 50) for stage in STAGES[:-1]: # Exclude archived stage_ideas = [i for i in ideas if i['stage'] == stage] if stage_ideas: emoji = STAGE_EMOJI[stage] print(f"\n{emoji} {stage.title()} ({len(stage_ideas)})") for idea in stage_ideas: notes = len(idea['notes']) print(f" #{idea['id']} {idea['title'][:35]} ({notes} notes)") print() def random_idea(): """Get a random idea to work on.""" ideas = load_ideas() active = [i for i in ideas if i['stage'] in ['seed', 'growing']] if not active: print("No active ideas") return idea = random.choice(active) emoji = STAGE_EMOJI[idea['stage']] print(f"\nšŸŽ² Random idea to develop:\n") print(f" {emoji} #{idea['id']} {idea['title']}") if idea.get('description'): print(f" {idea['description'][:60]}...") print() def main(): if len(sys.argv) < 2: print("Usage:") print(" ideas add <title> - Add new idea") print(" ideas note <id> <text> - Add development note") print(" ideas advance <id> - Move to next stage") print(" ideas show <id> - Show idea details") print(" ideas list [stage] - List ideas") print(" ideas random - Random idea to work on") print(" ideas archive <id> - Archive idea") print("") print(f"Stages: {' → '.join(STAGES[:-1])}") list_ideas() return cmd = sys.argv[1] if cmd == 'add' and len(sys.argv) > 2: title = ' '.join(sys.argv[2:]) add_idea(title) elif cmd == 'note' and len(sys.argv) > 3: idea_id = int(sys.argv[2]) note = ' '.join(sys.argv[3:]) add_note(idea_id, note) elif cmd == 'advance' and len(sys.argv) > 2: advance(int(sys.argv[2])) elif cmd == 'show' and len(sys.argv) > 2: show_idea(int(sys.argv[2])) elif cmd == 'list': stage = sys.argv[2] if len(sys.argv) > 2 else None list_ideas(stage) elif cmd == 'random': random_idea() elif cmd == 'archive' and len(sys.argv) > 2: archive(int(sys.argv[2])) else: print("Unknown command. Run 'ideas' for help.") if __name__ == "__main__": main()