Skip to content

Developer Guide

Arif Dogan edited this page Mar 4, 2025 · 1 revision

Developer Guide

This guide is intended for developers who want to contribute to LLMDog or understand its internals. We'll cover the project structure, key components, and how to extend or modify the application.

Project Architecture

LLMDog follows a clean architecture with clear separation of concerns. Here's an overview of the main components:

llmdog/
├── cmd/              # Command-line entry points
│   └── llmdog/       # Main application command
├── internal/         # Internal packages
│   ├── bookmarks/    # Bookmark management
│   ├── git/          # Git integration
│   ├── model/        # Core application model and logic
│   └── ui/           # User interface components

Key Components

Main Application (cmd/llmdog/main.go)

The entry point for the application, responsible for:

  • Parsing command-line arguments
  • Displaying version and help information
  • Initializing the application model
  • Starting the TUI

Model (internal/model/model.go)

The core of the application, handling:

  • Application state and business logic
  • File and directory management
  • Selection tracking
  • Output generation
  • Configuration management
  • Bookmark operations

User Interface (internal/ui/)

Split into two main files:

  • ui.go: Core UI components and styling
  • bookmark_ui.go: UI components for bookmark management

The UI uses the [Bubble Tea](https://github.com/charmbracelet/bubbletea) framework for the terminal interface and [Lip Gloss](https://github.com/charmbracelet/lipgloss) for styling.

Git Integration (internal/git/git.go)

Handles all Git-related functionality:

  • Detecting Git repositories
  • Parsing .gitignore files
  • Getting modified and staged files
  • Repository information

Bookmarks (internal/bookmarks/bookmarks.go)

Manages saved selections:

  • Loading and saving bookmarks
  • Creating, updating, and deleting bookmarks
  • Bookmark data structure

Data Flow

  1. The application starts in main.go, which initializes the model
  2. The model loads files from the current directory and sets up the UI
  3. User interactions are handled through the Bubble Tea event loop:
    • Key presses are captured and processed
    • State is updated accordingly
    • UI is re-rendered based on the new state
  4. When the user confirms selection, the model generates Markdown output
  5. Output is copied to the clipboard and the application exits

Key Data Structures

FileItem

Represents a file or directory in the UI:

type FileItem struct {
    Path           string
    Name           string
    IsDir          bool
    Selected       bool
    Depth          int
    Expanded       bool
    GitIgnored     bool
    ChildrenLoaded bool
    MatchesContent bool
}

Bookmark

Represents a saved selection:

type Bookmark struct {
    Name        string    
    Description string    
    FilePaths   []string  
    RootPath    string    
    Created     time.Time 
    Modified    time.Time 
}

Model

The main application state:

type Model struct {
    list                list.Model
    preview             string
    items               []ui.FileItem
    cwd                 string
    gitignoreRegexp     *regexp.Regexp
    // ... (many more fields)
}

Adding New Features

Adding a New Command-Line Option

  1. Open cmd/llmdog/main.go
  2. Add a new case to the command-line argument switch statement
  3. Implement the functionality for the new option
case "--my-new-option":
    // Handle the new option
    fmt.Println("Processing new option...")
    // Do something
    os.Exit(0)

Adding a New Configuration Option

  1. Update the Config struct in internal/model/model.go:
type Config struct {
    // Existing fields
    ShowHiddenFiles   bool
    FuzzyThreshold    float64
    // New field
    MyNewOption       string
}
  1. Update the LoadConfig function to include a default value
  2. Apply the configuration option where needed in the codebase

Adding a New UI Feature

  1. Define any new UI styles in internal/ui/ui.go
  2. Update the Model struct if new state is needed
  3. Add handler logic in the Update method in internal/model/model.go
  4. Update the View method to render the new feature

Adding a New Keyboard Shortcut

  1. Open internal/model/model.go
  2. Find the Update method and the tea.KeyMsg case
  3. Add a new case for your keyboard shortcut:
case "ctrl+x": // New shortcut
    // Implement the functionality
    return m, nil

Building and Testing

Building the Application

go build -o llmdog ./cmd/llmdog

Running with Debug Output

# Linux/macOS
BUBBLES_DEBUG=1 ./llmdog

# Windows PowerShell
$env:BUBBLES_DEBUG=1; ./llmdog

Cross-Compiling for Different Platforms

# For Windows
GOOS=windows GOARCH=amd64 go build -o llmdog.exe ./cmd/llmdog

# For macOS
GOOS=darwin GOARCH=amd64 go build -o llmdog-macos ./cmd/llmdog

# For Linux
GOOS=linux GOARCH=amd64 go build -o llmdog-linux ./cmd/llmdog

Code Style and Conventions

Go Conventions

LLMDog follows standard Go conventions:

Project-Specific Conventions

  • UI-related code belongs in the internal/ui package
  • Model and business logic goes in internal/model
  • Keep the main package minimal, delegating to internal packages
  • Use the Bubble Tea update/view pattern consistently

Performance Considerations

  • File Loading: For large directories, files are loaded lazily when directories are expanded
  • Preview Generation: Limited to a configurable maximum size to prevent slowdowns
  • Content Search: Can be slow on large projects, only enabled when explicitly toggled
  • Gitignore Processing: Converted to efficient regular expressions for faster matching

Common Extension Points

Adding Support for New File Types

Update the getFileIcon function in internal/ui/ui.go to add new file type icons:

func getFileIcon(name string, isDir bool) string {
    // ...
    switch ext {
    // ...
    case ".newext":
        return "🆕" // Icon for new extension
    // ...
    }
}

Customizing Output Format

Modify the BuildOutput function in internal/model/model.go to change how the Markdown output is formatted.

Adding New File Filters

To add new filtering capabilities, update the performSearch method in internal/model/model.go.

Clone this wiki locally