Compare commits

..

No commits in common. "e59af1cb029a45827686e81379894802bff7af52" and "250091bb8a497ecde70f86feefc6200f7fc63e38" have entirely different histories.

7 changed files with 8 additions and 133 deletions

View file

@ -1,26 +0,0 @@
# 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, 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.
## 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.

View file

@ -1,87 +0,0 @@
# 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.

View file

@ -18,13 +18,13 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
} else {
m.focus = listPane
}
case "ctrl+e":
case "e":
if m.mode == ViewMode {
m.mode = EditMode
} else {
m.mode = ViewMode
}
case " ":
case "a":
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.ScrollUp(1)
m.detail.LineUp(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.ScrollDown(1)
m.detail.LineDown(1)
} else {
m.list, cmd = m.list.Update(msg)
m.refreshDetail()

View file

@ -24,8 +24,8 @@
- ✅ **Parser integration** loading `/etc/hosts` into the UI
### Phase 3: Edit Mode (IN PROGRESS)
- 🔄 **Edit mode toggle** via 'ctrl+e' key with status bar indication
- 🔄 **Entry activation toggle** using spacebar
- 🔄 **Edit mode toggle** via 'e' key with status bar indication
- 🔄 **Entry activation toggle** using 'a' key
- 🔄 **Model tests** covering edit mode behavior
### Parser Capabilities Achieved

View file

@ -80,7 +80,6 @@
- **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

View file

@ -29,17 +29,6 @@ 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
- `shift`+`up`/`down`: Move the selected entry up or down
- `i` Sort by IP addresses
- `n` Sort by (the first) hostname
- `ctrl`+`s`: Save
- `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:

View file

@ -72,12 +72,12 @@ func TestEditModeToggleAndActivation(t *testing.T) {
m := tui.NewModel(hf)
// enter edit mode
nm, _ := m.Update(tea.KeyMsg{Type: tea.KeyCtrlE})
nm, _ := m.Update(tea.KeyMsg{Type: tea.KeyRunes, Runes: []rune{'e'}})
m = nm.(tui.Model)
assert.Equal(t, tui.EditMode, m.Mode())
// toggle active state of first entry
nm, _ = m.Update(tea.KeyMsg{Type: tea.KeySpace})
nm, _ = m.Update(tea.KeyMsg{Type: tea.KeyRunes, Runes: []rune{'a'}})
m = nm.(tui.Model)
assert.False(t, m.SelectedEntry().Active)