Alex Severyanov  ·  2026-03-25

terminal.ts

 1import { writable, get } from 'svelte/store';
 2
 3export const terminalOpen = writable(false);
 4export const terminalHeight = writable(300);
 5
 6// Pending review to send once WS connects
 7let pendingReview = false;
 8
 9function getWsInstance(): WebSocket | null {
10	if (typeof globalThis === 'undefined') return null;
11	return (globalThis as any).__lcr_ws || null;
12}
13
14export function getWs(): WebSocket | null {
15	return getWsInstance();
16}
17
18export function hasPendingReview(): boolean {
19	if (pendingReview) {
20		pendingReview = false;
21		return true;
22	}
23	return false;
24}
25
26export async function sendReviewToClaude(): Promise<{ success: boolean; message: string }> {
27	const ws = getWsInstance();
28
29	// If WS is already connected, send immediately
30	if (ws?.readyState === WebSocket.OPEN) {
31		terminalOpen.set(true);
32		ws.send(JSON.stringify({ type: 'review' }));
33		return { success: true, message: 'Review sent.' };
34	}
35
36	// Otherwise, open the terminal and queue the review
37	// The TerminalPanel will check for pending review on WS connect
38	pendingReview = true;
39	terminalOpen.set(true);
40	return { success: true, message: 'Opening terminal...' };
41}
42
43export async function stopClaudeSession(): Promise<void> {
44	const ws = getWsInstance();
45	if (ws?.readyState === WebSocket.OPEN) {
46		ws.send(JSON.stringify({ type: 'stop' }));
47	}
48}
49
50export async function restartSession(): Promise<void> {
51	const ws = getWsInstance();
52	if (ws?.readyState === WebSocket.OPEN) {
53		ws.send(JSON.stringify({ type: 'restart' }));
54	}
55}
56
57export function toggleTerminal() {
58	terminalOpen.update((v) => !v);
59}
60
61// Persist terminal height to localStorage
62if (typeof window !== 'undefined') {
63	const saved = localStorage.getItem('lcr-terminal-height');
64	if (saved) terminalHeight.set(Number(saved));
65	terminalHeight.subscribe((h) => localStorage.setItem('lcr-terminal-height', String(h)));
66}