Skip to content

[Bug] exit-worktree triggers full session view teardown/rebuild, causing timeline flash, layout shift, and scroll-to-top #432

@Astro-Han

Description

@Astro-Han

What happened?

When an agent session calls exit-worktree to leave a git worktree, the session view tears down and rebuilds. The message timeline unmounts, remounts with only 4 rendered messages, and content reassembles in-place — causing visible flicker, a large layout shift (CLS 0.38), and a 178ms jank burst. After the rebuild, when the user sends a follow-up message, the scroll position jumps from the bottom to near the top (scroll_top: 20451 → 4), forcing the user to manually scroll back.

Root cause chain

  1. Agent calls exit-worktree → backend updates activeDirectory to project root
  2. Sync propagates sync.data.path.directory change to frontend
  3. directory-layout.tsx detects the change and navigate()s to a new URL with the updated base64-encoded directory
  4. <Show when={resolved()} keyed> destroys and recreates the entire SDK/Sync subtree
  5. SyncProvider reset clears all message caches (sync.data.message[id] becomes undefined)
  6. session-main-view.tsx <Match when={...}> sees timelineMessagesReadyfalseMessageTimeline unmounts
  7. Messages reload from backend → timelineMessagesReadytrueMessageTimeline remounts with rendered_count: 4

Scroll-to-top (secondary)

After the rebuild, the user sends "下一步是什么?". A todo_force data refresh fires. The <Match when={...}> in session-main-view.tsx:132-136 uses its when value as an implicit SolidJS key. If timelineMessagesReady briefly becomes undefined during the refresh cycle, the <Match> destroys and recreates MessageTimeline. The new scroll container starts at scrollTop≈0, and the scroll-to-top is captured before forceScrollToBottom can recover.

Evidence from the session export:

Time scroll_top user_scrolled scroll_height
08:59:38.706 20451.5 false 21356
08:59:41.070 — (jank=1, long_task=55ms)
08:59:41.348 4 true 21356
08:59:41.606 2256 true

scroll_height is identical (21356), ruling out content-height change. scroll_top=4 is near-zero but not zero, consistent with DOM replacement (browser overflow-anchor residual) rather than a scrollTo(0,0) call.

Steps to reproduce

  1. Open PawWork in a git project
  2. Ask the agent to enter-worktree into a git worktree
  3. Let the agent complete some work (commits, file changes)
  4. Ask the agent to exit-worktree
  5. Observe the timeline flash, content rebuild, and layout shift
  6. Send a follow-up message after the rebuild
  7. Observe the scroll position jump to the top

What did you expect to happen?

  • Exiting a worktree should keep the existing message timeline intact
  • No visible teardown or rebuild of the session view
  • Scroll position should be preserved across the directory change

Diagnostics

Renderer diagnostics from session export

Time Event Detail
08:58:59 session.identity.transition Session identity remapped
08:59:03 Agent calls exit-worktree Directory: worktree → project root
08:59:16 session.timeline.mount rendered_count: 4 (was 70+)
08:59:16 session.data.refresh message_force — 211ms
08:59:21 incident.session_jank_burst long_task=178ms, frame_gap=258ms
08:59:26 incident.session_layout_shift CLS=0.3797
08:59:41 scroll_top drops ~20451 → 4 View jumps to top

Code pointers

  • packages/app/src/pages/directory-layout.tsx<Show when={resolved()} keyed> destroys subtree on directory change
  • packages/app/src/pages/session/session-main-view.tsx:132-136<Match when={...}> implicit key destroys MessageTimeline on transient state changes
  • packages/app/src/pages/session/message-timeline.tsx:415-425onMount/onCleanup emit timeline mount/unmount events
  • packages/app/src/pages/session/use-session-scroll-dock.tscreateAutoScroll state reset on scrollRef change
  • packages/ui/src/hooks/create-auto-scroll.tsx — scroll position tracking and auto-follow logic

Environment

  • PawWork: dev (local build)
  • OS: macOS 25.3.0
  • Session export: pawwork-session-nimble-wizard-2026-05-04-08-59-46.json

Metadata

Metadata

Assignees

No one assigned

    Labels

    P1High priorityappApplication behavior and product flowsbugSomething isn't workingharnessModel harness, prompts, tool descriptions, and session mechanicsuiDesign system and user interface

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions