docs: v0.40.2 release — approval UI, 547 tests (#188)
Co-authored-by: Nathan Esquenazi <nesquena@gmail.com>
This commit is contained in:
33
CHANGELOG.md
33
CHANGELOG.md
@@ -6,6 +6,39 @@
|
|||||||
---
|
---
|
||||||
|
|
||||||
|
|
||||||
|
## [v0.40.2] — 2026-04-09
|
||||||
|
|
||||||
|
### Features
|
||||||
|
- **Full approval UI** (PR #187): When the agent triggers a dangerous command
|
||||||
|
(e.g. `rm -rf`, `pkill -9`), a polished approval card now appears immediately
|
||||||
|
instead of leaving the chat stuck in "Thinking…" forever. Four one-click buttons:
|
||||||
|
Allow once, Allow session, Always allow, Deny. Enter key defaults to Allow once.
|
||||||
|
Buttons disable immediately on click to prevent double-submit. Card auto-focuses
|
||||||
|
Allow once so keyboard-only users can approve in one keystroke. All labels and
|
||||||
|
the heading are fully i18n-translated (English + Chinese).
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
- **Approval SSE event never sent** (PR #187): `register_gateway_notify()` was
|
||||||
|
never called before the agent ran, so the approval module had no way to push
|
||||||
|
the `approval` SSE event to the frontend. Fixed by registering a callback that
|
||||||
|
calls `put('approval', ...)` the instant a dangerous command is detected.
|
||||||
|
- **Agent thread never unblocked** (PR #187): `/api/approval/respond` did not call
|
||||||
|
`resolve_gateway_approval()`, so the agent thread waited for the full 5-minute
|
||||||
|
gateway timeout. Now calls it on every respond, waking the thread immediately.
|
||||||
|
- **`_unreg_notify` scoping** (PR #187): Variable was only assigned inside a `try`
|
||||||
|
block but referenced in `finally`. Initialised to `None` before the `try` so the
|
||||||
|
`finally` guard is always well-defined.
|
||||||
|
|
||||||
|
### Tests
|
||||||
|
- 32 new tests in `tests/test_sprint30.py`: approval card HTML structure, all 4
|
||||||
|
button IDs and data-i18n labels, keyboard shortcut in boot.js, i18n keys in both
|
||||||
|
locales, CSS loading/disabled/kbd states, messages.js button-disable behaviour,
|
||||||
|
streaming.py scoping, HTTP regression for all 4 choices.
|
||||||
|
- 16 tests in `tests/test_approval_unblock.py` (gateway approval unit + HTTP).
|
||||||
|
- **547 tests total** (499 → 515 → 547).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## [v0.40.1] — 2026-04-09
|
## [v0.40.1] — 2026-04-09
|
||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
> Prerequisites: SSH tunnel is active on port 8786. Open http://localhost:8786 in browser.
|
> Prerequisites: SSH tunnel is active on port 8786. Open http://localhost:8786 in browser.
|
||||||
> Server health check: curl http://127.0.0.1:8786/health should return {"status":"ok"}.
|
> Server health check: curl http://127.0.0.1:8786/health should return {"status":"ok"}.
|
||||||
>
|
>
|
||||||
> Automated tests: 499 total (499 passing, 0 known isolation failures)
|
> Automated tests: 547 total (547 passing, 0 known isolation failures)
|
||||||
> Run: `pytest tests/ -v --timeout=60`
|
> Run: `pytest tests/ -v --timeout=60`
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -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.40.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.40.2</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">💬</button>
|
<button class="nav-tab active" data-panel="chat" data-label="Chat" onclick="switchPanel('chat')" title="Chat">💬</button>
|
||||||
<button class="nav-tab" data-panel="tasks" data-label="Tasks" onclick="switchPanel('tasks')" title="Tasks">📅</button>
|
<button class="nav-tab" data-panel="tasks" data-label="Tasks" onclick="switchPanel('tasks')" title="Tasks">📅</button>
|
||||||
|
|||||||
Reference in New Issue
Block a user