tui: stabilize transcript scrollback
This commit is contained in:
parent
e2724636d0
commit
fcecbb2eff
@ -50,11 +50,16 @@ export class ChatLog extends Container {
|
||||
|
||||
private append(component: Component) {
|
||||
const wasAtLatest = this.scrollOffset === 0;
|
||||
const previousLineCount = wasAtLatest ? 0 : this.getRenderedLineCount(this.lastRenderWidth);
|
||||
this.addChild(component);
|
||||
this.pruneOverflow();
|
||||
if (wasAtLatest) {
|
||||
this.scrollToLatest();
|
||||
return;
|
||||
}
|
||||
const nextLineCount = this.getRenderedLineCount(this.lastRenderWidth);
|
||||
this.scrollOffset += Math.max(0, nextLineCount - previousLineCount);
|
||||
this.clampScrollOffset();
|
||||
}
|
||||
|
||||
setViewportHeight(height: number | null) {
|
||||
@ -109,6 +114,7 @@ export class ChatLog extends Container {
|
||||
this.toolById.clear();
|
||||
this.streamingRuns.clear();
|
||||
this.btwMessage = null;
|
||||
this.scrollToLatest();
|
||||
}
|
||||
|
||||
addSystem(text: string) {
|
||||
|
||||
@ -230,6 +230,10 @@ export function resolveInitialTuiAgentId(params: {
|
||||
return normalizeAgentId(params.fallbackAgentId);
|
||||
}
|
||||
|
||||
function isMouseSgrSequence(data: string): boolean {
|
||||
return /^\x1b\[<\d+;\d+;\d+[Mm]$/.test(data);
|
||||
}
|
||||
|
||||
export function parseMouseWheelEvent(data: string): { direction: "up" | "down"; row: number; col: number } | null {
|
||||
const match = /^\x1b\[<(\d+);(\d+);(\d+)([Mm])$/.exec(data);
|
||||
if (!match) {
|
||||
@ -552,12 +556,15 @@ export async function runTui(opts: TuiOptions) {
|
||||
const tui = new TUI(new ProcessTerminal());
|
||||
const dedupeBackspace = createBackspaceDeduper();
|
||||
tui.addInputListener((data) => {
|
||||
const mouse = parseMouseWheelEvent(data);
|
||||
if (!mouse || tui.hasOverlay()) {
|
||||
if (!isMouseSgrSequence(data)) {
|
||||
return undefined;
|
||||
}
|
||||
const mouse = parseMouseWheelEvent(data);
|
||||
if (!mouse || tui.hasOverlay()) {
|
||||
return { consume: true };
|
||||
}
|
||||
if (mouse.row < chatViewportTop || mouse.row > chatViewportBottom) {
|
||||
return undefined;
|
||||
return { consume: true };
|
||||
}
|
||||
if (mouse.direction === "up") {
|
||||
chatLog.scrollLines(3);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user