# Add Code Navigation and Investigation Guide for Go LSP Tools Added a new section to the CLAUDE.md documentation that explains how to use Go Language Server Protocol (LSP) tools when working with the Coder codebase. The guide includes: - Commands for finding function definitions, symbol references, and getting symbol information - Examples of LSP usage with specific commands - Guidance on when to use LSP versus other tools like grep or bash - A structured investigation strategy for navigating the codebase, starting with route registration and tracing through to implementations This documentation helps developers more efficiently explore and understand the codebase structure.
15 KiB
Coder Development Guidelines
Read cursor rules.
Quick Start Checklist for New Features
Before Starting
- Run
git pullto ensure you're on latest code - Check if feature touches database - you'll need migrations
- Check if feature touches audit logs - update
enterprise/audit/table.go
Development Server
Starting Development Mode
- Use
./scripts/develop.shto start Coder in development mode - This automatically builds and runs with
--devflag and proper access URL - Do NOT manually run
make build && ./coder server --dev- use the script instead
Build/Test/Lint Commands
Main Commands
make buildormake build-fat- Build all "fat" binaries (includes "server" functionality)make build-slim- Build "slim" binariesmake test- Run Go testsmake test RUN=TestFunctionNameorgo test -v ./path/to/package -run TestFunctionName- Test singlemake test-postgres- Run tests with Postgres databasemake test-race- Run tests with Go race detectormake test-e2e- Run end-to-end testsmake lint- Run all lintersmake fmt- Format all codemake gen- Generates mocks, database queries and other auto-generated files
Frontend Commands (site directory)
pnpm build- Build frontendpnpm dev- Run development serverpnpm check- Run code checkspnpm format- Format frontend codepnpm lint- Lint frontend codepnpm test- Run frontend tests
Code Style Guidelines
Go
- Follow Effective Go and Go's Code Review Comments
- Use
gofumptfor formatting - Create packages when used during implementation
- Validate abstractions against implementations
- Test packages: Use
package_testnaming (e.g.,identityprovider_test) for black-box testing
Error Handling
- Use descriptive error messages
- Wrap errors with context
- Propagate errors appropriately
- Use proper error types
- (
xerrors.Errorf("failed to X: %w", err))
Naming
- Use clear, descriptive names
- Abbreviate only when obvious
- Follow Go and TypeScript naming conventions
Comments
- Document exported functions, types, and non-obvious logic
- Follow JSDoc format for TypeScript
- Use godoc format for Go code
Commit Style
- Follow Conventional Commits 1.0.0
- Format:
type(scope): message - Types:
feat,fix,docs,style,refactor,test,chore - Keep message titles concise (~70 characters)
- Use imperative, present tense in commit titles
Database Work
Migration Guidelines
-
Create migration files:
- Location:
coderd/database/migrations/ - Format:
{number}_{description}.{up|down}.sql - Number must be unique and sequential
- Always include both up and down migrations
- Use helper scripts:
./coderd/database/migrations/create_migration.sh "migration name"- Creates new migration files./coderd/database/migrations/fix_migration_numbers.sh- Renumbers migrations to avoid conflicts./coderd/database/migrations/create_fixture.sh "fixture name"- Creates test fixtures for migrations
- Location:
-
Update database queries:
- MUST DO! Any changes to database - adding queries, modifying queries should be done in the
coderd/database/queries/*.sqlfiles - MUST DO! Queries are grouped in files relating to context - e.g.
prebuilds.sql,users.sql,oauth2.sql - After making changes to any
coderd/database/queries/*.sqlfiles you must runmake gento generate respective ORM changes
- MUST DO! Any changes to database - adding queries, modifying queries should be done in the
-
Handle nullable fields:
-
Use
sql.NullString,sql.NullBool, etc. for optional database fields -
Set
.Valid = truewhen providing values -
Example:
CodeChallenge: sql.NullString{ String: params.codeChallenge, Valid: params.codeChallenge != "", }
-
-
Audit table updates:
- If adding fields to auditable types, update
enterprise/audit/table.go - Add each new field with appropriate action (ActionTrack, ActionIgnore, ActionSecret)
- Run
make gento verify no audit errors
- If adding fields to auditable types, update
-
In-memory database (dbmem) updates:
- When adding new fields to database structs, ensure
dbmemimplementation copies all fields - Check
coderd/database/dbmem/dbmem.gofor Insert/Update methods - Missing fields in dbmem can cause tests to fail even if main implementation is correct
- When adding new fields to database structs, ensure
Database Generation Process
- Modify SQL files in
coderd/database/queries/ - Run
make gen - If errors about audit table, update
enterprise/audit/table.go - Run
make genagain - Run
make lintto catch any remaining issues
In-Memory Database Testing
When adding new database fields:
- CRITICAL: Update
coderd/database/dbmem/dbmem.goin-memory implementations - The
Insert*functions must include ALL new fields, not just basic ones - Common issue: Tests pass with real database but fail with in-memory database due to missing field mappings
- Always verify in-memory database functions match the real database schema after migrations
Example pattern:
// In dbmem.go - ensure ALL fields are included
code := database.OAuth2ProviderAppCode{
ID: arg.ID,
CreatedAt: arg.CreatedAt,
// ... existing fields ...
ResourceUri: arg.ResourceUri, // New field
CodeChallenge: arg.CodeChallenge, // New field
CodeChallengeMethod: arg.CodeChallengeMethod, // New field
}
Architecture
Core Components
- coderd: Main API service connecting workspaces, provisioners, and users
- provisionerd: Execution context for infrastructure-modifying providers
- Agents: Services in remote workspaces providing features like SSH and port forwarding
- Workspaces: Cloud resources defined by Terraform
Adding New API Endpoints
- Define types in
codersdk/package - Add handler in appropriate
coderd/file - Register route in
coderd/coderd.go - Add tests in
coderd/*_test.gofiles - Update OpenAPI by running
make gen
Sub-modules
Template System
- Templates define infrastructure for workspaces using Terraform
- Environment variables pass context between Coder and templates
- Official modules extend development environments
RBAC System
- Permissions defined at site, organization, and user levels
- Object-Action model protects resources
- Built-in roles: owner, member, auditor, templateAdmin
- Permission format:
<sign>?<level>.<object>.<id>.<action>
Database
- PostgreSQL 13+ recommended for production
- Migrations managed with
migrate - Database authorization through
dbauthzpackage
Frontend
The frontend is contained in the site folder.
For building Frontend refer to this document
Common Patterns
OAuth2/Authentication Work
- Types go in
codersdk/oauth2.goor similar - Handlers go in
coderd/oauth2.goorcoderd/identityprovider/ - Database fields need migration + audit table updates
- Always support backward compatibility
OAuth2 Development
OAuth2 Provider Implementation
When working on OAuth2 provider features:
-
OAuth2 Spec Compliance:
- Follow RFC 6749 for token responses
- Use
expires_in(seconds) notexpiry(timestamp) in token responses - Return proper OAuth2 error format:
{"error": "code", "error_description": "details"}
-
Error Response Format:
- Create OAuth2-compliant error responses for token endpoint
- Use standard error codes:
invalid_client,invalid_grant,invalid_request - Avoid generic error responses for OAuth2 endpoints
-
Testing OAuth2 Features:
- Use scripts in
./scripts/oauth2/for testing - Run
./scripts/oauth2/test-mcp-oauth2.shfor comprehensive tests - Manual testing: use
./scripts/oauth2/test-manual-flow.sh
- Use scripts in
-
PKCE Implementation:
- Support both with and without PKCE for backward compatibility
- Use S256 method for code challenge
- Properly validate code_verifier against stored code_challenge
-
UI Authorization Flow:
- Use POST requests for consent, not GET with links
- Avoid dependency on referer headers for security decisions
- Support proper state parameter validation
-
RFC 8707 Resource Indicators:
- Store resource parameters in database for server-side validation (opaque tokens)
- Validate resource consistency between authorization and token requests
- Support audience validation in refresh token flows
- Resource parameter is optional but must be consistent when provided
OAuth2 Error Handling Pattern
// Define specific OAuth2 errors
var (
errInvalidPKCE = xerrors.New("invalid code_verifier")
)
// Use OAuth2-compliant error responses
type OAuth2Error struct {
Error string `json:"error"`
ErrorDescription string `json:"error_description,omitempty"`
}
// Return proper OAuth2 errors
if errors.Is(err, errInvalidPKCE) {
writeOAuth2Error(ctx, rw, http.StatusBadRequest, "invalid_grant", "The PKCE code verifier is invalid")
return
}
Testing Patterns
- Use table-driven tests for comprehensive coverage
- Mock external dependencies
- Test both positive and negative cases
- Use
testutil.WaitLongfor timeouts in tests
Code Navigation and Investigation
Using Go LSP Tools (STRONGLY RECOMMENDED)
IMPORTANT: Always use Go LSP tools for code navigation and understanding. These tools provide accurate, real-time analysis of the codebase and should be your first choice for code investigation.
When working with the Coder codebase, leverage Go Language Server Protocol tools for efficient code navigation:
-
Find function definitions (USE THIS FREQUENTLY):
mcp__go-language-server__definition symbolName- Example:
mcp__go-language-server__definition getOAuth2ProviderAppAuthorize - Example:
mcp__go-language-server__definition ExtractAPIKeyMW - Quickly jump to function implementations across packages
- Use this when: You see a function call and want to understand its implementation
- Tip: Include package prefix if symbol is ambiguous (e.g.,
httpmw.ExtractAPIKeyMW)
- Example:
-
Find symbol references (ESSENTIAL FOR UNDERSTANDING IMPACT):
mcp__go-language-server__references symbolName- Example:
mcp__go-language-server__references APITokenFromRequest - Locate all usages of functions, types, or variables
- Understand code dependencies and call patterns
- Use this when: Making changes to understand what code might be affected
- Critical for: Refactoring, deprecating functions, or understanding data flow
- Example:
-
Get symbol information (HELPFUL FOR TYPE INFO):
mcp__go-language-server__hover filePath line column- Example:
mcp__go-language-server__hover /Users/thomask33/Projects/coder/coderd/httpmw/apikey.go 560 25 - Get type information and documentation at specific positions
- Use this when: You need to understand the type of a variable or return value
- Example:
-
Edit files using LSP (WHEN MAKING TARGETED CHANGES):
mcp__go-language-server__edit_file filePath edits- Make precise edits using line numbers
- Use this when: You need to make small, targeted changes to specific lines
-
Get diagnostics (ALWAYS CHECK AFTER CHANGES):
mcp__go-language-server__diagnostics filePath- Check for compilation errors, unused imports, etc.
- Use this when: After making changes to ensure code is still valid
LSP Tool Usage Priority
ALWAYS USE THESE TOOLS FIRST:
- Use LSP
definitioninstead of manual searching for function implementations - Use LSP
referencesinstead of grep when looking for function/type usage - Use LSP
hoverto understand types and signatures - Use LSP
diagnosticsafter making changes to check for errors
When to use other tools:
- Use Grep for: Text-based searches, finding patterns across files, searching comments
- Use Bash for: Running tests, git commands, build operations
- Use Read tool for: Reading configuration files, documentation, non-Go files
Investigation Strategy (LSP-First Approach)
- Start with route registration in
coderd/coderd.goto understand API endpoints - Use LSP
definitionlookup to trace from route handlers to actual implementations - Use LSP
referencesto understand how functions are called throughout the codebase - Follow the middleware chain using LSP tools to understand request processing flow
- Check test files for expected behavior and error patterns
- Use LSP
diagnosticsto ensure your changes don't break compilation
Common LSP Workflows
Understanding a new feature:
- Use
grepto find the main entry point (e.g., route registration) - Use LSP
definitionto jump to handler implementation - Use LSP
referencesto see how the handler is used - Use LSP
definitionon each function call within the handler
Making changes to existing code:
- Use LSP
referencesto understand the impact of your changes - Use LSP
definitionto understand the current implementation - Make your changes using
Editor LSPedit_file - Use LSP
diagnosticsto verify your changes compile correctly - Run tests to ensure functionality still works
Debugging issues:
- Use LSP
definitionto find the problematic function - Use LSP
referencesto trace how the function is called - Use LSP
hoverto understand parameter types and return values - Use
Readto examine the full context around the issue
Testing Scripts
OAuth2 Test Scripts
Located in ./scripts/oauth2/:
test-mcp-oauth2.sh- Full automated test suitesetup-test-app.sh- Create test OAuth2 appcleanup-test-app.sh- Remove test appgenerate-pkce.sh- Generate PKCE parameterstest-manual-flow.sh- Manual browser testing
Always run the full test suite after OAuth2 changes:
./scripts/oauth2/test-mcp-oauth2.sh
Troubleshooting
Common Issues
- "Audit table entry missing action" - Update
enterprise/audit/table.go - "package should be X_test" - Use
package_testnaming for test files - SQL type errors - Use
sql.Null*types for nullable fields - Missing newlines - Ensure files end with newline character
- Tests passing locally but failing in CI - Check if
dbmemimplementation needs updating - OAuth2 endpoints returning wrong error format - Ensure OAuth2 endpoints return RFC 6749 compliant errors
- OAuth2 tests failing but scripts working - Check in-memory database implementations in
dbmem.go - Resource indicator validation failing - Ensure database stores and retrieves resource parameters correctly
- PKCE tests failing - Verify both authorization code storage and token exchange handle PKCE fields