CRUSH.md

 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- **Lint**: `task lint` (golangci-lint run) or `task lint-fix` (with --fix)
 8- **Format**: `task fmt` (gofumpt -w .)
 9- **Dev**: `task dev` (runs with profiling enabled)
10
11## Available Tools
12
13### VS Code Diff Tool
14
15The `vscode_diff` tool opens VS Code with a diff view to compare two pieces of content. **VS Code diff is automatically enabled when running inside VS Code** (when `VSCODE_INJECTION=1` environment variable is set).
16
17**Default Behavior:**
18- **Automatic for file modifications**: Opens VS Code diff when using `write` or `edit` tools (only when inside VS Code)
19- **Default for explicit diff requests**: When you ask to "show a diff" or "compare files", VS Code is preferred over terminal output (only when inside VS Code)
20- **Smart fallback**: Uses terminal diff when not running inside VS Code or if VS Code is not available
21- Only opens if there are actual changes (additions or removals)
22- Requires user permission (requested once per session)
23
24**Configuration:**
25```json
26{
27  "options": {
28    "auto_open_vscode_diff": true  // Default: true when VSCODE_INJECTION=1, false otherwise
29  }
30}
31```
32
33**Manual Usage Example:**
34```json
35{
36  "left_content": "function hello() {\n  console.log('Hello');\n}",
37  "right_content": "function hello() {\n  console.log('Hello World!');\n}",
38  "left_title": "before.js",
39  "right_title": "after.js", 
40  "language": "javascript"
41}
42```
43
44**Requirements:**
45- VS Code must be installed
46- The `code` command must be available in PATH
47- Must be running inside VS Code (VSCODE_INJECTION=1 environment variable)
48- User permission will be requested before opening VS Code
49
50## Code Style Guidelines
51
52- **Imports**: Use goimports formatting, group stdlib, external, internal packages
53- **Formatting**: Use gofumpt (stricter than gofmt), enabled in golangci-lint
54- **Naming**: Standard Go conventions - PascalCase for exported, camelCase for unexported
55- **Types**: Prefer explicit types, use type aliases for clarity (e.g., `type AgentName string`)
56- **Error handling**: Return errors explicitly, use `fmt.Errorf` for wrapping
57- **Context**: Always pass context.Context as first parameter for operations
58- **Interfaces**: Define interfaces in consuming packages, keep them small and focused
59- **Structs**: Use struct embedding for composition, group related fields
60- **Constants**: Use typed constants with iota for enums, group in const blocks
61- **Testing**: Use testify/assert and testify/require, parallel tests with `t.Parallel()`
62- **JSON tags**: Use snake_case for JSON field names
63- **File permissions**: Use octal notation (0o755, 0o644) for file permissions
64- **Comments**: End comments in periods unless comments are at the end of the line.
65
66## Testing with Mock Providers
67
68When writing tests that involve provider configurations, use the mock providers to avoid API calls:
69
70```go
71func TestYourFunction(t *testing.T) {
72    // Enable mock providers for testing
73    originalUseMock := config.UseMockProviders
74    config.UseMockProviders = true
75    defer func() {
76        config.UseMockProviders = originalUseMock
77        config.ResetProviders()
78    }()
79
80    // Reset providers to ensure fresh mock data
81    config.ResetProviders()
82
83    // Your test code here - providers will now return mock data
84    providers := config.Providers()
85    // ... test logic
86}
87```
88
89## Formatting
90
91- ALWAYS format any Go code you write.
92  - First, try `goftumpt -w .`.
93  - If `gofumpt` is not available, use `goimports`.
94  - If `goimports` is not available, use `gofmt`.
95  - You can also use `task fmt` to run `gofumpt -w .` on the entire project,
96    as long as `gofumpt` is on the `PATH`.