newSession() did not reset _messagesTruncated or _oldestIdx, unlike
loadSession() which resets both at line 590. When a user switched from
a long session (messages > _INITIAL_MSG_LIMIT) to a new session, the
stale _messagesTruncated=true caused renderMessages() to show the
'Scroll up or click to load older messages' indicator on a fresh
conversation with only 1 message.
Add the same reset that loadSession() already performs so newSession()
starts with clean pagination state.
Replace the hardcoded 4-option deliver dropdown (local/discord/telegram/slack)
with a dynamic select populated from a new GET /api/crons/delivery-options
endpoint that reads _KNOWN_DELIVERY_PLATFORMS from hermes-agent.
Key changes:
- Add GET /api/crons/delivery-options endpoint returning all known platforms
- Frontend loads options asynchronously on first cron form open, with caching
- Enable deliver editing for existing jobs (was previously disabled)
- Include deliver in update payload when editing cron jobs
- Fallback to local-only if API unavailable
- Custom deliver values (e.g. feishu:oc_xxx) shown with * suffix
- Add cron_deliver_custom i18n key to all 12 locales
- Add 5 integration tests for the new endpoint
- Rename _escHandler to _keyHandler (now handles nav keys too)
- Store counter reference (lb._counterEl) to avoid DOM query on every nav
- Remove dead 'let counter = null' and 'hasNav' closure variable
- Use lb._navImages directly in keyboard handler for consistency
- Add null guard on lb.querySelector('img') in _navigateLightbox
- Inline _updateLightboxCounter one-liner
- Fix CSS section comment 'Image lightbox close' → 'Image lightbox'
- Fix CHANGELOG placeholder (#PR → #2967)
- _navigateLightbox now reads lb._navIndex / lb._navImages directly
instead of receiving a closure-captured index and rebuilding the
keyboard handler on every navigation. No more removeEventListener /
addEventListener churn.
- Button onclick handlers also read the live lb._navIndex.
- Removed dead backward-compat string-type shim and its unused oldEl
querySelector.
- Composer attach-tray chips now open single-image lightboxes (no
sibling detection across staged uploads).
When multiple images appear in the same message, clicking any image
now opens a lightbox with prev/next navigation buttons (‹ / ›) and
keyboard support (← / →). An image counter (e.g. '3 / 5') is shown at
the bottom of the overlay.
- _openImgLightbox now receives the clicked <img> element to find
sibling images within the same message container
- New _openImgLightboxWithNav, _navigateLightbox, _updateLightboxCounter
- CSS: .img-lightbox-nav (prev/next buttons), .img-lightbox-counter
- Close button (×), Escape key, and click-outside-to-close preserved