# Fix JetBrains Session Question Scroll

## Goal
When a question-like active view first appears in the JetBrains session UI, do not auto-scroll the transcript if the user is already away from the tail and the scroll-to-bottom button is visible. This applies to permission prompts and question-based views. Existing behavior should remain: if the transcript is already at the bottom, new questions/permissions keep the view at the bottom; explicit question navigation can still jump to the active card.

## Current Findings
- `SessionUi` wires `QuestionView` with:
  - `follow = { scroll.following() }`
  - `scroll = { scroll.followBottom(it) }`
- `QuestionView.show()` runs on first display and calls:
  - `val tail = follow()` before rendering the card
  - `scroll(tail)` after rendering
- `SessionScroll.following()` currently returns `component.viewport.view === messages && tail`.
- This can use stale internal follow state instead of the live scrollbar state. The user-visible condition is better represented by `SessionScroll.atBottom()`, which is also what `SessionController.beforeUpdate` uses for normal transcript updates.
- Existing `SessionScrollTest` already covers question and login-required middle-scroll preservation, but it does not cover permission first appearance and likely does not cover a stale-tail/live-not-at-bottom edge.

## Implementation Plan
1. Update question first-show follow sampling to use live bottom state.
   - In `SessionUi.buildUi()`, change the `QuestionView` `follow` lambda from `scroll.following()` to `scroll.atBottom()`.
   - Alternatively, if a single semantic API is preferred, change `SessionScroll.following()` to return `component.viewport.view === messages && atBottom()` and keep the `SessionUi` call site unchanged. Prefer the smaller, clearer call-site change unless tests show other `following()` behavior should change too.

2. Add permission scroll regression tests in `SessionScrollTest`.
   - Add `test permission appearing at bottom keeps scroll at bottom`.
   - Add `test permission appearing while user is in middle preserves scroll position`.
   - Emit `ChatEventDto.PermissionAsked("ses_test", PermissionRequestDto(...))` using the same DTO style as the existing recovered permission test.
   - Assert the scrollbar value is preserved and `jumpButton().isVisible` stays true when initially away from bottom.

3. Strengthen question regression coverage if needed.
   - Keep the existing `test question appearing while user is in middle preserves scroll position`.
   - If the bug reproduces only when the jump button is visible but `tail` can be stale, add a targeted regression that creates the visible jump state before `QuestionAsked` and asserts first display does not jump.
   - Avoid adding production-only test hooks; use existing `setValue`, `setValuePassive`, `drainScroll`, and event helpers.

4. Preserve intentional explicit navigation behavior.
   - Do not change `QuestionView.goForward()`, `goBack()`, or `goReview()`, which intentionally call `scroll(true)` and are covered by existing tests that expect navigation to jump to the active question card.
   - Do not change prompt growth or normal streaming follow behavior unless a failing test shows the same stale-state issue applies there.

5. Verification.
   - Run the targeted JetBrains frontend session scroll tests from `packages/kilo-jetbrains/` using Gradle test filtering for `SessionScrollTest` if supported.
   - Run `./gradlew typecheck` from `packages/kilo-jetbrains/` if the targeted tests pass or if Gradle filtering is unavailable.
   - If Java 21 is unavailable, first check/report that blocker as instructed by the repo docs.

## Expected Files To Touch
- `packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/SessionUi.kt`
- `packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/SessionScrollTest.kt`

## Non-Goals
- No backend or RPC protocol changes.
- No redesign of the session scroll algorithm.
- No changes to explicit question navigation auto-scroll behavior.
