Fix xterm clipping; move mic + Jump to Current into status bar #7
Reference in New Issue
Block a user
Delete Branch "terminal-layout-statusbar"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Terminal layout fixes for the xterm pane, plus relocating two floating overlay controls into the status bar.
Changes
term.open()mounts into, which xterm'sFitAddonalso measures — so the computed grid overhung the padding and the rightmost column / bottom row got clipped (visible as text sliced mid-character at the window edge). Padding now lives on a wrapper<div>; the xterm host fills that wrapper's content box with no padding of its own.useSTTinstance perTerminalViewrendered a floating bottom-left button. Now a singleuseSTTbound to the active session lives inApp, and the mic renders inline inStatusBar.Ctrl+Shift+Mis routed through the store (sttToggle) so the shortcut still toggles the active session's mic.TerminalViewsurfaces its scroll state (terminalAtBottom) and scroll action (scrollActiveToBottom) via the store; the status bar shows the control only when the active terminal is scrolled up.8px 12px 48px 16px→4px 8px 4px 8px) now that nothing floats over the terminal, so it claims as much area as possible.Testing
npm run build(tsc + vite) — cleannpx vitest run— 33 passed (the 7 reported errors are pre-existing, fromProjectCard.test.tsx'slistenmock, unrelated to this change)npx tauri build— compiled and produced the.deb/.rpmbundles successfully🤖 Generated with Claude Code
Automated code review (Claude agent)
Verdict: Largely correct. The zustand-function-storage pattern is used correctly, hook deps are sound, and background terminals cannot clobber the active one. One genuine behavioral regression around mid-recording tab switches, plus minor items.
Findings
1. [Major] STT transcript goes to whatever tab is active at stop time, not where recording started —
App.tsx+hooks/useSTT.tsA single
useSTT(activeSessionId ?? "", sendInput)lives inApp. The recording lifecycle does not reset whenactiveSessionIdchanges. Start recording in session A, switch to B, stop →stopRecordingcloses over the currentsessionId(B) and injects the transcript into terminal B. Regression vs. the old per-terminal instance.Fix: capture the target session at recording start (a
recordingSessionIdRefset instartRecording, used bystopRecordinginstead of the livesessionId). Keeps a single mic while pinning the transcript to the originating terminal.2. [Minor] Stale
scrollActiveToBottom/terminalAtBottomafter the active terminal unmounts —TerminalView.tsx, store defaultsThe registration effect only writes when
active(good), but nothing clears the store on close. After closing the last session,scrollActiveToBottomstill points at the disposed terminal's handler (termRef.currentis never reset to null in cleanup). Masked in practice becauseStatusBargates both controls behindactiveSessionId. A reset in the unmount path would be more robust.3. [Nit] Padding comment doesn't match the value —
TerminalView.tsxComment says "right side leaves a little room beside the scrollbar," but padding is symmetric
4px 8px 4px 8px.Confirmed correct
set({ sttToggle: fn })passes an object → shallow-merged and stored verbatim, not misinterpreted as a state updater. Correct.setSttToggleeffect deps[stt.toggle, setSttToggle]are right;stt.toggleidentity changes with STT state so the store always holds the latest. Read viagetState()at call time — no stale closure, no render loop.useSTT/SttButtonfully removed fromTerminalView; no leftover imports.containerRefnow has no padding; padding moved to wrapper.FitAddon+ResizeObservermeasure the host, so the grid no longer overhangs. Correct.StatusBarhides both controls when!activeSessionId; store defaults are safe no-ops.🤖 Generated with Claude Code
Review follow-up (commit
da7b7b9)All three findings addressed:
startRecordingnow captures the active session id intorecordingSessionIdRef;stopRecordinginjects the transcript via that ref instead of the livesessionId. Switching tabs mid-recording no longer misroutes the transcript — it lands in the terminal where recording began. (startRecordingdeps gainedsessionId;stopRecordingno longer depends on it.)termRef.currentis now nulled on dispose, and an unmount effect clearsterminalAtBottom/scrollActiveToBottomwhen the active terminal is closed (guarded by anactiveRef, so tab switches — which don't unmount — are unaffected and the newly-active terminal's effect re-writes fresh values after).4px 8pxgutter.Verified:
tscclean,vitest33 passed,vite buildclean.