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

4.7 KiB

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

# 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.