""" Workspace service - business logic for TDD workspace operations. """ from typing import Optional, Dict, Any from pathlib import Path from tddai import WorkspaceManager, IssueFetcher, WorkspaceStatus, TddaiError class WorkspaceInfo: """Value object for workspace information.""" def __init__(self, status: WorkspaceStatus, workspace=None): self.status = status self.workspace = workspace @property def is_clean(self) -> bool: return self.status == WorkspaceStatus.CLEAN @property def is_dirty(self) -> bool: return self.status == WorkspaceStatus.DIRTY @property def is_active(self) -> bool: return self.status == WorkspaceStatus.ACTIVE def get_test_files(self) -> list: """Get list of test files in workspace.""" if not self.workspace or not self.workspace.tests_dir.exists(): return [] return list(self.workspace.tests_dir.glob("*.py")) class WorkspaceService: """Service for workspace operations.""" def __init__(self): self.workspace_manager = WorkspaceManager() self.issue_fetcher = IssueFetcher() def get_workspace_info(self) -> WorkspaceInfo: """Get current workspace information.""" status = self.workspace_manager.get_status() workspace = None if status == WorkspaceStatus.ACTIVE: workspace = self.workspace_manager.get_current_workspace() return WorkspaceInfo(status, workspace) def start_issue_workspace(self, issue_number: int) -> WorkspaceInfo: """Start working on an issue. Returns: WorkspaceInfo with the created workspace Raises: TddaiError: If workspace already active or issue cannot be fetched """ # Check if workspace already active current_info = self.get_workspace_info() if current_info.is_active: raise TddaiError(f"Already working on issue #{current_info.workspace.issue_number}") # Fetch issue data issue_data = self.issue_fetcher.get_issue_data_dict(issue_number) # Create workspace workspace = self.workspace_manager.create_workspace(issue_data) return WorkspaceInfo(WorkspaceStatus.ACTIVE, workspace) def finish_current_workspace(self) -> Optional[int]: """Finish current workspace and return the issue number. Returns: Issue number that was finished, or None if no active workspace Raises: TddaiError: If workspace operations fail """ current_info = self.get_workspace_info() if not current_info.is_active: return None issue_number = current_info.workspace.issue_number self.workspace_manager.finish_workspace() return issue_number def get_workspace_summary(self) -> Dict[str, Any]: """Get workspace summary for display purposes.""" info = self.get_workspace_info() summary = { 'status': info.status, 'active': info.is_active, 'clean': info.is_clean, 'dirty': info.is_dirty } if info.workspace: test_files = info.get_test_files() summary.update({ 'issue_number': info.workspace.issue_number, 'issue_title': info.workspace.issue_title, 'issue_state': info.workspace.issue_state, 'workspace_dir': str(info.workspace.workspace_dir), 'test_count': len(test_files), 'test_files': [f.name for f in test_files], 'requirements_file': str(info.workspace.requirements_file), 'test_plan_file': str(info.workspace.test_plan_file) }) return summary