The streaming tail only overlaid the actively streaming message with live
parts from the sync store. When a turn moved to its next step message, the
previous message fell back to its lagging base record, briefly dropping its
completed tool parts — remounting them and replaying their reveal
animation once the record caught up.
Overlay live parts for every message of the streaming tail via a new
useSessionPartsForMessages hook, guarded so an empty live array never
erases parts the record does have. Also key generate-effect glyphs by
index so appended text does not replay earlier characters, and keep tool
row reveal wrappers mounted unconditionally.
Sending a message now parks that message near the top of the viewport
and streams the reply into reserved end space below it, instead of
jumping to the bottom and chasing it.
- swap @tanstack/react-virtual for @legendapp/list in the chat timeline; the
streaming tail becomes a normal list row rather than a separately rendered
block, so one component owns the scroll position
- add timelineScrollAnchoring: pure anchored-turn geometry plus the three
scroll modes (following-end / anchoring-new-turn / free-scrolling)
- replace useChatAutoFollow with useChatTimelineScroll, which opts out of
automatic movement on real gestures via a generation counter instead of the
timer windows the old implementation needed to recognise its own writes
- move the load-older button, question/permission cards, recap, status row and
bottom spacer into the list header/footer, since the list owns its container
- extract useScrollShadow so the shadows can attach to that container
maintainScrollAtEnd and maintainVisibleContentPosition replace the manual
prepend anchor-hold and the mobile quiet-window prepend deferral.
Validated: workspace type-check, lint, web build, ui tests per file.
Scroll behaviour itself is unverified and needs manual testing on web, desktop
and iOS.
Navigation model rebuilt around two full-width drawers and a minimal
header (sessions / title-switcher / usage ring / workspace):
- Left sessions drawer: cross-project tree with live status indicators,
swipe actions on sessions (rename/archive/delete) and on group headers
(project edit / two-step close, worktree delete), reorder-only edit
mode with collapsible project cards and draggable worktrees, app-level
footer (connected instance, settings, pending web update).
- Right workspace drawer: Changes / Files / Terminal / Notes / MCP as
pill tabs (inactive tabs icon-only); panes stay mounted once visited.
The full desktop file editor serves the Files tab; read/skill tool taps
in chat open the file there at the requested line.
- Header session switcher on title tap: 10 cross-project recents with
live busy/attention indicators and project · branch metadata; the
usage ring opens a metadata overlay with an explicit loading state.
- The overflow menu is gone on phones (its destinations moved into the
drawers); iPad keeps it until its dedicated layout pass.
Correctness and continuity:
- /auth/session answers bearer-first, so a stale WebView cookie can no
longer mask a revoked device token; cold launches classify failures
fast and land on an explicit connect screen.
- Authoritative session snapshots raise frozen ordering baselines and
stale live ranks — recents stay truthful after the app slept.
- Cold launches reopen the last active session per instance (persisted
pointer, confirmed against a sessions snapshot; a user-opened draft
clears it), with a logo hold instead of a draft flash.
Also: collapsed pill composer gains the stop control; chat tool rows
share one 36px rhythm; Task subtool rows truncate; larger bottom safe
area so the composer clears big-screen corner radii; Capacitor build
hides About/Update (store updates apply there); widgets link to the
sessions drawer with a list icon; MobileApp split into focused modules;
five mobile-surface detectors unified; translucent borders normalized to
70%; all new strings translated across the 10 locales.
iPad and foldable layouts are intentionally untouched - separate next version PR.
Improve OpenChamber responsiveness under large session workloads while fixing
cache, synchronization, and persistence correctness across runtimes, projects,
directories, and worktrees.
- prioritize selected and visible sessions during bootstrap and defer
non-critical enrichment work
- reduce redundant message loading, event processing, store publication, and
hidden sidebar work
- prevent stale session and message requests from overwriting newer
authoritative state
- preserve existing data when authoritative fetches fail instead of treating
failures as successful empty responses
- scope session materialization, messages, drafts, queues, todos, pins,
permissions, folders, tabs, Git state, and pull request data by runtime and
directory identity
- harden runtime switching, reconnect, cleanup, mutation reconciliation, and
persisted-state ordering
- preserve live subagent Task linkage when metadata arrives after an older
message request or while streaming parts are suspended
- coalesce overlapping tail refreshes without losing newer refresh demand
- improve cold-session loading by moving deferrable work out of the critical
bootstrap path
- isolate URL authentication, mobile credentials, native secrets, and other
runtime-owned state across endpoint changes
- bound long-lived caches and remove avoidable allocations from event and
rendering hot paths
- limit virtualization to archive collections where it improves rendering
without disrupting active sidebar layout
- stabilize session folders, pin ordering, expanded state, and persisted
sidebar behavior
- open skill files through the same secure editor and outside-workspace grant
flow used by file navigation, including worktree sessions
- expand regression coverage for stale completions, runtime collisions,
reconnect behavior, persistence races, authoritative empty results, and
subagent refresh ordering
- document the updated synchronization, cache ownership, performance, and
runtime-isolation invariants
The Prism syntaxTheme prop is no longer read after code highlighting moved to
the Shiki worker. Remove the now-dead prop threading and its source.
- Drop syntaxTheme from interfaces, destructures, prop passes, and React.memo
comparators across ChatMessage, MessageBody, ProgressiveGroup, ToolPart,
TurnActivity, ToolOutputDialog, and ChatInput.
- Drop the unused _syntaxTheme param from renderWebSearchOutput.
- Remove the dead generateSyntaxTheme usages (ChatMessage memo, PlanView
unassigned memo) and delete the now-unimported syntaxThemeGenerator module.
- Bump mobile line-height on tool/reasoning rows from leading-4 to leading-5
so descenders (g, y, p) are no longer clipped by truncate overflow
- Show the tool icon (not the chevron) for collapsed expandable tools on
mobile, matching reasoning rows; chevron now appears only when expanded
Adds animated reveals for file path tool descriptions
Keeps sorted mode tool animations working without extra chat gaps
Preserves file icons, truncation, and click behavior
Replace @remixicon/react with a shared Icon component that renders
via <use href> references to a single hidden SVG sprite. This reduces
DOM node count by replacing inline SVGs with lightweight references.
- Create Icon component with sprite injection (packages/ui/src/components/icon/)
- Migrate all 164 files from @remixicon/react to Icon component
- Auto-generate sprite data from remixicon bundle (scripts/generate-icon-sprite.mjs)
- Add bun run icons:generate to package.json
- Move @remixicon/react to devDependencies
- Add icon usage instructions to theme-system skill
The previous system layered three hooks (useScrollEngine, useChatScrollManager,
useChatTimelineController) with overlapping responsibilities, four parallel
ResizeObservers/MutationObservers, and six entry points to "scroll to bottom"
(force-flag combinations, persistent follow loops, materialization recovery).
This produced bugs where users could not break free of auto-follow during
streaming: scrollbar drag, keyboard scrolling and find-in-page were not
detected as user intent, and observers kept restarting the follow loop on
every DOM mutation.
The new architecture replaces the two low-level hooks with a single
useChatAutoFollow that owns scroll behaviour end to end:
- One state: 'following' or 'released'. No follow modes, no pin flags,
no marker pixels.
- One scroll writer: a lerp loop that runs only while the session is
streaming and state is 'following'. Idle sessions never write scrollTop
programmatically.
- One user-intent detector: wheel up, touch drag down, keyboard
(PageUp / Home / ArrowUp), pointerdown on the OverlayScrollbar thumb,
and explicit releaseAutoFollow() calls all flip the state to 'released'.
- A 1.2s grace period after explicit release: re-pin will not auto-engage
inside this window, so a small wheel up cannot snap the user back even
while they remain near the bottom spacer.
- Re-pin and the scroll-to-bottom button share the same threshold: the
height of the empty bottom spacer (10vh on desktop, 40px on mobile).
Released users see the button only after they have scrolled past the
spacer that already exists at the end of the chat.
- Save/restore of scroll position uses ratio mapping, debounced at 150ms
on user-driven scroll events; programmatic writes are masked via a short
window so they never persist as user positions.
- Container reattachment is detected via a useLayoutEffect probe over
scrollRef.current. Listeners and observers re-bind when ChatViewport
mounts after hydration or after the first message promotes a draft
session into a real chat.
- A pending-restore queue replays restoreSnapshot once the scroll
container appears, fixing the case where a hydrating session landed at
the top instead of the bottom.
Removed: useScrollEngine.ts, useChatScrollManager.ts, the persistent
follow loop with its own ResizeObserver+MutationObserver pair, the
materialization-recovery .finally resume that yanked idle users to the
bottom on transient sync gaps, and the openchamber:session-reselected
event (re-select still works through the existing onSessionSelected
callback). The openchamber:chat-force-scroll-bottom event remains for
synthetic-message paths like git-message generation.
Net change: ~1300 lines removed, two hooks replaced with one, one
observer pair instead of four.
* fix: exclude file content from reverted prompt text
Revert and fork now restore only the user's original prompt, not server-injected file content
Uses existing isSyntheticPart helper for type-safe filtering
* fix: keep scrollbar visible when hovering over thumb
* fix: prevent ESC abort from triggering when terminal is focused
* fix: pass directory to permission/question reply calls so approvals actually resolve
* fix: default model selection not responding after Base UI migration
* fix: prevent modal content from shifting and clipping footer buttons
* fix: improve session switching performance and add sub-agent export with prompt collapse
Defer viewport anchor saving to eliminate ~800ms UI freeze when switching sessions
Add export dialog to include sub-agent tasks recursively in markdown export
Add collapse chevron button for expanded user prompts in sticky header
* fix: resolve sidebar scroll and TDZ crash in session sidebar
* perf: reduce CPU overhead and re-renders across chat, layout, and settings
* fix: position collapse button at top of message and prevent ESC abort in terminal
* fix: position collapse button at top and add padding only when expanded
* refactor: extract shared PATH utilities and mobile keyboard hook
* refactor: import shared path-utils in electron, use module-level style constants
- Electron now imports pathLooksUserConfigured/mergePathValues from
shared path-utils.js instead of inline duplication
- ToolPart collapsedCustomStyle moved from useMemo([]) to module const
* fix: resolve remaining merge conflicts and type errors
- Remove duplicate variable declarations in SessionNodeItem
- Remove orphaned export callback body from conflict resolution
- Fix HelpDialog description -> descriptionKey (i18n rename)
* fix: resolve type-check and lint errors in session-actions.test.ts
- Added missing bun:test type declarations (beforeEach, mock, mock.module)
- Removed unused State import
- Replaced 'as any' casts with proper OpencodeClient and ChildStoreManager types
- Added eslint-disable for unused _ parameter in mock function
* fix PR 1028 export and PATH edge cases
* fix startup retry exhaustion state
* remove opencode package lock change
* fix sub-session rename cancellation
---------
Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
- Keep older assistant messages in the active turn stable while new content streams
- Prevent existing tool rows from rerendering when new tool activity is appended
- Tighten message and tool memo comparisons to isolate render work to changed rows
* fix: preserve unsent prompt when adding editor context in VS Code
* fix: append Add to chat selections as markdown blocks with stable spacing
Convert selected assistant content to markdown before appending
Wrap each Add to chat selection in an `md` fenced block
Preserve multiline composer formatting across repeated appends
* fix: normalize persisted Windows paths to prevent identity mismatches
* fix: hide Windows subprocess console popups across server tasks
Hide OpenCode startup and shell command child windows in the web server
Apply windowsHide to cloudflared and skills-catalog git subprocesses
Cover remaining git service exec paths that could surface console windows
* fix: restore chat auto re-pin when reaching bottom
Re-pin now triggers when scrolling back into the bottom zone, not only via the button.
Upward user scroll intent still unpins immediately and is not overridden by re-pin.
Unified bottom/re-pin threshold logic to reduce sensitivity mismatches.
* fix: restore chat scroll release on mobile during streaming
Restores pinned-scroll release on touch scroll up so mobile users can leave auto-follow while streaming.
Improves re-pin behavior near bottom to avoid sticky or inconsistent pin states.
Includes related chat UI and dependency updates in the same change set.
* fix: hide daemon startup probe consoles on Windows
* fix: prevent pinned scroll tug-of-war during streaming
* fix: prefer git.exe to avoid Windows diff popup flashes
* fix: prefer git.exe discovery in Windows git flows
* fix: avoid where probes in Windows git resolution
* fix: avoid update-check subprocess flashes on Windows
* fix: normalize read file path labels
* feat: add OpenChamber defaults and improve theme ports
Add new OpenChamber light and dark themes
Regenerate imported themes with stronger surface mapping
Set OpenChamber themes as the default top options
* fix: stabilize chat pin and unpin behavior during streaming
Restores reliable unpin on upward wheel and touch gestures while auto-follow is active.
Prevents immediate re-pin while the user is actively scrolling upward near the bottom.
Keeps smooth follow-to-bottom behavior while reducing scroll tug-of-war.
* fix: suppress Windows command popups in VSCode runtime processes
Hide spawned git and server process windows in VS Code runtime
Extend hidden-window handling to server port cleanup and reveal commands
Keep behavior unchanged on non-Windows platforms
* fix: polish activity tool rows and message spacing
Show each tool call as its own row in live and activity views
Keep tool descriptions inline with truncation and cleaner read-file paths
Tune spacing, todo counts, and bash timing display for clearer chat flow
* fix: refine activity tool rows and truncation behavior
Make activity collapse behavior consistent across modes and rename default mode label to Expanded
Show tool descriptions inline with improved spacing and one-row-per-tool rendering
Fix read/edit path truncation to clip from the start while keeping edit filenames highlighted
* fix: resolve chat activity lint regressions
Remove unused activity render mode state in message body
Mark path helper animation arg as intentionally unused to satisfy lint
* refactor: add canonical turn projection pipeline for chat
Centralizes turn/activity/summary derivation, migrates render consumers to shared projection sources, and adds projector regression coverage for retries, malformed parent fallbacks, and activity segmentation.
* refactor: stream assistant text live in turn-first render path
* refactor: complete phase-3 turn timeline history/navigation
* refactor: complete phase-4 turn pipeline cutover
Remove legacy grouping adapters and lock key edge cases with executable regression tests so turn-centric rendering stays stable across retry/history/navigation flows.
* fix: align chat history loading path with opencode parity
* fix: stabilize chat streaming and reduce render churn
* feat: add blurIn streaming text animation and smooth lerp-based auto-scroll
Streaming markdown now uses Streamdown blurIn animation (150ms, ease-out) for per-word reveal
Auto-scroll during streaming uses continuous exponential smoothing (lerp) instead of restarting spring animations
One-shot scroll-to-bottom (button click) uses motion spring for natural deceleration
* fix: respect user scroll-up during streaming and re-pin on scroll back to bottom
* fix: stabilize activity stream and tool progress rendering
Activity now stays chronologically consistent and avoids duplicate reasoning/justification.
Tool rows show running state and duration earlier with smoother pending behavior.
Removed legacy trim/timestamp paths to prevent message drops and simplify Activity UI.
* fix: reverted regression of revert functionality
* fix: stabilize chat activity layout and tool progress behavior
Stopped user messages from re-animating when new user messages appear.
Made Activity and aggregated tool rows wrap inline consistently without misaligned headers/icons.
Fixed tool part matching so duration and shine no longer reset across pending/in-progress status updates.
* fix: restore activity mode behavior and stabilize tool rendering
Re-enabled Collapsed/Summary/Detailed/Changes defaults for Activity and tool expansion.
Fixed tool row wrapping/alignment, removed user fade re-animations, and disabled FadeInOnReveal animations.
Improved tool status handling to reduce timer/shine resets and made reasoning bold render as normal text.
* refactor: simplify chat tool and message rendering
Replace activity-group rendering with flat inline part rendering
Remove obsolete tool output and justification activity settings
Keep user message animation and improve edit/apply-patch file path headers
* style: narrow chat and composer columns equally
* fix: Tool status checks and abort flow regression
* fix: improve multi-file apply patch header rendering
* fix: make timeline message jump scroll to selected chat entry
Conversation Timeline clicks now reliably scroll to the selected message in chat
Timeline dialog waits for navigation result before closing to avoid silent failures
Chat message scrolling now resolves the active chat scroller consistently
* chore: remove branch-added chat tests and clean lint leftovers
Removes newly added chat and message test files from this branch
Fixes lint blockers in ProgressiveGroup, ToolPart, and messageStore
Keeps type-check, lint, and build passing after cleanup
* fix: keep composer status row closest to the input
Status/todo row now renders below queued messages and attachments.
Linked GitHub issue/PR chips stay above status so input context order is consistent.
Improves chat composer readability while assistant is working.
* fix: disable assistant header animations and polish chat status behavior
Assistant message header now renders without transition effects
Removed a lint issue from the working placeholder props
Chat status and message flow updates improve consistency during active turns
* feat: increase bottom spacer in mobile chat for better scrolling
* feat: add sorted chat mode with progressive activity rendering
Adds global chat render mode settings for sorted and live behavior
Renders non-stop assistant output in Activity as messages complete
Disables streaming text animation in sorted mode and restores classic reasoning/justification blocks
* fix: stabilize chat timeline navigation and older history loading
Prevents auto-loading older history from scroll and keeps loading behind the button
Fixes timeline jump-to-message behavior that snapped back to the bottom
Reduces chat list flicker and empty-state glitches on large session pagination
* fix: stabilize sorted activity text and hide reasoning timers
Prevented sorted justification from appearing before message completion by requiring explicit non-stop finish.
Removed duration values for sorted Thinking and Justification blocks.
Kept smooth sorted auto-follow behavior tuned to reduce bottom-jump jitter.
* refactor: simplify chat tool rendering paths and add parts docs
Centralized tool icon mapping into a shared presentation helper used by grouped and expandable rows.
Removed static-tool-specific branches from ToolPart to keep it focused on expandable tools.
Added a new DOCUMENTATION.md explaining where to change tool descriptions and rendering behavior.
* feat: enhance event stream handling for message parts
- Refactor event key building functions to improve clarity and reduce redundancy.
- Introduce `applyPartDelta` method in message store for handling delta updates to message parts.
- Update `useEventStream` to utilize the new `applyPartDelta` method for processing incoming deltas.
- Enhance text extraction logic to accommodate new part types and improve merging behavior.
- Implement logic to skip delta-driven updates for ongoing text/reasoning parts to prevent overwriting.
- Adjust server-side text merging logic to handle trimmed text comparisons and improve consistency.
* feat: enhance OpencodeService with delta handling and stale delta management
- Introduced globalSseStaleDeltas to track stale deltas.
- Added methods to generate keys for delta and updated part events.
- Updated global SSE loop to skip processing stale deltas.
- Refactored global SSE event handling to improve performance and reliability.
refactor: remove unused streaming part handling in messageStore
- Eliminated streaming part queue and associated logic.
- Simplified message merging logic by removing redundant checks.
- Streamlined message handling to improve clarity and maintainability.
chore: clean up unused streaming text normalization functions
- Removed deprecated functions related to streaming text identity and merging.
- Simplified normalizeStreamingTextPayload to focus on current functionality.
* refactor: simplify streaming event passthrough
Use SDK-native global event streaming in the UI client
Remove dead server-side SSE normalization helpers
Keep streaming payloads closer to upstream behavior
* revert: remove message memory settings UI
Drop the restored message memory settings screen
Keep session settings focused on current defaults
Preserve chat history limits as internal behavior
* feat: add compact collapsed Activity preview in sorted mode
Collapsed Activity now shows a live preview of the latest 7 entries
Older activity rows roll up behind a +N more indicator
The +N more indicator is clickable to expand the full Activity
* fix: adjusted activity changed files text prominence
* fix: make sorted mode snap to bottom when not streaming
* perf: show chat scrollbar only on user-driven scrolling
Chat scrollbar now stays hidden during automatic follow-to-bottom
Scrollbar visibility is gated by real user scroll intent
Reduced scroll overhead by removing timer-based intent tracking
* refactor: align web and vscode session activity streaming
Route VS Code SSE through SDK-based proxy flow
Restore controlled web session activity tracking and cooldowns
Keep chat activity behavior consistent across runtimes
* fix: adjusted muted foreground themes color
* fix: stabilize session activity and attention updates
Keep streamed chat state in sync as sessions complete
Restore reliable attention indicators for inactive sessions
Tighten server and UI event handling for chat updates
* feat: add chat render previews and file icon visibility setting
Added animated chat render mode previews in Chat settings.
Added a new toggle to show or hide file icons across tool rows.
Persisted chat render, activity, and mermaid modes to shared settings file.
* fix: update default GitHub OAuth client ID
Use the new OpenChamber org GitHub OAuth app ID by default.
Keep web server and VS Code auth defaults in sync.
* fix: sync chat settings across VS Code chat views
Broadcast settings changes to both sidebar and editor chat webviews.
Apply synced settings in each webview via shared settings refresh.
Ensures chat render mode updates appear immediately in editor tabs.
* fix: stop writing session folders file in VS Code workspaces
Disable disk persistence for session folders in VS Code webview runtime
Keep session folder state in VS Code/webview storage instead of project files
Preserve existing behavior for non-VS Code runtimes
* style: polish expanded tool panels and bash output readability
Removed extra borders/labels in expanded tool cards for a cleaner UI
Added softer scroll shadows and full-height decorative activity line
Switched bash command/output to code-style typography with tighter spacing
* feat: add default-open tool controls for chat activity
Added Chat settings toggles to open Bash and Edit tools by default
Default-open behavior now applies across both sorted and live activity rendering
Users can still manually collapse default-open tools, plus bash output height was reduced
* fix: align chat loading skeleton with message layout
Match skeleton width and horizontal alignment to chat message column
Add one-line tool-style skeleton rows with subtle circular placeholders
Increase top spacing so loading state no longer touches chat header
* fix: prevent blank screen when adding inline diff comments
Sanitize persisted inline comment drafts to ignore invalid data
Harden diff annotations against malformed line numbers
Fail safely when annotation updates error instead of crashing the view
* fix: streamline VS Code archived sessions sidebar
Show archived sessions in VS Code only for the active workspace directory.
Render archived sessions as a flat list in VS Code without project-root subfolders.
Hide the "Open in Side Panel" session action in VS Code.
* fix(chat): render active tools before completion
* fix(chat): preserve running activity in collapsed view
* fix(chat): live-update duration for active tools
* fix: show live tool activity without timer resets
Show active tool rows before completion
Keep live duration stable during streaming updates
---------
Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
* feat(chat): add mermaid preview popups and fullscreen diagram viewer
Enable opening Mermaid diagrams from markdown and file attachments with a dedicated fullscreen dialog, while tightening preview loading behavior and sizing for more reliable interaction.
* refactor(chat): extract shared preview overlay hooks
Centralize fullscreen preview transition and viewport lifecycle logic so image and Mermaid dialogs stay behaviorally aligned while reducing maintenance overhead.
* fix(security): enforce workspace boundaries for fs read endpoints
Validate /api/fs/read and /api/fs/raw paths against active workspace roots and canonical realpaths to block traversal and symlink escapes before serving file contents.
* fix(chat): remove dead Mermaid copy component
Drop an unused merge-leftover component in MarkdownRenderer to keep lint clean without changing Mermaid preview behavior.
* fix: stale model variants in chat controls in draft session
* fix: attention indicator for project tabs
* fix: use part index and type for consistent IDs
* fix question card navigation for unanswered questions
* feat: added themes system
* feat: smart sidebar auto-hide for files/diff tabs + lower files sidebar threshold
* feat: added Checkbox component and update theming
- Add reusable Checkbox component for toggles across UI
- Replace several inputs with Checkbox in settings and commands panels
- Add DiffIcon and apply surface/border theming to key UI areas
* feat: Add convert-vscode-theme.cjs to convert VS Code themes to OpenChamber format
* refactor: remove unused permission logic from ChatInput
- Remove unused permission rules parsing logic from ChatInput
- Memoize renderTheme in DiffWorkerProvider to avoid unnecessary recalculations
- Remove forceOpaque helper in vscode theme adapter
* fix: guard VSCode theme loading in MarkdownRenderer
* feat: add custom user themes loading and reload
- Load user themes from ~/.config/openchamber/themes at runtime
- Expose /api/config/themes to fetch custom themes
- Allow theme reloading from Settings → Theme → Reload themes in the UI
* feat: add chat virtualization and turn grouping infrastructure
Implement VirtualMessageList with virtualization and overscan for smooth scrolling
Refactor MessageList to render only visible messages and pass scroll refs
Introduce TurnGroupingContext and provider to stabilize per-turn rendering and reduce re-renders
* feat: add web server session activity endpoint for visibility restore
Add /api/session-activity endpoint to expose tracked session activity
Use web server activity first when restoring visibility, with fallback to global status
Update server SSE to set session phase on activity events
* feat(chat): split TurnGroupingContext into UI/Streaming contexts
Add separate UI state and streaming contexts to reduce re-renders.
Skip animations for items visible in collapsed view when expanding.
Track shown parts in collapsed mode to fade in progressively
* feat(ui): cache turn groups with expand state and guard web activity
Add isExpanded to the turn cache key to trigger updates correctly
Expose isGroupExpanded from UI state so groups reflect expand/collapse
Limit web server session activity fetch to web runtime only
- Removed unused activeTurnAnchorId and activeTurnSpacerHeight from MemoryDebugPanel.
- Simplified useChatScrollManager by eliminating unnecessary state and functions related to active turn anchoring.
- Updated loadMessages function signatures to accept an optional limit parameter across message and session stores.
- Enhanced scroll behavior in useScrollEngine to support dynamic bottom tracking during animations.
- Improved event stream handling to allow for resyncing messages with a specified limit.
- Cleaned up session memory state to remove active turn properties, focusing on viewport anchoring.
Update all import statements to use @opencode-ai/sdk/v2
Modify Vite configurations to alias new SDK path
Update API client method signatures for SDK v2 compatibility