MCPcopy Create free account
hub / github.com/claude-code-best/claude-code / useReplBridge

Function useReplBridge

src/hooks/useReplBridge.tsx:72–918  ·  view source on GitHub ↗
(
  messages: Message[],
  setMessages: (action: React.SetStateAction<Message[]>) => void,
  abortControllerRef: React.RefObject<AbortController | null>,
  commands: readonly Command[],
  mainLoopModel: string,
)

Source from the content-addressed store, hash-verified

70 * Inbound messages from claude.ai are injected into the REPL via queuedCommands.
71 */
72export function useReplBridge(
73 messages: Message[],
74 setMessages: (action: React.SetStateAction<Message[]>) => void,
75 abortControllerRef: React.RefObject<AbortController | null>,
76 commands: readonly Command[],
77 mainLoopModel: string,
78): { sendBridgeResult: () => void } {
79 const handleRef = useRef<ReplBridgeHandle | null>(null);
80 const teardownPromiseRef = useRef<Promise<void> | undefined>(undefined);
81 const lastWrittenIndexRef = useRef(0);
82 const pendingResultAfterFlushRef = useRef(false);
83 const transcriptResetPendingRef = useRef(false);
84 // Tracks UUIDs already flushed as initial messages. Persists across
85 // bridge reconnections so Bridge #2+ only sends new messages — sending
86 // duplicate UUIDs causes the server to kill the WebSocket.
87 const flushedUUIDsRef = useRef(new Set<string>());
88 const failureTimeoutRef = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);
89 // Persists across effect re-runs (unlike the effect's local state). Reset
90 // only on successful init. Hits MAX_CONSECUTIVE_INIT_FAILURES → fuse blown
91 // for the session, regardless of replBridgeEnabled re-toggling.
92 const consecutiveFailuresRef = useRef(0);
93 const setAppState = useSetAppState();
94 const commandsRef = useRef(commands);
95 commandsRef.current = commands;
96 const mainLoopModelRef = useRef(mainLoopModel);
97 mainLoopModelRef.current = mainLoopModel;
98 const messagesRef = useRef(messages);
99 messagesRef.current = messages;
100 const store = useAppStateStore();
101 const { addNotification } = useNotifications();
102 const replBridgeEnabledRaw = useAppState(s => s.replBridgeEnabled);
103 const replBridgeEnabled = feature('BRIDGE_MODE') ? replBridgeEnabledRaw : false;
104 const replBridgeConnectedRaw = useAppState(s => s.replBridgeConnected);
105 const replBridgeConnected = feature('BRIDGE_MODE') ? replBridgeConnectedRaw : false;
106 const replBridgeSessionActiveRaw = useAppState(s => s.replBridgeSessionActive);
107 const replBridgeSessionActive = feature('BRIDGE_MODE') ? replBridgeSessionActiveRaw : false;
108 const replBridgeOutboundOnlyRaw = useAppState(s => s.replBridgeOutboundOnly);
109 const replBridgeOutboundOnly = feature('BRIDGE_MODE') ? replBridgeOutboundOnlyRaw : false;
110 const replBridgeInitialNameRaw = useAppState(s => s.replBridgeInitialName);
111 const replBridgeInitialName = feature('BRIDGE_MODE') ? replBridgeInitialNameRaw : undefined;
112
113 // Initialize/teardown bridge when enabled state changes.
114 // Passes current messages as initialMessages so the remote session
115 // starts with the existing conversation context (e.g. from /bridge).
116 useEffect(() => {
117 // feature() check must use positive pattern for dead code elimination —
118 // negative pattern (if (!feature(...)) return) does NOT eliminate
119 // dynamic imports below.
120 if (feature('BRIDGE_MODE')) {
121 if (!replBridgeEnabled) return;
122
123 const outboundOnly = replBridgeOutboundOnly;
124 function notifyBridgeFailed(detail?: string): void {
125 if (outboundOnly) return;
126 addNotification({
127 key: 'bridge-failed',
128 jsx: (
129 <>

Callers 1

REPLFunction · 0.85

Calls 15

useSetAppStateFunction · 0.85
useAppStateStoreFunction · 0.85
useNotificationsFunction · 0.85
useAppStateFunction · 0.85
notifyBridgeFailedFunction · 0.85
isAssistantModeFunction · 0.85
initReplBridgeFunction · 0.85
setReplBridgeHandleFunction · 0.85
getRemoteSessionUrlFunction · 0.85
buildBridgeConnectUrlFunction · 0.85

Tested by

no test coverage detected