diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index 5517421ce..ebc52254c 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -506,7 +506,7 @@ pub fn run() { && !daemon_mode && !daemon_foreground_requested() && !cfg!(debug_assertions) // Always use internal supervisor in debug builds - && std::env::var("ALPHAHUMAN_DAEMON_INTERNAL").is_err() // Allow override via env var + && std::env::var("ALPHAHUMAN_DAEMON_INTERNAL").unwrap_or("false".to_string()) != "true" // Allow override via env var { // On macOS, start external LaunchAgent service for background daemon tauri::async_runtime::spawn(async move { diff --git a/src/providers/SocketProvider.tsx b/src/providers/SocketProvider.tsx index 3ea197788..dfbe2edf8 100644 --- a/src/providers/SocketProvider.tsx +++ b/src/providers/SocketProvider.tsx @@ -26,11 +26,13 @@ import { * In web mode: uses the frontend Socket.io client directly. */ const SocketProvider = ({ children }: { children: React.ReactNode }) => { + console.log('[SocketProvider] Component mounting/re-rendering'); const token = useAppSelector(state => state.auth.token); const socketStatus = useAppSelector(selectSocketStatus); const previousTokenRef = useRef(null); const tauriListenersSetup = useRef(false); const usesRustSocket = isTauri(); + console.log('[SocketProvider] usesRustSocket:', usesRustSocket, 'isTauri():', isTauri()); // Setup daemon lifecycle management in Tauri mode const daemonLifecycle = useDaemonLifecycle(); @@ -55,13 +57,40 @@ const SocketProvider = ({ children }: { children: React.ReactNode }) => { // Setup Tauri event listeners once useEffect(() => { + console.log('[SocketProvider] useEffect triggered, usesRustSocket:', usesRustSocket, 'tauriListenersSetup:', tauriListenersSetup.current); + if (usesRustSocket && !tauriListenersSetup.current) { - setupTauriSocketListeners(); + console.log('[SocketProvider] Condition met - calling setupTauriSocketListeners()'); + console.log('[SocketProvider] About to call setupTauriSocketListeners()'); + + // Set this immediately to prevent multiple calls tauriListenersSetup.current = true; + + setupTauriSocketListeners() + .then(() => { + console.log('[SocketProvider] setupTauriSocketListeners() completed successfully'); + }) + .catch((error) => { + console.error('[SocketProvider] setupTauriSocketListeners() failed:', error); + console.error('[SocketProvider] Error details:', { + message: error?.message, + stack: error?.stack, + toString: error?.toString(), + }); + // Reset flag on failure so it can retry + tauriListenersSetup.current = false; + }); + } else if (usesRustSocket && tauriListenersSetup.current) { + console.log('[SocketProvider] Tauri listeners already set up, skipping'); + } else if (!usesRustSocket) { + console.log('[SocketProvider] Not using Rust socket, skipping Tauri listener setup'); + } else { + console.log('[SocketProvider] Unexpected condition - usesRustSocket:', usesRustSocket, 'tauriListenersSetup.current:', tauriListenersSetup.current); } return () => { if (usesRustSocket && tauriListenersSetup.current) { + console.log('[SocketProvider] Cleaning up Tauri socket listeners'); cleanupTauriSocketListeners(); tauriListenersSetup.current = false; } diff --git a/src/services/daemonHealthService.ts b/src/services/daemonHealthService.ts index 9c1cc97ea..e619c0d26 100644 --- a/src/services/daemonHealthService.ts +++ b/src/services/daemonHealthService.ts @@ -25,7 +25,9 @@ export class DaemonHealthService { * Should be called once when the app starts in Tauri mode. */ async setupHealthListener(): Promise { + console.log('[DaemonHealth] setupHealthListener() called - starting setup process'); try { + console.log('[DaemonHealth] About to call listen() for alphahuman:health event'); console.log('[DaemonHealth] Setting up alphahuman:health event listener'); this.healthEventListener = await listen('alphahuman:health', event => { @@ -39,9 +41,12 @@ export class DaemonHealthService { console.warn('[DaemonHealth] Failed to parse health snapshot:', event.payload); } }); + console.log('[DaemonHealth] alphahuman:health listener created successfully'); // Start initial timeout + console.log('[DaemonHealth] Starting health timeout'); this.startHealthTimeout(); + console.log('[DaemonHealth] Health timeout started'); console.log('[DaemonHealth] Health listener setup complete'); return this.healthEventListener; diff --git a/src/utils/tauriSocket.ts b/src/utils/tauriSocket.ts index 46ef332a7..717f78837 100644 --- a/src/utils/tauriSocket.ts +++ b/src/utils/tauriSocket.ts @@ -24,7 +24,11 @@ import { BACKEND_URL } from './config'; // Check if we're running in Tauri export const isTauri = (): boolean => { - return coreIsTauri(); + const isTauriEnv = coreIsTauri(); + const windowTauri = typeof window !== 'undefined' ? !!window.__TAURI__ : 'undefined'; + const userAgent = typeof navigator !== 'undefined' ? navigator.userAgent : 'undefined'; + console.log('[TauriSocket] isTauri() check:', isTauriEnv, 'window.__TAURI__:', windowTauri, 'userAgent:', userAgent); + return isTauriEnv; }; // --------------------------------------------------------------------------- @@ -126,10 +130,17 @@ function getSocketUserId(): string { * This should be called once when the app starts in Tauri mode. */ export async function setupTauriSocketListeners(): Promise { - if (!isTauri()) return; + console.log('[TauriSocket] setupTauriSocketListeners() called'); + if (!isTauri()) { + console.log('[TauriSocket] Not in Tauri environment, returning early'); + return; + } + console.log('[TauriSocket] In Tauri environment, proceeding with listener setup'); try { + console.log('[TauriSocket] Starting listener setup sequence'); // Listen for Rust socket state changes (Phase 2 — primary) + console.log('[TauriSocket] Setting up runtime:socket-state-changed listener'); unlistenSocketState = await listen<{ status: string; socket_id: string | null }>( 'runtime:socket-state-changed', event => { @@ -158,14 +169,18 @@ export async function setupTauriSocketListeners(): Promise { } } ); + console.log('[TauriSocket] runtime:socket-state-changed listener setup complete'); // Listen for forwarded server events + console.log('[TauriSocket] Setting up server:event listener'); unlistenServerEvent = await listen<{ event: string; data: unknown }>('server:event', event => { console.log('[TauriSocket] Server event:', event.payload.event, event.payload.data); // Future: dispatch to specific handlers based on event type }); + console.log('[TauriSocket] server:event listener setup complete'); // Legacy: Listen for connect requests from Rust (backwards compat) + console.log('[TauriSocket] Setting up legacy socket:should_connect listener'); unlistenConnect = await listen<{ backendUrl: string; token: string }>( 'socket:should_connect', async event => { @@ -174,15 +189,20 @@ export async function setupTauriSocketListeners(): Promise { void event; } ); + console.log('[TauriSocket] socket:should_connect listener setup complete'); // Legacy: Listen for disconnect requests from Rust + console.log('[TauriSocket] Setting up legacy socket:should_disconnect listener'); unlistenDisconnect = await listen('socket:should_disconnect', async () => { console.log('[TauriSocket] Legacy disconnect request (ignored — using Rust socket)'); // No-op: Rust socket handles disconnection now }); + console.log('[TauriSocket] socket:should_disconnect listener setup complete'); // Setup daemon health monitoring + console.log('[TauriSocket] About to setup daemon health listener'); unlistenDaemonHealth = await daemonHealthService.setupHealthListener(); + console.log('[TauriSocket] Daemon health listener setup result:', unlistenDaemonHealth); console.log('[TauriSocket] Event listeners setup complete'); } catch (error) {