helmd: inbäddad webbklient (vanilla SPA) + Docker-image för Pi5 (LAN-only)
All checks were successful
helmd-image / build (push) Successful in 36s
helmd-release / build-release (push) Successful in 1m6s

- web/: token-login, sessionslista, ANSI-skärmvy (SSE+poll), promptfält,
  frågekort, tangentrad, delningsflik (bild/HTML-sandbox/markdown), inställningar
- go:embed via webfs.go — servern förblir en enda binär, strikt CSP
- browser-verifierad mot riktig agy (fråga -> kort -> svar -> kört)
- Dockerfile (alpine + tmux/bash) + helmd-image.yaml -> localhost:5000/helmd
- integrationstest utökat till 29 gröna

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-05 22:17:12 +02:00
parent f9f94e59bc
commit 12ffcaa2bd
13 changed files with 830 additions and 6 deletions

29
helmd/webfs.go Normal file
View File

@@ -0,0 +1,29 @@
package main
import (
"embed"
"io/fs"
"net/http"
)
// Webbklienten byggs in i binären — hela v2 är fortfarande en enda fil.
//
//go:embed web
var webFiles embed.FS
// mountWeb serves the embedded UI on / (the /api/* routes are more
// specific and win in the mux).
func mountWeb(mux *http.ServeMux) {
sub, err := fs.Sub(webFiles, "web")
if err != nil {
panic(err)
}
fileServer := http.FileServerFS(sub)
mux.Handle("GET /", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// UI:t behöver ingen auth (koden är publik i repot); API:t
// skyddas separat. Strikt CSP så att inget externt kan läcka in.
w.Header().Set("Content-Security-Policy",
"default-src 'self'; img-src 'self' data:; style-src 'self'; script-src 'self'")
fileServer.ServeHTTP(w, r)
}))
}