From d8e0664fa3e20cc2e1da610b0ef3209ce8320e98 Mon Sep 17 00:00:00 2001 From: xcaliber Date: Tue, 3 Mar 2026 13:12:13 +0000 Subject: [PATCH] Changeset 0.22.6 (#148) --- .gitea/workflows/ci.yaml | 6 +- CHANGELOG.md | 23 + Dockerfile.frontend | 11 +- VERSION | 2 +- docker-entrypoint-fe.sh | 100 +- docs/ROADMAP.md | 22 + k8s/frontend.yaml | 9 +- nginx.conf | 96 +- server/pages/pages.go | 6 +- server/pages/templates/base.html | 2 + server/pages/templates/surfaces/chat.html | 629 +++++++- server/pages/templates/surfaces/editor.html | 1 - server/pages/templates/surfaces/notes.html | 1 - server/pages/templates/surfaces/settings.html | 21 + src/index.html | 1307 +---------------- src/js/__tests__/policy-gating.test.js | 133 +- src/js/app.js | 45 +- src/js/chat.js | 16 +- src/js/editor-mode.js | 275 +--- src/js/extensions.js | 15 +- src/js/pages.js | 45 + src/js/repl.js | 1 - src/js/router.js | 322 ---- src/js/surfaces.js | 368 ----- 24 files changed, 983 insertions(+), 2473 deletions(-) delete mode 100644 src/js/router.js delete mode 100644 src/js/surfaces.js diff --git a/.gitea/workflows/ci.yaml b/.gitea/workflows/ci.yaml index f262fbd..a8ab990 100644 --- a/.gitea/workflows/ci.yaml +++ b/.gitea/workflows/ci.yaml @@ -261,7 +261,7 @@ jobs: echo "${UNIT_PKGS}" | sed 's/^/ /' echo "" - go test -v -race -count=1 -p 1 ${UNIT_PKGS} + go test -v -race -count=1 -p 1 -timeout 8m ${UNIT_PKGS} echo "✓ Unit tests complete" - name: Run SQLite handler integration tests @@ -270,7 +270,7 @@ jobs: DB_DRIVER: sqlite run: | echo "━━━ SQLite Integration Tests (handlers + stores) ━━━" - go test -v -race -count=1 -p 1 \ + go test -v -race -count=1 -p 1 -timeout 8m \ ./handlers/... \ ./store/sqlite/... echo "✓ SQLite integration tests complete" @@ -351,7 +351,7 @@ jobs: PGPASSWORD: ${{ secrets.POSTGRES_PASSWORD }} run: | echo "━━━ Postgres Integration Tests ━━━" - go test -v -race -count=1 -p 1 \ + go test -v -race -count=1 -p 1 -timeout 8m \ ./store/postgres/... \ ./handlers/... echo "✓ Postgres integration tests complete" diff --git a/CHANGELOG.md b/CHANGELOG.md index 8288bf6..03f4fbc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,29 @@ All notable changes to Chat Switchboard. +## [0.22.6] — 2026-03-03 + +### Fixed +- **Split FE/BE deployment: page route proxying.** Frontend container now supports `BACKEND_URL` env var. When set, the entrypoint generates nginx `proxy_pass` blocks for page routes (`/`, `/login`, `/chat/:id`, `/admin/*`, `/editor/*`, `/notes/*`, `/settings/*`) so Go template rendering works in k8s split-image deployments. When unset, behavior is unchanged (SPA fallback). Both `BASE_PATH=""` and `BASE_PATH="/prefix"` variants supported. +- **CI test timeout.** All `go test` commands now include `-timeout 8m` to prevent indefinite hangs from runner resource contention or race-detector compilation stalls. Previously used Go's 10-minute default with no goroutine dump on timeout. + +### Removed +- **`router.js` (322 lines).** Client-side hash router fully replaced by server-side page routes. All `Router.*` call sites in `chat.js` replaced with `history.replaceState()` for URL updates. All `typeof Router` guards in `app.js` removed. +- **`surfaces.js` (368 lines).** Client-side surface registry replaced by Go template surface architecture. Extension API stubs (`surfaces.register`, `surfaces.activate`, etc.) now log deprecation warnings. `surfaces.getCurrent()` returns `window.__SURFACE__` from server-rendered page data. +- **`index.html` SPA shell (1,296 lines → 16 lines).** Original monolithic SPA entry point replaced with a minimal redirect page. All real routes now served by Go templates; `index.html` only serves as nginx `try_files` fallback for unknown paths. +- **`editor-mode.js` old Surfaces paths (~260 lines).** Removed `_register()`, `openDirect()`, `_unregister()`, `_activate()`, `_deactivate()`, `_embedChat()`, `_returnChat()`, and full `check()`/`checkStartup()` implementations. Only `mountServerRendered()` remains as the entry point. `check()` and `checkStartup()` kept as no-ops for backward compat with `projects-ui.js` callers. +- **SPA-only entrypoint code path.** `docker-entrypoint-fe.sh` now requires `BACKEND_URL` (fails fast if unset). Removed dead `%%BASE_HREF%%`, `%%ENVIRONMENT%%`, `%%BRANDING_JSON%%` injection into index.html. Removed branding config file loading (branding now handled by Go templates). + +### Changed +- `docker-entrypoint-fe.sh`: Simplified from 227 → 184 lines. Requires `BACKEND_URL`. Removed SPA-only fallback path. +- `nginx.conf` (unified container): Consolidated repeated `proxy_set_header` blocks. Uses `$backend` variable. Page routes proxy to Go backend for template rendering. +- `base.html`: Added `__ENV__` and `__BRANDING__` globals for JS compatibility (previously injected by index.html sed). +- `server/pages/pages.go`: Added `Environment` field to `PageData`, populated from config. +- `extensions.js`: `ui.replace()`, `ui.restore()`, and `surfaces.*` API methods now log deprecation warnings instead of calling removed Surfaces system. +- `app.js`: Removed `Surfaces.init()`, `EditorMode.checkStartup()`, and `Router.init()` calls. Simplified to direct `sessionStorage` chat restore. +- `chat.js`: Replaced `Router.update()` calls with `history.replaceState()` for URL-bar sync on chat selection/creation. +- `repl.js`: Removed `surfaces.js` import reference. + ## [0.22.5] — 2026-03-03 ### Added diff --git a/Dockerfile.frontend b/Dockerfile.frontend index a34aaf7..7d507be 100644 --- a/Dockerfile.frontend +++ b/Dockerfile.frontend @@ -1,15 +1,20 @@ # ========================================== # Chat Switchboard - Frontend Dockerfile # ========================================== -# Static SPA served by nginx. No API proxy — -# in k8s, the Ingress routes /api/ and /ws to -# the backend service directly. +# Static SPA served by nginx. In k8s, the +# Ingress routes /api/ and /ws to the backend +# service directly. # # Supports path-based deployment via BASE_PATH # env var (e.g. /dev, /test, or empty for root). # The entrypoint generates the nginx config and # injects BASE_PATH into index.html at startup. # +# v0.22.6+: Set BACKEND_URL to proxy page routes +# (/, /login, /admin, /editor, /notes, /settings) +# to the Go backend for server-rendered templates. +# When unset, page routes fall through to SPA. +# # Build context: repo root # ========================================== diff --git a/VERSION b/VERSION index 03035cd..18fb7fe 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.22.5 +0.22.6 diff --git a/docker-entrypoint-fe.sh b/docker-entrypoint-fe.sh index 752fd7f..fd1bdeb 100644 --- a/docker-entrypoint-fe.sh +++ b/docker-entrypoint-fe.sh @@ -2,16 +2,23 @@ # ============================================ # Chat Switchboard - Frontend Entrypoint # ============================================ -# Injects BASE_PATH into index.html and nginx -# config at container startup. Supports path- -# based multi-env deployment on a single domain. +# nginx serves static assets and proxies page +# routes to the Go backend for template rendering. +# API/WS routes are handled by Ingress directly. # -# Environment: -# BASE_PATH - URL prefix (e.g. "/dev", "/test", or "") +# Environment (required): +# BACKEND_URL - Backend service URL +# (e.g. "http://switchboard-be:8080") +# +# Environment (optional): +# BASE_PATH - URL prefix (e.g. "/dev", "" for root) +# ENVIRONMENT - Environment name for logging # ============================================ set -e BASE_PATH="${BASE_PATH:-}" +BACKEND_URL="${BACKEND_URL:?BACKEND_URL is required (e.g. http://switchboard-be:8080)}" +ENVIRONMENT="${ENVIRONMENT:-production}" # Read version from VERSION file (baked in at build time) APP_VERSION="dev" @@ -19,39 +26,16 @@ if [ -f /VERSION ]; then APP_VERSION=$(cat /VERSION | tr -d '[:space:]') fi -# Compute base href (needs trailing slash for tag) -if [ -z "${BASE_PATH}" ]; then - BASE_HREF="/" -else - BASE_HREF="${BASE_PATH}/" -fi - -# ── Read branding config ──────────────────── -BRANDING_JSON="{}" -if [ -f /branding/branding.json ]; then - # Compact to single line for safe sed injection - BRANDING_JSON=$(tr -d '\n' < /branding/branding.json | sed 's/ */ /g') - echo "✅ Branding config loaded from /branding/branding.json" -else - echo "ℹ️ No branding mount — using defaults" -fi - -# ── Read environment name ───────────────── -ENVIRONMENT="${ENVIRONMENT:-production}" - -# Compute build hash from frontend file contents (changes on every deploy) +# Compute build hash from JS file contents (unique per deploy) BUILD_HASH=$(find /usr/share/nginx/html/js -name '*.js' -exec md5sum {} + 2>/dev/null | sort | md5sum | cut -c1-8) if [ -z "${BUILD_HASH}" ]; then BUILD_HASH=$(date +%s | md5sum | cut -c1-8) fi -# ── Inject into index.html ────────────────── +# ── Inject into index.html (redirect page) ── sed -i \ -e "s|%%BASE_PATH%%|${BASE_PATH}|g" \ - -e "s|%%BASE_HREF%%|${BASE_HREF}|g" \ -e "s|%%APP_VERSION%%|${APP_VERSION}|g" \ - -e "s|%%ENVIRONMENT%%|${ENVIRONMENT}|g" \ - -e "s|%%BRANDING_JSON%%|${BRANDING_JSON}|g" \ /usr/share/nginx/html/index.html # Inject version and build hash into service worker @@ -60,13 +44,45 @@ sed -i \ -e "s|%%BUILD_HASH%%|${BUILD_HASH}|g" \ /usr/share/nginx/html/sw.js -echo "✅ Frontend configured: BASE_PATH=${BASE_PATH:-/} VERSION=${APP_VERSION} BUILD=${BUILD_HASH} ENV=${ENVIRONMENT}" +echo "✅ Frontend: BASE_PATH=${BASE_PATH:-/} VERSION=${APP_VERSION} BUILD=${BUILD_HASH} BACKEND=${BACKEND_URL}" + +# ── Page route proxy blocks ───────────────── +page_proxy_block() { + local path="$1" + cat < /etc/nginx/conf.d/default.conf <<'NGINX' + cat > /etc/nginx/conf.d/default.conf < window.__BASE__ = '{{.BasePath}}'; window.__VERSION__ = '{{.Version}}'; + window.__ENV__ = '{{.Environment}}'; + window.__BRANDING__ = {}; window.__SURFACE__ = '{{.Surface}}'; window.__PAGE_DATA__ = {{.Data | toJSON}}; window.__USER__ = {{.User | toJSON}}; diff --git a/server/pages/templates/surfaces/chat.html b/server/pages/templates/surfaces/chat.html index 03e9519..cc40cd9 100644 --- a/server/pages/templates/surfaces/chat.html +++ b/server/pages/templates/surfaces/chat.html @@ -1,14 +1,631 @@ {{/* Chat surface (Phase 1 bridge). - Server renders the page shell. Existing SPA JS takes over the DOM. - All scripts from index.html are loaded here — minus the three - already in base.html (api.js, events.js, ui-primitives.js). + Server renders the page shell with full SPA scaffold. + Existing SPA JS (app.js, ui-core.js, chat.js, etc.) populates + these pre-built DOM elements with data. + + v0.22.6 fix: The original index.html contained the full scaffold + (1,296 lines). When it was replaced with a redirect stub, this + template needed the scaffold — but it was shipped empty. + This template restores the required DOM structure. */}} {{define "surface-chat"}} - {{end}} +{{define "settings-providers"}} + +
+ +
+ +
Loading providers…
+{{end}} + +{{define "settings-personas"}} +
+ +
+ +
Loading presets…
+{{end}} + {{define "css-settings"}}