import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { useCallback, useEffect, useMemo, useState } from "react";
import { Box, useApp, useInput, useStdout } from "ink";
import { getCommands, runSlashCommand } from "../commands/index.js";
import { buildRepositoryMap } from "../context/repositoryMap.js";
import { isBackspaceInput, isDeleteInput, isPrintableInput, keypressDeleteAction, } from "../keybindings/inputKeys.js";
import { commandPaletteInsertText, getCommandPaletteItems, } from "../prompt/commandPalette.js";
import { getHistorySearchItems, historySearchInsertText, } from "../prompt/historySearch.js";
import { getQuickOpenItems, quickOpenMentionText, quickOpenPathText, } from "../prompt/quickOpen.js";
import { completeSlashCommand, getSlashCommandSuggestions, } from "../prompt/commandSuggestions.js";
import { QueryEngine } from "../query/QueryEngine.js";
import { SessionStorage } from "../services/session/sessionStorage.js";
import { setCurrentSessionId } from "../services/session/resumeService.js";
import { ThemeService } from "../services/theme/themeService.js";
import { isChineseUi, normalizeUiLanguage } from "../services/ui/languageService.js";
import { stopSharedWeChatOpenClawRemoteControlService } from "../remote/wechat/service.js";
import { stopSharedWeComRemoteControlService } from "../remote/wecom/service.js";
import { useInputHistory } from "../hooks/useInputHistory.js";
import { useApprovals } from "../hooks/useApprovals.js";
import { usePromptEditor } from "../hooks/usePromptEditor.js";
import { useRuntimePermissions } from "../hooks/useRuntimePermissions.js";
import { gateDecisionOptions } from "../services/approval/gateDecisionOptions.js";
import { DeepSeekClient } from "../services/deepseek/client.js";
import { DEEPSEEK_MODEL_OPTIONS } from "../services/deepseek/models.js";
import { Composer } from "./Composer.js";
import { CommandPalette } from "./CommandPalette.js";
import { Footer } from "./Footer.js";
import { Header } from "./Header.js";
import { HistorySearchPanel } from "./HistorySearchPanel.js";
import { MemoryUsageIndicator } from "./MemoryUsageIndicator.js";
import { ModelPicker, modelPickerModel } from "./ModelPicker.js";
import { currentSessionPendingGates, PendingGatePanel } from "./PendingGatePanel.js";
import { PromptHelpPanel } from "./PromptHelpPanel.js";
import { PromptNoticePanel } from "./PromptNoticePanel.js";
import { QuickOpenPanel } from "./QuickOpenPanel.js";
import { QueuedPromptPanel } from "./QueuedPromptPanel.js";
import { SidePanel } from "./SidePanel.js";
import { StartupShellPromptPanel, startupShellChoices } from "./StartupShellPromptPanel.js";
import { groupTranscriptItems, Transcript } from "./Transcript.js";
import { setActiveTerminalTheme } from "./design/terminalTheme.js";
export function Workbench(props) {
    setActiveTerminalTheme(new ThemeService(props.config.projectPath).current().theme);
    const app = useApp();
    const { stdout } = useStdout();
    const height = stdout.rows ? Math.max(8, stdout.rows - 7) : 18;
    const columns = stdout.columns ?? 100;
    const showSidePanel = process.env.DEEPSEEKCODE_SIDE_PANEL === "1" || columns >= 150;
    const mainWidth = showSidePanel ? Math.max(48, columns - 38) : columns;
    const [activeConfig, setActiveConfig] = useState(props.config);
    const [activeProvider, setActiveProvider] = useState(props.provider);
    const [items, setItems] = useState([]);
    const [transcriptScrollOffset, setTranscriptScrollOffset] = useState(0);
    const [busy, setBusy] = useState(false);
    const [runActivity, setRunActivity] = useState(null);
    const [activityNowMs, setActivityNowMs] = useState(() => Date.now());
    const [selectedSuggestion, setSelectedSuggestion] = useState(0);
    const [paletteOpen, setPaletteOpen] = useState(false);
    const [paletteQuery, setPaletteQuery] = useState("");
    const [paletteSelected, setPaletteSelected] = useState(0);
    const [historyOpen, setHistoryOpen] = useState(false);
    const [historyEntries, setHistoryEntries] = useState([]);
    const [historyQuery, setHistoryQuery] = useState("");
    const [historySelected, setHistorySelected] = useState(0);
    const [quickOpenOpen, setQuickOpenOpen] = useState(false);
    const [quickOpenFiles, setQuickOpenFiles] = useState([]);
    const [quickOpenQuery, setQuickOpenQuery] = useState("");
    const [quickOpenSelected, setQuickOpenSelected] = useState(0);
    const [queuedPrompts, setQueuedPrompts] = useState([]);
    const [lastTurnUsage, setLastTurnUsage] = useState({});
    const [sessionUsage, setSessionUsage] = useState({});
    const [helpOpen, setHelpOpen] = useState(false);
    const [clearPromptPending, setClearPromptPending] = useState(false);
    const [sessionStartedAtMs] = useState(() => Date.now());
    const [gateSelectedIndex, setGateSelectedIndex] = useState(0);
    const [modelSelectorOpen, setModelSelectorOpen] = useState(false);
    const [modelSelectedIndex, setModelSelectedIndex] = useState(0);
    const [startupShellPromptOpen, setStartupShellPromptOpen] = useState(() => !props.config.shellEnabled && process.env.DEEPSEEKCODE_STARTUP_SHELL_PROMPT !== "0");
    const [startupShellSelectedIndex, setStartupShellSelectedIndex] = useState(0);
    const editor = usePromptEditor();
    const history = useInputHistory();
    const { permissions, setShell } = useRuntimePermissions({
        allowShell: activeConfig.shellEnabled,
        allowBrowser: activeConfig.browserEnabled,
        profile: activeConfig.permissionProfile,
    });
    const sessionStorage = useMemo(() => new SessionStorage(activeConfig.dataDir), [activeConfig.dataDir]);
    const switchModel = useCallback((model) => {
        if (busy) {
            const text = isChineseUi(activeConfig.language)
                ? "请先完成或取消当前任务，再切换模型。"
                : "Finish or cancel the current run before switching models.";
            sessionStorage.append({ role: "system", text });
            setItems((previous) => [...previous, { role: "system", text, timestamp: Date.now() }]);
            return false;
        }
        const providerConfig = activeConfig.provider
            ? { ...activeConfig.provider, model }
            : null;
        setActiveConfig((previous) => ({
            ...previous,
            model,
            provider: providerConfig,
        }));
        setActiveProvider(providerConfig ? new DeepSeekClient(providerConfig) : null);
        setModelSelectorOpen(false);
        const text = isChineseUi(activeConfig.language) ? `模型已切换到 ${model}` : `Model switched to ${model}`;
        sessionStorage.append({ role: "system", text });
        setItems((previous) => [...previous, { role: "system", text, timestamp: Date.now(), model }]);
        return true;
    }, [activeConfig, busy, sessionStorage]);
    const switchLanguage = useCallback((language) => {
        const normalized = normalizeUiLanguage(language);
        if (!normalized)
            return false;
        setActiveConfig((previous) => ({
            ...previous,
            language: normalized,
        }));
        const text = isChineseUi(normalized) ? "界面语言已切换为中文。" : "UI language switched to English.";
        sessionStorage.append({ role: "system", text });
        setItems((previous) => [...previous, { role: "system", text, timestamp: Date.now() }]);
        return true;
    }, [sessionStorage]);
    const openModelSelector = useCallback(() => {
        const current = DEEPSEEK_MODEL_OPTIONS.findIndex((option) => option.id === activeConfig.model);
        setModelSelectedIndex(Math.max(0, current));
        setModelSelectorOpen(true);
        setPaletteOpen(false);
        setHistoryOpen(false);
        setQuickOpenOpen(false);
        setHelpOpen(false);
        setClearPromptPending(false);
    }, [activeConfig.model]);
    const appendSystemMessage = useCallback((text) => {
        sessionStorage.append({ role: "system", text });
        setItems((previous) => [...previous, { role: "system", text, timestamp: Date.now() }]);
    }, [sessionStorage]);
    const appendRemoteUserMessage = useCallback((text) => {
        const message = `[wechat] ${text}`;
        sessionStorage.append({ role: "user", text: message });
        setItems((previous) => [...previous, { role: "user", text: message, timestamp: Date.now() }]);
    }, [sessionStorage]);
    const appendRemoteAssistantMessage = useCallback((text) => {
        const message = `[wechat] ${text}`;
        sessionStorage.append({ role: "assistant", text: message });
        setItems((previous) => [...previous, { role: "assistant", text: message, timestamp: Date.now(), model: activeConfig.model }]);
    }, [activeConfig.model, sessionStorage]);
    const engine = useMemo(() => new QueryEngine({
        config: activeConfig,
        state: props.state,
        provider: activeProvider,
        permissions,
        requestExit: () => app.exit(),
        requestClear: () => setItems([]),
        requestModelSelector: openModelSelector,
        switchModel,
        switchLanguage,
        emitSystemMessage: appendSystemMessage,
        emitRemoteUserMessage: appendRemoteUserMessage,
        emitRemoteAssistantMessage: appendRemoteAssistantMessage,
        awaitUserDecisions: true,
        sessionPersistence: "external",
    }), [
        activeConfig,
        activeProvider,
        props.state,
        permissions,
        app,
        openModelSelector,
        switchModel,
        switchLanguage,
        appendSystemMessage,
        appendRemoteUserMessage,
        appendRemoteAssistantMessage,
    ]);
    const commands = useMemo(() => getCommands(engine.commandContext()), [engine]);
    const suggestions = useMemo(() => paletteOpen ? [] : getSlashCommandSuggestions(commands, editor.value, editor.cursor, 5), [commands, editor.cursor, editor.value, paletteOpen]);
    const paletteItems = useMemo(() => getCommandPaletteItems(commands, paletteQuery, 9), [commands, paletteQuery]);
    const historyItems = useMemo(() => getHistorySearchItems(historyEntries, historyQuery, 9), [historyEntries, historyQuery]);
    const quickOpenItems = useMemo(() => getQuickOpenItems(quickOpenFiles, quickOpenQuery, 9), [quickOpenFiles, quickOpenQuery]);
    const transcriptEntryCount = useMemo(() => groupTranscriptItems(items).length, [items]);
    const maxTranscriptScrollOffset = Math.max(0, transcriptEntryCount - 1);
    const pendingGates = useApprovals(props.state, "pending", 20);
    const visiblePendingGates = useMemo(() => currentSessionPendingGates(pendingGates, sessionStartedAtMs), [pendingGates, sessionStartedAtMs]);
    const activeGate = visiblePendingGates[0];
    const activeGateOptions = useMemo(() => activeGate
        ? gateDecisionOptions({ gate: activeGate, projectPath: activeConfig.projectPath })
        : [], [activeGate, activeConfig.projectPath]);
    useEffect(() => {
        setCurrentSessionId(props.state, activeConfig.projectPath, sessionStorage.sessionId);
    }, [props.state, activeConfig.projectPath, sessionStorage.sessionId]);
    useEffect(() => {
        return () => {
            void stopSharedWeChatOpenClawRemoteControlService();
            void stopSharedWeComRemoteControlService();
        };
    }, []);
    useEffect(() => {
        setSelectedSuggestion((previous) => Math.min(previous, Math.max(0, suggestions.length - 1)));
    }, [suggestions.length]);
    useEffect(() => {
        setPaletteSelected((previous) => Math.min(previous, Math.max(0, paletteItems.length - 1)));
    }, [paletteItems.length]);
    useEffect(() => {
        setHistorySelected((previous) => Math.min(previous, Math.max(0, historyItems.length - 1)));
    }, [historyItems.length]);
    useEffect(() => {
        setQuickOpenSelected((previous) => Math.min(previous, Math.max(0, quickOpenItems.length - 1)));
    }, [quickOpenItems.length]);
    useEffect(() => {
        setGateSelectedIndex((previous) => Math.min(previous, Math.max(0, activeGateOptions.length - 1)));
    }, [activeGate?.id, activeGateOptions.length]);
    useEffect(() => {
        setTranscriptScrollOffset((previous) => Math.min(previous, maxTranscriptScrollOffset));
    }, [maxTranscriptScrollOffset]);
    useEffect(() => {
        setModelSelectedIndex((previous) => Math.min(previous, Math.max(0, DEEPSEEK_MODEL_OPTIONS.length - 1)));
    }, []);
    useEffect(() => {
        if (busy || queuedPrompts.length === 0)
            return;
        const nextPrompt = queuedPrompts[0];
        if (!nextPrompt)
            return;
        setQueuedPrompts((previous) => previous.slice(1));
        void submit(nextPrompt, { resetEditor: false });
    }, [busy, queuedPrompts]);
    useEffect(() => {
        if (!clearPromptPending)
            return;
        const timeout = setTimeout(() => setClearPromptPending(false), 900);
        return () => clearTimeout(timeout);
    }, [clearPromptPending]);
    useEffect(() => {
        if (process.env.DEEPSEEKCODE_MOUSE === "0")
            return;
        stdout.write("\x1b[?1000h\x1b[?1006h");
        return () => {
            stdout.write("\x1b[?1000l\x1b[?1006l");
        };
    }, [stdout]);
    useEffect(() => {
        if (!busy)
            return;
        const timer = setInterval(() => setActivityNowMs(Date.now()), 1000);
        return () => clearInterval(timer);
    }, [busy]);
    useInput((character, key) => {
        const mouseWheelDelta = mouseWheelDeltaFromInput(character);
        if (mouseWheelDelta !== 0) {
            scrollTranscript(mouseWheelDelta);
            return;
        }
        if (isMouseInput(character)) {
            return;
        }
        if (key.ctrl && character === "c") {
            if (busy && engine.cancelActiveRun()) {
                setQueuedPrompts([]);
                const text = isChineseUi(activeConfig.language) ? "姝ｅ湪鍙栨秷褰撳墠浠诲姟..." : "Cancelling current run...";
                setItems((previous) => [
                    ...previous,
                    { role: "system", text, timestamp: Date.now() },
                ]);
                return;
            }
            app.exit();
            return;
        }
        if (handleModelSelectorInput(character, key)) {
            return;
        }
        if (handleStartupShellPromptInput(character, key)) {
            return;
        }
        if (handleGatePromptInput(character, key)) {
            return;
        }
        if (helpOpen) {
            if (key.escape || (character === "?" && editor.value.length === 0)) {
                setHelpOpen(false);
                return;
            }
            if (isPrintableInput(character, key) || key.return || key.tab) {
                setHelpOpen(false);
            }
        }
        if (quickOpenOpen) {
            if (key.escape) {
                closeQuickOpen();
                return;
            }
            if (key.return) {
                insertQuickOpenFile(true);
                return;
            }
            if (key.tab) {
                insertQuickOpenFile(false);
                return;
            }
            if (key.upArrow) {
                setQuickOpenSelected((previous) => (quickOpenItems.length === 0 ? 0 : (previous - 1 + quickOpenItems.length) % quickOpenItems.length));
                return;
            }
            if (key.downArrow) {
                setQuickOpenSelected((previous) => (quickOpenItems.length === 0 ? 0 : (previous + 1) % quickOpenItems.length));
                return;
            }
            if (handleDeleteKeyInput(character, key)) {
                return;
            }
            if (key.ctrl && character === "u") {
                setQuickOpenQuery("");
                setQuickOpenSelected(0);
                return;
            }
            if (isPrintableInput(character, key)) {
                setQuickOpenQuery((previous) => previous + character);
                setQuickOpenSelected(0);
            }
            return;
        }
        if (historyOpen) {
            if (key.escape) {
                closeHistorySearch();
                return;
            }
            if (key.return || key.tab) {
                insertHistoryPrompt();
                return;
            }
            if (key.upArrow) {
                setHistorySelected((previous) => (historyItems.length === 0 ? 0 : (previous - 1 + historyItems.length) % historyItems.length));
                return;
            }
            if (key.downArrow) {
                setHistorySelected((previous) => (historyItems.length === 0 ? 0 : (previous + 1) % historyItems.length));
                return;
            }
            if (handleDeleteKeyInput(character, key)) {
                return;
            }
            if (key.ctrl && character === "u") {
                setHistoryQuery("");
                setHistorySelected(0);
                return;
            }
            if (isPrintableInput(character, key)) {
                setHistoryQuery((previous) => previous + character);
                setHistorySelected(0);
            }
            return;
        }
        if (paletteOpen) {
            if (key.escape) {
                closePalette();
                return;
            }
            if (key.return || key.tab) {
                insertPaletteCommand();
                return;
            }
            if (key.upArrow) {
                setPaletteSelected((previous) => (paletteItems.length === 0 ? 0 : (previous - 1 + paletteItems.length) % paletteItems.length));
                return;
            }
            if (key.downArrow) {
                setPaletteSelected((previous) => (paletteItems.length === 0 ? 0 : (previous + 1) % paletteItems.length));
                return;
            }
            if (handleDeleteKeyInput(character, key)) {
                return;
            }
            if (key.ctrl && character === "u") {
                setPaletteQuery("");
                setPaletteSelected(0);
                return;
            }
            if (isPrintableInput(character, key)) {
                setPaletteQuery((previous) => previous + character);
                setPaletteSelected(0);
            }
            return;
        }
        if (clearPromptPending && !key.escape) {
            setClearPromptPending(false);
        }
        if (key.escape) {
            if (editor.value.length > 0) {
                if (clearPromptPending) {
                    editor.reset();
                    setClearPromptPending(false);
                }
                else {
                    setClearPromptPending(true);
                }
            }
            return;
        }
        if (key.ctrl && character === "o") {
            setHelpOpen(false);
            setClearPromptPending(false);
            openQuickOpen();
            return;
        }
        if (key.ctrl && character === "r") {
            setHelpOpen(false);
            setClearPromptPending(false);
            setHistoryEntries(history.snapshot({ newestFirst: true }));
            setHistoryQuery(editor.value);
            setHistorySelected(0);
            setHistoryOpen(true);
            return;
        }
        if (key.ctrl && character === "p") {
            setHelpOpen(false);
            setClearPromptPending(false);
            setPaletteQuery(editor.value.startsWith("/") ? editor.value.slice(1) : "");
            setPaletteSelected(0);
            setPaletteOpen(true);
            return;
        }
        if (editor.value === "/model" && (key.return || key.tab)) {
            openModelSelector();
            editor.reset();
            return;
        }
        if (character === "?" && editor.value.length === 0 && !key.ctrl && !key.meta) {
            setHelpOpen(true);
            setClearPromptPending(false);
            return;
        }
        if (key.return && key.shift) {
            editor.dispatch({ type: "insert", text: "\n" });
            return;
        }
        if (key.tab && suggestions.length > 0) {
            const index = key.shift
                ? (selectedSuggestion - 1 + suggestions.length) % suggestions.length
                : selectedSuggestion;
            const completion = completeSlashCommand(editor.value, editor.cursor, suggestions[index]);
            editor.set(completion.value, completion.cursor);
            setSelectedSuggestion(0);
            return;
        }
        if (key.return && suggestions.length > 0 && shouldCompleteSelectedSuggestion(editor.value, suggestions[selectedSuggestion]?.name)) {
            const completion = completeSlashCommand(editor.value, editor.cursor, suggestions[selectedSuggestion]);
            editor.set(completion.value, completion.cursor);
            setSelectedSuggestion(0);
            return;
        }
        if (isPageUpKey(key)) {
            scrollTranscript(10);
            return;
        }
        if (isPageDownKey(key)) {
            scrollTranscript(-10);
            return;
        }
        if (key.return) {
            if (busy) {
                if (isImmediateBusyCommand(editor.value)) {
                    void runImmediateSlashCommand(editor.value);
                }
                else {
                    queuePrompt(editor.value);
                }
            }
            else {
                void submit(editor.value);
            }
            return;
        }
        if (handleDeleteKeyInput(character, key)) {
            return;
        }
        if (key.leftArrow) {
            editor.dispatch({ type: "moveLeft" });
            return;
        }
        if (key.rightArrow) {
            editor.dispatch({ type: "moveRight" });
            return;
        }
        if (key.upArrow) {
            if (suggestions.length > 0) {
                setSelectedSuggestion((previous) => (previous - 1 + suggestions.length) % suggestions.length);
                return;
            }
            if (key.ctrl) {
                scrollTranscript(1);
                return;
            }
            const previous = history.previous(editor.value);
            if (previous !== null)
                editor.set(previous, "end");
            return;
        }
        if (key.downArrow) {
            if (suggestions.length > 0) {
                setSelectedSuggestion((previous) => (previous + 1) % suggestions.length);
                return;
            }
            if (key.ctrl) {
                scrollTranscript(-1);
                return;
            }
            const next = history.next();
            if (next !== null)
                editor.set(next, "end");
            return;
        }
        if (key.ctrl && character === "a") {
            editor.dispatch({ type: "moveStart" });
            return;
        }
        if (key.ctrl && character === "e") {
            editor.dispatch({ type: "moveEnd" });
            return;
        }
        if (key.ctrl && character === "u") {
            editor.dispatch({ type: "clearBefore" });
            return;
        }
        if (key.ctrl && character === "k") {
            editor.dispatch({ type: "clearAfter" });
            return;
        }
        if (key.ctrl && character === "w") {
            editor.dispatch({ type: "deleteWordBefore" });
            return;
        }
        if (isPrintableInput(character, key)) {
            editor.dispatch({ type: "insert", text: character });
            setSelectedSuggestion(0);
        }
    });
    function handleGatePromptInput(character, key) {
        if (!activeGate || activeGateOptions.length === 0)
            return false;
        if (quickOpenOpen || historyOpen || paletteOpen || helpOpen)
            return false;
        const typedAnswerCommand = gateTypedQuestionAnswerCommand(activeGate.subjectType, editor.value);
        if (editor.value.trim()) {
            if (key.return && typedAnswerCommand) {
                editor.reset();
                setClearPromptPending(false);
                void applyGateCommand(typedAnswerCommand);
                return true;
            }
            return false;
        }
        if (key.upArrow) {
            setGateSelectedIndex((previous) => (activeGateOptions.length === 0 ? 0 : (previous - 1 + activeGateOptions.length) % activeGateOptions.length));
            return true;
        }
        if (key.downArrow || key.tab) {
            setGateSelectedIndex((previous) => (activeGateOptions.length === 0 ? 0 : (previous + (key.shift ? -1 : 1) + activeGateOptions.length) % activeGateOptions.length));
            return true;
        }
        if (key.return) {
            void applyGateDecision(activeGateOptions[gateSelectedIndex] ?? activeGateOptions[0]);
            return true;
        }
        if (key.escape) {
            const cancel = activeGateOptions.find((option) => option.tone === "neutral")
                ?? activeGateOptions.find((option) => option.tone === "reject");
            if (cancel)
                void applyGateDecision(cancel);
            return true;
        }
        const lower = character.toLowerCase();
        if (/^[1-9]$/.test(character)) {
            const option = activeGateOptions[Number(character) - 1];
            if (option)
                void applyGateDecision(option);
            return true;
        }
        const directShortcut = gateDirectShortcutIntent(activeGate.subjectType, editor.value, lower);
        if (directShortcut === "allow") {
            const allow = activeGateOptions.find((option) => option.tone === "allow");
            if (allow)
                void applyGateDecision(allow);
            return true;
        }
        if (directShortcut === "reject") {
            const reject = activeGateOptions.find((option) => option.tone === "reject");
            if (reject)
                void applyGateDecision(reject);
            return true;
        }
        if (lower === "s") {
            const session = activeGateOptions.find((option) => option.command.includes("shell-session"));
            if (session) {
                void applyGateDecision(session);
                return true;
            }
        }
        if (isPrintableInput(character, key)) {
            return false;
        }
        return false;
    }
    function handleStartupShellPromptInput(character, key) {
        if (!startupShellPromptOpen)
            return false;
        if (key.upArrow) {
            setStartupShellSelectedIndex((previous) => ((previous - 1 + startupShellChoices.length) % startupShellChoices.length));
            return true;
        }
        if (key.downArrow || key.tab) {
            setStartupShellSelectedIndex((previous) => ((previous + (key.shift ? -1 : 1) + startupShellChoices.length) % startupShellChoices.length));
            return true;
        }
        const lower = character.toLowerCase();
        if (key.return || lower === "y" || lower === "a") {
            applyStartupShellChoice(startupShellChoices[startupShellSelectedIndex] ?? "enable");
            return true;
        }
        if (key.escape || lower === "n") {
            applyStartupShellChoice("ask");
            return true;
        }
        if (/^[12]$/.test(character)) {
            applyStartupShellChoice(startupShellChoices[Number(character) - 1] ?? "ask");
            return true;
        }
        return true;
    }
    function applyStartupShellChoice(choice) {
        setStartupShellPromptOpen(false);
        setStartupShellSelectedIndex(0);
        const zh = isChineseUi(activeConfig.language);
        if (choice === "enable") {
            setShell(true);
            setActiveConfig((previous) => ({
                ...previous,
                shellEnabled: true,
                permissionProfile: previous.permissionProfile === "safe" ? "dev" : previous.permissionProfile,
            }));
            const text = zh
                ? "本次 TUI 会话已开启 shell 权限。"
                : "Shell permission is enabled for this TUI session.";
            sessionStorage.append({ role: "system", text });
            setItems((previous) => [...previous, { role: "system", text, timestamp: Date.now() }]);
            return;
        }
        const text = zh
            ? "shell 保持关闭；需要执行命令时会再弹出权限选择。"
            : "Shell stays off; command execution will ask again when needed.";
        sessionStorage.append({ role: "system", text });
        setItems((previous) => [...previous, { role: "system", text, timestamp: Date.now() }]);
    }
    async function applyGateDecision(option) {
        if (!option)
            return;
        if (option.command.includes("<")) {
            editor.set(option.command.replace(/<[^>]+>/g, "").trimEnd() + " ", "end");
            return;
        }
        await applyGateCommand(option.command);
    }
    async function applyGateCommand(command) {
        const result = await runSlashCommand(command, engine.commandContext());
        applyCommandResult(result, command);
        if (result.submit) {
            if (busy) {
                setQueuedPrompts((previous) => [...previous, result.submit]);
            }
            else {
                void submit(result.submit, { resetEditor: false });
            }
        }
        if (result.exit)
            app.exit();
    }
    async function runImmediateSlashCommand(value) {
        const text = value.trim();
        if (!text)
            return;
        editor.reset();
        setClearPromptPending(false);
        setSelectedSuggestion(0);
        history.add(text);
        setItems((previous) => appendUserIfMissing(previous, text, Date.now()));
        const zh = isChineseUi(activeConfig.language);
        const statusText = zh
            ? `旁路执行命令：${text}`
            : `Running side command: ${text}`;
        setItems((previous) => [...previous, { role: "system", text: statusText, timestamp: Date.now() }]);
        try {
            const result = await runSlashCommand(text, immediateCommandContext());
            applyCommandResult(result, text);
            if (result.submit) {
                setQueuedPrompts((previous) => [...previous, result.submit]);
            }
            if (result.exit)
                app.exit();
        }
        catch (error) {
            const message = error instanceof Error ? error.message : String(error);
            const failure = zh ? `旁路命令失败：${message}` : `Side command failed: ${message}`;
            sessionStorage.append({ role: "error", text: failure });
            setItems((previous) => [...previous, { role: "error", text: failure, timestamp: Date.now() }]);
        }
    }
    function immediateCommandContext() {
        const provider = activeConfig.provider ? new DeepSeekClient(activeConfig.provider) : activeProvider;
        return {
            ...engine.commandContext(),
            provider,
            recordUsageEvent: (usage) => {
                setLastTurnUsage((previous) => addUsage(previous, usage));
                setSessionUsage((previous) => addUsage(previous, usage));
            },
        };
    }
    function applyCommandResult(result, fallbackText) {
        if (result.clear) {
            setItems([]);
        }
        if (result.display) {
            sessionStorage.append({ role: "system", text: result.message ?? fallbackText });
            setItems((previous) => [
                ...previous,
                { role: "display", text: result.message ?? "", display: result.display, timestamp: Date.now() },
            ]);
        }
        else if (result.message) {
            const message = result.message;
            sessionStorage.append({ role: "system", text: message });
            setItems((previous) => [...previous, { role: "system", text: message, timestamp: Date.now() }]);
        }
    }
    function handleBackspaceInput() {
        if (quickOpenOpen) {
            setQuickOpenQuery((previous) => previous.slice(0, -1));
            return;
        }
        if (historyOpen) {
            setHistoryQuery((previous) => previous.slice(0, -1));
            return;
        }
        if (paletteOpen) {
            setPaletteQuery((previous) => previous.slice(0, -1));
            return;
        }
        editor.dispatch({ type: "backspace" });
    }
    function handleDeleteInput() {
        if (quickOpenOpen) {
            setQuickOpenQuery((previous) => previous.slice(0, -1));
            return;
        }
        if (historyOpen) {
            setHistoryQuery((previous) => previous.slice(0, -1));
            return;
        }
        if (paletteOpen) {
            setPaletteQuery((previous) => previous.slice(0, -1));
            return;
        }
        editor.dispatch({ type: "delete" });
    }
    function handleDeleteKeyInput(character, key) {
        const action = keypressDeleteAction(character, key);
        if (action === "backspace" || (!action && isBackspaceInput(character, key))) {
            handleBackspaceInput();
            return true;
        }
        if (action === "delete" || (!action && isDeleteInput(character, key))) {
            handleDeleteInput();
            return true;
        }
        return false;
    }
    function closePalette() {
        setPaletteOpen(false);
        setPaletteQuery("");
        setPaletteSelected(0);
    }
    function insertPaletteCommand() {
        const item = paletteItems[paletteSelected];
        if (!item)
            return;
        const text = commandPaletteInsertText(item);
        editor.set(text, "end");
        closePalette();
    }
    function closeHistorySearch() {
        setHistoryOpen(false);
        setHistoryQuery("");
        setHistorySelected(0);
    }
    function insertHistoryPrompt() {
        const item = historyItems[historySelected];
        if (!item)
            return;
        editor.set(historySearchInsertText(item), "end");
        closeHistorySearch();
    }
    function openQuickOpen() {
        try {
            setQuickOpenFiles(buildRepositoryMap(activeConfig.projectPath, 800).files);
        }
        catch {
            setQuickOpenFiles([]);
        }
        const mentionMatch = /@([^\s]*)$/.exec(editor.value.slice(0, editor.cursor));
        setQuickOpenQuery(mentionMatch?.[1] ?? "");
        setQuickOpenSelected(0);
        setQuickOpenOpen(true);
    }
    function closeQuickOpen() {
        setQuickOpenOpen(false);
        setQuickOpenQuery("");
        setQuickOpenSelected(0);
    }
    function insertQuickOpenFile(asMention) {
        const item = quickOpenItems[quickOpenSelected];
        if (!item)
            return;
        const text = asMention ? quickOpenMentionText(item) : quickOpenPathText(item);
        const beforeCursor = editor.value.slice(0, editor.cursor);
        const afterCursor = editor.value.slice(editor.cursor);
        const mentionMatch = /@([^\s]*)$/.exec(beforeCursor);
        if (mentionMatch) {
            const start = beforeCursor.length - mentionMatch[0].length;
            const nextValue = `${beforeCursor.slice(0, start)}${text}${afterCursor}`;
            editor.set(nextValue, start + text.length);
        }
        else {
            const nextValue = `${beforeCursor}${text}${afterCursor}`;
            editor.set(nextValue, beforeCursor.length + text.length);
        }
        closeQuickOpen();
    }
    function queuePrompt(value) {
        const text = value.trim();
        if (!text)
            return;
        setQueuedPrompts((previous) => [...previous, text]);
        editor.reset();
        setClearPromptPending(false);
        setSelectedSuggestion(0);
    }
    function updateRunActivity(phase, text, detail) {
        const now = Date.now();
        setActivityNowMs(now);
        setRunActivity((previous) => {
            const sameActivity = previous
                && previous.phase === phase
                && previous.text === text
                && previous.detail === detail;
            return {
                phase,
                text,
                detail,
                startedAtMs: sameActivity ? previous.startedAtMs : now,
                updatedAtMs: now,
            };
        });
    }
    function touchRunActivity(phase, text, detail) {
        const now = Date.now();
        setActivityNowMs(now);
        setRunActivity((previous) => {
            if (!previous) {
                return {
                    phase,
                    text,
                    detail,
                    startedAtMs: now,
                    updatedAtMs: now,
                };
            }
            if (previous.phase !== phase || previous.text !== text || previous.detail !== detail) {
                return {
                    phase,
                    text,
                    detail,
                    startedAtMs: now,
                    updatedAtMs: now,
                };
            }
            return {
                ...previous,
                updatedAtMs: now,
            };
        });
    }
    async function submit(value, options = {}) {
        const text = value.trim();
        if (!text)
            return;
        setTranscriptScrollOffset(0);
        if (options.resetEditor ?? true)
            editor.reset();
        setClearPromptPending(false);
        history.add(text);
        setItems((previous) => appendUserIfMissing(previous, text, Date.now()));
        setBusy(true);
        updateRunActivity("starting", "Starting run", activeConfig.model);
        setLastTurnUsage({});
        let streamingAssistant = "";
        let reasoningText = "";
        let turnUsage = {};
        try {
            for await (const event of engine.submit(text)) {
                if (event.type === "user") {
                    sessionStorage.append({ role: "user", text: event.text });
                    setItems((previous) => appendUserIfMissing(previous, event.text, Date.now()));
                }
                else if (event.type === "assistant_delta") {
                    touchRunActivity("chatting", "Streaming answer", activeConfig.model);
                    streamingAssistant += event.text;
                    setItems((previous) => replaceStreamingAssistant(previous, streamingAssistant, activeConfig.model));
                }
                else if (event.type === "assistant") {
                    updateRunActivity("finishing", "Preparing final response", activeConfig.model);
                    streamingAssistant = "";
                    if (reasoningText.trim()) {
                        setItems((previous) => markThinkingDone(previous, turnUsage));
                    }
                    sessionStorage.append({ role: "assistant", text: event.text });
                    setItems((previous) => replaceFinalAssistant(previous, event.text, activeConfig.model));
                }
                else if (event.type === "reasoning_delta") {
                    touchRunActivity("planning", "Receiving model reasoning", activeConfig.model);
                    reasoningText += event.text;
                    setItems((previous) => replaceThinkingLine(previous, reasoningText));
                }
                else if (event.type === "usage") {
                    touchRunActivity(runActivity?.phase ?? "planning", "Updating usage", activeConfig.model);
                    const nextTurnUsage = addUsage(turnUsage, event.usage);
                    turnUsage = nextTurnUsage;
                    setLastTurnUsage(nextTurnUsage);
                    setSessionUsage((previous) => addUsage(previous, event.usage));
                    if (reasoningText.trim()) {
                        setItems((previous) => markThinkingDone(previous, nextTurnUsage));
                    }
                }
                else if (event.type === "tool_start") {
                    updateRunActivity("tool", "Running tool", event.text);
                    setItems((previous) => [...previous, { role: "tool-start", text: event.text, timestamp: Date.now() }]);
                }
                else if (event.type === "tool_result") {
                    touchRunActivity("tool", "Tool result received", event.text.split("\n")[0]);
                    setItems((previous) => [...previous, { role: "tool", text: event.text, timestamp: Date.now() }]);
                }
                else if (event.type === "command") {
                    sessionStorage.append({ role: "system", text: event.text });
                    setItems((previous) => [...previous, { role: "system", text: event.text, timestamp: Date.now() }]);
                }
                else if (event.type === "command_display") {
                    sessionStorage.append({ role: "system", text: event.fallbackText ?? "[command display]" });
                    setItems((previous) => [
                        ...previous,
                        { role: "display", text: event.fallbackText ?? "", display: event.display, timestamp: Date.now() },
                    ]);
                }
                else if (event.type === "error") {
                    sessionStorage.append({ role: "error", text: event.text });
                    setItems((previous) => [...previous, { role: "error", text: event.text, timestamp: Date.now() }]);
                }
                else if (event.type === "status") {
                    updateRunActivity(event.phase, event.text, event.detail);
                }
            }
        }
        finally {
            setBusy(false);
            setRunActivity(null);
        }
    }
    function scrollTranscript(delta) {
        setClearPromptPending(false);
        setTranscriptScrollOffset((previous) => {
            const next = Math.max(0, Math.min(maxTranscriptScrollOffset, previous + delta));
            return next;
        });
    }
    function handleModelSelectorInput(character, key) {
        if (!modelSelectorOpen)
            return false;
        if (key.escape) {
            setModelSelectorOpen(false);
            return true;
        }
        if (key.upArrow) {
            setModelSelectedIndex((previous) => (DEEPSEEK_MODEL_OPTIONS.length === 0
                ? 0
                : (previous - 1 + DEEPSEEK_MODEL_OPTIONS.length) % DEEPSEEK_MODEL_OPTIONS.length));
            return true;
        }
        if (key.downArrow || key.tab) {
            setModelSelectedIndex((previous) => (DEEPSEEK_MODEL_OPTIONS.length === 0
                ? 0
                : (previous + (key.shift ? -1 : 1) + DEEPSEEK_MODEL_OPTIONS.length) % DEEPSEEK_MODEL_OPTIONS.length));
            return true;
        }
        if (key.return) {
            const option = DEEPSEEK_MODEL_OPTIONS[modelSelectedIndex];
            if (option)
                switchModel(option.id);
            return true;
        }
        if (/^[1-9]$/.test(character)) {
            const option = DEEPSEEK_MODEL_OPTIONS[Number(character) - 1];
            if (option)
                switchModel(option.id);
            return true;
        }
        return true;
    }
    return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Header, { config: activeConfig, provider: activeProvider }), _jsxs(Box, { children: [_jsx(Box, { flexGrow: 1, flexDirection: "column", marginRight: showSidePanel ? 1 : 0, children: _jsx(Transcript, { items: items, height: height, width: mainWidth, scrollOffset: transcriptScrollOffset, providerReady: Boolean(activeProvider), model: activeConfig.model, projectPath: activeConfig.projectPath, permissionProfile: permissions.profile ?? activeConfig.permissionProfile, shellEnabled: permissions.allowShell, browserEnabled: permissions.allowBrowser, language: activeConfig.language }) }), showSidePanel && (_jsx(SidePanel, { config: activeConfig, state: props.state, busy: busy, permissions: permissions, lastTurnUsage: lastTurnUsage, sessionUsage: sessionUsage }))] }), _jsx(PendingGatePanel, { projectPath: activeConfig.projectPath, state: props.state, sessionStartedAtMs: sessionStartedAtMs, gates: pendingGates, selectedDecisionIndex: gateSelectedIndex }), startupShellPromptOpen && (_jsx(StartupShellPromptPanel, { selectedIndex: startupShellSelectedIndex, projectPath: activeConfig.projectPath, language: activeConfig.language, width: columns })), helpOpen && (_jsx(PromptHelpPanel, { width: columns, busy: busy, language: activeConfig.language })), paletteOpen && (_jsx(CommandPalette, { commands: commands, query: paletteQuery, selectedIndex: paletteSelected, width: columns })), historyOpen && (_jsx(HistorySearchPanel, { entries: historyEntries, query: historyQuery, selectedIndex: historySelected, width: columns })), quickOpenOpen && (_jsx(QuickOpenPanel, { projectPath: activeConfig.projectPath, files: quickOpenFiles, query: quickOpenQuery, selectedIndex: quickOpenSelected, width: columns })), modelSelectorOpen && (_jsx(Box, { paddingX: 1, marginTop: 1, children: _jsx(ModelPicker, { model: modelPickerModel({
                        activeModel: activeConfig.model,
                        providerName: activeConfig.provider?.name,
                        providerReady: Boolean(activeProvider),
                        selectedIndex: modelSelectedIndex,
                    }), width: Math.max(48, columns - 2) }) })), _jsx(QueuedPromptPanel, { prompts: queuedPrompts, width: columns }), _jsx(MemoryUsageIndicator, { width: columns }), clearPromptPending && (_jsx(PromptNoticePanel, { kind: "clear-pending", width: columns })), _jsx(Composer, { value: editor.value, cursor: editor.cursor, busy: busy, queuedCount: queuedPrompts.length, width: columns, suggestions: suggestions, selectedSuggestion: selectedSuggestion, activePromptHint: startupShellPromptOpen
                    ? startupShellComposerHint(activeConfig.language)
                    : activeGate
                        ? gateComposerHint(activeGate.subjectType, activeConfig.language)
                        : undefined, language: activeConfig.language, activity: runActivity, activityNowMs: activityNowMs }), _jsx(Footer, { busy: busy, queuedCount: queuedPrompts.length, permissions: permissions, config: activeConfig, state: props.state, sessionStartedAtMs: sessionStartedAtMs, lastTurnUsage: lastTurnUsage, sessionUsage: sessionUsage, providerReady: Boolean(activeProvider), width: columns, compact: !showSidePanel, transcriptScrollOffset: transcriptScrollOffset, activity: runActivity, activityNowMs: activityNowMs })] }));
}
function gateComposerHint(subjectType, language = "zh-CN") {
    const zh = isChineseUi(language === "en" ? "en" : "zh-CN");
    if (subjectType === "question") {
        return zh
            ? "问题等待回答：直接输入答案，或用方向键/数字选择，Esc 拒绝。"
            : "Answer prompt active: type an answer, choose a number, or Esc to reject.";
    }
    if (subjectType === "plan") {
        return zh
            ? "计划等待确认：Up/Down 选择，Enter/Y 通过，N 拒绝，Esc 取消。"
            : "Plan approval active: use Up/Down, Enter/Y to approve, N to reject, Esc to cancel.";
    }
    return zh
        ? "权限等待确认：Up/Down 选择，Enter/Y 允许一次，S 本会话允许 shell，N 拒绝，Esc 取消。"
        : "Permission prompt active: use Up/Down, Enter/Y to allow once, S to allow shell for this session, N to reject, Esc to cancel.";
}
function startupShellComposerHint(language = "zh-CN") {
    const zh = isChineseUi(language === "en" ? "en" : "zh-CN");
    return zh
        ? "启动权限等待选择：Up/Down 选择，Enter/Y 开启 shell，N/Esc 保持关闭。"
        : "Startup permission prompt: Up/Down to choose, Enter/Y to enable shell, N/Esc to keep it off.";
}
function appendUserIfMissing(items, text, timestamp) {
    const last = items[items.length - 1];
    if (last?.role === "user" && last.text === text)
        return items;
    return [...items, { role: "user", text, timestamp }];
}
export function gateTypedQuestionAnswerCommand(subjectType, value) {
    const answer = value.trim();
    if (subjectType !== "question" || !answer || answer.startsWith("/"))
        return null;
    return `/question answer latest ${answer}`;
}
function shouldCompleteSelectedSuggestion(value, commandName) {
    if (!commandName)
        return false;
    const trimmed = value.trim();
    if (!trimmed.startsWith("/") || /\s/.test(trimmed))
        return false;
    return trimmed !== `/${commandName}`;
}
const IMMEDIATE_BUSY_COMMANDS = new Set([
    "ask",
    "status",
    "remote-control",
    "remote",
    "wecom",
    "queue",
    "runs",
    "events",
    "trace",
    "artifacts",
    "usage",
    "cost",
    "approval",
    "question",
    "plan",
    "permissions",
    "shell",
    "browser",
    "agents",
    "mcp",
    "skills",
    "tools",
    "cancel",
    "pause",
    "run-resume",
    "unpause",
    "retry",
]);
function isImmediateBusyCommand(value) {
    const match = value.trim().match(/^\/([a-zA-Z][\w-]*)/);
    if (!match)
        return false;
    return IMMEDIATE_BUSY_COMMANDS.has(match[1].toLowerCase());
}
function isPageUpKey(key) {
    return Boolean(key.pageUp)
        || Boolean(key.pageup);
}
function isPageDownKey(key) {
    return Boolean(key.pageDown)
        || Boolean(key.pagedown);
}
function mouseWheelDeltaFromInput(input) {
    const button = mouseButtonCodeFromInput(input);
    if (button === null || (button & 64) !== 64)
        return 0;
    return (button & 1) === 0 ? 3 : -3;
}
function isMouseInput(input) {
    return containsMouseInput(input);
}
function mouseButtonCodeFromInput(input) {
    if (!input)
        return null;
    const sgrMatch = /(?:\x1b)?\[<(\d+);\d+;\d+([mM])/.exec(input);
    if (sgrMatch) {
        if (sgrMatch[2] === "m")
            return null;
        return Number.parseInt(sgrMatch[1] ?? "", 10);
    }
    const x10Match = /(?:\x1b)?\[M([\s\S])([\s\S])([\s\S])/.exec(input);
    if (!x10Match)
        return null;
    return x10Match[1].charCodeAt(0) - 32;
}
function containsMouseInput(input) {
    if (!input)
        return false;
    return /(?:\x1b)?\[<\d+;\d+;\d+[mM]/.test(input)
        || /(?:\x1b)?\[M[\s\S]{3}/.test(input);
}
export function gateDirectShortcutIntent(subjectType, currentPrompt, character) {
    if (currentPrompt.trim() || subjectType === "question")
        return null;
    const lower = character.toLowerCase();
    if (lower === "y" || lower === "a")
        return "allow";
    if (lower === "n" || lower === "r")
        return "reject";
    return null;
}
function replaceStreamingAssistant(items, text, model) {
    const previousStreaming = items.at(-1);
    const timestamp = previousStreaming?.role === "assistant" && previousStreaming.streaming
        ? previousStreaming.timestamp
        : Date.now();
    const cleaned = dropStreamingAssistant(items);
    return [...cleaned, { role: "assistant", text, timestamp, model, streaming: true }];
}
function replaceFinalAssistant(items, text, model) {
    const previousStreaming = items.at(-1);
    const timestamp = previousStreaming?.role === "assistant" && previousStreaming.streaming
        ? previousStreaming.timestamp
        : Date.now();
    const cleaned = dropStreamingAssistant(items);
    return [...cleaned, { role: "assistant", text, timestamp, model }];
}
function dropStreamingAssistant(items) {
    const last = items.at(-1);
    if (last?.role !== "assistant" || !last.streaming)
        return items;
    return items.slice(0, -1);
}
function replaceThinkingLine(items, text) {
    const normalized = text.trim() || "thinking...";
    if (items.at(-1)?.role === "thinking") {
        return [...items.slice(0, -1), { role: "thinking", text: normalized }];
    }
    return [...items, { role: "thinking", text: normalized }];
}
function markThinkingDone(items, usage) {
    const last = items.at(-1);
    if (last?.role !== "thinking")
        return items;
    if (/thinking done/.test(last.text))
        return items;
    const suffix = usageSummary(usage);
    return [
        ...items.slice(0, -1),
        {
            ...last,
            text: `${last.text}${suffix ? `\nthinking done - ${suffix}` : "\nthinking done"}`,
        },
    ];
}
function addUsage(left, right) {
    return {
        inputTokens: addNumber(left.inputTokens, right.inputTokens),
        outputTokens: addNumber(left.outputTokens, right.outputTokens),
        cacheHitTokens: addNumber(left.cacheHitTokens, right.cacheHitTokens),
        cacheMissTokens: addNumber(left.cacheMissTokens, right.cacheMissTokens),
    };
}
function addNumber(left, right) {
    if (left === undefined)
        return right;
    if (right === undefined)
        return left;
    return left + right;
}
function usageSummary(usage) {
    const output = usage.outputTokens ?? 0;
    const hit = usage.cacheHitTokens ?? 0;
    const miss = usage.cacheMissTokens ?? 0;
    const cache = hit + miss > 0 ? `cache ${Math.round((hit / (hit + miss)) * 100)}%` : "";
    return [`tokens+${output}`, cache].filter(Boolean).join(" - ");
}
