ReadEnvGroups returned a nil slice (out := groups[:0]) whenever no group
ended up with fields, which marshals to JSON null instead of []. The
admin UI's EnvSection calls groups.reduce()/iterates unconditionally, so
that null crashed the Server Settings page.
Also switch the source of the panel structure from .env.example to .env
once .env exists, falling back to .env.example only pre-setup: .env
already carries the same group headers and comments after any save
(WriteEnvValues always rewrites it from .env.example's exact text), so
it's the more current source of what's actually configured.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
ReadEnvGroups returned (nil, nil) when .env.example wasn't found, and that
nil slice marshaled to JSON null instead of []. The admin UI's env editor
unconditionally calls .reduce()/.map() on the response, so it crashed on
load with "Cannot read properties of null" -- and .env.example was never
copied into the container image in the first place, so this was always the
production code path, not an edge case.
Fixed the nil-slice response and added .env.example to the image so the
editor actually has a template of available settings to show. The real
current values still require the deploy host to mount its actual .env file
into the owpengram-admin container at /app/.env (procctl.Manager.Root is
just os.Getwd(), i.e. the container's /app workdir) -- that's a systemd
Quadlet unit change on the deploy host, not something this commit can fix on
its own.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>