What happened?
Exiting Pi in regular mode can leave the shell cursor invisible when an extension closes an overlay during session_shutdown. pi -ne exits normally without an extension; the bug reproduces with only the minimal extension below. Related: #9419 (fullscreen report, auto-closed).
Captured on macOS in a 140×40 PTY: stop() shows the cursor, then shutdown cleanup calls hideOverlay(), which hides it again. Final controls: ESC[?25h ESC[?2004l ESC[?25l. Rendering has stopped, so nothing restores the cursor. The shell needs printf '\033[?25h' to recover.
Steps to reproduce
Save as cursor-repro.ts:
import type { ExtensionAPI } from '@earendil-works/pi-coding-agent';
export default function (pi: ExtensionAPI) {
let close: (() => void) | undefined;
pi.on('session_start', (_event, ctx) => {
void ctx.ui.custom((_tui, _theme, _keys, done) => {
close = () => done(undefined);
return { render: () => ['overlay'], invalidate() {} };
}, { overlay: true, overlayOptions: { nonCapturing: true } });
});
pi.on('session_shutdown', () => close?.());
}
Run pi --no-session -ne -e ./cursor-repro.ts --tui-mode regular, wait for startup, then /quit.
Expected behavior
Overlay cleanup after TUI shutdown should leave the shell cursor visible. In a temporary Pi 0.85.1 installation, guarding the empty-stack hideCursor() calls in hideOverlay() and the overlay handle's hide() with !this.stopped fixed the minimal repro. No upstream PR submitted.
Version
Minimal repro verified on 0.85.1. The same shutdown behavior was also observed on 0.87.1 with an overlay-owning extension.
What happened?
Exiting Pi in regular mode can leave the shell cursor invisible when an extension closes an overlay during
session_shutdown.pi -neexits normally without an extension; the bug reproduces with only the minimal extension below. Related: #9419 (fullscreen report, auto-closed).Captured on macOS in a 140×40 PTY:
stop()shows the cursor, then shutdown cleanup callshideOverlay(), which hides it again. Final controls:ESC[?25h ESC[?2004l ESC[?25l. Rendering has stopped, so nothing restores the cursor. The shell needsprintf '\033[?25h'to recover.Steps to reproduce
Save as
cursor-repro.ts:Run
pi --no-session -ne -e ./cursor-repro.ts --tui-mode regular, wait for startup, then/quit.Expected behavior
Overlay cleanup after TUI shutdown should leave the shell cursor visible. In a temporary Pi 0.85.1 installation, guarding the empty-stack
hideCursor()calls inhideOverlay()and the overlay handle'shide()with!this.stoppedfixed the minimal repro. No upstream PR submitted.Version
Minimal repro verified on 0.85.1. The same shutdown behavior was also observed on 0.87.1 with an overlay-owning extension.