From 0413ee4fc0b5738240ff3b3ebc72f0b5b50a0a9e Mon Sep 17 00:00:00 2001 From: Hermes Bot Date: Sun, 3 May 2026 07:15:01 +0000 Subject: [PATCH] release: stamp v0.50.278 (PR #1520 \u2014 sidebar Unassigned filter chip) CHANGELOG, ROADMAP, TESTING bumped (3929 \u2192 3936). Pre-release Opus advisor pass: SHIP AS-IS. Sentinel collision impossible (UUID hex \u2014 no underscores), stale-active-filter on project delete safe, CSS specificity clean. One non-blocking edge case (stuck filter at zero projects + zero unassigned) explicitly deferred per Opus advice (recoverable via reload, too narrow to justify pre-merge work). Both contributors (Thanatos-Z and AlexeyDsov) credited via Co-authored-by trailers preserved from the synthesis commit. --- CHANGELOG.md | 13 +++++++++++++ ROADMAP.md | 2 +- TESTING.md | 4 ++-- 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8aacf567..e852b72b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,18 @@ # Hermes Web UI -- Changelog +## [v0.50.278] — 2026-05-03 + +### Added (1 PR — splices best of #1497 + #1513) + +- **Sidebar "Unassigned" filter chip** (self-built, splices contributor PRs #1497 by @Thanatos-Z and #1513 by @AlexeyDsov; both contributors credited via `Co-authored-by` trailers on the merge commit) — adds a new chip to the project filter bar in the session sidebar. Clicking it filters the visible sessions to those with no `project_id` assigned. **First-principles synthesis** of both contributor approaches: (1) **Sentinel state** from #1497 (`NO_PROJECT_FILTER = '__none__'` constant on the existing `_activeProject` variable rather than a parallel `_showNoneProject` boolean from #1513) — single state variable, no two-state-machine ambiguity, "All" handler resets one variable, no risk of "All" + "Unassigned" both reading active. UUID hex collision impossible (`api/models.py:923` and `api/routes.py:2672` both use `uuid.uuid4().hex[:12]`, no underscores). (2) **Conditional rendering** from #1497 — chip only appears when `hasUnprojected = profileFiltered.some(s => !s.project_id)` is true, so the project-bar stays uncluttered in the common case where every session is organized. The project-bar itself now also renders when there are unassigned sessions even with no projects (was previously gated on `_allProjects.length > 0` alone). (3) **Dashed-border visual** from #1497 (`.project-chip.no-project{border-style:dashed;}`) reads as a meta-filter rather than another project. (4) **"Unassigned" label** (new) is clearer than #1497's "No project" (sounds like a status filter) or #1513's "None" (ambiguous — none of what?). Matches conventional file-manager / task-tracker UX. Hover tooltip elaborates: "Show conversations not yet assigned to a project." (5) **Branched empty-state copy** from #1497 ("No unassigned sessions." vs the generic "No sessions in this project yet."). 7 regression tests in `tests/test_sidebar_unassigned_filter.py` pin every contract: sentinel constant declared, filter logic uses `!s.project_id` when sentinel is active, chip only renders when relevant, label and click handler, dashed-border treatment, branched empty-state copy, and the "All" chip handler resets `_activeProject` to null (catches a regression toward a parallel-boolean design). + +### Notes + +- 3929 → **3936** tests passing (+7 regression tests). +- Pre-release Opus advisor pass: SHIP AS-IS. Verified sentinel collision impossible, stale-active-filter on project delete safe (sentinel never equals a real project_id), CSS specificity has no conflict (active chip = dashed border + accent color), source-string tests match the sibling-feature pattern. One non-blocking edge case (stuck filter when zero projects + zero unassigned, recoverable via page reload) explicitly deferred per Opus advice — too narrow to justify pre-merge work. +- Both contributor PRs (#1497, #1513) remain open and unaffected — this PR specifically supersedes only the "no project filter" sub-feature of each. #1497's other changes (sticky controls, batch-select repositioning) still need their own UX review pass; #1513's right-click context menu was intentionally dropped because "rename/delete no project" isn't a meaningful action. +- Live verified at port 8789 with seeded data (5 projects + 77 sessions, ~73 unassigned in the active profile): chip toggles correctly between filters, dashed border present per `getComputedStyle`, active state applies the accent treatment. + ## [v0.50.277] — 2026-05-03 ### Fixed (1 PR — self-built, supersedes contributor PR #1511) diff --git a/ROADMAP.md b/ROADMAP.md index 740796cd..6784147b 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -3,7 +3,7 @@ > Goal: Full 1:1 parity with the Hermes CLI experience via a clean dark web UI. > Everything you can do from the CLI terminal, you can do from this UI. > -> Last updated: v0.50.277 (May 03, 2026) — 3929 tests collected +> Last updated: v0.50.278 (May 03, 2026) — 3936 tests collected > Tests: `pytest tests/ --collect-only -q` > Source: / diff --git a/TESTING.md b/TESTING.md index 68d63e77..a8a15379 100644 --- a/TESTING.md +++ b/TESTING.md @@ -1835,8 +1835,8 @@ Bridged CLI sessions: --- -*Last updated: v0.50.277, May 03, 2026* -*Total automated tests collected: 3929* +*Last updated: v0.50.278, May 03, 2026* +*Total automated tests collected: 3936* *Regression gate: tests/test_regressions.py* *Run: pytest tests/ -v --timeout=60* *Source: /*