mirror of
https://github.com/nesquena/hermes-webui.git
synced 2026-05-25 11:10:18 +00:00
33a145a669
## Release v0.50.240 Batch release of 13 PRs that passed full triage + code review + test suite (3199 tests, 0 failures). --- ### Added - **Compact tool activity mode** (`simplified_tool_calling`, default on) — groups tool calls and thinking traces into a single collapsed "Activity" disclosure card per assistant turn. Also adds a new **Calm Console** theme with earth/slate palette and serif prose. @Michaelyklam — #1282 - **PDF first-page preview** — `MEDIA:` `.pdf` files render a canvas thumbnail via PDF.js CDN (4 MB cap). **HTML sandbox iframe** — `.html`/`.htm` files render inline in a sandboxed `<iframe srcdoc>` (256 KB cap). 10 i18n keys × 7 locales. @bergeouss — #1280, closes #480 #482 - **Inline Excalidraw diagram preview** — `.excalidraw` files render as pure SVG (no external deps; rectangles, ellipses, diamonds, text, lines, arrows, freehand; 512 KB cap). @bergeouss — #1279, closes #479 - **Inline CSV table rendering** — fenced `csv` blocks and `MEDIA:` CSV files render as scrollable HTML tables with auto-separator detection. @bergeouss — #1277, closes #485 - **Inline SVG, audio, and video rendering** — SVG as `<img>`, audio as `<audio controls>`, video as `<video controls>`. @bergeouss — #1276, closes #481 - **Batch session select mode** — multi-select sessions for bulk Archive/Delete/Move. 11 i18n keys × 7 locales. @bergeouss — #1275, closes #568 - **Collapsible skill category headers** — click to collapse/expand without re-render; state persists across filter cycles. @bergeouss — #1281 - **`providers.only_configured` setting** — opt-in flag to restrict the model picker to explicitly configured providers. @KingBoyAndGirl — #1268 - **OpenCode Go model catalog** — adds Kimi K2.6, DeepSeek V4 Pro/Flash, MiMo V2.5/Pro, Qwen3.6/3.5 Plus. @nesquena-hermes — #1284, closes #1269 ### Fixed - **Profile `TERMINAL_CWD` TypeError** — `_build_agent_thread_env()` helper merges env before `_set_thread_env()` call. @hi-friday — #1266 - **Service worker subpath cache bypass** — regex now matches `/api/*` under any mount prefix. @Michaelyklam — #1278 - **SSE client disconnect leaks** — `TimeoutError`/`OSError` treated as clean disconnects; server backlog 64, threads daemonized; session list renders before saved-session restore. @KayZz69 — #1267 - **i18n locale corrections** — Korean MCP strings (23), Chinese MCP strings (23), zh-Hant missing keys (41), de missing keys (229). @bergeouss — #1274, closes #1273 --- ### Test results ``` 3199 passed, 2 skipped, 3 xpassed in 72.79s ``` ### PRs on hold (not included) #1265 (draft), #1271 (superseded by #1266), #1272 (skipped XSS tests), #1232 (partial test run), #1222 (review questions open), #1134 (live-server tests), #1132 (superseded by #1134), #1108 (negative UX review), #1084 (empty description)
55 lines
2.6 KiB
Python
55 lines
2.6 KiB
Python
import pathlib
|
|
import re
|
|
|
|
|
|
STYLE_CSS = (pathlib.Path(__file__).parent.parent / "static" / "style.css").read_text(encoding="utf-8")
|
|
UI_JS = (pathlib.Path(__file__).parent.parent / "static" / "ui.js").read_text(encoding="utf-8")
|
|
COMPACT_CSS = re.sub(r"\s+", "", STYLE_CSS)
|
|
|
|
|
|
def test_tool_card_toggle_uses_transformable_layout_and_transition():
|
|
assert ".tool-card-toggle{" in COMPACT_CSS
|
|
assert "display:inline-flex" in COMPACT_CSS
|
|
assert "transition:transform.18sease" in COMPACT_CSS
|
|
|
|
|
|
def test_tool_card_detail_uses_transitionable_collapsed_state():
|
|
assert ".tool-card-detail{display:block;max-height:0;opacity:0;overflow:hidden;" in COMPACT_CSS
|
|
assert re.search(
|
|
r"\.tool-card\.open\s+\.tool-card-detail\s*\{[^}]*max-height:\s*600px;[^}]*opacity:\s*1;",
|
|
STYLE_CSS,
|
|
)
|
|
# Open state must set overflow to auto so the inner <pre> scroll is not clipped (#1170).
|
|
assert re.search(
|
|
r"\.tool-card\.open\s+\.tool-card-detail\s*\{[^}]*overflow:\s*auto;",
|
|
STYLE_CSS,
|
|
)
|
|
|
|
|
|
def test_thinking_card_toggle_and_body_use_animation_friendly_state():
|
|
assert ".thinking-card-toggle{margin-left:auto;font-size:10px;display:inline-flex;" in COMPACT_CSS
|
|
assert ".thinking-card-header{display:flex;align-items:center;gap:8px;" in COMPACT_CSS
|
|
# Body uses div default (display:block); canonical rule lives in the
|
|
# consolidated block. Open state caps at 260px (intentional "quieter" sizing).
|
|
assert ".thinking-card-body{max-height:0;opacity:0;overflow:hidden;" in COMPACT_CSS
|
|
assert re.search(
|
|
r"\.thinking-card\.open\s+\.thinking-card-body\s*\{[^}]*max-height:\s*260px;[^}]*opacity:\s*1;",
|
|
STYLE_CSS,
|
|
)
|
|
|
|
|
|
def test_tool_card_toggle_uses_same_chevron_icon_markup_as_thinking_card():
|
|
assert "<span class=\"thinking-card-toggle\">${li('chevron-right',12)}</span>" in UI_JS
|
|
assert "<span class=\"tool-card-toggle\">${li('chevron-right',12)}</span>" in UI_JS
|
|
assert "<div class=\"thinking-card\"><div class=\"thinking-card-header\" onclick=\"this.parentElement.classList.toggle('open')\"><span class=\"thinking-card-icon\">" in UI_JS
|
|
|
|
|
|
def test_thinking_card_uses_panel_chrome_with_gold_palette():
|
|
# Canonical thinking-card rule lives in the consolidated block (border-radius
|
|
# tightened from 10px → 8px as part of the "quieter card" design pass).
|
|
assert re.search(
|
|
r"\.thinking-card\s*\{[^}]*background:\s*var\(--accent-bg\);[^}]*border:\s*1px\s+solid\s+var\(--accent-bg-strong\);[^}]*border-radius:\s*8px;",
|
|
STYLE_CSS,
|
|
)
|
|
assert "border-left: 2px solid rgba(201,168,76,.4);" not in STYLE_CSS
|