volna-tweaks

DSH PLUGINUI 与外观

仓库 pridurok-goxa/volna-tweaks

UI 与外观 未标注验证等级 安全审查:未标注 可信度:未标注 可安装插件
安装这个插件

Volna 是一个 DSH plugin 微调合集,用一个包为 DeepSeek Harness 加上移动端界面、面板自由缩放、文件下载、队列编辑与费用红绿灯等开关式增强。

一句话选型结论

按资料字段整理

volna-tweaks 是UI 与外观类的 DSH 可安装插件,未做沙盒验证,暂无安全审查结论,列出 5 项功能,有可直接复制的安装命令。验证通过不等于安全:插件会读写文件、执行命令或联网,装前先到仓库确认它做了什么;涉及密钥或系统权限的,建议先在隔离环境试装。

分类UI 与外观 收录类型可安装插件 验证等级未标注验证等级 安全审查未标注
验证等级 UNKNOWN 未标注验证等级
GitHub 星标 0 复刻 0 · 未关闭 issue 未标注
最近更新 2026-11-13 创建于 2026-10-08
README 75.4 KB 正文体量,越大说明说明书写得越细

安装

可安装插件
在 DSH 里执行,装完用 dsh plugin list 确认已挂上;标了 L4 / L5 的命令已在沙盒里真实跑通
dsh plugin --profile web add github:pridurok-goxa/volna-tweaks
  1. 1
    确认版本与运行环境

    仓库没有标注兼容版本与 Node.js 要求,先确认你的 DSH 版本能装,再继续。

  2. 2
    执行安装命令

    在 DSH 里执行上面的命令;多包仓库要注意区分具体子包名,别装错包。

  3. 3
    确认已挂载

    用 dsh plugin list 查看列表里是否出现这个插件,出现即挂载成功。

  4. 4
    试跑并检查权限

    加载后跑一个最小用例,确认它能正常工作;同时看它申请了哪些文件、命令或网络权限。

兼容 DSH 版本未标注版本不匹配时安装会报错
Node.js 要求未标注来自仓库 package.json 的 engines 字段
前置依赖无需要同时安装的同级依赖
npm 包名未发布到 npm可用 npm view 查看包信息

能做什么

5 项功能
字段来自项目仓库与公开索引,中文说明由本站标注

volna-tweaks:DeepSeek Harness 的界面调整组合包

  • 移动端输入与侧边栏优化
  • 面板宽度自由拖拽缩放
  • 聊天文件一键下载
  • 带附件的队列编辑表单
  • 高价时段红绿灯暂停

上游标签

deepseek-harnessdsh-plugintweaksui-zoom

验证等级与安全审查

未标注验证等级
自动化流程结论,不是人工审核
验证等级未标注验证等级上游未给出验证结论,安装前请自行确认
安全审查未标注静态分析结论,未标注不代表已通过审查
仓库健康度未标注按仓库活跃度与最近更新时间给出
可信度未标注综合仓库活跃度与验证结果

选择建议

装之前先看这几条
按条目字段给出的判断,不替你决定用不用

值得选的地方

  • 有可直接复制的安装命令,不用自己翻文档找入口。
  • 列出了 5 项功能,能直接看出它解决什么问题。

先想清楚的地方

  • 安全审查还没结论,装之前先看仓库改了什么、要什么权限。
  • 没有声明 Node.js 版本要求,版本不匹配可能装不上。
  • 验证通过不等于安全:插件会读写文件、执行命令或联网,装前先到仓库确认它做了什么。

更适合

  • 需要在UI 与外观场景里给 DSH 补能力的人。
  • 能接受在本地装依赖、愿意自己确认权限的人。

不太适合

  • 只使用 DSH 官方内置能力、不接受第三方插件的人。

同类对比

6 个同类
同分类里挑最接近的几条,字段以各自详情页为准
插件验证等级安全审查星标兼容版本安装命令
volna-tweaks当前 未做沙盒验证 未标注 0 未标注 有
nuwa-skill 未做沙盒验证 未标注 3.8 万 未标注 有
awesome-dsh-plugin L4 · 沙盒安装通过 低风险 1.8 万 0.1.1-rc.2 有
deepseek-balance-whale-widget L4 · 沙盒安装通过 低风险 4,492 0.1.7-rc.2 等 2 个 有
dsh-better-sidebar L4 · 沙盒安装通过 低风险 4,112 0.1.7-rc.2 等 10 个 有
dsh-deep-whale L4 · 沙盒安装通过 低风险 2,470 未标注 有

仓库档案

UI 与外观
字段来自项目仓库与公开索引,中文说明由本站标注
作者 / 维护方pridurok-goxa仓库 volna-tweaks · 默认分支 未标注
分类UI 与外观interface
收录类型可安装插件声明了 dsh.bundle、可用 dsh plugin add 安装的条目
开发语言JavaScript仓库主语言
许可证未标注商用或二次分发前请确认条款原文
星标 / 复刻 / issue0 / 0 / 未标注收录时的数值,非实时
创建 / 更新2026-10-08 · 2026-11-13最后推送 未标注
本站收录2026-11-14首次进入本站目录的时间

README 全文

75.4 KB
作者原文,中文版优先;只做安全转义,不改内容

Волна твик (volna-tweaks)

Твики DeepSeek Harness одним пакетом. Каждый включается своей галочкой на странице
пакета (Settings → Plugins → «Волна твик») и выключается там же — без перезапуска.

Твик Что делает
fileDownload Скачивание файлов: долгое нажатие на файловой карточке в чате и пункт «Скачать» в меню вкладки файла правой панели
queueEditor Единая форма редактирования очереди: текст и вложения, добавление/удаление, сохранение на прежнем месте; host-роут в tweaks/queue-edit-host.js
mobileComposer Мобильный ввод: Enter/paste без отправки, «+» только File/Goal/Plan, / без меню, системный чип Plan (вход через «+» → Plan), прокрутка к каретке, высота черновика вдвое меньше, без подчёркивания ввода
mobileSidebar Мобильный shell: ящик слева, иконка и название в шапке, чат на всю ширину, панели в нижней иконке, все меню в верхнем «…»
zoom Масштаб всего интерфейса: пара клавиш меняет размер интерфейса, а не только шрифт переписки
contextMenu Своё меню по правой кнопке: системное меню Electron не масштабируется вместе с интерфейсом
whisper Распознавание русской речи локальной моделью Whisper (tweaks/whisper-host.js, Python-воркер): выключено по умолчанию
trafficLight Светофор дорогих часов DeepSeek: лампа и переключатель «Спецсигнал» под полем ввода; на пике встают все ходы (цель, итоги субагентов, сообщения команды, расписания, внешние сообщения), на зелёном продолжаются сами; спецсигнал пускает чат и всё его дерево работать на красном
imageModelFallback Кнопка «Отправить с Flash» над полем ввода, когда выбранная модель не видит изображения: меняет модель и повторяет отправку
freePanels Свободный размер панелей: штатный драг не упирается в лимиты DSH (сайдбар 264–420, правая панель 300 – 0.7 окна, центр не уже 400)

Свободный размер панелей (твик freePanels)

Штатный драг панелей DSH клампит ширины: сайдбар 264–420 px, правая панель
300 px – 70% окна (min(окно − сайдбар − 400, 0.7·окно)), центральная колонка не уже
400 px. Из-за этого панель упирается, а ручка продолжает «уезжать» от курсора.

Твик перехватывает нажатие на ручку рамки в capture-фазе — приложение свой
DragHandle не получает — и пишет ширину прямо в сетку рамки. Правила:

  • тянуть можно до 120 px с каждой стороны и так, чтобы центру осталось не меньше
    120 px (граница — 120 px, чтобы было чем взяться за разделитель);
  • ширины запоминаются (localStorage, ключ dsh.ui-panels.v1) и применяются на
    следующей загрузке; пока панели не тянули, используется ширина приложения;
  • свернутый сайдбар и закрытая/полноэкранная правая панель не трогаются — там
    шириной распоряжается само приложение;
  • в настольном приложении вместе с сеткой обновляется
    --dsh-windows-sidebar-width, чтобы шапка окна оставалась выровненной;
  • в масштабе сдвиг курсора уже в логических пикселях: координату на ручках
    [data-side] делит твик «масштаб», второй раз делить нельзя.

Разметка DSH берётся только по data-*-атрибутам и суффиксам классов
([class*="_frame"], [class*="_sidebarCol"], [data-rightbar-col],
[data-side="..."]), поэтому привязки к хешам сборки нет и твик работает и в
браузере, и в настольном приложении.

Редактор очереди с вложениями (queueEditor)

Durable-строки очереди (не Sending...) редактируются одной формой в стиле
основного композера: textarea с переносом Enter, вложения с превью и ×,
кнопка «+ Вложение» (картинки и файлы), Save/Cancel.

Клик по штатному карандашу перехватывается и открывает форму вместо нативного
inline-редактора. Хостовый роут POST /dsh-tweaks/queue/edit сохраняет новые
вложения через attachments.saveImages/saveFile, проверяет, что существующие
ссылки принадлежат этому элементу очереди, и заменяет сообщение через
agent.inbox.replace — позиция в очереди не меняется, остальные строки не
трогаются. Форма поднимается в conversation.input.dock над очередью; на телефоне
она на всю ширину. При исчезновении элемента/ошибке форма остаётся открытой с
текстом ошибки, очередь не меняется. Хост-роут требует перезапуска dsh.

Скачивание файлов (fileDownload)

Долгое нажатие (≈0.5 с) на файловой карточке в чате открывает меню со строкой
«Скачать» и «Копировать путь». В правой панели у вкладки файла меню
(долгое нажатие / контекстное меню) получает «Скачать» и «Копировать путь»
рядом со штатным Close. Путь для durable-вложения разрешает host через
attachments.fileHostPath, для workspace-файла — через workspaceFiles.stat.

Байты отдаёт хост-роут POST /dsh-tweaks/download: durable-вложение читается
attachments.readFileStream, файл workspace — workspaceFiles.readBytes.
Браузер получает Blob и скачивает обычной ссылкой. Роут закрыт штатным
connection-фильтром; клиентская галочка fileDownload только управляет UI.
Хост-роут требует перезапуска dsh.

Меню «+»: только строки

Позицию, ширину, анимацию и закрытие меню «+» задаёт ядро. Твик больше не
перехватывает клик по «+» и не пишет position/left/top меню: он только
скрывает лишние строки, оставляя File/Goal/Plan (Файл/Цель/План).

Меню «+» на любом языке

Фильтр оставляет в меню только File/Goal/Plan по служебным alias (file,
goal, plan), а не по видимой подписи. Поэтому русские «Файл/Цель/План» и
другие локали не превращают меню в пустое.

Твик «цель живёт» (host)

goalKeepalive — host-твик: после restart/fork/resume возвращает активацию
цели active+disarmed, не трогая ручную паузу, complete и blocked.
Журнал — $DSH_HOME/dsh-tweaks/goal-keepalive.log, ротация 1 МБ.

Страховка агентов (agentGuards, host)

Механическая страховка к правилам агентов HARNESS (аудит промахов 13.11.2026).
Хук tools/pre-execute отказывает в вызове до исполнения тела инструмента:

Правило Флаг Что ловит Промахи
secrets agentGuardsSecrets в bash: PGPASSWORD=<литерал>, DSN postgres://u:<пароль>@, --password=<литерал>, Bearer <токен>, токены ghp_/gho_/github_pat_/re_/sk-/xox?-. $VAR, ${VAR}, $(…) разрешены 18, 21
wip agentGuardsWip +wip в команде выката; dev-stand.sh deploy/resume с --allow-shared-tree или из грязного worktree (git status --porcelain); --ref пропускается 1, 2, 8, 13
rootWrite agentGuardsRootWrite write/edit/apply_patch в основной checkout на main/master внутри agentGuardsRootWriteRoots (по умолчанию /home/goxa/project); linked worktree и agentGuardsRootWriteAllow (docs/plans/, .cursor/plans/, reports/, .local/, .wt/, INFRA-CHANGES.md) пропускаются 1, 2, 20, 26
loop agentGuardsLoop agentGuardsLoopLimit (3) одинаковых вызовов подряд у одного агента (имя + аргументы без description) 16, 22

agentGuards: false снимает хук целиком. Флаги volatile: правка в
cordis.patch.yml профиля применяется без перезапуска плагина. Галочек в
форме нет — это политика инстанса, а не вкус пользователя.

Журнал отказов — $DSH_HOME/dsh-tweaks/agent-guards.jsonl (JSON на строку,
ротация 1 МБ): ts, rule, tool, session, sub, reason, misses.
Значение секрета в журнал не пишется — только вид совпадения. Журнал читает
еженедельный разбор реестра инцидентов.

Ошибка самой проверки = пропуск вызова (fail-open) и строка guard-error;
git вызывается с таймаутом 3 с. Проверка: node test/check-agent-guards.cjs.

Диагностический выключатель

?tweaks=off выключает твики только для этой ссылки: параметр остаётся в
адресе, но в localStorage ничего не записывается. Обычная ссылка без параметра
всегда включает твики; старый сохранённый флаг снимается автоматически.
?tweaks=on тоже снимает legacy-флаг. Перезапуск DSH не нужен.

Мобильная панель твиков и версии

В подвале мобильной левой панели есть кнопка «Твики»: она открывает ту же форму
флагов, что и страница пакета, в собственной шторке — без перехода
Plugins → Волна твик. Под каждым переключателем указаны полные версии:
0.2.1-rc.5 и 0.2.2-rc.1. Твики, которые ядро 0.2.2-rc.1 уже делает само
(drawer, автоскрытие, клавиатура, центр, меню «…»), на нём не применяются.

Светофор регистрируется в conversation.input.dock на 0.2.1-rc.5 и
0.2.2-rc.1; старый conversation.composer.dock остаётся fallback для более
ранних сборок. На 0.2.2-rc.1 лампа стоит в conversation.composer.dock —
под полем ввода, первой перед статистикой ходов/токенов/контекста. По умолчанию
она показывает не текущие часы, а оставшееся время до смены тарифа
(2ч 15м, 17м); на красном — до зелёного. Панель «Дешёвые часы» открывается
у этой лампы. Вторым элементом в строке дока стоит переключатель «Спецсигнал»,
а подпись лампы (aria-label/title) — это статус: «ждёт зелёного до 13:00»,
«спецсигнал: работа на красном (вдвое дороже) до 13:00» или «вне пика — до пн
04:00».

Совместимость версий ядра

Твики определяют возможности DOM, а не номер версии. Если у ядра есть нативный
drawer (data-sidebar-drawer / drawerMask), мобильная левая панель остаётся
за ядром: наш слой не пишет fixed-правила и не накладывает вторую подложку.
freePanels в этом режиме держит первую колонку сетки нулевой, а zoom не
раздувает узкую рамку до 1024 px. На ядре без drawer работает наш выдвижной
слой и прежняя сетка.

Меню верхнего «…»: быстрый показ

Пункты (Copy session ID, Feedback, Download session log, виды) собираются в меню
до его появления; затем меню один раз проявляется на финальной позиции с
коротким сдвигом сверху вниз (130ms ease-out). Пока идёт сборка, меню скрыто,
поэтому оно не растёт и не дёргается после открытия.

Панель светофора: над лампой при любом масштабе

Панель «Дешёвые часы» рендерится порталом в body, вне зум-контекста #root.
Позиция считается в визуальных пикселях окна, а собственный transform: scale() панели компенсирует масштаб интерфейса. Панель всегда садится низом
над лампой, прокручивается при нехватке места и пересчитывается при смене
масштаба/размера окна. Это исправляет уезжание за окно в Windows-приложении,
браузере и на телефоне.

Кнопка «отправить с Flash» (твик imageModelFallback)

Когда сервер отвергает отправку с причиной «модель не поддерживает изображения»
(например, в чате выбран DeepSeek-V4-Pro), обычный текст ошибки ничего не предлагает
сделать. Твик добавляет над полем ввода плашку с кнопкой Отправить с Flash:

  • неудавшаяся отправка к этому моменту уже восстановлена в поле ввода (текст и
    картинки), поэтому кнопка не теряет вложение;
  • клик переключает модель через штатный modelDirectories.directoryFor(sessionId).select
    (провайдер, модель и
    уровень рассуждений берутся из настроек и текущего выбора сессии) и повторяет
    ту же отправку публичным inputActions.submit();
  • причину отказа сервер присылает кодом MODEL_DOES_NOT_SUPPORT_IMAGES — по нему
    плашка и появляется, поэтому чужие ошибки она не перехватывает;
  • крестик скрывает плашку до следующего отказа.

Провайдер и модель-замена — служебные поля схемы Config (index.js), а не галочки:
imageFallbackProvider (по умолчанию deepseek-account), imageFallbackModel
(deepseek-flash) и imageFallbackLabel (Flash) — подпись на кнопке. Правятся
через патч профиля, если раскладка моделей на сервере другая.

Клавиши (твик zoom)

Действие Основной блок Нумпад Мышь
Крупнее Ctrl + = Ctrl + + Ctrl + колесо вверх
Мельче Ctrl + - Ctrl + − Ctrl + колесо вниз
Сброс 100% Ctrl + 0 Ctrl + 0 —

Shift не нужен: клавиша читается по позиции, поэтому Ctrl + Shift + = тоже
работает, и раскладка не важна. Шаг — 5%, диапазон — 50…200%. Размер показывается
плашкой в правом нижнем углу 1,2 с и хранится в localStorage (ключ dsh.ui-zoom.v1).

В браузере Ctrl + = / - / 0 забирает страница, поэтому там те же действия
доступны с Alt. Переназначить любую комбинацию: Settings → «Горячие клавиши».

Установка

plugin_manager action=install_bundle target=<путь к папке плагина>

Репозиторий: https://github.com/pridurok-goxa/volna-tweaks.

Windows:

git clone https://github.com/pridurok-goxa/volna-tweaks.git C:\volna-tweaks

Затем в DSH: plugin_manager action=install_bundle target=C:\volna-tweaks.

Вручную: добавить "volna-tweaks": "link:<путь>" в зависимости профиля, вписать
volna-tweaks в dsh.profile.bundles, затем pnpm install в папке профиля.

Как устроено

  • client.js — браузерная половина: реестр TWEAKS, чтение флагов, форма, код твиков.
  • index.js — хост-половина: схема Config с флагами твиков и подключение
    хост-частей (tweaks/whisper-host.js, tweaks/traffic-light-host.js).
  • cordis.patch.yml — одна запись пакета (id: zoom); строка на странице Plugins
    выключает пакет целиком, поэтому отдельные твики живут флагами, а не записями.
  • locale/en.json, locale/ru.json — подписи карточки пакета (meta.title,
    meta.description); блок meta: в cordis.patch.yml страница Plugins не читает.

Включение и выключение твиков

Флаг твика — поле схемы Config в index.js, помеченное .volatile(): только такие
поля DSH показывает в настройках и принимает на запись, а их смена доходит до живой
записи без перезапуска. Имя поля = id твика в реестре TWEAKS в client.js.

Форму DSH не рисует — её рисует плагин. Галочки живут в слоте
plugins.bundle.config с ключом dsh-tweaks, то есть на странице самого пакета.
Клик по галочке сразу пишет значение (set с прочитанной ревизией) в клиентский
сервис configForms — тот же, откуда плагин читает флаги: namespace формы — id
записи в cordis.patch.yml, то есть zoom.

client.js держит один набор твиков на пакет: apply(ctx) читает флаги,
включает включённые, выключает выключенные и подписывается на изменения. Ресурсы
твика регистрируются через api.own и снимаются при выключении, поэтому повторное
включение не оставляет двойных обработчиков. Пока конфигурация не готова
(configForms нет или status !== 'ready'), работают дефолты реестра: zoom,
contextMenu и trafficLight включены, whisper — нет. В готовом снимке
отсутствие поля — это тоже дефолт реестра: пропавшее поле не включает твик,
выключенный по умолчанию.

Выключение zoom возвращает интерфейс к 100% (значение в localStorage остаётся,
включение вернёт прежний масштаб); попапы при этом возвращаются к исходным
координатам. Выключение contextMenu возвращает системное меню.

Новый твик: поле в Config (index.js), запись в TWEAKS (client.js) и, если у
твика есть код, свой регион в client.js — /* #region tweak- */. Соседей это
не задевает.

Хост-часть твика

Хост-часть твика (если нужна) — отдельный файл tweaks/-host.js, который
index.js подключает по флагу. Клиентская половина у пакета одна, отдельного
модуля на твик не бывает; клиентской части может не быть вовсе — у whisper её
нет, галочка включает хост-часть.

Плагин читает флаги через событие loader/volatile-update: смена одних только
volatile-полей не перезапускает плагин, а DSH компилирует новые значения в уже
выданную конфигурацию и уведомляет владельца записи. Значения volatile-полей
приходят ссылками Volatile (.get()), поэтому хост-часть получает развёрнутую
копию конфигурации обычными значениями. Жизненный цикл твика whisper: флаг
включён — activate(ctx, config); выключен — deactivate(); сменился
whisperModel у включённого — deactivate() и следом activate() с новыми
значениями (размер модели провайдер читает один раз при регистрации).
Переключения идут очередью, а выгрузка плагина ждёт deactivate() — Python-воркер
не переживает твик.

Жизненный цикл твика trafficLight проще: activate(ctx, config) ставит
слушателей и таймер, а смена значений политики приходит в update(config) без
перезапуска — удержанные на красном напоминания переживают правку окон.
deactivate() снимает слушателей, будит ожидающие вызовы и возвращает удержанное
в работу.

Модуль твика импортируется динамически и в try/catch: файла может не быть
(другая ветка, неполная поставка), и тогда причина уходит в лог, а схема Config
и остальные твики продолжают работать. Поле files в package.json включает
tweaks/**, поэтому Python-воркер (tweaks/worker.py) попадает в поставку.

При первом включении твика «речь» хост-половина один раз выставляет настройки
распознавания: после успешного activate (провайдер whisper-local уже
зарегистрирован) идёт ctx.speechToText.configure({ providerId: 'whisper-local', language: 'ru' }), а затем в своё служебное volatile-поле whisperSelectionApplied
записывается признак «выставлено». Галочки у этого поля нет: форма строится из
реестра TWEAKS, а не из схемы. Дальше выбор не перезаписывается — сменил
пользователь провайдера или язык руками, configure больше не зовётся. Ошибка
(службы распознавания нет, язык не поддержан, служба настроек недоступна) уходит
в лог и твик не роняет; признак при этом не ставится, поэтому при следующем
включении попытка повторяется.

Светофор дорогих часов

Правило тарифов DeepSeek (сверено с официальной страницей цен,
ред. 2026-09-10): пиковая цена действует по будням 09:00–12:00 и 14:00–18:00
по Пекину
(для Москвы это 04:00–07:00 и 09:00–13:00), кроме официальных
праздников КНР; всё остальное время — полцены. Полуинтервалы: граница 12:00 уже
вне пика, 14:00 — снова пик.

Индикатор — круглая лампа под полем ввода, самой первой в строке дока
(перед системными показателями): зелёный — полцены, жёлтый мигает
за выбранное время до пика, красный — пик. В шапке индикатора нет: она остаётся
за системными кнопками и заголовком чата. На красном при работающих сессиях
лампа дышит (плавно растёт от меньшего размера до нормального) и на каждом
максимуме роста от её края уходит мягкая волна — радиус ограничен 2.6 диаметра
лампы, поэтому волна не выходит за пределы индикатора. Панель открывается только по нажатию на лампу, раскрывается вверх от неё и никогда не уходит за край окна: если места над лампой мало, панель ограничивается по высоте и прокручивается внутри. Оформление повторяет
системный попап (беседа «Token usage»/контекст): матовый полупрозрачный фон
--dsw-specific-menu, блюр подложки --dsw-menu-backdrop-filter, системные тень и
скругление. Внутри — горизонтальная шкала суток: 24 кружочка от 0 до 24 часов в
местном времени разработчика, красные — дорогие часы, зелёные — дешёвые (в
выходные и праздники вся полоска зелёная), текущий час крупнее и под указателем
«сейчас». Жёлтых кружочков на шкале нет: жёлтой мигает только лампа, предупреждая о
приближении дорогого времени. Под каждым кружочком постоянно видна подпись его часа,
а часы, открывающие зелёный диапазон (после дорогого окна или с начала суток),
выделены жирнее — по ним читается структура дня: для московских окон это 00, 07 и 13.
Подпись под шкалой в покое показывает текущий час, при наведении — час под курсором,
формат один и тот же, поэтому ничего не появляется и не пропадает. Ниже — отсчёт до смены тарифа,
правило тарифов отдельными строками (будни и часы, праздники, текущий часовой пояс)
и строка «Смена тарифа» с адресом: например «пн 09:00 (через 60 ч)» — в пятницу
вечером следующее дорогое окно действительно в понедельник, потому что выходные
целиком дешёвые. Наведение на шкалу подсвечивает час под курсором и его статус: зона
наведения — вся полоска, поэтому на переходах между кружочками шкала не мигает.

Рядом с лампой — маленький переключатель «Спецсигнал»: в покое тускло-серая
точка, включённый — синяя с двойными вспышками, как проблесковый маячок
(при prefers-reduced-motion: reduce — статичный синий без анимации). Он
пускает этот чат и всё его дерево субагентов работать на красном (вдвое дороже)
и включается-выключается только человеком. Состояние живёт не в localStorage,
а в конфиге пакета (поле trafficLightSpecial), поэтому действует на всех
устройствах и переживает рестарт DSH. Начальное значение — чат
session-e4698bf8-717f-4e1a-9390-a2b40c03d985: включено по решению Игоря
(t1447u), он работает на красном вместе со своим деревом. В панели та же кнопка
стоит строкой
«Спецсигнал: вкл/выкл» с пояснением, что чат и команда работают на красном, а
строка статуса отвечает на вопрос «чего и до каких пор ждём» — см. «Пауза на
красном». Если запись не сохранилась (настройки успели поменять в другой
вкладке), кнопка один раз перечитывает снимок и повторяет запись, а на 5 секунд
показывает подсказку «Спецсигнал не сохранился…».

Настройки твика — на странице пакета рядом с галочкой, свои у каждого браузера
(лежат в localStorage, ключ dsh.ui-light.settings.v1, хост-половине они не нужны):

Настройка Значения
Нижний индикатор (dockMode) «Только индикатор» · «Индикатор и время» (по умолчанию) · «Индикатор и оставшееся время» · «Индикатор, время и тариф»
Предупреждение (warningMinutes) за 10 (по умолчанию), 20 или 30 минут до пика

Умолчания одинаковы для всех: твик включён, нижний индикатор — «Индикатор и
время», предупреждение — за 10 минут до пика. Личные правки в браузере
перекрывают умолчания только у того, кто их сделал: это настройки показа, паузы
и спецсигнал от них не зависят.

Пауза на красном

На красном встают все ходы без спецсигнала, а на зелёном они продолжаются
сами — без нажатий и повторов:

  • модельный вызов (llm/stream) любой сессии ждёт зелёного: цель, итоги
    субагентов (subagent-settled), сообщения команды (agent-message и
    team-message), расписания, внешние сообщения. Входящие не изымаются — их ход
    просто ждёт, поэтому ничего не теряется;
  • сообщение расписания (schedule) на красном снимается из входящих агента и
    возвращается на зелёном (sessionController.resolveAgent + agent.followup):
    памятка лежит в $DSH_HOME/dsh-tweaks/held.json, доставка повторяется до 8 раз
    и переживает рестарт DSH;
  • пустой ход (доставку изъяли, а ход всё равно открылся) на красном отклоняется:
    модельного вызова и трат нет. У сессии со спецсигналом такой ход не
    отклоняется;
  • служебные вызовы с purpose (заголовок чата, компакция) работой хода не
    считаются и проходят сразу;
  • пропуск даёт только переключатель «Спецсигнал»: он пускает сессию и всё её
    дерево субагентов и субсубагентов, действует через любое число красных окон,
    пока человек его не выключит. Набор берётся из
    $DSH_HOME/dsh-tweaks/special.json (запись атомарная: tmp + rename), затем из
    конфига, затем из seed — поэтому выключение тоже переживает рестарт: пустой
    список пишется как «выключено», а не как «файла нет». На старте файл
    авторитетнее конфига: если они разошлись, факт расхождения пишется в лог
    строкой state-conflict, а гейт идёт по файлу. В работе набор меняет
    переключатель — его запись ложится и в конфиг, и в леджер;
  • сообщения пропуск не дают — ни человеческий промпт, ни промпт
    continuable-субагента, ни стиринг родителя: harness-relay и
    deputy-wake-prompt.py шлют тот же clientTimeZone (константу
    Europe/Moscow), ту же owner-cookie и байт-в-байт такой же source,
    principal в этой установке не выставляется никому, а IP/UA в сессию не
    пишутся. Поэтому ночью человек встаёт вместе со всеми, а если работает —
    включает спецсигнал. Отдельно: gate2-verify различает человека сильнее —
    он смотрит access-лог nginx (браузерный POST с внешнего адреса и Mozilla),
    а relay и watchdog ходят на 127.0.0.1 мимо nginx. Следующий шаг усиления —
    principal для сервисных учёток хаба или транспортный хук
    connection/request; сейчас это не делается;
  • ночной сценарий МСК: 04:00 — пауза, 07:00 — работа продолжается сама, 09:00 —
    снова пауза, после 13:00 — дешёвое время. Окна, праздники КНР и жёлтое
    предупреждение берутся из политики выше;
  • статус виден в панели (ждёт зелёного до 13:00, спецсигнал: работа на красном (вдвое дороже) до 13:00, вне пика — до пн 04:00) и в подписи лампы;
    его считает браузер по политике и конфигу — своего RPC у твика нет;
  • диагностика: $DSH_HOME/dsh-tweaks/traffic-light.log. Прежние строки
    trafficLight: … (свет, удержание, доставка) не изменились; рядом появились
    структурированные события: pause | session=… | until=…,
    resume | session=… | after=green,
    signal | session=… | state=on|off | actor=ui-config|seed|config|file | rev=N,
    state-conflict | file=N | config=N | authority=file, save-error | reason=…,
    signal-less | reason=no-initiator. Journal для этого не нужен.

Масштаб

zoom ставится корню приложения (#root). Размеры корня не подменяются: движок сам
отдаёт содержимому логическую ширину «ширина / масштаб», и интерфейс заполняет окно.
transform: scale не подходит — с ним расходится попадание курсора в элементы.

Настройку «Font size» в Settings плагин не трогает: она меняет только текст переписки.

Попапы

Меню и подсказки приложение монтирует порталами в body, мимо корня. Общий zoom до них
не достаёт, поэтому каждый слой получает свой, а координаты плагин заворачивает в формулу:

/* приложение пишет --dsh-ui-zoom-src-left: 270px */
left: calc(var(--dsh-ui-zoom-src-left) / var(--dsh-ui-zoom));

Делит браузер, а не JS. --dsh-ui-zoom лежит на корне документа, поэтому смена масштаба
пересчитывает все попапы разом. JS-деление давало дрейф: на нецелом масштабе частное —
периодическая дробь, браузер округляет inline-длину, и меню уезжало в разные места экрана.

offsetWidth и offsetHeight попапов плагин отдаёт приложению в вьюпортных пикселях:
по ним оно выравнивает меню по кнопке и подгоняет его под экран. При смене масштаба
плагин шлёт resize — якорь переехал.

Меню по правой кнопке

Системное меню рисует Electron, и zoom до него не достаёт. Плагин перехватывает правый
клик и показывает своё: в поле ввода — Undo, Redo, Cut, Copy, Paste, Select All,
при выделении вне поля — только Copy. Вставка идёт через Clipboard API.

Своё меню — обычный слой в body, поэтому масштаб ему отдаёт твик zoom через мост
(пока твик выключен, мост молчит: масштабировать нечего). Фон и текст — токены темы.
Подписи берутся через translate(): штатный переводчик отдаёт сам ключ, если словарь
не успел подключиться, и в меню появлялось menu.copy.

Полоски изменения ширины

Приложение прибавляет к ширине панели сдвиг e.clientX - origin, а ширина — в логических
пикселях. Курсор визуальный, поэтому плагин отдаёт событиям на полоске логический
clientX: иначе на 150% панель проходит в полтора раза больше курсора.

Позицию полоска получает как left: viewport - rightbar. Под zoom эта арифметика
расходится с сеткой — при 125% полоска стояла на 1078 px, а граница панели на 1202 px.
Поэтому плагин ставит полоску по границе колонки: offsetLeft и offsetWidth.

Рамка интерфейса

AppFrame измеряет себя через getBoundingClientRect() и из этой ширины считает колонки.
Под zoom движок отдаёт визуальную ширину, поэтому плагин возвращает логическую. Ниже
1024 логических пикселей не опускает: по этому порогу приложение сворачивает сайдбар
(SIDEBAR_AUTO_COLLAPSE). Подмена живёт на уровне пакета и идемпотентна, поэтому
повторное включение твика не делит замер дважды.

Ограничения

  • Меню Application и Edit рисует Windows — плагин до них не достаёт.
  • Чем крупнее масштаб, тем раньше сворачивается сайдбар: zoom уменьшает логическую
    ширину, а порог у приложения — 1024 логических пикселя. При окне 1180 px панель
    сворачивается примерно со 120%.
  • Ширина правой панели хранится в пикселях, поэтому с ростом масштаба занимает большую
    долю окна. Меняется перетаскиванием полоски.
  • Вставка в своём меню зависит от доступа к буферу обмена.
  • Длинное меню ограничивается по высоте в vh, а vh зум не масштабирует.
  • На не-loopback Web служба конфигурации недоступна (status: 'unavailable'): там
    галочки заблокированы, а твики работают на дефолтах. В Desktop и на loopback всё в порядке.
  • @deepseek-ai/schemastery объявлен в peerDependencies: пакет берётся из установки
    DSH, отдельная установка не нужна. Правка index.js подхватывается после перезапуска
    приложения — HMR по умолчанию следит только за файлами профиля (root: []).
  • Мобильное меню держится за те же хрупкие привязки, что и свободные панели:
    суффиксы хешированных классов (_frame, _sidebarCol, _rowActions) и
    data-атрибуты (data-sidebar-collapsed, data-row-key, data-queue-dock). При
    крупной смене вёрстки DSH режим не включается (нет рамки или колонки) и интерфейс
    остаётся штатным; проверить это можно по атрибуту
    html[data-dsh-tweaks-mobile-drawer].
  • Подавление фокуса после тапа по чату — на время твика подменённый
    HTMLElement.prototype.focus: программный фокус поля ввода глотается, нативный
    тап по полю работает. Desktop-поведение не меняется.
  • Enter в редакторе очереди остаётся переносом строки только на touch-устройстве;
    на desktop Enter по-прежнему сохраняет сообщение.
  • Клавиатура при «+» и @ не скрывается (по просьбе): меню открываются поверх
    неё. Тап вне меню закрывает его, чтобы оно не залипало.
  • Подчёркивание последнего слова снимается через spellcheck=false и прозрачную
    рамку композиции; на части Android-клавиатур системное подчёркивание IME может
    остаться — это поведение клавиатуры, не приложения.
  • Реальную экранную клавиатуру iOS/Android DOM-тест не воспроизводит: после
    обновления страницы нужна проверка человеком на телефоне.
  • На планшете с открытой правой панелью раскрытый ящик заставляет приложение
    пересчитать трек панели по развёрнутому сайдбару; твик берёт трек из сетки
    приложения как есть и не восстанавливает прежнюю ширину. На телефоне правая
    панель в узкой раскладке места не получает, поэтому это не проявляется.
  • Чистка шапки — DOM-надстройка: второстепенные кнопки скрыты невидимыми
    анкорами, а в меню верхнего «…» добавляются пункты-прокси и «Copy session ID».
    Подписи прокси берутся из aria-label/title исходных кнопок; при смене вёрстки
    DSH прокси могут не появиться, а сами кнопки останутся скрытыми до правки
    селекторов. Меню видов (Browse other plugins / Create your plugin) вставляется
    после чтения скрытого меню, поэтому его подписи зависят от локали приложения.
  • Поиск в маленьких меню убирается эвристикой: поле поиска скрывается, если в
    меню не больше шести пунктов. Если в новой вёрстке поиск нужен маленькому меню,
    правило придётся сузить.
  • Фильтр «+» держит подписи пунктов en/zh (File/文件, Goal/目标,
    Plan/计划) — при смене набора это единственная точка правки. Чип режима
    подписывается по имени claim (plan → «Plan»).
  • «Copy session ID» пишет в буфер обмена через примитив оболочки с fallback на
    navigator.clipboard; без разрешения на буфер пункт остаётся, но копирование
    может не сработать.
  • Светофор на красном останавливает все ходы, включая ручные: сообщение
    человека, агента, сервиса, субагента и relay пропуска не дают — отличить
    человека от сервиса по сообщению нельзя (см. «Пауза на красном»). Ночью
    работают через спецсигнал.
  • Спецсигнал включается и выключается только кнопкой, разового пропуска нет.
    Кнопку технически может нажать любой клиент с owner-cookie: служба
    конфигурации не передаёт принципал (configForms), поэтому в лог пишется
    actor=ui-config, а не имя человека. Усиление — свой typert-неймспейс либо
    principal для сервисных учёток хаба; сейчас это не делается.
  • Дочерний чат показывает базовый статус: наследование спецсигнала от родителя
    клиенту не видно, поэтому в нём будет «ждёт зелёного», хотя работа идёт.
  • Родословная читается только у живых агентов: если промежуточная сессия
    выгружена, цепочка обрывается и потомок ждёт зелёного (fail-closed).
  • Спецсигнал не имеет срока: он действует через любое число красных окон, пока
    его не выключат, и всё это время работа идёт по двойной цене.
  • Расписания удерживаются и возвращаются на зелёном; остальные сообщения не
    изымаются — их ход просто ждёт.
  • Служебные вызовы с purpose (заголовок чата, компакция) на красном не ждут.
  • Леджер special.json может не записаться (save-error, повтор на каждом
    пересчёте): в памяти и в интерфейсе остаётся значение конфига, а после
    перезапуска авторитетным снова становится файл — расхождение при старте видно
    строкой state-conflict. Направление «файл ON, конфиг OFF» означает работу по
    двойной цене при статусе «ждёт зелёного».
  • Единственный обход гейта без кнопки — вызов, у которого не определяется сессия
    (id === ''): он проходит и пишет signal-less. Промпты человека и сервисов
    всегда несут сессию, так что путь остаётся страховкой от ложной блокировки.
  • Скриншоты светофора снимает руководитель на своём стенде: headless-браузера на
    хосте нет.

Проверка

node --check client.js
node --check index.js
node test\check-client.cjs
node test\check-whisper.cjs
node test\check-host.cjs
node test\check-traffic-light.cjs
node test\check-mobile-composer.cjs
node test\check-mobile-sidebar.cjs
node test\check-agent-guards.cjs

test/check-client.cjs гоняет настоящий client.js в песочнице с заглушками DOM,
React, ctx и configForms: 95 проверок; мобильные регионы — ещё 36 + 13 + 8 + 7 + 5 + 4 + 2 контрактов — флаги включают и выключают твики,
твик без клиентского кода (whisper) включается и выключается галочкой, повторное
включение не копит обработчики, дефолты без службы конфигурации, форма пишет
значения (операция set + ревизия), шаг и границы масштаба, хранилище, команды и их
привязки, плашка, Ctrl + колесо, попапы (перехват координат, calc(), сигнал
resize, отсутствие дрейфа), полоски, рамка, меню по правой кнопке, режим
выдвижного мобильного меню (узкая/широкая рамка, тап по чату, «три точки») и
спецсигнал светофора: различимые маркеры у лампы и в панели, подпись статуса в
aria-label лампы, блокировка кнопки без сессии и без права записи, повтор после
устаревшей ревизии, reduced-motion, дочерний чат с базовым статусом и паритет
ключей в обоих словарях.

test/check-host.cjs проверяет хост-половину без установки DSH: index.js грузится
с заглушкой @deepseek-ai/schemastery, флаг поднимает настоящий
tweaks/whisper-host.js, смена модели перезапускает его, выгрузка снимает, а
пропажа файла хост-части не роняет плагин. Там же — разовая настройка
распознавания: первое включение зовёт configure ровно один раз и сохраняет
признак в своё поле схемы, повторный запуск с готовым признаком выбор не трогает,
падение configure и отсутствие службы распознавания твик не роняют.
test/check-whisper.cjs — контракт самой хост-части.

test/check-traffic-light.cjs проверяет светофор v2 на моке контекста: политику
окон и её копию в client.js (дрейфа нет), гейт на красном (ждёт любой ход,
включая человеческий промпт и итоги субагентов), наследование спецсигнала по
дереву и пределы подъёма, удержание и возврат расписаний, пустой ход, purpose,
id === '' (signal-less), персистентность леджера (файл → конфиг → seed,
пустой список = выключено, state-conflict, save-error с повтором), строки
лога и seed session-e4698bf8-… в схеме. Отдельно — ассерты автономного стенда.

test/traffic-light-stand.html — стенд светофора v2: открывается локально
(file://), без сети и сборки, показывает все состояния сразу — зелёный, жёлтый,
красный с ожиданием, красный со спецсигналом, отказ записи, reduced-motion — и
таблицу «состояние → ожидание». Скриншоты по нему снимает руководитель;
машинные ассерты стенда живут в test/check-traffic-light.cjs.

test/zoom-stand.html прогоняется в headless Edge в реальном времени: --dump-dom
отдаёт страницу до конца её асинхронной работы, а --virtual-time-budget ломает
порядок ResizeObserver и даёт ложный сбой на перетаскивании полоски. Стенд прогоняет
связку «якорь — портал» на всех масштабах 0.5…2.0 и четырёх раскладках, отдельно
проверяет полоску панели, перетаскивание и меню под курсором.

Мобильный composer (mobileComposer)

Входит в существующий пакет dsh-tweaks (та же галочка Settings → Plugins).
Включён по умолчанию; desktop Enter/Shift+Enter не меняются. Мобильное устройство
определяется через (pointer: coarse) или userAgentData.mobile, а не ширину окна.
На таком устройстве и физическая клавиатура работает в безопасном мобильном режиме.

Слот conversation.input.overlay привязывает capture-обработчики только к своей
карточке [data-composer-card]. Публичные InputActions.captureInsertion/insertText
сохраняют выделение, ссылки, защиту ревизии, санитаризацию и undo. Enter и
beforeinput-only insertParagraph/insertLineBreak не попадают в upstream submit.
IME-подтверждение не превращается в перенос строки. Текстовый paste и
beforeinput-only insertFromPaste сохраняют весь текст, пустые строки и tabs;
CRLF/CR нормализуются в LF. Картинки и смешанный paste с файлами остаются штатными.
Никаких изменений минифицированного HARNESS, приватного Lexical API или отправки
сообщения из твика нет. При отключении/размонтаже обработчики снимаются.

Штатный режим и многоабзацная вставка

Используется штатный mode/claim API HARNESS 0.2.1-rc.5:
inputTriggers.sessionOf(actx).resolveClaim,
slash/input-begin-command, slash/input-consume-token, InputActions.
Выбор через «+» создаёт штатный claim, не вставляет буквальный /plan в тело.
Штатный atomic node скрыт только визуально внутри редактора; тот же режим показан

README 较长,此处只展示前 60 KB。完整内容请到仓库查看 ↗。

常见问题

5 问
答案由本站依据条目字段整理,不引用上游原文
volna-tweaks 怎么安装?

在 DSH 里执行 `dsh plugin --profile web add github:pridurok-goxa/volna-tweaks` 即可。

volna-tweaks 的验证等级是什么意思?

未标注验证等级。上游未给出验证结论,安装前请自行确认

volna-tweaks 安全吗?

未标注。

volna-tweaks 装之前要先确认什么?

先看它会读写哪些文件、执行哪些命令、连接哪些网络地址;验证等级只说明装得上、跑得起来,不等于安全。涉及密钥或系统权限的,建议先在隔离环境试装。

volna-tweaks 有哪些功能?

移动端输入与侧边栏优化、面板宽度自由拖拽缩放、聊天文件一键下载、带附件的队列编辑表单、高价时段红绿灯暂停。

UI 与外观
按星标排序,可作替代方案

nuwa-skill

nuwa-skill

女娲 DSH plugin 只需输入一个名字,就自动调研、提炼并验证任何人的心智模型、决策启发式与表达 DNA,生成可直接调用的思维视角 S

未标注验证等级 3.8 万 星

awesome-dsh-plugin

awesome-dsh-plugin

A curated list of plugins for DeepSeek Harness (dsh) · DeepSeek Harnes

L4 · 沙盒安装通过 1.8 万 星

deepseek-balance-whale-widget

DeepSeek-Balance-Whale-Widget

DSH 界面右下角的常驻小鲸鱼余额挂件,实时显示 DeepSeek 账户余额、今日已用与每轮对话消耗,支持拖拽吸附、Q 弹动画与音效,开箱即

L4 · 沙盒安装通过 4,492 星

dsh-better-sidebar

DSH-better-sidebar

面向 DeepSeek Harness 的服务化侧边栏工作台插件,把文件编辑、终端、Git 变更、子代理任务与侧边对话整合进右侧栏与底部面板

L4 · 沙盒安装通过 4,112 星

dsh-deep-whale

dsh-deep-whale

DSH Web 鲸鱼娘皮肤系列(深海女仆工坊 maid-atelier)。

L4 · 沙盒安装通过 2,470 星

deepseek-design

deepseek-design

可视化设计工作室,支持网站、App 原型、海报、信息卡、报告和杂志的模板创建、元素编辑、选区级 AI 草稿衔接与导出。

L4 · 沙盒安装通过 1,438 星

pridurok-goxa 的其它插件

1 个

插件的元信息来自作者仓库;分类、验证等级与安全结论的中文说明为中文整理,最近核验 —。