What happened
The "New messages" scroll-to-bottom indicator in the chat surface is not dismissed correctly:
- Scrolling back to the bottom does not clear it. After scrolling up and receiving a new assistant message, scrolling all the way back down leaves the "New messages" label visible even though the user is at the bottom.
- It leaks across conversations. With the indicator active in one conversation, a brand-new conversation shows "New messages" from the start, and the first message of the new conversation re-triggers the indicator even after the user previously dismissed it.
Expected: the indicator clears once the user is at the bottom, and switching conversations resets the indicator state entirely.
How to reproduce
- Open a conversation with enough history that the content overflows the viewport.
- Scroll up so the floating scroll-to-bottom button appears.
- Wait for / trigger a new assistant message so the button label becomes "New messages".
- Scroll all the way back to the bottom.
- Observed: "New messages" is still shown at the bottom edge (screenshot 3).
- Without clicking the indicator, start a brand-new conversation.
- Observed: the new conversation shows "New messages" from the start (screenshot 2); the first message of the new conversation re-triggers the indicator (screenshot 1) even though the user is at the bottom.
Environment
- Maka version: 0.1.5 (desktop build,
CFBundleShortVersionString = 0.1.5)
- OS and version: macOS, Apple Silicon (arm64)
- Surface: Desktop
Logs, screenshots, or additional context
Runtime screenshots:
- Full window — transcript scrolled up with the "New messages" indicator floating over the chat.

- Bottom strip — transcript bottom and composer with the "New messages" indicator still present.

- Near-fullscreen — transcript scrolled back to the bottom; "New messages" is still shown at the bottom edge.

Probable root cause (from the bundled renderer, @astryxdesign/core):
useChatNewMessages only clears hasNewMessages via dismiss(); the ResizeObserver sets it whenever the last .astryx-chat-message element changes while isLocked is false.
useChatStreamScroll only re-locks auto-follow on scrollend; it never reports "at bottom" back to the indicator, so isScrolledUp and hasNewMessages are independent and the button stays visible/labeled.
ChatLayout is not remounted per conversation (no key={sessionId}), so hasNewMessages, lastMessageRef (pointing at the previous conversation's last .astryx-chat-message node) and the unlocked isLocked=false survive a conversation switch; the new conversation's first message then re-flags hasNewMessages.
Suggested fixes (any of): reset lastMessageRef/hasNewMessages when the observed content element is replaced (conversation switch); clear the new-message flag when scrollend settles within the lock threshold; or remount ChatLayout per conversation (key={sessionId}).
What happened
The "New messages" scroll-to-bottom indicator in the chat surface is not dismissed correctly:
Expected: the indicator clears once the user is at the bottom, and switching conversations resets the indicator state entirely.
How to reproduce
Environment
CFBundleShortVersionString = 0.1.5)Logs, screenshots, or additional context
Runtime screenshots:
Probable root cause (from the bundled renderer,
@astryxdesign/core):useChatNewMessagesonly clearshasNewMessagesviadismiss(); theResizeObserversets it whenever the last.astryx-chat-messageelement changes whileisLockedis false.useChatStreamScrollonly re-locks auto-follow onscrollend; it never reports "at bottom" back to the indicator, soisScrolledUpandhasNewMessagesare independent and the button stays visible/labeled.ChatLayoutis not remounted per conversation (nokey={sessionId}), sohasNewMessages,lastMessageRef(pointing at the previous conversation's last.astryx-chat-messagenode) and the unlockedisLocked=falsesurvive a conversation switch; the new conversation's first message then re-flagshasNewMessages.Suggested fixes (any of): reset
lastMessageRef/hasNewMessageswhen the observed content element is replaced (conversation switch); clear the new-message flag whenscrollendsettles within the lock threshold; or remountChatLayoutper conversation (key={sessionId}).