dsh-edt-projects (dsh-edt-projects)
pravets/dsh-edt-projects/packages/dsh-edt-projects
面向 1C 开发的 MCP 枢纽:通过 EDT-MCP 保持 1C:EDT 连接,按需以工作区根目录启动 BSL Language Server,并提供逐项目设置、只读文档 wiki、模型规则以及 SonarQube/GitLab 技能。需安装 1C:EDT 2026.1/2026.2 并运行 EDT-MCP(默认 127.0.0.1:8765)。
安装
dsh plugin --profile web add github:pravets/dsh-edt-projects该插件位于仓库的 packages/dsh-edt-projects 子路径下。
README
dsh-edt-projects
Плагин DeepSeek Harness для разработки на 1С. Держит подключённым 1C:EDT через EDT-MCP, поднимает по требованию BSL Language Server, при необходимости подключает MCP-сервер трекера и добавляет в системный промпт правила, по которым агент работает с конфигурацией 1С, а не с файлами наугад.
Плагин включается только в выбранных проектах (см. «Где включается»). В
остальных сессиях в контексте остаётся один маленький инструмент edt_config:
ни правил 1С, ни MCP-инструментов, ни навыков там нет.
Что вы получаете
mcp__edt__*— инструменты EDT во включённых проектах. Метаданные и объекты, формы, СКД, запросы, сборка внешних обработок, YAxUnit — около ста инструментов сервераedt-mcp-server. Монтируются при создании сессии, а не в чужие проекты.mcp__bsl__*— BSL Language Server по требованию. Диагностика конкретного файла, переходы, иерархия вызовов, типы платформы. Монтируется черезedt_pin, чтобы его схемы не занимали контекст постоянно.mcp__tasks__*— любой MCP-сервер трекера (YouTrack, Jira, GitLab, GitHub) тем же способом.- Настройки на проект. Второй проект — другой
.dsh-1c.json, без перезапуска DSH: порт EDT, корень исходников для BSL, вики, флаги тестов и навыков. - Вики проекта только для чтения. Пути попадают в промпт, запись по ним отклоняется на уровне инструментов.
- Правила для модели. «Исходники 1С правим только инструментами EDT», точечная диагностика через BSL, изменения состояния проекта — только по явной просьбе.
- Навыки SonarQube и GitLab и правила тестируемости (YAxUnit, Vanessa) — включаются флагами в конфиге включённого проекта.
Требования
- DSH 0.2.x и профиль (
desktopилиweb). - EDT 2026.1 / 2026.2 с установленным EDT-MCP: Help → Install New Software →
https://ditrixnew.github.io/EDT-MCP/→ EDT MCP Server Feature → перезапуск. - MCP-сервер запущен: Window → Preferences → MCP Server → Server Port и
автостарт. Порт по умолчанию —
8765, плагин по умолчанию ходит туда же. - Plain text mode включён (там же, Plain text mode (Cursor compatibility)).
Без него EDT отдаёт результат как embedded resource, а клиент показывает вместо
него
[embedded resource unsupported]— и инструменты становятся бесполезны.
Установка
plugin_manager { action: "install_bundle", target: "dsh-edt-projects" }
Пакет публичный, поэтому этого достаточно: менеджер плагинов возьмёт его из npm и включит. После установки перезапуск DSH не нужен; инструменты 1С появятся в новой сессии, каталог которой выбран (см. «Где включается»).
Другие способы — для разработки и закрытых сетей:
| Способ | Что передать |
|---|---|
| локальные исходники | install_bundle с путём C:\git\dsh-edt-plugin\packages\dsh-edt-projects (создаёт link:, правки видны после пересборки профиля) |
| релизный tarball | URL https://github.com/pravets/dsh-edt-projects/releases/download/v0.10.0/dsh-edt-projects-0.10.0.tgz |
| Web UI | Plugins → Add plugin → тот же путь или URL |
Где включается
Плагин не активен глобально: при создании сессии он смотрит на исходный каталог сессии и решает так:
| Условие | Итог |
|---|---|
enabled: true в настройках проекта или пользователя | включён |
enabled: false там же | выключен, даже если есть файл проекта и путь в списке |
в каталоге сессии есть разбираемый .dsh-1c.json | включён |
каталог (или его предок) есть в projects файла $DSH_HOME/dsh-1c.json | включён |
| ничего из перечисленного | выключен |
Сравнение путей идёт по границе каталога (C:\git\trade2 не считается проектом
C:\git\trade), ~ раскрывается, на Windows регистр не важен. Битый JSON не
включает проект: ошибка пишется в лог, а edt_config остаётся доступным.
Worktree — отдельный каталог: его нужно либо добавить в projects, либо завести
ему собственный .dsh-1c.json (например, если файл лежит в репозитории).
В выключенном проекте от плагина остаётся только edt_config — у него же
action=init создаёт .dsh-1c.json и тем самым включает проект на лету. В
включённом — правила 1С, mcp__edt__*, edt_servers/edt_pin/edt_unpin/
edt_reload, вики, навыки и правила тестируемости.
Быстрый старт
- Установить плагин (команда выше) и начать новую сессию в каталоге проекта.
- Включить проект: в нём вызвать
edt_config action=init(создаст.dsh-1c.json) или добавить путь вprojectsпользовательского файла. - Проверить связку: вызвать
mcp__edt__get_edt_versionиmcp__edt__list_projects. Если инструментов нет — раздел «Диагностика». - Если порт EDT не 8765, или нужна вики, или флаги тестов — дополнить
.dsh-1c.json(см. ниже).
Настройки
Два файла, одинаковый формат, читаются на каждый edt_pin, edt_reload, каждый
шаг и каждый рендер промпта:
| Слой | Файл |
|---|---|
| пользователь | $DSH_HOME/dsh-1c.json |
| проект | <каталог, где создана сессия>/.dsh-1c.json |
Приоритет: проект > пользователь > встроенные значения cordis.patch.yml.
Проект определяется исходным каталогом сессии: cd внутри сессии не
переключает конфиг, корень BSL и пути вики.
{
"enabled": true,
"projects": ["C:\\git\\trade"],
"wiki": { "paths": ["C:\\git\\dev-llm-wiki"], "entry": "wiki/index.md" },
"servers": {
"edt": { "url": "http://127.0.0.1:8765/mcp" },
"bsl": { "root": "C:\\git\\trade\\src\\cf" },
"tasks": { "url": "https://tracker.example/mcp" }
},
"tests": { "yaxunit": { "enabled": true, "project": "cfe_yaxunit" } },
"sonar": { "enabled": true },
"gitlab": { "enabled": false }
}
| Ключ | Смысл | По умолчанию |
|---|---|---|
enabled | явно включить/выключить плагин для проекта | не задан: решают файл проекта и projects |
projects | каталоги, где плагин включён (обычно в пользовательском файле) | пусто |
servers.edt.url | адрес MCP-сервера EDT | http://127.0.0.1:8765/mcp |
servers.edt.toolCallTimeoutMs | таймаут вызова: update_database, run_yaxunit_tests идут дольше 60 с | 900000 |
servers.bsl.jar / url / version | готовый jar, зеркало или закреплённый тег релиза | не заданы |
servers.bsl.root | корень исходников для BSL LS | каталог запуска DSH |
servers.bsl.mode | hybrid (LSP+MCP) или stdio | hybrid |
servers.tasks.url | MCP-сервер трекера | не задан |
wiki.paths / wiki.entry | корни вики и входная страница | пусто |
tests.yaxunit / tests.vanessa | правила тестируемости | выключены |
sonar.enabled / sonar.projectKey | навык SonarQube | выключен |
gitlab.enabled | навык GitLab | выключен |
servers.*.shared больше не работает: сервер всегда монтируется в скоупе
сессии. Полный список ключей, включая servers.bsl.java, cwd, port и
servers.*.headers, — в схеме edt_config action=validate и в
packages/dsh-edt-projects/cordis.patch.yml.
Создать файл и дополнить новыми ключами:
node tools/config-init.mjs # .dsh-1c.json проекта
node tools/config-init.mjs --user # $DSH_HOME/dsh-1c.json
node tools/config-init.mjs --dry-run # показать, что добавится
Из сессии то же делает инструмент edt_config: show (действующие значения,
источники и включён ли проект), init, upgrade (дописывает только
отсутствующие ключи, по умолчанию dryRun: true), validate. Существующие
значения не меняются никогда, битый JSON не перезаписывается; enabled в
дефолты не входит, чтобы upgrade не выключил уже включённый проект.
Что применяется на лету:
| Изменение | Как применить |
|---|---|
wiki.paths, servers.bsl.root | сразу: читаются на каждый запрос и edt_pin |
servers.<name>.url, headers | edt_reload("edt") — сервер переподключится |
enabled, projects | сразу: на следующем шаге сессии |
cordis.patch.yml, переменные окружения | только перезапуск DSH |
Переменные окружения — для разовых запусков и CI:
| Переменная | Что задаёт |
|---|---|
EDT_MCP_URL, EDT_MCP_TOKEN | адрес и токен MCP-сервера EDT |
TASKS_MCP_URL, TASKS_MCP_TOKEN | адрес и токен трекера |
DSH_1C_WIKI, DSH_1C_WIKI_ENTRY | корни вики через ; и входная страница |
DSH_1C_BSL_LS_JAR, DSH_1C_BSL_LS_URL | готовый jar или зеркало |
DSH_1C_BSL_LS_VERSION | закреплённый тег, например v1.0.7 |
DSH_1C_BSL_LS_GITHUB_TOKEN | токен GitHub для API (иначе GITHUB_TOKEN, GH_TOKEN) |
DSH_1C_BSL_LS_CACHE, DSH_1C_BSL_LS_DOWNLOAD | каталог кэша и запрет скачивания |
DSH_1C_BSL_LS_ROOT, DSH_1C_BSL_LS_CWD | корень рабочего пространства и рабочий каталог LS |
Серверы по требованию
Собственные инструменты плагина названы с префиксом edt_, чтобы не пересекаться
с чужими MCP-плагинами и с серверными mcp__edt__*:
| Инструмент | Что делает |
|---|---|
edt_config | настройки плагина: включение проекта, вики, тесты, серверы, навыки; show/init/upgrade/validate |
edt_servers | состояние серверов: mounted, lazy, unavailable, failed, транспорт, число инструментов |
edt_pin | монтирует сервер; его инструменты появляются в следующем же запросе модели |
edt_unpin | снимает сервер и освобождает контекст |
edt_reload | перечитывает настройки и перезапускает серверы с изменившимся конфигом |
edt_config доступен всегда — им включают проект. Остальные четыре видны только
во включённом проекте.
EDT монтируется при создании сессии включённого проекта (lazy: false), BSL LS
и трекер — по требованию. Каждая сессия (и субагент) получает свой MCP-клиент:
для EDT это отдельное HTTP-подключение, отдельный workspace в EDT не создаётся.
Ошибка подключения не валит старт: сервер остаётся в состоянии failed, клиент
продолжает реконнект в фоне. Для bsl корень можно передать прямо при
монтировании: edt_pin("bsl", root: "C:\\git\\trade\\src\\cf").
BSL Language Server
Если servers.bsl.jar не задан, плагин скачивает сервер сам при первом
edt_pin("bsl"): из кэша → со страниц релизов GitHub → через API (если задан
токен) → по предсказуемому адресу → из любого другого jar в кэше. Файл пишется как
.part и переименовывается только после сверки sha256; несовпадение хеша
обрывает загрузку, а не повторяется без проверки.
- Без токена загрузка идёт со страниц релизов и не упирается в лимит GitHub API
(60 запросов в час на IP). С
DSH_1C_BSL_LS_GITHUB_TOKEN— 5000/ч, API первым. - Если лимит всё же исчерпан, ошибка называет время сброса и выходы: задать токен,
закрепить
DSH_1C_BSL_LS_VERSION, указатьURLили готовыйJAR. - Кэш (
$DSH_HOME/cache/bsl-language-server) переиспользуется: следующиеpinне ходят в сеть.
Гибридный режим. BSL LS узнаёт о рабочих пространствах только через MCP roots,
а dsh-mcp-client этот capability не объявляет. Поэтому плагин запускает
java -jar … lsp --mcp --server.port=<порт> и сам отправляет LSP-initialize с
workspaceFolders, а клиент подключает к http://127.0.0.1:<порт>/mcp. Один процесс
обслуживает и LSP, и MCP. Границы конфигурации задаёт DSH_1C_BSL_LS_ROOT; если
корень не тот, межфайловые операции работают хуже, чем могли бы.
Вики проекта
При заданном wiki в промпт добавляется блок с путями и входной точкой, а запись
по этим путям запрещена на уровне инструментов: edit, write,
str_replace_editor и apply_patch отклоняются с сообщением «Вики доступна только
для чтения». Чтение (read, grep, glob) работает как обычно — это документация,
а не конфигурация, правило «правки только через EDT» к ней не относится.
Входная точка ищется по порядку: entry из настроек → wiki/index.md →
index.md → README.md → AGENTS.md. Несуществующие каталоги отбрасываются с
предупреждением в лог.
Тесты и навыки
Флаги включают в промпт правила тестируемости:
{ "tests": { "yaxunit": { "enabled": true, "project": "cfe_yaxunit" }, "vanessa": { "enabled": true } } }
yaxunit— закладывать тестируемость: логика отдельными процедурами без побочных эффектов, зависимости параметрами, тонкие обработчики, изоляция через Мокито; тесты писать в указанный проект.vanessa— если юнитов мало (интеграция, обмен, интерфейс, печатные формы), предлагать 2–3 сценария с шагами и ожидаемым результатом, не создавая их молча.
Навыки появляются в каталоге только во включённом проекте и при включённом флаге; они приходят из пакета, так что проектный навык с тем же именем их переопределяет:
{ "sonar": { "enabled": true }, "gitlab": { "enabled": true } }
Адреса и ключи в текстах навыков не зашиты: сервер Sonar, ключ проекта, GitLab-хост
и glab-авторизация определяются в момент работы. Мерж, force-push и пуш в основную
ветку запрещены текстом навыка.
Правила для модели
Во включённом проекте плагин добавляет в системный промпт одну секцию: искать
структуру и метаданные через edt__*, а не файловым поиском; править исходники
1С только инструментами EDT (write_module_source, create_metadata,
modify_metadata, dcs, apply_quick_fix), иначе модель EDT разъезжается с
диском; точечную диагностику брать у bsl__analyze_file, а не у
get_project_errors; типы платформы сверять по bsl__type_info; менять состояние
проекта (update_database, удаление, переименование) только по явной просьбе.
Если нужного инструмента в EDT нет, модель должна остановиться и назвать операцию,
а не обходить ограничение файловыми правками. Секция собирается под фактически
настроенные серверы: пока bsl не смонтирован, про его инструменты в промпте нет ни
строки. В выключенном проекте секция пустая и в промпт не попадает.
Диагностика
| Симптом | Что делать |
|---|---|
нет mcp__edt__* | edt_config action=show → включён ли проект; затем edt_servers → состояние edt, порт и запущенный сервер в EDT |
edt_pin("bsl") падает «не удалось получить релиз» | задать DSH_1C_BSL_LS_JAR, URL или VERSION; при лимите — DSH_1C_BSL_LS_GITHUB_TOKEN |
[embedded resource unsupported] | включить Plain text mode в настройках MCP-сервера EDT |
| BSL не видит файлы конфигурации | задать DSH_1C_BSL_LS_ROOT (корень исходников) |
| правки не видны в EDT | править через edt__*; после ручной правки — revalidate_objects или resync_to_disk |
| плагин не появился в списке | plugin_manager list_bundles; проверить, что версия DSH ≥ 0.2.0 |
| проект в worktree не включён | worktree — отдельный каталог: добавить его в projects или завести свой .dsh-1c.json |
| после переименования каталога плагина ошибки про старый путь | переустановить плагин: remove_bundle, затем install_bundle |
Живая проверка без DSH: npm run check:edt — печатает версию сервера, число
инструментов и делает два безопасных вызова.
Разработка
packages/dsh-edt-projects/ бандл: манифест, cordis.patch.yml, lib/, skills/, locale/, иконка
tools/ проверки, тесты, smoke, заглушка MCP
.github/workflows/ CI, Release по тегу, Smoke по расписанию
npm ci # зависимости проверок
npm run validate # манифест, патч, локали, иконка, готовность к публикации, порт
npm test # 112 проверок: правила, BSL, конфиг, включение, вики, тесты, схема, навыки, cwd
npm run pack:check # состав tarball
npm run check:edt # живой MCP-сервер EDT
npm run smoke # прогон бандла в одноразовом профиле DSH
Smoke ставит бандл из dist/*.tgz в одноразовый DSH_HOME, проверяет композицию
профиля и поднимает заглушку MCP на порту из патча. Затем дважды стартует headless
сессию: из каталога без .dsh-1c.json (заглушка не должна получить initialize) и
из каталога с .dsh-1c.json (должна). Нужен установленный DSH
(npm i --no-save @deepseek-ai/dsh@0.2.1-rc.5 или DSH_BIN); если порт занят живым
EDT — задайте SMOKE_PORT.
Релиз: поднять version в packages/dsh-edt-projects/package.json, добавить
запись в CHANGELOG.md, поставить тег vX.Y.Z и запушить. release.yml сверит тег
с версией, соберёт tarball, приложит его к GitHub Release и опубликует версию в npm
через trusted publisher (OIDC, без токенов и секретов).
Версионирование
Проект в статусе беты и версионируется как 0.x (текущая — v0.10.0). Между 0.x
без миграции могут меняться ключи конфига, имена инструментов и структура
cordis.patch.yml; edt_config upgrade дополняет файл, но совместимость не
гарантирует. Версия 1.0.0 будет означать зафиксированный API. История — в
CHANGELOG.md.
Лицензия
MIT — см. LICENSE.