Add a robust debug logging system that captures application state, user interactions, and system diagnostics for enhanced troubleshooting and development experience. ## ✨ Features Added ### 🔍 **Multi-Source Data Capture** - **Console Logging**: Captures all console.log, console.warn, console.error - **Error Handling**: Intercepts JavaScript errors and unhandled promise rejections - **Network Monitoring**: Tracks all fetch requests with timing and status - **User Actions**: Records user interactions and UI events - **Terminal Activity**: Captures shell input/output with ANSI cleaning - **Performance Metrics**: Memory usage, page load times, paint timing ### 📊 **System Information Collection** - Platform detection (macOS, Windows, Linux) - Browser and viewport information - Git repository status (branch, commit, dirty state) - Application state (model, provider, workbench view) - Performance and memory statistics ### 🎯 **User Interface Integration** - **Avatar Dropdown**: "Download Debug Log" option with download icon - **Header Actions**: "Debug Log" button alongside existing "Report Bug" - **One-Click Download**: Generates comprehensive debug reports - **Error Handling**: Graceful degradation with user feedback ### 🔧 **Technical Implementation** - **Circular Buffers**: Memory-efficient storage with fixed capacity (1K entries) - **Lazy Loading**: Zero performance impact when disabled (default state) - **Debouncing**: Terminal logs debounced at 100ms to prevent spam - **JSON Safe**: Circular reference protection and depth limiting - **Async Operations**: Non-blocking debug operations ### 📁 **Files Modified** - `app/utils/debugLogger.ts` (1,284 lines) - Core debug logging utility - `app/utils/logger.ts` - Integration with existing logging system - `app/utils/shell.ts` - Terminal activity capture - `app/components/@settings/core/AvatarDropdown.tsx` - UI integration - `app/components/header/HeaderActionButtons.client.tsx` - Header button - `app/root.tsx` - Initialization and setup - `app/routes/api.git-info.ts` - Git information endpoint ## 🚀 **Benefits** - **Enhanced Debugging**: Comprehensive data collection for issue reproduction - **Performance Monitoring**: Built-in performance tracking and memory analysis - **User Support**: Easy debug log generation for support tickets - **Developer Experience**: Rich debugging data without performance penalty - **Production Ready**: Opt-in system with zero impact on regular users ## 🔒 **Security & Privacy** - Client-side only operation (no server transmission) - User-controlled data collection and export - No sensitive information captured automatically - Manual opt-in required for debug mode activation ## 📈 **Performance Impact** - **Disabled by Default**: No performance impact for regular users - **Lazy Initialization**: Components loaded only when needed - **Memory Bounded**: Fixed-size buffers prevent memory leaks - **Non-Blocking**: All operations are asynchronous - **Efficient Storage**: Circular buffers with automatic cleanup ## 🔄 **Integration Points** - Seamlessly integrates with existing `logger` utility - Compatible with current shell/terminal implementation - Works with existing error handling patterns - Maintains backward compatibility This implementation provides developers and users with powerful debugging capabilities while maintaining excellent performance and user experience.
70 lines
1.8 KiB
TypeScript
70 lines
1.8 KiB
TypeScript
import { json } from '@remix-run/cloudflare';
|
|
import { execSync } from 'child_process';
|
|
import { existsSync } from 'fs';
|
|
|
|
export async function loader() {
|
|
try {
|
|
// Check if we're in a git repository
|
|
if (!existsSync('.git')) {
|
|
return json({
|
|
branch: 'unknown',
|
|
commit: 'unknown',
|
|
isDirty: false,
|
|
});
|
|
}
|
|
|
|
// Get current branch
|
|
const branch = execSync('git rev-parse --abbrev-ref HEAD', { encoding: 'utf8' }).trim();
|
|
|
|
// Get current commit hash
|
|
const commit = execSync('git rev-parse HEAD', { encoding: 'utf8' }).trim();
|
|
|
|
// Check if working directory is dirty
|
|
const statusOutput = execSync('git status --porcelain', { encoding: 'utf8' });
|
|
const isDirty = statusOutput.trim().length > 0;
|
|
|
|
// Get remote URL
|
|
let remoteUrl: string | undefined;
|
|
|
|
try {
|
|
remoteUrl = execSync('git remote get-url origin', { encoding: 'utf8' }).trim();
|
|
} catch {
|
|
// No remote origin, leave as undefined
|
|
}
|
|
|
|
// Get last commit info
|
|
let lastCommit: { message: string; date: string; author: string } | undefined;
|
|
|
|
try {
|
|
const commitInfo = execSync('git log -1 --pretty=format:"%s|%ci|%an"', { encoding: 'utf8' }).trim();
|
|
const [message, date, author] = commitInfo.split('|');
|
|
lastCommit = {
|
|
message: message || 'unknown',
|
|
date: date || 'unknown',
|
|
author: author || 'unknown',
|
|
};
|
|
} catch {
|
|
// Could not get commit info
|
|
}
|
|
|
|
return json({
|
|
branch,
|
|
commit,
|
|
isDirty,
|
|
remoteUrl,
|
|
lastCommit,
|
|
});
|
|
} catch (error) {
|
|
console.error('Error fetching git info:', error);
|
|
return json(
|
|
{
|
|
branch: 'error',
|
|
commit: 'error',
|
|
isDirty: false,
|
|
error: error instanceof Error ? error.message : 'Unknown error',
|
|
},
|
|
{ status: 500 },
|
|
);
|
|
}
|
|
}
|