Coverage for src/prosemark/freewriting/ports/cli_adapter.py: 100%
45 statements
« prev ^ index » next coverage.py v7.8.0, created at 2025-09-24 18:08 +0000
« prev ^ index » next coverage.py v7.8.0, created at 2025-09-24 18:08 +0000
1"""CLI adapter port interfaces for freewriting command interface.
3This module defines the port interfaces for the command-line interface
4components of the freewriting feature.
5"""
7from __future__ import annotations
9from abc import ABC, abstractmethod
10from dataclasses import dataclass
11from typing import TYPE_CHECKING
13if TYPE_CHECKING: # pragma: no cover
14 from prosemark.freewriting.domain.models import SessionConfig
15 from prosemark.freewriting.ports.tui_adapter import TUIAdapterPort, TUIConfig
18class CLIAdapterPort(ABC):
19 """Port interface for CLI operations.
21 This port defines the contract for command-line interface operations
22 such as argument parsing and TUI launching.
23 """
25 @property
26 @abstractmethod
27 def tui_adapter(self) -> TUIAdapterPort:
28 """TUI adapter instance for launching interface.
30 Returns:
31 The TUI adapter instance used by this CLI adapter.
33 """
35 @abstractmethod
36 def parse_arguments(
37 self,
38 node: str | None,
39 title: str | None,
40 word_count_goal: int | None,
41 time_limit: int | None,
42 theme: str,
43 current_directory: str | None,
44 ) -> SessionConfig:
45 """Parse and validate CLI arguments into session configuration.
47 Args:
48 node: Optional UUID of target node.
49 title: Optional session title.
50 word_count_goal: Optional word count target.
51 time_limit: Optional time limit in seconds.
52 theme: UI theme name.
53 current_directory: Working directory override.
55 Returns:
56 Validated SessionConfig object.
58 Raises:
59 ValidationError: If any arguments are invalid.
61 """
63 @abstractmethod
64 def validate_node_argument(self, node: str | None) -> str | None:
65 """Validate node UUID argument.
67 Args:
68 node: Node UUID string to validate.
70 Returns:
71 Validated UUID string or None.
73 Raises:
74 ValidationError: If UUID format is invalid.
76 """
78 @abstractmethod
79 def create_tui_config(self, theme: str) -> TUIConfig:
80 """Create TUI configuration from CLI arguments.
82 Args:
83 theme: Theme name from CLI.
85 Returns:
86 TUIConfig object with appropriate settings.
88 Raises:
89 ValidationError: If theme is not available.
91 """
93 @abstractmethod
94 def launch_tui(self, session_config: SessionConfig, tui_config: TUIConfig) -> int:
95 """Launch the TUI interface with given configuration.
97 Args:
98 session_config: Session configuration.
99 tui_config: TUI configuration.
101 Returns:
102 Exit code (0 for success, non-zero for error).
104 """
106 @abstractmethod
107 def handle_cli_error(self, error: Exception) -> int:
108 """Handle CLI-level errors and display appropriate messages.
110 Args:
111 error: The exception that occurred.
113 Returns:
114 Appropriate exit code.
116 """
119class CommandValidationPort(ABC):
120 """Port interface for command validation operations.
122 This port defines the contract for validating command arguments
123 and checking system capabilities.
124 """
126 @abstractmethod
127 def validate_write_command_args(
128 self,
129 node: str | None,
130 title: str | None,
131 word_count_goal: int | None,
132 time_limit: int | None,
133 ) -> dict[str, str | int | bool]:
134 """Validate arguments for the write command.
136 Args:
137 node: Optional node UUID.
138 title: Optional title.
139 word_count_goal: Optional word count goal.
140 time_limit: Optional time limit.
142 Returns:
143 Dictionary of validation results and normalized values.
145 Raises:
146 ValidationError: If validation fails.
148 """
150 @abstractmethod
151 def get_available_themes(self) -> list[str]:
152 """Get list of available UI themes.
154 Returns:
155 List of theme names.
157 """
159 @abstractmethod
160 def get_current_working_directory(self) -> str:
161 """Get current working directory.
163 Returns:
164 Absolute path to current directory.
166 """
168 @abstractmethod
169 def check_directory_writable(self, directory: str) -> bool:
170 """Check if directory is writable.
172 Args:
173 directory: Directory path to check.
175 Returns:
176 True if writable, False otherwise.
178 """
181# CLI-specific data structures
182@dataclass(frozen=True)
183class CLIContext:
184 """Context information for CLI operations."""
186 command_name: str
187 arguments: dict[str, str | int | bool]
188 working_directory: str
189 user_config: dict[str, str]
190 debug_mode: bool
193@dataclass(frozen=True)
194class ValidationResult:
195 """Result of argument validation."""
197 is_valid: bool
198 errors: list[str]
199 warnings: list[str]
200 normalized_values: dict[str, str | int | bool]
203@dataclass(frozen=True)
204class CLIResponse:
205 """Response from CLI operations."""
207 exit_code: int
208 message: str | None
209 error_details: dict[str, str] | None