Skip to content

Framework-select screen garbles text when the terminal is shorter than 28 rows #1111

Description

@Ref34t

What happened

I ran npx @posthog/wizard (v2.63.0) in a project it could not auto-detect. On the framework-select screen, lines were drawn on top of each other:

  • The two intro lines merged into one:
    We'.env* file contents will not leave your machine.ork.
    (that is the .env* line stamped over "We'll use AI to analyze your project and complete work.")
  • List items merged too: astroar (astro + angular), and vue disappeared.

The selection itself still works — arrows and enter do the right thing. Only the paint is wrong.

Reproduction

It is deterministic and depends only on terminal height:

  1. Make the terminal 27 rows or shorter (width doesn't matter, tested at 110 cols).
  2. Run the wizard in a directory with no framework markers, so it lands on the framework-select screen.
  3. The screen is garbled. At 28 rows or taller the same screen renders perfectly.

It gets worse the shorter the terminal. At 20 rows:

                        ▸ nextjsype to filter 2laravelns
                          vuet                 flutterit
                          tanstack-start       kmp
                          react-nativeter      android

At 24 rows (matches my original screenshots):

             We'.env* file contents will not leave your machine.ork.

                       Could not auto-detect your framework.

                               Select your framework
                             Type to filter 23 options
                      ▸ nextjs               laravel
                        nuxt                 sveltekit
                        react-router         flutter
                        ...
                        astroar              python

To rule out my terminal app, I reproduced it with a scripted pseudo-terminal (pty with pinned rows/cols, output fed to the pyte terminal emulator). Same corruption, same 27/28 threshold — both on the published v2.63.0 and on current main (10c9cb7). Happy to share the repro script.

What I think is going on

The framework-select frame needs 28 rows at minimum (banner + intro + notice + 23-option grid + footer). When the terminal has fewer rows than the frame, Ink's repaint can't address the rows that scrolled out of the viewport, so parts of the previous frame survive and new lines land on top of old ones. It corrupts on first paint, not just after a resize.

Expected

One of:

  • the screen adapts when stdout.rows is small (scroll the option list / drop the intro lines), or
  • a minimum-size notice instead of garbled output.

Screenshots from the original run (healthy fullscreen vs. two broken sizes) coming in a comment below.

Activity

  1. Ref34t commented on Aug 19, 2026

    @Ref34t
    Author

    Screenshots from the original run (macOS Terminal, same project, only the window size changes):

    Fullscreen — renders correctly (intro on two lines, vue / angular / astro each on their own row):

    healthy fullscreen

    Medium window (~24 rows) — lines merge (We'.env* ... machine.ork., astroar, vue gone):

    corrupted medium window

    Small window (~20 rows) — worse (angularative, kmptter, fewer rows than 23 options):

    corrupted small window

  2. chrisdeely commented on Oct 22, 2026

    @chrisdeely

    This issue appears to have returned as of v2.87.0, and occurs at up to 30 rows, despite the documented minimum being 28.

    120x30
    Image

    120x31
    Image

    Too small message

    Image
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions