MCPcopy Create free account
hub / github.com/ShipSecAI/studio / useTerminalStream

Function useTerminalStream

frontend/src/hooks/useTerminalStream.ts:51–300  ·  view source on GitHub ↗
(options: UseTerminalStreamOptions)

Source from the content-addressed store, hash-verified

49}
50
51export function useTerminalStream(options: UseTerminalStreamOptions): UseTerminalStreamResult {
52 const { runId, nodeId, stream = 'pty', autoConnect = true } = options;
53 const [chunks, setChunks] = useState<TerminalChunk[]>([]);
54 const [isHydrating, setIsHydrating] = useState(false);
55 const [isStreaming, setIsStreaming] = useState(false);
56 const [error, setError] = useState<string | null>(null);
57 const [mode, setMode] = useState<TerminalStreamMode>('idle');
58 const cursorRef = useRef<string | null>(null);
59 const eventSourceRef = useRef<EventSource | null>(null);
60 const pendingRunKey = `${runId ?? 'none'}:${nodeId}:${stream}`;
61
62 const closeStream = useCallback(() => {
63 eventSourceRef.current?.close();
64 eventSourceRef.current = null;
65 setIsStreaming(false);
66 }, []);
67
68 const hydrate = useCallback(
69 async (cursorOverride?: string | null) => {
70 if (!runId) {
71 return;
72 }
73 setIsHydrating(true);
74 setError(null);
75 try {
76 const result = await api.executions.getTerminalChunks(runId, {
77 nodeRef: nodeId,
78 stream,
79 cursor: cursorOverride ?? undefined,
80 });
81 cursorRef.current = result.cursor ?? null;
82 setChunks((prev) =>
83 cursorOverride ? mergeTerminalChunks(prev, result.chunks) : result.chunks,
84 );
85 if (result.chunks.length > 0) {
86 setMode(autoConnect ? 'live' : 'replay');
87 }
88 } catch (err) {
89 console.error('[useTerminalStream] hydrate failed', err);
90 setError(err instanceof Error ? err.message : 'Failed to load terminal output');
91 } finally {
92 setIsHydrating(false);
93 }
94 },
95 [runId, nodeId, stream, autoConnect],
96 );
97
98 const fetchMore = useCallback(async () => {
99 if (!runId || !cursorRef.current) {
100 return;
101 }
102 try {
103 const result = await api.executions.getTerminalChunks(runId, {
104 nodeRef: nodeId,
105 stream,
106 cursor: cursorRef.current,
107 });
108 if (result.chunks.length === 0) {

Callers 1

Calls 5

mergeTerminalChunksFunction · 0.85
connectFunction · 0.85
errorMethod · 0.80
debugMethod · 0.80
closeMethod · 0.45

Tested by

no test coverage detected