diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md index ec4a23e..016ef91 100644 --- a/DEVELOPMENT.md +++ b/DEVELOPMENT.md @@ -276,11 +276,55 @@ Uses OpenAI chat completions format with tool support: - Verify temperature is set to 0.1 for consistent results - Tests expect multiple tool calls for comprehensive validation -### Logging +### Debug Logging System -- Background script logs appear in service worker console -- Sidepanel logs appear in sidepanel DevTools console -- Use `console.log()` for debugging (remove in production) +The extension features a comprehensive debug logging system that works across all contexts (background, sidepanel, content scripts, options). + +#### Using the Debug Logger + +```typescript +// Import the logger +import { backgroundLogger, sidepanelLogger, contentLogger, optionsLogger } from '~/utils/debug-logger'; +// Or use the context-aware logger +import { getContextLogger } from '~/utils/debug-logger'; + +// Use the appropriate logger for your context +const logger = backgroundLogger; // or getContextLogger() for automatic detection + +// Log at different levels +logger.debug('Debug information', { data: 'example' }); +logger.info('Information message', { userId: 123 }); +logger.warn('Warning message', { issue: 'performance' }); +logger.error('Error occurred', new Error('Something went wrong')); // Automatically captures stack traces +``` + +#### Viewing Debug Logs + +1. **In Sidepanel**: Click the debug icon (🐛) in the header to open the debug log viewer +2. **In DevTools**: Logs also appear in the browser console for immediate debugging +3. **Export Logs**: Use the export button in the debug viewer to save logs as JSON + +#### Debug Viewer Features + +- **Real-time filtering** by log level (debug, info, warn, error) +- **Context filtering** by source (background, sidepanel, content, options) +- **Text search** through log messages and data +- **Time-based filtering** (last hour, last 10 minutes, all time) +- **Auto-refresh** for live log monitoring +- **Export functionality** for sharing or analysis + +#### Configuration + +- **Max Log Entries**: Configurable limit (default: 10,000 entries) +- **Auto-pruning**: Old entries are automatically removed when limit is exceeded +- **Persistent Storage**: Logs survive extension restarts and browser sessions + +#### Performance Considerations + +- Logs are stored efficiently using chunked storage +- Only recent entries are kept in memory +- Background logging has minimal performance impact +- Type validation ensures data integrity ## Contributing diff --git a/README.md b/README.md index bf0f045..02991e3 100644 --- a/README.md +++ b/README.md @@ -20,9 +20,11 @@ https://github.com/user-attachments/assets/7a584180-e8dd-4c7f-838a-efd051fa2968 ## Quick Start -Ready-to-use extension builds are available in the releases section. For development setup, see [DEVELOPMENT.md](DEVELOPMENT.md). +Currently there aren't ready-to-use extension builds. -If you want to see a quick demo, go to Google.com and type `click Reject All, search fluffy robots, and tell me which 3 are the most popular` +For development setup, see [DEVELOPMENT.md](DEVELOPMENT.md). + +Once you got the extension running, if you want to see a quick demo go to Google.com and type `click Reject All, search fluffy robots, and tell me which 3 are the most popular` ## Installation diff --git a/entrypoints/sidepanel/ChatInterface.tsx b/entrypoints/sidepanel/ChatInterface.tsx index 6bd476c..6ed7ee5 100644 --- a/entrypoints/sidepanel/ChatInterface.tsx +++ b/entrypoints/sidepanel/ChatInterface.tsx @@ -12,6 +12,7 @@ import type { MessageToSidebar, } from '~/utils/types'; import { createStableId, isExtensionSettings } from '~/utils/types'; +import DebugLogViewer from './components/DebugLogViewer'; import ManualToolInterface from './ManualToolInterface'; import { MemoizedMarkdown } from './MemoizedMarkdown'; @@ -278,6 +279,8 @@ const ChatInterface: React.FC = () => { const [isLoading, setIsLoading] = useState(false); const [status, setStatus] = useState<{ text: string; type?: 'error' | 'thinking' }>({ text: '' }); const [tabId, setTabId] = useState(null); + const [showDebugLogs, setShowDebugLogs] = useState(false); + const [showToolsPanel, setShowToolsPanel] = useState(false); const messagesEndRef = useRef(null); const isRefreshingRef = useRef(false); @@ -295,12 +298,6 @@ const ChatInterface: React.FC = () => { const getTabChatHistory = useCallback( (settings: ExtensionSettings | null, currentTabId: number | null): ChatMessage[] => { - sidepanelLogger.debug('getTabChatHistory called', { - hasSettings: !!settings, - currentTabId, - settingsType: typeof settings, - }); - if (!settings) { sidepanelLogger.debug('No settings, returning empty array'); return []; @@ -314,12 +311,6 @@ const ChatInterface: React.FC = () => { } const tabConversations = settings.tabConversations?.[currentTabId.toString()]; - sidepanelLogger.debug('Tab conversations lookup', { - hasTabConversations: !!settings.tabConversations, - tabKey: currentTabId.toString(), - foundConversation: !!tabConversations, - conversationLength: tabConversations?.length || 0, - }); return tabConversations || []; }, @@ -560,18 +551,9 @@ const ChatInterface: React.FC = () => { }; const renderAssistantMessage = (message: ChatMessage) => { - sidepanelLogger.debug('renderAssistantMessage called', { - messageId: message.id, - hasContent: !!message.content, - }); - // Process AI SDK UI parts structure const messageWithParts = message as StreamingChatMessageWithParts; if (messageWithParts.parts && Array.isArray(messageWithParts.parts)) { - sidepanelLogger.debug('Processing message parts (AI SDK UI)', { - partCount: messageWithParts.parts.length, - }); - return (
{messageWithParts.parts.map((part: MessagePart, index: number) => ( @@ -601,23 +583,41 @@ const ChatInterface: React.FC = () => {

LLM Chat

+ {settings?.debugMode && ( + + )} +
@@ -637,13 +637,6 @@ const ChatInterface: React.FC = () => {
) : ( (() => { - sidepanelLogger.debug('Rendering messages', { - messageCount: messages?.length || 0, - isArray: Array.isArray(messages), - messageTypes: Array.isArray(messages) - ? messages.filter((m) => m).map((m) => m.role) - : [], - }); return (Array.isArray(messages) ? messages : []) .filter((message) => { if (!message) { @@ -676,7 +669,11 @@ const ChatInterface: React.FC = () => { - + {showToolsPanel && ( + + )} + + setShowDebugLogs(false)} />