Admin Debug Context
<!-- rules:stamp -->
Rules from common-docs/systems/platform/ui-shell/builder-panel/FEATURE.md — edit there, never here (python3 common-docs/meta/scripts/one_home.py --write).
- No AI integration starts without a Builder feed. The same change that adds a data step to a
surface publishes its inputs, findings, workflow step outputs, AI runs and provision snapshots, so
Arman can see every value the page has, in real time, from the first minute. Tell him exactly what
to click: one click to open the panel is fine, not knowing it exists is not.
- The panel shows the truth, unmodified. Every exact request and response (client calls and the
server's external calls), an Activity timeline, and derived values only in a separate group that
links to its raw source. Values render through the canonical multi-format JSON component; copy is
icon-only, never a "Copy" label.
- Evidence is tiered by certainty and risk. Early raw-input steps are safe, read-only searches;
deeper or risky steps fire only after a person confirms; a node fires when its inputs are ready or
confirmed. Jev pre-suggests choices with a "we think this one" animation, still provision-first.
<!-- rules:stamp-end -->
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'); // namespace
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 }); // merge namespaced data
publishKey('Key', value); // set single key
isActive // boolean — true only when admin AND debug mode is on
Adding a debug module panel
For richer feature-specific UIs (not just JSON data), create a debug module:
Step 1 — Create the component
// components/admin/debug/MyFeatureDebug.tsx
'use client';
import { useAppSelector } from '@/lib/redux/hooks';
export default function MyFeatureDebug() {
// Read exclusively from Redux selectors — no local fetch, no useState for data
const data = useAppSelector(selectSomething);
return <div className="p-4 type-secondary font-mono">{JSON.stringify(data, null, 2)}</div>;
}
Step 2 — Register in the registry
// components/admin/debug/debugModuleRegistry.tsx
import MyFeatureDebug from './MyFeatureDebug';
import { Zap } from 'lucide-react';
export const debugModules: DebugModule[] = [
// ... existing modules ...
{
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.