Add toggle in chat input to switch between Enter-to-send (default)
and Ctrl+Enter-to-send modes. Preference persists in localStorage.
Keyboard shortcuts modal reflects the current setting.
When CI fails on main, posts failure details to OpenClaw webhook
which spawns an isolated agent to diagnose and fix the issue.
Webhook URL and token stored as GitHub secrets (no hardcoded URLs).
When scrolled up and new messages arrive, the scroll-to-bottom button
now shows a count badge (e.g. '3', '99+') instead of just bouncing.
This gives users a clear sense of how many messages they missed.
Clickable example prompts appear when a session has no messages,
giving users quick-start ideas. 2x2 grid on desktop, stacked on mobile.
Fully i18n'd (EN/FR).
Fix: reconcile deleted-sessions blacklist against gateway on each refresh. Permanent sessions like agent:main:main auto-recover from accidental deletion. Closes#3
- Remove font-style:italic from .ht-italic (different glyph widths cause desync)
- Remove font-weight:600 from .ht-heading (bolder glyphs are wider)
- Remove background/border-radius from code token spans
- Remove text-decoration from .ht-link
- Token spans now ONLY use color — zero text geometry changes
- Use inherit for font-size/line-height in shared .ht-backdrop/.ht-textarea
- Add update check hook: polls GitHub releases, shows indicator in sidebar
- #63: 'New messages' label only shows when actual new messages arrive while scrolled up; plain arrow button shown otherwise
- #64: Fix cursor desync in HighlightedTextarea by matching backdrop border width to textarea
- #65: Move floating buttons inside scroll container with sticky positioning to prevent overlap with growing textarea
- #66: Graceful fallback to Bot icon when agent avatar image fails to load
- Show line numbers for code blocks with more than 3 lines
- Toggle button (# icon + line count) in the language header bar
- Preference persisted in localStorage
- Line numbers are non-selectable (won't copy with code)
- Hidden for short snippets to reduce visual noise
Consecutive messages from the same role within 2 minutes are visually
grouped: subsequent messages hide the avatar (keeping alignment) and
use tighter vertical spacing. Date separators and role changes break
groups. This matches modern chat UX patterns (Discord, Telegram).
Track how long each assistant response took to generate and display
it subtly next to the timestamp (e.g. '· 12.3s'). The timing is
measured from the first streaming delta to the final state, and
preserved across the history reload that follows stream completion.
Only visible for messages generated during the current session.
- Set document.documentElement.lang on initial load and locale change
- Ensures screen readers and browser features respect the active language
- Removes duplicate aria-label on MessageSearch input
Adds a consistent focus ring (accent-dim color, 2px) on all focusable
elements when navigated via keyboard (:focus-visible). Mouse/touch clicks
no longer show the default browser outline (:focus:not(:focus-visible)).
Elements with existing Tailwind focus:ring-* classes are unaffected since
they already handle their own focus styling.
- Replace raw text timestamps with <time> HTML elements
- Add dateTime attribute (ISO 8601) for accessibility and machine readability
- Add title attribute showing full date+time on hover (weekday, date, time with seconds)
- Localized tooltip using the user's language preference
- Helps users see exact timestamps for older messages shown as abbreviated times
Move react-markdown, remark-gfm, remark-breaks, and rehype-highlight
imports from eager to dynamic via a LazyMarkdown wrapper component.
The ~336KB markdown bundle is now loaded on-demand after initial paint
instead of blocking the critical rendering path.
- Create LazyMarkdown component with Suspense fallback
- Pre-load plugins in parallel on module init
- Replace all ReactMarkdown usage in ChatMessage with LazyMarkdown
- Hide sidebar, header, chat input, and scroll button when printing
- Reset backgrounds to white, text to black for readability
- Code blocks get light background with borders
- Tool calls styled for print (compact, bordered)
- External links show their URL in parentheses
- Chat scroll area becomes fully visible (no overflow)
- Messages avoid page-break-inside for clean pagination
- Remove shadows and backdrop filters in print
- Replace div with <main> for primary chat pane (screen reader landmark)
- Replace div with <section> for split pane
- Add skip-to-content link for keyboard navigation (Tab → jump to chat input)
- Add aria-expanded and aria-label to tool call badge buttons
- Add id='chat-input' to textarea for skip link target
- Add i18n keys for new ARIA labels (EN + FR)