| name | admin-debug-context |
| description | Wire any route or feature to the admin debug system so the floating AdminIndicator shows live debug context and enables one-click full-context copy for AI agents. Use when asked to add debug visibility, wire a route to the debug panel, add console error capture, or enable the copy-context workflow for a page. |
Admin Debug Context
Performance guarantee
The entire debug system is zero cost for non-admins:
AdminIndicatorWrapper checks selectIsAdmin from Redux and returns null immediately if false
- Both
AdminIndicatorIsland (ssr layout) and DynamicAdminIndicatorWrapper (authenticated layout) use dynamic(..., { ssr: false }) — the admin bundle never downloads for non-admins
useDebugContext is a no-op when isAdmin is false — no dispatch, no effect, no render cost
Architecture — four layers
Layout (server)
└── AdminIndicatorWrapper (client, admin-only)
├── AdminDebugContextCollector ← auto: pathname, searchParams, viewport,
│ console errors, unhandledrejection
└── AdminIndicator (Small/Medium/Large)
├── MediumIndicator
│ └── debugModules icons → DebugModulePanel modal
└── LargeIndicator
├── API config + health grid
├── Recent API calls log
├── [Copy Full Context] button ← assembles everything for AI agent
├── Console Errors panel ← captured automatically
└── Debug Data (JSON) ← written via useDebugContext
What is auto-captured (no route work needed)
AdminDebugContextCollector runs at layout level inside AdminIndicatorWrapper. For every admin session it automatically captures:
| Data | How |
|---|
| Current pathname | usePathname() on every navigation |
| Search params | useSearchParams() on every navigation |
| Browser viewport | window.innerWidth/Height |
| User agent | navigator.userAgent |
| Navigation count | increments on each pathname change |
console.error calls | patches console.error while mounted |
unhandledrejection events | window.addEventListener |
window.error events | window.addEventListener |
This is available instantly in the "Copy Full Context" snapshot even for routes that add zero custom debug code.
Adding route/feature debug data
The hook — use this everywhere
import { useDebugContext } from '@/hooks/useDebugContext';
export default function MyComponent({ sessionId }: { sessionId: string }) {
const session = useAppSelector(s => selectSession(s, sessionId));
const { publish, isActive } = useDebugContext('Chat');
useEffect(() => {
publish({
'Session ID': sessionId,
'Status': session?.status,
'Message Count': session?.messages.length,
'Conversation ID': session?.conversationId,
});
}, [isActive, session?.status, session?.messages.length, sessionId]);
}
Key rules:
- First arg is the namespace — appears as group header in the debug panel
- Keys are auto-prefixed:
"Chat:Session ID", "Chat:Status", etc.
isActive is true only when isAdmin && isDebugMode — use it in useEffect deps to gate expensive collection
- The hook auto-clears all namespace keys on unmount — no manual cleanup needed
- Safe in any component tree — pure no-op for non-admins
Hook API
const { publish, publishKey, isActive } = useDebugContext('Namespace');
publish({ 'Key': value, 'Other Key': otherValue });
publishKey('Key', value);
isActive
Adding a debug module panel
For richer feature-specific UIs (not just JSON data), create a debug module:
Step 1 — Create the component
'use client';
import { useAppSelector } from '@/lib/redux/hooks';
export default function MyFeatureDebug() {
const data = useAppSelector(selectSomething);
return <div className="p-4 text-xs font-mono">{JSON.stringify(data, null, 2)}</div>;
}
Step 2 — Register in the registry
import MyFeatureDebug from './MyFeatureDebug';
import { Zap } from 'lucide-react';
export const debugModules: DebugModule[] = [
{
id: 'my-feature',
name: 'My Feature',
icon: Zap,
component: MyFeatureDebug,
description: 'Live state of my feature',
color: 'text-purple-400',
},
];
The icon appears in the MediumIndicator debug row. Clicking opens the panel modal. Component only mounts when the panel is open — zero overhead when closed.
Copy Full Context — the AI agent workflow
The Copy button in LargeIndicator assembles a complete markdown snapshot:
# Admin Debug Context Snapshot
Generated: 2026-03-27T10:42:00.000Z
Admin: admin@example.com
## Route
- **Path:** /demos/chat/c/abc-123
- **Viewport:** 1440×900
- **Render Count:** 3
## API Config
- **Active Server:** localhost
- **Backend URL:** http://localhost:8000
- **Health:** healthy (42ms)
## Feature Debug Data
### Chat
- **Session ID:** sess-xyz
- **Status:** streaming
- **Message Count:** 7
## Recent API Calls
| Status | Method | Path | HTTP | Duration |
...
## Console Errors
No errors captured.
Workflow: Admin sees a bug → opens LargeIndicator → clicks Copy → pastes into AI agent chat. Agent gets full context: what page, what state, what the API is doing, any errors.
Data sources reference
| What | Selector | Slice |
|---|
| Is admin | selectIsAdmin | userSlice |
| Debug mode on | selectIsDebugMode | adminDebugSlice |
| Route context | selectRouteContext | adminDebugSlice |
| Console errors | selectConsoleErrors | adminDebugSlice |
| Debug data (JSON) | selectDebugData | adminDebugSlice |
| Active server | selectActiveServer | apiConfigSlice |
| Backend URL | selectResolvedBaseUrl | apiConfigSlice |
| Server health | selectActiveServerHealth | apiConfigSlice |
| Recent API calls | selectRecentApiCalls | apiConfigSlice |
| Active chat session | selectActiveChatSessionId | activeChatSlice |
| Chat session object | selectSession(state, sessionId) | chatConversations |
| Chat messages | selectMessages(state, sessionId) | chatConversations |
Viewing debug context
- Small indicator — two colored dots (server env, health)
- Medium indicator — debug icon row; click any icon for that feature's panel
- Large indicator — full admin dashboard:
- Copy button (always visible) — one click to copy everything for an AI agent
- Console Errors panel — auto-captured, collapsible, shows stack traces
- Debug Data section (debug mode on) — namespaced JSON from
useDebugContext
- API calls log and all environments health grid
Enable debug mode: click the Debug toggle in MediumIndicator or LargeIndicator.