feat: introduce debug panel for performance monitoring

- Added a debug panel to monitor server performance, including memory and CPU metrics.
- Implemented debug services for real-time tracking of processes and performance metrics.
- Created API endpoints for metrics collection and process management.
- Enhanced UI components for displaying metrics and process statuses.
- Updated documentation to include new debug API details.

This feature is intended for development use and can be toggled with the `ENABLE_DEBUG_PANEL` environment variable.
This commit is contained in:
Kacper
2026-01-05 18:55:44 +01:00
parent abab7be367
commit 78d08c2b5b
36 changed files with 8560 additions and 9 deletions

View File

@@ -24,6 +24,14 @@ import { ThemeOption, themeOptions } from '@/config/theme-options';
import { SandboxRiskDialog } from '@/components/dialogs/sandbox-risk-dialog';
import { SandboxRejectionScreen } from '@/components/dialogs/sandbox-rejection-screen';
import { LoadingState } from '@/components/ui/loading-state';
import {
DebugPanelWrapper,
DebugStatusBarWrapper,
DebugDockedPanelWrapper,
RenderTrackingProvider,
RenderProfiler,
} from '@/components/debug';
import { useDebugStore } from '@/store/debug-store';
const logger = createLogger('RootLayout');
@@ -46,6 +54,7 @@ function RootLayoutContent() {
const authChecked = useAuthStore((s) => s.authChecked);
const isAuthenticated = useAuthStore((s) => s.isAuthenticated);
const { openFileBrowser } = useFileBrowser();
const toggleDebugPanel = useDebugStore((s) => s.togglePanel);
const isSetupRoute = location.pathname === '/setup';
const isLoginRoute = location.pathname === '/login';
@@ -87,12 +96,31 @@ function RootLayoutContent() {
}
}, []);
// Debug panel shortcut - Cmd/Ctrl+Shift+D
const handleDebugPanelShortcut = useCallback(
(event: KeyboardEvent) => {
// Only in dev mode
if (!import.meta.env.DEV && import.meta.env.VITE_ENABLE_DEBUG_PANEL !== 'true') {
return;
}
const cmdCtrl = event.metaKey || event.ctrlKey;
if (cmdCtrl && event.shiftKey && event.key.toLowerCase() === 'd') {
event.preventDefault();
toggleDebugPanel();
}
},
[toggleDebugPanel]
);
useEffect(() => {
window.addEventListener('keydown', handleStreamerPanelShortcut);
window.addEventListener('keydown', handleDebugPanelShortcut);
return () => {
window.removeEventListener('keydown', handleStreamerPanelShortcut);
window.removeEventListener('keydown', handleDebugPanelShortcut);
};
}, [handleStreamerPanelShortcut]);
}, [handleStreamerPanelShortcut, handleDebugPanelShortcut]);
const effectiveTheme = getEffectiveTheme();
// Defer the theme value to keep UI responsive during rapid hover changes
@@ -394,12 +422,25 @@ function RootLayoutContent() {
aria-hidden="true"
/>
)}
<Sidebar />
<RenderProfiler name="Sidebar">
<Sidebar />
</RenderProfiler>
<div
className="flex-1 flex flex-col overflow-hidden transition-all duration-300"
style={{ marginRight: streamerPanelOpen ? '250px' : '0' }}
>
<Outlet />
{/* Main content area */}
<div className="flex-1 flex flex-col min-h-0">
<RenderProfiler name="MainContent">
<Outlet />
</RenderProfiler>
</div>
{/* Docked Debug Panel - expands above status bar */}
<DebugDockedPanelWrapper />
{/* Docked Debug Status Bar - VS Code style footer */}
<DebugStatusBarWrapper />
</div>
{/* Hidden streamer panel - opens with "\" key, pushes content */}
@@ -410,6 +451,9 @@ function RootLayoutContent() {
/>
<Toaster richColors position="bottom-right" />
{/* Floating Debug Panel - alternative mode */}
<DebugPanelWrapper />
{/* Show sandbox dialog if needed */}
<SandboxRiskDialog
open={sandboxStatus === 'needs-confirmation'}
@@ -421,9 +465,18 @@ function RootLayoutContent() {
}
function RootLayout() {
// Check if dev mode for render tracking
const isDev = import.meta.env.DEV || import.meta.env.VITE_ENABLE_DEBUG_PANEL === 'true';
return (
<FileBrowserProvider>
<RootLayoutContent />
{isDev ? (
<RenderTrackingProvider>
<RootLayoutContent />
</RenderTrackingProvider>
) : (
<RootLayoutContent />
)}
</FileBrowserProvider>
);
}