From 3c239e68f3fd2e755b0ceb61500e98b621d5f7ab Mon Sep 17 00:00:00 2001 From: phg Date: Thu, 14 Aug 2025 08:04:04 +0200 Subject: [PATCH 1/6] feat: Add CLAUDE.md for project documentation and guidance --- CLAUDE.md | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 CLAUDE.md diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..904d2aa --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,87 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Project Overview + +This is a Go TUI application for managing `/etc/hosts` files using the Bubble Tea framework. The app provides a two-pane interface (list view + detail view) for viewing, editing, and managing host entries with features like activation/deactivation, sorting, and DNS resolution. + +## Architecture + +The codebase follows a clean architecture pattern with separation of concerns: + +- `cmd/hosts/main.go` - Entry point that parses `/etc/hosts` and launches the TUI +- `internal/core/` - Core business logic and data models + - `models.go` - Data structures for HostEntry and HostsFile with validation + - `parser.go` - Hosts file parsing, formatting, and writing with intelligent formatting detection +- `internal/tui/` - Bubble Tea TUI components + - `model.go` - Main Bubble Tea model with pane navigation and mode management + - `view.go` - Rendering logic for the two-pane interface + - `update.go` - Message handling and state updates +- `tests/` - Test files following TDD approach + +## Key Technical Patterns + +### Data Models +- `HostEntry` represents individual host entries with IP, hostname, aliases, comments, and active status +- `HostsFile` contains collections of entries with methods for searching, adding, and removing +- All models include validation methods and proper error handling + +### TUI Architecture +- Uses Bubble Tea's Model-View-Update pattern +- Two-pane layout with list and detail views +- Mode switching between ViewMode and EditMode +- Pane focus management (listPane/detailPane) + +### File Operations +- Intelligent formatting detection preserves original hosts file style +- Atomic file operations with backup creation +- Proper validation before writing changes + +## Development Commands + +### Build and Run +```bash +go run cmd/hosts/main.go +go build -o hosts cmd/hosts/main.go +``` + +### Testing +```bash +go test ./... # Run all tests +go test ./tests/ # Run tests in tests directory +go test -v ./internal/core/ # Run core package tests with verbose output +go test -cover ./... # Run tests with coverage +``` + +### Dependencies +Key dependencies are managed via `go.mod`: +- Bubble Tea framework for TUI +- Bubbles for common components +- Lip Gloss for styling +- testify for test assertions + +## Important Implementation Details + +### Hosts File Parsing +The parser in `internal/core/parser.go` handles: +- Active and inactive (commented) entries +- Inline comments preservation +- Intelligent formatting detection (tabs vs spaces) +- IPv4/IPv6 address validation +- RFC-compliant hostname validation + +### TUI Navigation +- Tab/Shift+Tab for pane switching +- Arrow keys for list navigation +- Space for toggling entry activation +- 'q' to quit application + +### Error Handling +- Comprehensive validation at model level +- Parse warnings collection during file parsing +- Graceful error recovery in TUI operations + +## Memory Bank Integration + +This project uses Cline's Memory Bank system located in `memory-bank/` directory. The project brief and context files provide additional architectural context and development history. Always consult these files when making significant changes to understand the project's evolution and design decisions. \ No newline at end of file From 3f794786b62be349090571b8a242d56f6f899838 Mon Sep 17 00:00:00 2001 From: Philip Henning Date: Thu, 14 Aug 2025 08:28:49 +0200 Subject: [PATCH 2/6] docs: add project agents guidance --- AGENTS.md | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 AGENTS.md diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..51f8cb6 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,26 @@ +# AGENTS + +## Memory Bank Requirements +- **Always read the Memory Bank before starting any task.** +- Memory Bank lives in `memory-bank/` and contains: + - `projectbrief.md` + - `productContext.md` + - `systemPatterns.md` + - `techContext.md` + - `activeContext.md` + - `progress.md` +- The Memory Bank is the single source of project context. If a user requests **update memory bank**, review every file in the directory before making changes. +- After significant work or when insights are gained, update `activeContext.md` and `progress.md`. Create additional files in `memory-bank/` when useful for organizing new documentation. + +## Development Guidelines +- **Language:** Go using modules. +- **Formatting:** run `gofmt -w` on modified Go files. +- **Testing:** practice TDD and run `go test ./...` before committing. +- **Linting:** run `golangci-lint run` when available. +- **Structure:** keep application code inside `internal/` packages and follow existing patterns for `core`, `tui`, and `utils`. +- **Error Handling:** return errors instead of panicking and provide clear messages. + +## Commit Process +- Ensure Memory Bank is updated when project state changes. +- Run the formatting, lint, and test commands above. +- Commit only when the worktree is clean and all commands pass. From 103a41cdc20dbe611bd354146cf0b4db4fdf1838 Mon Sep 17 00:00:00 2001 From: phg Date: Thu, 14 Aug 2025 08:54:35 +0200 Subject: [PATCH 3/6] docs: Update project brief with key bindings for user interaction --- memory-bank/projectbrief.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/memory-bank/projectbrief.md b/memory-bank/projectbrief.md index 692059f..c08b60e 100644 --- a/memory-bank/projectbrief.md +++ b/memory-bank/projectbrief.md @@ -29,6 +29,15 @@ The user can: - Use DNS-based resolution for hostnames - Quickly update IP addresses +Key Bindings: +- `ctrl`+`e`: Change to edit mode +- `e`: Edit the currently selected hostname entry +- `space`: Entry activation toggle +- `i` Sort by IP addresses +- `n` Sot by (the first) hostname +- `c` To open the tool configuration +- `?` or `h`: Display help about all Key Bindings + The program will operate in **view-only mode** by default and require explicit entry into **edit mode**, at which point it will request elevated (sudo) permissions until editing is disabled. The project uses: From 9af4c54d1e977ef412a2b462f33b84a6d8e12158 Mon Sep 17 00:00:00 2001 From: phg Date: Thu, 14 Aug 2025 08:58:44 +0200 Subject: [PATCH 4/6] docs: Update key bindings in project brief for clarity and completeness --- memory-bank/projectbrief.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/memory-bank/projectbrief.md b/memory-bank/projectbrief.md index c08b60e..fb4ecde 100644 --- a/memory-bank/projectbrief.md +++ b/memory-bank/projectbrief.md @@ -33,8 +33,10 @@ Key Bindings: - `ctrl`+`e`: Change to edit mode - `e`: Edit the currently selected hostname entry - `space`: Entry activation toggle +- `shift`+`up`/`down`: Move the selected entry up or down - `i` Sort by IP addresses -- `n` Sot by (the first) hostname +- `n` Sort by (the first) hostname +- `ctrl`+`s`: Save - `c` To open the tool configuration - `?` or `h`: Display help about all Key Bindings From ecb7a1ab93b1ad4d56728b0cc041f5f7cf3e9107 Mon Sep 17 00:00:00 2001 From: Philip Henning Date: Thu, 14 Aug 2025 09:04:25 +0200 Subject: [PATCH 5/6] Update key bindings to match project brief --- internal/tui/update.go | 8 ++++---- memory-bank/activeContext.md | 4 ++-- memory-bank/progress.md | 1 + tests/tui_test.go | 4 ++-- 4 files changed, 9 insertions(+), 8 deletions(-) diff --git a/internal/tui/update.go b/internal/tui/update.go index e29fd15..8092961 100644 --- a/internal/tui/update.go +++ b/internal/tui/update.go @@ -18,13 +18,13 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { } else { m.focus = listPane } - case "e": + case "ctrl+e": if m.mode == ViewMode { m.mode = EditMode } else { m.mode = ViewMode } - case "a": + case " ": if m.mode == EditMode { if entry := m.SelectedEntry(); entry != nil { entry.Active = !entry.Active @@ -34,7 +34,7 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { } case "up", "k": if m.focus == detailPane { - m.detail.LineUp(1) + m.detail.ScrollUp(1) } else { m.list, cmd = m.list.Update(msg) m.refreshDetail() @@ -42,7 +42,7 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { return m, cmd case "down", "j": if m.focus == detailPane { - m.detail.LineDown(1) + m.detail.ScrollDown(1) } else { m.list, cmd = m.list.Update(msg) m.refreshDetail() diff --git a/memory-bank/activeContext.md b/memory-bank/activeContext.md index c19e750..5a6e125 100644 --- a/memory-bank/activeContext.md +++ b/memory-bank/activeContext.md @@ -24,8 +24,8 @@ - ✅ **Parser integration** loading `/etc/hosts` into the UI ### Phase 3: Edit Mode (IN PROGRESS) -- 🔄 **Edit mode toggle** via 'e' key with status bar indication -- 🔄 **Entry activation toggle** using 'a' key +- 🔄 **Edit mode toggle** via 'ctrl+e' key with status bar indication +- 🔄 **Entry activation toggle** using spacebar - 🔄 **Model tests** covering edit mode behavior ### Parser Capabilities Achieved diff --git a/memory-bank/progress.md b/memory-bank/progress.md index aedc400..13272c7 100644 --- a/memory-bank/progress.md +++ b/memory-bank/progress.md @@ -80,6 +80,7 @@ - **Active work**: Expand edit mode with file integration and advanced editing - **Blockers**: None - comprehensive parser foundation with 54 tests completed - **Parser status**: Production-ready with all safety features implemented +- **Key bindings updated**: `ctrl+e` for edit mode, spacebar to toggle entries ### Development Readiness - ✅ **Architecture designed**: Clear technical approach documented diff --git a/tests/tui_test.go b/tests/tui_test.go index a73719a..ae7ce72 100644 --- a/tests/tui_test.go +++ b/tests/tui_test.go @@ -72,12 +72,12 @@ func TestEditModeToggleAndActivation(t *testing.T) { m := tui.NewModel(hf) // enter edit mode - nm, _ := m.Update(tea.KeyMsg{Type: tea.KeyRunes, Runes: []rune{'e'}}) + nm, _ := m.Update(tea.KeyMsg{Type: tea.KeyCtrlE}) m = nm.(tui.Model) assert.Equal(t, tui.EditMode, m.Mode()) // toggle active state of first entry - nm, _ = m.Update(tea.KeyMsg{Type: tea.KeyRunes, Runes: []rune{'a'}}) + nm, _ = m.Update(tea.KeyMsg{Type: tea.KeySpace}) m = nm.(tui.Model) assert.False(t, m.SelectedEntry().Active) From e59af1cb029a45827686e81379894802bff7af52 Mon Sep 17 00:00:00 2001 From: phg Date: Thu, 14 Aug 2025 09:08:41 +0200 Subject: [PATCH 6/6] docs: Enhance testing guidelines to include interactive UI testing --- AGENTS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AGENTS.md b/AGENTS.md index 51f8cb6..f6d0d32 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -15,7 +15,7 @@ ## Development Guidelines - **Language:** Go using modules. - **Formatting:** run `gofmt -w` on modified Go files. -- **Testing:** practice TDD and run `go test ./...` before committing. +- **Testing:** practice TDD and run `go test ./...` before committing, also Test the Application interactively, to ensure the UI is also correct. - **Linting:** run `golangci-lint run` when available. - **Structure:** keep application code inside `internal/` packages and follow existing patterns for `core`, `tui`, and `utils`. - **Error Handling:** return errors instead of panicking and provide clear messages.