fix(trust-dialog): re-read a throttled trust-dialog scan instead of dropping it

The scan must schedule its own next read rather than wait for PTY output, but a call inside the throttle was simply dropped. The dialog's own paint is often the last output a launching pane produces and lands inside that throttle, so the session sat on the dialog with no keystroke ever sent. A stopped session no longer scans, since the kill's own output kept it answering a dialog in a dead pane.
This commit is contained in:
JD committed 2026-10-14 22:03:15 -04:00
1 parent a8a8bb71a3
commit 892c2fc4df
4 files changed
+64 -8

No files matched your search

+42
View File
@@ -239,6 +239,48 @@ describe('Session trust-dialog auto-accept', () => {
expect(writes).toEqual([]);
});
it('reads the dialog that painted inside the throttle of the read before it', () => {
vi.useFakeTimers();
// Measured on 2.1.294: one read at +156 ms saw a blank pane, the dialog painted
// within the throttle, and a quiet dialog sends no further output to read on.
let screen = '';
const { writes, tick } = sessionShowing(() => screen);
tick();
vi.advanceTimersByTime(500);
screen = RENDERED_DIALOG_2_1_252;
tick(); // the dialog's own paint: throttled, and the last output the pane produces
vi.advanceTimersByTime(5000);
expect(writes[0]).toBe(TRUST_KEY_DOWN);
});
it('cancels a deferred read when the session is stopped', async () => {
vi.useFakeTimers();
// DELETE goes through stop(), and a read deferred just before it must not outlive it.
let screen = '';
const { session, tick } = sessionShowing(() => screen);
tick();
screen = RENDERED_DIALOG_2_1_252;
const before = vi.getTimerCount();
tick(); // throttled, so a read is deferred
expect(vi.getTimerCount()).toBe(before + 1);
await session.stop(false);
expect(vi.getTimerCount()).toBe(0);
});
it('neither scans nor arms a timer once the session is stopped', async () => {
vi.useFakeTimers();
// Killing the pane produces output of its own, and the buffer tail still shows the
// dialog, so a deleted session went on "answering" it on a timer for several seconds.
const { session, tick } = sessionShowing(() => RENDERED_DIALOG_2_1_252);
await session.stop(false);
const log = vi.spyOn(console, 'log').mockImplementation(() => {});
tick();
tick(); // inside the throttle of the first
expect(vi.getTimerCount()).toBe(0);
expect(log.mock.calls.some(([line]) => String(line).includes('trust dialog'))).toBe(false);
log.mockRestore();
});
it('does not press Enter on a normal screen', () => {
vi.useFakeTimers();
const { writes, tick } = sessionShowing(() => RENDERED_MAIN_UI);