From 6b9b9dc808e51f570e56b77086ad4cd8e94cdf47 Mon Sep 17 00:00:00 2001 From: nesquena-hermes Date: Mon, 20 Jul 2026 20:57:21 -0700 Subject: [PATCH] Release: Kanban New-Task modal reachable on mobile (#6301, @jpalazz2) (#6384) Co-authored-by: nesquena-hermes --- CHANGELOG.md | 2 ++ static/style.css | 5 +++-- tests/test_kanban_ui_static.py | 21 +++++++++++++++++++++ 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 51cf8af3..deb84235 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,8 @@ ### Fixed +- **The Kanban "New task" modal is reachable on phones again.** On a narrow viewport, a tall create-task modal was vertically centered, pushing its top (the title and first input) above the top of the screen with no way to scroll back to it. The mobile overlay now uses `align-items: safe center` and `overflow-y: auto`, so an overflowing modal keeps its top on-screen and scrolls as needed; desktop and wider layouts are unchanged. Thanks @jpalazz2. (#6301) + - **Concurrent chats under different profiles can no longer cross the profile boundary mid-turn.** In a single WebUI process, two chats streaming at once could resolve different Hermes profiles, but agent construction and later prompt/config/skill reads still depended on process-global `HERMES_HOME` and globally-patched skill-module paths after the env lock was released — so a second profile's turn could overwrite those globals mid-first-turn and bleed one profile's `SOUL.md`/skills/config into another's chat. The resolved profile home is now bound through the agent's per-thread context-local override for the entire streaming turn (and detached worker scope) and reset in the run's terminal `finally`, so concurrent profiles stay isolated even if the process globals are clobbered mid-run. Checkpoint saves skip the skill lock (no deadlock) and the capability check rejects globally-patched module state (no leak), with a serialized snapshot/patch/restore fallback that keeps older agents safe. Thanks @starship-s. (#5877, #5567, #2023) - **The consolidated Kanban board now fills the panel's vertical space.** In consolidated view (a single board, not split into per-profile lanes), the columns were previously clamped to a short fixed height, leaving a large empty gap below the board. The consolidated board now grows to the full panel height and scrolls as one tall surface; the per-profile lane view keeps its existing height clamp and contained scrolling. CSS-only. Thanks @jpalazz2. (#6308) diff --git a/static/style.css b/static/style.css index be923c43..86829dbd 100644 --- a/static/style.css +++ b/static/style.css @@ -7023,8 +7023,9 @@ main.main.showing-insights > #mainInsights{display:flex;overflow-y:auto;} min-width:min(280px, calc(100vw - 24px)); max-width:calc(100vw - 24px); } - /* Modal scales to viewport width on phones with reasonable padding. */ - .kanban-modal-overlay{padding:12px;} + /* Modal scales to viewport width on phones with reasonable padding. + Ensure it's on screen and scrollable */ + .kanban-modal-overlay{align-items:safe center;overflow-y:auto;padding:12px;} .kanban-modal{padding:16px 16px 14px;border-radius:14px;} .kanban-modal-row-inline{flex-direction:column;gap:0;} .kanban-column-body{overscroll-behavior:auto;} diff --git a/tests/test_kanban_ui_static.py b/tests/test_kanban_ui_static.py index bf080210..82036810 100644 --- a/tests/test_kanban_ui_static.py +++ b/tests/test_kanban_ui_static.py @@ -815,6 +815,27 @@ def test_kanban_review_feedback_static_ui_fixes_exist(): assert "kanban-stats-grid" in PANELS +def test_kanban_modal_mobile_responsive_css(): + """On narrow phones (<=640px) a tall kanban modal must stay reachable: the + overlay scrolls (overflow-y:auto) and safe-centers its content + (align-items:safe center) so an overflowing modal is never clipped above + the fold where its top can't be scrolled back into view.""" + # There are several `.kanban-modal-overlay{...}` rules (skin override, base + # desktop, and the mobile <=640px override, which is last in the file). + # Match against COMPACT_STYLE — whitespace-stripped, like the sibling CSS + # tests — and take the last rule to isolate the mobile override, instead of + # depending on brittle @media-block bracket matching. + overlay_rules = re.findall(r"\.kanban-modal-overlay\{([^}]*)\}", COMPACT_STYLE) + assert overlay_rules, "no .kanban-modal-overlay rule found in style.css" + mobile = overlay_rules[-1] + assert "overflow-y:auto" in mobile, f"mobile overlay must be scrollable. Got: {mobile}" + # `align-items:safe center` compacts to `align-items:safecenter`. + assert "align-items:safecenter" in mobile, ( + f"mobile overlay must safe-center its content so an overflowing modal " + f"is never clipped above the fold. Got: {mobile}" + ) + + def test_kanban_task_detail_renderer_executes_with_log_and_formats_feedback(): import json import subprocess