DSH Plugins Marketplace

DSH Plugins

Plugins

/

dsh-pult

a

dsh-pult

Manifest valid

Remote — right column dsh: cfsmcp2 contexts, LM Studio models, MCP servers and sessions in one bundle

UI (client)hasBundlePatchMachine translated

Пульт — правая колонка dsh: сессии, MCP-серверы и локальные модели

Одна колонка правой боковой панели dsh, в которой видно всё, ради чего её открывают: какие контексты cfsmcp2 готовы и что сейчас индексируется, загружены ли эмбеддинги в локальный LM Studio, живы ли MCP-серверы и контейнеры, и что происходит в сессиях Харнесса.

Колонка — это четыре раздела и одна страница: каталог контекстов сверху, модели LM Studio под ним, список MCP-серверов в середине и список сессий внизу. Всё это один bundle: одна стилистика, одно запоминание сложенного, никакой сборки — client.js уже собранный браузерный бандл.

Сессии: «Закреплённые», «На исполнении» и дни, тёмная и светлая тема

Что нового

1.20.1 — колонка называется «Пульт»: так подписаны шапка и вкладка, рядом с названием стоит знак колонки, а группа строк серверов называется Серверы, не MCP servers.

1.19.0 — одна кнопка ⚙ в шапке раскрывает пять секций с переключателями: каталог cfsmcp2, LM Studio, серверы и контейнеры, Oh!MyMind, сессии. Выключенная секция не рисуется и не делает своих запросов.

1.18.0 — галка «применять cfsmcp2» в настройках тегов: снятая значит, что список сессий вовсе не обращается к cfsmcp2 — ни точек, ни тегов, ни запросов каталога; выбранные теги cfsmcp2 снимаются с фильтра.

1.17.1 — «метки» переименованы в теги во всём интерфейсе и в выгрузке.

1.17.0 — сегодняшняя работа целиком:

  • фильтр списка: имя + теги cfsmcp2 + свои теги, все условия вместе, «N из M», ×;
  • группы тегов: группа = название + уникальный символ (● ★ ■ ▲ ◆ ⬢ ✚ ◯ ♥ ⚑), старые теги уезжают в «Общие», группы подписаны во всех списках, cfsmcp2 — первая группа;
  • теги в выгрузке: отдельный столбец на каждую группу, и файл считается по фильтру;
  • архив: кнопка 📦 в строке, полоса «Архив» внизу, внутри — по месяцам, всё свёрнуто и у свёрнутого месяца теги не читаются;
  • часы хода: длительность плашкой, замирает под зелёной галочкой;
  • рекомендация вместо пустого комментария у закреплённой сессии (3–6 слов);
  • цвет по уровню доступа: зелёный/обычный/красный, любой другой вариант — янтарный;
  • три значка строки увеличиваются вдвое под курсором.

Разделы

РазделЧто показывает
Контексты cfsmcp2каждый контекст поиска с версией, синонимом, тегами и прогрессом индексации, фильтр по имени/синониму/теге, чипы меток, очередь индексации и действие «Загрузить» на контекст
LM Studioэмбеддинг-модели, загруженные в локальный LM Studio прямо сейчас (чат-модели не показываются); голова красная, пока эмбеддинга нет, пока LM Studio не отвечает или пока Host не знает маршрут
Серверы и контейнерыстрока на каждый отслеживаемый контейнер или нативный MCP-сервер: точки состояния, связь с сессией, возраст данных, старт/стоп/рестарт и пузырь с подробностями
Сессиивсе непустые сессии Харнесса, свежие сверху: полоса «Закреплённые», затем «На исполнении», затем дни (Сегодня / Вчера / Позавчера / Далее) и «+ Новая сессия»

Каждая шапка складывает свой блок, каждая полоса группы (группа серверов, день) — свои строки.

Требования

  • dsh с профилем, где смонтированы connection и ui-sidebar-right — они входят в composition dsh-web-app, то есть в обычную desktop/web-поставку. Плагин ничего не патчит в установленном dsh.
  • Node.js ^22.19 || >=24 — то же ограничение, что у dsh.
  • Зависимостей нет: client.js — готовый браузерный бандл, хост-половина использует только node: и fetch. Установка — это pnpm add из GitHub и включение строки, сборки нет.
  • Необязательно, по разделам:
    • Docker — для строк-контейнеров (без него строки с container не получат состояние, а действия вернут ошибку);
    • LM Studio на 127.0.0.1:1234 — для раздела моделей;
    • cfsmcp2 на 127.0.0.1:8559 — для каталога контекстов;
    • zstd (brew install zstd) — только для экспорта сессий: журнал сессии — цепочка zstd-кадров, а встроенный zlib читает лишь первый.

Раздел, которому не хватает своего сервера, честно говорит об этом и не мешает остальным.

LM Studio: загруженный эмбеддинг и случай «LLM есть, эмбеддинга нет»

Установка

Плагин ставится прямо из GitHub — ни клонировать, ни собирать ничего не нужно.

Через интерфейс (проще всего)

  1. Боковая панель → Plugins → Add plugin.

  2. Вставить адрес репозитория:

    github:askred-dot-ru/dsh-pult
    

    (понимается и https://github.com/askred-dot-ru/dsh-pult.git, и путь к локальному клону, если он у вас есть).

  3. Install → дождаться pnpm → Enable now — эта кнопка сама включает строку в профиле, вручную править package.json не нужно.

  4. Перезапустить dsh: строки Loader читаются при старте процесса.

Через CLI

dsh plugin --profile desktop add github:askred-dot-ru/dsh-pult
# затем включить bundle: в ~/.dsh/profiles/desktop/package.json добавить
# "dsh-pult" в dsh.profile.bundles — `plugin add` только ставит зависимость
pnpm install            # в каталоге профиля, если правили package.json руками

Профильный package.json после установки:

{
  "dependencies": {
    "dsh-pult": "link:/путь/к/клону/dsh-pult"
  },
  "dsh": {
    "profile": {
      "bundles": [
        "@deepseek-ai/dsh-base",
        "@deepseek-ai/dsh-web-app",
        "dsh-pult"
      ]
    }
  }
}

Проверка и откат

  • В карточке плагина — строка dsh-pult; в сайдбаре появляется вкладка «Пульт» с четырьмя разделами.
  • Компонент Обновить в карточке: плагины из Git не обновляются сами — обновление это переустановка более новой версии.
  • Откат: выключить строку в карточке (или убрать "dsh-pult" из dsh.profile.bundles и dependencies), затем pnpm install в каталоге профиля и перезапуск dsh.
  • Если у вас уже стоит @local/mcp-panel (прежнее имя этой же панели) — выключите его: страница регистрируется под одним и тем же TAB_ID, и две копии будут спорить за одно место в сайдбаре.

Настройка строки

Все ключи строки — необязательные; значения ниже — то, что корабль везёт по умолчанию (cordis.patch.yml пакета). Править можно в cordis.patch.yml профиля или в карточке плагина.

- insert:
    - id: pult
      name: 'dsh-pult'
      config:
        targets: []
        pollMs: 5000
        probe: true
        confirmActions: false
        url: http://127.0.0.1:8559/mcp/
        contextsTtlMs: 300000
        contextsTimeoutMs: 8000
        indexTtlMs: 3000
        importTimeoutMs: 120000
        lmStudioUrl: http://127.0.0.1:1234
        lmStudioTimeoutMs: 4000
        # sessionsRoot: ~/.dsh/sessions
        # exportDir: ~/Downloads
        # openExport: true
КлючПо умолчаниюЧто делает
targets[]список отслеживаемых строк — контейнеров и MCP-серверов; пусто намеренно, чужие серверы никто не угадает (форма записи ниже)
pollMs5000как часто панель перечитывает состояние серверов
probetrueдиалить ли endpoint MCP-сервера, чтобы отличить «процесс жив» от «порт отвечает»
confirmActionsfalseспрашивать ли подтверждение на стоп и рестарт
urlhttp://127.0.0.1:8559/mcp/MCP-адрес cfsmcp2
contextsTtlMs300000сколько живёт прочитанный каталог контекстов
contextsTimeoutMs8000таймаут одного вызова cfsmcp2
indexTtlMs3000как часто перечитывается состояние индексации
importTimeoutMs120000сколько ждать «Загрузить» на контексте
lmStudioUrlhttp://127.0.0.1:1234адрес LM Studio
lmStudioTimeoutMs4000таймаут запроса моделей
sessionsRoot~/.dsh/sessionsгде лежат журналы сессий
exportDir~/Downloadsкуда писать экспорт
openExporttrueоткрывать ли книгу Excel сразу после записи
abbreviations—короткие имена для синонимов контекстов в заголовках

Запись в targets

Строка — это контейнер, контейнер с MCP-сервером или нативный MCP-процесс. Только строку с контейнером можно запускать и останавливать.

targets:
  # MCP-сервер в контейнере: состояние, действия, связь с сессией, диальчик порта.
  - group: MCP servers
    container: cfsmcp2-cfsmcp2-1
    label: cfsmcp2
    server: cfsmcp2
    url: http://127.0.0.1:8559/mcp/

  # Нативный MCP-сервер: контейнера нет, есть только связь с сессией и диальчик,
  # плюс возраст данных по каталогам из dataPaths.
  - group: MCP servers
    container: null
    label: openviking
    server: openviking
    url: http://127.0.0.1:1933/mcp
    dataPaths: ['~/.openviking/data/viking']

  # Просто контейнер, без MCP: строка состояния и кнопки.
  - group: containers
    container: my-worker-1
    label: my-worker-1
ПолеОбязательноСмысл
containerнетимя контейнера Docker; null — нативный сервер (запускать нечего)
serverнетserverName из dsh-mcp-client; по нему строка понимает, что инструменты сервера зарегистрированы в текущей сессии
labelнетчто написано в строке; по умолчанию server, иначе имя контейнера
groupнетзаголовок группы; по умолчанию MCP servers для серверов и containers для остальных
urlнетendpoint для диальчика; пусто — не диа́лить
dataPathsнеткаталоги данных нативного сервера: строка покажет самый свежий mtime, ~ раскрывается

Строка, у которой нет ни container, ни server, пропускается.

Разделы подробнее

Контексты cfsmcp2

Каталог читается с MCP-сервера cfsmcp2 (list_context_groups и спутники), а состояние индексации — с его REST: /api/system/job-queue, /api/entities, /api/tags. cfsmcp2 — сервер семантики по коду и метаданным 1С, поэтому синонимы контекстов — названия продуктов 1С, а abbreviations сокращает их в заголовках (УПП, БП, ЗУП и прочие) по таблице из index.js. Сокращение меняет только показанное имя: name контекста — аргумент каждого вызова поиска, и он никогда не переписывается. Поэтому у контекста видны:

  • имя, версия и синоним (синоним можно сократить через abbreviations);
  • теги контекста — чипами, с цветом из REST-каталога тегов;
  • прогресс индексации: сколько объектов и методов уже разобрано, что в очереди;
  • очередь: работающий контекст, ждущие, приостановленные — они идут первыми;
  • фильтр по имени, синониму и теге, плюс чипы меток над списком;
  • «Загрузить» — перечитать контекст из его источника (POST api/cfsmcp2-contexts/action). Пока сервер работает, панель показывает, что ждёт, и не даёт нажать второй раз.

LM Studio

Локальный LM Studio отвечает на 127.0.0.1:1234; браузер не может спросить его с другого origin, поэтому api/v0/models забирает Host и отдаёт панели короткую форму (id, type, state, publisher, quantization, maxContext, loadedContext). Раздел опрашивает его раз в 10 с.

Раздел отвечает на один вопрос: эмбеддинги, которые нужны MCP-серверам, в памяти? Поэтому показаны только модели типа embeddings и только загруженные; чат-модели не показываются вовсе, а не «вторым сортом». Строка — это имя, а справа квантование и длина контекста.

СостояниеГоловаСправа
эмбеддинг загруженобычная«1 эмбеддинг» / «2 эмбеддинга» / «5 эмбеддингов»
LLM загружена, эмбеддинга неткрасная плашка«нет эмбеддинга», ниже — какая LLM занимает память
ничего не загруженокрасная плашка«нет эмбеддинга», ниже — сколько моделей скачано
LM Studio не отвечаеткрасная плашка«нет связи», ниже — причина
Host не знает маршруткрасная плашка«нет маршрута», ниже — HTTP и подсказка про перезапуск

Загруженная чат-модель поиску не помогает: LM Studio поднят и отвечает, а semantic_search нечем считать эмбеддинг. Именно этот случай красная полоса и называет.

Строка про маршрут — не про LM Studio: браузерная половина может быть новее запущенного Host. Переключатель плагина перезагружает бандл браузера и снова вызывает apply из уже импортированного модуля, поэтому маршрут, добавленный в index.js, появляется только после перезапуска приложения. Раздел так и говорит, вместо того чтобы валить вину на LM Studio.

MCP-серверы

Страница показывает по строке на каждую цель из targets:

  • точки состояния: контейнер запущен / здоров / остановлен, плюс отдельная точка «порт отвечает»;
  • связь с сессией: зарегистрированы ли в текущей сессии инструменты mcp__<server>__*. MCP-клиент регистрирует их только после успешного connect и discovery и снимает, когда исчерпан бюджет переподключений, — поэтому их наличие и есть взгляд сессии на «подключён»;
  • возраст данных: самый свежий mtime под dataPaths (для нативных серверов);
  • старт / стоп / рестарт — только для строк с контейнером; кнопка приходит в состояние ожидания, а после ответа панель перечитывает снимок;
  • пузырь с подробностями: образ, порты, состояние, endpoint, ошибка Docker.

confirmActions: true заставляет стоп и рестарт спрашивать подтверждение вторым нажатием; запуск действует сразу.

Сессии

Каждая непустая сессия Харнесса — строка, свежие сверху. Порядок не хронологический там, где это важно: строка, которая ждёт читателя, уходит из своего дня в полосу «На исполнении» над «Сегодня». Ждёт — значит идёт ход, задан вопрос или ход закончился и результат ещё никто не открыл. Сессия стоит ровно в одном месте, поэтому полоса никогда не повторяет строку из дня.

Внутри полосы порядок по тому, что строка просит у читателя, а потом по свежести: вопрос первый (ничего не сдвинется, пока не ответят), затем живая сессия, затем непросмотренный результат.

Сессия, открытая в основном виде, не попадает в полосу за непросмотренный результат: читатель смотрит на неё, и закончившийся ход — не новость. Платформа может держать флаг completionUnread до ухода из сессии, и строка иначе осталась бы с зелёной галочкой в «На исполнении» уже после хода — список, который выглядит застрявшим. Поэтому для этой одной строки флаг игнорируется: она возвращается в свой день и галочку не рисует. Вопрос и идущий ход считаются и для неё.

СтатусЗначокЧто значит
работаетповорачивающееся полукольцо в деловом цвете, с ореолом, на подсвеченной строкеидёт ход
ждёт ответаконтурный «?» в цвете предупреждения, «дышит»модель спросила, читатель должен ответить
готово, не просмотренозалитая галочка в цвете успеха, со свечениемход закончился, результат никто не открыл
без активностизначка нет; строку ведёт точка цвета проектатишина

Режим доступа в заголовке. Когда в поставке есть сервис разрешений, заголовок каждой строки несёт пресет сессии: read-only — безопасный, зеленеет, danger-full-access — опасный, краснеет, обычный workspace-write остаётся спокойным. Подкраска — color-mix цвета состояния с цветом подписи, поэтому один токен читается в обеих темах; подсказка строки называет режим словами («доступ: полный доступ»). Строка без projections.permissions рисуется обычно.

Сессия, открытая в основном виде, помечена ещё и контуром в деловом цвете, чтобы было видно, где вы, не читая заголовков. Контур — внутренняя тень: он повторяет радиус строки, не меняет её размер и не портит подложку живой строки. Подсказка добавляет «открыта сейчас».

Теги из cfsmcp2. Строка подписывается от своего cwd в два прохода:

  1. контекст, имя которого — целый сегмент пути (побеждает самый длинный, так shop_a бьёт shop), а его теги становятся чипами;
  2. иначе — тег, имя которой целый сегмент пути, самая глубокая: для /Users/alex/work/shop/tmp это work, если work заведён тегом, а при нескольких подходящих побеждает та, что глубже в пути. Контекст без своих меток откатывается к той же теге.

Точка берёт цвет первого чипа. Весь каталог меток, с цветами, читается из REST /api/tags и накладывается поверх MCP list_context_groups, который называет только теги, привязанные к готовому контексту, — поэтому тег без своего контекста всё равно сохраняет цвет. Подсказка строки называет совпадение словами: «контекст: shop» или «тег по папке: work».

Свои теги. Это теги читателя, отдельно от меток контекстов cfsmcp2: ничего не импортируется, каталог строится руками. Тег — это имя и цвет; кнопка 🏷 в шапке рядом с «+ Новая сессия» открывает менеджер, где тег создают, переименовывают, перекрашивают и удаляют. Удаление снимает тег со всех сессий.

Строка помечается из самой строки: у каждой есть кнопка 🏷 перед иголкой (приглушена, пока меток нет), она открывает выбор под строкой, где любая известная тег включается и выключается сразу. Чипы стоят справа от заголовка, непосредственно перед временем: сначала теги читателя — в своём цвете, потом теги от cwd. Заголовок забирает оставшееся место и обрезается многоточием. Когда колонка уже, чем 420 px, подписи чипов сбрасываются: тег показывает только точку, а теги cfsmcp2 от cwd скрываются — ведущая точка всё так же несёт цвет портфеля, полное имя в подсказке.

Оба списка живут в хранилище панели (tags, sessionTags), поэтому переживают перезагрузку и общие для сайдбара всех сессий. У cfsmcp2 свои теги контекстов; две системы не пересекаются, и тег сессии никогда не меняет контекст поиска.

Пустые сессии не показываются. Сессия пуста до первого сообщения; такие строки — заглушки (обычно брошенные «+ Новая сессия»), и плагин их пропускает (blank === true в строке списка). С первым сообщением строка появляется.

«Закреплённые», иголка и комментарий

У каждой строки справа, рядом со временем, есть иголка. Клик закрепляет сессию: она уходит из своей полосы — «На исполнении», дня — в «Закреплённые», самую громкую полосу списка, прямо над «На исполнении». Второй клик открепляет, и строка возвращается в полосу, которой соответствует по своей дате и статусу.

Иголка главнее вычисленных полос, с одним исключением: сессия, в которой сейчас идут действия ИИ, уходит в «На исполнении» на время хода, чтобы работа была там, где её ищут. Сама иголка не снимается — ход закончится, и строка вернётся в «Закреплённые». Вопрос и непросмотренный результат остаются в закреплённой полосе, где значок статуса всё равно виден.

Полоса закреплённых покрашена тёплым акцентом (state-warn-tertiary плюс 3 px state-warn-primary, подпись в state-warn-label), а заголовки строк в ней набраны тяжелее — читатель сам положил эти строки сюда, значит они громче живой полосы.

«Закреплённые» охватывают дни, поэтому их строки называют день словами — кроме сегодняшнего, где только время: 14:05, «вчера 09:12», «позавчера 18:40» и ДД.ММ ЧЧ:ММ для всего старше. В дневных полосах день не повторяется: шапка его уже сказала.

Комментарий. Закреплённая строка может нести одну короткую затег (до 300 символов). Она рисуется двумя курсивными строками под строкой, с отступом до заголовка; длинный текст обрезается, полный — в подсказке. Клик по строке открывает правку на месте: поле на две строки, Enter сохраняет, Esc отменяет, очистка поля удаляет комментарий. Без комментария закреплённая строка показывает бледное «+ комментарий» при наведении, чтобы не занимать строку впустую.

Комментарий принадлежит иголке: как только строка вернулась в «На исполнении» или свой день, строка пропадает и текст доступен только в подсказке. Повторное закрепление возвращает её на место, потому что текст хранится по id сессии в notes.

Фильтр списка

В строке поиска три независимых условия, и они работают вместе:

УсловиеЧто делает
поле поискаполнотекстовый отбор по наименованию сессии, «поиск по наименованию сессий…»
чипы теговотбор по тегам: cfsmcp2 и свои
счётчик N из Mсколько строк осталось от всех

Внутри одного условия действует ИЛИ (несколько тегов — любая из них), между условиями — И: «отчёт + тег p0 + свой тег срочно» оставит только то, что подходит под все три. Рядом — ×, снимающий все условия сразу. Пустой результат пишет «ничего не найдено по фильтру». Состояние фильтра живёт в хранилище панели, поэтому переход в другую сессию его не сбрасывает.

Теги по умолчанию скрыты — их раскрывает кнопка 🏷; при активном, но свёрнутом фильтре кнопка подсвечена и показывает число выбранных условий.

Галка «применять cfsmcp2»

Первая строка в настройках тегов (⚙ в строке поиска). Включена по умолчанию; выключенная значит, что список сессий вовсе не читает cfsmcp2:

ЧтоВключеноВыключено
запрос каталога api/cfsmcp2-contextsидётне идёт ни одного
точка проекта в строкецвет контекстаточки нет
теги cfsmcp2 в строкечипы с цветомнет
группа cfsmcp2 в фильтреперваянет
теги cfsmcp2, выбранные в фильтресохраняютсяснимаются при выключении
свои теги, группы, архив, часы ходаработаютработают так же

Настройка живёт в хранилище панели и переживает перезагрузку. Выгрузка за период при выключенной галке пишет пустые столбцы cfsmcp2 — читать их не из чего.

Группы тегов

Свои теги живут группами. У группы есть название и символ, и символ — её опознавательный знак: на строке сессии тег рисуется символом своей группы, а не точкой, поэтому видно, из какой он группы.

ЧтоКак
символ группы● кружок, ★ звёздочка, ■ квадрат, ▲ треугольник, ◆ ромб, ⬢ шестиугольник, ✚ крест, ◯ кольцо, ♥ сердце, ⚑ флажок
уникальностьсимвол принадлежит одной группе; занятый в списке недоступен, а попытка выставить его отказывается
число группзадаёт читатель; когда все десять символов заняты, форма новой группы гаснет
удалениеудаляет теги группы и их назначения на сессиях; последнюю группу удалить нельзя

Теги, созданные до появления групп, читаются как группа «Общие» с кружком — это делает миграция при чтении хранилища, писать ничего не нужно.

Везде, где теги предлагаются на выбор, они разделены по группам, и группа подписана — в менеджере (⚙), в пикере под строкой, в диалоге «Новая сессия» (там группы стоят колонками) и в чипах фильтра, где каждая группа начинается с новой строки. Отдельной строки «мои» нет: cfsmcp2 — такая же группа тегов и всегда первая, за ней свои группы в порядке справочника.

Архив

Последняя полоса списка — «Архив», кнопка 📦 в строке отправляет сессию туда, повторный клик возвращает. Вне архива значок серый и приглушённый, в архиве — включён и подсвечен.

Внутри архив разложен по месяцам («Ноябрь 2026», «Октябрь 2026», …), свежий месяц выше, и все месяцы всегда свёрнуты: открытое состояние не запоминается. Свёрнутый месяц не показывает ни строк, ни тегов — сессии не строятся, пока месяц не развёрнут, поэтому год архива стоит несколько строк.

Часы хода, рекомендация и цвет доступа

ЧтоКак
часы ходапока ход идёт, справа вместо времени стоит длительность в плашке (3:41, после часа 1:02:05); под зелёной галочкой число замирает и уходит вместе с ней
рекомендацияу закреплённой сессии без своего комментария после хода появляется подсказка на 3–6 слов («сверить итог и снять иголку»), тише и мельче комментария, с ведущей ↳; клик переносит её в поле комментария
цвет заголовкаread-only — зелёный, workspace-write — обычный, danger-full-access — красный, любой другой вариант (производный custom, свой пресет сборки) — янтарный

Экспорт сессий за период

Кнопка ⤓ в строке поиска открывает маленькую панель: две даты (по умолчанию предыдущий месяц) и два действия — JSON и Excel. Файл считается по текущему фильтру: в него попадают ровно те сессии, что видны в списке, а панель пишет «сессий по фильтру: N из M».

В книге после плоского столбца «Теги сессии» идёт по столбцу на каждую группу тегов (● Общие, ★ Проекты, …) со значениями, отмеченными у сессии в этой группе. В JSON то же структурой: tag_groups в корне — справочник групп, и tag_groups у каждой сессии — { group, shape, tags }. Оба файла Host пишет в ~/Downloads как sessions-<from>_<to>.<ext>; панель показывает получившийся путь. Книга Excel открывается сразу после записи (macOS open), чтобы цифры были на экране без похода в Finder; openExport: false это выключает. JSON только пишется, никогда не открывается.

Данные берутся из хранилища сессий на диске (~/.dsh/sessions/<bucket>/<session>/session*.jsonl.zstd). Работа сессии — её ходы: turn/start … turn/end несут оба конца, а активное время — сумма ходов, обрезанная периодом, то есть время, которое агент действительно работал, а не время, пока сессия была открыта. Даты — первый и последний ход внутри периода, поэтому маркер, записанный днями позже, их не растягивает. Экспортируются только сессии, у которых в периоде есть хотя бы один ход.

Журнал — цепочка zstd-кадров, на которой zlib останавливается после первого кадра; поэтому Host зовёт CLI zstd и говорит об этом в панели, если бинарника нет.

Форма JSON (каждая тег cfsmcp2 — отдельным полем, теги самой сессии — списком):

{
  "period": { "from": "2026-10-01", "to": "2026-10-31" },
  "generatedAt": "2026-11-06T11:18:39.304Z",
  "total": { "activeMs": 105600000, "active": "29 ч 20 мин" },
  "sessions": [
    {
      "session": "Квартальный отчёт",
      "cfsmcp2_tag_1": "work",
      "cfsmcp2_tag_2": "",
      "cfsmcp2_tag_3": "",
      "session_tags": ["Срочно"],
      "started_at": "2026-10-06 15:06",
      "ended_at": "2026-10-26 16:37",
      "active": "2 ч 13 мин",
      "active_hours": 2.21
    }
  ]
}

Книга Excel содержит те же колонки (Наименование сессии · три теги cfsmcp2 · теги сессии · начало · окончание · активное время, ч) плюс жирную строку Итого с суммой часов.

Название и знак

Продукт называется «Пульт» — так подписаны шапка страницы и вкладка в сайдбаре, рядом стоит знак колонки: тот же глиф, что в icon.svg (рамка и три штриха), вставленный инлайном, поэтому он берёт цвет акцента из темы. Идентификаторы вкладки (kind, id) и имена мест не менялись — сайдбар помнит открытую вкладку по ним.

Настройки панели: пять секций

В шапке рядом с ⟳ стоит ⚙ — одна кнопка настроек на всю колонку. Она раскрывает карточку с пятью областями и переключателем у каждой:

СекцияЧто прячется при выключении
Каталог cfsmcp2вся секция каталога; список сессий заодно перестаёт читать cfsmcp2 — ни запросов, ни точек, ни тегов
LM Studioсекция моделей и её опрос
Серверы и контейнерыстроки серверов и вся их панель
Oh!MyMindстроки группы ohimymind — четыре контейнера (api, worker, embedder, db); когда появится отдельная секция с индексом знаний, эта галка будет владеть и ею
Сессиисписок сессий внизу страницы целиком

Выключенная секция не рисуется вовсе — не прячется стилями, а просто отсутствует, поэтому и опроса своего не делает. Кнопка ⚙ остаётся на месте при любом наборе: иначе выключенное было бы не вернуть. Состояние лежит в хранилище панели (sections) и переживает перезагрузку.

Что сложено — запоминается

Состояние складывания — маленькое хранилище в localStorage под ключом dsh.pult.v1:

{
  "catalogue": false,
  "sessions": false,
  "models": false,
  "groups": ["containers"],
  "buckets": ["yesterday"],
  "pins": ["3f1c9a02"],
  "notes": { "3f1c9a02": "сверить суммы с прошлым кварталом" },
  "tags": [{ "id": "tag-1", "name": "Срочно", "color": "#ef4444" }],
  "sessionTags": { "3f1c9a02": ["tag-1"] }
}

Сложили всё, кроме списка сессий, в одной сессии — ровно так это выглядит в следующей, а разложили обратно там же. Состояние принадлежит панели, не сессии: это приспособление для чтения, и человек не должен складывать одни и те же четыре раздела при каждом переключении.

Как это устроено

ФайлРоль
client.jsстраница: каталог контекстов, модели, список серверов, список сессий и хранилище сложенного
index.jsчетыре хост-половины: маршруты и конфигурация
cordis.patch.ymlодна строка Host с объединённой конфигурацией
scripts/preview.mjsстатический рендер панели в HTML для скриншотов (npm run preview → docs/*.html)
icon.svgиконка пакета

Маршруты Host, по одной семье на половину, все относительные к документу:

МаршрутНазначение
api/mcp-docker-statusснимок состояния серверов и контейнеров
api/mcp-docker-status/actionстарт / стоп / рестарт контейнера
api/cfsmcp2-contextsкаталог, состояния сущностей и очередь индексации
api/cfsmcp2-contexts/actionперечитать контекст из источника
api/lmstudioмодели LM Studio с их загруженностью
api/sessions-activityходы по сессиям внутри периода, из хранилища сессий
api/sessions-exportзаписать JSON/XLSX в ~/Downloads

Устойчивость и диагностика

Вход бандла не бросает исключений: каждая регистрация (тип вкладки, страница, места, установка стилей, автооткрытие) обёрнута в свой try/catch, отказ пишется в консоль как [dsh-pult] <шаг> и не роняет остальные. Хост-половина устроена так же (start() внутри guarded apply). Причина — отказ одной регистрации в dsh репортится как «бандл не активировался» и уносит всю загрузку приложения, а панель сайдбара этого не стоит.

Клиентская половина после активации отправляет POST api/dsh-pult/diag с отчётом (какие регистрации прошли, какая отказала и с какой ошибкой), а хост-половина пишет его в $TMPDIR/dsh-pult-activation.log и в лог хоста. Если файл пуст — бандл не доехал до браузера; если в нём есть failed — виден точный шаг. Каждый старт Host пишет туда же строку host start routes=…: если в файле нет свежей строки с нужным маршрутом, значит работает старый Host и приложение надо перезапустить, а не переключать плагин. Временный инструмент удаляется вместе с DIAG_PATH в index.js.

Сайдбар помнит вкладку на каждую сессию

Вкладка запоминается парой kind/id. Страница сохраняет пару прежней вкладки серверов — kind: 'mcp-docker-status', id: '@local/cfsmcp2-contexts' — поэтому сессия, запомнившая вкладку до объединения, открывает её, а не заглушку «Nothing here can view this kind of content yet». В справочнике (guide) страница одна.

Разработка

Сборки нет: client.js — готовый браузерный бандл, index.js — обычный ESM. Проверка синтаксиса и рендер превью:

npm run check          # node --check index.js && node --check client.js
npm run preview        # docs/preview.html, docs/preview-sessions.html, docs/preview-models.html

scripts/preview.mjs подменяет React заглушкой и вызывает настоящие компоненты панели с вымышленными данными, поэтому картинки в README — это реальный рендер кода, а не макет. Скриншоты снимаются с получившихся HTML-страниц.

Лицензия

MIT — см. LICENSE.

Comments

Loading…

Similar plugins

dsh-lazy-mcp

by zhe97396-tech

MCP gateway for dsh that connects each server on first use and disconnects it after an idle window; tool lists are cached on disk, existing mcpServers files can be imported, and child-process environm

Tools & CapabilitiesModels & ProvidersManifest valid

★ 0

MIT

JavaScript

Oct 19, 2026

dsh plugin --profile web add dsh-lazy-mcp

by whiteS18

MCP server management panel in Settings: add, edit, enable/disable and delete servers across user and workspace scopes with form or JSON editing, and auto-register discovered MCP tools as native conve

UI & ExperienceManifest valid

★ 0

MIT

JavaScript

Oct 8, 2026

dsh plugin --profile web add dsh-mcp-servers-panel

by jipika

dsh-skill-mcp-panel (local build): 技能与 MCP 管理改为设置窗口分栏,不再占用侧栏与中央主区。基于上游 2.1.0。

Manifest valid

★ 0

MIT

JavaScript

Oct 20, 2026

dsh plugin --profile web add dsh-skill-mcp-panel

by functy23

DeepSeek Harness 的 MCP 服务与 Skills 管理器:面板里增删改 MCP 行、扫描导入其他 Agent 配置、管理 Skills(DSH Web 插件)

Tools & CapabilitiesManifest valid

★ 34

↓ 248/wk

MIT

TypeScript

Oct 6, 2026

dsh plugin --profile web add dsh-mcp-studio

by imaused

Expose a stdio MCP server (Playwright, Chrome DevTools, any MCP) as native DeepSeek Harness tools

Tools & CapabilitiesManifest valid

★ 0

MIT

JavaScript

Nov 1, 2026

dsh plugin --profile web add dsh-mcp-bridge

by hlyyh21201-prog

DSH plugin: manage MCP servers from the Web settings panel (list, start/stop, edit, probe by real handshake) and import configs from Codex TOML, mcpServers JSON and VS Code mcp.json.

Manifest valid

★ 0

MIT

JavaScript

Oct 16, 2026

dsh plugin --profile web add @yyh/dsh-mcp-hub