1# Crush Development Guide
2
3## Build/Test/Lint Commands
4
5- **Build**: `go build .` or `go run .`
6- **Test**: `task test` or `go test ./...` (run single test: `go test ./internal/llm/prompt -run TestGetContextFromPaths`)
7- **Update Golden Files**: `go test ./... -update` (regenerates .golden files when test output changes)
8 - Update specific package: `go test ./internal/tui/components/core -update` (in this case, we're updating "core")
9- **Lint**: `task lint:fix`
10- **Format**: `task fmt` (`gofumpt -w .`)
11- **Modernize**: `task modernize` (runs `modernize` which make code simplifications)
12- **Dev**: `task dev` (runs with profiling enabled)
13- **Pre-commit flow**: `task fmt lint-fix test`
14
15## Code Style Guidelines
16
17- **Imports**: Use `goimports` formatting, group stdlib, external, internal packages
18- **Formatting**: Use gofumpt (stricter than gofmt), enabled in golangci-lint
19- **Naming**: Standard Go conventions - PascalCase for exported, camelCase for unexported
20- **Types**: Prefer explicit types, use type aliases for clarity (e.g., `type AgentName string`)
21- **Error handling**: Return errors explicitly, use `fmt.Errorf` for wrapping
22- **Context**: Always pass `context.Context` as first parameter for operations
23- **Interfaces**: Define interfaces in consuming packages, keep them small and focused
24- **Structs**: Use struct embedding for composition, group related fields
25- **Constants**: Use typed constants with iota for enums, group in const blocks
26- **Testing**: Use testify's `require` package, parallel tests with `t.Parallel()`,
27 `t.SetEnv()` to set environment variables. Always use `t.Tempdir()` when in
28 need of a temporary directory. This directory does not need to be removed.
29- **JSON tags**: Use snake_case for JSON field names
30- **File permissions**: Use octal notation (0o755, 0o644) for file permissions
31- **Log messages**: Log messages must start with a capital letter (e.g., "Failed to save session" not "failed to save session")
32 - This is enforced by `task lint:log` which runs as part of `task lint`
33- **Comments**: End comments in periods unless comments are at the end of the line.
34
35## Testing with Mock Providers
36
37When writing tests that involve provider configurations, use the mock providers to avoid API calls:
38
39```go
40func TestYourFunction(t *testing.T) {
41 // Enable mock providers for testing
42 originalUseMock := config.UseMockProviders
43 config.UseMockProviders = true
44 defer func() {
45 config.UseMockProviders = originalUseMock
46 config.ResetProviders()
47 }()
48
49 // Reset providers to ensure fresh mock data
50 config.ResetProviders()
51
52 // Your test code here - providers will now return mock data
53 providers := config.Providers()
54 // ... test logic
55}
56```
57
58## Formatting
59
60- ALWAYS format any Go code you write.
61 - First, try `gofumpt -w .`.
62 - If `gofumpt` is not available, use `goimports`.
63 - If `goimports` is not available, use `gofmt`.
64 - You can also use `task fmt` to run `gofumpt -w .` on the entire project,
65 as long as `gofumpt` is on the `PATH`.
66
67## Comments
68
69- Comments that live on their own lines should start with capital letters and
70 end with periods. Wrap comments at 78 columns.
71
72## Committing
73
74- ALWAYS use semantic commits (`fix:`, `feat:`, `chore:`, `refactor:`, `docs:`, `sec:`, etc).
75- Try to keep commits to one line, not including your attribution. Only use
76 multi-line commits when additional context is truly necessary.
77
78## Working on the TUI (UI)
79Anytime you need to work on the tui before starting work read the internal/ui/AGENTS.md file