[agent/claude:opus] DX audit and fix. 1) Review CLAUDE.md — update any outdate... #2
3 changed files with 41 additions and 3 deletions
|
|
@ -27,7 +27,7 @@ See `docs/architecture.md` for full detail. Summary:
|
|||
- **Responsive**: Multi-variant breakpoint wrapper (`data-variant` attributes), renders all variants in insertion order
|
||||
- **Pipeline**: Render → StripTags → go-i18n/reversal Tokenise → GrammarImprint (server-side only)
|
||||
- **Codegen**: Web Component classes with closed Shadow DOM, generated at build time by `cmd/codegen/`
|
||||
- **WASM**: `cmd/wasm/` exports `renderToString()` only — size gate: < 3 MB raw, < 1 MB gzip
|
||||
- **WASM**: `cmd/wasm/` exports `renderToString()` only — size gate: < 3.5 MB raw, < 1 MB gzip
|
||||
|
||||
## Server/Client Split
|
||||
|
||||
|
|
@ -40,9 +40,10 @@ Files guarded with `//go:build !js` are excluded from WASM:
|
|||
|
||||
## Dependencies
|
||||
|
||||
- `forge.lthn.ai/core/go-i18n` (replace directive → `../go-i18n`)
|
||||
- `forge.lthn.ai/core/go-i18n` — internationalisation, text reversal pipeline
|
||||
- `forge.lthn.ai/core/go-io` — file I/O abstraction (`coreio.Local`)
|
||||
- `forge.lthn.ai/core/go-log` — structured logging and error wrapping (`log.E()`)
|
||||
- `forge.lthn.ai/core/go-inference` (indirect, via go-i18n)
|
||||
- Both `go-i18n` and `go-inference` must be cloned alongside this repo for builds
|
||||
- Go 1.26+ required (uses `range` over integers, `iter.Seq`, `maps.Keys`, `slices.Collect`)
|
||||
|
||||
## Coding Standards
|
||||
|
|
@ -53,6 +54,8 @@ Files guarded with `//go:build !js` are excluded from WASM:
|
|||
- Licence: EUPL-1.2 — add `// SPDX-Licence-Identifier: EUPL-1.2` to new files
|
||||
- Safe-by-default: HTML escaping via `html.EscapeString()` on Text nodes and attribute values, void element handling, entitlement deny-by-default
|
||||
- Deterministic output: sorted attributes on El nodes, reproducible block ID paths
|
||||
- Error handling: use `log.E(scope, message, err)` from `go-log`, never `fmt.Errorf`
|
||||
- File I/O: use `coreio.Local` from `go-io`, never `os.ReadFile`/`os.WriteFile`
|
||||
- Commits: conventional commits + `Co-Authored-By: Virgil <virgil@lethean.io>`
|
||||
|
||||
## Test Conventions
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package main
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
|
|
@ -9,6 +10,12 @@ import (
|
|||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
type errReader struct{}
|
||||
|
||||
func (errReader) Read([]byte) (int, error) {
|
||||
return 0, errors.New("read failed")
|
||||
}
|
||||
|
||||
func TestRun_Good(t *testing.T) {
|
||||
input := strings.NewReader(`{"H":"nav-bar","C":"main-content"}`)
|
||||
var output bytes.Buffer
|
||||
|
|
@ -49,3 +56,11 @@ func TestRun_Good_Empty(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
assert.Empty(t, output.String())
|
||||
}
|
||||
|
||||
func TestRun_Bad_ReadError(t *testing.T) {
|
||||
var output bytes.Buffer
|
||||
|
||||
err := run(errReader{}, &output)
|
||||
assert.Error(t, err)
|
||||
assert.Contains(t, err.Error(), "reading stdin")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,3 +52,23 @@ func TestGenerateBundle_Good(t *testing.T) {
|
|||
assert.Contains(t, js, "MainContent")
|
||||
assert.Equal(t, 2, strings.Count(js, "extends HTMLElement"))
|
||||
}
|
||||
|
||||
func TestGenerateBundle_Good_DeduplicatesTags(t *testing.T) {
|
||||
slots := map[string]string{
|
||||
"H": "nav-bar",
|
||||
"F": "nav-bar",
|
||||
}
|
||||
js, err := GenerateBundle(slots)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, 1, strings.Count(js, "extends HTMLElement"),
|
||||
"duplicate tag should produce only one class definition")
|
||||
}
|
||||
|
||||
func TestGenerateBundle_Bad_InvalidTag(t *testing.T) {
|
||||
slots := map[string]string{
|
||||
"H": "notag",
|
||||
}
|
||||
_, err := GenerateBundle(slots)
|
||||
assert.Error(t, err)
|
||||
assert.Contains(t, err.Error(), "hyphen")
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue