diff --git a/package.json b/package.json index c970968..c4895e9 100644 --- a/package.json +++ b/package.json @@ -82,7 +82,7 @@ "zod": "^4.1.13" }, "devDependencies": { - "@eslint/eslintrc": "^3", + "@eslint/eslintrc": "^3.3.3", "@tailwindcss/postcss": "^4", "@types/node": "^20", "@types/react": "^19", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 80e9eeb..a039dd0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -175,7 +175,7 @@ importers: version: 4.1.13 devDependencies: '@eslint/eslintrc': - specifier: ^3 + specifier: ^3.3.3 version: 3.3.3 '@tailwindcss/postcss': specifier: ^4 diff --git a/src/features/john-gpt/components/ChatInput.tsx b/src/features/john-gpt/components/ChatInput.tsx index 32d1863..9b0981f 100644 --- a/src/features/john-gpt/components/ChatInput.tsx +++ b/src/features/john-gpt/components/ChatInput.tsx @@ -37,7 +37,7 @@ export const ChatInput: React.FC = ({ input.onchange = (e) => { const file = (e.target as HTMLInputElement).files?.[0]; if (file) { - console.log('File selected:', file); + // console.log('File selected:', file); // TODO: Handle file upload } }; diff --git a/src/features/john-gpt/components/ChatMessages.tsx b/src/features/john-gpt/components/ChatMessages.tsx index 7009f90..bd6b518 100644 --- a/src/features/john-gpt/components/ChatMessages.tsx +++ b/src/features/john-gpt/components/ChatMessages.tsx @@ -367,7 +367,7 @@ export const ChatMessages = React.memo(function ChatMessages({ {message.parts?.map((part: any, index: number) => { // AI SDK returns tool calls as parts with type 'tool-{toolName}' if (part.type === 'tool-navigate' && part.state === 'output-available') { - console.log('🚀 [ChatMessages] Found tool-navigate part:', part); + // console.log('🚀 [ChatMessages] Found tool-navigate part:', part); const result = part.output; if (result.action === 'showLoginComponent') { @@ -408,7 +408,7 @@ export const ChatMessages = React.memo(function ChatMessages({ // Handle unified goTo tool if (part.type === 'tool-goTo' && part.state === 'output-available') { - console.log('🚀 [ChatMessages] Found tool-goTo part:', part); + // console.log('🚀 [ChatMessages] Found tool-goTo part:', part); const result = part.output; if (result.action === 'showLoginComponent') { diff --git a/src/features/john-gpt/components/ChatView.tsx b/src/features/john-gpt/components/ChatView.tsx index 2b3f8ea..6a12eb6 100644 --- a/src/features/john-gpt/components/ChatView.tsx +++ b/src/features/john-gpt/components/ChatView.tsx @@ -52,7 +52,7 @@ export function ChatView({ user, className, conversationId: conversationIdProp, // Small delay to allow navigation to complete first const timeoutId = setTimeout(() => { if (isFollowMeActive) { - console.log('[ChatView] Clearing follow-me state - arrived at full JohnGPT page'); + // console.log('[ChatView] Clearing follow-me state - arrived at full JohnGPT page'); deactivateFollowMe(); } }, 100); @@ -129,7 +129,7 @@ export function ChatView({ user, className, conversationId: conversationIdProp, if (!isModelInitialized) { const stored = localStorage.getItem('johngpt-widget-model'); if (stored) { - console.log('[ChatView] Restored model from localStorage:', stored); + // console.log('[ChatView] Restored model from localStorage:', stored); setSelectedModelId(stored); fetchModelName(stored); } @@ -159,7 +159,7 @@ export function ChatView({ user, className, conversationId: conversationIdProp, if (conversation && conversation.messages.length > 0) { // Hydrate messages into chat setMessages(conversation.messages as any); - console.log('[ChatView] Loaded conversation:', internalConversationId, conversation.messages.length, 'messages'); + // console.log('[ChatView] Loaded conversation:', internalConversationId, conversation.messages.length, 'messages'); } } catch (error) { console.error('[ChatView] Failed to load conversation:', error); @@ -177,13 +177,13 @@ export function ChatView({ user, className, conversationId: conversationIdProp, const loadImportSession = async () => { try { - console.log('[ChatView] Importing session:', importSessionId); + // console.log('[ChatView] Importing session:', importSessionId); const session = await dbSyncManager.loadConversation(importSessionId, { isWidget: true }); if (session && session.messages.length > 0) { setMessages(session.messages as any); setIsImportBannerVisible(true); - console.log('[ChatView] Imported widget session with', session.messages.length, 'messages'); + // console.log('[ChatView] Imported widget session with', session.messages.length, 'messages'); } } catch (error) { console.error('[ChatView] Failed to import session:', error); @@ -251,7 +251,7 @@ export function ChatView({ user, className, conversationId: conversationIdProp, const newId = crypto.randomUUID(); setInternalConversationId(newId); currentConversationId = newId; - console.log('[ChatView] Generated new conversation ID:', newId); + // console.log('[ChatView] Generated new conversation ID:', newId); } // Send message first (don't block on navigation) diff --git a/src/features/john-gpt/components/ConversationSidebar.tsx b/src/features/john-gpt/components/ConversationSidebar.tsx index 2b9d9c3..288cd32 100644 --- a/src/features/john-gpt/components/ConversationSidebar.tsx +++ b/src/features/john-gpt/components/ConversationSidebar.tsx @@ -90,7 +90,7 @@ export function ConversationSidebar({ user, isDriveConnected, className, activeC // Subscribe to ANY list changes (Created, Saved, Deleted) const unsubscribe = dbSyncManager.onListChange(() => { - console.log('[ConversationSidebar] List changed, refreshing...'); + // console.log('[ConversationSidebar] List changed, refreshing...'); fetchConversations(); }); @@ -198,7 +198,7 @@ export function ConversationSidebar({ user, isDriveConnected, className, activeC // Use DB Sync Manager to delete (Handles Local + API + Drive) await dbSyncManager.deleteConversation(deletingId); - console.log('[ConversationSidebar] Deleted conversation:', deletingId); + // console.log('[ConversationSidebar] Deleted conversation:', deletingId); } catch (error) { console.error('[ConversationSidebar] Delete failed:', error); } finally { diff --git a/src/features/john-gpt/components/JohnGPTDialog.tsx b/src/features/john-gpt/components/JohnGPTDialog.tsx index e0c2e4c..e700989 100644 --- a/src/features/john-gpt/components/JohnGPTDialog.tsx +++ b/src/features/john-gpt/components/JohnGPTDialog.tsx @@ -93,14 +93,14 @@ function JohnGPTDialogContent({ open, onOpenChange, user, followMeConversationId try { const conversation = await dbSyncManager.loadConversation(followMeConversationId); if (conversation && conversation.messages.length > 0) { - console.log('[JohnGPTDialog] Loading follow-me conversation:', followMeConversationId, 'with', conversation.messages.length, 'messages'); + // console.log('[JohnGPTDialog] Loading follow-me conversation:', followMeConversationId, 'with', conversation.messages.length, 'messages'); setMessages(conversation.messages as any); } } catch (error) { console.error('[JohnGPTDialog] Failed to load follow-me conversation:', error); } } else if (!isPersistenceLoading && initialMessages.length > 0 && messages.length === 0) { - console.log('[JohnGPTDialog] Loading', initialMessages.length, 'messages from IndexedDB'); + // console.log('[JohnGPTDialog] Loading', initialMessages.length, 'messages from IndexedDB'); setMessages(initialMessages); } }; @@ -140,7 +140,7 @@ function JohnGPTDialogContent({ open, onOpenChange, user, followMeConversationId React.useEffect(() => { const storedModelId = localStorage.getItem('johngpt-widget-model'); if (storedModelId) { - console.log('[JohnGPTDialog] Inherited model from localStorage:', storedModelId); + // console.log('[JohnGPTDialog] Inherited model from localStorage:', storedModelId); setInheritedModelId(storedModelId); } }, []); diff --git a/src/features/john-gpt/context/ActiveChatContext.tsx b/src/features/john-gpt/context/ActiveChatContext.tsx index 2817868..930b7ea 100644 --- a/src/features/john-gpt/context/ActiveChatContext.tsx +++ b/src/features/john-gpt/context/ActiveChatContext.tsx @@ -47,7 +47,7 @@ export function ActiveChatProvider({ children }: { children: React.ReactNode }) if (stored) { const parsed = JSON.parse(stored) as ActiveChatState; setState(parsed); - console.log('[ActiveChatContext] Hydrated follow-me state:', parsed); + // console.log('[ActiveChatContext] Hydrated follow-me state:', parsed); } } catch (error) { console.warn('[ActiveChatContext] Failed to hydrate state:', error); @@ -70,7 +70,7 @@ export function ActiveChatProvider({ children }: { children: React.ReactNode }) }, [state]); const activateFollowMe = useCallback((conversationId: string, userId: string) => { - console.log('[ActiveChatContext] Activating follow-me mode:', { conversationId, userId }); + // console.log('[ActiveChatContext] Activating follow-me mode:', { conversationId, userId }); setState({ conversationId, isFollowMeMode: true, @@ -79,7 +79,7 @@ export function ActiveChatProvider({ children }: { children: React.ReactNode }) }, []); const deactivateFollowMe = useCallback(() => { - console.log('[ActiveChatContext] Deactivating follow-me mode'); + // console.log('[ActiveChatContext] Deactivating follow-me mode'); setState({ conversationId: null, isFollowMeMode: false, diff --git a/src/features/john-gpt/context/ChatActionContext.tsx b/src/features/john-gpt/context/ChatActionContext.tsx index d295fc1..5e29682 100644 --- a/src/features/john-gpt/context/ChatActionContext.tsx +++ b/src/features/john-gpt/context/ChatActionContext.tsx @@ -45,7 +45,7 @@ export function ChatActionProvider({ children }: { children: ReactNode }) { useEffect(() => { const spotlight = searchParams.get('spotlight'); if (spotlight) { - console.log('✨ [ChatActionContext] Spotlight param detected:', spotlight); + // console.log('✨ [ChatActionContext] Spotlight param detected:', spotlight); // Clean up the URL by removing the spotlight param const newUrl = new URL(window.location.href); @@ -97,7 +97,7 @@ export function ChatActionProvider({ children }: { children: ReactNode }) { }, []); const navigateTo = useCallback((url: string, options?: { isMobile?: boolean }) => { - console.log('🚀 [ChatActionContext] navigateTo called with:', url); + // console.log('🚀 [ChatActionContext] navigateTo called with:', url); const isMobile = options?.isMobile ?? (typeof window !== 'undefined' && window.innerWidth < 768); // Minimize chat to show the page being navigated to @@ -109,7 +109,7 @@ export function ChatActionProvider({ children }: { children: ReactNode }) { })); // Navigate to the URL - use router.push for client-side navigation (preserves state) - console.log('🚀 [ChatActionContext] Navigating to:', url); + // console.log('🚀 [ChatActionContext] Navigating to:', url); // Use requestAnimationFrame to ensure state updates settle before navigation requestAnimationFrame(() => { @@ -128,7 +128,7 @@ export function ChatActionProvider({ children }: { children: ReactNode }) { const scrollToSection = useCallback((sectionId: string) => { const element = document.getElementById(sectionId); if (element) { - console.log('✨ [ChatActionContext] Scrolling to section:', sectionId); + // console.log('✨ [ChatActionContext] Scrolling to section:', sectionId); // 1. Scroll to element element.scrollIntoView({ behavior: 'smooth', block: 'start' }); diff --git a/src/features/john-gpt/hooks/useBranchingChat.ts b/src/features/john-gpt/hooks/useBranchingChat.ts index 38f497b..41b0d02 100644 --- a/src/features/john-gpt/hooks/useBranchingChat.ts +++ b/src/features/john-gpt/hooks/useBranchingChat.ts @@ -51,7 +51,7 @@ export function useBranchingChat(options: UseBranchingChatOptions = {}) { const [currentMode, setCurrentMode] = useState(null); // 2. Initialize useChat with currentPath for navigation context - console.log('[useBranchingChat] Options received:', { body: options.body, api: options.api, currentPath: pathname }); + // console.log('[useBranchingChat] Options received:', { body: options.body, api: options.api, currentPath: pathname }); const chatHelpers = useChat({ ...options, @@ -76,7 +76,7 @@ export function useBranchingChat(options: UseBranchingChatOptions = {}) { case 'navigate': // Navigate to page with spotlight effect setTimeout(() => { - console.log('[goTo] Navigating to:', result.url); + // console.log('[goTo] Navigating to:', result.url); // Add spotlight=page param to trigger page glow on arrival const separator = result.url.includes('?') ? '&' : '?'; router.push(`${result.url}${separator}spotlight=page`); @@ -87,7 +87,7 @@ export function useBranchingChat(options: UseBranchingChatOptions = {}) { // Scroll to section on current page if (result.sectionId && scrollFn) { setTimeout(() => { - console.log('[goTo] Scrolling to:', result.sectionId); + // console.log('[goTo] Scrolling to:', result.sectionId); scrollFn(result.sectionId); }, 500); } @@ -96,7 +96,7 @@ export function useBranchingChat(options: UseBranchingChatOptions = {}) { case 'navigateAndScroll': // Navigate to page, then scroll to section setTimeout(() => { - console.log('[goTo] Navigate + Scroll:', result.url, result.sectionId); + // console.log('[goTo] Navigate + Scroll:', result.url, result.sectionId); // Add spotlight param with section ID const sep = result.url.includes('?') ? '&' : '?'; router.push(`${result.url}${sep}spotlight=${result.sectionId}`); @@ -141,7 +141,7 @@ export function useBranchingChat(options: UseBranchingChatOptions = {}) { if (lastMessage.role === 'assistant' && (lastMessage as any).metadata) { const mode = (lastMessage as any).metadata.mode; if (mode) { - console.log('[useBranchingChat] Found mode in metadata:', mode); + // console.log('[useBranchingChat] Found mode in metadata:', mode); setCurrentMode(mode); } } @@ -290,7 +290,7 @@ export function useBranchingChat(options: UseBranchingChatOptions = {}) { } ); - console.log('[useBranchingChat] Conversation saved to IndexedDB:', conversationId); + // console.log('[useBranchingChat] Conversation saved to IndexedDB:', conversationId); } catch (error) { console.error('[useBranchingChat] Save failed:', error); } @@ -308,7 +308,7 @@ export function useBranchingChat(options: UseBranchingChatOptions = {}) { const generateTitle = async () => { try { - console.log('[useBranchingChat] Generating AI title after 6 messages...'); + // console.log('[useBranchingChat] Generating AI title after 6 messages...'); // Convert messages to API format const messagesToSend = messages.map((msg: any) => ({ @@ -329,7 +329,7 @@ export function useBranchingChat(options: UseBranchingChatOptions = {}) { } const { title } = await res.json(); - console.log('[useBranchingChat] AI-generated title:', title); + // console.log('[useBranchingChat] AI-generated title:', title); // Update via SyncManager const messagesToSave = messages.map((msg: any) => { diff --git a/src/features/john-gpt/hooks/useWidgetPersistence.ts b/src/features/john-gpt/hooks/useWidgetPersistence.ts index e765f0c..d8d72bb 100644 --- a/src/features/john-gpt/hooks/useWidgetPersistence.ts +++ b/src/features/john-gpt/hooks/useWidgetPersistence.ts @@ -113,7 +113,7 @@ export function useWidgetPersistence( // Check if IndexedDB is supported if (!indexedDBClient || typeof indexedDB === 'undefined') { - console.log('[useWidgetPersistence] IndexedDB not supported'); + // console.log('[useWidgetPersistence] IndexedDB not supported'); setIsLoading(false); return; } @@ -123,10 +123,10 @@ export function useWidgetPersistence( const cachedSession = await dbSyncManager.loadConversation(sessionId, { isWidget: true }); if (cachedSession && cachedSession.messages && cachedSession.messages.length > 0) { - console.log('[useWidgetPersistence] Loaded session:', sessionId, 'with', cachedSession.messages.length, 'messages'); + // console.log('[useWidgetPersistence] Loaded session:', sessionId, 'with', cachedSession.messages.length, 'messages'); setInitialMessages(cachedSession.messages); } else { - console.log('[useWidgetPersistence] No existing session found for:', sessionId); + // console.log('[useWidgetPersistence] No existing session found for:', sessionId); } } catch (error) { console.error('[useWidgetPersistence] Error loading session:', error); @@ -143,7 +143,7 @@ export function useWidgetPersistence( try { await dbSyncManager.deleteConversation(sessionId); setInitialMessages([]); - console.log('[useWidgetPersistence] Session cleared:', sessionId); + // console.log('[useWidgetPersistence] Session cleared:', sessionId); } catch (error) { console.error('[useWidgetPersistence] Error clearing session:', error); } diff --git a/src/features/john-gpt/index.tsx b/src/features/john-gpt/index.tsx index fc7da42..e402065 100644 --- a/src/features/john-gpt/index.tsx +++ b/src/features/john-gpt/index.tsx @@ -22,7 +22,7 @@ export const JohnGPTFeature = ({ user }: { user?: WorkOSUser | null }) => { useEffect(() => { if (isFollowMeMode && !isOpen) { // Don't auto-open, but the button will pulse to indicate active chat - console.log('[JohnGPTFeature] Follow-me mode active, conversation:', activeChat?.state.conversationId); + // console.log('[JohnGPTFeature] Follow-me mode active, conversation:', activeChat?.state.conversationId); } }, [isFollowMeMode, isOpen, activeChat?.state.conversationId]); diff --git a/src/lib/storage/db-sync-manager.ts b/src/lib/storage/db-sync-manager.ts index bef9696..5a9dae6 100644 --- a/src/lib/storage/db-sync-manager.ts +++ b/src/lib/storage/db-sync-manager.ts @@ -84,7 +84,7 @@ export class DBSyncManager { // Authenticated if userId exists AND is not anonymous this.isAuthenticated = !!userId && !userId.startsWith('anonymous-'); - console.log(`[DBSyncManager] Initialized. User: ${userId || 'Guest'} (Auth: ${this.isAuthenticated}), Online: ${this.isOnline}`); + // console.log(`[DBSyncManager] Initialized. User: ${userId || 'Guest'} (Auth: ${this.isAuthenticated}), Online: ${this.isOnline}`); if (this.isAuthenticated && this.isOnline) { this.processOfflineQueue(); @@ -111,7 +111,7 @@ export class DBSyncManager { const { accessToken } = await res.json(); googleDriveClient.setAccessToken(accessToken); this.isDriveConnected = true; - console.log('[DBSyncManager] Google Drive connected'); + // console.log('[DBSyncManager] Google Drive connected'); return true; } catch (error) { console.warn('[DBSyncManager] Failed to initialize Google Drive:', error); @@ -141,7 +141,7 @@ export class DBSyncManager { }; await googleDriveClient.saveConversation(driveData); - console.log(`[DBSyncManager] Backed up ${conversationId} to Drive`); + // console.log(`[DBSyncManager] Backed up ${conversationId} to Drive`); } catch (error) { console.error('[DBSyncManager] Drive backup failed:', error); }