Files
Niko Syring d41761d6e9 feat: complete Rust-to-Go rewrite with Bubbletea v2
Rewrites oxker from Rust/ratatui to Go/Bubbletea, migrated to the
Bubbletea v2 API (charm.land/bubbletea/v2). Removes all original Rust
source files and legacy Go modules (internal/ui, internal/input, bubbles).

Key changes:
- View() returns tea.View with declarative AltScreen and MouseMode
- KeyMsg → KeyPressMsg, MouseMsg → MouseClickMsg/WheelMsg/MotionMsg/ReleaseMsg
- execWriteKey rewritten for v2 key fields (Code/Mod/Text)
- Mouse toggle via View field instead of imperative commands
- Filter/search text input uses msg.Text for v2 space key compat

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 03:41:14 +01:00

106 lines
4.7 KiB
Markdown

# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Project Overview
Oxker is a Go rewrite of the original Rust-based TUI for viewing and controlling Docker containers. It uses the Bubbletea framework for the terminal UI and the Docker SDK for container management.
**Note:** The git history still contains deleted Rust source files (src/, Cargo.toml, etc.). Original Rust source is preserved in `source/` for reference. The active codebase is entirely Go.
## Build & Run
```bash
# Build
go build -o oxker ./cmd/oxker
# Run
./oxker
# Run with debug mode (no TUI)
./oxker -g
# Vet
go vet ./...
# Test
go test ./...
# Run a single test
go test ./cmd/oxker -run TestAppStart
# Tidy modules
go mod tidy
# All-in-one build script (build + vet + tidy)
./build.sh
```
## Architecture
The app follows the Elm architecture (Model-View-Update) via Bubbletea:
- **`cmd/oxker/`** - Entry point and CLI argument parsing
- `main.go` - Creates `tea.Program` with AltScreen + mouse support, passes config to `app.New(cfg)`
- `cli.go` - Flag definitions, config loading, CLI-to-config mapping
- **`internal/app/app.go`** - Central application model (~1850 lines, self-contained). Contains:
- `App` struct implementing `tea.Model` (Init/Update/View)
- `Container` data type with 60-sample rolling stats buffers (CPU, mem, RX, TX)
- Container state machine: RunningHealthy, RunningUnhealthy, Paused, Exited, Dead, Restarting, Removing, Created, Unknown
- Catppuccin Mocha color palette
- Sorting (9 columns, asc/desc toggle), filtering (4 modes: Name/Image/Status/All), log search with match navigation
- Sparkline charts for CPU, Memory, and Network bandwidth
- Mouse support (wheel scroll, click to select containers, click headers to sort)
- Docker exec via `tea.ExecProcess` (suspends TUI, runs `docker exec -it <id> sh`)
- Inspect panel (JSON), delete confirmation popup, error/info overlays
- Log panel: resize, toggle, horizontal scroll, save to file
- SI units (1000-based) for byte formatting
- CPU calculation: `(cpu_delta / system_delta) * online_cpus * 100.0`
- **`internal/docker/client.go`** - Thin wrapper around `github.com/docker/docker/client`. Key methods:
- `ContainerStatsOneShot` - Single stats snapshot with proper JSON decoding
- `Logs` - Container log streaming
- `ContainerExec` - Docker exec API (used by client, app uses CLI `docker exec` via `tea.ExecProcess`)
- Standard CRUD: Start, Stop, Restart, Delete, Pause, Unpause, Inspect
- **`internal/config/config.go`** - Configuration with TOML and JSONC support. Includes:
- `AppColors` - Full color theming for every UI element
- `Keymap` - Customizable key bindings with primary/secondary support
- Config file resolution: absolute path, relative to CWD, then `~/.config/oxker/`
- **`internal/input/`**, **`internal/ui/`**, **`internal/utils/`** - Legacy modules from earlier architecture, currently unused by app.go
## Key Dependencies
- `github.com/charmbracelet/bubbletea` v1.3.10 - TUI framework (Elm architecture)
- `github.com/charmbracelet/lipgloss` - Terminal styling
- `github.com/docker/docker` - Docker SDK
- `github.com/BurntSushi/toml` - TOML config parsing
## Data Flow
1. `main.go` parses CLI args -> loads config -> creates `App` model with config -> starts `tea.Program`
2. `App.Init()` fires `loadContainers()` and `tickCmd()` concurrently
3. `tickCmd()` fires every `DockerIntervalMs` (default 1000ms), triggers container list reload + stats updates
4. Stats collected via `ContainerStatsOneShot` (one-shot, not streaming) for each running container
5. Key/mouse events route through `App.Update()` -> mode-specific handler (normal, filter, search, inspect, delete confirm)
6. Container actions dispatch via `doAction()` which calls Docker SDK through `CmdMgr`
## CLI Flags
Key flags: `-d` (update interval ms), `-r` (raw logs), `-c` (color logs), `-t` (timestamps), `-s` (show self), `-g` (debug/no-TUI), `-config-file`, `-host`, `-timezone`, `-use-cli`, `-no-stderr`, `-save-dir`
## Mouse API (bubbletea v1.3.10)
`tea.MouseMsg` is a struct (not interface). Use `msg.Action` (MouseActionPress/Release/Motion) and `msg.Button` (MouseButtonLeft/WheelUp/WheelDown etc.) directly. No subtypes like MouseWheelMsg or MouseClickMsg.
## JCodeMunch (jmunch) Usage
- Start with `get_repo_outline` to quickly understand the repository structure.
- Use `get_file_outline` before reading source to understand the API surface first.
- Narrow searches using `kind`, `language`, and `file_pattern`.
- Batch-retrieve related symbols with `get_symbols` instead of repeated `get_symbol` calls.
- Use `search_text` when symbol search does not locate the needed content.
- Use `verify: true` on `get_symbol` to detect source drift since indexing.