From 7a83144f8629c26d2e45eb28ebfefe9710d91eef Mon Sep 17 00:00:00 2001 From: Andrey Nering Date: Tue, 10 Feb 2026 14:13:14 -0300 Subject: [PATCH] chore: update `AGENTS.md`, mention `x/ansi` package --- AGENTS.md | 7 ++++--- internal/ui/AGENTS.md | 18 ++++++++++++++++++ 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 654f1cd0a7fe1cbb50a3026f86f31b68e04f8043..0691c3b7bdef8bdd1adfde6cb75e5fd0e2e01d60 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -7,17 +7,18 @@ - **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 .) +- **Format**: `task fmt` (`gofumpt -w .`) +- **Modernize**: `task modernize` (runs `modernize` which make code simplifications) - **Dev**: `task dev` (runs with profiling enabled) ## Code Style Guidelines -- **Imports**: Use goimports formatting, group stdlib, external, internal packages +- **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 +- **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 diff --git a/internal/ui/AGENTS.md b/internal/ui/AGENTS.md index 9bb2ceaf20da8b75df3a40390111b2a8be7f94c2..4140bd60820c2799849e2cd6beccaf36d6ef93e2 100644 --- a/internal/ui/AGENTS.md +++ b/internal/ui/AGENTS.md @@ -1,15 +1,25 @@ # UI Development Instructions ## General Guidelines + - Never use commands to send messages when you can directly mutate children or state. - Keep things simple; do not overcomplicate. - Create files if needed to separate logic; do not nest models. - Never do IO or expensive work in `Update`; always use a `tea.Cmd`. - Never change the model state inside of a command use messages and than update the state in the main loop +- Use the `github.com/charmbracelet/x/ansi` package for any string manipulation + that might involves ANSI codes. Do not manipulate ANSI strings at byte level! + Some useful functions: + * `ansi.Cut` + * `ansi.StringWidth` + * `ansi.Strip` + * `ansi.Truncate` + ## Architecture ### Main Model (`model/ui.go`) + Keep most of the logic and state in the main model. This is where: - Message routing happens - Focus and UI state is managed @@ -17,35 +27,42 @@ Keep most of the logic and state in the main model. This is where: - Dialogs are orchestrated ### Components Should Be Dumb + Components should not handle bubbletea messages directly. Instead: - Expose methods for state changes - Return `tea.Cmd` from methods when side effects are needed - Handle their own rendering via `Render(width int) string` ### Chat Logic (`model/chat.go`) + Most chat-related logic belongs here. Individual chat items in `chat/` should be simple renderers that cache their output and invalidate when data changes (see `cachedMessageItem` in `chat/messages.go`). ## Key Patterns ### Composition Over Inheritance + Use struct embedding for shared behaviors. See `chat/messages.go` for examples of reusable embedded structs for highlighting, caching, and focus. ### Interfaces + - List item interfaces are in `list/item.go` - Chat message interfaces are in `chat/messages.go` - Dialog interface is in `dialog/dialog.go` ### Styling + - All styles are defined in `styles/styles.go` - Access styles via `*common.Common` passed to components - Use semantic color fields rather than hardcoded colors ### Dialogs + - Implement the dialog interface in `dialog/dialog.go` - Return message types from `Update()` to signal actions to the main model - Use the overlay system for managing dialog lifecycle ## File Organization + - `model/` - Main UI model and major components (chat, sidebar, etc.) - `chat/` - Chat message item types and renderers - `dialog/` - Dialog implementations @@ -56,6 +73,7 @@ Use struct embedding for shared behaviors. See `chat/messages.go` for examples o - `logo/` - Logo rendering ## Common Gotchas + - Always account for padding/borders in width calculations - Use `tea.Batch()` when returning multiple commands - Pass `*common.Common` to components that need styles or app access