Contributing
How to contribute to grepai
Getting Started
- Fork and clone the repository:
git clone https://github.com/YOUR_USERNAME/grepai.git
cd grepai
- Install dependencies:
go mod download
- Run tests:
make test
- Build:
make build
Development Commands
# Build the binary
make build
# Run tests with race detection
make test
# Run tests with coverage
make test-cover
# Format code with gofmt
make fmt
# Lint with golangci-lint
make lint
# Run ALL checks before committing (recommended)
make pre-commit
# Build and run
make run
# Cross-compile for all platforms
make build-all
# Generate CLI documentation
make docs-generate
Before Committing
Always run the pre-commit checks before pushing your changes:
make pre-commit
This single command will:
- Format all Go files with
gofmt - Vet - detect common errors with
go vet - Lint - run comprehensive checks with
golangci-lint - Test - run all tests with race detection
If all checks pass, you’re ready to commit!
Project Structure
grepai/
├── cli/ # CLI commands (Cobra)
│ ├── root.go
│ ├── init.go
│ ├── watch.go
│ ├── search.go
│ └── status.go
├── config/ # Configuration loading
├── embedder/ # Embedding providers
│ ├── embedder.go # Interface
│ ├── ollama.go
│ └── openai.go
├── store/ # Vector storage
│ ├── store.go # Interface
│ ├── gob.go
│ └── postgres.go
├── indexer/ # Indexing logic
│ ├── scanner.go # File walking
│ ├── chunker.go # Text splitting
│ └── indexer.go # Orchestration
├── search/ # Search logic
├── watcher/ # File watching
└── docs/ # Documentation (Astro/Starlight)
Adding a New Embedder
- Create a new file in
embedder/:
// embedder/myembedder.go
package embedder
type MyEmbedder struct {
// ...
}
func NewMyEmbedder(config Config) (*MyEmbedder, error) {
// ...
}
func (e *MyEmbedder) Embed(ctx context.Context, text string) ([]float32, error) {
// ...
}
func (e *MyEmbedder) EmbedBatch(ctx context.Context, texts []string) ([][]float32, error) {
// ...
}
func (e *MyEmbedder) Dimensions() int {
return 768 // or whatever your embedder produces
}
-
Add configuration in
config/config.go -
Wire it up in CLI commands
Adding a New Store
- Create a new file in
store/:
// store/mystore.go
package store
type MyStore struct {
// ...
}
func NewMyStore(config Config) (*MyStore, error) {
// ...
}
func (s *MyStore) Store(ctx context.Context, chunks []Chunk) error {
// ...
}
func (s *MyStore) Search(ctx context.Context, embedding []float32, limit int) ([]Result, error) {
// ...
}
func (s *MyStore) Delete(ctx context.Context, filePath string) error {
// ...
}
func (s *MyStore) Close() error {
// ...
}
-
Add configuration in
config/config.go -
Wire it up in CLI commands
Commit Convention
Follow conventional commits:
type(scope): description
Types: feat, fix, docs, style, refactor, test, chore
Examples:
feat(embedder): add support for Cohere embeddings
fix(watcher): handle symlink loops gracefully
docs(readme): update installation instructions
Pull Request Process
- Create a feature branch:
git checkout -b feat/my-feature
-
Make your changes and commit
-
Run pre-commit checks:
make pre-commit
- Push and create a PR:
git push origin feat/my-feature
- Fill out the PR template
Code Style
- Follow standard Go conventions
- Run
make lintbefore committing - Keep functions focused and small
- Add tests for new functionality
- Document exported types and functions