From 40a1e6794938ea632e8d00b050746b80ebe3e916 Mon Sep 17 00:00:00 2001 From: phg Date: Tue, 29 Jul 2025 13:50:55 +0200 Subject: [PATCH] initial commit --- .clinerules | 115 +++++++++++++++++++++ .python-version | 1 + README.md | 0 main.py | 6 ++ memory-bank/activeContext.md | 135 +++++++++++++++++++++++++ memory-bank/productContext.md | 68 +++++++++++++ memory-bank/progress.md | 133 ++++++++++++++++++++++++ memory-bank/projectbrief.md | 83 +++++++++++++++ memory-bank/systemPatterns.md | 183 ++++++++++++++++++++++++++++++++++ memory-bank/techContext.md | 110 ++++++++++++++++++++ pyproject.toml | 9 ++ uv.lock | 39 ++++++++ 12 files changed, 882 insertions(+) create mode 100644 .clinerules create mode 100644 .python-version create mode 100644 README.md create mode 100644 main.py create mode 100644 memory-bank/activeContext.md create mode 100644 memory-bank/productContext.md create mode 100644 memory-bank/progress.md create mode 100644 memory-bank/projectbrief.md create mode 100644 memory-bank/systemPatterns.md create mode 100644 memory-bank/techContext.md create mode 100644 pyproject.toml create mode 100644 uv.lock diff --git a/.clinerules b/.clinerules new file mode 100644 index 0000000..e6be63d --- /dev/null +++ b/.clinerules @@ -0,0 +1,115 @@ +# Cline's Memory Bank + +I am Cline, an expert software engineer with a unique characteristic: my memory resets completely between sessions. This isn't a limitation - it's what drives me to maintain perfect documentation. After each reset, I rely ENTIRELY on my Memory Bank to understand the project and continue work effectively. I MUST read ALL memory bank files at the start of EVERY task - this is not optional. + +## Memory Bank Structure + +The Memory Bank consists of core files and optional context files, all in Markdown format. Files build upon each other in a clear hierarchy: + +flowchart TD + PB[projectbrief.md] --> PC[productContext.md] + PB --> SP[systemPatterns.md] + PB --> TC[techContext.md] + + PC --> AC[activeContext.md] + SP --> AC + TC --> AC + + AC --> P[progress.md] + +### Core Files (Required) +1. `projectbrief.md` + - Foundation document that shapes all other files + - Created at project start if it doesn't exist + - Defines core requirements and goals + - Source of truth for project scope + +2. `productContext.md` + - Why this project exists + - Problems it solves + - How it should work + - User experience goals + +3. `activeContext.md` + - Current work focus + - Recent changes + - Next steps + - Active decisions and considerations + - Important patterns and preferences + - Learnings and project insights + +4. `systemPatterns.md` + - System architecture + - Key technical decisions + - Design patterns in use + - Component relationships + - Critical implementation paths + +5. `techContext.md` + - Technologies used + - Development setup + - Technical constraints + - Dependencies + - Tool usage patterns + +6. `progress.md` + - What works + - What's left to build + - Current status + - Known issues + - Evolution of project decisions + +### Additional Context +Create additional files/folders within memory-bank/ when they help organize: +- Complex feature documentation +- Integration specifications +- API documentation +- Testing strategies +- Deployment procedures + +## Core Workflows + +### Plan Mode +flowchart TD + Start[Start] --> ReadFiles[Read Memory Bank] + ReadFiles --> CheckFiles{Files Complete?} + + CheckFiles -->|No| Plan[Create Plan] + Plan --> Document[Document in Chat] + + CheckFiles -->|Yes| Verify[Verify Context] + Verify --> Strategy[Develop Strategy] + Strategy --> Present[Present Approach] + +### Act Mode +flowchart TD + Start[Start] --> Context[Check Memory Bank] + Context --> Update[Update Documentation] + Update --> Execute[Execute Task] + Execute --> Document[Document Changes] + +## Documentation Updates + +Memory Bank updates occur when: +1. Discovering new project patterns +2. After implementing significant changes +3. When user requests with **update memory bank** (MUST review ALL files) +4. When context needs clarification + +flowchart TD + Start[Update Process] + + subgraph Process + P1[Review ALL Files] + P2[Document Current State] + P3[Clarify Next Steps] + P4[Document Insights & Patterns] + + P1 --> P2 --> P3 --> P4 + end + + Start --> Process + +Note: When triggered by **update memory bank**, I MUST review every memory bank file, even if some don't require updates. Focus particularly on activeContext.md and progress.md as they track current state. + +REMEMBER: After every memory reset, I begin completely fresh. The Memory Bank is my only link to previous work. It must be maintained with precision and clarity, as my effectiveness depends entirely on its accuracy. \ No newline at end of file diff --git a/.python-version b/.python-version new file mode 100644 index 0000000..24ee5b1 --- /dev/null +++ b/.python-version @@ -0,0 +1 @@ +3.13 diff --git a/README.md b/README.md new file mode 100644 index 0000000..e69de29 diff --git a/main.py b/main.py new file mode 100644 index 0000000..12a0b01 --- /dev/null +++ b/main.py @@ -0,0 +1,6 @@ +def main(): + print("Hello from hosts!") + + +if __name__ == "__main__": + main() diff --git a/memory-bank/activeContext.md b/memory-bank/activeContext.md new file mode 100644 index 0000000..380a08d --- /dev/null +++ b/memory-bank/activeContext.md @@ -0,0 +1,135 @@ +# Active Context: hosts + +## Current Work Focus + +**Project Initialization Phase**: Setting up the foundational structure for the hosts TUI application. The project is in its earliest stage with basic uv configuration and placeholder code. + +## Recent Changes + +### Memory Bank Initialization +- Created complete memory bank structure with all core files +- Documented project vision, technical context, and system architecture +- Established clear patterns and design decisions for implementation + +### Current Project State +- Basic uv project with Python 3.13 requirement +- Minimal `main.py` with placeholder "Hello from hosts!" message +- ruff configured as the only dependency +- Project structure planned but not yet implemented + +## Next Steps + +### Immediate Priorities (Phase 1) +1. **Set up proper project structure**: + - Create `src/hosts/` package directory + - Move main.py to proper location + - Add `__init__.py` files + +2. **Add core dependencies**: + - Add textual for TUI framework + - Add pytest for testing + - Configure project entry point in pyproject.toml + +3. **Implement basic data models**: + - Create `src/hosts/core/models.py` with HostEntry and HostsFile classes + - Implement basic validation logic + - Add type hints and docstrings + +4. **Create hosts file parser**: + - Implement `src/hosts/core/parser.py` + - Handle comments, active/inactive entries + - Parse existing `/etc/hosts` format + +### Phase 2 Priorities +1. **Basic TUI implementation**: + - Create main application class + - Implement two-pane layout + - Add entry list view + +2. **Read-only functionality**: + - Load and display hosts file + - Navigate between entries + - Show entry details + +3. **Testing foundation**: + - Set up pytest configuration + - Create test fixtures for sample hosts files + - Implement parser tests + +## Active Decisions and Considerations + +### Architecture Decisions Made +- **Layered architecture**: TUI → Manager → Core → System layers +- **Command pattern**: For undo/redo functionality +- **Immutable state**: All operations return new state +- **Permission model**: Explicit edit mode with sudo management + +### Design Patterns Chosen +- **Observer pattern**: For state change notifications +- **Factory pattern**: For parser creation +- **Command pattern**: For operations with undo capability + +### Technical Constraints Acknowledged +- **Python 3.13+**: Using modern Python features +- **Unix-like systems**: Primary target (Linux, macOS) +- **Root access**: Required for `/etc/hosts` modifications +- **File integrity**: Must preserve existing structure + +## Important Patterns and Preferences + +### Code Organization +- **Separation of concerns**: Clear layer boundaries +- **Type safety**: Comprehensive type hints +- **Documentation**: Docstrings for all public APIs +- **Testing**: TDD approach with high coverage + +### User Experience Priorities +- **Safety first**: Read-only by default, explicit edit mode +- **Keyboard-driven**: Efficient navigation without mouse +- **Visual clarity**: Clear active/inactive indicators +- **Error prevention**: Validation before any file writes + +### Development Workflow +- **uv for everything**: Package management and execution +- **ruff for quality**: Linting and formatting +- **pytest for testing**: Comprehensive test coverage +- **Incremental development**: Build and test each component + +## Learnings and Project Insights + +### Key Insights from Planning +1. **Permission management is critical**: The sudo handling needs careful design +2. **File integrity is paramount**: Users trust their hosts file +3. **DNS integration adds complexity**: But provides significant value +4. **TUI responsiveness matters**: No blocking operations in UI thread + +### Risk Areas Identified +- **Permission escalation**: Security implications of sudo usage +- **File corruption**: Atomic writes and validation essential +- **Cross-platform compatibility**: Different hosts file locations +- **Large file performance**: Memory usage with many entries + +### Success Factors +- **Clear separation of read/write modes**: Reduces accidental changes +- **Comprehensive validation**: Prevents invalid configurations +- **Intuitive keyboard shortcuts**: Faster than manual editing +- **Visual feedback**: Users always know current state + +## Current Development Environment + +### Tools Ready +- **uv**: Package manager configured +- **ruff**: Code quality tool available +- **Python 3.13**: Runtime environment set + +### Next Tool Additions Needed +- **textual**: TUI framework (primary dependency) +- **pytest**: Testing framework +- **textual.testing**: TUI testing utilities + +### Project Structure Status +- **Current**: Flat structure with main.py +- **Target**: Proper package structure in src/hosts/ +- **Migration needed**: Move and reorganize files + +This active context represents the current state as we begin actual implementation of the hosts TUI application. diff --git a/memory-bank/productContext.md b/memory-bank/productContext.md new file mode 100644 index 0000000..9d7f380 --- /dev/null +++ b/memory-bank/productContext.md @@ -0,0 +1,68 @@ +# Product Context: hosts + +## Why This Project Exists + +Managing the `/etc/hosts` file is a common task for developers, system administrators, and power users, but it's traditionally done through manual text editing. This approach has several pain points: + +- **Error-prone**: Manual editing can introduce syntax errors or accidentally break existing entries +- **Inefficient**: No quick way to activate/deactivate entries for testing different configurations +- **Poor organization**: Large hosts files become difficult to navigate and maintain +- **No validation**: Easy to introduce invalid IP addresses or malformed entries +- **Limited functionality**: No built-in DNS resolution or IP comparison features + +## Problems It Solves + +1. **Safe Editing**: Provides validation and structured editing to prevent hosts file corruption +2. **Quick Testing**: Easy activation/deactivation of entries for testing different network configurations +3. **Organization**: Visual interface for sorting, reordering, and categorizing entries +4. **DNS Integration**: Automatic IP resolution and comparison for CNAME-like functionality +5. **User Experience**: Modern TUI interface that's faster and more intuitive than text editing + +## How It Should Work + +### Core User Experience +- **Two-pane interface**: Left pane shows all entries, right pane shows details of selected entry +- **Visual indicators**: Clear distinction between active/inactive entries +- **Keyboard-driven**: Efficient navigation and editing without mouse dependency +- **Safe operations**: All changes validated before writing to system files + +### Key Workflows + +1. **Viewing Mode (Default)**: + - Read-only access to `/etc/hosts` + - Browse and inspect entries safely + - No system permissions required + +2. **Edit Mode**: + - Activated explicitly by user + - Requests sudo permissions when enabled + - Maintains permissions until edit mode is exited + - All modification operations available + +3. **Entry Management**: + - Toggle entries active/inactive with simple keypress + - Reorder entries by dragging or keyboard shortcuts + - Sort by IP address, hostname, or comments + - Add/edit comments for documentation + +4. **DNS Operations**: + - Store DNS names alongside IP addresses + - Resolve DNS names to current IP addresses + - Compare resolved IPs with stored IPs + - User choice when IPs differ + +## User Experience Goals + +- **Immediate productivity**: Users should be able to accomplish common tasks within seconds +- **Error prevention**: Interface should make it difficult to create invalid configurations +- **Confidence**: Users should feel safe making changes without fear of breaking their system +- **Efficiency**: Common operations should require minimal keystrokes +- **Clarity**: Current state and available actions should always be obvious +- **Flexibility**: Support both quick edits and complex reorganization tasks + +## Success Metrics + +- Users can activate/deactivate entries faster than manual editing +- Zero corrupted hosts files due to application usage +- Users prefer the TUI over manual editing for hosts management +- DNS resolution features save time in dynamic IP environments diff --git a/memory-bank/progress.md b/memory-bank/progress.md new file mode 100644 index 0000000..61a8718 --- /dev/null +++ b/memory-bank/progress.md @@ -0,0 +1,133 @@ +# Progress: hosts + +## What Works + +### Project Foundation +- ✅ **uv project initialized**: Basic Python 3.13 project with uv configuration +- ✅ **Code quality setup**: ruff configured for linting and formatting +- ✅ **Memory bank complete**: All core documentation files created and populated +- ✅ **Architecture defined**: Clear layered architecture and design patterns established + +### Documentation +- ✅ **Project brief**: Comprehensive project definition and requirements +- ✅ **Product context**: User experience goals and problem definition +- ✅ **Technical context**: Technology stack and development setup +- ✅ **System patterns**: Architecture, design patterns, and implementation paths +- ✅ **Active context**: Current work focus and next steps + +## What's Left to Build + +### Phase 1: Foundation (Immediate) +- ❌ **Project structure**: Create proper `src/hosts/` package structure +- ❌ **Dependencies**: Add textual, pytest, and other required packages +- ❌ **Entry point**: Configure proper application entry point in pyproject.toml +- ❌ **Core models**: Implement HostEntry and HostsFile data classes +- ❌ **Hosts parser**: Create parser for reading/writing `/etc/hosts` files + +### Phase 2: Core Functionality +- ❌ **Basic TUI**: Implement main application with two-pane layout +- ❌ **File loading**: Read and parse existing hosts file +- ❌ **Entry display**: Show hosts entries in left pane +- ❌ **Detail view**: Show selected entry details in right pane +- ❌ **Navigation**: Keyboard navigation between entries + +### Phase 3: Read-Only Features +- ❌ **Entry selection**: Highlight and select entries +- ❌ **Sorting**: Sort entries by IP, hostname, or comments +- ❌ **Filtering**: Filter entries by active/inactive status +- ❌ **Search**: Find entries by hostname or IP + +### Phase 4: Edit Mode +- ❌ **Permission management**: Sudo request and management +- ❌ **Edit mode toggle**: Switch between read-only and edit modes +- ❌ **Entry activation**: Toggle entries active/inactive +- ❌ **Entry reordering**: Move entries up/down in the list +- ❌ **Entry editing**: Modify IP addresses, hostnames, comments + +### Phase 5: Advanced Features +- ❌ **DNS resolution**: Resolve hostnames to IP addresses +- ❌ **IP comparison**: Compare stored vs resolved IPs +- ❌ **CNAME support**: Store DNS names alongside IP addresses +- ❌ **Undo/Redo**: Command pattern implementation +- ❌ **File validation**: Comprehensive validation before saving + +### Phase 6: Polish +- ❌ **Error handling**: Graceful error handling and user feedback +- ❌ **Help system**: In-app help and keyboard shortcuts +- ❌ **Configuration**: User preferences and settings +- ❌ **Performance**: Optimization for large hosts files + +## Current Status + +### Development Stage +**Stage**: Project Initialization +**Progress**: 10% (Foundation documentation complete) +**Next Milestone**: Basic project structure and dependencies + +### Immediate Blockers +1. **Project structure**: Need to create proper package layout +2. **Dependencies**: Must add textual framework to begin TUI development +3. **Entry point**: Configure uv to run the application properly + +### Recent Accomplishments +- Completed comprehensive project planning and documentation +- Established clear architecture and design patterns +- Created memory bank system for project continuity +- Defined development phases and priorities + +## Known Issues + +### Current Limitations +- **Placeholder implementation**: main.py only prints hello message +- **Missing dependencies**: Core frameworks not yet added +- **No package structure**: Files not organized in proper Python package +- **No tests**: Testing framework not yet configured + +### Technical Debt +- **Temporary main.py**: Needs to be moved to proper location +- **Missing type hints**: Will need comprehensive typing +- **No error handling**: Basic error handling patterns needed +- **No logging**: Logging system not yet implemented + +## Evolution of Project Decisions + +### Initial Decisions (Current) +- **Python 3.13**: Chosen for modern features and performance +- **Textual**: Selected for rich TUI capabilities +- **uv**: Adopted for fast package management +- **ruff**: Chosen for code quality and speed + +### Architecture Evolution +- **Layered approach**: Decided on clear separation of concerns +- **Command pattern**: Chosen for undo/redo functionality +- **Immutable state**: Selected for predictable state management +- **Permission model**: Explicit edit mode for safety + +### Design Considerations +- **Safety first**: Read-only default mode prioritized +- **User experience**: Keyboard-driven interface emphasized +- **File integrity**: Atomic operations and validation required +- **Performance**: Responsive UI for large files planned + +## Success Metrics Progress + +### Completed Metrics +- ✅ **Project documentation**: Comprehensive planning complete +- ✅ **Architecture clarity**: Clear technical direction established +- ✅ **Development setup**: Basic environment ready + +### Pending Metrics +- ❌ **Functional prototype**: Basic TUI not yet implemented +- ❌ **File parsing**: Hosts file reading not yet working +- ❌ **User testing**: No user interface to test yet +- ❌ **Performance benchmarks**: No code to benchmark yet + +## Next Session Priorities + +1. **Create project structure**: Set up src/hosts/ package layout +2. **Add dependencies**: Install textual and pytest +3. **Implement data models**: Create HostEntry and HostsFile classes +4. **Basic parser**: Read and parse simple hosts file format +5. **Minimal TUI**: Create basic application shell + +The project is well-planned and ready for implementation to begin. diff --git a/memory-bank/projectbrief.md b/memory-bank/projectbrief.md new file mode 100644 index 0000000..232ab6f --- /dev/null +++ b/memory-bank/projectbrief.md @@ -0,0 +1,83 @@ +# Project Brief: hosts + +## Foundation of the Project + +The **hosts** project is a Python-based terminal application designed to manage the system `/etc/hosts` file with a modern, user-friendly Text User Interface (TUI). The goal is to simplify the manipulation, organization, and updating of hostname entries directly from the terminal without manual text editing. + +## High-Level Overview + +The application provides a two-pane TUI: + +- **Left pane:** List of all hostname entries. +- **Right pane:** Detailed view of the selected entry. +The user can easily activate/deactivate entries, reorder them, sort by different attributes, and maintain comments. It also supports CNAME-like functionality by allowing DNS-based IP resolution and quick IP updates. + +The project uses: + +- **Python** for development +- **Textual** as the TUI framework +- **uv** for Python runtime management and execution +- **ruff** for linting and formatting, ensuring clean and consistent code + +## Core Requirements & Goals + +- Display all `/etc/hosts` entries in a two-pane TUI. +- Activate or deactivate specific hostname entries. +- Reorder hostname entries manually. +- Sort entries by target or destination. +- Add and edit comments for entries. +- Support CNAME-style DNS name storage and automatic IP address resolution. +- Compare resolved IP addresses and let the user choose which one to keep. +- Validate all changes before writing to `/etc/hosts`. +- Provide an intuitive, efficient terminal experience for managing hosts without manually editing text. +- The user must enable edit mode, before only viewing of `/etc/hosts` is allowed. When edit mode is enabled ask for sudo permissions, keep the permissions until the edit mode is exited. + +## Example One-Line Summary + +**“Building a Python-based TUI app for managing `/etc/hosts` entries with sorting, DNS resolution, and quick activation/deactivation using uv and ruff.”** + +## Directory structure + +hosts/ +├── pyproject.toml # Project file, uv managed +├── README.md +├── src/ +│ └── hosts/ +│ ├── init.py +│ ├── main.py # Entry point (uv run hosts) +│ ├── tui/ # UI components (Textual) +│ │ ├── init.py +│ │ └── views.py +│ ├── core/ # Business logic +│ │ ├── init.py +│ │ ├── parser.py # /etc/hosts parsing & writing +│ │ ├── models.py # Data models (Entry, Comment, etc.) +│ │ ├── dns.py # DNS resolution & comparison +│ │ └── manager.py # Core operations (activate, sort, reorder) +│ └── utils.py +└── tests/ +├── init.py +├── test_parser.py +├── test_manager.py +├── test_dns.py +└── test_tui.py + +## Testing Strategy (TDD) + +### Approach + +- Write unit tests **before** implementing each feature. +- Use **pytest** as the testing framework. +- Ensure full coverage for critical modules (`parser`, `dns`, `manager`). +- Mock `/etc/hosts` file I/O and DNS lookups to avoid system dependencies. +- Include integration tests for the Textual TUI (using `textual.testing` or snapshot testing). + +### Example Tests to Start With (MVP) + +1. **Parsing Tests**: + - Parse simple `/etc/hosts` with comments and disabled entries. + - Ensure writing back preserves file integrity. +2. **Activation/Deactivation Tests**: + - Toggle entries and validate updated state. +3. **TUI Rendering Tests**: + - Ensure initial layout shows entries correctly. diff --git a/memory-bank/systemPatterns.md b/memory-bank/systemPatterns.md new file mode 100644 index 0000000..34b4fde --- /dev/null +++ b/memory-bank/systemPatterns.md @@ -0,0 +1,183 @@ +# 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/tui/`) +- **views.py**: Main application views and widgets +- **Responsibilities**: User interaction, display logic, event handling +- **Dependencies**: Manager layer for operations + +#### Manager Layer (`src/hosts/core/manager.py`) +- **Responsibilities**: Coordinate operations, maintain application state +- **Dependencies**: Core models, parser, DNS resolver +- **Patterns**: Command pattern for operations, Observer for state changes + +#### Core Layer (`src/hosts/core/`) +- **models.py**: Data structures (Entry, Comment, HostsFile) +- **parser.py**: Hosts file parsing and serialization +- **dns.py**: DNS resolution and IP comparison +- **Responsibilities**: Pure business logic, no I/O dependencies + +#### System Layer +- **File I/O**: Direct `/etc/hosts` file operations +- **DNS Resolution**: Network calls for hostname resolution +- **Permission Management**: Sudo privilege handling + +## Key Technical Decisions + +### Data Model Design +```python +@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 + +@dataclass +class HostsFile: + entries: list[HostEntry] + header_comments: list[str] + footer_comments: list[str] +``` + +### State Management +- **Immutable operations**: All modifications return new state +- **Validation pipeline**: Every change goes through validation +- **Undo/Redo capability**: Maintain operation history +- **Dirty state tracking**: Know when changes need saving + +### Permission Model +```python +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 + +### Command Pattern +```python +class Command(ABC): + @abstractmethod + def execute(self) -> HostsFile: + pass + + @abstractmethod + def undo(self) -> HostsFile: + pass + +class ToggleEntryCommand(Command): + def __init__(self, entry_index: int): + self.entry_index = entry_index + + def execute(self, hosts_file: HostsFile) -> HostsFile: + # Toggle entry active state + + def undo(self, hosts_file: HostsFile) -> HostsFile: + # Reverse the toggle +``` + +### Observer Pattern +```python +class HostsManager: + def __init__(self): + self.observers: list[Observer] = [] + self.state: HostsFile = HostsFile() + + def notify_observers(self, event: StateChangeEvent): + for observer in self.observers: + observer.on_state_change(event) +``` + +### Factory Pattern +```python +class ParserFactory: + @staticmethod + def create_parser(file_path: str) -> HostsParser: + # Return appropriate parser based on file format + return StandardHostsParser(file_path) +``` + +## Critical Implementation Paths + +### Application Startup +1. **Initialize TUI**: Create Textual app instance +2. **Load hosts file**: Parse `/etc/hosts` in read-only mode +3. **Build UI**: Populate left pane with entries +4. **Enter main loop**: Handle user input and events + +### Edit Mode Activation +1. **User triggers edit mode**: Keyboard shortcut or menu +2. **Request sudo**: Prompt for password if needed +3. **Validate permissions**: Ensure write access to `/etc/hosts` +4. **Update UI state**: Enable edit operations +5. **Maintain permissions**: Keep sudo active until exit + +### Entry Modification +1. **User action**: Toggle, reorder, or edit entry +2. **Create command**: Instantiate appropriate command object +3. **Validate operation**: Check if change is valid +4. **Execute command**: Apply change to in-memory state +5. **Update UI**: Refresh display to show changes +6. **Track dirty state**: Mark file as needing save + +### File Persistence +1. **User saves**: Explicit save command or auto-save +2. **Validate entire file**: Ensure no syntax errors +3. **Create backup**: Optional backup of original file +4. **Write atomically**: Use temporary file + rename +5. **Verify write**: Confirm file was written correctly + +### DNS Resolution Flow +1. **User requests resolution**: For entry with DNS name +2. **Resolve hostname**: Use socket.gethostbyname() +3. **Compare IPs**: Current IP vs resolved IP +4. **Present choice**: Show user both options +5. **Update entry**: Apply user's choice +6. **Mark dirty**: Flag file for saving + +## Error Handling Patterns + +### Graceful Degradation +- **Permission denied**: Fall back to read-only mode +- **DNS resolution failure**: Show error but continue +- **File corruption**: Load what's possible, warn user +- **Network unavailable**: Disable DNS features + +### User Feedback +- **Status bar**: Show current mode and operation status +- **Modal dialogs**: For errors requiring user attention +- **Inline validation**: Real-time feedback on input +- **Progress indicators**: For long-running operations + +### Recovery Mechanisms +- **Undo operations**: Allow reverting recent changes +- **File restoration**: Restore from backup if available +- **Safe mode**: Minimal functionality if errors occur +- **Graceful exit**: Always attempt to save valid changes diff --git a/memory-bank/techContext.md b/memory-bank/techContext.md new file mode 100644 index 0000000..1c65d84 --- /dev/null +++ b/memory-bank/techContext.md @@ -0,0 +1,110 @@ +# Technical Context: hosts + +## Technologies Used + +### Core Technologies +- **Python 3.13+**: Modern Python with latest features and performance improvements +- **Textual**: Rich TUI framework for building terminal applications with modern UI components +- **uv**: Fast Python package manager and runtime for dependency management and execution + +### Development Tools +- **ruff**: Lightning-fast Python linter and formatter for code quality +- **pytest**: Testing framework for comprehensive test coverage +- **textual.testing**: Built-in testing utilities for TUI components + +## Development Setup + +### Project Structure +``` +hosts/ +├── pyproject.toml # uv-managed project configuration +├── README.md +├── main.py # Current entry point (temporary) +├── src/hosts/ # Main package (planned) +│ ├── __init__.py +│ ├── main.py # Application entry point +│ ├── tui/ # UI components +│ ├── core/ # Business logic +│ └── utils.py +└── tests/ # Test suite +``` + +### Current State +- Basic uv project initialized with Python 3.13 +- Minimal main.py with placeholder implementation +- ruff configured as dependency for code quality +- Project structure planned but not yet implemented + +### Runtime Management +- **uv run hosts**: Planned command to execute the application +- **uv**: Handles all dependency management and virtual environment +- **Python 3.13**: Required minimum version for modern features + +## Technical Constraints + +### System Integration +- **Root access required**: Must handle `/etc/hosts` file modifications +- **Sudo permission management**: Request permissions only in edit mode +- **File integrity**: Must preserve existing hosts file structure and comments +- **Cross-platform compatibility**: Focus on Unix-like systems (Linux, macOS) + +### Performance Requirements +- **Fast startup**: TUI should load quickly even with large hosts files +- **Responsive UI**: No blocking operations in the main UI thread +- **Memory efficient**: Handle large hosts files without excessive memory usage + +### Security Considerations +- **Privilege escalation**: Only request sudo when entering edit mode +- **Input validation**: Validate all IP addresses and hostnames before writing +- **Backup strategy**: Consider creating backups before modifications +- **Permission dropping**: Release sudo permissions when exiting edit mode + +## Dependencies + +### Current Dependencies +```toml +[project] +requires-python = ">=3.13" +dependencies = [ + "ruff>=0.12.5", +] +``` + +### Planned Dependencies +- **textual**: TUI framework (to be added) +- **pytest**: Testing framework (to be added) +- **ipaddress**: Built-in Python module for IP validation +- **socket**: Built-in Python module for DNS resolution + +## Tool Usage Patterns + +### Development Workflow +1. **uv run**: Execute the application during development +2. **ruff check**: Lint code for style and potential issues +3. **ruff format**: Auto-format code to maintain consistency +4. **pytest**: Run test suite for validation +5. **uv add**: Add new dependencies as needed + +### Code Quality +- **ruff configuration**: Enforce consistent Python style +- **Type hints**: Use modern Python typing for better code clarity +- **Docstrings**: Document all public APIs and complex logic +- **Test coverage**: Aim for high coverage on core business logic + +## Architecture Decisions + +### Separation of Concerns +- **TUI layer**: Handle user interface and input/output +- **Core layer**: Business logic for hosts file management +- **Utils layer**: Shared utilities and helper functions + +### Error Handling +- **Graceful degradation**: Handle missing permissions or file access issues +- **User feedback**: Clear error messages in the TUI +- **Recovery mechanisms**: Allow users to retry failed operations + +### Testing Strategy +- **Unit tests**: Test core logic in isolation +- **Integration tests**: Test TUI components with mocked file system +- **Snapshot testing**: Verify TUI rendering consistency +- **Mock external dependencies**: DNS resolution and file I/O diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..eba40d4 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,9 @@ +[project] +name = "hosts" +version = "0.1.0" +description = "Add your description here" +readme = "README.md" +requires-python = ">=3.13" +dependencies = [ + "ruff>=0.12.5", +] diff --git a/uv.lock b/uv.lock new file mode 100644 index 0000000..fd7de66 --- /dev/null +++ b/uv.lock @@ -0,0 +1,39 @@ +version = 1 +revision = 2 +requires-python = ">=3.13" + +[[package]] +name = "hosts" +version = "0.1.0" +source = { virtual = "." } +dependencies = [ + { name = "ruff" }, +] + +[package.metadata] +requires-dist = [{ name = "ruff", specifier = ">=0.12.5" }] + +[[package]] +name = "ruff" +version = "0.12.5" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/30/cd/01015eb5034605fd98d829c5839ec2c6b4582b479707f7c1c2af861e8258/ruff-0.12.5.tar.gz", hash = "sha256:b209db6102b66f13625940b7f8c7d0f18e20039bb7f6101fbdac935c9612057e", size = 5170722, upload-time = "2025-07-24T13:26:37.456Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d4/de/ad2f68f0798ff15dd8c0bcc2889558970d9a685b3249565a937cd820ad34/ruff-0.12.5-py3-none-linux_armv6l.whl", hash = "sha256:1de2c887e9dec6cb31fcb9948299de5b2db38144e66403b9660c9548a67abd92", size = 11819133, upload-time = "2025-07-24T13:25:56.369Z" }, + { url = "https://files.pythonhosted.org/packages/f8/fc/c6b65cd0e7fbe60f17e7ad619dca796aa49fbca34bb9bea5f8faf1ec2643/ruff-0.12.5-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:d1ab65e7d8152f519e7dea4de892317c9da7a108da1c56b6a3c1d5e7cf4c5e9a", size = 12501114, upload-time = "2025-07-24T13:25:59.471Z" }, + { url = "https://files.pythonhosted.org/packages/c5/de/c6bec1dce5ead9f9e6a946ea15e8d698c35f19edc508289d70a577921b30/ruff-0.12.5-py3-none-macosx_11_0_arm64.whl", hash = "sha256:962775ed5b27c7aa3fdc0d8f4d4433deae7659ef99ea20f783d666e77338b8cf", size = 11716873, upload-time = "2025-07-24T13:26:01.496Z" }, + { url = "https://files.pythonhosted.org/packages/a1/16/cf372d2ebe91e4eb5b82a2275c3acfa879e0566a7ac94d331ea37b765ac8/ruff-0.12.5-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:73b4cae449597e7195a49eb1cdca89fd9fbb16140c7579899e87f4c85bf82f73", size = 11958829, upload-time = "2025-07-24T13:26:03.721Z" }, + { url = "https://files.pythonhosted.org/packages/25/bf/cd07e8f6a3a6ec746c62556b4c4b79eeb9b0328b362bb8431b7b8afd3856/ruff-0.12.5-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8b13489c3dc50de5e2d40110c0cce371e00186b880842e245186ca862bf9a1ac", size = 11626619, upload-time = "2025-07-24T13:26:06.118Z" }, + { url = "https://files.pythonhosted.org/packages/d8/c9/c2ccb3b8cbb5661ffda6925f81a13edbb786e623876141b04919d1128370/ruff-0.12.5-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f1504fea81461cf4841778b3ef0a078757602a3b3ea4b008feb1308cb3f23e08", size = 13221894, upload-time = "2025-07-24T13:26:08.292Z" }, + { url = "https://files.pythonhosted.org/packages/6b/58/68a5be2c8e5590ecdad922b2bcd5583af19ba648f7648f95c51c3c1eca81/ruff-0.12.5-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:c7da4129016ae26c32dfcbd5b671fe652b5ab7fc40095d80dcff78175e7eddd4", size = 14163909, upload-time = "2025-07-24T13:26:10.474Z" }, + { url = "https://files.pythonhosted.org/packages/bd/d1/ef6b19622009ba8386fdb792c0743f709cf917b0b2f1400589cbe4739a33/ruff-0.12.5-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ca972c80f7ebcfd8af75a0f18b17c42d9f1ef203d163669150453f50ca98ab7b", size = 13583652, upload-time = "2025-07-24T13:26:13.381Z" }, + { url = "https://files.pythonhosted.org/packages/62/e3/1c98c566fe6809a0c83751d825a03727f242cdbe0d142c9e292725585521/ruff-0.12.5-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8dbbf9f25dfb501f4237ae7501d6364b76a01341c6f1b2cd6764fe449124bb2a", size = 12700451, upload-time = "2025-07-24T13:26:15.488Z" }, + { url = "https://files.pythonhosted.org/packages/24/ff/96058f6506aac0fbc0d0fc0d60b0d0bd746240a0594657a2d94ad28033ba/ruff-0.12.5-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2c47dea6ae39421851685141ba9734767f960113d51e83fd7bb9958d5be8763a", size = 12937465, upload-time = "2025-07-24T13:26:17.808Z" }, + { url = "https://files.pythonhosted.org/packages/eb/d3/68bc5e7ab96c94b3589d1789f2dd6dd4b27b263310019529ac9be1e8f31b/ruff-0.12.5-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:c5076aa0e61e30f848846f0265c873c249d4b558105b221be1828f9f79903dc5", size = 11771136, upload-time = "2025-07-24T13:26:20.422Z" }, + { url = "https://files.pythonhosted.org/packages/52/75/7356af30a14584981cabfefcf6106dea98cec9a7af4acb5daaf4b114845f/ruff-0.12.5-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:a5a4c7830dadd3d8c39b1cc85386e2c1e62344f20766be6f173c22fb5f72f293", size = 11601644, upload-time = "2025-07-24T13:26:22.928Z" }, + { url = "https://files.pythonhosted.org/packages/c2/67/91c71d27205871737cae11025ee2b098f512104e26ffd8656fd93d0ada0a/ruff-0.12.5-py3-none-musllinux_1_2_i686.whl", hash = "sha256:46699f73c2b5b137b9dc0fc1a190b43e35b008b398c6066ea1350cce6326adcb", size = 12478068, upload-time = "2025-07-24T13:26:26.134Z" }, + { url = "https://files.pythonhosted.org/packages/34/04/b6b00383cf2f48e8e78e14eb258942fdf2a9bf0287fbf5cdd398b749193a/ruff-0.12.5-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:5a655a0a0d396f0f072faafc18ebd59adde8ca85fb848dc1b0d9f024b9c4d3bb", size = 12991537, upload-time = "2025-07-24T13:26:28.533Z" }, + { url = "https://files.pythonhosted.org/packages/3e/b9/053d6445dc7544fb6594785056d8ece61daae7214859ada4a152ad56b6e0/ruff-0.12.5-py3-none-win32.whl", hash = "sha256:dfeb2627c459b0b78ca2bbdc38dd11cc9a0a88bf91db982058b26ce41714ffa9", size = 11751575, upload-time = "2025-07-24T13:26:30.835Z" }, + { url = "https://files.pythonhosted.org/packages/bc/0f/ab16e8259493137598b9149734fec2e06fdeda9837e6f634f5c4e35916da/ruff-0.12.5-py3-none-win_amd64.whl", hash = "sha256:ae0d90cf5f49466c954991b9d8b953bd093c32c27608e409ae3564c63c5306a5", size = 12882273, upload-time = "2025-07-24T13:26:32.929Z" }, + { url = "https://files.pythonhosted.org/packages/00/db/c376b0661c24cf770cb8815268190668ec1330eba8374a126ceef8c72d55/ruff-0.12.5-py3-none-win_arm64.whl", hash = "sha256:48cdbfc633de2c5c37d9f090ba3b352d1576b0015bfc3bc98eaf230275b7e805", size = 11951564, upload-time = "2025-07-24T13:26:34.994Z" }, +]