Files
nebula/AGENTS.md

228 lines
5.1 KiB
Markdown
Raw Permalink Normal View History

# AGENTS.md - Nebula Project Guidelines
## Project Overview
Nebula is a Go/Templ wallet application with HTMX 4 for server-driven UI and WebAwesome (wa-*) web components.
**Stack**: Go 1.25+ | templ v0.3.977 | htmx 4.0.0-alpha5 | WebAwesome | SQLite WASM
## Build & Run Commands
```bash
# Generate Go code from .templ files (REQUIRED after any .templ changes)
templ generate
# Build the project
go build ./...
# Run development server (serves on :8080)
go run main.go
# Watch mode for templ files
templ generate --watch
# Full build + run + open browser
make all
```
## Directory Structure
```
nebula/
├── models/ # Data types (MVC models)
├── views/ # Page templates (.templ)
├── layouts/ # Base layouts (DashboardLayout, CenteredLayout)
├── components/ # Reusable UI components
├── handlers/ # HTTP route handlers
├── _migrate/ # HTML prototypes to convert
├── HTMX.md # htmx 4 patterns documentation
└── SQLC.md # Database schema documentation
```
## Code Style
### Go Files
- Standard `gofmt` formatting
- Package-level types in `models/` directory
- Handlers in `handlers/routes.go` with pattern: `handleX(w http.ResponseWriter, r *http.Request)`
- Use `r.Header.Get("HX-Request") == "true"` to detect HTMX requests
- Return partials for HTMX, full pages for direct navigation
### Templ Files (.templ)
- One main page template per file: `PageName(data ModelType) templ.Component`
- Helper functions lowercase: `helperName()`
- CSS-in-templ using `templ css` blocks or `<style>` tags
- Component parameters use Go types from `models/` package
### Naming Conventions
| Type | Convention | Example |
|------|------------|---------|
| Page template | `XxxPage` | `SettingsPage`, `DashboardPage` |
| Partial template | `XxxContent`, `XxxTab` | `DashboardContent`, `ProfileTab` |
| OOB update | `XxxWithOOB`, `XxxWithStepper` | `LoginStepWithOOB` |
| Model struct | PascalCase | `SettingsData`, `ProfileSettings` |
| Handler func | `handleXxx` | `handleSettings`, `handleDashboard` |
## HTMX 4 Patterns
### Partial Updates
```html
<div hx-get="/endpoint" hx-target="#target" hx-swap="innerHTML">
```
### Out-of-Band Updates
```go
templ ComponentWithOOB() {
@MainContent()
<div id="sidebar" hx-swap-oob="true">
@UpdatedSidebar()
</div>
}
```
### HTMX Request Detection
```go
if r.Header.Get("HX-Request") == "true" {
views.PartialContent(data).Render(r.Context(), w)
return
}
views.FullPage(data).Render(r.Context(), w)
```
## WebAwesome Components
Use `wa-*` web components for UI:
```html
<wa-button variant="brand">Click me</wa-button>
<wa-card>Content</wa-card>
<wa-tab-group>
<wa-tab panel="one">Tab 1</wa-tab>
<wa-tab-panel name="one">Panel 1</wa-tab-panel>
</wa-tab-group>
<wa-icon name="user"></wa-icon>
<wa-avatar initials="JD"></wa-avatar>
```
## Route Registration
All routes in `handlers/routes.go`:
```go
func RegisterRoutes(mux *http.ServeMux) {
mux.HandleFunc("GET /path", handlePath)
mux.HandleFunc("POST /path/action", handleAction)
}
```
Go 1.22+ routing patterns:
- `GET /path` - method prefix
- `GET /path/{param}` - path parameters via `r.PathValue("param")`
- `GET /path/{param...}` - catch-all
## Model Pattern
Models in `models/` package with `DefaultXxxData()` factory functions:
```go
// models/example.go
package models
type ExampleData struct {
Field1 string
Field2 int
Items []Item
}
func DefaultExampleData() ExampleData {
return ExampleData{
Field1: "default",
Items: []Item{...},
}
}
```
## Migration Pattern (HTML to Templ)
When converting `_migrate/*.html` files:
1. Create model types in `models/xxx.go`
2. Create view in `views/xxx.templ`
3. Add route in `handlers/routes.go`
4. Update sidebar active state in `components/sidebar.templ`
### Templ Syntax Reference
```go
// Conditionals
if condition {
<div>shown</div>
}
// Loops
for _, item := range items {
<div>{ item.Name }</div>
}
// Boolean attributes
<input disabled?={ isDisabled } />
<wa-tab active?={ tab == "profile" }>
// String interpolation
<div class={ "base " + extraClass }>
<div data-id={ item.ID }>
// Raw HTML (use sparingly)
@templ.Raw(htmlString)
// Component composition
@ChildComponent(props)
```
## Testing
```bash
# Run all tests
go test ./...
# Run with verbose
go test -v ./...
# Run specific package
go test ./handlers/...
```
## Common Tasks
### Add New Page
1. Create `models/newpage.go` with data types
2. Create `views/newpage.templ` with page template
3. Add handler in `handlers/routes.go`
4. Add nav item in `components/sidebar.templ` if needed
### Add New Component
1. Create in `components/newcomp.templ`
2. Import in views: `import "nebula/components"`
3. Use: `@components.NewComp(props)`
### Modify Layout
Layouts in `layouts/`:
- `base.templ` - HTML document wrapper with htmx CDN
- `app.templ` - Dashboard app shell with sidebar
- `centered.templ` - Centered auth pages
## Dependencies
- **templ**: Template engine - `go install github.com/a-h/templ/cmd/templ@latest`
- **htmx 4**: Loaded from CDN in `layouts/base.templ`
- **WebAwesome**: Loaded from CDN in `layouts/base.templ`