Skip to content

dsh-better-sandbox-ui

Verified

@rkfg/dsh-better-sandbox-ui · v0.4.1 · MIT · Web UI

Settings page for the DeepSeek Harness better-sandbox plugin; edits apply without a restart.

Install

dsh plugin add @rkfg/dsh-better-sandbox-ui

Confirm the layer applied with dsh --profile default --dump-config — see the install guide.

Source

Published to npm without a public repository. Inspect the package contents before installing.

Tags

Readme

@rkfg/dsh-better-sandbox-ui

Раздел Sandbox в диалоге настроек: четыре поля со списками (гранты на запись, закрытые от чтения каталоги и файлы, запрещённые к изменению имена путей) и одно поле с именем уровня эскалации, чтение и правка через штатный слой настроек харнесса. Правка применяется без перемонтирования записей и без рестарта, значение сохраняется в cordis.patch.yml профиля. Русская копия этого файла; первичен README.md.

Состав

Файл Роль
index.js единственная хостовая запись пакета (пустой сервис)
client.js клиентская половина: слот settings.section, форма, запись через ctx.remote.settings
cordis.patch.yml слой бандла: одна запись

Пакет с dsh.client обязан иметь ровно одну запись загрузчика, поэтому UI живёт отдельным пакетом, а не внутри @rkfg/dsh-better-sandbox.

Установка

Ставится вместе с хостовым пакетом: ./scripts/install.sh (или штатно — dsh plugin --profile web add <package>). Нужен рестарт профиля, чтобы загрузчик увидел новую запись; правка клиентского кода вступает в силу перезагрузкой страницы.

Почему не собственный Remote API

Собственное ctx.remote-пространство имён клиенту недоступно: согласно cookbook/adding-a-remote-api.md клиент обязан объявить в inject сервис remote.<namespace>, а это пространство генерируется из артефактов ./typert и ./remote, которых у рукописного JS-пакета нет. Поэтому форма читает ctx.remote.settings.describe() (без аргументов) и пишет ctx.remote.settings.update('better-sandbox', patch, revision) — тот же путь, что у встроенного диалога настроек. Сервис sandboxGuard на хосте при этом остаётся доступен инструментам и тестам.

Проверка значений

Форма проверяет каждое поле до сохранения и не даёт писать, пока в поле есть проблемы, перечисляя их красным под этим полем. У трёх видов полей разные правила: поля путей требуют абсолютный путь или ~/… (форма ~user отвергается), поле имён путей ожидает один компонент вроде .git — имя с разделителем там ошибка, а сам .git корректен. Поле уровня эскалации — не список: оно сохраняется одной строкой, обязано быть одним строчным словом и не позаимствовать имя режима у штатной лестницы (read-only, workspace-write, danger-full-access); пустое значение выключает уровень. Дубликаты внутри одного списка отвергаются в обоих списочных видах. Существование пути намеренно не проверяется: браузер не достает до сервиса плагина, поэтому правило на ещё не созданный каталог принимается и бездействует, пока каталог не появится. test/settings-ui-probe.mjs прогоняет это в настоящем браузере: открывает раздел, пишет непригодные правила и непригодное имя уровня, нажимает Save и проверяет, что все подписи появились, а запись была заблокирована.

Параллельные правки

describe() отдаёт значения вместе с ревизией документа, а update() приносит эту ревизию обратно: запись, построенная на устаревшем снимке, отвергается с SETTINGS_CONFLICT вместо молчаливой перезамены чужой правки (patch профиля правят сразу несколько вкладок, менеджер плагинов, CLI и текстовый редактор). При таком отказе форма сохраняет набранное, обновляет ревизию и просит сохранить заново.

На практике конфликт редок: слой настроек сам уведомляет открытые формы об изменении документа (settings/document-updated), и открытый раздел перечитывает снимок самостоятельно — это наблюдалось в прогоне с двумя вкладками, где сохранение из второй вкладки сдвинуло ревизию под первой вкладкой до того, как та нажала Save. Ветка конфликта — страховка на узкую гонку между этим перечитыванием и нажатием. Сама защита по ревизии покрыта test/revision-probe.js (DSH_PROBE=revision).

Model Experience

Влияние на контекст модели

Косвенно, через @rkfg/dsh-better-sandbox: списки, сохранённые здесь, определяют, какие строки анонса правил попадают в контекст рантайма и какие пути дают отказ чтения.

Token effect

Zero-direct: сам раздел ничего не добавляет в контекст модели.

KV Cache effect

Independent: изменения конфига сбрасывают переиспользование префикса только через смену секции анонса в @rkfg/dsh-better-sandbox, к этому пакету это не относится.

Known Limitations and Deferred Work

  • Слой настроек проверяет пути, а не значения — settings.update объединяет патч и отвергает только поля, не объявленные volatile; правило, которое хост отверг бы (одиночный /, ~/…, выходящий за пределы домашней папки), сохранить можно. Форма отклоняет те формы, которые видит браузер, а хост отвергает разрешение пути и сообщает причину в логе и в sandboxGuard.state().
  • Документ настроек — это и есть cordis.patch.yml профиля — сохранение со страницы переписывает строку этой записи в нём, а volatile-списки применяются без рестарта. Строка ищется по разрешённому имени записи: если модуль объявлен относительным путём (./better-sandbox/rules.js, так его объявляют контуры), строка не совпадает, добавляется вторая, и слой сообщает о перекрытии и отклоняет запись. В профиле с плагином из пакета — то есть в обычном случае — всё сохраняется.
  • Нет проверки существования пути — страница не может обратиться к сервису плагина (клиентское пространство имён появляется только из сгенерированных артефактов ./typert и ./remote, которых у рукописного пакета нет), поэтому проверяется только синтаксис — правило на всю файловую систему отклоняется здесь же; правило на отсутствующий каталог сохраняется, а хост помечает его как missing в sandboxGuard.state() и пишет в лог вместе со всеми отвергнутыми правилами.
  • Только volatile-поля — denyDepth, denyScanTtlMs, denySkipDirs, maskFallback, readDenialSignature на странице не показываются: их читают конструкторы провайдеров, поэтому они требуют рестарта.
  • Нет предпросмотра применения — форма не показывает, какие из уже существующих правил изменили состояние (стали читаемыми, стали защищёнными) после сохранения.
  • Подписи только в en и zh — словарь раздела зарегистрирован для этих двух языков; русские подписи появятся вместе с русской локализацией харнесса.