Remove the blanket .agent/ gitignore so the phase roadmap, user stories, reports, and PLAN.md are versioned with the code. Only runtime artifacts (.agent/phase-sessions/, .agent/pipeline.log) remain ignored. Update AGENTS.md git protocol rule to match.
2.8 KiB
2.8 KiB
Story: Configurable app name
Phase: 39_configurable_brand · E2E: tests/e2e/test_configurable_brand.py
Narrative
As the owner, the app is "Brain of Reese" because that's what I named
it — but the name is hard-coded across every template and JS string. I want
to be able to rename the app with one env var (BOR_APP_NAME) so every
page title, the header brand, the status labels, and the aria text carry
the new name without touching code.
- Given the app is running with
BOR_APP_NAME="Brain of Testy" - When I open any page (chat, sources, tuning, login, document viewer)
- Then the title, the header brand, the status labels ("Brain of Testy is thinking"), the empty-state greeting, and the document-viewer titles all say "Brain of Testy" — and with the variable unset the app is byte-identical to today ("Brain of Reese").
Acceptance criteria
GET /api/config(public, stateless) →{app_name, version}from settings — exactly those two keys (no secrets, no other settings); unit + integration tested.frontend/assets/brand.js(classic script, loaded first on all five pages): setswindow.BOR_BRANDsynchronously (default "Brain of Reese"), fetches/api/config(cache: "no-store"), and applies the name —document.title(global replace of the literal), every.brand-text(bold split: a name starting "Brain of " bolds the remainder, else plain; the name is HTML-escaped), every text node and thearia-label/placeholder/ meta-contentattributes containing the literal; a fetch failure falls back to the default (console.warn, the page never breaks).- The JS hard-codes move off the literal:
app.js(status labels, the typing label, the elapsed-hint aria) +document.js(page titles) readwindow.BOR_BRAND(default "Brain of Reese" if unset). Containerfile: an esbuild line for brand.js next to the others.- The story E2E boots its own app instance with
BOR_APP_NAMEoverridden (distinct port; the shared conftest server keeps the default name so the existing title assertions stay green) and asserts title/brand/greeting/aria/label. .env.example+ README documentBOR_APP_NAME(what it affects, the default, the bold-split rule).- Unit + integration green,
app/coverage >90%, story E2E green in isolation, ruff + pyright clean, one--no-gpg-signcommit.
Playwright Mapping Rule
tests/e2e/test_configurable_brand.py — one story, one file, run in
isolation: the overridden-name instance shows the new brand in the title,
the header .brand-text (with the bold split), the empty-state greeting,
the messages aria-label, and the chat status label; the default-name
shared server still renders "Brain of Reese" (the no-op regression).