diff --git a/apps/web/src/components/panes/TerminalPane.tsx b/apps/web/src/components/panes/TerminalPane.tsx index 8f8af6e..f765eb7 100644 --- a/apps/web/src/components/panes/TerminalPane.tsx +++ b/apps/web/src/components/panes/TerminalPane.tsx @@ -184,8 +184,35 @@ export function TerminalPane({ sessionId, paneId, label, active = false }: Props term.loadAddon(search); term.loadAddon(new WebLinksAddon()); term.open(container); + // v1.10.4 gap fix: bypass FitAddon's proposeDimensions(), which subtracts + // a phantom scrollbar width even when CSS hides the scrollbar. Compute + // cols/rows directly from the host's clientWidth/clientHeight divided by + // the renderer's reported cell size. Falls back to FitAddon if cell + // metrics aren't ready yet (e.g. on very first mount). + const fitFull = (): void => { + const host = containerRef.current; + const t = termRef.current; + if (!host || !t) return; + if (!t.element || !(t.element as HTMLElement).offsetParent) return; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const core: any = (t as any)._core; + const cellW: number | undefined = core?._renderService?.dimensions?.css?.cell?.width; + const cellH: number | undefined = core?._renderService?.dimensions?.css?.cell?.height; + if (!cellW || !cellH || cellW <= 0 || cellH <= 0) { + try { fit.fit(); } catch { /* not ready */ } + return; + } + const cols = Math.max(2, Math.floor(host.clientWidth / cellW)); + const rows = Math.max(1, Math.floor(host.clientHeight / cellH)); + if (cols !== t.cols || rows !== t.rows) { + try { t.resize(cols, rows); } catch { /* ignore */ } + } + }; + try { - fit.fit(); + fitFull(); + // v1.10.4: also push initial size to PTY so opencode/bash get correct cols/rows + api.terminals.resize(sessionId, paneId, term.cols, term.rows).catch(() => {}); } catch { /* container not yet sized */ } @@ -199,7 +226,8 @@ export function TerminalPane({ sessionId, paneId, label, active = false }: Props .then(() => { if (disposed) return; try { - fit.fit(); + fitFull(); + api.terminals.resize(sessionId, paneId, term.cols, term.rows).catch(() => {}); } catch { /* ignore */ } @@ -363,7 +391,7 @@ export function TerminalPane({ sessionId, paneId, label, active = false }: Props const fireResize = (): void => { try { - fit.fit(); + fitFull(); } catch { return; }