hosts/memory-bank/systemPatterns.md

14 KiB

System Patterns: hosts

System Architecture

Layered Architecture

┌─────────────────────────────────────┐
│             TUI Layer               │  ← User Interface (Textual)
├─────────────────────────────────────┤
│           Manager Layer             │  ← Orchestration & Operations
├─────────────────────────────────────┤
│            Core Layer               │  ← Business Logic
├─────────────────────────────────────┤
│           System Layer              │  ← File I/O & DNS
└─────────────────────────────────────┘

Component Relationships

TUI Layer (src/hosts/main.py and src/hosts/tui/)

  • HostsManagerApp: Complete Textual application with reactive state management and DataTable interface
  • ConfigModal: Professional modal dialog for configuration management
  • Responsibilities: User interaction, display logic, event handling, navigation, configuration UI
  • Dependencies: Core models, parser, and config for data operations
  • Implementation: Two-pane layout with DataTable, modal system, and rich visual styling

Core Layer (src/hosts/core/)

  • models.py: Complete data structures (HostEntry, HostsFile) with validation and sorting
  • parser.py: Robust hosts file parsing, serialization, and file operations
  • config.py: Configuration management with JSON persistence and default handling
  • Responsibilities: Pure business logic, data validation, file integrity, settings management
  • Implementation: Comprehensive validation, error handling, and configuration persistence

System Layer (Implemented)

  • File I/O: Atomic file operations with backup support
  • Permission checking: Validation of file access permissions
  • 🔄 DNS Resolution: Planned for Phase 5 advanced features
  • 🔄 Permission Management: Sudo handling planned for Phase 3 edit mode

Key Technical Decisions

Data Model Design (Implemented)

@dataclass
class HostEntry:
    ip_address: str
    hostnames: list[str]
    comment: str | None = None
    is_active: bool = True
    dns_name: str | None = None  # For CNAME-like functionality
    
    # Implemented methods:
    def to_hosts_line(self) -> str
    @classmethod
    def from_hosts_line(cls, line: str) -> "HostEntry | None"
    def __post_init__(self) -> None  # Validation
    
@dataclass
class HostsFile:
    entries: list[HostEntry] = field(default_factory=list)
    header_comments: list[str] = field(default_factory=list)
    footer_comments: list[str] = field(default_factory=list)
    
    # Implemented methods:
    def add_entry(self, entry: HostEntry) -> None
    def remove_entry(self, index: int) -> None
    def toggle_entry(self, index: int) -> None
    def get_active_entries(self) -> list[HostEntry]
    def get_inactive_entries(self) -> list[HostEntry]
    def sort_by_ip(self) -> None
    def sort_by_hostname(self) -> None
    def find_entries_by_hostname(self, hostname: str) -> list[HostEntry]
    def find_entries_by_ip(self, ip: str) -> list[HostEntry]

# Configuration Management (Implemented)
class Config:
    def __init__(self):
        self.config_dir = Path.home() / ".config" / "hosts-manager"
        self.config_file = self.config_dir / "config.json"
        self._settings = self._load_default_settings()
    
    # Implemented methods:
    def load(self) -> None
    def save(self) -> None
    def get(self, key: str, default: Any = None) -> Any
    def set(self, key: str, value: Any) -> None
    def is_default_entry(self, ip_address: str, hostname: str) -> bool
    def should_show_default_entries(self) -> bool
    def toggle_show_default_entries(self) -> None

State Management (Implemented)

  • Reactive state: Using Textual's reactive attributes for complex UI updates
  • Configuration state: Persistent settings with JSON storage and graceful error handling
  • Sorting state: Reactive sort column and direction with visual indicators
  • Validation pipeline: All data validated in models, parser, and configuration
  • File integrity: Atomic operations preserve file structure
  • Error handling: Graceful degradation for all error conditions
  • Modal state: Professional modal dialog lifecycle management
  • 🔄 Undo/Redo capability: Planned for Phase 4 with command pattern
  • 🔄 Dirty state tracking: Will be implemented in Phase 3 edit mode

Permission Model (Planned for Phase 3)

# Current implementation (read-only mode)
class HostsManagerApp:
    edit_mode: reactive[bool] = reactive(False)  # Always False in Phase 1
    
    def update_status(self):
        mode = "Edit mode" if self.edit_mode else "Read-only mode"
        # Status bar shows current mode

# Planned for Phase 3:
class PermissionManager:
    def __init__(self):
        self.edit_mode = False
        self.sudo_acquired = False
    
    def enter_edit_mode(self) -> bool:
        # Request sudo permissions
        # Set edit_mode = True only if successful
    
    def exit_edit_mode(self):
        # Release sudo permissions
        # Set edit_mode = False

Design Patterns in Use

Reactive Pattern (Implemented)

class HostsManagerApp(App):
    # Reactive attributes automatically update UI
    hosts_file: reactive[HostsFile] = reactive(HostsFile())
    selected_entry_index: reactive[int] = reactive(0)
    edit_mode: reactive[bool] = reactive(False)
    sort_column: reactive[str] = reactive("")  # "ip" or "hostname"
    sort_ascending: reactive[bool] = reactive(True)
    
    def on_data_table_row_highlighted(self, event):
        # Automatic UI updates when selection changes
        self.selected_entry_index = event.cursor_row
        self.update_entry_details()
    
    def on_data_table_header_selected(self, event):
        # Interactive column sorting
        if "IP Address" in str(event.column_key):
            self.action_sort_by_ip()
        elif "Canonical Hostname" in str(event.column_key):
            self.action_sort_by_hostname()

Data Validation Pattern (Implemented)

@dataclass
class HostEntry:
    def __post_init__(self):
        # Comprehensive validation on creation
        if not self.ip_address or not self.hostnames:
            raise ValueError("IP address and hostnames required")
        
        # Validate IP address format
        try:
            ipaddress.ip_address(self.ip_address)
        except ValueError as e:
            raise ValueError(f"Invalid IP address: {e}")

Command Pattern (Planned for Phase 4)

# Will be implemented for undo/redo functionality
class Command(ABC):
    @abstractmethod
    def execute(self) -> HostsFile:
        pass
    
    @abstractmethod
    def undo(self) -> HostsFile:
        pass

Factory Pattern (Implemented)

class HostsParser:
    def __init__(self, file_path: str = "/etc/hosts"):
        # Single parser handles all hosts file formats
        self.file_path = file_path

# Configuration Factory Pattern (Implemented)
class Config:
    def _load_default_settings(self) -> Dict[str, Any]:
        # Factory method for default configuration
        return {
            "show_default_entries": False,
            "default_entries": [
                {"ip": "127.0.0.1", "hostname": "localhost"},
                {"ip": "255.255.255.255", "hostname": "broadcasthost"},
                {"ip": "::1", "hostname": "localhost"},
            ],
            "window_settings": {
                "last_sort_column": "",
                "last_sort_ascending": True,
            }
        }

Modal Pattern (Implemented)

class ConfigModal(ModalScreen):
    def __init__(self, config: Config):
        super().__init__()
        self.config = config
    
    def action_save(self) -> None:
        # Save configuration and close modal
        checkbox = self.query_one("#show-defaults-checkbox", Checkbox)
        self.config.set("show_default_entries", checkbox.value)
        self.config.save()
        self.dismiss(True)
    
    def action_cancel(self) -> None:
        # Cancel changes and close modal
        self.dismiss(False)

Critical Implementation Paths

Application Startup ( Implemented)

  1. Initialize TUI: Textual app with reactive state management and configuration loading
  2. Load configuration: JSON settings with graceful error handling and defaults
  3. Load hosts file: Robust parsing with error handling and filtering
  4. Build UI: Two-pane layout with DataTable, details, and modal system
  5. Enter main loop: Smooth keyboard navigation, sorting, and event handling
  6. Error handling: Graceful degradation for file access and configuration issues

Entry Navigation ( Implemented)

  1. DataTable navigation: Professional table with cursor and selection tracking
  2. Keyboard navigation: Up/down arrows, header clicking, and keyboard shortcuts
  3. Selection tracking: Reactive updates to selected_entry_index with DataTable events
  4. Detail updates: Automatic refresh of right pane details with rich formatting
  5. Position restoration: Maintains cursor position on reload with intelligent matching
  6. Visual feedback: Color-coded entries with clear active/inactive indication

File Operations ( Implemented)

  1. File parsing: Comprehensive hosts file format support with edge case handling
  2. Comment preservation: Maintains all comments and formatting perfectly
  3. Error handling: Graceful handling of permission, format, and configuration errors
  4. Validation: Complete IP address and hostname validation with user feedback
  5. Status feedback: Rich status bar with detailed information and operation feedback
  6. Configuration integration: Settings-aware parsing and display

Configuration Management ( Implemented)

  1. Settings loading: JSON configuration with graceful error handling
  2. Default management: Intelligent default entry detection and filtering
  3. Modal interface: Professional configuration dialog with keyboard bindings
  4. Persistence: Automatic saving to ~/.config/hosts-manager/ directory
  5. Live updates: Immediate application of configuration changes
  6. Error recovery: Fallback to defaults on configuration errors

Sorting and Filtering ( Implemented)

  1. Interactive sorting: Click column headers to sort by IP or hostname
  2. Sort direction toggle: Ascending/descending with visual indicators
  3. Keyboard shortcuts: Sort by IP (i) and hostname (n) keys
  4. Visual feedback: Sort arrows in column headers showing current state
  5. Default entry filtering: Hide/show system entries based on configuration
  6. Intelligent IP sorting: Proper IPv4/IPv6 numerical sorting

Edit Mode Activation (🔄 Planned for Phase 3)

  1. 🔄 User triggers edit mode: Keyboard shortcut implementation
  2. 🔄 Request sudo: Secure password prompt
  3. 🔄 Validate permissions: Ensure write access to /etc/hosts
  4. 🔄 Update UI state: Enable edit operations and visual indicators
  5. 🔄 Maintain permissions: Keep sudo active until explicit exit

Entry Modification (🔄 Planned for Phase 3-4)

  1. 🔄 User action: Toggle, reorder, or edit entry operations
  2. 🔄 Create command: Command pattern for undo/redo support
  3. 🔄 Validate operation: Real-time validation of changes
  4. 🔄 Execute command: Apply changes to in-memory state
  5. 🔄 Update UI: Immediate visual feedback
  6. 🔄 Track dirty state: Mark file as needing save

File Persistence (🔄 Planned for Phase 3)

  1. 🔄 User saves: Explicit save command or auto-save option
  2. 🔄 Validate entire file: Comprehensive syntax checking
  3. 🔄 Create backup: Automatic backup before modifications
  4. 🔄 Write atomically: Safe temporary file + rename operation
  5. 🔄 Verify write: Confirm successful file write

DNS Resolution Flow (🔄 Planned for Phase 5)

  1. 🔄 User requests resolution: For entries with DNS names
  2. 🔄 Resolve hostname: Async DNS resolution
  3. 🔄 Compare IPs: Current IP vs resolved IP comparison
  4. 🔄 Present choice: User dialog for IP selection
  5. 🔄 Update entry: Apply user's choice with validation
  6. 🔄 Mark dirty: Flag file for saving

Error Handling Patterns

Graceful Degradation

  • Permission denied: Fall back to read-only mode with clear status indication
  • Configuration errors: Use defaults and continue with warning
  • File corruption: Load what's possible, warn user, maintain functionality
  • DNS resolution failure: Show error but continue (planned for Phase 5)
  • Network unavailable: Disable DNS features (planned for Phase 5)

User Feedback

  • Rich status bar: Show current mode, entry counts, file path, and operation status
  • Modal dialogs: Professional configuration interface with proper keyboard handling
  • Color-coded entries: Visual distinction between active/inactive entries
  • Sort indicators: Visual arrows showing current sort column and direction
  • Interactive headers: Click feedback and hover states for column sorting
  • Progress indicators: For long-running operations (planned for Phase 3)

Recovery Mechanisms

  • Configuration fallback: Automatic fallback to defaults on configuration errors
  • Position restoration: Intelligent cursor position maintenance on reload
  • Error isolation: Configuration errors don't affect core functionality
  • Undo operations: Allow reverting recent changes (planned for Phase 4)
  • File restoration: Restore from backup if available (planned for Phase 3)
  • Safe mode: Minimal functionality if errors occur
  • Graceful exit: Always attempt to save valid changes and configuration