This document is for automated agents and contributors who will work on the humble-cli repository. It documents the repository layout, developer-facing commands, patterns, and important gotchas discovered in the codebase. Only facts observed in the repository are included.
Language: Go 1.24+ Purpose: Command-line tool to interact with Humble Bundle purchases: list bundles, show details, search products, download items, and manage a session key for authentication.
.
├── cmd/
│ └── humble-cli/ # CLI entry point (main.go with Cobra framework)
├── internal/
│ ├── api/ # Humble Bundle API client
│ ├── commands/ # Command implementations
│ ├── config/ # Configuration management
│ ├── download/ # File download with retry
│ ├── keymatch/ # Fuzzy key matching
│ ├── models/ # Data structures (Bundle, Product, etc.)
│ └── util/ # Utility functions
├── docs/ # Browser session key extraction guides
├── .github/workflows/ # CI/CD workflows
├── go.mod # Go module definition
├── go.sum # Dependency checksums
├── Makefile # Build automation
├── README.md # User-facing documentation
# Debug build
go build -o humble-cli ./cmd/humble-cli
# Release build (optimized, smaller binary)
go build -ldflags="-s -w" -o humble-cli ./cmd/humble-cli
# Build for all platforms (using Makefile)
make build-all# Run all tests
go test ./...
# Run tests with coverage
go test -coverprofile=coverage.out ./...
go tool cover -html=coverage.out
# Run tests with race detector
go test -race ./...# Install to $GOPATH/bin
go install ./cmd/humble-cli
# Format code
go fmt ./...
# Run linter (requires golangci-lint)
golangci-lint run
# Download dependencies
go mod download
go mod tidy
# Clean build artifacts
make clean- Session key is stored in:
~/.humble-cli-key(plain text file) - Set via:
humble-cli auth "<SESSION-KEY>" - The session key is the
_simpleauth_sesscookie from humblebundle.com - See
docs/session-key-*.mdfor browser-specific extraction guides
- Uses Cobra for command-line interface
- Commands defined in
cmd/humble-cli/main.go - Command implementations in
internal/commands/commands.go - Flags and subcommands follow Cobra conventions
- Standard Go error patterns:
if err != nil - Wrap errors with context:
fmt.Errorf("context: %w", err) - User-facing errors mapped in
internal/commands/commands.go:- HTTP 401 → "Is the session key correct?"
- HTTP 404 → "Is the bundle key correct?"
- Uses goroutines and channels (no external async framework)
- Bundle fetching: concurrent batches of 10 keys
- Download retry: 3 attempts with 5-second delay
- Custom
HumbleTimetype ininternal/models/bundle.go - Handles Humble Bundle's datetime format (no timezone)
- Tries multiple formats: microseconds, seconds, RFC3339
- Custom
UnmarshalJSONonBundletype - Silently skips malformed products (partial deserialization)
- Allows graceful handling of API inconsistencies
- Test files alongside source:
*_test.go - Table-driven tests for utilities
- No mocks/fakes - tests use realistic data structures
All dependencies use permissive licenses (MIT/BSD/Apache 2.0):
github.com/spf13/cobrav1.8.0 - CLI frameworkgithub.com/PuerkitoBio/goqueryv1.9.0 - HTML parsinggithub.com/schollz/progressbar/v3v3.14.0 - Progress barsgithub.com/olekukonko/tablewriterv0.0.5 - Table formatting
- Runs on: ubuntu-latest, windows-latest, macos-latest
- Go versions: 1.24, 1.25, 1.26
- Commands:
go test ./...andgo test -race ./... - Triggers: pushes/PRs to master, changes in cmd/, internal/, or Go files
- Triggers: tags matching
v[0-9]+.* - Builds binaries for: Linux (amd64, arm64), macOS (amd64, arm64), Windows (amd64)
- Creates GitHub release automatically
- Uploads
.tar.gz(Unix) and.zip(Windows) archives
- Auto-merges minor dependabot updates
- Requires
DEPENDABOT_AUTO_MERGEsecret
- Most commands require
~/.humble-cli-keyto exist - Use
humble-cli auth "<KEY>"to set it up - If missing or invalid, commands will fail with clear error messages
- Humble Bundle API returns timestamps without timezone
HumbleTimetype handles this by trying multiple formats- Always use
HumbleTimefor bundle/product timestamps
- Bundle unmarshaling skips malformed products silently
- This prevents one bad product from breaking the entire bundle
- Check logs if products seem missing
- Downloads create directories:
bundle-name/product-name/ - Filenames are sanitized: invalid chars replaced with
_ - Progress bars show current/total bytes
- Resume supported via HTTP Range headers
list --field key --field nameproduces CSV-like output- Valid fields:
key,name,size,claimed - Useful for scripting and automation
- Run tests after edits:
go test ./... - Format code:
go fmt ./... - Check for warnings:
go build ./... - Preserve behavioral parity: User-facing behavior should match expectations
- Update documentation: Keep README.md and AGENTS.md in sync
cmd/humble-cli/main.go- CLI definitions and entry pointinternal/commands/commands.go- All command implementationsinternal/api/humble.go- HTTP API interactionsinternal/models/bundle.go- Data structures and time handlinginternal/config/config.go- Session key storage.github/workflows/tests.yml- CI test strategyMakefile- Build automation
- Directories: lowercase (cmd, internal, docs)
- Files: lowercase with underscores only in test files (
*_test.go) - Packages: lowercase, single word (api, config, util)
- Exported functions/types: CamelCase (HumanizeBytes, Bundle)
- Unexported functions/types: camelCase (sanitizeFilename, downloadFile)
- Constants: CamelCase or ALL_CAPS for package-level
- No Makefile linter config (could be added)
- No Docker configuration
- No Homebrew formula (maintained separately if it exists)
- No shell completions in repo (generated at runtime via Cobra)
END OF AGENTS.MD