Aligns with the warehack-ing host convention (matches birdcage-docs):
Dockerfile — multi-stage with named targets:
base shared npm ci + COPY
dev npx astro dev --host 0.0.0.0 --port 4321 (HMR enabled)
build npx astro build (produces /app/dist)
prod caddy:2-alpine serves /srv with /health probe + HEALTHCHECK
docker-compose.yml — picks the target via APP_ENV in .env:
build.target = ${APP_ENV:-dev}
caddy.reverse_proxy upstream port = ${APP_PORT:-4321}
Adds the streaming/HMR caddy labels CLAUDE.md requires for Vite-over-
Caddy: flush_interval=-1, transport.read/write_timeout=0, keepalive,
stream_timeout=24h, stream_close_delay=5s
Volume mounts ./src, ./public, astro.config.mjs (live in dev, harmless
in prod since the prod stage doesn't reference /app)
astro.config.mjs — vite.server.hmr block now picks up VITE_HMR_HOST
env var and configures host/protocol/clientPort for wss-on-443 HMR
through Caddy. Falls back to undefined when unset so plain
'npm run dev' still works.
Caddyfile — adds /health endpoint for the Dockerfile HEALTHCHECK,
SPA-style try_files fallback chain (path -> path/index.html -> /index.html).
Makefile — adds 'make dev' / 'make prod' that rewrite APP_ENV+APP_PORT
in .env then rebuild. Tail-logs after up/restart so you see startup
diagnostics without a separate 'make logs'.
.env.example — five vars (COMPOSE_PROJECT_NAME, APP_ENV, APP_PORT,
PUBLIC_DOMAIN, VITE_HMR_HOST), defaulting to prod mode against the
public hai-omni-pro-ii.warehack.ing domain. .env stays gitignored so
each environment (local, remote) can override.
Local container rebuilt + recreated, healthy, /health returns 200,
PUBLIC_DOMAIN locally still set to .l.warehack.ing in the host .env.
src/content/docs/ — twelve pages totalling ~18,800 words, ported from
the omni-pca repo's docs and reference material:
index.mdx (377 w) landing page with three CardGrid links
start/quickstart.md (572 w) three flows: decode .pca / talk to
panel / install in HA
reference/protocol.md (2525 w) byte-level Omni-Link II spec, full
packet+message layouts, the two
non-public quirks, opcode tables
reference/file-format.md (1593 w) XOR-LCG cipher, key derivation,
PCA01.CFG schema, .pca PCA03 header
reference/library-api.md (1170 w) module-by-module Python API summary
reference/ha-entities.md (1070 w) per-platform entity catalogue
reference/ha-services.md (567 w) seven services + automation YAML
explanation/quirks.md (1448 w) the headline RE essay — session-key
XOR mix + per-block whitening, why
no public client documents them
explanation/architecture.md (1123 w) library + HA + mock + tests
explanation/pc-access-bug.md (1131 w) LargeVocabulary off-by-N
journey.md (6194 w) chronological retrospective ported
from omni-pca/docs/JOURNEY.md
changelog.md (1213 w) full 2026.5.10 release notes
Dockerfile — pinned node:lts-alpine and caddy:latest (registry-1
.docker.io was returning 'tls: internal error' on node:25-alpine and
caddy:2-alpine pulls; the pinned tags are cached locally and work).
TODO comment notes to bump back to node:25 once registry stabilises.
.gitignore — added .env / .env.local just in case.
Build: 13 pages built clean in 1.83s, sitemap + Pagefind search index
emitted. Container runs at hai-omni-docs-docs (caddy network), accepts
requests with Host: hai-omni-pro-ii.warehack.ing, returns rendered
Starlight HTML with title/description meta intact. Once DNS for
hai-omni-pro-ii.warehack.ing points at the host, the site is live.
Astro 6 + Starlight 0.39 documentation site for omni-pca, organised
around the Diatáxis framework (Tutorials / How-to / Reference /
Explanation), plus a chronological Journey page and Changelog.
Theme: muted slate-blue with amber accents. astro-icon + lucide
preinstalled. Astro telemetry and Starlight devToolbar both off.
Deployment: multi-stage Dockerfile (node:25-alpine builder ->
caddy:2-alpine runtime), inner Caddy serves static dist on :80,
outer caddy-docker-proxy on the host terminates TLS for
hai-omni-pro-ii.warehack.ing.