docs(AGENTS): update Nebula project guidelines and knowledge base

This commit is contained in:
2026-01-12 00:21:22 -05:00
parent fcbe848b8a
commit 1deb0c8a27

292
AGENTS.md
View File

@@ -1,227 +1,133 @@
# AGENTS.md - Nebula Project Guidelines
# NEBULA PROJECT KNOWLEDGE BASE
## Project Overview
**Generated:** 2026-01-11 | **Commit:** fcbe848 | **Branch:** feat/pkg
Nebula is a Go/Templ wallet application with HTMX 4 for server-driven UI and WebAwesome (wa-*) web components.
## OVERVIEW
**Stack**: Go 1.25+ | templ v0.3.977 | htmx 4.0.0-alpha5 | WebAwesome | SQLite WASM
Go/Templ wallet UI framework using HTMX 4 for server-driven interactions and WebAwesome (`wa-*`) web components. Hybrid: root is a library (`package nebula`), `cmd/server/` is the reference app.
## 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
## 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
├── cmd/server/ # App entry: main.go + routes.go (handlers HERE, not handlers/)
├── views/ # Page templates (.templ) - XxxPage, XxxContent, XxxWithStepper
├── components/ # Reusable UI (sidebar, stepper, navbar, charts)
├── layouts/ # Base (HTML shell), App (dashboard), Centered (auth)
├── models/ # Data structs + DefaultXxxData() factories
├── htmx/ # HTMX 4 context/request/response helpers
├── pkg/config/ # Config models for middleware injection
── _migrate/ # HTML prototypes pending conversion (technical debt)
├── middleware.go # Injects HTMX + Config into request context
├── mount.go # Mount() helper for handler registration
├── options.go # WithXxx() functional options
└── config.go # DefaultConfig() + Config struct
```
## Code Style
## WHERE TO LOOK
### Go Files
| Task | Location | Notes |
|------|----------|-------|
| Add route | `cmd/server/routes.go` | Go 1.22+ patterns: `GET /path/{param}` |
| Add page | `views/` + `models/` | Create XxxPage + model, register in routes.go |
| HTMX patterns | `HTMX.md` | `<hx-partial>`, morphing, SSE, OOB updates |
| Modify layout | `layouts/base.templ` | CDN scripts, htmx-config meta tag |
| WebAwesome ref | [webawesome.com](https://webawesome.com) | All `wa-*` components |
| Migrate HTML | `_migrate/` -> `views/` | See MIGRATION.md |
- 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
## CONVENTIONS
### Templ Files (.templ)
### Naming
- 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
| Type | Pattern | Example |
|------|---------|---------|
| Page template | `XxxPage(data)` | `DashboardPage(data, tab)` |
| Partial (HTMX) | `XxxContent`, `XxxTab` | `DashboardContent(data, tab)` |
| OOB update | `XxxWithStepper`, `XxxWithOOB` | `WelcomeStepWithStepper(step)` |
| Model | `XxxData`, `XxxState` | `DashboardData`, `LoginState` |
| Factory | `DefaultXxxData()` | `DefaultDashboardData()` |
| Handler | `handleXxx` | `handleDashboard` |
### 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
### HTMX 4 Request Pattern
```go
templ ComponentWithOOB() {
@MainContent()
<div id="sidebar" hx-swap-oob="true">
@UpdatedSidebar()
func handleXxx(w http.ResponseWriter, r *http.Request) {
data := models.DefaultXxxData()
if r.Header.Get("HX-Request") == "true" {
views.XxxContent(data).Render(r.Context(), w) // Partial
return
}
views.XxxPage(data).Render(r.Context(), w) // Full page
}
```
### OOB Updates (Multi-Target)
```templ
templ XxxStepWithStepper(step int) {
@XxxStepContent(step)
<div id="stepper-container" hx-swap-oob="innerHTML">
@components.Stepper(step, steps)
</div>
}
```
### HTMX Request Detection
### Templ Syntax Quick Ref
```go
if r.Header.Get("HX-Request") == "true" {
views.PartialContent(data).Render(r.Context(), w)
return
}
views.FullPage(data).Render(r.Context(), w)
```templ
if cond { } // Conditional
for _, item := range items { } // Loop
<input disabled?={ isDisabled } /> // Bool attr
<div class={ "base " + extra }> // String interpolation
@ChildComponent(props) // Composition
@templ.Raw(html) // Raw HTML (avoid)
```
## WebAwesome Components
## ANTI-PATTERNS (THIS PROJECT)
Use `wa-*` web components for UI:
| DO NOT | Why |
|--------|-----|
| Edit `*_templ.go` files | Generated by `templ generate` - changes purged |
| Use separate `htmx-ext-*` packages | HTMX 4 bundles extensions at `/dist/ext/` |
| Rely on implicit inheritance | Use `:inherited` modifier (`hx-target:inherited`) |
| Use `TopBar` or `TopBarStyles` | DEPRECATED - use `wa-page` slots instead |
| Manual DOM manipulation | Use `hx-*` attributes; server controls state |
| Put handlers in `handlers/` | Docs outdated - use `cmd/server/routes.go` |
```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
## COMMANDS
```bash
# Run all tests
go test ./...
# Generate templ (REQUIRED after .templ changes)
templ generate
# Run with verbose
go test -v ./...
# Dev server on :8080
go run ./cmd/server
# OR
make start
# Run specific package
go test ./handlers/...
# Full cycle: generate + start + open browser
make all
# Build binary
make build # outputs ./nebula
# Watch mode
templ generate --watch
```
## Common Tasks
## STACK VERSIONS
### Add New Page
- **Go**: 1.25.5 (cutting-edge)
- **templ**: v0.3.977
- **htmx**: 4.0.0-alpha5 (CDN)
- **WebAwesome**: Kit 47c7425b971f443c (CDN)
- **D3.js**: v7 (charts)
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
## NOTES
### 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`
- **No tests exist** - `go test ./...` returns "no test files"
- **No CI/CD** - No `.github/workflows/`
- **SQLite WASM** mentioned in docs but not implemented
- **Documentation references `handlers/`** - doesn't exist; handlers are in `cmd/server/routes.go`
- Config split: root `config.go` (app config) vs `pkg/config/` (HTMX feature flags)
- Middleware chain: `nebula.Middleware(opts...)(mux)` injects context for templates