diff --git a/CHANGELOG.md b/CHANGELOG.md index bc41f30..ef3158b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,29 @@ ### Added - **`/compress` command with optional focus topic** — manual session compression runs as a real API call via `POST /api/session/compress`, replacing the old agent-message-based `/compact`. Accepts an optional focus topic (`/compress summarize code changes`) that guides what the compression preserves. The compression flow is shown as three transcript-inline cards: a command card (gold), a running card (blue with animated dots), and a collapsible green success card showing the message-count delta and token savings. A reference card renders the full context compaction summary. `/compact` continues to work as an alias. `focus_topic` capped at 500 chars for defense-in-depth. Fallback token estimation uses word-count approximation when model metadata helpers are unavailable — intentional for resilience. (Closes #469, PR #619 by @franksong2702) +## [v0.50.81] — 2026-04-18 + +### Fixed +- **Auto-title extraction improved for tool-heavy first turns** — sessions where the agent's first response involved tool calls (e.g. memory lookups, file reads) were generating poor titles because the title extractor skipped all assistant messages with `tool_calls`, even when those messages contained substantive visible text. The extractor now picks the first pure (non-tool-call) assistant reply as the title source, using `_looks_invalid_generated_title()` to distinguish meta-reasoning preambles from real agentic replies. Also fixes `_is_provisional_title()` to normalize whitespace before comparing, so CJK text truncated at 64 characters correctly re-triggers title updates. (Closes #639, PR #640 by @franksong2702) + + +## [v0.50.80] — 2026-04-18 + +### Fixed +- **Clicking a skill no longer silently loads content into a hidden panel** — `openSkill()` now calls `ensureWorkspacePreviewVisible()` so the workspace panel auto-opens when you click a skill in the Skills tab. (Closes #643) +- **Long thinking/reasoning traces now scroll instead of being clipped** — the thinking card body now uses `overflow-y: auto` when open, so long traces are fully readable. (Closes #638) +- **Sidebar nav icon hit targets are now correctly aligned** — added `display:flex; align-items:center; justify-content:center` to `.nav-tab` so clicking the icon itself (not below it) activates the tab. (Closes #636) +- **Safari iOS input auto-zoom fixed** — bumped `textarea#msg` base font-size from 14px to 16px, which prevents Safari from zooming the viewport on input focus (Safari zooms when font-size < 16px). Visual difference is negligible. (Closes #630) + +## [v0.50.79] — 2026-04-17 + +### Fixed +- **Default model no longer shows as "(unavailable)" for non-OpenAI users** — changed the hardcoded fallback `DEFAULT_MODEL` from `openai/gpt-5.4-mini` to `""` (empty). When no default model is configured, the WebUI now defers to the active provider's own default instead of pre-selecting an OpenAI model that most providers don't have. Users who want a specific default can still set `HERMES_WEBUI_DEFAULT_MODEL` env var or pick a model in Preferences. (Closes #646) + +## [v0.50.78] — 2026-04-17 + +### Fixed +- **Gemma 4 thinking tokens no longer shown raw in chat** — added `<|turn|>thinking\n...` to the streaming think-token parser in `static/messages.js` and `_strip_thinking_markup()` in `api/streaming.py`. Previously Gemma 4's reasoning output appeared as raw text prepended to the answer. (Closes #607) ## [v0.50.77] — 2026-04-17 ### Changed @@ -20,29 +43,6 @@ - **Topbar border invisible in light mode** — added `:root:not(.dark)` border override. (PR #627) - **User message bubble text contrast** — accent-colored bubbles now use skin-aware text colors meeting WCAG AA (Poseidon dark improved from 2.8 → 6.5 ratio). (PR #627) - **Settings skin persistence race condition** — save now waits for server confirmation before applying. (PR #627) -## [v0.50.78] — 2026-04-17 - -### Fixed -- **Gemma 4 thinking tokens no longer shown raw in chat** — added `<|turn|>thinking\n...` to the streaming think-token parser in `static/messages.js` and `_strip_thinking_markup()` in `api/streaming.py`. Previously Gemma 4's reasoning output appeared as raw text prepended to the answer. (Closes #607) -## [v0.50.79] — 2026-04-17 - -### Fixed -- **Default model no longer shows as "(unavailable)" for non-OpenAI users** — changed the hardcoded fallback `DEFAULT_MODEL` from `openai/gpt-5.4-mini` to `""` (empty). When no default model is configured, the WebUI now defers to the active provider's own default instead of pre-selecting an OpenAI model that most providers don't have. Users who want a specific default can still set `HERMES_WEBUI_DEFAULT_MODEL` env var or pick a model in Preferences. (Closes #646) - -## [v0.50.80] — 2026-04-18 - -### Fixed -- **Clicking a skill no longer silently loads content into a hidden panel** — `openSkill()` now calls `ensureWorkspacePreviewVisible()` so the workspace panel auto-opens when you click a skill in the Skills tab. (Closes #643) -- **Long thinking/reasoning traces now scroll instead of being clipped** — the thinking card body now uses `overflow-y: auto` when open, so long traces are fully readable. (Closes #638) -- **Sidebar nav icon hit targets are now correctly aligned** — added `display:flex; align-items:center; justify-content:center` to `.nav-tab` so clicking the icon itself (not below it) activates the tab. (Closes #636) -- **Safari iOS input auto-zoom fixed** — bumped `textarea#msg` base font-size from 14px to 16px, which prevents Safari from zooming the viewport on input focus (Safari zooms when font-size < 16px). Visual difference is negligible. (Closes #630) - -## [v0.50.81] — 2026-04-18 - -### Fixed -- **Auto-title extraction improved for tool-heavy first turns** — sessions where the agent's first response involved tool calls (e.g. memory lookups, file reads) were generating poor titles because the title extractor skipped all assistant messages with `tool_calls`, even when those messages contained substantive visible text. The extractor now picks the first pure (non-tool-call) assistant reply as the title source, using `_looks_invalid_generated_title()` to distinguish meta-reasoning preambles from real agentic replies. Also fixes `_is_provisional_title()` to normalize whitespace before comparing, so CJK text truncated at 64 characters correctly re-triggers title updates. (Closes #639, PR #640 by @franksong2702) - - ## [v0.50.76] — 2026-04-17 ### Fixed @@ -1349,38 +1349,6 @@ Major UI overhaul by **[@aronprins](https://github.com/aronprins)** — the bigg --- -## [v0.36] Self-Update Checker with One-Click Update -*April 5, 2026 | 433 tests* - -### Features -- **Update checker.** Non-blocking background check on boot detects when the - WebUI or hermes-agent git repos are behind upstream. Blue banner shows - "WebUI: N updates, Agent: N updates available" with Update Now / Later. -- **One-click update.** "Update Now" runs `git stash && git pull --ff-only && - git stash pop` on each behind repo, then reloads the page. Concurrent update - attempts blocked via lock. Dirty working trees safely stashed and restored. -- **Settings toggle.** "Check for updates" checkbox in Settings panel. Persisted - server-side. Disabled = no background fetch, no banner. -- **30-minute cache.** Git fetch runs at most twice per hour regardless of tab - count. Results cached server-side with TTL. -- **Session-scoped dismissal.** "Later" dismisses banner for the current tab - session (sessionStorage). New tabs get a fresh check. -- **Test mode.** `?test_updates=1` URL param shows the banner with fake data - (localhost only) for UI testing without needing to actually be behind. - -### Architecture -- New `api/updates.py`: `check_for_updates()`, `apply_update()`. Thread-safe - caching with `_cache_lock`. Concurrent apply blocked with `_apply_lock`. - Default branch auto-detected (master/main). -- `api/routes.py`: `GET /api/updates/check`, `POST /api/updates/apply`. - Simulate endpoint gated to 127.0.0.1. -- `static/ui.js`: `_showUpdateBanner()`, `dismissUpdate()`, `applyUpdates()`. -- `static/boot.js`: fire-and-forget check on boot (does not block UI). -- `api/config.py`: `check_for_updates` in settings defaults + bool keys. -- Docker safe: all git ops gated by `.git` directory existence check. - ---- - ## [v0.35.1] Model dropdown fixes *April 5, 2026 | 433 tests* @@ -1390,19 +1358,6 @@ Major UI overhaul by **[@aronprins](https://github.com/aronprins)** — the bigg --- -## [v0.35] Security hardening -*April 5, 2026 | 433 tests* - -### Security fixes -- **ENV race condition (HIGH):** Two concurrent sessions could interleave `os.environ` writes, clobbering workspace and session keys. Fixed with a global `_ENV_LOCK` in `streaming.py` that serializes the env save/restore block across all sessions. (#108) -- **Predictable signing key (MEDIUM):** Session cookies were signed with `sha256(STATE_DIR)` -- deterministic and forgeable if the install path is known. Now generates a cryptographically random 32-byte key on first startup, persisted to `STATE_DIR/.signing_key` (chmod 600). (#108) -- **Upload path traversal (MEDIUM):** Filenames like `..` survived the `[^\w.\-]` sanitization regex because dots are allowed. Fixed by rejecting dot-only filenames and validating the resolved path stays within the workspace sandbox via `safe_resolve_ws()`. (#108) -- **Weak password hashing (MEDIUM):** Bare SHA-256 with a predictable salt replaced with PBKDF2-SHA256 at 600k iterations (OWASP recommendation) using the random signing key as salt. No new dependencies (stdlib `hashlib.pbkdf2_hmac`). (#108) - -**Breaking change:** Existing session cookies and password hashes are invalidated on first restart after upgrade. Users with password auth enabled will need to re-set their password. - ---- - ## [v0.34.3] Light theme final polish *April 5, 2026 | 433 tests* @@ -1429,81 +1384,6 @@ Major UI overhaul by **[@aronprins](https://github.com/aronprins)** — the bigg --- -## [v0.34] Sprint 26 -- Pluggable UI Themes -*April 5, 2026 | 433 tests* - -### Features -- **6 built-in themes.** Dark (default), Light, Slate, Solarized Dark, Monokai, - Nord. Defined as CSS variable overrides on `:root[data-theme="name"]` — the - entire UI adapts automatically. -- **Theme picker in Settings.** Dropdown with instant live preview. Changes - apply immediately as you click through options. -- **`/theme` slash command.** `/theme dark`, `/theme light`, etc. -- **Theme persistence.** Saved server-side in `settings.json` and client-side - in `localStorage` for flicker-free loading on page refresh. -- **Flash prevention.** Inline `