import { useEffect } from 'react'; import type { Issue, IssueSeverity } from '../../lib/issues'; interface IssuesDrawerProps { issues: Issue[]; onClose: () => void; onJumpTo?: (lineNo: number) => void; /** Optional predicate: "is this line currently visible under the active * filter?". When provided, jump buttons for filtered-out lines are * disabled and flagged. */ isLineVisible?: (lineNo: number) => boolean; } const SEV_COLOR: Record = { error: 'var(--color-sev-error)', warning: 'var(--color-sev-warning)', info: 'var(--color-sev-info)', }; const KIND_LABEL: Record = { orphan_tool_call: 'orphan tool.call', missing_tool_result: 'missing tool.result', tool_error: 'tool error', tool_truncated: 'tool output truncated', model_filtered: 'response filtered', model_max_tokens: 'hit max_tokens', incomplete_step: 'incomplete step', incomplete_compaction: 'incomplete compaction', active_plan_mode: 'plan mode active', rejected_approval: 'approval rejected', wire_warning: 'wire warning', }; export function IssuesDrawer({ issues, onClose, onJumpTo, isLineVisible }: IssuesDrawerProps) { // ESC closes — standard drawer affordance. useEffect(() => { const onKey = (e: KeyboardEvent) => { if (e.key === 'Escape') onClose(); }; window.addEventListener('keydown', onKey); return () => { window.removeEventListener('keydown', onKey); }; }, [onClose]); return ( <>
{issues.length === 0 ? (
no issues detected
) : (
    {issues.map((iss, i) => ( ))}
)}
); } function IssueItem({ issue, onJumpTo, onClose, isLineVisible, }: { issue: Issue; onJumpTo?: (lineNo: number) => void; onClose: () => void; isLineVisible?: (lineNo: number) => boolean; }) { const color = SEV_COLOR[issue.severity]; const lineNo = issue.lineNo; const hidden = lineNo !== null && isLineVisible !== undefined && !isLineVisible(lineNo); const canJump = lineNo !== null && onJumpTo !== undefined && !hidden; return (
  • {issue.summary}
    {issue.detail !== undefined ? (
    {issue.detail}
    ) : null}
  • ); }