# dsh-mobile-upgrade

[English](../../README.md) | [简体中文](../zh-Hans/README.md) | [繁體中文](../zh-Hant/README.md) | [日本語](../ja/README.md) | [한국어](../ko/README.md) | [Español](../es/README.md) | [Français](../fr/README.md) | [Deutsch](../de/README.md) | Русский

Удобства для мобильных устройств в веб-профиле [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) (`dsh`), оформленные как один плагин. Всё отрисовывается через собственные слоты и сигналы состояния хоста — без захвата разметки, без плавающих виджетов, без опроса DOM чата.

## Что вы получаете

- **Строка перезапуска** — пункт «Перезапустить службу» в Настройки → Общие. Сначала запрашивает подтверждение, перезапускает процесс `dsh` и автоматически перезагружает страницу, когда служба снова отвечает.
- **Переключатели модальностей ввода** — флажки text/image/video в каждой строке модели нативного редактора провайдеров, записывающие массив `input` модели в `settings.yaml` (с резервной копией рядом с файлом). Для моделей каталога без пользовательской маршрутизации переключатели показываются только для чтения.
- **Боковая панель-шторка на узких экранах** — ниже 1024px боковая панель сворачивается в маленький угловой чип, сохраняющий собственный переключатель хоста; в развёрнутом виде вся панель всплывает шторкой поверх контента во всю ширину, а выбор сессии снова её закрывает. Чип и шторка сменяют друг друга атомарно (без анимации геометрии, которая может застыть при занятом основном потоке), а нажатие, закрывающее шторку, сворачивает её в том же кадре, вместо ожидания повторной отрисовки хостом — поэтому телефон с множеством запущенных сессий не может оставить шторку полураскрытой, и закрытый чип никогда не остаётся белым поверх рейла, который хост уже опустошил.
- **Вкладки настроек на узких экранах** — ниже 700px боковая навигация диалога настроек превращается в ряд горизонтально прокручиваемых вкладок.
- **Меню моделей во всю ширину** — ниже 700px меню моделей композера привязывается ровно к ширине экрана (поля 12px) вместо выхода за край экрана; вертикальное размещение над триггером остаётся за хостом.
- **Прокручиваемая карточка вопроса** — ниже 1024px открытый вопрос больше не может вытеснить собственные варианты за пределы экрана: вопрос получает собственную область прокрутки с ограничением высоты, поэтому длинный вопрос прокручивается на месте, список вариантов под ним занимает всё оставшееся место, а варианты, строка отправки и кнопки сворачивания и закрытия остаются на экране и доступны. Короткий вопрос не затрагивается, а карточка по-прежнему подстраивается под своё содержимое.
- **Обход панели деталей** — полноэкранная панель деталей инструментов, кнопка закрытия которой в текущем хосте не работает, на узких экранах не отрисовывается вовсе, поэтому не может заблокировать чат.
- **Реактивность, устойчивая к шторму** — наблюдатели шторки/меню и опросчик настроек реагируют на шквал стриминговых сообщений с ограниченной частотой и отступают, пока хост недоступен; при перемонтировании рейла во время переподключения состояние шторки сохраняется, а не мерцает, а нажатия, закрывающие шторку, повторяются через перемонтирование, вместо того чтобы попадать по устаревшему переключателю: множество одновременно стримящихся сессий больше не замораживает ввод и не дёргает боковую панель до некликабельности — открыта она или закрыта.
- **Защита каталога сабагентов** — хост отдаёт каталог сабагентов, перечисляя весь корпус сессий на каждый запрос (~1s на длинной истории), а его клиент спрашивает при каждом выборе, наведении на чип и событии состава. Плагин оборачивает это обновление: родитель без детей в живом списке сессий не опрашивается вовсе, к одному родителю обращаются не чаще одного раза за 2,5с, а запуски обновлений разнесены — веерный запуск сабагентов больше не морит хост голодом полными проходами по корпусу.
- **Чипы родословной, открывающиеся кликом** — на десктопе чипы сабагентов («N subagents» и переключатель заголовка сабагента) в текущем хосте открываются только при наведении; клик ничего не делает. Плагин переводит клик по чипу в пару событий наведения, которую хост уже понимает, поэтому клик открывает и закрывает дерево (крошки предков сохраняют переход по клику).
- **Сборщик заголовка на узких экранах** — ниже 1024px чипы заголовка сессии (родословная, задачи, пресет) шире телефона и работают только по наведению. Они сворачиваются в одну таблетку (`≡ заголовок · N agents · M jobs`); нажатие открывает лист во всю ширину с родословной сессии (каждый предок нажимаем, у каждого — число потомков), деревом сабагентов с корнем в корне семейства — строки отрисовываются из живого списка сессий, ветви получают свой каталог по требованию через защищённое обновление — и фоновыми задачами этой сессии. На десктопе ничего не меняется.
- **Самообновление** — клиентский бандл раздаётся неизменным по ревизиям, поэтому вкладка на телефоне может днями работать на старой сборке. Страница сравнивает ревизию, с которой загрузилась, с той, что сервер публикует сейчас, и перезагружает себя, когда страница простаивает (никогда во время набора черновика), или предлагает нажимаемый баннер.
- **Регулирование рендера списка сессий** — хост отправляет кадр с полным значением на каждое изменение проекции каждой подключённой сессии, а представление тайминга работающего субагента меняется на каждом зафиксированном событии — занятый фоновый флот вливает в страницу 50-150 кадров/с. Каждый кадр раньше перерисовывал весь список сессий (одна пересборка проходит по всем сводкам плюс O(n²)-чистку кеша — по замерам это большая часть времени главного потока; страница замерзала до перезагрузки). Плагин сворачивает эти перерисовки в адаптивный завершающий интервал, а значения по-прежнему без изменений поступают в хранилища каждой сессии — фоновый стриминг больше не замораживает страницу, в любой сессии, новой или старой.
- **Переключатели по функциям** — плагин устанавливает раздел `dsh-mobile-upgrade` в Настройки → Плагины с переключателем для каждой функции.

## Скриншоты

Плавающая кнопка и шторка сессий (с пояснениями):

| | |
|---|---|
| ![Плавающая кнопка](../../res/shot-floating-chip.png) | ![Шторка сессий](../../res/shot-drawer.png) |

## Установка

```sh
dsh plugin --profile web add dsh-mobile-upgrade
```

Перезапустите `dsh web` и откройте веб-профиль на телефоне: строка перезапуска — в Настройки → Общие, а переключатели — в Настройки → Плагины → dsh-mobile-upgrade. Вложения загружаются через собственную систему вложений композера хоста.

Требуется `dsh` 0.1.5-rc.1 или новее (встроенная система вложений хоста заменила функцию загрузки этого плагина).

## Конфигурация

Карточка настроек плагина принимает:

| Ключ | По умолчанию | Значение |
|---|---|---|
| `restartEnabled` | `true` | Предоставлять строку перезапуска и её маршрут |

## Переключатели функций

Каждую функцию можно включать и выключать в Настройки → Плагины → dsh-mobile-upgrade (вступает в силу при следующей загрузке страницы) либо переопределить на устройстве ключом `localStorage` — `mfx-restart`, `mfx-settle`, `mfx-drawer`, `mfx-settings`, `mfx-modality`, `mfx-menus`, `mfx-net`, `mfx-questions`, `mfx-selfupdate`, `mfx-agents`, `mfx-header`, `mfx-listthrottle` — значение `"0"` отключает функцию.

## Известные ограничения

- Клиент цепляется за конкретные элементы интерфейса хоста по их хешированным CSS-классам (меню, переключатель шторки, редактор провайдеров, чипы заголовка сессии). Если сборка хоста переименует их, затронутые функции деградируют, пока этот плагин не догонит; остальное продолжает работать. Область вопроса в карточке определяется вместо этого по её собственному хуку `data-question-key`, поэтому продолжает работать и после пересборки хоста, которая лишь заново хеширует свои CSS-модули.
- Сборщик заголовка и клик-шим родословной едут на собственных данных хоста (живой список сессий и его каталоги сабагентов); они не добавляют запросов сверх защищённых выборок ветвей, а нажатие на строку, чей режим ещё загружается, завершится само, как только каталог придёт.
- Переключатели модальностей ввода могут изменять только маршруты провайдеров, настроенные вами самостоятельно; маршруты из одного каталога только для чтения по замыслу — выдуманный раздел каталога обрушивает весь каталог моделей.

## Замечания по безопасности

HTTP-маршруты плагина (перезапуск, правка настроек) сами по себе не выполняют аутентификацию — они доверяют веб-поверхности `dsh`, в которую загружены. Прежде чем открывать развёртывание за пределы localhost, поместите его за ту же преграду, что и остальной интерфейс (аутентификация обратного прокси, привязка к loopback).

## Ссылки сообщества

- [Linux.Do](https://linux.do) — Сообщество для обмена и обсуждения технологий.

## Лицензия

Распространяется под [Synthetic Source License (SySL), версия 1.0](LICENSE).

> УВЕДОМЛЕНИЕ: Это программное обеспечение включает код, сгенерированный искусственным интеллектом. Условия Synthetic Source License, включая требования о раскрытии моделей, см. в файле LICENSE.
