DSH Plugins Marketplace

DSH Plugins

Plugins

/

dsh-restart

d

dsh-restart

Identified

Restart DeepSeek Harness from the sidebar or from an agent tool, with a watchdog, profile rollback and auto-continue

dsh-restart

Перезапуск DeepSeek Harness из интерфейса или инструментом агента — с возможностью продолжить ту же сессию после старта.

Что делает

ВозможностьГде
Кнопка «Перезапустить»футер сайдбара, рядом с аккаунтом (иконка питания)
Подтверждениемодалка с двумя кнопками, без лишних опций
Инструмент агентаdsh_restart({ fake }) — только для разработки расширений
Продолжение сессиирестарт инструментом открывает сессию и пишет [auto.continue]

Как работает рестарт

Перезапускающий процесс не может быть потомком приложения: taskkill /T убивает всё дерево вместе с ним. Поэтому плагин:

  1. пишет маркер %LOCALAPPDATA%\dsh-restart\pending.json;
  2. создаёт одноразовую задачу планировщика DSH-Restart (Windows) с helper-скриптом;
  3. helper ждёт 1.5 с, закрывает дерево процесса приложения, ждёт 1.8 с, запускает .exe и удаляет задачу.

На macOS/Linux используется отдельный sh-процесс (kill + open/запуск).

Автопродолжение

После старта клиент читает маркер через локальный мост 127.0.0.1:49233:

GET  /claim      → { marker } — атомарно: маркер получает только один клиент
POST /restart    → записать маркер и перезапустить
GET  /health     → признак живого хоста для сторожа
GET  /settings   → текущие переопределения
POST /settings   → сохранить переопределения (без перезапуска)

Маркер забирает ровно одна загрузка страницы, поэтому двойная инициализация не даёт двух сообщений. Рестарт инструментом возвращает сессию сообщением [auto.continue]: клиент открывает ту же сессию, дожидается готовности композера, вставляет текст и отправляет его кнопкой отправки (Enter — запасной вариант). Кнопка в футере сайдбара маркер не создаёт и сессию не продолжает.

Черновик пользователя не теряется: если в поле уже есть текст, он временно откладывается в localStorage, отправляется [auto.continue], после чего текст возвращается в поле ввода (без отправки). Очередь сообщений — состояние сессии, плагин её не читает и не меняет.

Инструмент

Инструмент нужен для разработки и отладки самого DSH: плагин, cordis.patch.yml, профиль. Он не предназначен для обычной работы, «обновления состояния» или вызовов без изменения кода/конфигурации, которое требует свежего процесса.

dsh_restart { fake: true }
→ Preflight passed; fake restart requested, nothing was restarted.

Без fake инструмент перезапускает приложение и возвращает сессию сообщением [auto.continue]. Флаг fake прогоняет все проверки, но ничего не перезапускает — для тестов. Если инструмент отключён, вызов из старой памяти падает с unknown tool "dsh_restart".

Настройки плагина

На странице Plugins → Restart → Configure:

НастройкаПо умолчаниюЧто делает
Команда dsh_restart доступна агентувключенопри выключении инструмент исчезает; вызов из старой памяти падает с unknown tool "dsh_restart"
Сторож активенвключенопри выключении рестарт просто закрывает и открывает приложение, без отката профиля
Ожидание сторожа, сек10сколько ждать признака живого старта перед откатом (1–120)

Переопределения хранятся в %LOCALAPPDATA%\dsh-restart\settings.json; значения из cordis.patch.yml остаются умолчаниями. Сохранение настроек не требует перезапуска: инструмент регистрируется и снимается на лету.

Когда инструмент отказывает

dsh_restart доступен агенту только в «тихом» режиме — когда перезапуск никому не помешает:

ПроверкаОтказ
Вызов из подагентаdsh_restart is only available to the main agent: a subagent cannot restart the app; do not retry, report the need to the parent agent instead
Режим доступа не Full accessdsh_restart requires the Full access permission preset (current: …)
Другая сессия или подагент ещё работаетdsh_restart refused: N other session(s) or subagent(s) are still working (…)
Есть работающая фоновая задачаdsh_restart refused: N background job(s) are still running (…)

Проверки идут через ctx.permissionPresets.current(agent.session), ctx.agents.list() и ctx.jobs.list(agentId); статус «работает» — running либо непустая очередь входа агента. Признак подагента — exec.agent.options.subagentDepth (плюс exec.parent).

Кнопка в интерфейсе эти проверки не выполняет: пользователь сам решает, когда перезапускать.

Ограничения

  • пункт в трее и в нативном меню Application плагином добавить нельзя: трей и меню живут в процессе Electron main, а плагин — в дочернем host-процессе;
  • перезапуск выполняется через Планировщик задач Windows; если политика запрещает создание задач, рестарт не сработает;
  • воркспейс-сессии, которые в этот момент выполняют ход, будут прерваны (как и предупреждает модалка).

Кнопка и инструмент ведут себя по-разному

  • dsh_restart (агент) — всегда открывает сессию и пишет [auto.continue] (или [auto.continue.failed], если сторож откатил профиль).
  • Кнопка «Restart DeepSeek Harness» в сайдбаре — просто перезапускает приложение: маркер не создаётся, сессия не продолжается, авто-сообщение не отправляется.

Куки и «Web authentication failed»

Каждый запуск Desktop Host занимает новый порт и ставит куку dsh-auth-<random> для 127.0.0.1. Chromium хранит куки по хосту, а не по порту, поэтому старые куки не заменяются и копятся. Замерено на живой установке: около 122 таких куки дают заголовок Cookie примерно на 17.5 КБ, он перестаёт влезать в лимит (16 КБ), приветственный запрос получает 431, и приложение падает с desktop welcome: Web authentication failed. Дополнительно срок жизни этих куки ограничен в профиле: connection.cookieMaxAgeDays: 7.

Перед каждым запуском (после убийства приложения, до Start-Process) helper запускает src/cookie-clean.py и удаляет только строки dsh-auth-* для 127.0.0.1/localhost. Остальные куки не трогаются.

Если приложение всё же упало именно на приветствии (лог падения содержит Web authentication failed), сторож не откатывает профиль и не отключает плагины: он чистит куки, запускает приложение ещё раз и ждёт здорового старта.

Привязка сторожа к рестарту

Каждый рестарт получает токен:

dsh_restart → marker { token, sessionId } + watchdog.json { token }
сторож  → перед откатом сверяет токен в watchdog.json
старт   → хост удаляет watchdog.json (токен аннулирован)

Поэтому сторож срабатывает только для того рестарта, который его запустил, и не может тронуть приложение, поднятое позже или другим рестартом.

Перед откатом сторож сравнивает SHA-256 файлов package.json, cordis.patch.yml, cordis.yml с сохранёнными в момент запроса. Если файлы изменились вручную, откат не выполняется — считается, что правки взял на себя человек.

Файлы профиля пишутся без BOM (WriteAllText + UTF8Encoding(false)), иначе хост не может прочитать package.json.

Известное ограничение: задача подагента после его завершения

Если подагент запустил фоновую задачу и завершил ход, DSH удаляет запись об этой задаче вместе с агентом, хотя сама задача продолжает работать. Проверка перед рестартом такую задачу не увидит и рестарт не отклонит.

Что покрыто:

Владелец работыОтказ
Своя фоновая задачада
Подагент или чужая сессия ещё работаютда
Их задачи, пока владелец живда
Задача подагента после завершения его ходанет

Почему так: реестр задач ctx.jobs ключуется по id агента и очищается при его уничтожении; обёртка jobs.start видит только задачи, запущенные через этот путь, а подагент запускает их иначе. Детект по дочерним процессам ненадёжен: рядом постоянно появляются и исчезают служебные процессы приложения. Решение отложено.

Установка

npx --yes github:machine202502/dsh-restart

Или вручную:

"dsh-restart": "github:machine202502/dsh-restart#main"

и добавить dsh-restart в dsh.profile.bundles.

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

Проверка

node tests/smoke.mjs                   # инструмент, проверки, fake, мост
node tests/load-client.mjs client.js   # клиентский модуль грузится и отдаёт apply

Лицензия

MIT

Comments

Loading…