diff --git a/CHANGELOG.md b/CHANGELOG.md index 5548aa4..939b4d8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,33 @@ --- +## [v0.27] Profile Creation Fallback for Docker (Issue #44) +*April 3, 2026 | 426 tests* + +### Bug Fixes +- **Profile creation works without hermes-agent.** In Docker containers where + `hermes_cli` is not importable, profile creation now falls back to a local + implementation that creates the directory structure and optionally clones + config files. Previously returned `RuntimeError` with "hermes-agent required". +- **Name validation uses `fullmatch()`.** Prevents trailing-newline bypass of + the `$` anchor in `re.match()`. Not reachable from the web UI (name is + stripped), but fixed for defense-in-depth. +- **`clone_from` validated in `create_profile_api()`.** Defense-in-depth: + prevents path traversal if called by a non-HTTP client. +- **Fallback return uses full 9-key schema.** Previously returned only 2 keys + (`name`, `path`), inconsistent with the normal response shape. +- **Atomic directory creation.** `mkdir(exist_ok=False)` prevents TOCTOU race + on concurrent profile creates. + +### Architecture +- `api/profiles.py`: `_validate_profile_name()`, `_create_profile_fallback()`, + `_PROFILE_ID_RE`, `_PROFILE_DIRS`, `_CLONE_CONFIG_FILES` constants matching + upstream `hermes_cli.profiles`. +- `docker-compose.yml`: Removed `:ro` from `~/.hermes` mount (required for + profile writes). Localhost-only binding preserved. + +--- + ## [v0.26] Profile System Polish -- 10 Post-Sprint-23 Fixes *April 3, 2026 | 426 tests* @@ -877,4 +904,4 @@ Three-panel layout: sessions sidebar, chat area, workspace panel. --- -*Last updated: v0.26, April 3, 2026 | Tests: 426* +*Last updated: v0.27, April 3, 2026 | Tests: 426* diff --git a/SPRINTS.md b/SPRINTS.md index 6d104c2..e50b6c6 100644 --- a/SPRINTS.md +++ b/SPRINTS.md @@ -1,6 +1,6 @@ # Hermes Web UI -- Forward Sprint Plan -> Current state: v0.26 | 426 tests | Daily driver ready +> Current state: v0.27 | 426 tests | Daily driver ready > 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 @@ -663,5 +663,5 @@ and switchToProfile() didn't refresh workspaces or sessions. --- *Last updated: April 3, 2026* -*Current version: v0.26 | 426 tests* +*Current version: v0.27 | 426 tests* *Next sprint: Sprint 24 (Desktop Application)* diff --git a/static/index.html b/static/index.html index 1bd22f9..4903dce 100644 --- a/static/index.html +++ b/static/index.html @@ -13,7 +13,7 @@