replaceBanner regenerates the banner with the current shine column and splices it into place inside m.output. Anything written after the banner (the user's first prompt, agent output, etc.) is preserved — replaceBanner only rewrites the leading byte range that bannerEnd points at. Width comes from m
()
| 866 | // comes from m.bannerWidth (captured before the stdout redirect) rather |
| 867 | // than a fresh TermWidth() call. |
| 868 | func (m *harness) replaceBanner() { |
| 869 | post := "" |
| 870 | full := m.output.String() |
| 871 | if m.bannerEnd > 0 && m.bannerEnd <= len(full) { |
| 872 | post = full[m.bannerEnd:] |
| 873 | } |
| 874 | animated := AnimatedBanner(m.bannerWidth, m.shineCol) |
| 875 | m.output.Reset() |
| 876 | m.output.WriteString(animated) |
| 877 | m.bannerEnd = m.output.Len() |
| 878 | m.output.WriteString(post) |
| 879 | } |
| 880 | |
| 881 | // setConversationContent pushes the current scrollback buffer into the |
| 882 | // viewport, wrapping it to the viewport's width first so long lines |
no test coverage detected