chore: update AGENTS.md (#2388)

Christian Rocha created

Change summary

AGENTS.md | 142 +++++++++++++++++++++++++++++++++++++++++++++++---------
1 file changed, 118 insertions(+), 24 deletions(-)

Detailed changes

AGENTS.md 🔗

@@ -1,39 +1,130 @@
 # Crush Development Guide
 
+## Project Overview
+
+Crush is a terminal-based AI coding assistant built in Go by
+[Charm](https://charm.land). It connects to LLMs and gives them tools to read,
+write, and execute code. It supports multiple providers (Anthropic, OpenAI,
+Gemini, Bedrock, Copilot, Hyper, MiniMax, Vercel, and more), integrates with
+LSPs for code intelligence, and supports extensibility via MCP servers and
+agent skills.
+
+The module path is `github.com/charmbracelet/crush`.
+
+## Architecture
+
+```
+main.go                            CLI entry point (cobra via internal/cmd)
+internal/
+  app/app.go                       Top-level wiring: DB, config, agents, LSP, MCP, events
+  cmd/                             CLI commands (root, run, login, models, stats, sessions)
+  config/
+    config.go                      Config struct, context file paths, agent definitions
+    load.go                        crush.json loading and validation
+    provider.go                    Provider configuration and model resolution
+  agent/
+    agent.go                       SessionAgent: runs LLM conversations per session
+    coordinator.go                 Coordinator: manages named agents ("coder", "task")
+    prompts.go                     Loads Go-template system prompts
+    templates/                     System prompt templates (coder.md.tpl, task.md.tpl, etc.)
+    tools/                         All built-in tools (bash, edit, view, grep, glob, etc.)
+      mcp/                         MCP client integration
+  session/session.go               Session CRUD backed by SQLite
+  message/                         Message model and content types
+  db/                              SQLite via sqlc, with migrations
+    sql/                           Raw SQL queries (consumed by sqlc)
+    migrations/                    Schema migrations
+  lsp/                             LSP client manager, auto-discovery, on-demand startup
+  ui/                              Bubble Tea v2 TUI (see internal/ui/AGENTS.md)
+  permission/                      Tool permission checking and allow-lists
+  skills/                          Skill file discovery and loading
+  shell/                           Bash command execution with background job support
+  event/                           Telemetry (PostHog)
+  pubsub/                          Internal pub/sub for cross-component messaging
+  filetracker/                     Tracks files touched per session
+  history/                         Prompt history
+```
+
+### Key Dependency Roles
+
+- **`charm.land/fantasy`**: LLM provider abstraction layer. Handles protocol
+  differences between Anthropic, OpenAI, Gemini, etc. Used in `internal/app`
+  and `internal/agent`.
+- **`charm.land/bubbletea/v2`**: TUI framework powering the interactive UI.
+- **`charm.land/lipgloss/v2`**: Terminal styling.
+- **`charm.land/glamour/v2`**: Markdown rendering in the terminal.
+- **`charm.land/catwalk`**: Snapshot/golden-file testing for TUI components.
+- **`sqlc`**: Generates Go code from SQL queries in `internal/db/sql/`.
+
+### Key Patterns
+
+- **Config is a Service**: accessed via `config.Service`, not global state.
+- **Tools are self-documenting**: each tool has a `.go` implementation and a
+  `.md` description file in `internal/agent/tools/`.
+- **System prompts are Go templates**: `internal/agent/templates/*.md.tpl`
+  with runtime data injected.
+- **Context files**: Crush reads AGENTS.md, CRUSH.md, CLAUDE.md, GEMINI.md
+  (and `.local` variants) from the working directory for project-specific
+  instructions.
+- **Persistence**: SQLite + sqlc. All queries live in `internal/db/sql/`,
+  generated code in `internal/db/`. Migrations in `internal/db/migrations/`.
+- **Pub/sub**: `internal/pubsub` for decoupled communication between agent,
+  UI, and services.
+- **CGO disabled**: builds with `CGO_ENABLED=0` and
+  `GOEXPERIMENT=greenteagc`.
+
 ## Build/Test/Lint Commands
 
 - **Build**: `go build .` or `go run .`
-- **Test**: `task test` or `go test ./...` (run single test: `go test ./internal/llm/prompt -run TestGetContextFromPaths`)
-- **Update Golden Files**: `go test ./... -update` (regenerates .golden files when test output changes)
-  - Update specific package: `go test ./internal/tui/components/core -update` (in this case, we're updating "core")
+- **Test**: `task test` or `go test ./...` (run single test:
+  `go test ./internal/llm/prompt -run TestGetContextFromPaths`)
+- **Update Golden Files**: `go test ./... -update` (regenerates `.golden`
+  files when test output changes)
+  - Update specific package:
+    `go test ./internal/tui/components/core -update` (in this case,
+    we're updating "core")
 - **Lint**: `task lint:fix`
 - **Format**: `task fmt` (`gofumpt -w .`)
-- **Modernize**: `task modernize` (runs `modernize` which make code simplifications)
+- **Modernize**: `task modernize` (runs `modernize` which makes code
+  simplifications)
 - **Dev**: `task dev` (runs with profiling enabled)
 
 ## Code Style Guidelines
 
-- **Imports**: Use `goimports` formatting, group stdlib, external, internal packages
-- **Formatting**: Use gofumpt (stricter than gofmt), enabled in golangci-lint
-- **Naming**: Standard Go conventions - PascalCase for exported, camelCase for unexported
-- **Types**: Prefer explicit types, use type aliases for clarity (e.g., `type AgentName string`)
-- **Error handling**: Return errors explicitly, use `fmt.Errorf` for wrapping
-- **Context**: Always pass `context.Context` as first parameter for operations
-- **Interfaces**: Define interfaces in consuming packages, keep them small and focused
-- **Structs**: Use struct embedding for composition, group related fields
-- **Constants**: Use typed constants with iota for enums, group in const blocks
-- **Testing**: Use testify's `require` package, parallel tests with `t.Parallel()`,
-  `t.SetEnv()` to set environment variables. Always use `t.Tempdir()` when in
-  need of a temporary directory. This directory does not need to be removed.
-- **JSON tags**: Use snake_case for JSON field names
-- **File permissions**: Use octal notation (0o755, 0o644) for file permissions
-- **Log messages**: Log messages must start with a capital letter (e.g., "Failed to save session" not "failed to save session")
-  - This is enforced by `task lint:log` which runs as part of `task lint`
-- **Comments**: End comments in periods unless comments are at the end of the line.
+- **Imports**: Use `goimports` formatting, group stdlib, external, internal
+  packages.
+- **Formatting**: Use gofumpt (stricter than gofmt), enabled in
+  golangci-lint.
+- **Naming**: Standard Go conventions — PascalCase for exported, camelCase
+  for unexported.
+- **Types**: Prefer explicit types, use type aliases for clarity (e.g.,
+  `type AgentName string`).
+- **Error handling**: Return errors explicitly, use `fmt.Errorf` for
+  wrapping.
+- **Context**: Always pass `context.Context` as first parameter for
+  operations.
+- **Interfaces**: Define interfaces in consuming packages, keep them small
+  and focused.
+- **Structs**: Use struct embedding for composition, group related fields.
+- **Constants**: Use typed constants with iota for enums, group in const
+  blocks.
+- **Testing**: Use testify's `require` package, parallel tests with
+  `t.Parallel()`, `t.SetEnv()` to set environment variables. Always use
+  `t.Tempdir()` when in need of a temporary directory. This directory does
+  not need to be removed.
+- **JSON tags**: Use snake_case for JSON field names.
+- **File permissions**: Use octal notation (0o755, 0o644) for file
+  permissions.
+- **Log messages**: Log messages must start with a capital letter (e.g.,
+  "Failed to save session" not "failed to save session").
+  - This is enforced by `task lint:log` which runs as part of `task lint`.
+- **Comments**: End comments in periods unless comments are at the end of the
+  line.
 
 ## Testing with Mock Providers
 
-When writing tests that involve provider configurations, use the mock providers to avoid API calls:
+When writing tests that involve provider configurations, use the mock
+providers to avoid API calls:
 
 ```go
 func TestYourFunction(t *testing.T) {
@@ -70,9 +161,12 @@ func TestYourFunction(t *testing.T) {
 
 ## Committing
 
-- ALWAYS use semantic commits (`fix:`, `feat:`, `chore:`, `refactor:`, `docs:`, `sec:`, etc).
+- ALWAYS use semantic commits (`fix:`, `feat:`, `chore:`, `refactor:`,
+  `docs:`, `sec:`, etc).
 - Try to keep commits to one line, not including your attribution. Only use
   multi-line commits when additional context is truly necessary.
 
 ## Working on the TUI (UI)
-Anytime you need to work on the tui before starting work read the internal/ui/AGENTS.md file
+
+Anytime you need to work on the TUI, read `internal/ui/AGENTS.md` before
+starting work.