docs: fix CHANGELOG ordering + README architecture counts
- CHANGELOG: reorder v0.50.19/v0.50.20/v0.50.21 to correct newest-first (v0.50.19 was mistakenly at the top above v0.50.21 and v0.50.20) - README: fix architecture block test count 51 files/802 functions → 61 files/961 - README: update line counts to actual wc -l values: routes.py ~2250, streaming.py ~660, ui.js ~1740, messages.js ~655, sessions.js ~800 Co-authored-by: Nathan Esquenazi <nesquena@gmail.com>
This commit is contained in:
10
CHANGELOG.md
10
CHANGELOG.md
@@ -5,11 +5,6 @@
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## [v0.50.19] Fix UnicodeEncodeError when downloading files with non-ASCII filenames (PR #378)
|
|
||||||
|
|
||||||
- **Workspace file downloads no longer crash for Unicode filenames** (`api/routes.py`): Clicking a PDF or other file with Chinese, Japanese, Arabic, or other non-ASCII characters in its name caused a `UnicodeEncodeError` because Python's HTTP server requires header values to be latin-1 encodable. A new `_content_disposition_value(disposition, filename)` helper centralises `Content-Disposition` generation: it strips CR/LF (injection guard), builds an ASCII fallback for the legacy `filename=` parameter (non-ASCII chars replaced with `_`), and preserves the full UTF-8 name in `filename*=UTF-8''...` per RFC 5987. Both `attachment` and `inline` responses use it.
|
|
||||||
- 2 new integration tests in `tests/test_sprint29.py` covering Chinese filenames for both download and inline responses, verifying the header is latin-1 encodable and `filename*=UTF-8''` is present; 924 tests total (up from 922)
|
|
||||||
|
|
||||||
## [v0.50.21] Live reasoning, tool progress, and in-flight session recovery (PR #367)
|
## [v0.50.21] Live reasoning, tool progress, and in-flight session recovery (PR #367)
|
||||||
|
|
||||||
- **Durable inflight reload recovery** (`static/ui.js`, `static/messages.js`): `saveInflightState` / `loadInflightState` / `clearInflightState` backed by `localStorage` (`hermes-webui-inflight-state` key, per-session, 10-minute TTL). Snapshots are saved on every token, tool event, and tool completion, and cleared when the run ends/errors/cancels. On a full page reload with an active stream, `loadSession()` hydrates from the snapshot before calling `attachLiveStream(..., {reconnecting:true})` — partial messages, live tool cards, and reasoning text all survive the reload.
|
- **Durable inflight reload recovery** (`static/ui.js`, `static/messages.js`): `saveInflightState` / `loadInflightState` / `clearInflightState` backed by `localStorage` (`hermes-webui-inflight-state` key, per-session, 10-minute TTL). Snapshots are saved on every token, tool event, and tool completion, and cleared when the run ends/errors/cancels. On a full page reload with an active stream, `loadSession()` hydrates from the snapshot before calling `attachLiveStream(..., {reconnecting:true})` — partial messages, live tool cards, and reasoning text all survive the reload.
|
||||||
@@ -40,6 +35,11 @@
|
|||||||
- 25 new tests in `tests/test_issues_373_374_375.py`; 949 tests total (up from 924)
|
- 25 new tests in `tests/test_issues_373_374_375.py`; 949 tests total (up from 924)
|
||||||
|
|
||||||
|
|
||||||
|
## [v0.50.19] Fix UnicodeEncodeError when downloading files with non-ASCII filenames (PR #378)
|
||||||
|
|
||||||
|
- **Workspace file downloads no longer crash for Unicode filenames** (`api/routes.py`): Clicking a PDF or other file with Chinese, Japanese, Arabic, or other non-ASCII characters in its name caused a `UnicodeEncodeError` because Python's HTTP server requires header values to be latin-1 encodable. A new `_content_disposition_value(disposition, filename)` helper centralises `Content-Disposition` generation: it strips CR/LF (injection guard), builds an ASCII fallback for the legacy `filename=` parameter (non-ASCII chars replaced with `_`), and preserves the full UTF-8 name in `filename*=UTF-8''...` per RFC 5987. Both `attachment` and `inline` responses use it.
|
||||||
|
- 2 new integration tests in `tests/test_sprint29.py` covering Chinese filenames for both download and inline responses, verifying the header is latin-1 encodable and `filename*=UTF-8''` is present; 924 tests total (up from 922)
|
||||||
|
|
||||||
## [v0.50.18] Recover from invalid default workspace paths (PR #366)
|
## [v0.50.18] Recover from invalid default workspace paths (PR #366)
|
||||||
|
|
||||||
- **WebUI no longer breaks when the configured default workspace is unavailable** (`api/config.py`): The workspace resolution path was refactored into three composable functions — `_workspace_candidates()`, `_ensure_workspace_dir()`, and `resolve_default_workspace()`. When the configured workspace (from env var, settings file, or passed path) cannot be created or accessed, the server falls back through an ordered priority list: `HERMES_WEBUI_DEFAULT_WORKSPACE` env var → `~/workspace` (if exists) → `~/work` (if exists) → `~/workspace` (create it) → `STATE_DIR/workspace`.
|
- **WebUI no longer breaks when the configured default workspace is unavailable** (`api/config.py`): The workspace resolution path was refactored into three composable functions — `_workspace_candidates()`, `_ensure_workspace_dir()`, and `resolve_default_workspace()`. When the configured workspace (from env var, settings file, or passed path) cannot be created or accessed, the server falls back through an ordered priority list: `HERMES_WEBUI_DEFAULT_WORKSPACE` env var → `~/workspace` (if exists) → `~/work` (if exists) → `~/workspace` (create it) → `STATE_DIR/workspace`.
|
||||||
|
|||||||
12
README.md
12
README.md
@@ -470,25 +470,25 @@ api/
|
|||||||
models.py Session model + CRUD + CLI bridge (~377 lines)
|
models.py Session model + CRUD + CLI bridge (~377 lines)
|
||||||
onboarding.py First-run onboarding wizard, OAuth provider support (~507 lines)
|
onboarding.py First-run onboarding wizard, OAuth provider support (~507 lines)
|
||||||
profiles.py Profile state management, hermes_cli wrapper (~411 lines)
|
profiles.py Profile state management, hermes_cli wrapper (~411 lines)
|
||||||
routes.py All GET + POST route handlers (~2200 lines)
|
routes.py All GET + POST route handlers (~2250 lines)
|
||||||
state_sync.py /insights sync — message_count to state.db (~113 lines)
|
state_sync.py /insights sync — message_count to state.db (~113 lines)
|
||||||
streaming.py SSE engine, run_agent, cancel support (~560 lines)
|
streaming.py SSE engine, run_agent, cancel support (~660 lines)
|
||||||
updates.py Self-update check and release notes (~257 lines)
|
updates.py Self-update check and release notes (~257 lines)
|
||||||
upload.py Multipart parser, file upload handler (~82 lines)
|
upload.py Multipart parser, file upload handler (~82 lines)
|
||||||
workspace.py File ops, workspace helpers, git detection (~288 lines)
|
workspace.py File ops, workspace helpers, git detection (~288 lines)
|
||||||
static/
|
static/
|
||||||
index.html HTML template (~600 lines)
|
index.html HTML template (~600 lines)
|
||||||
style.css All CSS incl. mobile responsive, themes (~1050 lines)
|
style.css All CSS incl. mobile responsive, themes (~1050 lines)
|
||||||
ui.js DOM helpers, renderMd, tool cards, context indicator (~1900 lines)
|
ui.js DOM helpers, renderMd, tool cards, context indicator (~1740 lines)
|
||||||
workspace.js File preview, file ops, git badge (~286 lines)
|
workspace.js File preview, file ops, git badge (~286 lines)
|
||||||
sessions.js Session CRUD, collapsible groups, search, reload recovery (~840 lines)
|
sessions.js Session CRUD, collapsible groups, search, reload recovery (~800 lines)
|
||||||
messages.js send(), SSE handlers, rAF throttle, live streaming (~700 lines)
|
messages.js send(), SSE handlers, live streaming, session recovery (~655 lines)
|
||||||
panels.js Cron, skills, memory, profiles, settings (~1438 lines)
|
panels.js Cron, skills, memory, profiles, settings (~1438 lines)
|
||||||
commands.js Slash command autocomplete (~267 lines)
|
commands.js Slash command autocomplete (~267 lines)
|
||||||
boot.js Mobile nav, voice input, boot IIFE (~524 lines)
|
boot.js Mobile nav, voice input, boot IIFE (~524 lines)
|
||||||
tests/
|
tests/
|
||||||
conftest.py Isolated test server (port 8788)
|
conftest.py Isolated test server (port 8788)
|
||||||
51 test files 802 test functions
|
61 test files 961 test functions
|
||||||
Dockerfile python:3.12-slim container image
|
Dockerfile python:3.12-slim container image
|
||||||
docker-compose.yml Compose with named volume and optional auth
|
docker-compose.yml Compose with named volume and optional auth
|
||||||
.github/workflows/ CI: multi-arch Docker build + GitHub Release on tag
|
.github/workflows/ CI: multi-arch Docker build + GitHub Release on tag
|
||||||
|
|||||||
Reference in New Issue
Block a user