Skip to content

terminal-pilot: screenshot serialization retains inverse after SGR 27 #612

Description

@kamilio

Summary

terminal-pilot's screenshot serialization retains inverse styling after the PTY
explicitly disables it with SGR 27. Reproduced September 5, 2026 with the installed
terminal-pilot 0.0.1 package, Node 22.22.0, Linux. This reproduces without any
application UI library or framework.

Reproduction

Save this as /tmp/terminal-pilot-ansi.mjs:

process.stdout.write("\x1b[31mRED\x1b[0m  \x1b[36mCYAN\x1b[0m  plain\r\n\x1b[7;37m INVERSE \x1b[27;36m NORMAL CYAN \x1b[0m DEFAULT \r\n");
setInterval(() => {}, 1000);
terminal-pilot create-session --session ansi-reset --cwd /tmp --cols 64 --rows 12 node /tmp/terminal-pilot-ansi.mjs
terminal-pilot screenshot --session ansi-reset -o /tmp/ansi-reset.png
terminal-pilot close-session --session ansi-reset

Expected: only INVERSE has an inverted background. NORMAL CYAN should be
cyan text on the default dark background, since SGR 27 disabled inverse before
the text was written. DEFAULT should have default styling.

Actual: NORMAL CYAN has a cyan filled background with dark text. The preceding
inverse attribute survives until the later SGR 0. The top-row RED/CYAN controls
render correctly, so this is not a general color-support or font issue.

Likely boundary and impact

The installed terminal buffer's full-style serialization omits disabled flags
when switching cells. Emitting the next cell's enabled style without resetting
the prior style loses inverse-off (and may lose other attribute-off transitions).
Please verify TerminalBuffer.renderLine() and serializeStyleState() in the
source version corresponding to the distributed package.

This makes screenshot-based TUI QA show false selection/highlight remnants. It
should not be addressed by changing application output that already uses valid
SGR sequences.

Suggested coverage

  • Round-trip cells with inverse-on → inverse-off plus a foreground change.
  • Cover bold/dim/underline disable transitions and explicit default colors.
  • Assert serialized raw lines reconstruct the same styles as emulator cells.
  • Screenshot the minimal fixture and verify the normal segment's background.

The reproduction PNG was captured and visually inspected; no private repository
content is needed to reproduce this defect.

Activity

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