#!/usr/bin/env bash
#
# Pilot check: go-tell consuming the shared contract.
#
# go-tell is the hard case. Before the migration it had no CSS custom properties at
# all: 340 hardcoded hex values and 153 per-palette override rules, with cyberpunk
# baked into the un-scoped base rules. Its stylesheet now reads from the contract, so
# this check exists to prove the rewrite works rather than to assert that it was typed:
#
# - The four palettes go-tell's own rules key on are all published.
# - Switching a palette through the shipped control moves the rendered page.
# - The terminal palette's global `font-family: ... !important` reaches the
# application but not into the controls' shadow roots.
# - The appearance axis writes data-mode, which is what gives go-tell the light
# mode it never had.
#
# It does not boot go-tell: the application needs Postgres and a session cookie to
# reach its authenticated routes, and none of that is what is being tested. What is
# tested is the built shell and the built stylesheet.
set -euo pipefail
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
TELL="${GO_TELL_DIR:-/home/dnoulet/go/go-tell}"
WORK="$(mktemp -d)"
PORT="${PORT:-8396}"
THEME_PORT="${THEME_PORT:-8395}"
CHROME="${CHROME:-$(command -v chromium || command -v chromium-browser || command -v google-chrome || true)}"
cleanup() {
for pid in "${SERVER_PID:-}" "${THEME_PID:-}"; do
[[ -n "$pid" ]] && kill "$pid" 2>/dev/null || true
done
rm -rf "$WORK"
}
trap cleanup EXIT
[[ -d "$TELL/ui/app" ]] || { echo "go-tell not found at $TELL; set GO_TELL_DIR" >&2; exit 1; }
[[ -n "$CHROME" ]] || { echo "no chromium found; set CHROME" >&2; exit 1; }
echo "==> building the service, the SDK and go-tell's UI"
(cd "$ROOT" && go build -o "$WORK/go-bananas" ./cmd/go-bananas)
(cd "$ROOT/sdk" && npm run build >/dev/null)
(cd "$TELL/ui/app" && npm run build >/dev/null)
DIST="$TELL/ui/dist"
[[ -d "$DIST" ]] || { echo "expected a build at $DIST" >&2; exit 1; }
mkdir -p "$WORK/site" "$WORK/site/assets"
cp "$ROOT"/sdk/dist/*.js "$WORK/site/assets/"
cp "$DIST/index.html" "$WORK/site/index.html"
cp "$DIST"/assets/* "$WORK/site/" 2>/dev/null || true
cp "$ROOT/hack/pilot-go-tell.js" "$WORK/site/pilot.js"
# The contract is added here rather than served through go-tell's Go handler, because
# this check serves the built shell with a plain static server. The mechanism itself is
# covered where it lives, by `go test ./internal/web/ -run Theme` in go-tell; this check
# is about whether the stylesheet and the controls work together. What is added below is
# what applyThemeOrigin adds when CMS_THEME_BASE_URL is set.
echo "==> assembling go-tell's built shell"
SHELL="$WORK/site/index.html" SITE_ASSETS="$WORK/site" THEME_ORIGIN="http://localhost:$THEME_PORT" \
python3 <<'PY'
import os, re
path = os.environ['SHELL']
origin = os.environ['THEME_ORIGIN']
s = open(path).read()
# The shell references its own bundle by absolute path; the check serves those files
# beside the shell rather than under /assets.
s = re.sub(r'(src|href)="/assets/', r'\1="/', s)
# What go-tell's handler adds when the theme origin is configured: a stylesheet and the
# control module, inside the head so the stylesheet parses before the body renders.
tag = (
'\n '
'\n \n'
)
if '' in s:
s = s.replace('', tag + ' ', 1)
# Transitions are disabled for the check. go-tell transitions `background` over
# 300ms, and a headless run under --virtual-time-budget fast-forwards timers without
# advancing the style clock, so a transition never leaves its start value: the
# untransitioned --bn-bg already reports the new palette while the computed background
# still reports the old one. That is an artefact of the harness, not of the
# application, and reading through it is the only way to make the assertions
# deterministic.
s = s.replace(
'',
''
' ',
1,
)
# The reporter, appended to the copy. go-tell's own source is never edited.
s = s.replace('