"""Service for writing progress log entries.""" from datetime import date from pathlib import Path from development_hub.paths import paths class ProgressWriter: """Writes daily progress log entries to markdown files.""" def __init__(self, progress_dir: Path | None = None): """Initialize progress writer. Args: progress_dir: Directory for progress files. Defaults to settings value. """ self._progress_dir = progress_dir or paths.progress_dir def get_today_path(self) -> Path: """Get path to today's progress file.""" today = date.today() filename = today.strftime("%Y-%m-%d.md") return self._progress_dir / filename def file_exists(self) -> bool: """Check if today's progress file already exists.""" return self.get_today_path().exists() def create_progress_entry( self, projects: list[str], focus: list[str], completed: list[str], in_progress: list[str], blocked: list[str] | None = None, next_tasks: list[str] | None = None, notes: str | None = None, ) -> Path: """Create or update today's progress log entry. Args: projects: List of project keys worked on focus: Primary focus items completed: Completed tasks in_progress: Tasks in progress blocked: Blocked items (optional) next_tasks: Next up items (optional) notes: Additional notes (optional) Returns: Path to the created/updated file """ today = date.today() path = self.get_today_path() # Build content lines = [ "---", f"date: {today.isoformat()}", f"projects: [{', '.join(projects)}]", "---", "", ] # Focus section if focus: lines.append("## Focus") for item in focus: lines.append(f"- {item}") lines.append("") # Completed section lines.append("## Completed") if completed: for item in completed: lines.append(f"- [x] {item}") else: lines.append("(none yet)") lines.append("") # In Progress section lines.append("## In Progress") if in_progress: for item in in_progress: lines.append(f"- [ ] {item}") else: lines.append("(none)") lines.append("") # Blocked section lines.append("## Blocked") if blocked: for item in blocked: lines.append(f"- {item}") else: lines.append("(none)") lines.append("") # Next section if next_tasks: lines.append("## Next") for i, item in enumerate(next_tasks, 1): lines.append(f"{i}. {item}") lines.append("") # Notes section if notes: lines.append("## Notes") lines.append(notes) lines.append("") # Write file self._progress_dir.mkdir(parents=True, exist_ok=True) path.write_text("\n".join(lines)) return path def append_completed(self, task: str) -> bool: """Append a completed task to today's progress. Args: task: The completed task description Returns: True if successful, False if no progress file exists """ path = self.get_today_path() if not path.exists(): return False content = path.read_text() lines = content.split("\n") # Find the Completed section for i, line in enumerate(lines): if line.strip() == "## Completed": # Find where to insert (after the header) insert_idx = i + 1 # Skip (none yet) if present if insert_idx < len(lines) and lines[insert_idx].strip() == "(none yet)": lines[insert_idx] = f"- [x] {task}" else: lines.insert(insert_idx, f"- [x] {task}") path.write_text("\n".join(lines)) return True return False def append_in_progress(self, task: str) -> bool: """Append an in-progress task to today's progress. Args: task: The task description Returns: True if successful, False if no progress file exists """ path = self.get_today_path() if not path.exists(): return False content = path.read_text() lines = content.split("\n") # Find the In Progress section for i, line in enumerate(lines): if line.strip() == "## In Progress": insert_idx = i + 1 if insert_idx < len(lines) and lines[insert_idx].strip() == "(none)": lines[insert_idx] = f"- [ ] {task}" else: lines.insert(insert_idx, f"- [ ] {task}") path.write_text("\n".join(lines)) return True return False