Build infra + CLAUDE.md
Build / build (push) Successful in 10m3s

This commit is contained in:
2026-08-09 18:09:16 +02:00
parent 8af1ff6ec1
commit 012caf5672
4 changed files with 94 additions and 1 deletions
+28
View File
@@ -0,0 +1,28 @@
name: Build
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version-file: go.mod
- name: Generate dashboard_gsx.go from dashboard.gsx
run: go run github.com/grindlemire/go-tui/cmd/tui generate ./...
- name: Build
run: go build -v ./...
- name: Vet
run: go vet ./...
+53
View File
@@ -0,0 +1,53 @@
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## What this is
A terminal dashboard (TUI) built with `github.com/grindlemire/go-tui`, showing simulated CPU/memory/disk gauges, network sparklines, and a scrolling event feed. Single binary, no external services.
## Commands
```sh
# Regenerate dashboard_gsx.go from dashboard.gsx (required before build if the .go file is missing/stale)
go run github.com/grindlemire/go-tui/cmd/tui generate ./...
# Build
go build ./...
# Vet
go vet ./...
# Run the app
go run .
```
There are no test files in this repo yet.
## Architecture
### The .gsx → .go code generation step
`dashboard.gsx` is the source of truth for the UI. It's written in `.gsx`, a JSX-like DSL (Tailwind-esque `class` strings, `{expr}` interpolation, `for`/`if` control flow, a `templ` method that compiles to `Render`) provided by the `go-tui` module. **`dashboard_gsx.go` is generated output — do not hand-edit it.** It's git-ignored and carries a `// Code generated by tui generate. DO NOT EDIT.` header.
To change the UI: edit `dashboard.gsx`, then run `go run github.com/grindlemire/go-tui/cmd/tui generate ./...` to regenerate `dashboard_gsx.go`. Non-templ Go code (helper funcs, the `dashboardApp` struct, `produceEvents`, etc.) also lives in `dashboard.gsx` — the whole file is the source, not just the template block.
The `tui` CLI is wired into `go.mod` as a Go 1.24+ `tool` dependency (`tool github.com/grindlemire/go-tui/cmd/tui`), which is why `go.sum` carries `golang.org/x/tools` etc. even though the app code doesn't import them directly. Don't `go mod tidy` this away — it strips the generator's transitive deps and breaks `go run .../cmd/tui generate`.
CI (`.gitea/workflows/build.yml`) regenerates `dashboard_gsx.go` from scratch on every run before building, so the generated file never needs to be committed or kept in sync manually.
### App structure (go-tui conventions)
- `main.go` wires up `tui.NewApp(tui.WithRootComponent(Dashboard(eventCh)), tui.WithMouse())` and runs it. A background goroutine (`produceEvents`) pushes random events onto `eventCh`.
- `dashboardApp` (defined in `dashboard.gsx`) is the root component. It implements several go-tui interfaces, each independently optional and picked up via interface satisfaction (see the compile-time checks at the bottom of the generated file):
- `KeyMap() tui.KeyMap` — key bindings (`q`/Esc to quit, `j`/`k`/arrows to scroll).
- `HandleMouse(tui.MouseEvent) bool` — mouse wheel scroll support.
- `Watchers() []tui.Watcher` — background subscriptions: a 500ms timer (`updateMetrics`, simulates metric drift) and a channel watch (`addEvent`, consumes `eventCh`).
- `Render(*tui.App) *tui.Element` — the generated view tree (from the `templ` block).
- `BindApp(*tui.App)` — generated; wires every `*tui.State[T]` field to the app so state changes trigger re-renders. If you override `BindApp` yourself, call the generated `bindAppFields` helper rather than re-listing fields.
- All mutable UI state (`cpu`, `mem`, `sparkIn`, `events`, `scrollY`, ...) is `*tui.State[T]`, read via `.Get()` and mutated via `.Set()`. `eventsRef *tui.Ref` gives imperative access to the events panel element (used for `MaxScroll()`/auto-scroll-to-bottom in `addEvent`).
- Adding a new stateful field to `dashboardApp` means: add the `tui.State`/`tui.Ref` field, initialize it in `Dashboard(...)`, use it in the `templ` block — the generator regenerates `bindAppFields` and the compile-time interface checks automatically.
### CI
`.gitea/workflows/build.yml` runs on push/PR to `main`: checkout → setup-go (version from `go.mod`) → `tui generate``go build``go vet`.
+7 -1
View File
@@ -2,7 +2,13 @@ module dashboard
go 1.26.5
require github.com/grindlemire/go-tui v0.19.0
require (
github.com/grindlemire/go-tui v0.19.0 // indirect
golang.org/x/mod v0.32.0 // indirect
golang.org/x/sync v0.19.0 // indirect
golang.org/x/sys v0.40.0 // indirect
golang.org/x/tools v0.41.0 // indirect
)
tool github.com/grindlemire/go-tui/cmd/tui
+6
View File
@@ -1,4 +1,10 @@
github.com/grindlemire/go-tui v0.19.0 h1:4k4MRoYUFChUCfO5Lr4Z05SI3jlTSuH3W1H5/HKVH8s=
github.com/grindlemire/go-tui v0.19.0/go.mod h1:95oaPy6Iu6MZpiByUqxYz2Wcbckzvaw3K0jgQeI4dD0=
golang.org/x/mod v0.32.0 h1:9F4d3PHLljb6x//jOyokMv3eX+YDeepZSEo3mFJy93c=
golang.org/x/mod v0.32.0/go.mod h1:SgipZ/3h2Ci89DlEtEXWUk/HteuRin+HHhN+WbNhguU=
golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ=
golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/tools v0.41.0 h1:a9b8iMweWG+S0OBnlU36rzLp20z1Rp10w+IY2czHTQc=
golang.org/x/tools v0.41.0/go.mod h1:XSY6eDqxVNiYgezAVqqCeihT4j1U2CCsqvH3WhQpnlg=