Repository navigation
Keep e2e prompt output from drawing over the outer terminal (4.0.0-DEV3) - #20
Open
KeithRaghubar wants to merge 1 commit into
Open
KeithRaghubar wants to merge 1 commit into
KeithRaghubar wants to merge 1 commit into
Conversation
answer.py runs a scenario's command on a pty that has no window size, so sysforge assumed 80x24: its progress bar set a scroll region for rows 1-23 and painted row 24. answer.py copied the raw bytes to stdout, and through podman exec they reached the terminal running make e2e or make pre-release, overlapping text on that row while the real bottom line stayed blank. TerminalFilter now sits between the pty and stdout: text, colour, \r and erase-to-end-of-line pass; every other sequence is dropped, as is text drawn between a cursor save and its restore (the bar row). A newline inside that bracket means it was not a one-row paint, so its text is kept. Sequences split across reads are held until complete. Prompt matching still reads the unfiltered stream. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
During
make pre-release, text overlapped on one line near the bottom of the terminal while the terminal's real last line stayed blank. The terminal was fine oncemakefinished.tools/e2e/answer.pyruns a scenario's command on a pseudo-terminal frompty.fork(), which never gets a window size. The child sees 0×0 andshutil.get_terminal_size()falls back to 80×24, butisatty()is true, so sysforge's progress bar runs in TTY mode. It sets a scroll region for rows 1–23 (ESC[1;23r) and paints row 24.answer.pycopied the raw stream to stdout, andpodman execcarried it to the terminal runningmake e2e, whatever that terminal's real height. This affects the five scenarios that useanswer:10-quickstart,20-repo-optin,45-interactive,50-maintainand75-config-merge.Fix
A
TerminalFilternow sits between the pty and stdout:\r, colour (ESC[…m) and erase-to-end-of-line (ESC[K), which work wherever the cursor is.ui/progress.pypaints the bar row. Stripping only the cursor moves would splice[building] …into content lines. A bar paint is one row, so a newline inside the bracket means it wasn't one, and that text is kept. An unrestored save at the end also keeps its text.os.readcalls until it's complete.Prompt matching still runs on the unfiltered stream, and the command still runs on a terminal, so the scenarios exercise the same interactive paths.
Docs:
tools/e2e/README.md,docs/design/17-release-plan.md(+DESIGN.md), and a4.0.0-DEV3release-note entry under## Changed.Tests
tests/test_e2e_answer.py(8 tests): the bar's establish/paint/release sequences; colour,\randESC[Ksurviving; a sequence and a paint each split across reads; an unrestored save, mid-stream and at the end; alternate screen, title and cursor visibility. The last test runsanswer.pyon a real pty and checks the prompt is still answered while placement is stripped. All 8 failed before the fix. The split-sequence test caught a regex bug during the fix: the short-form branch[0-~]tookESC [itself as a complete sequence.ui.progresssession plus phase, run under both versions): the oldanswer.pyemittedESC[1;23rand the row-24 paint; the new one emits only the content lines.lint,check-standards,check-designandcheck-surfaceare clean.Tier: this is the e2e harness itself, so I didn't add a new e2e scenario. The pty test above exercises the real pseudo-terminal boundary. I haven't run
make e2elocally; CI runs it on this PR.Checklist
docs/release-notes/unreleased.md, led by its roadmap IDmake surfacecommitted, and its diff matches what I meant to change (no surface change;check-surfaceclean)tools/retired_names.toml(none)docs/guides/) still describes it correctly (no user guide covers the e2e harness;tools/e2e/README.mdupdated)make pre-release(ormake ci-local) passes locally (not run; the full suite and the static guards pass)🤖 Generated with Claude Code