Skip to content

perf(app): stabilize long session timelines#402

Merged
Astro-Han merged 9 commits into
devfrom
pawwork/long-session-timeline-perf-plan
May 3, 2026
Merged

perf(app): stabilize long session timelines#402
Astro-Han merged 9 commits into
devfrom
pawwork/long-session-timeline-perf-plan

Conversation

@Astro-Han

@Astro-Han Astro-Han commented May 3, 2026

Copy link
Copy Markdown
Owner

Summary

  • Keep long session timelines bounded around the latest turns while preserving reading and hash-target modes.
  • Restore bottom history mode when the user manually returns to the bottom, so later appends stay bounded without requiring the jump-to-latest button.
  • Coalesce contiguous streaming message.part.delta events safely before emitting them to the renderer.
  • Add focused tests for history window behavior and event queue ordering barriers.

Why

Long-running sessions could accumulate too many rendered turns during streaming, making the timeline more likely to flicker, jump, or become expensive to update.

Related Issue

Part of #397. This PR covers the first-stage bounded rendering and safe delta coalescing work; broader follow-ups such as turn normalization, Markdown pacing, and true virtualization should stay in #397 or separate follow-up issues.

Human Review Status

Pending. A human should make the final merge decision after reviewing the final diff, verification evidence, and CI.

Review Focus

  • History window mode transitions: bottom-follow, reading older content, hash target, manual return-to-bottom, and jump-to-latest.
  • Event queue semantics: only contiguous same-key deltas are merged; non-delta events and other part deltas remain ordering barriers.
  • Confirm no generated files or local docs are included.

Risk Notes

Medium: this changes session timeline rendering behavior and global event flush preparation. The changes are intentionally scoped and covered by focused unit tests, but reviewers should pay close attention to scroll restoration and stream ordering.

How To Verify

Focused tests: bun --cwd packages/app test:unit src/context/global-sdk-event-queue.test.ts src/context/global-sync/event-reducer.test.ts → 735 pass, 0 fail
Focused tests: bun --cwd packages/app test:unit src/pages/session/use-session-history-window.test.ts src/pages/session/use-session-hash-scroll.test.ts → 737 pass, 0 fail
Typecheck: bun --cwd packages/app typecheck → tsgo -b completed successfully
Manual long-session check: isolated Electron profile with 2 longest sessions, max 347 messages / 1295 parts → scroll up, jump to latest, and session switching behaved normally
Manual multi-session check: isolated Electron profile with 30 sessions, 5260 messages, 18888 parts → sidebar scrolling and switching behaved normally; diagnostics did not show runaway jank or memory

Screenshots or Recordings

Manual screenshots were captured locally from the isolated Electron run. No permanent artifact is attached because this is a performance/behavior fix rather than a visual design change.

Checklist

  • Human review status is stated above as pending, approved, or not required
  • I linked the related issue, or stated why there is no issue
  • This PR has type, scope, and priority labels, or I requested maintainer labeling
  • I described the review focus and any meaningful risks
  • I listed the relevant verification steps and the key result for each
  • I did not introduce unrelated refactors, dependencies, generated files, or file changes beyond the stated scope
  • I manually checked visible UI or copy changes when needed, with screenshots or recordings
  • I considered macOS and Windows impact for desktop, packaging, updater, signing, paths, shell, or permissions changes
  • I called out docs, release notes, dependencies, permissions, credentials, deletion behavior, generated content, or local file changes when relevant
  • I reviewed the final diff for unrelated changes and suspicious dependency changes
  • I am targeting dev, and my PR title and commit messages use Conventional Commits in English

Maintainer labeling requested: please add type perf, scope app, and priority P2 if appropriate.

Summary by CodeRabbit

  • New Features

    • Session history modes: bottom, reading, and hash; mark and clear hash targets and improved resume-latest behavior.
  • Refactor

    • Centralized background event coalescing to reduce redundant message-part updates and ensure directory-scoped isolation.
    • History/window logic refactored for mode-aware scrolling, stable expansion, and resume behavior.
  • Tests

    • Added comprehensive tests for event coalescing and history-window interactions.

@coderabbitai

coderabbitai Bot commented May 3, 2026

Copy link
Copy Markdown
Contributor

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 7fb3813f-0eb3-4a16-a47a-ea9ff67ba766

📥 Commits

Reviewing files that changed from the base of the PR and between f983ca3 and 89b2755.

📒 Files selected for processing (4)
  • packages/app/src/pages/session/use-session-hash-scroll.test.ts
  • packages/app/src/pages/session/use-session-history-window.test.ts
  • packages/app/src/pages/session/use-session-history-window.ts
  • packages/app/src/pages/session/use-session-timeline-interaction.ts
✅ Files skipped from review due to trivial changes (1)
  • packages/app/src/pages/session/use-session-hash-scroll.test.ts

📝 Walkthrough

Walkthrough

Adds a standalone event coalescer for queued SDK events and integrates it into the global SDK buffer. Separately, session history/windowing gains a mode-aware model ("bottom" | "reading" | "hash"), new control helpers and APIs, updated hash-scroll / timeline wiring, and expanded tests.

Changes

Event Coalescing & SDK Integration

Layer / File(s) Summary
Data Shape & Helpers
packages/app/src/context/global-sdk-event-queue.ts
Adds exported QueuedGlobalEvent = { directory: string; payload: Event } and internal key helpers (deltaKey, partKey, replaceableKey, appendDelta).
Core Coalescing Logic
packages/app/src/context/global-sdk-event-queue.ts
Implements coalesceQueuedEvents(events: QueuedGlobalEvent[]) to override later "replaceable" events, drop stale message.part.delta entries when a message.part.updated appears, and concatenate contiguous compatible message.part.delta fragments.
SDK Integration
packages/app/src/context/global-sdk.tsx
Replaces inline coalescing/staleness tracking with a QueuedGlobalEvent[] buffer; enqueues raw events and calls coalesceQueuedEvents(queue) during flush().
Tests
packages/app/src/context/global-sdk-event-queue.test.ts
Adds tests validating contiguous-delta merging, non-merge across other parts, barrier-event stopping, field-specific non-merge, stale-delta pruning before full update, delta-update-delta ordering, multiple full updates behavior, post-prune ordering, directory-scoped isolation, and composite-key safety for directory strings containing separators.

Mode-Aware History Window & Hash Scroll Wiring

Layer / File(s) Summary
API & Pure Helper
packages/app/src/pages/session/use-session-history-window.ts
Adds exported resolveHistoryTurnStart(...) computing effective turnStart from mode, storedTurnStart, length, userScrolled, and optional initialWindow; SessionHistoryWindowInput gains isAtBottom() and scroller().
State & Core Hook
packages/app/src/pages/session/use-session-history-window.ts
Introduces mode state (default "bottom") and refactors turnStart derivation to call resolveHistoryTurnStart.
Control Surface & Helpers
packages/app/src/pages/session/use-session-history-window.ts
Extends setTurnStart(start, opts?) to accept { mode }; adds expandForReading, expandForHash, markHashTarget, resumeLatestWindow, returnToLatestIfFollowing, clearHashTarget, and mode() accessor on the returned API.
Flows & Effects
packages/app/src/pages/session/use-session-history-window.ts
Rewires backfill, load/reveal, prefetch, and preserve-scroll flows to use mode-aware helpers; switching sessions resets prefetch state and forces mode: "bottom"; userScrolled transitions "bottom""reading" while "hash" prevents auto-return.
Tests / Harness
packages/app/src/pages/session/use-session-history-window.test.ts
Adds harness, generators, condensed assertions, and unit/integration tests for resolveHistoryTurnStart, hash-target activation, resume-to-latest behavior, reading→bottom transitions, load-and-reveal semantics, and hash-target clearing.
Hash Scroll Wiring
packages/app/src/pages/session/use-session-hash-scroll.ts
Hook input now requires markHashTarget(index) and optional onMessageHashCleared; scrollToMessage calls markHashTarget(index) and clearMessageHash invokes input.onMessageHashCleared?.().
Timeline Interaction Wiring
packages/app/src/pages/session/use-session-timeline-interaction.ts
Adds resumeLatest wrapper (calls historyWindow.resumeLatestWindow() then resumeScroll()); wires markHashTarget into useSessionHashScroll and calls historyWindow.clearHashTarget() on message-hash clear.
Hash Scroll Tests
packages/app/src/pages/session/use-session-hash-scroll.test.ts
Adds tests verifying presence of hash-clearing wiring and string patterns for onMessageHashCleared and historyWindow.clearHashTarget().

Sequence Diagram

sequenceDiagram
    participant User
    participant SDK as SDK Stream
    participant Queue as Event Queue
    participant Coalesce as coalesceQueuedEvents
    participant Emitter as Event Emitter
    participant History as HistoryWindow
    participant Timeline as Timeline Render

    User->>SDK: streaming response events
    SDK->>Queue: enqueue `QueuedGlobalEvent` (delta/update/status)
    SDK->>Queue: schedule flush
    Queue->>Coalesce: coalesceQueuedEvents(queue)
    Note over Coalesce: replaceables overridden,\nstale deltas removed, contiguous deltas concatenated
    Coalesce-->>Emitter: emit coalesced events
    Emitter->>History: deliver events
    alt mode == "bottom"
        History->>Timeline: compute bottom window
    else mode == "reading"
        History->>Timeline: expand for reading (preserve view)
    else mode == "hash"
        History->>Timeline: pin hash target
    end
    Timeline->>User: render messages
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

app, P2

Poem

🐰 I stitched the deltas, one then two,
I kept the hash so jumps stay true,
Modes mind the view and hold the line,
Streams tidy up, events align.
Hop, coalesce, resume—all fine!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 20.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'perf(app): stabilize long session timelines' clearly and concisely summarizes the main change—a performance improvement that bounds and stabilizes rendering of long session timelines.
Description check ✅ Passed The pull request description comprehensively covers all required template sections: summary of changes, rationale (why), related issue, human review status, review focus, risk notes, verification steps with actual test results, manual checks, and a completed checklist addressing all major concerns.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch pawwork/long-session-timeline-perf-plan

Review rate limit: 2/10 reviews remaining, refill in 46 minutes and 24 seconds.

Comment @coderabbitai help to get the list of available commands and usage tips.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a centralized event coalescing mechanism for the SDK event queue and refines session history window management by implementing explicit modes (bottom, reading, and hash) to handle message appends and scrolling more effectively. A performance improvement was suggested for the coalesceQueuedEvents function to avoid redundant calls to rebuildReplaceable unless a removal actually occurs, preventing potential performance bottlenecks.

Comment thread packages/app/src/context/global-sdk-event-queue.ts

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
packages/app/src/context/global-sdk-event-queue.test.ts (1)

37-73: ⚡ Quick win

Add a directory-isolation regression test.

Current coverage doesn’t verify that same messageID/partID/field across different directory values are never merged or pruned together. Adding this is low-cost and protects multi-session behavior explicitly.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/app/src/context/global-sdk-event-queue.test.ts` around lines 37 -
73, Add a regression test that asserts directory isolation: within the same
describe block add a test that uses coalesceQueuedEvents with queued events
created via queued(delta(...), updated(...), status(...)) where the
deltas/updates share the same messageID/partID/field but have different
directory values; verify using eventTypes(events) and deltas(events) that events
from different directory values are never merged or pruned together (i.e., they
remain separate entries and stale-to-updated pruning only applies within the
same directory), referencing the existing helpers coalesceQueuedEvents, queued,
delta, updated, status, eventTypes and deltas to locate where to add and what to
assert.
packages/app/src/pages/session/use-session-history-window.test.ts (1)

87-89: 💤 Low value

Test name slightly misaligned with test case.

The test is named "reading mode does not slide the window..." but actually tests mode: "bottom" with userScrolled: true. This tests the pre-transition behavior (bottom mode respecting scroll position) rather than reading mode itself. The test is valid but the name could be clearer.

Consider renaming to clarify it tests the bottom-mode-with-scroll-freeze behavior:

-  test("reading mode does not slide the window when the user scrolls upward inside the rendered range", () => {
+  test("bottom mode freezes window position when user has scrolled", () => {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/app/src/pages/session/use-session-history-window.test.ts` around
lines 87 - 89, Rename the test whose body calls resolveHistoryTurnStart({ mode:
"bottom", storedTurnStart: 15, length: 26, userScrolled: true }) so its
description reflects bottom-mode scroll-freeze behavior instead of "reading
mode" (e.g., change the test name string from "reading mode does not slide the
window when the user scrolls upward inside the rendered range" to something like
"bottom mode preserves storedTurnStart when user has scrolled inside rendered
range"); update only the test description text associated with that assertion to
match the actual scenario using resolveHistoryTurnStart and leave the assertion
logic unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/app/src/context/global-sdk-event-queue.ts`:
- Around line 66-72: The loop that prunes stale deltas on message.part.updated
currently scans the entire result array (in global-sdk-event-queue.ts inside the
handler using partKey(event) and rebuildReplaceable), causing O(n²) behavior
under many updates; instead maintain an index (e.g., a Map keyed by partKey)
that maps each partKey to the queued delta entries (or their indices/IDs) so
that when handling a "message.part.updated" you only look up and remove matching
deltas from result via that map, and keep the map updated whenever you
push/splice entries and call rebuildReplaceable to preserve correctness.

---

Nitpick comments:
In `@packages/app/src/context/global-sdk-event-queue.test.ts`:
- Around line 37-73: Add a regression test that asserts directory isolation:
within the same describe block add a test that uses coalesceQueuedEvents with
queued events created via queued(delta(...), updated(...), status(...)) where
the deltas/updates share the same messageID/partID/field but have different
directory values; verify using eventTypes(events) and deltas(events) that events
from different directory values are never merged or pruned together (i.e., they
remain separate entries and stale-to-updated pruning only applies within the
same directory), referencing the existing helpers coalesceQueuedEvents, queued,
delta, updated, status, eventTypes and deltas to locate where to add and what to
assert.

In `@packages/app/src/pages/session/use-session-history-window.test.ts`:
- Around line 87-89: Rename the test whose body calls resolveHistoryTurnStart({
mode: "bottom", storedTurnStart: 15, length: 26, userScrolled: true }) so its
description reflects bottom-mode scroll-freeze behavior instead of "reading
mode" (e.g., change the test name string from "reading mode does not slide the
window when the user scrolls upward inside the rendered range" to something like
"bottom mode preserves storedTurnStart when user has scrolled inside rendered
range"); update only the test description text associated with that assertion to
match the actual scenario using resolveHistoryTurnStart and leave the assertion
logic unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 4f33e216-d857-4c70-95fb-82a46f7d00dc

📥 Commits

Reviewing files that changed from the base of the PR and between 7635333 and a9e571c.

📒 Files selected for processing (7)
  • packages/app/src/context/global-sdk-event-queue.test.ts
  • packages/app/src/context/global-sdk-event-queue.ts
  • packages/app/src/context/global-sdk.tsx
  • packages/app/src/pages/session/use-session-hash-scroll.ts
  • packages/app/src/pages/session/use-session-history-window.test.ts
  • packages/app/src/pages/session/use-session-history-window.ts
  • packages/app/src/pages/session/use-session-timeline-interaction.ts

Comment thread packages/app/src/context/global-sdk-event-queue.ts Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/app/src/pages/session/use-session-history-window.test.ts`:
- Around line 16-40: The harness uses plain locals (messages, userScrolled) so
Solid reactivity in createSessionHistoryWindow never sees changes; update
createHarness to expose reactive sources (e.g., use createSignal or createStore)
for messages and userScrolled and pass their getter functions into
createSessionHistoryWindow (so visibleUserMessages and userScrolled read the
reactive getters), then implement setCount and setUserScrolled to call the
corresponding signal/setter to trigger memo/effect invalidation in the hook.

In `@packages/app/src/pages/session/use-session-history-window.ts`:
- Around line 276-284: The effect currently collapses every non-"bottom" mode
into returnToLatestIfFollowing(), which causes "hash" mode to be dropped
unintentionally; update the branches that check userScrolled and state.mode so
that returnToLatestIfFollowing() (and any implicit resumeLatestWindow behavior)
only runs when state.mode === "reading" (or when explicitly resuming), and do
not auto-exit when state.mode === "hash"; adjust the if (!userScrolled &&
state.mode !== "bottom") branch and the final fallback to guard on state.mode
=== "reading" instead of all non-"bottom" modes so "hash" remains sticky until
an explicit clear/resume action.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: f2d6ef5a-5072-4ed2-acba-0a9681e747c3

📥 Commits

Reviewing files that changed from the base of the PR and between a9e571c and 27f5981.

📒 Files selected for processing (2)
  • packages/app/src/pages/session/use-session-history-window.test.ts
  • packages/app/src/pages/session/use-session-history-window.ts

Comment thread packages/app/src/pages/session/use-session-history-window.test.ts Outdated
Comment thread packages/app/src/pages/session/use-session-history-window.ts

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/app/src/context/global-sdk-event-queue.ts`:
- Around line 5-26: The composite key helpers deltaKey, partKey and
replaceableKey currently join components with ":" which can collide if any
component (especially event.directory) contains ":"; update these functions to
produce unambiguous keys by encoding or serializing components (e.g., return
JSON.stringify([event.directory, props.messageID, props.partID, props.field])
for deltaKey, JSON.stringify([event.directory, props.messageID, props.partID])
for partKey, and JSON.stringify(["session.status", event.directory,
event.payload.properties.sessionID]) or JSON.stringify(["lsp.updated",
event.directory]) for replaceableKey) so keys are deterministic and
collision-free for all QueuedGlobalEvent payload shapes. Ensure all branches
return a string (not undefined) and keep the same semantics for different
payload types.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: ccc45e2b-c67a-4595-bf6f-d770eb3d9141

📥 Commits

Reviewing files that changed from the base of the PR and between 27f5981 and 0a9ceff.

📒 Files selected for processing (3)
  • packages/app/src/context/global-sdk-event-queue.test.ts
  • packages/app/src/context/global-sdk-event-queue.ts
  • packages/app/src/pages/session/use-session-history-window.test.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/app/src/pages/session/use-session-history-window.test.ts

Comment thread packages/app/src/context/global-sdk-event-queue.ts

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/app/src/pages/session/use-session-history-window.ts (1)

159-183: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Guard async history expansion against mode changes.

Both async loadMore continuations unconditionally re-enter reading mode after the await. If the user has already resumed bottom-following or jumped to a hash target while the request is in flight, the late completion still calls expandForReading(...) and can yank the timeline back out of the current mode.

Suggested fix
+    const requestedMode = mode()
+
     while (true) {
       await input.loadMore(id)
       if (input.sessionID() !== id) return
@@
     if (opts?.prefetch) {
+      if (mode() !== requestedMode) return
       const current = turnStart()
       preserveScroll(() => expandForReading(current + growth))
       return
     }
@@
-    preserveScroll(() => expandForReading(Math.max(0, afterVisible - target)))
+    if (mode() === requestedMode) {
+      preserveScroll(() => expandForReading(Math.max(0, afterVisible - target)))
+    }

Apply the same guard in loadAndReveal as well if you want the button path to preserve a later mode transition too.

Also applies to: 205-244

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/app/src/pages/session/use-session-history-window.ts` around lines
159 - 183, The async continuation after awaiting input.loadMore(...) must abort
if the UI mode or session changed while the request was in flight: add guards
right after each await (the one in this function and the same spot in
loadAndReveal) to return early unless input.sessionID() === id and the UI is
still in reading-mode (i.e. turnStart() === 0 or whatever current-mode predicate
you use); only then compute growth and call expandForReading(...). Ensure you
also preserve the existing sessionID check and the state.prefetchNoGrowth update
but do the mode/session checks before calling expandForReading.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@packages/app/src/pages/session/use-session-history-window.ts`:
- Around line 159-183: The async continuation after awaiting input.loadMore(...)
must abort if the UI mode or session changed while the request was in flight:
add guards right after each await (the one in this function and the same spot in
loadAndReveal) to return early unless input.sessionID() === id and the UI is
still in reading-mode (i.e. turnStart() === 0 or whatever current-mode predicate
you use); only then compute growth and call expandForReading(...). Ensure you
also preserve the existing sessionID check and the state.prefetchNoGrowth update
but do the mode/session checks before calling expandForReading.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 7e57e62a-02e0-4f69-a00b-d849af920b1f

📥 Commits

Reviewing files that changed from the base of the PR and between 3989a65 and ba6d688.

📒 Files selected for processing (5)
  • packages/app/src/context/global-sdk-event-queue.test.ts
  • packages/app/src/context/global-sdk-event-queue.ts
  • packages/app/src/pages/session/use-session-history-window.test.ts
  • packages/app/src/pages/session/use-session-history-window.ts
  • packages/app/src/pages/session/use-session-timeline-interaction.ts
✅ Files skipped from review due to trivial changes (1)
  • packages/app/src/pages/session/use-session-timeline-interaction.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • packages/app/src/context/global-sdk-event-queue.ts
  • packages/app/src/pages/session/use-session-history-window.test.ts

@Astro-Han Astro-Han merged commit 991fc90 into dev May 3, 2026
27 checks passed
@Astro-Han Astro-Han deleted the pawwork/long-session-timeline-perf-plan branch May 11, 2026 07:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant