nemezida1337/dsh-locale-russian ↗★ 0
dsh-locale-russian
Russian (ru) language pack for the DeepSeek Harness web client 适合需要使用俄语界面进行交互的DSH用户。
Install
npx -p @deepseek-ai/dsh dsh plugin --profile web add github:nemezida1337/dsh-locale-russianREADME
Read the full README ↗dsh-locale-russian
Русская локализация web-интерфейса DeepSeek Harness.
Индекс маркета: https://nemezida1337.github.io/dsh-locale-russian/index.json — добавьте его на странице Плагины → Обзор, чтобы установить пакет оттуда.
Пакет — обычный клиентский плагин DSH: он добавляет язык ru в расширяемый каталог локалей и регистрирует переводы для всех namespace интерфейса. Недостающие ключи автоматически показываются по-английски, поэтому неполный перевод не ломает интерфейс. Одновременно это bundle, поэтому ставится одной командой и умеет обновляться как обычный пакет.
- Охват: 3058 строк в 65 namespace — все строки интерфейса, которые показывает приложение: панели, настройки, диалоги, карточки инструментов, подсказки, тексты ошибок UI, единицы измерения и форматы дат. Строки сняты и с CLI-сборки, и с установленного приложения (
app.asar); пропущенных ключей нет (см.reports/coverage.json). - Терминология: единый глоссарий (GLOSSARY.md) и правила стиля (STYLE.md).
- Склонения: русские формы множественного числа выбираются по
Intl.PluralRules('ru'), а не по английскому правилу «1 или много». - Описания плагинов: подписи карточек в разделе «Встроенные плагины» тоже переводятся — 421 строка из манифестов и
locale/*.jsonпакетов, таблицаdictionary/plugin-meta.json, подстановка черезLocaleRuntime.resolveText.
Установка
Пакет не требует форка DeepSeek Harness и не меняет его файлы.
Обычная установка
dsh plugin --profile web add dsh-locale-russian
Команда ставит пакет из npm в указанный профиль через pnpm, добавляет его в dependencies и в dsh.profile.bundles, после чего строка locale-ru появляется в собранном дереве. Так же устанавливается из git, tarball или локального пути:
dsh plugin --profile web add github:nemezida1337/dsh-locale-russian
dsh plugin --profile web add file:/абсолютный/путь/к/рабочей/копии
Приложение DeepSeek Harness (desktop)
Профиль desktop принадлежит Electron-приложению, и CLI отказывается им управлять. Поэтому пакет подключают либо строкой патча на локальную копию, либо установкой в профиль вручную.
Строка патча — удобно, когда нужна живая рабочая копия:
-
Возьмите копию репозитория в постоянное место, например
~/Developer/dsh-locale-russian. -
Добавьте строку в
~/.dsh/profiles/desktop/cordis.patch.yml, сохранив остальные записи:- insert: - id: locale-ru name: file:///абсолютный/путь/к/dsh-locale-russian/lib/index.js -
Перезапустите приложение.
Обычная установка из npm — то же, что делает dsh plugin, но вручную: добавьте "dsh-locale-russian": "^0.1.2" в ~/.dsh/profiles/desktop/package.json и в его dsh.profile.bundles, затем выполните pnpm add dsh-locale-russian в каталоге профиля (pnpm лежит внутри приложения: …/DeepSeek Harness.app/Contents/Resources/runtime/primary-runtime/dependencies/pnpm/bin/pnpm.mjs).
В обоих случаях дальше откройте Настройки → Общие → Язык и выберите Русский; выбор сохраняется в ~/.dsh/settings.yaml. Если система и браузер приложения настроены на русский, интерфейс переключится сам при первом запуске после установки.
Удаление
Удалите добавленную строку из cordis.patch.yml (и запись зависимости из package.json профиля при установке через dsh plugin) и перезапустите приложение. Настройка языка очистится сама при следующем изменении языка.
Как это работает
-
Плагин объявляет язык:
ctx.locale.addLanguage({ id: 'ru', label: 'Русский', fallback: 'en' }). -
Для каждого namespace регистрируется словарь:
ctx.locale.register(namespace, 'ru', {...}). Ключи совпадают с оригинальными, значения — русские. -
Русские склонения: словарь может хранить до трёх форм, разделённых
|, а пакет подменяетLocaleRuntime.prototype.translate, выбирая форму по числу из параметров вызова. Для не-ruлокалей вызывается исходный метод без изменений, поэтому английский и китайский интерфейсы работают ровно как раньше. -
Метаданные плагинов: описания и названия пакетов приходят от хоста как
LocalizedTextи рисуются черезLocaleRuntime.resolveText. Пакет подменяет и этот метод, подставляя русский текст из таблицыdictionary/plugin-meta.json; если пакет отдаёт свой русский вариант, он выигрывает.
Подробнее о формате форм — в STYLE.md.
Разработка
node tools/extract-static.mjs # словари из установленной сборки DSH
node tools/extract-repo.mjs # словари из исходников репозитория
node tools/build-inventory.mjs # объединённый инвентарь строк
node tools/build-batches.mjs # батчи для перевода
node tools/lint-translations.mjs # проверка переводов (глоссарий, плейсхолдеры, склонения)
node tools/build-package.mjs # сборка dictionary/ru.json и lib/
node tools/verify-package.mjs # проверка собранного бандла без браузера
node tools/report-drift.mjs # ключи, у которых английский текст изменился между сборками
node tools/apply-reviews.mjs # перенос правок рецензентов в dictionary/overrides.json
node tools/extract-asar.mjs # клиентские пакеты из app.asar установленного приложения
node tools/extract-plugin-meta.mjs # описания пакетов-плагинов для раздела «Встроенные плагины»
node tools/build-plugin-batches.mjs # батчи этих описаний
node tools/build-market.mjs # индекс маркета плагинов (market/index.json)
node tools/validate-market.mjs # проверка индекса официальным валидатором DSH
node tools/mark-translated.mjs # запомнить английский текст, по которому сделан перевод
node tools/refresh.mjs # вся цепочка обновления одной командой
node tools/gui-sweep.mjs # обход интерфейса: текст, скриншоты, обрезки
node tools/screenshot-gui.mjs # снимок одного экрана (для отладки)
Если вы делаете свой плагин для DSH — практическое руководство со всеми граблями лежит в contrib/plugin-recipe.md.
Общие помощники лежат в tools/lib: cdp.mjs — запуск headless Chrome и операции над страницей, parse-js.mjs — чтение словарей из бандлов и исходников, paths.mjs — сокращение машинных путей в отчётах.
Порядок извлечения строк:
node tools/extract-asar.mjs --out .app-packages # пакеты приложения из app.asar
DSH_CLIENT_PKG_ROOT="$PWD/.app-packages" node tools/extract-static.mjs --out strings/app.json
node tools/extract-static.mjs # пакеты CLI-сборки
node tools/extract-repo.mjs # исходники репозитория
node tools/build-inventory.mjs # объединить: приложение → CLI → репозиторий
node tools/build-batches.mjs --delta # только новое и изменившееся
Готовые переводы лежат в translations/*.json по батчам; dictionary/ru.json — результат сборки. Отчёты проверок — в reports/.
Строки берутся из трёх источников по убыванию приоритета: клиентские пакеты установленного приложения (распакованные из app.asar), пакеты CLI-сборки и исходники репозитория. Приоритетный источник задаёт английский текст, который видит переводчик; батч p3 (дельта приложения) перекрывает ранее переведённые ключи, у которых текст изменился.
После выхода новой версии DSH
- Обновите приложение и склонируйте свежий репозиторий (
git pull). - Запустите
npm run refresh— одна команда проходит всю цепочку: распаковываетapp.asar, снимает словари приложения, CLI-сборки и репозитория, пересобирает метаданные плагинов, инвентарь, батчи дельты и отчёт о расхождениях. В конце печатается сводка: сколько строк без перевода, сколько переписано, сколько описаний плагинов не хватает. - Переведите файлы
batches/p3-*.json(строки интерфейса) иbatches/plugin-*.json(описания плагинов). - Отметьте раунд как завершённый:
npm run mark-translated— команда запоминает, по какому английскому тексту сделан перевод, чтобы дельта не возвращалась. npm test(линтер, сборка, индекс маркета, проверка бандла); при необходимости расширьтеengines.dshв манифесте.
Проверить дельту без правок можно командой npm run refresh:check: она вернёт ненулевой код, если остались непереведённые или переписанные строки.
Правки редакторов и рецензентов хранятся отдельно от батчей — в dictionary/overrides.json (строки интерфейса) и dictionary/plugin-meta-overrides.json (метаданные плагинов); они применяются поверх переводов при сборке и участвуют в проверках, поэтому не теряются при повторном извлечении строк.
Непрерывная интеграция
.github/workflows/ci.yml содержит три job-а (два из них выполняются на Ubuntu и Windows, то есть пять прогонов), а pages.yml и release.yml публикуют индекс маркета и выпускают версии:
| Job | Когда | Что делает |
|---|---|---|
checks | push, pull request | линтер, сборка пакета, индекс маркета, проверка бандла |
dsh-drift | ежедневно по расписанию и вручную | ставит свежий @deepseek-ai/dsh из npm (Ubuntu и Windows), снимает с него строки и падает, если появились непереведённые или переписанные; при находке открывает issue в этом репозитории |
smoke | push, pull request | поднимает настоящий сервер dsh web с пакетом через строку патча (Ubuntu и Windows), проверяет boot-граф и прогоняет обход интерфейса |
dsh-drift — это и есть сигнал «вышел новый DSH, нужна дельта»: в отчёте job-а видно, сколько строк добавилось и какие именно. После публикации репозитория на GitHub эти проверки включаются сами, без настройки секретов.
Выпуск версии
npm version patch # или minor / major — поднимает версию в package.json
git push --follow-tags # тег vX.Y.Z запускает workflow release
.github/workflows/release.yml берёт версию из тега, собирает пакет, прогоняет проверки, публикует в npm с аттестацией происхождения (--provenance) и создаёт GitHub-релиз. Если версия уже есть в реестре, публикация пропускается.
Секреты не нужны: публикация идёт через trusted publishing (OIDC). На npmjs.com в настройках пакета → Publishing access → Trusted publishing добавьте издателя:
| Поле | Значение |
|---|---|
| Owner | nemezida1337 |
| Repository | dsh-locale-russian |
| Workflow | release.yml |
| Environment | пусто |
После этого выпуск — это npm version patch && git push --follow-tags. Токены не нужны, и npm не требует подтверждения отпечатком: он доверяет репозиторию. Это важно, потому что npm сворачивает granular-токены с обходом 2FA для прямой публикации (анонс).
Ручной выпуск тоже работает — npm publish --access public из локального терминала (там подтверждение отпечатком проходит через браузер).
Обход интерфейса
npm run sweep -- --url "http://127.0.0.1:5610/?token=…" # пройти по экранам
npm run sweep:check -- --url "…" # сравнить с эталоном и упасть при обрезке
Обход открывает главный экран, все разделы настроек, новый диалог и меню ввода / и @, сохраняет текст и скриншот каждого экрана в reports/sweep/, и сообщает об элементах, чей текст обрезан контейнером. Это тот класс дефектов, который иначе находится случайно: например, подпись «Встроенные плагины» не помещалась в боковой панели и превращалась в «Встроенные п…».
Сводка обхода (reports/sweep/summary.json) служит эталоном: --compare показывает, где обрезки стало больше, --fail-on-clip падает при обрезке нашей копии. Строки данных хоста (описания навыков из SKILL.md, имена пакетов, моделей и команд) в провал не идут: они не переводятся — так же ведёт себя и китайская локаль, — и обход помечает их отдельно.
В CI этот шаг входит в job smoke, который выполняется на Ubuntu и Windows: шрифтовые метрики различаются, и Linux уже находил обрезки, которых нет на macOS. Снимки экранов уходят артефактом.
Публикация
Пакет одновременно является bundle (dsh.bundle.patch — файл cordis.patch.yml со строкой locale-ru) и клиентским плагином (dsh.client), поэтому ставится целиком, одной командой. Обычный выпуск описан выше, в разделе «Выпуск версии»; вручную то же самое выглядит так:
npm login # один раз, если публикуете не из CI
npm test # линтер, сборка, индекс, проверка бандла
npm publish --access public
Имя пакета
Имя dsh-locale-ru в npm уже занято другим автором: там лежит пакет dsh-locale-ru@0.1.1 — тоже русская локализация DSH, но меньшего охвата (31 namespace / 1048 строк, без русских склонений, целевая версия DSH 0.1.1-rc.2). Наш пакет называется dsh-locale-russian и покрывает 65 namespace / 3058 строк, включая сборку 0.2.1-rc.2, и умеет склонения.
Смена имени — одна правка в package.json:
# 1. выберите свободное имя, например @ваш-скоуп/dsh-locale-ru
node -e "const f='package.json',p=require('./'+f);p.name='@ваш-скоуп/dsh-locale-ru';require('fs').writeFileSync(f,JSON.stringify(p,null,2)+'\n')"
# 2. пересоберите: id бандла и строка патча подставятся автоматически
node tools/build-package.mjs && node tools/build-market.mjs
Сборка генерирует cordis.patch.yml и id бандла из имени манифеста, поэтому рассинхронизации не будет: имя пакета, id модуля и строка патча всегда совпадают. При смене имени не забудьте поправить repository, homepage и bugs — сейчас там адрес этого репозитория.
GitHub без npm
dsh plugin --profile web add github:nemezida1337/dsh-locale-russian
Подходит и tarball, и локальный путь (file:/абсолютный/путь).
Индекс маркета
node tools/build-market.mjs собирает каталог market/: index.json (формат 1) и icon.svg. Индекс уже опубликован workflow-ом pages.yml:
https://nemezida1337.github.io/dsh-locale-russian/index.json
Пользователи добавляют этот адрес на странице Плагины → Обзор (в английском интерфейсе — Discover), после чего карточка появляется в списке и ставится оттуда. Свой индекс — та же команда сборки и любой статический https-хостинг.
Индекс отдаёт название, описание, иконку, автора, версии и требуемый диапазон DSH, поэтому список рисуется без обращения к npm. Установка из «Обзора» идёт через plugin_manager с подтверждением и требует, чтобы в профиле был включён bundle рынка @deepseek-ai/dsh-experimental-plugin-market-bundle (в поставке он выключен).
Диапазон совместимости
engines.dsh в манифесте (^0.1.5-rc.1 || ^0.2.1-rc.2) перечисляет сборки, на которых пакет проверен. Диапазон выглядит необычно, потому что semver не считает pre-release версию подходящей произвольному диапазону: >=0.1.5-rc.1 <0.3.0 не совпал бы с 0.2.1-rc.2. Если DSH обновится, DSH может отклонить пакет по этому полю — тогда расширьте диапазон и выпустите новую версию.
Совместимость
- Проверено на DeepSeek Harness
0.1.5-rc.x(CLI-сборка, клиентские пакеты0.1.5-rc.2) и на приложении0.2.1-rc.2(клиентские пакеты распакованы изapp.asar; покрытие — 2901 строка, пропусков нет). - Пакет использует публичный контракт локали (
addLanguage,register,getSnapshot) и два приватных метода рантайма:translateдля склонений иresolveTextдля метаданных плагинов. Оба вызова защищены проверкой типа: если метод исчезнет, пакет продолжит работать — склонения перестанут выбираться, описания плагинов останутся английскими, строки интерфейса не пострадают. Обсуждения в upstream об этом — хук склонений и локализация оболочки; тексты лежат в contrib/upstream-issues.md, витрина плагина — discussions/10146.