/**
 * WorkspaceOutputShelf.tsx — S612: pannello output sotto l'editor
 *
 * Desktop: pannello resizable (react-resizable-panels) sotto l'editor.
 * Mobile:  shelf collassabile da bottom con CSS transition.
 *
 * Mostra le ultime azioni del task attivo (tool calls, file writes, ecc.)
 * e l'ultimo run code snippet — senza duplicare TerminalPanel/xterm.
 * "→ Terminale" / "→ Esegui" navigano ai tab dedicati per il full output.
 *
 * S614 — bug fix + polish:
 *   - usa selectActiveTask (evita triple subscription con tasks.find)
 *   - auto-scroll al fondo della activity list quando arrivano nuove azioni
 *   - MobileOutputShelf si auto-apre quando isStreaming passa da false → true
 */

import { useState, useEffect, useRef, useCallback, memo } from "react";
import { ChevronUp, ChevronDown, Terminal, Play, Zap, X } from "lucide-react";
import { useTaskStore, selectActiveTask } from "@/store/taskStore";
import { useChatStore } from "@/store/chatStore";
import { useWorkspaceStore }  from "@/store/workspaceStore";
import { useAgentFileChanged } from "@/hooks/useAgentFileChanged";   // Fix D: watch mode
import { runVfsTsCheck }       from "@/lib/vfsTsChecker";             // GAP-3: TS check
import type { VfsTsError }     from "@/lib/vfsTsChecker";

// ─── Repair prompt formatter ──────────────────────────────────────────────────
// Produce un prompt conciso che l'agente può leggere e usare per correggere
// gli errori TypeScript. Max 8 errori + 4 warning per non eccedere il context.

function formatRepairPrompt(errors: VfsTsError[]): string {
  const errs  = errors.filter(e => e.sev === "error");
  const warns = errors.filter(e => e.sev !== "error");
  const header = errs.length > 0 && warns.length > 0
    ? `🔧 Correggi ${errs.length} errore/i TypeScript e ${warns.length} warning:`
    : errs.length > 0
      ? `🔧 Correggi ${errs.length} errore/i TypeScript:`
      : `🔧 Correggi ${warns.length} warning TypeScript:`;
  const errLines  = errs.slice(0, 8).map(e => `• ${e.file}:${e.line}:${e.col} TS${e.code}: ${e.message}`);
  const warnLines = warns.slice(0, 4).map(e => `⚠ ${e.file}:${e.line}:${e.col} TS${e.code}: ${e.message}`);
  const overflow  = errs.length > 8 ? [`… e altri ${errs.length - 8} errori non mostrati`] : [];
  return [header, "", ...errLines, ...overflow, ...(warns.length > 0 && errs.length < 8 ? warnLines : [])].join("\n");
}

// ─── Action icon map ──────────────────────────────────────────────────────────

const ACTION_ICONS: Record<string, string> = {
  file_write:  "✏️", file_read: "📖", file_open: "📂", file_delete: "🗑️",
  search_web:  "🔍", code_run:  "▶️", tool_call: "🔧", api_call:   "🌐",
  thinking:    "💭", plan:      "📋", memory:    "🧠",
};

function actionIcon(type: string): string {
  return ACTION_ICONS[type] ?? "⚡";
}

function elapsedLabel(ms: number): string {
  if (ms < 1000) return `${ms}ms`;
  if (ms < 60000) return `${(ms / 1000).toFixed(1)}s`;
  return `${Math.floor(ms / 60000)}m`;
}

// ─── Tab type ─────────────────────────────────────────────────────────────────

type ShelfTab = "activity" | "code" | "errors";

// ─── Shelf content ────────────────────────────────────────────────────────────

function ShelfContent({
  tab, onGoToTerminal, onGoToRun,
  // S614: riceve activeTask come prop — un'unica subscription nel parent
  activeTask, agentLiveStatus, isStreaming,
  tsErrors, tsChecking, onRepairTs,
}: {
  tab: ShelfTab;
  onGoToTerminal: () => void;
  onGoToRun: () => void;
  activeTask:      ReturnType<typeof selectActiveTask>;
  agentLiveStatus: string;
  isStreaming:     boolean;
  tsErrors:        VfsTsError[];
  tsChecking:      boolean;
  /** Fix D: callback che inietta il repair prompt nell'input bar via "agente:submit_input" */
  onRepairTs?:     () => void;
}) {
  const runCode = useWorkspaceStore(s => s.runCode);
  // S614: auto-scroll al fondo quando arrivano nuove azioni
  const bottomRef = useRef<HTMLDivElement | null>(null);
  const actions = activeTask?.actions ?? [];

  useEffect(() => {
    if (tab === "activity" && bottomRef.current) {
      bottomRef.current.scrollIntoView({ behavior: "smooth", block: "end" });
    }
  }, [actions.length, tab]);

  if (tab === "activity") {
    const MAX_VISIBLE = 20;
    const hiddenCount = Math.max(0, actions.length - MAX_VISIBLE);
    const recentActions = actions.slice(-MAX_VISIBLE); // ultimi 20, ordine cronologico

    return (
      <div style={{ flex: 1, overflow: "auto", padding: "4px 0" }}>
        {/* S621: indicatore azioni precedenti nascosti (truncation hint) */}
        {hiddenCount > 0 && (
          <div style={{
            display: "flex", alignItems: "center", justifyContent: "center",
            padding: "3px 10px",
            borderBottom: "1px solid rgba(99,102,241,0.08)",
            marginBottom: 2,
          }}>
            <span style={{ fontSize: "0.62rem", color: "#4a4a78", fontStyle: "italic" }}>
              ⋯ {hiddenCount} azioni precedenti
            </span>
          </div>
        )}
        {/* Live status */}
        {isStreaming && agentLiveStatus && (
          <div style={{
            display: "flex", alignItems: "center", gap: 6,
            padding: "4px 10px",
            borderBottom: "1px solid rgba(99,102,241,0.10)",
            marginBottom: 2,
          }}>
            <span style={{
              width: 6, height: 6, borderRadius: "50%",
              background: "#22c55e",
              animation: "mem-tab-pulse 1s ease-in-out infinite",
              flexShrink: 0,
            }} />
            <span style={{ fontSize: "0.7rem", color: "#86efac", fontStyle: "italic",
              overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>
              {agentLiveStatus}
            </span>
          </div>
        )}

        {/* Actions log */}
        {recentActions.length === 0 ? (
          <p style={{ fontSize: "0.68rem", color: "#3a3a6a", padding: "10px 12px", lineHeight: 1.5 }}>
            Nessuna attività. L'agente inizierà a registrare le azioni qui.
          </p>
        ) : (
          recentActions.map(action => (
            <div key={action.id} style={{
              display: "flex", alignItems: "center", gap: 6,
              padding: "2px 10px",
              opacity: action.done ? 0.6 : 1,
              transition: "opacity 0.2s",
            }}>
              <span style={{ fontSize: "0.7rem", flexShrink: 0 }}>{actionIcon(action.type)}</span>
              <span style={{
                flex: 1, fontSize: "0.68rem",
                color: action.done ? "#4a5568" : "#a0aec0",
                overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap",
              }}>
                {action.explanation ?? action.label}
              </span>
              {action.detail && (
                <span style={{ fontSize: "0.62rem", color: "#3b82f6",
                  maxWidth: 100, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap",
                  flexShrink: 0 }}>
                  {action.detail}
                </span>
              )}
              {action.durationMs !== undefined && (
                <span style={{ fontSize: "0.6rem", color: "#2d3748", flexShrink: 0 }}>
                  {elapsedLabel(action.durationMs)}
                </span>
              )}
            </div>
          ))
        )}

        {/* S614: sentinella per auto-scroll */}
        <div ref={bottomRef} style={{ height: 1 }} />

        {/* Full terminal link */}
        <button
          onClick={onGoToTerminal}
          style={{
            display: "flex", alignItems: "center", gap: 4,
            margin: "6px 10px 4px",
            background: "none", border: "none", cursor: "pointer",
            color: "#4a4a78", fontSize: "0.62rem",
            padding: "3px 0",
            transition: "color 0.15s",
          }}
          onMouseEnter={e => { e.currentTarget.style.color = "#818cf8"; }}
          onMouseLeave={e => { e.currentTarget.style.color = "#4a4a78"; }}
        >
          <Terminal size={10} />
          Apri terminale completo →
        </button>
      </div>
    );
  }


  // ─── Tab ERRORI — Fix D: TS errors live aggiornati dopo ogni file write ──
  if (tab === "errors") {
    return (
      <div style={{ flex: 1, overflow: "auto", padding: "6px 10px" }}>
        {tsChecking && (
          <div style={{ display: "flex", alignItems: "center", gap: 6, padding: "4px 0", marginBottom: 4 }}>
            <span style={{
              width: 6, height: 6, borderRadius: "50%",
              background: "#f59e0b",
              animation: "mem-tab-pulse 1s ease-in-out infinite",
              flexShrink: 0,
            }} />
            <span style={{ fontSize: "0.65rem", color: "#fbbf24", fontStyle: "italic" }}>
              Controllo TypeScript…
            </span>
          </div>
        )}
        {onRepairTs && tsErrors.length > 0 && (
          <button
            onClick={onRepairTs}
            disabled={isStreaming}
            style={{
              display: "flex", alignItems: "center", gap: 5,
              margin: "6px 0 8px",
              padding: "5px 12px",
              background: isStreaming
                ? "rgba(99,102,241,0.06)"
                : "rgba(99,102,241,0.14)",
              border: "1px solid rgba(99,102,241,0.30)",
              borderRadius: 8,
              cursor: isStreaming ? "not-allowed" : "pointer",
              color: isStreaming ? "#3a3a6a" : "#818cf8",
              fontSize: "0.68rem", fontWeight: 600,
              transition: "background 0.15s, color 0.15s",
              opacity: isStreaming ? 0.5 : 1,
            }}
            onMouseEnter={e => { if (!isStreaming) e.currentTarget.style.background = "rgba(99,102,241,0.22)"; }}
            onMouseLeave={e => { if (!isStreaming) e.currentTarget.style.background = "rgba(99,102,241,0.14)"; }}
            title={isStreaming ? "Agente già in esecuzione — attendi il completamento" : `Invia ${tsErrors.length} errore/i all'agente per la correzione automatica`}
          >
            🔧
            {isStreaming ? "Agente in esecuzione…" : `Correggi ${tsErrors.length > 9 ? "9+" : tsErrors.length} errore/i`}
          </button>
        )}
        {!tsChecking && tsErrors.length === 0 ? (
          <p style={{ fontSize: "0.68rem", color: "#22c55e", lineHeight: 1.5 }}>
            ✓ Nessun errore TypeScript rilevato.
          </p>
        ) : (
          tsErrors.map((err, i) => (
            <div key={i} style={{
              display: "flex", flexDirection: "column", gap: 1,
              padding: "4px 0",
              borderBottom: "1px solid rgba(99,102,241,0.07)",
            }}>
              <div style={{ display: "flex", alignItems: "center", gap: 6 }}>
                <span style={{
                  fontSize: "0.6rem", fontWeight: 700,
                  color: err.sev === "error" ? "#f87171" : "#fbbf24",
                  flexShrink: 0,
                }}>
                  {err.sev === "error" ? "ERR" : "WARN"}
                </span>
                <span style={{
                  fontSize: "0.6rem", color: "#4a4a78", fontFamily: "monospace",
                  overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap",
                }}>
                  {err.file.split("/").pop()}:{err.line}:{err.col}
                </span>
                <span style={{ fontSize: "0.55rem", color: "#3a3a5a", flexShrink: 0 }}>
                  TS{err.code}
                </span>
              </div>
              <span style={{
                fontSize: "0.67rem", color: "#9ca3af",
                paddingLeft: 0,
                overflow: "hidden", textOverflow: "ellipsis",
                display: "-webkit-box", WebkitLineClamp: 2, WebkitBoxOrient: "vertical",
              }}>
                {err.message}
              </span>
            </div>
          ))
        )}
      </div>
    );
  }

  // tab === "code"
  return (
    <div style={{ flex: 1, overflow: "auto", padding: "6px 10px" }}>
      {runCode ? (
        <>
          <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", marginBottom: 4 }}>
            <span style={{ fontSize: "0.62rem", color: "#4a4a78", fontFamily: "monospace" }}>
              {runCode.filename}
            </span>
            <button
              onClick={onGoToRun}
              style={{
                display: "flex", alignItems: "center", gap: 3,
                background: "rgba(34,197,94,0.12)", border: "1px solid rgba(34,197,94,0.25)",
                borderRadius: 8, padding: "2px 8px", cursor: "pointer",
                color: "#4ade80", fontSize: "0.65rem", fontWeight: 600,
                transition: "background 0.15s",
              }}
              onMouseEnter={e => { e.currentTarget.style.background = "rgba(34,197,94,0.22)"; }}
              onMouseLeave={e => { e.currentTarget.style.background = "rgba(34,197,94,0.12)"; }}
            >
              <Play size={9} />
              Esegui
            </button>
          </div>
          <pre style={{
            margin: 0, fontSize: "0.68rem", color: "#9ca3af",
            fontFamily: '"JetBrains Mono", ui-monospace, monospace',
            lineHeight: 1.5,
            whiteSpace: "pre-wrap", wordBreak: "break-all",
            maxHeight: 200, overflow: "auto",
          }}>
            {runCode.code.slice(0, 800)}
            {runCode.code.length > 800 && "\n… (troncato)"}
          </pre>
        </>
      ) : (
        <p style={{ fontSize: "0.68rem", color: "#3a3a6a", lineHeight: 1.5 }}>
          Nessun codice in esecuzione. L'agente popolerà questo pannello quando eseguirà codice.
        </p>
      )}
    </div>
  );
}

// ─── Desktop shelf (embedded in PanelGroup) ───────────────────────────────────

export const WorkspaceOutputShelf = memo(function WorkspaceOutputShelf({
  onGoToTerminal,
  onGoToRun,
}: {
  onGoToTerminal: () => void;
  onGoToRun: () => void;
}) {
  const [tab, setTab]  = useState<ShelfTab>("activity");
  // S614: una sola subscription per il task attivo
  const activeTask     = useTaskStore(selectActiveTask);
  const isStreaming    = useChatStore(s => s.isStreaming);
  const agentLiveStatus= useChatStore(s => s.agentLiveStatus);
  const runCode        = useWorkspaceStore(s => s.runCode);

  const activityCount = activeTask?.actions.length ?? 0;
  const hasCode = !!runCode;

  const setInput      = useChatStore(s => s.setInput); // Fix D: repair bridge

  // ─── Fix D: TS errors live — aggiornati dopo ogni file write (agent:file-changed) ──
  const [tsErrors,   setTsErrors]   = useState<VfsTsError[]>([]);
  const [tsChecking, setTsChecking] = useState(false);
  const _mountedD = useRef(true);
  useEffect(() => { _mountedD.current = true; return () => { _mountedD.current = false; }; }, []);
  const _runTsCheck = useCallback(async () => {
    setTsChecking(true);
    try {
      const errs = await runVfsTsCheck();
      if (_mountedD.current) setTsErrors(errs);
    } catch { /* non-fatal */ }
    finally { if (_mountedD.current) setTsChecking(false); }
  }, []);
  // Debounce 600ms — leggermente più lento del debounce del hook (300ms) per
  // aspettare che tutte le scritture batch siano complete prima del TS check.
  useAgentFileChanged(useCallback(() => { void _runTsCheck(); }, [_runTsCheck]), 600);

  // ─── Fix D: onRepairTs — invia errori TS all'agente via ChatInputBar bridge ──
  const _onRepairTs = useCallback(() => {
    if (!tsErrors.length) return;
    setInput(formatRepairPrompt(tsErrors));
    window.dispatchEvent(new CustomEvent("agente:submit_input"));
  }, [tsErrors, setInput]);

  return (
    <div style={{
      display: "flex", flexDirection: "column",
      background: "rgba(4,5,16,0.97)",
      borderTop: "1px solid rgba(99,102,241,0.18)",
      overflow: "hidden", height: "100%",
    }}>
      {/* Header + tabs */}
      <div style={{
        display: "flex", alignItems: "center", gap: 0,
        borderBottom: "1px solid rgba(99,102,241,0.10)",
        flexShrink: 0, height: 30,
      }}>
        {([
          { id: "activity" as ShelfTab, label: "ATTIVITÀ", badge: activityCount, badgeColor: isStreaming ? "#22c55e" : "#3b82f6" },
          { id: "code"     as ShelfTab, label: "CODICE",   badge: hasCode ? 1 : 0, badgeColor: "#3b82f6" },
          { id: "errors"   as ShelfTab, label: "ERRORI",   badge: tsErrors.length,  badgeColor: tsErrors.some(e=>e.sev==="error") ? "#ef4444" : "#f59e0b" },
        ] as const).map(t => (
          <button key={t.id} onClick={() => setTab(t.id)} style={{
            display: "flex", alignItems: "center", gap: 4,
            padding: "0 12px", height: "100%",
            background: tab === t.id ? "rgba(99,102,241,0.08)" : "none",
            border: "none", borderBottom: tab === t.id ? "2px solid #818cf8" : "2px solid transparent",
            cursor: "pointer",
            color: tab === t.id ? "#818cf8" : "#3a3a6a",
            fontSize: "0.6rem", fontWeight: 700, letterSpacing: "0.06em",
            transition: "color 0.15s, border-color 0.15s",
          }}>
            {t.id === "activity" ? <Zap size={10} /> : <Play size={10} />}
            {t.label}
            {t.badge > 0 && (
              <span style={{
                background: t.badgeColor,
                color: "#fff", fontSize: "0.55rem", fontWeight: 700,
                borderRadius: 4, padding: "0 3px", minWidth: 14, textAlign: "center",
              }}>
                {t.badge > 9 ? "9+" : t.badge}
              </span>
            )}
          </button>
        ))}

        {/* Right spacer + links */}
        <div style={{ flex: 1 }} />
        <button onClick={onGoToTerminal} title="Vai al terminale"
          style={{ background: "none", border: "none", cursor: "pointer",
            color: "#3a3a6a", padding: "0 8px", height: "100%", display: "flex",
            alignItems: "center", transition: "color 0.15s" }}
          onMouseEnter={e => { e.currentTarget.style.color = "#818cf8"; }}
          onMouseLeave={e => { e.currentTarget.style.color = "#3a3a6a"; }}
        >
          <Terminal size={12} />
        </button>
        <button onClick={onGoToRun} title="Vai a Esegui"
          style={{ background: "none", border: "none", cursor: "pointer",
            color: "#3a3a6a", padding: "0 8px", height: "100%", display: "flex",
            alignItems: "center", transition: "color 0.15s" }}
          onMouseEnter={e => { e.currentTarget.style.color = "#22c55e"; }}
          onMouseLeave={e => { e.currentTarget.style.color = "#3a3a6a"; }}
        >
          <Play size={12} />
        </button>
      </div>

      {/* Content — S614: passa activeTask/isStreaming come props, evita triple subscription */}
      <ShelfContent
        tab={tab}
        onGoToTerminal={onGoToTerminal}
        onGoToRun={onGoToRun}
        activeTask={activeTask}
        agentLiveStatus={agentLiveStatus}
        isStreaming={isStreaming}
        tsErrors={tsErrors}
        tsChecking={tsChecking}
        onRepairTs={_onRepairTs}
      />
    </div>
  );
});

// ─── Mobile collapseable shelf ────────────────────────────────────────────────

export const MobileOutputShelf = memo(function MobileOutputShelf({
  onGoToTerminal,
  onGoToRun,
}: {
  onGoToTerminal: () => void;
  onGoToRun: () => void;
}) {
  const [open, setOpen] = useState(false);
  const [tab, setTab]   = useState<ShelfTab>("activity");
  // S614: una sola subscription
  const activeTask     = useTaskStore(selectActiveTask);
  const isStreaming    = useChatStore(s => s.isStreaming);
  const agentLiveStatus= useChatStore(s => s.agentLiveStatus);
  const actCount = activeTask?.actions.length ?? 0;

  const setInputM = useChatStore(s => s.setInput); // Fix D: repair bridge

  // ─── Fix D: TS errors live (condivide la stessa logica del desktop) ──────
  const [tsErrors,    setTsErrorsM]   = useState<VfsTsError[]>([]);
  const [tsCheckingM, setTsCheckingM] = useState(false);
  const _mountedM = useRef(true);
  useEffect(() => { _mountedM.current = true; return () => { _mountedM.current = false; }; }, []);
  const _runTsCheckM = useCallback(async () => {
    setTsCheckingM(true);
    try {
      const errs = await runVfsTsCheck();
      if (_mountedM.current) setTsErrorsM(errs);
    } catch { /* non-fatal */ }
    finally { if (_mountedM.current) setTsCheckingM(false); }
  }, []);
  useAgentFileChanged(useCallback(() => { void _runTsCheckM(); }, [_runTsCheckM]), 600);

  const _onRepairTsM = useCallback(() => {
    if (!tsErrors.length) return;
    setInputM(formatRepairPrompt(tsErrors));
    window.dispatchEvent(new CustomEvent("agente:submit_input"));
  }, [tsErrors, setInputM]);

  // S614: auto-apre il pannello quando l'agente inizia a streammare
  const prevStreaming = useRef(false);
  useEffect(() => {
    if (isStreaming && !prevStreaming.current) {
      setOpen(true);
    }
    prevStreaming.current = isStreaming;
  }, [isStreaming]);

  return (
    <div style={{
      borderTop: "1px solid rgba(99,102,241,0.18)",
      background: "rgba(4,5,16,0.97)",
      flexShrink: 0,
      transition: "max-height 0.25s cubic-bezier(0.4,0,0.2,1)",
      maxHeight: open ? "40vh" : "30px",
      overflow: "hidden",
      display: "flex", flexDirection: "column",
    }}>
      {/* Toggle bar */}
      <button
        onClick={() => setOpen(v => !v)}
        style={{
          display: "flex", alignItems: "center", gap: 6,
          padding: "0 12px", height: 30,
          background: "none", border: "none", cursor: "pointer",
          color: "#4a4a78", fontSize: "0.62rem", fontWeight: 700,
          letterSpacing: "0.06em", width: "100%", textAlign: "left",
          flexShrink: 0,
        }}
      >
        <Zap size={10} />
        ATTIVITÀ
        {actCount > 0 && (
          <span style={{
            background: isStreaming ? "#22c55e" : "#3b82f6",
            color: "#fff", fontSize: "0.55rem", fontWeight: 700,
            borderRadius: 4, padding: "0 3px", minWidth: 14, textAlign: "center",
          }}>
            {actCount > 9 ? "9+" : actCount}
          </span>
        )}
        <span style={{ flex: 1 }} />
        {open ? <ChevronDown size={12} /> : <ChevronUp size={12} />}
      </button>

      {/* Shelf content when open */}
      {open && (
        <div style={{ display: "flex", flexDirection: "column", flex: 1, overflow: "hidden" }}>
          {/* Tabs */}
          <div style={{
            display: "flex", borderBottom: "1px solid rgba(99,102,241,0.10)",
            flexShrink: 0,
          }}>
            {(["activity", "code", "errors"] as ShelfTab[]).map(t => (
              <button key={t} onClick={() => setTab(t)} style={{
                padding: "4px 12px", background: "none",
                border: "none", borderBottom: tab === t ? "2px solid #818cf8" : "2px solid transparent",
                cursor: "pointer", color: tab === t ? "#818cf8" : "#3a3a6a",
                fontSize: "0.6rem", fontWeight: 700, letterSpacing: "0.05em",
                display: "flex", alignItems: "center", gap: 4,
              }}>
                {t === "activity" ? "ATTIVITÀ" : t === "code" ? "CODICE" : "ERRORI"}
                {t === "errors" && tsErrors.length > 0 && (
                  <span style={{
                    background: tsErrors.some(e=>e.sev==="error") ? "#ef4444" : "#f59e0b",
                    color: "#fff", fontSize: "0.52rem", fontWeight: 700,
                    borderRadius: 4, padding: "0 3px", minWidth: 14, textAlign: "center",
                  }}>
                    {tsErrors.length > 9 ? "9+" : tsErrors.length}
                  </span>
                )}
              </button>
            ))}
            <div style={{ flex: 1 }} />
            <button onClick={() => setOpen(false)} style={{
              background: "none", border: "none", cursor: "pointer",
              color: "#3a3a6a", padding: "0 10px",
            }}>
              <X size={12} />
            </button>
          </div>
          <ShelfContent
            tab={tab}
            onGoToTerminal={() => { onGoToTerminal(); setOpen(false); }}
            onGoToRun={() => { onGoToRun(); setOpen(false); }}
            activeTask={activeTask}
            agentLiveStatus={agentLiveStatus}
            isStreaming={isStreaming}
            tsErrors={tsErrors}
            tsChecking={tsCheckingM}
            onRepairTs={_onRepairTsM}
          />
        </div>
      )}
    </div>
  );
});
