fix: emit needsRefresh after OpenCode TUI stabilizes

After the 3s TUI stabilization timeout, emit needsRefresh so the
client fetches the full terminal buffer. Without this, the terminal
appears empty until the user manually refreshes or switches tabs.

Wire needsRefresh as a proper session listener in server.ts with
cleanup in both removal paths to prevent memory leaks.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
arkon
2026-02-26 13:03:28 +01:00
co-authored by Claude Opus 4.6
parent 5ad0e7f9b4
commit 2e3a08fad2
2 changed files with 11 additions and 0 deletions
+2
View File
@@ -986,9 +986,11 @@ export class Session extends EventEmitter {
// OpenCode uses Bubble Tea TUI — no ❯ prompt to detect.
// Wait for TUI to stabilize (output stops changing), then mark ready.
// Don't clear the buffer — the TUI's initial render IS the useful content.
// Emit needsRefresh so the client fetches the full buffer once the TUI has rendered.
this._promptCheckTimeout = setTimeout(() => {
this._promptCheckTimeout = null;
this._status = 'idle';
this.emit('needsRefresh');
}, 3000);
} else {
// Claude mode: wait for ❯ prompt
+9
View File
@@ -307,6 +307,7 @@ function getOrCreateSelfSignedCert(): { key: string; cert: string } {
interface SessionListenerRefs {
terminal: (data: string) => void;
clearTerminal: () => void;
needsRefresh: () => void;
message: (msg: ClaudeMessage) => void;
error: (error: string) => void;
completion: (result: string, cost: number) => void;
@@ -4169,6 +4170,7 @@ NOW: Generate the implementation plan for the task above. Think step by step.`;
if (listeners) {
session.off('terminal', listeners.terminal);
session.off('clearTerminal', listeners.clearTerminal);
session.off('needsRefresh', listeners.needsRefresh);
session.off('message', listeners.message);
session.off('error', listeners.error);
session.off('completion', listeners.completion);
@@ -4238,6 +4240,11 @@ NOW: Generate the implementation plan for the task above. Think step by step.`;
this.broadcast('session:clearTerminal', { id: session.id });
},
needsRefresh: () => {
// Tell clients to reload the terminal buffer (e.g., after OpenCode TUI stabilizes)
this.broadcast('session:needsRefresh', { id: session.id });
},
message: (msg: ClaudeMessage) => {
this.broadcast('session:message', { id: session.id, message: msg });
},
@@ -4436,6 +4443,7 @@ NOW: Generate the implementation plan for the task above. Think step by step.`;
// Attach all listeners to the session
session.on('terminal', listeners.terminal);
session.on('clearTerminal', listeners.clearTerminal);
session.on('needsRefresh', listeners.needsRefresh);
session.on('message', listeners.message);
session.on('error', listeners.error);
session.on('completion', listeners.completion);
@@ -5611,6 +5619,7 @@ NOW: Generate the implementation plan for the task above. Think step by step.`;
if (listeners) {
session.off('terminal', listeners.terminal);
session.off('clearTerminal', listeners.clearTerminal);
session.off('needsRefresh', listeners.needsRefresh);
session.off('message', listeners.message);
session.off('error', listeners.error);
session.off('completion', listeners.completion);