HERMES-GIELIE/api
nesquena-hermes 2beebaa6a2
feat: opt-in chat bubble layout (closes #336) (#403)
* feat(ui): opt-in chat bubble layout

Closes #336.

Adds a settings toggle that right-aligns user messages and left-aligns
assistant replies. Off by default - the current full-width layout is
friendlier to code blocks and tool output, so bubbles are strictly
opt-in per the maintainer note on the issue.

Wiring follows the existing token-usage / cli-sessions pattern:

- api/config.py: new bubble_layout bool in _SETTINGS_DEFAULTS and
  _SETTINGS_BOOL_KEYS, validated + persisted like the rest.
- static/style.css: .bubble-layout gated selectors using :has() to
  tag msg-rows by .msg-role.user / .msg-role.assistant without any JS
  changes to message creation. User rows get align-self: flex-end,
  max-width: 75%, and a row-reverse header; assistant rows flex-start.
  A 700px media query widens the max to 92% on narrow screens.
- static/index.html: new checkbox with i18n keys next to the existing
  token-usage toggle.
- static/panels.js: loads the setting into the checkbox, saves it
  back, and toggles body.bubble-layout immediately on save.
- static/boot.js: applies the class on initial load so refreshed
  tabs honor the persisted setting without a flash.
- static/i18n.js: English label + description.

Test suite errors are environmental (test server fails to start on
port 8788 on main as well).

* i18n(es): add Spanish translations for bubble_layout setting

* fix+test: boot.js bubble-layout reset on failure; add 22 tests for issue #336

* docs: v0.50.24 release — version badge and CHANGELOG

---------

Co-authored-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com>
Co-authored-by: Nathan Esquenazi <nesquena@gmail.com>
2026-04-13 21:42:01 -07:00
..
__init__.py Hermes Web UI — Sprints 11-14: multi-provider models, settings, session QoL, alerts, polish 2026-03-31 07:02:47 +00:00
auth.py security: bandit fixes B310/B324/B110 + QuietHTTPServer (#354) 2026-04-13 11:11:56 -07:00
config.py feat: opt-in chat bubble layout (closes #336) (#403) 2026-04-13 21:42:01 -07:00
gateway_watcher.py security: bandit fixes B310/B324/B110 + QuietHTTPServer (#354) 2026-04-13 11:11:56 -07:00
helpers.py v0.46.0: security, Docker UID/GID, model discovery, i18n, cancel fix 2026-04-11 10:17:52 -07:00
models.py fix: live reasoning, tool progress, in-flight session recovery (#367) 2026-04-13 16:18:15 -07:00
onboarding.py security: bandit fixes B310/B324/B110 + QuietHTTPServer (#354) 2026-04-13 11:11:56 -07:00
profiles.py security: bandit fixes B310/B324/B110 + QuietHTTPServer (#354) 2026-04-13 11:11:56 -07:00
routes.py fix: onboarding unblocked for reverse proxy / SSH tunnel deployments (fixes #390) (#391) 2026-04-13 17:52:07 -07:00
startup.py v0.46.0: security, Docker UID/GID, model discovery, i18n, cancel fix 2026-04-11 10:17:52 -07:00
state_sync.py security: bandit fixes B310/B324/B110 + QuietHTTPServer (#354) 2026-04-13 11:11:56 -07:00
streaming.py fix: live reasoning, tool progress, in-flight session recovery (#367) 2026-04-13 16:18:15 -07:00
updates.py fix: improve self-update git pull diagnostics (#287) 2026-04-12 00:19:33 -07:00
upload.py chore: add missing type hints across 10 files 2026-04-05 13:30:20 +07:00
workspace.py security: bandit fixes B310/B324/B110 + QuietHTTPServer (#354) 2026-04-13 11:11:56 -07:00