Contributing to LazyCurl ๐Ÿค

January 17, 2026 ยท View on GitHub

Thank you for your interest in contributing to LazyCurl! This document provides guidelines and conventions to follow when contributing to this project.

Table of Contents


Getting Started

Prerequisites

  • Go 1.21 or higher
  • Git
  • A GitHub account

Setup Development Environment

  1. Fork the repository

  2. Clone your fork:

    git clone https://github.com/YOUR_USERNAME/LazyCurl.git
    cd LazyCurl
    
  3. Add upstream remote:

    git remote add upstream https://github.com/kbrdn1/LazyCurl.git
    
  4. Install dependencies:

    go mod download
    
  5. Build the project:

    make build
    
  6. Run the application:

    make run
    

Working with Claude Code (Parallel Features)

When working on multiple features simultaneously with Claude Code, use Git Worktrees to maintain isolated working directories. This prevents context switching and keeps each Claude Code session focused on its specific task.

Why Git Worktrees?

  • Each worktree has its own working directory with isolated files while sharing the same Git history
  • Claude Code maintains deep context understanding for each feature without pollution from other work
  • No need for git stash or constant branch switching
  • Parallel development without merge conflicts with yourself

gwq - Git Worktree Manager

We use gwq for efficient worktree management with fuzzy finder integration.

Installation:

# Via Homebrew (macOS/Linux)
brew install d-kuro/tap/gwq

# Via Go
go install github.com/d-kuro/gwq/cmd/gwq@latest

gwq Commands Reference

CommandDescription
gwq add -b <branch>Create worktree with new branch
gwq add -iInteractive worktree creation with fuzzy finder
gwq listList all worktrees
gwq list -vList with verbose info (uncommitted changes, etc.)
gwq get <pattern>Get worktree path (for cd $(gwq get feat))
gwq cd <pattern>Change to worktree directory (launches new shell)
gwq exec <pattern> -- <cmd>Execute command in worktree
gwq remove <branch>Remove worktree
gwq remove -b <branch>Remove worktree AND delete branch
gwq statusShow status of all worktrees
gwq status --watchMonitor worktrees in real-time
gwq pruneClean up stale worktree references

Quick Create Examples

# Create a feature worktree
gwq add -b feat/#123-user-authentication

# Create a bugfix worktree
gwq add -b fix/#456-http-timeout

# Create a hotfix worktree
gwq add -b hotfix/#789-critical-security-fix

# Interactive creation with fuzzy finder
gwq add -i

# Use the interactive manager
make worktree

Branch naming convention: <type>/#<issue>-<description>

Branch types available: feat, fix, hotfix, docs, test, refactor, chore, perf, ci, build

# Navigate to a worktree (fuzzy match)
cd $(gwq get authentication)
gwq cd feat                          # Opens new shell in matching worktree

# Execute commands in worktrees
gwq exec authentication -- make build
gwq exec -s feat -- make test         # Stay in worktree after execution

# Monitor all worktrees
gwq status --watch

Running Claude Code Sessions

# Terminal 1 - Working on authentication
cd $(gwq get authentication)
claude

# Terminal 2 - Working on API refactor
cd $(gwq get refactor)
claude

# Terminal 3 - Fixing bug
cd $(gwq get fix)
claude

Or using gwq cd (launches new shell):

gwq cd authentication && claude

Cleanup

# Remove a specific worktree
gwq remove feat/#123-user-authentication

# Remove worktree AND delete the branch
gwq remove -b feat/#123-completed-feature

# Dry run to preview what would be removed
gwq remove --dry-run feat/#123-old-feature

# Clean up stale worktree references
gwq prune

Configuration (Optional)

Create ~/.config/gwq/config.toml or .gwq.toml in the project root:

[worktree]
basedir = "~/worktrees"

[[repository_settings]]
repository = "~/Projects/Perso/LazyCurl"
setup_commands = ["make deps"]

This automatically runs make deps when creating worktrees.

Best Practices

  1. Use gwq: Prefer gwq add -b over manual git worktree add for consistency
  2. Bootstrap Each Worktree: Run make deps in each new worktree (or configure in .gwq.toml)
  3. Keep Worktrees Updated: Regularly merge main into feature branches to avoid large conflicts
  4. Clean Up: Use gwq remove -b after merging to remove worktrees AND branches
  5. Monitor Status: Use gwq status --watch to track changes across all worktrees

Development Workflow

  1. Sync with upstream:

    git checkout main
    git pull upstream main
    
  2. Create a new branch following the Branch Convention

  3. Make your changes following the Code Style

  4. Test your changes (see Testing)

  5. Commit your changes following the Commit Convention

  6. Push to your fork and create a Pull Request


Branch Convention ๐ŸŒฟ

Main branches:

  • main: Production-ready code
  • dev: Development branch (currently not used, all development on feature branches)

Naming Convention ๐Ÿ“›

<type>/#<issue-number>-<short-description>

Components:

  • type: Type of the branch (see types below)
  • issue-number: Related GitHub issue number
  • short-description: Brief description in kebab-case

Branch Types

  • feat or feature: New feature implementation
  • fix: Bug fix
  • hotfix: Critical bug fix in production
  • docs: Documentation changes
  • test: Adding or modifying tests
  • refactor: Code refactoring
  • chore: Maintenance tasks
  • ci: CI/CD configuration changes
  • build: Build system changes
  • perf: Performance improvements

Examples

  • feat/#12-add-collection-loader
  • fix/#25-fix-yaml-parsing
  • docs/#8-update-contributing-guide
  • refactor/#33-reorganize-ui-components
  • perf/#45-optimize-response-rendering
  • test/#18-add-http-client-tests

Commit Convention ๐Ÿ“

We follow the Conventional Commits specification with Gitmoji emojis.

Format

<type>(<scope>)<!>: <subject> <emoji>

โš ๏ธ Important: Emoji must be at the END of the commit message for release-please compatibility.

Examples

# โœ… Correct - emoji at the end
feat(api): add cURL import functionality โœจ
fix(ui): resolve panel resize issue ๐Ÿ›
docs: update installation guide ๐Ÿ“

# โŒ Incorrect - emoji at the start (breaks release-please)
โœจ feat(api): add cURL import functionality
๐Ÿ› fix(ui): resolve panel resize issue

Emojis

Use Gitmoji suffixes for commit messages:

EmojiCodeDescription
โœจ:sparkles:New feature
๐Ÿ›:bug:Bug fix
๐Ÿ“:memo:Documentation
โ™ป๏ธ:recycle:Refactor code
โšก๏ธ:zap:Performance
โœ…:white_check_mark:Tests
๐Ÿ”ง:wrench:Configuration
๐Ÿš€:rocket:Deployment
๐ŸŽจ:art:UI/Style
๐Ÿ”ฅ:fire:Remove code/files
๐Ÿš‘๏ธ:ambulance:Critical hotfix
โฌ†๏ธ:arrow_up:Upgrade dependencies
โฌ‡๏ธ:arrow_down:Downgrade dependencies
๐Ÿ—๏ธ:building_construction:Architecture changes

Tip: Install the Gitmoji VSCode extension

Types

  • feat: New feature
  • fix: Bug fix
  • docs: Documentation only
  • style: Code style changes (formatting, missing semi-colons, etc.)
  • refactor: Code refactoring (neither fixes a bug nor adds a feature)
  • perf: Performance improvements
  • test: Adding or correcting tests
  • chore: Maintenance tasks (build, dependencies, etc.)
  • ci: CI/CD changes
  • build: Build system changes

Scopes

Choose a scope based on the affected module:

  • ui: User interface components
  • api: HTTP client and API logic
  • config: Configuration management
  • collections: Collections management
  • environments: Environment variables
  • styles: Lipgloss styles
  • cli: Command-line interface
  • docs: Documentation
  • tests: Test files

Breaking Changes

Indicate breaking changes with ! after the type/scope:

โœจ feat(api)!: change collection file format to v2

Subject Guidelines

Use imperative mood and follow these patterns:

VerbUse CaseExample
addCreate capabilityโœจ feat(collections): add folder support
changeChange behaviorโ™ป๏ธ refactor(ui): change panel layout logic
removeDelete capability๐Ÿ”ฅ feat(api): remove deprecated methods
fixFix issue๐Ÿ› fix(config): fix YAML parsing error
bumpIncrease versionโฌ†๏ธ chore(deps): bump bubbletea to v1.4.0
optimizePerformanceโšก๏ธ perf(ui): optimize viewport rendering
refactorRestructureโ™ป๏ธ refactor(api): refactor HTTP client
updateUpdate code๐Ÿ”ง chore(config): update default theme colors
improveEnhance codeโœจ feat(ui): improve keyboard navigation
disableDisable code๐Ÿ”’ chore(api): disable experimental feature

Rules:

  • Don't capitalize first letter
  • No period (.) at the end
  • Keep it under 72 characters

Commit Examples

โœจ feat(collections): add JSON collection loader
๐Ÿ› fix(ui): fix panel resize on terminal size change
๐Ÿ“ docs: update installation instructions
โ™ป๏ธ refactor(api): refactor request builder logic
โšก๏ธ perf(ui): optimize large collection rendering
โœ… test(api): add HTTP client unit tests
๐Ÿ”ง chore(config): update default keybindings
๐Ÿš€ ci: add GitHub Actions workflow
๐ŸŽจ style(ui): improve response viewer colors
๐Ÿ”ฅ feat(api)!: remove legacy request format

Pull Request Process

Before Creating a PR

  1. โœ… Ensure your code compiles: make build
  2. โœ… Run tests: make test (when available)
  3. โœ… Format your code: make fmt
  4. โœ… Update documentation if needed
  5. โœ… Ensure your branch is up to date with main

PR Title

Use the same format as commit messages:

<emoji> <type>(<scope>): <description>

Example: โœจ feat(collections): add Postman import support

PR Description Template

## Description
Brief description of the changes

## Related Issue
Fixes #<issue-number>

## Type of Change
- [ ] Bug fix
- [ ] New feature
- [ ] Breaking change
- [ ] Documentation update

## Changes Made
- Change 1
- Change 2
- Change 3

## Testing
Describe how you tested your changes

## Screenshots (if applicable)
Add screenshots for UI changes

## Checklist
- [ ] My code follows the project's code style
- [ ] I have performed a self-review of my code
- [ ] I have commented my code where necessary
- [ ] I have updated the documentation
- [ ] My changes generate no new warnings
- [ ] I have added tests that prove my fix/feature works
- [ ] New and existing tests pass locally

Review Process

  • At least 1 approval is required
  • All CI checks must pass
  • Code must be up to date with main branch
  • Resolve all review comments before merging

Code Style

Go Code Style

Follow the official Go Code Review Comments.

Key points:

  • Use gofmt for formatting (automatically done with make fmt)
  • Use meaningful variable and function names
  • Keep functions small and focused
  • Add comments for exported functions and types
  • Use Go idioms and best practices

File Organization

LazyCurl/
โ”œโ”€โ”€ cmd/                   # Application entrypoints
โ”‚   โ””โ”€โ”€ lazycurl/
โ”œโ”€โ”€ internal/              # Private application code
โ”‚   โ”œโ”€โ”€ api/              # HTTP client and API logic
โ”‚   โ”œโ”€โ”€ config/           # Configuration management
โ”‚   โ””โ”€โ”€ ui/               # TUI components
โ”œโ”€โ”€ pkg/                   # Public libraries
โ”‚   โ””โ”€โ”€ styles/           # Lipgloss styles
โ”œโ”€โ”€ docs/                  # Documentation
โ”œโ”€โ”€ .github/              # GitHub configuration
โ””โ”€โ”€ scripts/              # Build and deployment scripts

Naming Conventions

Files:

  • Use snake_case: collections_view.go
  • Test files: collections_view_test.go

Functions/Methods:

  • Exported: PascalCase (e.g., LoadCollection)
  • Private: camelCase (e.g., parseJSON)

Constants:

  • Exported: PascalCase (e.g., DefaultTimeout)
  • Private: camelCase (e.g., maxRetries)

Variables:

  • Use descriptive names: collectionPath, httpClient
  • Avoid single letters except for short scopes (i, j, k in loops)

Comments

// LoadCollection loads a collection from the specified path.
// It returns an error if the file doesn't exist or is invalid JSON.
func LoadCollection(path string) (*Collection, error) {
    // Implementation
}

Testing

Running Tests

# Run all tests
make test

# Run with coverage
make test-coverage

# Run specific package tests
go test ./internal/api/...

Writing Tests

  • Place test files next to the code they test
  • Use table-driven tests when possible
  • Test both success and error cases
  • Mock external dependencies

Example:

func TestLoadCollection(t *testing.T) {
    tests := []struct {
        name    string
        path    string
        want    *Collection
        wantErr bool
    }{
        {
            name:    "valid collection",
            path:    "testdata/valid.json",
            want:    &Collection{Name: "Test"},
            wantErr: false,
        },
        {
            name:    "invalid path",
            path:    "nonexistent.json",
            want:    nil,
            wantErr: true,
        },
    }

    for _, tt := range tests {
        t.Run(tt.name, func(t *testing.T) {
            got, err := LoadCollection(tt.path)
            if (err != nil) != tt.wantErr {
                t.Errorf("LoadCollection() error = %v, wantErr %v", err, tt.wantErr)
                return
            }
            if !reflect.DeepEqual(got, tt.want) {
                t.Errorf("LoadCollection() = %v, want %v", got, tt.want)
            }
        })
    }
}

Documentation

Code Documentation

  • Document all exported functions, types, and constants
  • Use GoDoc format
  • Include examples when helpful

Project Documentation

  • Update README.md for user-facing changes
  • Update DEVELOPMENT_PLAN.md for roadmap changes
  • Add examples in docs/ directory

Changelog

Update CHANGELOG.md following Keep a Changelog format:

## [Unreleased]
### Added
- New feature description

### Changed
- Changed feature description

### Fixed
- Bug fix description

GitHub Labels

Note: For complete label documentation including organization-level labels and implementation instructions, see .github/LABELS.md.

Type Labels

LabelColorDescription
feature#0E8A16New feature implementation
fix#D73A4ABug fix
hotfix#FF3333Critical production bug fix
docs#1D76DBDocumentation changes
test#87CEEBTest additions or modifications
refactor#FBCA04Code restructuring
chore#808080Maintenance tasks
optimization#FFA500Performance improvements

Domain Labels

LabelColorDescription
ui/ux#FF69B4User interface/experience
api#0075CAHTTP client and API logic
collections#7D56F4Collections management
environments#00D9FFEnvironment variables
configuration#26A69AConfiguration system
ci/cd#26A69ACI/CD pipeline
security#B60205Security issues

Management Labels

LabelColorDescription
dependencies#8B008BDependency updates
breaking#FF0000Breaking changes
good first issue#7057ffGood for newcomers
help wanted#008672Extra attention needed
urgent#FF1493Requires immediate attention

Status Labels

LabelColorDescription
duplicate#CCCCCCDuplicate issue/PR
invalid#444444Invalid issue
wontfix#FFFFFFWill not be fixed

Priority Levels

Use GitHub project boards or issue fields for priorities:

  • Critical: Blocking issue, immediate resolution needed
  • High: Important, resolve quickly
  • Medium: Standard priority
  • Low: Minor issue, can be deferred
  • Trivial: Cosmetic improvements

Release Process ๐Ÿš€

Releases are managed using Semantic Versioning:

Versioning Format

vMAJOR.MINOR.PATCH
  • MAJOR: Breaking changes
  • MINOR: New features (backward compatible)
  • PATCH: Bug fixes (backward compatible)

Examples

  • v1.0.0 - Initial release
  • v1.1.0 - New feature added
  • v1.1.1 - Bug fix
  • v2.0.0 - Breaking changes

Release Workflow

  1. Update CHANGELOG.md
  2. Create release branch: release/vX.Y.Z
  3. Update version in code if applicable
  4. Create PR to main
  5. After merge, create GitHub release with tag vX.Y.Z
  6. GitHub Actions will automatically build and publish binaries

Community Guidelines

Code of Conduct

  • Be respectful and inclusive
  • Welcome newcomers
  • Provide constructive feedback
  • Focus on what is best for the community

Getting Help


Additional Resources


Thank You! ๐Ÿ™

Thank you for contributing to LazyCurl! Your contributions help make this project better for everyone.


Copyright ยฉ 2024-present @kbrdn1

MIT License