GLF - GitLab Fuzzy Finder
π¬π§ English | π·πΊ Π ΡΡΡΠΊΠΈΠΉ | π¨π³ δΈζ
β‘ Fast CLI tool for instant fuzzy search across self-hosted GitLab projects using local cache.

β¨ Features
- β‘ Lightning-fast fuzzy search with local caching
- π Multi-token search - Search with spaces:
"api storage" finds projects with both terms
- π§ Smart ranking - Combines usage history with starred favorites for intelligent results
- β GitLab starred integration - Starred projects automatically rank higher (no config needed)
- π Auto-sync on startup - Projects refresh in background while you search
- π JSON API mode - Machine-readable output for Raycast, Alfred, and custom integrations
- π Cross-platform builds for macOS, Linux, and Windows
π Quick Start
Installation
Homebrew (macOS/Linux)
The easiest way to install GLF on macOS or Linux:
# Add the tap
brew tap igusev/tap
# Install GLF
brew install glf
# Update to latest version
brew upgrade glf
MacPorts (macOS)
Alternative installation method for macOS users:
# Clone the ports repository
git clone https://github.com/igusev/macports-ports.git
cd macports-ports
# Add as a local port source (requires sudo)
sudo bash -c "echo 'file://$(pwd)' >> /opt/local/etc/macports/sources.conf"
# Update and install
sudo port sync
sudo port install glf
# Update to latest version
sudo port selfupdate
sudo port upgrade glf
Scoop (Windows)
The easiest way to install GLF on Windows:
# Add the bucket
scoop bucket add igusev https://github.com/igusev/scoop-bucket
# Install GLF
scoop install igusev/glf
# Update to latest version
scoop update glf
Linux Packages
Native packages for various Linux distributions are available on the releases page.
Debian/Ubuntu (APT)
# Download the .deb package from releases
wget https://github.com/igusev/glf/releases/download/v0.3.0/glf_0.3.0_linux_amd64.deb
# Install the package
sudo apt install ./glf_0.3.0_linux_amd64.deb
Fedora/RHEL/CentOS (DNF/YUM)
# Download the .rpm package from releases
wget https://github.com/igusev/glf/releases/download/v0.3.0/glf_0.3.0_linux_amd64.rpm
# Install the package (Fedora/RHEL 8+)
sudo dnf install ./glf_0.3.0_linux_amd64.rpm
# Or using yum (RHEL 7/CentOS 7)
sudo yum install ./glf_0.3.0_linux_amd64.rpm
Alpine Linux (APK)
# Download the .apk package from releases
wget https://github.com/igusev/glf/releases/download/v0.3.0/glf_0.3.0_linux_amd64.apk
# Install the package
sudo apk add --allow-untrusted ./glf_0.3.0_linux_amd64.apk
Arch Linux (Pacman)
# Download the archlinux package from releases
wget https://github.com/igusev/glf/releases/download/v0.3.0/glf_0.3.0_linux_amd64.pkg.tar.zst
# Install the package
sudo pacman -U ./glf_0.3.0_linux_amd64.pkg.tar.zst
Note: Replace v0.3.0 and 0.3.0 with the latest version number from the releases page.
From Source
# Clone the repository
git clone https://github.com/igusev/glf.git
cd glf
# Build and install
make install
Binary Releases
You can download the official GLF binaries from the releases page.
Available formats:
- macOS (Intel & Apple Silicon):
.tar.gz archives
- Linux:
.tar.gz archives, .deb packages (Debian/Ubuntu), .rpm packages (Fedora/RHEL), .apk packages (Alpine), Arch Linux packages
- Windows (x64):
.zip archives
- FreeBSD, OpenBSD:
.tar.gz archives
Configuration
Run the interactive configuration wizard:
glf --init
This will prompt you for:
- GitLab instance URL (e.g.,
https://gitlab.example.com)
- Personal Access Token (with
read_api scope)
- API timeout (default: 30 seconds)
Configuration is saved to ~/.config/glf/config.yaml.
To reset and reconfigure:
glf --init --reset
Manual Configuration
Create ~/.config/glf/config.yaml:
gitlab:
url: "https://gitlab.example.com"
token: "your-personal-access-token"
timeout: 30 # optional, defaults to 30 seconds
cache:
dir: "~/.cache/glf" # optional
Environment Variables
You can also use environment variables:
export GLF_GITLAB_URL="https://gitlab.example.com"
export GLF_GITLAB_TOKEN="your-token-here"
export GLF_GITLAB_TIMEOUT=30 # optional
Creating a Personal Access Token
- Go to your GitLab instance
- Navigate to User Settings β Access Tokens
- Create a new token with
read_api scope
- Copy the token and use it in
glf --init
Sync Projects
Fetch projects from GitLab and build local cache:
glf sync
Search Projects
Interactive Mode (Default)
# Launch interactive fuzzy finder
glf
# Start with initial query
glf backend
Navigation:
β/β - Navigate through results
Enter - Select project
Ctrl+R - Manually refresh/sync projects from GitLab
Ctrl+X - Exclude/un-exclude project from search results
Ctrl+H - Toggle showing excluded projects
? - Toggle help text
Esc/Ctrl+C - Quit
- Type to filter projects in real-time
Activity Indicator:
β - Idle (nothing happening)
β (green) - Active: syncing projects or loading selection history
β (red) - Error: sync failed
- Auto-sync runs on startup, manual sync available with
Ctrl+R
π Usage
Commands
glf [query] Search projects (default: interactive TUI)
glf --init Configure GitLab connection
glf --init --reset Reset and reconfigure GitLab connection
glf --sync Sync projects from GitLab to local cache
glf --help Show help
Flags
--init Run interactive configuration wizard
--reset Reset configuration and start from scratch (use with --init)
-g, --open Alias for --go (for compatibility)
--go Auto-select first result and open in browser
-s, --sync Synchronize projects cache
--full Force full sync (use with --sync)
-v, --verbose Enable verbose logging
--scores Show score breakdown for debugging ranking
--json Output results in JSON format (for API integrations)
--limit N Limit number of results in JSON mode (default: 20)
Examples
# Interactive search
glf
# Search with pre-filled query
glf microservice
# Multi-token search (matches projects with all terms)
glf api storage # Finds projects containing both "api" AND "storage"
glf user auth service # Finds projects with all three terms
# Auto-select first result and open in browser
glf ingress -g # Opens first "ingress" match
glf api --go # Same as -g (alias for compatibility)
# Open current Git repository in browser
glf .
# Sync projects from GitLab
glf --sync # Incremental sync
glf --sync --full # Full sync (removes deleted projects)
# Verbose mode for debugging
glf sync --verbose
# Show ranking scores for debugging
glf --scores
# Configure GitLab connection
glf --init
# Reset and reconfigure
glf --init --reset
JSON Output Mode (API Integration)
GLF supports JSON output for integration with tools like Raycast, Alfred, or custom scripts:
# Output search results as JSON
glf --json api
# Limit number of results
glf --json --limit 5 backend
# Include relevance scores (optional)
glf --json --scores microservice
# Get all projects (no query)
glf --json --limit 100
JSON Output Format (without --scores):
{
"query": "api",
"results": [
{
"path": "backend/api-server",
"name": "API Server",
"description": "REST API for authentication",
"url": "https://gitlab.example.com/backend/api-server",
"starred": true
}
],
"total": 5,
"limit": 20
}
JSON Output Format (with --scores):
{
"query": "api",
"results": [
{
"path": "backend/api-server",
"name": "API Server",
"description": "REST API for authentication",
"url": "https://gitlab.example.com/backend/api-server",
"starred": true,
"score": 123.45,
"history_score": 50,
"starred_bonus": 50
}
],
"total": 5,
"limit": 20
}
Score Breakdown:
When using --scores flag, each project includes a relevance score that combines:
- Search Relevance: Fuzzy matching + full-text search score
- Usage History: Frequency of previous selections (with exponential decay)
- Starred Bonus: +50 for starred projects
- Query-Specific Boost: 3x multiplier for projects selected with this exact query
Higher scores indicate better matches. Projects are automatically sorted by score (descending).
Use Cases:
- Raycast Extension: Quick project navigation from Raycast
- Alfred Workflow: GitLab project search in Alfred
- CI/CD Scripts: Automated project discovery and URL generation
- Custom Tools: Build your own integrations on top of GLF's search
- Analytics: Use
--scores to understand ranking and optimize search queries
Error Handling:
When errors occur, GLF outputs JSON error format and exits with code 1:
{
"error": "no projects in cache"
}
Smart Ranking
GLF uses multiple signals to rank projects intelligently:
Usage History:
- First time: Search
"api" β Select myorg/api/storage
- Next time: Search
"api" β myorg/api/storage appears first!
- The more you select a project, the higher it ranks
- Query-specific boost: projects selected for specific search terms rank higher for those terms
- Recent selections get extra boost (last 7 days)
Starred Favorites (Automatic):
- β Starred projects get +50 points boost automatically
- Works seamlessly - just star projects in GitLab, no configuration needed
Scoring Priority: Usage History > Starred Projects > Search Relevance
History is stored in ~/.cache/glf/history.gob and persists across sessions.
π§ Development
Building
# Build for current platform
make build
# Build for all platforms
make build-all
# Build for specific platform
make build-linux
make build-macos
make build-windows
# Create release archives
make release
Testing
# Run tests
make test
# Run tests with coverage
make test-coverage
# Format code
make fmt
# Run linters
make lint
Releasing
GLF uses automated CI/CD for releases via GitHub Actions and GoReleaser.
Automatic Release Process
When a new version tag is pushed, the release workflow automatically:
- β
Builds binaries for all supported platforms (macOS, Linux, Windows, FreeBSD, OpenBSD)
- β
Creates Linux packages (.deb, .rpm, .apk, Arch Linux)
- β
Creates GitHub Release with artifacts and changelog
- β
Updates Homebrew tap for macOS/Linux users
- β
Updates MacPorts Portfile for macOS users
- β
Updates Scoop bucket for Windows users
Creating a New Release
# Create and push a version tag
git tag v0.3.0
git push origin v0.3.0
# GitHub Actions will automatically:
# - Run GoReleaser
# - Build cross-platform binaries
# - Create GitHub release
# - Update package managers (Homebrew, MacPorts, Scoop)
Manual Release (optional)
You can also trigger releases manually from GitHub Actions UI:
- Go to Actions β Release β Run workflow
Project Structure
glf/
βββ cmd/glf/ # CLI entry point
β βββ main.go # Main command and search logic
βββ internal/
β βββ config/ # Configuration handling
β βββ gitlab/ # GitLab API client
β βββ history/ # Selection frequency tracking
β βββ index/ # Description indexing (Bleve)
β βββ logger/ # Logging utilities
β βββ search/ # Combined fuzzy + full-text search
β βββ sync/ # Sync logic
β βββ tui/ # Terminal UI (Bubbletea)
β βββ types/ # Shared types
βββ Makefile # Build automation
βββ README.md
βοΈ Configuration Options
GitLab Settings
| Option |
Description |
Default |
Required |
gitlab.url |
GitLab instance URL |
- |
Yes |
gitlab.token |
Personal Access Token |
- |
Yes |
gitlab.timeout |
API timeout in seconds |
30 |
No |
Cache Settings
| Option |
Description |
Default |
Required |
cache.dir |
Cache directory path |
~/.cache/glf |
No |
Exclusions
| Option |
Description |
Default |
Required |
exclusions |
List of project paths to exclude |
[] |
No |
Example with exclusions:
gitlab:
url: "https://gitlab.example.com"
token: "your-token"
exclusions:
- "archived/old-project"
- "deprecated/legacy-api"
Excluded projects can be toggled with Ctrl+X in the TUI or hidden/shown with Ctrl+H.
π Troubleshooting
Connection Issues
# Use verbose mode to see detailed logs
glf sync --verbose
Common issues:
- Invalid GitLab URL: Verify URL in config
- Token expired: Regenerate token in GitLab
- Network timeout: Increase timeout in config
- Insufficient permissions: Ensure token has
read_api scope
Cache Issues
# Check cache location
ls -la ~/.cache/glf/
# Clear cache and re-sync
rm -rf ~/.cache/glf/
glf sync
Configuration Issues
# Reconfigure GitLab connection
glf --init
# Reset and reconfigure from scratch
glf --init --reset
# Check current configuration
cat ~/.config/glf/config.yaml
π License
MIT License - see LICENSE file for details.
π€ Contributing
Contributions are welcome! Please feel free to submit issues and pull requests.
π Acknowledgments