diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index bc99374..b75d406 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -63,7 +63,7 @@ actions. The topbar remains focused on conversation context and the workspace/fi panels.js Cron, skills, memory, workspace, profiles, todo, settings (~974 lines) commands.js Slash command registry, parser, autocomplete dropdown (~156 lines) onboarding.js First-run wizard overlay, provider setup flow, and settings/workspace orchestration. - boot.js Event wiring, mobile nav, voice input, boot IIFE (~338 lines) + boot.js Event wiring, mobile sidebar/workspace nav, voice input, boot IIFE (~338 lines) tests/ conftest.py Isolated test server (port 8788, separate HERMES_HOME) (~240 lines) test_sprint{1-20b}.py Feature tests per sprint (21 files, 415 test functions) diff --git a/README.md b/README.md index c70e424..5da980c 100644 --- a/README.md +++ b/README.md @@ -277,8 +277,8 @@ WireGuard. Install it on your server and your phone, and they join the same private network -- no port forwarding, no SSH tunnels, no public exposure. The Hermes Web UI is fully responsive with a mobile-optimized layout -(hamburger sidebar, bottom navigation bar, touch-friendly controls), so it -works well as a daily-driver agent interface from your phone. +(hamburger sidebar, sidebar top tabs in the drawer, touch-friendly controls), +so it works well as a daily-driver agent interface from your phone. **Setup:** @@ -451,10 +451,10 @@ across 53 test files. ### Mobile responsive - Hamburger sidebar -- slide-in overlay on mobile (<640px) -- Bottom navigation bar -- 5-tab iOS-style fixed bar +- Sidebar top tabs stay available on mobile; no fixed bottom nav stealing chat height - Files slide-over panel from right edge - Touch targets minimum 44px on all interactive elements -- Composer positioned above bottom nav +- Full-height chat/composer on phones without bottom-nav spacing - Desktop layout completely unchanged --- @@ -542,7 +542,7 @@ A run of focused quality-of-life improvements: terminal tool approval prompts th Added the 7th built-in theme: pure black backgrounds with warm accents tuned to reduce burn-in risk. Small diff, big impact for anyone on an OLED display. **[@Bobby9228](https://github.com/Bobby9228)** — Mobile Profiles button + Android Chrome fixes (PRs #253, #263, #265) -Added the Profiles tab to the mobile bottom navigation bar, making profile switching reachable on phones, plus a set of Android Chrome-specific fixes for the profile dropdown. +Added the Profiles entry to the mobile navigation flow, making profile switching reachable on phones, plus a set of Android Chrome-specific fixes for the profile dropdown. **[@franksong2702](https://github.com/franksong2702)** — Session title guard + breadcrumb nav (PRs #301, #302) Two clean bug fixes / features: the session title guard that stops `title_from()` from overwriting user-renamed sessions after every turn, and clickable breadcrumb navigation in the workspace file preview panel. diff --git a/ROADMAP.md b/ROADMAP.md index 14db757..7dbedee 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -39,7 +39,7 @@ | Sprint 18 | Thinking display + workspace tree | File preview auto-close, thinking/reasoning cards, expandable directory tree (#22) | 318 | | Sprint 19 | Auth + security hardening | Password auth (off by default), login page, security headers, 20MB body limit (#23) | 328 | | Sprint 20 | Voice input + send button | Voice input (Web Speech API), send button icon-circle with pop-in animation | 415 | -| Sprint 21 | Mobile responsive + Docker | Hamburger sidebar, bottom nav, files slide-over, Docker support (#21, #7) | 415 | +| Sprint 21 | Mobile responsive + Docker | Hamburger sidebar, mobile nav, files slide-over, Docker support (#21, #7) | 415 | | Sprint 22 | Multi-profile support | Profile picker, management panel, seamless switching, per-session tracking (#28) | 415 | | Sprint 23 | Agentic transparency | Token/cost display, subagent cards, skill picker in cron, skill linked files, workspace tree persistence, timestamp fixes | 424 | | v0.44.0 patch | Fix batch: approval card, login CSP, update diagnostics, Lucide icons | PRs #221 #225 #226 #227 #228 | 579 | @@ -50,7 +50,7 @@ | v0.48.0 | Gateway session sync | Real-time Telegram/Discord/Slack sessions in sidebar via SSE + DB polling (#274 @bergeouss); +10 tests | 658 | | v0.48.1 | Table inline formatting | `inlineMd()` in table cells — **bold**, *italic*, `code`, links render correctly (PR #278); 0 new tests | 658 | | v0.48.2 | Provider mismatch warning | Toast warning + auth_mismatch error type for provider/model mismatches (#283, fixes #266); +21 tests | 679 | -| v0.49.1 | Docker docs + mobile Profiles button | Two-container Docker compose (#291/#288); Profiles button in mobile bottom nav with mobileSwitchPanel, data-panel, correct SVG size and position (#297/#265 @gabogabucho); +3 tests | 700 | +| v0.49.1 | Docker docs + mobile Profiles button | Two-container Docker compose (#291/#288); Profiles added to the mobile navigation flow with correct panel wiring and SVG sizing (#297/#265 @gabogabucho); +3 tests | 700 | | v0.49.0 | First-run onboarding wizard + self-update hardening | One-shot bootstrap + guided setup wizard; provider config persisted to config.yaml + .env; OpenRouter/Anthropic/OpenAI/Custom; wizard hidden after completion (#285); self-update stderr/split-ref/conflict fixes (#287); skip flaky redaction test (#289); +18 tests | 697 | | v0.32 | Auto-compaction handling | Compression detection, /compact command, real context window indicator | 424 | | v0.33 | /insights sync | Opt-in state.db sync so `hermes /insights` includes WebUI sessions | 424 | @@ -223,7 +223,7 @@ - [x] Voice input via Web Speech API (Sprint 20) ### Mobile -- [x] Mobile responsive layout — hamburger sidebar, bottom nav, files slide-over (Sprint 21) +- [x] Mobile responsive layout — hamburger sidebar, sidebar tabs on phones, files slide-over (Sprint 21 + later mobile nav simplification) ### Profiles - [x] Multi-profile support — create, switch, delete profiles (Sprint 22, Issue #28) diff --git a/TESTING.md b/TESTING.md index fb81998..71e788e 100644 --- a/TESTING.md +++ b/TESTING.md @@ -1715,12 +1715,13 @@ Each has automated API-level tests in `tests/test_sprint{N}.py`. - Open on mobile viewport (<640px): hamburger icon visible in topbar. - Tap hamburger → sidebar slides in from left with backdrop overlay. - Tap outside sidebar → closes. Tap a session → closes and loads session. -- Bottom navigation bar: 5 tabs (Chat, Tasks, Skills, Memory, Spaces). -- Tap "Tasks" in bottom nav → sidebar opens showing Tasks panel. -- Tap "Chat" in bottom nav → sidebar closes (chat is in main area). +- Sidebar top nav remains visible inside the mobile drawer; includes Chat/Tasks/Skills/Memory/Spaces/Profile tabs. +- Tap "Tasks" in the drawer nav → Tasks panel opens in the sidebar drawer. +- Tap "Chat" in the drawer nav → sidebar closes and chat is unobstructed in the main area. - Files button in topbar → right panel slides in from right. +- No fixed mobile bottom nav; chat transcript and composer use the reclaimed vertical space. - All touch targets are at least 44px (session items, buttons, icons). -- Desktop viewport (>640px): no hamburger, no bottom nav, no mobile elements. +- Desktop viewport (>640px): no hamburger or mobile overlay; desktop layout unchanged. - Docker: `docker compose up -d` starts server on port 8787. - Docker: session data persists across container restarts (named volume). diff --git a/static/boot.js b/static/boot.js index 42881fe..2f6234c 100644 --- a/static/boot.js +++ b/static/boot.js @@ -155,11 +155,7 @@ function toggleWorkspacePanel(force){ openWorkspacePanel(nextMode); } function mobileSwitchPanel(name){ - // Switch the panel content view switchPanel(name); - // For non-chat panels (tasks, skills, memory, spaces), open the sidebar - // so the panel is visible. For 'chat', the content is in the main area — - // just close the sidebar so the chat view is unobstructed. if(name==='chat'){ closeMobileSidebar(); } else { @@ -170,10 +166,6 @@ function mobileSwitchPanel(name){ if(overlay)overlay.classList.add('visible'); } } - // Update bottom nav active state - document.querySelectorAll('.mobile-nav-btn').forEach(btn=>{ - btn.classList.toggle('active',btn.dataset.panel===name); - }); } $('btnSend').onclick=()=>{ diff --git a/static/index.html b/static/index.html index 1f79a94..9459e82 100644 --- a/static/index.html +++ b/static/index.html @@ -553,32 +553,6 @@
-