This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
mdv is a dual-mode markdown viewer written in Go that operates as both a terminal UI (TUI) and a native GUI application. It uses Bubble Tea for the TUI, Wails for the GUI, and Glamour/Goldmark for markdown rendering.
All development is managed through Task. Common commands:
# Build both TUI and GUI binaries
task build:all
# Build TUI only (outputs ./mdv)
task build:tui
# Build GUI only (requires Wails CLI, outputs to cmd/mdv-gui/build/bin/mdv-gui)
task build:gui
# Run TUI in development with a file
task run:tui -- examples/demo.md
# Run GUI in development (Wails dev mode with hot reload)
task run:gui -- examples/demo.md
# Test with built binaries (simulates installed state)
task demo -- mdv examples/
task demo -- mdv -g examples/demo.md
# Run tests
task test
# Format code
task fmt
# Install to $GOPATH/bin
task install:all
# Clean build artifacts
task cleanManual Go commands (without Task):
- Build TUI:
go build -o ./mdv ./cmd/mdv - Build GUI:
cd cmd/mdv-gui && wails build - Run TUI:
go run ./cmd/mdv [file.md]
-
cmd/mdv/ - TUI application entry point
- Cobra-based CLI with smart file detection
- Bubble Tea model/view/update loop (cmd/mdv/main.go:19-101)
- File picker for directories with multiple markdown files (cmd/mdv/main.go:103-148)
- File watcher for live reload using fsnotify (cmd/mdv/main.go:363-398)
- Can launch GUI mode via
-gflag by exec'ing mdv-gui
-
cmd/mdv-gui/ - GUI application (Wails-based)
- Simple Go backend (app.go) that loads markdown and converts to HTML
- Frontend renders HTML in a native webview
- Opens external links in system browser (cmd/mdv-gui/app.go:63-65)
-
internal/config/ - Configuration system
- Uses Viper for layered config (flags > directory .mdv.yaml > local .mdv.yaml > ~/.config/mdv/config.yaml > env vars)
- Directory-specific configs: when viewing a file, mdv checks for .mdv.yaml in that file's directory
- Environment variables: MDV_THEME, MDV_THEME_LIGHT, MDV_THEME_DARK, MDV_WRAP, MDV_WATCH, MDV_GUI, MDV_EXCLUDE, MDV_EDITOR
- Config struct: Theme, ThemeLight, ThemeDark, Wrap, GUI, Watch, Exclude, File, Editor
- Setting
gui: truein config makesmdvlaunch in GUI mode by default (equivalent to-gflag)
-
internal/render/ - Markdown rendering
ToANSI(): Converts markdown to ANSI for terminal (uses Glamour)ToHTML(): Converts markdown to HTML for GUI (uses Goldmark)- Goldmark configured with GitHub Flavored Markdown extensions
- Theme auto-detection: checks macOS AppleInterfaceStyle or Linux COLORFGBG (internal/render/render.go:33-63)
- Smart file detection: No args → auto-detect single .md in current dir, or show picker if multiple
- Directory scanning: Point to a directory, mdv finds all markdown files (respects exclude patterns)
- Exclude patterns: Glob patterns via config or
--excludeflag to skip files when scanning - Live reload:
--watchflag uses fsnotify to auto-update TUI on file changes - Dual mode: TUI (
mdv) can launch GUI (mdv-gui) by pressing 'o' or using-gflag - Theme handling: "auto" theme detects system dark/light preference; users can customize which themes are used via
theme-lightandtheme-darkconfig options
- Command-line flags (highest)
.mdv.yamlin target file's directory.mdv.yamlin current working directory~/.config/mdv/config.yaml- Environment variables
- Built-in defaults (lowest)
↑/↓orj/k: Scrollg/GorHome/End: Jump to top/bottomr: Manual reloado: Open in GUI modeq/Esc/Ctrl+C: Quit
The repository includes example markdown files in examples/ for testing various features:
examples/demo.md- General demoexamples/features.md- Feature showcaseexamples/config.yaml- Example config
Key external dependencies:
- Bubble Tea: TUI framework
- Glamour: Terminal markdown rendering
- Goldmark: Markdown parsing (with GFM extensions)
- Wails v2: GUI framework
- Cobra: CLI framework
- Viper: Configuration management
- fsnotify: File watching
- GUI builds require Wails CLI and CGO_ENABLED=1
- The TUI can run without Wails/GUI dependencies
- Both binaries (mdv, mdv-gui) are independent executables
- mdv-gui can be invoked directly or via
mdv -g