Дизайн компактного режима: конкурентный анализ и оптимизация
Переключение компактного/подробного режима по Ctrl+O — конкурентный анализ с Claude Code, обзор текущей реализации и рекомендации по оптимизации.
Документация для пользователей: Settings — ui.compactMode.
1. Основные выводы
Qwen Code и Claude Code предоставляют сочетание клавиш Ctrl+O для переключения между компактным и подробным режимами вывода инструментов, однако философия дизайна, состояние по умолчанию и модель взаимодействия принципиально различаются. В этом документе представлен детальный сравнительный анализ на уровне исходного кода, выявлены пробелы в UX и предложены оптимизации для Qwen Code.
| Параметр | Claude Code | Qwen Code |
|---|---|---|
| Режим по умолчанию | Компактный (verbose=false) | Подробный (compactMode=false) |
| Семантика переключения | Временный просмотр деталей | Постоянное переключение предпочтений |
| Сохранение состояния | Только в рамках сессии, сброс при перезапуске | Сохраняется в settings.json |
| Область действия | Глобальное переключение экрана (prompt ↔ transcript) | Переключение рендеринга на уровне компонентов |
| Замороженный снимок | Отсутствует (нет концепции) | Отсутствует (удалено) |
| Подсказка расширения для инструмента | Да (“ctrl+o to expand”) | Да (“Press Ctrl+O to show full tool output”) |
2. Анализ реализации в Claude Code
2.1 Архитектура
Claude Code использует подход на уровне экранов, а не переключение рендеринга на уровне компонентов:
┌──────────────────────────────────┐
│ AppState (Zustand) │
│ verbose: boolean (default: false)│
│ screen: 'prompt' | 'transcript' │
└──────────┬───────────────────────┘
│
┌─────┴──────┐
│ Ctrl+O │ toggles screen mode
│ Handler │ NOT a rendering flag
└─────┬──────┘
│
┌─────▼──────────────┐
│ REPL.tsx │
│ screen='prompt' → compact view (default)
│ screen='transcript'→ detailed view
└────────────────────────┘2.2 Ключевые файлы исходного кода
| Компонент | Файл | Ключевая логика |
|---|---|---|
| Обработчик переключения | src/hooks/useGlobalKeybindings.tsx:90-132 | Переключает screen между 'prompt' и 'transcript' |
| Привязка клавиш | src/keybindings/defaultBindings.ts:44 | app:toggleTranscript |
| Определение состояния | src/state/AppStateStore.ts:472 | verbose: false (только в сессии) |
| Подсказка расширения | src/components/CtrlOToExpand.tsx:29-46 | Текст “(ctrl+o to expand)” для каждого инструмента |
| Фильтр сообщений | src/components/Messages.tsx:93-151 | filterForBriefTool() для компактного вида |
| Разрешения | src/components/permissions/PermissionRequest.tsx | Рендерится в слое оверлея, никогда не скрывается |
2.3 Принятые проектные решения
- Компактный режим по умолчанию. Пользователи сразу видят чистый интерфейс; детализация включается по запросу.
- Ограничен сессией.
verboseсбрасывается вfalseпри каждой новой сессии — Claude Code предполагает, что пользователи в основном предпочитают компактный вид и нуждаются в деталях лишь временно. - Переключение на уровне экрана. Ctrl+O не меняет способ рендеринга компонентов; он переключает весь дисплей между экраном “prompt” (компактный) и экраном “transcript” (подробный).
- Без заморозки снимков. Концепция заморозки снимков отсутствует. При переключении дисплей сразу обновляется текущим состоянием.
- Диалоги разрешений вынесены отдельно. Подтверждения инструментов рендерятся в выделенном слое оверлея, который никогда не затрагивается переключением verbose/compact.
- Подсказка для каждого инструмента. Компонент
CtrlOToExpandпоказывает контекстную подсказку на отдельных инструментах при большом выводе, подавляется в субагентах.
2.4 Пользовательский сценарий
Session start → compact mode (default)
│
├─ Tool outputs are summarized in a single line
├─ Large tool output shows "(ctrl+o to expand)" hint
│
├─ User presses Ctrl+O
│ └─→ Screen switches to transcript (detailed view)
│ └─ User sees all tool output, thinking, etc.
│
├─ User presses Ctrl+O again
│ └─→ Screen switches back to prompt (compact)
│
└─ Session ends → verbose resets to false3. Анализ реализации в Qwen Code
3.1 Архитектура
Qwen Code использует флаг рендеринга на уровне компонентов, который каждый UI-компонент считывает из контекста:
┌─────────────────────────────────────┐
│ CompactModeContext │
│ compactMode: boolean (default: false)│
│ setCompactMode: (v) => void │
└──────────┬──────────────────────────┘
│
┌─────┴──────┐
│ Ctrl+O │ toggles compactMode
│ Handler │ persists to settings
└─────┬──────┘
│
┌─────▼──────────────────┐
│ Each component reads │
│ compactMode and │
│ decides how to render │
└────────────────────────┘
│
┌─────▼──────────────────────────────┐
│ ToolGroupMessage │
│ showCompact = compactMode │
│ && !hasConfirmingTool │
│ && !hasErrorTool │
│ && !isEmbeddedShellFocused │
│ && !isUserInitiated │
└────────────────────────────────────┘3.2 Ключевые файлы исходного кода
| Компонент | Файл | Ключевая логика |
|---|---|---|
| Обработчик переключения | AppContainer.tsx:1684-1690 | Переключает compactMode, сохраняет в настройки |
| Контекст | CompactModeContext.tsx | compactMode, setCompactMode |
| Группа инструментов | ToolGroupMessage.tsx:105-110 | showCompact с 4 условиями принудительного раскрытия |
| Сообщение инструмента | ToolMessage.tsx:346-350 | Скрывает displayRenderer в компактном режиме |
| Компактный вывод | CompactToolGroupDisplay.tsx:49-108 | Однострочное резюме со статусом и подсказкой |
| Подтверждение | ToolConfirmationMessage.tsx:113-147 | Упрощенное компактное подтверждение с 3 вариантами |
| Советы | Tips.tsx:14-29 | Ротация стартовых советов включает подсказку о компактном режиме |
| Синхронизация настроек | SettingsDialog.tsx:189-193 | Синхронизация с CompactModeContext + refreshStatic |
| MainContent | MainContent.tsx:60-76 | Рендерит live pendingHistoryItems |
| Thinking | HistoryItemDisplay.tsx:123-133 | Скрывает gemini_thought в компактном режиме |
3.3 Принятые проектные решения
- Подробный режим по умолчанию. Пользователи сразу видят весь вывод инструментов и ход мыслей.
- Постоянное предпочтение.
compactModeсохраняется вsettings.jsonи переживает перезапуск сессий. - Рендеринг на уровне компонентов. Каждый компонент считывает
compactModeиз контекста и самостоятельно настраивает свой рендеринг. - Защита принудительного раскрытия. Четыре условия переопределяют компактный режим, гарантируя видимость критически важных элементов UI (подтверждения, ошибки, shell, действия пользователя).
- Без заморозки снимков. Переключение всегда показывает вывод в реальном времени — замороженные снимки отсутствуют.
- Синхронизация с диалогом настроек. Переключение компактного режима из настроек мгновенно обновляет состояние React через
setCompactMode. - Ненавязчивое обнаружение. Компактный режим представляется через ротацию стартовых советов (Tips), а не через постоянный индикатор в футере, что позволяет избежать загромождения UI.
3.4 Пользовательский сценарий
Session start → verbose mode (default)
│
├─ All tool outputs, thinking, details visible
│
├─ User presses Ctrl+O (or toggles in Settings)
│ └─→ compactMode = true, persisted
│ ├─ Tool groups show single-line summary
│ ├─ Thinking/thought content hidden
│ └─ Confirmations, errors, shell still expanded
│
├─ User presses Ctrl+O again
│ └─→ compactMode = false, persisted
│ └─ All details visible again
│
└─ Next session → same mode as last session4. Углубленный анализ ключевых различий
4.1 Философия режима по умолчанию
| Аспект | Claude Code (компактный по умолчанию) | Qwen Code (подробный по умолчанию) |
|---|---|---|
| Первое впечатление | Чистый, минималистичный — профессиональный вид | Информативный — полная прозрачность |
| Кривая обучения | Пользователь должен изучить Ctrl+O для просмотра деталей | Пользователь сразу видит всё |
| Целевая аудитория | Опытные пользователи, доверяющие инструменту | Пользователи, желающие понимать происходящее |
| Информационная перегрузка | Избегается по умолчанию | Возможна для новых пользователей |
| Обнаруживаемость | Подсказки “(ctrl+o to expand)” для каждого инструмента | Ротация стартовых советов + ? shortcuts + /help |
Анализ: Компактный режим по умолчанию в Claude Code работает, потому что его аудитория — в основном опытные разработчики, доверяющие инструменту и не нуждающиеся в просмотре каждого вызова. Подробный режим по умолчанию в Qwen Code уместен на текущем этапе развития продукта, где важно строить доверие пользователей через прозрачность.
4.2 Модель сохранения состояния
| Аспект | Claude Code | Qwen Code |
|---|---|---|
| Сохраняется? | Нет — только в сессии | Да — в settings.json |
| Обоснование | Подробный просмотр — временная потребность | Режим — пользовательское предпочтение |
| Поведение при перезапуске | Всегда запускается в компактном режиме | Запускается в последнем использованном режиме |
Анализ: Claude Code рассматривает просмотр деталей как мгновенную потребность — вы посмотрели и вернулись назад. Qwen Code рассматривает это как стабильное предпочтение — одни пользователи всегда хотят детали, другие всегда хотят компактный вид. Оба подхода валидны; подход Qwen Code более гибок.
4.3 Защита подтверждений
| Аспект | Claude Code | Qwen Code |
|---|---|---|
| Механизм | Слой оверлея/модального окна (структурно отделен) | Условия принудительного раскрытия в showCompact |
| Покрытие | Полное — подтверждения никогда не могут быть скрыты | Полное — 4 условия покрывают все интерактивные состояния |
| UI компактного подтверждения | Н/Д (оверлей всегда полный) | Упрощенный RadioButtonSelect с 3 вариантами |
Анализ: Архитектурное разделение в Claude Code (слой оверлея) более надежно. Подход Qwen Code с принудительным раскрытием эффективен, но требует явного добавления каждого нового интерактивного состояния в список условий.
4.4 Подход к рендерингу
| Аспект | Claude Code | Qwen Code |
|---|---|---|
| Область переключения | На уровне экрана (prompt ↔ transcript) | На уровне компонентов (каждый компонент решает сам) |
| Гранулярность | Всё или ничего | Тонкая настройка для каждого компонента |
| Гибкость | Низкая — глобальный переключатель | Высокая — компоненты могут переопределять |
| Согласованность | Гарантирована | Зависит от реализации каждого компонента |
Анализ: Подход Qwen Code на уровне компонентов более гибок (например, принудительное раскрытие для конкретных условий), но требует большей дисциплины для поддержания согласованности. Подход Claude Code на уровне экрана проще и гарантирует единообразное поведение.
5. Рекомендации по оптимизации
5.1 [P0] Оставить подробный режим по умолчанию — изменения не требуются
Подробный режим по умолчанию в Qwen Code — верное решение для текущего этапа. Новым пользователям необходима прозрачность для формирования доверия. По мере взросления продукта стоит рассмотреть перевод компактного режима в состояние по умолчанию (как в Claude Code).
5.2 [P1] Раскрытие для отдельных инструментов при большом выводе
Claude Code показывает “(ctrl+o to expand)” на отдельных инструментах с большим выводом. В Qwen Code сейчас доступен только глобальный переключатель. Рекомендуется рассмотреть:
- Если вывод одного инструмента превышает N строк, показывать подсказку “expand” для этого инструмента в компактном режиме.
- Область применения: будущее улучшение, не текущий приоритет.
5.3 [P2] Рассмотреть переопределение в рамках сессии
Некоторым пользователям может быть удобен компактный режим по умолчанию, но иногда требуется подробный вид для конкретной сессии. Рекомендуется поддержать оба варианта:
settings.json→ постоянное значение по умолчанию (текущее поведение)- Ctrl+O во время сессии → временное переопределение только для текущей сессии (поведение Claude Code)
- При перезапуске сессии → возврат к значению из settings.json
Это даст пользователям лучшее из обоих миров. Реализация потребует разделения состояния “настройки по умолчанию” и “переопределение сессии”.
5.4 [P2] Структурное разделение для подтверждений
В настоящее время защита подтверждений опирается на условия showCompact в ToolGroupMessage. Рекомендуется рассмотреть более надежный подход:
- Рендерить подтверждения в отдельном слое (по аналогии с оверлеем в Claude Code).
- Это сделает архитектурно невозможным влияние компактного режима на подтверждения.
- Более низкий приоритет, поскольку текущий подход с принудительным раскрытием работает корректно.
6. Текущий статус реализации
После внесения изменений в ветку feat/compact-mode-optimization:
| Функция | Статус | Примечания |
|---|---|---|
| Подсказка в стартовых советах | Готово | Подсказка о компактном режиме в ротации Tips (ненавязчиво) |
| Ctrl+O в сочетаниях клавиш (?) | Готово | Добавлено в компонент KeyboardShortcuts |
| Ctrl+O в /help | Готово | Добавлено в компонент Help |
| Синхронизация диалога настроек | Готово | Синхронизация compactMode с CompactModeContext |
| Без заморозки снимков | Готово | Переключение всегда показывает вывод в реальном времени |
| Защита подтверждений | Готово | Принудительное раскрытие + guard WaitingForConfirmation |
| Защита shell | Готово | Принудительное раскрытие !isEmbeddedShellFocused |
| Защита ошибок | Готово | Принудительное раскрытие !hasErrorTool |
| Обновление документации | Готово | settings.md, keyboard-shortcuts.md |
7. Справочник файлов
Qwen Code
| Файл | Назначение |
|---|---|
packages/cli/src/ui/AppContainer.tsx | Обработчик переключения, инициализация состояния, провайдер контекста |
packages/cli/src/ui/contexts/CompactModeContext.tsx | Определение контекста |
packages/cli/src/ui/components/messages/ToolGroupMessage.tsx | Логика принудительного раскрытия |
packages/cli/src/ui/components/messages/ToolMessage.tsx | Скрытие вывода для отдельных инструментов |
packages/cli/src/ui/components/messages/CompactToolGroupDisplay.tsx | Рендеринг компактного вида |
packages/cli/src/ui/components/messages/ToolConfirmationMessage.tsx | UI компактного подтверждения |
packages/cli/src/ui/components/MainContent.tsx | Рендеринг ожидающих элементов истории |
packages/cli/src/ui/components/Tips.tsx | Стартовый совет с подсказкой о компактном режиме |
packages/cli/src/ui/components/Help.tsx | Запись сочетания клавиш /help |
packages/cli/src/ui/components/KeyboardShortcuts.tsx | Запись сочетания клавиш ? |
packages/cli/src/ui/components/SettingsDialog.tsx | Синхронизация настроек |
packages/cli/src/ui/components/HistoryItemDisplay.tsx | Скрытие содержимого мыслей (thinking) |
packages/cli/src/config/settingsSchema.ts | Определение настройки |
packages/cli/src/config/keyBindings.ts | Привязка Ctrl+O |
Claude Code (для справки)
| Файл | Назначение |
|---|---|
src/hooks/useGlobalKeybindings.tsx | Обработчик переключения |
src/state/AppStateStore.ts | Определение состояния (verbose: false) |
src/components/CtrlOToExpand.tsx | Подсказка расширения для инструмента |
src/components/Messages.tsx | Фильтр кратких сообщений |
src/screens/REPL.tsx | Переключение режима на уровне экрана |
src/components/permissions/PermissionRequest.tsx | Подтверждение на основе оверлея |