@@ -1,15 +1,25 @@
11# UI Development Instructions
22
33## General Guidelines
4+
45- Never use commands to send messages when you can directly mutate children or state.
56- Keep things simple; do not overcomplicate.
67- Create files if needed to separate logic; do not nest models.
78- Never do IO or expensive work in `Update`; always use a `tea.Cmd`.
89- Never change the model state inside of a command use messages and than update the state in the main loop
10+- Use the `github.com/charmbracelet/x/ansi` package for any string manipulation
11+ that might involves ANSI codes. Do not manipulate ANSI strings at byte level!
12+ Some useful functions:
13+ * `ansi.Cut`
14+ * `ansi.StringWidth`
15+ * `ansi.Strip`
16+ * `ansi.Truncate`
17+
918
1019## Architecture
1120
1221### Main Model (`model/ui.go`)
22+
1323Keep most of the logic and state in the main model. This is where:
1424- Message routing happens
1525- Focus and UI state is managed
@@ -17,35 +27,42 @@ Keep most of the logic and state in the main model. This is where:
1727- Dialogs are orchestrated
1828
1929### Components Should Be Dumb
30+
2031Components should not handle bubbletea messages directly. Instead:
2132- Expose methods for state changes
2233- Return `tea.Cmd` from methods when side effects are needed
2334- Handle their own rendering via `Render(width int) string`
2435
2536### Chat Logic (`model/chat.go`)
37+
2638Most 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`).
2739
2840## Key Patterns
2941
3042### Composition Over Inheritance
43+
3144Use struct embedding for shared behaviors. See `chat/messages.go` for examples of reusable embedded structs for highlighting, caching, and focus.
3245
3346### Interfaces
47+
3448- List item interfaces are in `list/item.go`
3549- Chat message interfaces are in `chat/messages.go`
3650- Dialog interface is in `dialog/dialog.go`
3751
3852### Styling
53+
3954- All styles are defined in `styles/styles.go`
4055- Access styles via `*common.Common` passed to components
4156- Use semantic color fields rather than hardcoded colors
4257
4358### Dialogs
59+
4460- Implement the dialog interface in `dialog/dialog.go`
4561- Return message types from `Update()` to signal actions to the main model
4662- Use the overlay system for managing dialog lifecycle
4763
4864## File Organization
65+
4966- `model/` - Main UI model and major components (chat, sidebar, etc.)
5067- `chat/` - Chat message item types and renderers
5168- `dialog/` - Dialog implementations
@@ -56,6 +73,7 @@ Use struct embedding for shared behaviors. See `chat/messages.go` for examples o
5673- `logo/` - Logo rendering
5774
5875## Common Gotchas
76+
5977- Always account for padding/borders in width calculations
6078- Use `tea.Batch()` when returning multiple commands
6179- Pass `*common.Common` to components that need styles or app access