Standardize on the .agents/ directory (shared with project skills): phases/, user_stories/, reports/, screenshots/, validate.sh, and phase-sessions/ + pipeline.log all move to .agents/ (git mv preserves history; runtime artifacts move alongside). Updates every reference in AGENTS.md, README.md, .gitignore, app docstrings, and test story headers. Historical KB content in data/ and the runtime pipeline.log transcript are left untouched.
5.1 KiB
Phase 21 — Thinking Window: No Scroll Back, Just Live
Source: TODO.md L4 — "Disable scroll in the thinking window.
Users don't need to scroll back through thinking, just see it live."
Story: .agents/user_stories/thinking-no-scroll.md (created by task 02)
Context: frontend/assets/styles.css —
details.thinking .thinking-text (today: max-height: 320px; overflow-y: auto;, i.e. a user-scrollable 320px window, ~line 444);
frontend/assets/app.js — the phase-17 thinking block (ensureThinkingBlock,
the streaming thinking branch that appends chunks and already pins the
stream to the bottom: textEl.scrollTop = textEl.scrollHeight, ~line 886),
and the phase-14 restore path (stored thinking re-renders a
collapsed block).
Objective
The live Thinking block is a scratchpad, not a transcript. The user must
not be able to scroll back through it — the 320px window always shows the
live tail of the reasoning stream (the existing per-chunk
bottom-pinning stays). Wheel, drag, and keyboard scrolling on
.thinking-text stop working; the stream itself keeps pinning to the
bottom as chunks arrive.
Owner-confirmed (2026-08-24, roadmap A2)
- Keep the 320px clip — "just see it live" means the window stays a fixed 320px viewport showing the newest lines; no auto-height growth, no "↓ more" affordance.
- The answer bubble is untouched — final answers keep their existing scroll behavior (phase 11 long answers).
- Restored (collapsed) Thinking blocks are untouched — the phase-14 restore renders them collapsed, where overflow is moot.
Design
- CSS (the whole functional change):
details.thinking .thinking-text—overflow-y: auto→overflow-y: hidden; keepmax-height: 320px.overflow: hiddenstill permits programmatic scrolling (scrollTop), so the phase-17 pin (textEl.scrollTop = textEl.scrollHeighton every thinking chunk) keeps the window glued to the live tail — no JS change needed. Add a CSS comment: no user scroll back (owner choice 2026-08-24): the window is a live tail only — the JS bottom-pin is the sole scroller. - No JS change — the pin already exists; nothing else touches
.thinking-textscroll. - Non-goals: no change to the answer bubble, the collapsed restore state, the summary/chevron, or the auto-collapse on first delta (phase 17).
Dependencies
17_thinking_display(complete) — the block, the pin, the restore.18_follow_bottom_scroll(complete) — no overlap (chat-page scroll gate only; the thinking window is a separate inner element).11_long_answers(complete) — the untouched answer-bubble behavior.
Tasks
01_disable_thinking_scroll.md— the CSS change + source-level unit pins.02_e2e_story_suite_commit.md—tests/e2e/test_thinking_no_scroll.py(the story gate, isolated), regression suites, story file, final validation, the single atomic commit, phase move tocomplete/.
Locked decisions
- A11 untouched — no CDN, pure CSS. A16 honored — one new story E2E suite + adapted regressions. No anchor changed.
Testing & Quality
- Unit (source-level, new
tests/unit/test_thinking_no_scroll.py, repo source-pin pattern):styles.csscarriesdetails.thinking .thinking-textwithoverflow-y: hiddenandmax-height: 320px; the phase-17 pin line (textEl.scrollTop = textEl.scrollHeight) still present inapp.js(the live-tail mechanism must not be lost). - Integration: none (no
app/changes). - Coverage: frontend-only; the >90%
app/gate is unaffected. - E2E:
tests/e2e/test_thinking_no_scroll.py(task 02), green in isolation (prereqpodman compose up -d db). - Lint/types:
uv run ruff check . && uv run pyrightclean.
Completion Criteria
- With a long thinking stream, wheel/mouse-drag/keyboard on
.thinking-textdo not move it; the visible content is always the live tail (scrollTop === scrollHeightafter each chunk, within 1px). - Computed style:
overflow-y: hidden,max-height: 320px. - A long answer bubble still scrolls normally; a restored collapsed Thinking block still renders (phase 17 regression).
uv run pytestgreen;uv run pytest --cov=app --cov-report=term-missing≥ today's number.uv run pytest tests/e2e/test_thinking_no_scroll.py -v --no-covgreen in isolation; regressions green in isolation:test_thinking_display.py,test_long_answers.py.uv run ruff check . && uv run pyrightclean.- UI Structure Check (AGENTS.md rule 5): no new surface; the block keeps its focus-visible summary, aria contract, and reduced-motion behavior.
.agents/user_stories/thinking-no-scroll.mdexists.- One
--no-gpg-signcommit (below);.agents/phases/todo/21_thinking_no_scroll/moved to.agents/phases/complete/.
Commit
git add -A .agents/ frontend/ tests/ && git commit --no-gpg-sign -m "fix(ui): thinking window no longer scrolls — live 320px view pinned to the stream tail"