Files
nebula/AGENTS.md

5.1 KiB

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

# 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

<div hx-get="/endpoint" hx-target="#target" hx-swap="innerHTML">

Out-of-Band Updates

templ ComponentWithOOB() {
    @MainContent()
    <div id="sidebar" hx-swap-oob="true">
        @UpdatedSidebar()
    </div>
}

HTMX Request Detection

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:

<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:

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:

// 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

// 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

# 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