docs: v0.36 release notes, version bump for self-update checker

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Nathan Esquenazi
2026-04-05 09:27:27 -07:00
parent beb56b1a8b
commit 27706367b7
3 changed files with 36 additions and 4 deletions

View File

@@ -5,6 +5,38 @@
--- ---
## [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 ## [v0.35.1] Model dropdown fixes
*April 5, 2026 | 433 tests* *April 5, 2026 | 433 tests*
@@ -1236,4 +1268,4 @@ Three-panel layout: sessions sidebar, chat area, workspace panel.
--- ---
*Last updated: v0.34, April 5, 2026 | Tests: 433* *Last updated: v0.36, April 5, 2026 | Tests: 433*

View File

@@ -1,6 +1,6 @@
# Hermes Web UI -- Forward Sprint Plan # Hermes Web UI -- Forward Sprint Plan
> Current state: v0.35 | 433 tests | Daily driver ready > Current state: v0.36 | 433 tests | Daily driver ready
> This document plans the path from here to two targets: > This document plans the path from here to two targets:
> >
> Target A: 1:1 feature parity with the Hermes CLI (everything you can do from the > Target A: 1:1 feature parity with the Hermes CLI (everything you can do from the
@@ -1156,6 +1156,6 @@ New test cases in `tests/test_sprint26.py`:
--- ---
*Last updated: April 5, 2026* *Last updated: April 5, 2026*
*Current version: v0.35 | 433 tests* *Current version: v0.36 | 433 tests*
*Next sprint: Sprint 24 (Web Polish + Bug Fix Pass)* *Next sprint: Sprint 24 (Web Polish + Bug Fix Pass)*
*Horizon sprint: Sprint 25 (macOS Desktop Application)* *Horizon sprint: Sprint 25 (macOS Desktop Application)*

View File

@@ -14,7 +14,7 @@
<body> <body>
<div class="layout"> <div class="layout">
<aside class="sidebar"> <aside class="sidebar">
<div class="sidebar-header"><div class="logo">H</div><div><h1 style="margin:0;font-size:15px;font-weight:700;letter-spacing:-.01em">Hermes</h1><div style="font-size:10px;color:var(--muted);opacity:.8;margin-top:1px">v0.35.1</div></div></div> <div class="sidebar-header"><div class="logo">H</div><div><h1 style="margin:0;font-size:15px;font-weight:700;letter-spacing:-.01em">Hermes</h1><div style="font-size:10px;color:var(--muted);opacity:.8;margin-top:1px">v0.36</div></div></div>
<div class="sidebar-nav"> <div class="sidebar-nav">
<button class="nav-tab active" data-panel="chat" data-label="Chat" onclick="switchPanel('chat')" title="Chat">&#128172;</button> <button class="nav-tab active" data-panel="chat" data-label="Chat" onclick="switchPanel('chat')" title="Chat">&#128172;</button>
<button class="nav-tab" data-panel="tasks" data-label="Tasks" onclick="switchPanel('tasks')" title="Tasks">&#128197;</button> <button class="nav-tab" data-panel="tasks" data-label="Tasks" onclick="switchPanel('tasks')" title="Tasks">&#128197;</button>