Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 21 additions & 1 deletion frontend/src/components/panels/TerminalPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ export const TerminalPanel: React.FC<TerminalPanelProps> = React.memo(({ panel,
const terminalState = panel.state?.customState as TerminalPanelState | undefined;
const isCliPanel = !!terminalState?.isCliPanel;
const [isCliReady, setIsCliReady] = useState(!!terminalState?.isCliReady);
const isCliPanelRef = useRef(isCliPanel);

// ptyId for the current PTY behind this panel, delivered via
// `terminal:ptyReady` when spawned through the ptyHost UtilityProcess.
Expand All @@ -119,6 +120,10 @@ export const TerminalPanel: React.FC<TerminalPanelProps> = React.memo(({ panel,

// Sync isCliReady from panel prop when it changes (e.g. backend persisted isCliReady
// before this component subscribed to the IPC event, or panel state was updated externally)
useEffect(() => {
isCliPanelRef.current = isCliPanel;
}, [isCliPanel]);

useEffect(() => {
if (terminalState?.isCliReady && !isCliReady) {
setIsCliReady(true);
Expand Down Expand Up @@ -822,6 +827,21 @@ export const TerminalPanel: React.FC<TerminalPanelProps> = React.memo(({ panel,
// The "[Image] " prefix we used to add actually broke the parser's
// path-detection — on Windows+WSL it caused Claude to cache the file but
// never attach it to the API call (see commit 7b76ee5).
const pasteText = (text: string) => {
if (!terminal) return;
const shouldProtectMultilinePaste = isCliPanelRef.current && !tuiActiveRef.current && /[\r\n]/.test(text);
if (shouldProtectMultilinePaste) {
window.electronAPI.invoke(
'terminal:input',
panel.id,
text.replace(/\r\n|\r|\n/g, '\x1b\r'),
);
return;
}

terminal.paste(text);
};

const handlePaste = (e: ClipboardEvent) => {
// Step 1: Check for images in browser clipboard (works on native Windows/macOS)
const items = e.clipboardData?.items;
Expand Down Expand Up @@ -895,7 +915,7 @@ export const TerminalPanel: React.FC<TerminalPanelProps> = React.memo(({ panel,

// No image found — forward the text content xterm would have pasted.
if (text && !disposed && terminal) {
terminal.paste(text);
pasteText(text);
}
})();
};
Expand Down
Loading