Skip to content

fix(terminal): enable scrollback by suppressing tmux alternate screen#405

Merged
skulidropek merged 6 commits into
ProverCoderAI:mainfrom
konard:issue-404-5a7f728e1091
Jun 15, 2026
Merged

fix(terminal): enable scrollback by suppressing tmux alternate screen#405
skulidropek merged 6 commits into
ProverCoderAI:mainfrom
konard:issue-404-5a7f728e1091

Conversation

@konard

@konard konard commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

Problem

Issue #404: "Почему терминал не способен скролиться?" — the web terminal cannot be scrolled. The reporter clarifies: "Он постоянно очищает весь текст и даёт видеть только 1 страницу" (it constantly clears all the text and only lets you see one page).

Root cause

Project terminals run inside tmux (renderTmuxAttachCommand in packages/api/src/services/terminal-sessions.ts starts tmux with mouse on, history-limit 50000). tmux switches xterm.js into the alternate screen buffer (DEC private modes 47/1047/1049).

The alternate screen keeps no scrollback in xterm. So every repaint wipes the visible buffer — the terminal shows only the current page — and wheel scrolling (terminal.scrollLines) has nothing to reveal. xterm's scrollback: 50_000 setting only applies to the normal buffer, which tmux never used.

Fix

The query-suppression layer already had a fully-implemented but never-enabled suppressAlternateScreen option (terminal-query-suppression.ts), with a comment explicitly anticipating "project terminals opt out to keep xterm scrollback visible". This PR turns it on for project terminals.

  • New pure gating module packages/terminal/src/web/terminal-screen-policy.ts decides per session (project terminals are identified by browserProjectId):
    • shouldAllowTerminalMouseTracking (existing behaviour, extracted)
    • shouldSuppressTerminalAlternateScreen (new)
  • terminal-panel-runtime.ts passes suppressAlternateScreen into the querySuppression options when creating the runtime.
  • Exported from src/web/index.ts.

With the alternate screen suppressed, tmux/TUI output stays in xterm's normal buffer, accumulating in the 50k-line scrollback, so wheel scrolling reveals earlier history.

Auth/login terminals (no browserProjectId) are unaffected — they keep the conservative default and continue to use the alternate screen.

Reproduction

  1. Open a project terminal (tmux-backed) in the web UI.
  2. Run a command producing more than one screen of output (e.g. seq 1 200).
  3. Before the fix: only the last page is visible; scrolling up shows nothing.
  4. After the fix: scrolling up reveals the earlier output from xterm's scrollback.

Tests

  • New packages/terminal/tests/web/terminal-alternate-screen.test.ts covers the gating: project sessions suppress the alternate screen and allow mouse tracking; auth sessions do neither; session classification by browserProjectId.
  • Existing terminal-query-suppression.test.ts already verifies that suppressAlternateScreen: true makes the CSI ?h/?l handlers consume modes 47/1047/1049.
  • Full suite: 143 tests passing, tsc --noEmit clean, all linters (lint, lint:tests, lint:effect) clean.

Refs #404

Fixes #404

Adding .gitkeep for PR creation (default mode).
This file will be removed when the task is complete.

Issue: ProverCoderAI#404
@coderabbitai

coderabbitai Bot commented Jun 15, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@skulidropek, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 56 minutes and 10 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 2ae7e9f8-c2d5-46e0-8823-58edfc856faf

📥 Commits

Reviewing files that changed from the base of the PR and between 29e8943 and 1097a6a.

📒 Files selected for processing (11)
  • .changeset/terminal-scrollback-alternate-screen.md
  • packages/api/src/services/terminal-sessions.ts
  • packages/api/tests/terminal-sessions.test.ts
  • packages/app/CHANGELOG.md
  • packages/app/package.json
  • packages/docker-git-session-sync/CHANGELOG.md
  • packages/docker-git-session-sync/package.json
  • packages/terminal/src/web/index.ts
  • packages/terminal/src/web/terminal-panel-runtime.ts
  • packages/terminal/src/web/terminal-screen-policy.ts
  • packages/terminal/tests/web/terminal-alternate-screen.test.ts
📝 Walkthrough

Walkthrough

В файл .gitkeep добавлена одна строка автогенерируемого комментария, содержащая метку времени, идентификатор ветки и ссылку на issue.

Changes

Обновление .gitkeep

Layer / File(s) Summary
Комментарий в .gitkeep
.gitkeep
Добавлена одна строка с автогенерируемым комментарием, указывающим на ветку и связанный issue.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~1 minutes


Important

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

❌ Failed checks (1 error, 3 warnings)

Check name Status Explanation Resolution
Requirements Alignment ❌ Error PR заявляет решение Issue #404 (проблема скроллинга), но содержит только сервисное изменение .gitkeep с нарушением конвенции. Отсутствуют код, инварианты проверяемости (Story+Prove) и тесты, требуе... Добавить актуальное решение Issue #404, Story с инвариантами проверяемости (INV-*), релевантные тесты; удалить содержимое .gitkeep (оставить пустым).
Linked Issues check ⚠️ Warning PR в статусе черновика без конкретных изменений кода, не решает требования linked issue #404 по исправлению прокрутки терминала. Реализуйте и протестируйте решение для проблемы прокрутки терминала, добавив соответствующие изменения в код.
Out of Scope Changes check ⚠️ Warning Единственное изменение (.gitkeep файл) не связано с исправлением проблемы прокрутки терминала из issue #404. Удалите изменение .gitkeep файла и добавьте реальные изменения кода, необходимые для исправления прокрутки терминала.
Title check ⚠️ Warning Заголовок содержит конкретное техническое решение (подавление альтернативного буфера tmux), но изменения в raw_summary показывают только добавление строки в .gitkeep файл, что не соответствует описанному решению. Заголовок либо не соответствует актуальным изменениям в PR (требуется обновление заголовка), либо missing реальные изменения кода, упомянутые в описании.
✅ Passed checks (3 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Security Regression ✅ Passed Изменение только добавляет комментарий с публичными метаданными (timestamp, branch ID, issue link) в файл .gitkeep. Проверка не выявила command injection, path traversal, credential/PII exposure, D...
Description check ✅ Passed PR description полностью заполнена всеми необходимыми разделами: Problem, Root cause, Fix, Reproduction, Tests. Содержит подробное объяснение проблемы, решения и верификации.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@coderabbitai coderabbitai 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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.gitkeep:
- Line 1: The `.gitkeep` file currently contains auto-generated metadata
comments, which violates the standard convention for `.gitkeep` files that serve
as placeholders for empty directories in git repositories. Remove all content
from the `.gitkeep` file completely, leaving it empty as per the established
convention. If metadata about PR generation needs to be preserved, use an
alternative mechanism such as a separate log file or documentation in a
different location.
🪄 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: ASSERTIVE

Plan: Pro Plus

Run ID: 199d6567-e68f-4113-997b-e0f46ecb9e28

📥 Commits

Reviewing files that changed from the base of the PR and between 76f4fab and 29e8943.

📒 Files selected for processing (1)
  • .gitkeep
📜 Review details
⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (18)
  • GitHub Check: E2E (Login context)
  • GitHub Check: E2E (Browser command)
  • GitHub Check: E2E (OpenCode)
  • GitHub Check: Lint
  • GitHub Check: E2E (Runtime volumes + SSH)
  • GitHub Check: Test
  • GitHub Check: Lint Effect-TS
  • GitHub Check: E2E (Local package CLI)
  • GitHub Check: Build
  • GitHub Check: E2E (Clone cache)
  • GitHub Check: E2E (Clone auto-open SSH)
  • GitHub Check: Types
  • GitHub Check: Final build (macos-latest)
  • GitHub Check: Dist deps prune
  • GitHub Check: Final build (windows-latest)
  • GitHub Check: Final build (ubuntu-latest)
  • GitHub Check: Snapshot
  • GitHub Check: dist-deps-prune
🧰 Additional context used
📓 Path-based instructions (1)
**/{.git*,config*,*.sh,docker-compose*}

📄 CodeRabbit inference engine (README.md)

Use git credential helper to automatically select correct token by host for HTTPS clone/push operations

Files:

  • .gitkeep

Comment thread .gitkeep Outdated
github-actions Bot and others added 3 commits June 15, 2026 07:02
…ble scrollback

Project terminals run inside tmux, which switches xterm into the alternate
screen buffer (DEC 47/1047/1049). The alternate screen keeps no scrollback,
so output was cleared on every repaint and wheel scroll had nothing to reveal
("constantly clears all text, only shows one page").

Wire the already-implemented suppressAlternateScreen query-suppression option
on for project terminals via a new pure gating module (terminal-screen-policy),
keeping tmux/TUI output in xterm's normal 50k-line scrollback buffer.

Refs ProverCoderAI#404
@konard konard changed the title [WIP] Почему терминал не способен скролиться? fix(terminal): enable scrollback by suppressing tmux alternate screen Jun 15, 2026
@konard konard marked this pull request as ready for review June 15, 2026 07:10
@konard

konard commented Jun 15, 2026

Copy link
Copy Markdown
Contributor Author

Working session summary

All CI checks pass. The only failure is CodeRabbit ("Prepaid credits exhausted"), an account-level billing issue unrelated to this change. Working tree is clean and the PR is ready.

Summary

Issue #404 ("Why is the terminal not able to scroll? It constantly clears all the text and only lets you see one page") is resolved in PR #405.

Root cause: Project terminals run inside tmux, which switches xterm.js into the alternate screen buffer (DEC private modes 47/1047/1049). The alternate screen keeps no scrollback, so every repaint wiped the visible buffer (only one page shown) and wheel scrolling had nothing to reveal. xterm's scrollback: 50_000 only applies to the normal buffer, which tmux never used.

Fix: Enabled the already-implemented-but-dormant suppressAlternateScreen query-suppression option for project terminals. The codebase even had a comment anticipating exactly this. Changes:

  • New pure gating module packages/terminal/src/web/terminal-screen-policy.tsshouldSuppressTerminalAlternateScreen / shouldAllowTerminalMouseTracking, keyed on browserProjectId (so auth/login terminals are unaffected).
  • terminal-panel-runtime.ts wires suppressAlternateScreen into querySuppression.
  • Exported from src/web/index.ts.
  • New test tests/web/terminal-alternate-screen.test.ts.

With the alternate screen suppressed, tmux/TUI output stays in xterm's normal buffer and accumulates in the 50k-line scrollback, so wheel scrolling reveals earlier history.

Verification:

  • 143 tests passing, tsc --noEmit clean, all three linters clean locally.
  • All GitHub CI checks green (Lint, Test, Types, Build, all E2E, Final builds on all OSes).
  • Changeset added; main merged in; pushed to issue-404-5a7f728e1091; PR marked ready.

PR: #405


This summary was automatically extracted from the AI working session output.

@konard

konard commented Jun 15, 2026

Copy link
Copy Markdown
Contributor Author

🤖 Solution Draft Log

This log file contains the complete execution trace of the AI solution draft process.

💰 Cost estimation:

  • Public pricing estimate: $4.802885
  • Calculated by Anthropic: $5.339544
  • Difference: $0.536659 (+11.17%)

📊 Context and tokens usage:

Claude Opus 4.8: (2 sub-sessions)

  1. 116.4K / 1M (12%) input tokens, 34.9K / 128K (27%) output tokens
  2. 51.4K / 1M (5%) input tokens, 5.2K / 128K (4%) output tokens

Total: (24.2K new + 145.2K cache writes + 5.2M cache reads) input tokens, 46.4K output tokens, $4.802885 cost

🤖 Models used:

  • Tool: Anthropic Claude Code
  • Requested: opus
  • Model: Claude Opus 4.8 (claude-opus-4-8)

📎 Log file uploaded as Gist (2368KB)


Now working session is ended, feel free to review and add any feedback on the solution draft.

@konard

konard commented Jun 15, 2026

Copy link
Copy Markdown
Contributor Author

✅ Ready to merge

This pull request is now ready to be merged:

  • All CI checks have passed
  • No merge conflicts
  • No pending changes

Monitored by hive-mind with --auto-restart-until-mergeable flag

@skulidropek

skulidropek commented Jun 15, 2026

Copy link
Copy Markdown
Member

AI Session Backup

Commit: 1097a6a
Status: success
Files: 4 (4.32 MB)
Links: README | Manifest

git status

On branch issue-404-5a7f728e1091
nothing to commit, working tree clean

@skulidropek skulidropek mentioned this pull request Jun 15, 2026
@skulidropek

skulidropek commented Jun 15, 2026

Copy link
Copy Markdown
Member

AI Session Backup

Commit: 1097a6a
Status: success
Files: 4 (4.35 MB)
Links: README | Manifest

git status

On branch issue-404-5a7f728e1091
nothing to commit, working tree clean

@skulidropek skulidropek merged commit e7f1518 into ProverCoderAI:main Jun 15, 2026
18 of 19 checks passed
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.

Почему терминал не способен скролиться?

2 participants