Skip to content

release: v0.51.95 (Release BS / stage-388 / 5-PR batch — live tool dedup + browser dashboard links + messaging dedup + Geist Contrast skin + SSE diagnostics)#2608

Merged
nesquena-hermes merged 19 commits into
masterfrom
release/stage-388
May 20, 2026
Merged

release: v0.51.95 (Release BS / stage-388 / 5-PR batch — live tool dedup + browser dashboard links + messaging dedup + Geist Contrast skin + SSE diagnostics)#2608
nesquena-hermes merged 19 commits into
masterfrom
release/stage-388

Conversation

@nesquena-hermes
Copy link
Copy Markdown
Collaborator

Release v0.51.95 — 5-PR batch

5 contributor PRs across 4 backend fixes + 1 visual skin. All rebased clean, full pytest (6,065 tests) green, Opus Advisor said ship.

What's in this batch

Fixed (backend)

  • PR fix: stream live tool callback events #2598 by @AJV20 — Surface live tool activity when Hermes Agent reports tools through its dedicated tool_start_callback / tool_complete_callback path. Legacy on_tool path now early-returns for tool.started / tool.completed when structured callbacks are wired, preventing double-emission to the SSE stream.
  • PR fix(system): allow browser-only dashboard links #2533 by @AJV20 — Allow Settings → System to save public browser-only Official Hermes Dashboard links (reverse-proxy URLs) without treating them as server-side probe targets. URL sanitization runs against the configured link; dashboard probe is skipped for browser-only links.
  • PR fix(session): dedupe messaging transcript timestamp variants #2607 by @AJV20 — Deduplicate messaging/CLI session transcript rows when the sidecar and state store encode the same no-id message with equivalent timestamps in different formats ("10.0" vs 10). The messaging-display merge now reuses _session_message_merge_key(...) instead of an ad-hoc dedup key.

Added (additive surface)

  • PR feat: add Geist Contrast skin #2521 by @intellectronica — Geist Contrast skin. Light + dark variant pair, high-contrast yellow-on-black accent, Geist editorial typography. Opt-in only via Settings → Appearance → Skin. Default unchanged. Slash command /theme geist-contrast now resolves correctly via skin.value lookup. Visually approved by Nathan via Telegram-gated screenshot package across 4 viewports (desktop dark/light + mobile dark/light, 1920×1080 + 390×844).
  • PR feat(health): expose WebUI stream runtime diagnostics #2524 by @AJV20 — Add non-sensitive SSE stream runtime diagnostics to /health?deep=1 (active stream count, subscriber totals, offline buffered-event counts). Read-only telemetry; existing surfaces unchanged.

Pre-Opus gate

Check Result
Python AST (api/)
JS syntax (sessions / ui / boot / messages / commands)
Merge markers ✅ (none)
CHANGELOG placeholders ✅ (no TBD/N/A)
CJK escapes ✅ (n/a, only pre-existing test fixtures)
Docker surface ✅ (no changes)
api/routes.py size delta ✅ (+47/-12)

Tests

  • Full pytest: 6,065 passed, 6 skipped, 3 xpassed, 8 subtests passed (130s)
  • Two existing tests needed tightening to accommodate PR feat: add Geist Contrast skin #2521's scoped :root[data-skin="geist-contrast"] overrides (they used naive STYLE_CSS.find(".theme-pick-btn.active") substring matching that picked up the new scoped selector instead of the global rule). Fixed by anchoring the searches to the #mainSettings selector prefix and excluding :root[data-skin= lines from the session-title color assertion. The global rules are unchanged — only test specificity tightened.

Browser sanity check

  • /health returns ok
  • /health?deep=1 shows the new stream_runtime block from PR feat(health): expose WebUI stream runtime diagnostics #2524
  • POST /api/settings {"skin":"geist-contrast"} accepted; setting persisted
  • POST /api/settings {"dashboard_browser_url":"http://localhost:9119/dashboard"} accepted (no 422)

Opus Advisor verdict

Ship the stage. All five PRs are logically sound. One follow-up worth a tracked-but-not-blocking ticket: IPv6 bracket-stripping bug in normalize_dashboard_browser_url (api/dashboard_probe.py:89-93) — http://[::1]:9119 reconstructs as http://::1:9119 (brackets dropped). Not security-critical (IPv6 dashboards uncommon); fine to ship and patch in a follow-up.

Opus also confirmed PR #2598's early-return gate is correctly conditional on _agent_params set membership, so legacy-only agents still emit events. PR #2607's merge key handles all numeric timestamp encodings via _normalized_message_timestamp_for_key. PR #2521's /theme slash command fix preserves single-word skin lookups via the (s.value || s.name) fallback.

Follow-up tickets (non-blocking)

  • IPv6 host bracket-stripping in api/dashboard_probe.py — open as a separate issue after this batch ships.

PRs in this stage

Closes: #2598, #2533, #2607, #2521, #2524


🤖 Stage authored by agent following the canonical full-PR-triage-release workflow. Brief at /tmp/stage-388-brief.md. Worktree at /tmp/wt-stage-388.

AJV20 and others added 19 commits May 19, 2026 14:55
# Conflicts:
#	CHANGELOG.md
Unreleased section now reflects:
- PR #2598 live tool event dedup (AJV20)
- PR #2533 browser dashboard links (AJV20)
- PR #2607 messaging transcript dedup (AJV20)
- PR #2521 Geist Contrast skin (intellectronica)
- PR #2524 SSE runtime diagnostics endpoint (AJV20)

Removed merge markers and consolidated stray entries that leaked into the v0.51.94 release block.
PR #2521 (Geist Contrast skin) legitimately adds a scoped
`:root[data-skin="geist-contrast"] .theme-pick-btn.active` override that
appears earlier in style.css than the global `#mainSettings .theme-pick-btn.active`
rule. The naive substring search in tests/test_1059_settings_picker_active_state.py
found the skin-specific override first (which correctly uses --border2 for its
palette), failing the global assertion that wanted --accent.

Tighten both assertions to anchor on the `#mainSettings` selector prefix so
they always match the global rule regardless of how many skin-specific
overrides land in the file.
…assertion

PR #2521 (Geist Contrast skin) adds a scoped
`:root[data-skin="geist-contrast"] .session-item.active .session-title` rule
that legitimately uses its own palette values. The existing assertion in
test_sprint40_ui_polish.py matched on any line containing the
`.session-item.active .session-title` substring, picking up the skin-scoped
override and asserting against its palette.

Exclude lines containing `:root[data-skin=` from the base-rule scan so
skin-scoped overrides are free to use their own design tokens, while the
global rule still enforces var(--gold) / var(--accent-text).
@nesquena-hermes nesquena-hermes merged commit 9c983e6 into master May 20, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants