Перейти к содержимому

Общий конфиг IDE и AI-агентов

Сделайте так, чтобы у каждого разработчика в команде были одинаковые настройки VS Code, одинаковые AGENTS.md / CLAUDE.md и одинаковые git-хуки — и при этом никто не правил бы эти файлы вручную. Три подкоманды рендеринга DWE (dwe render ide, dwe render ai, dwe render git) делают всё это из template-паков, закоммиченных в репозиторий.

Это руководство проведёт вас от нуля до работающего общего конфига с возможностью индивидуальных настроек для каждого разработчика. Полная схема и краевые случаи — в справочнике render.

Все три рендерера читают паки из workspace/templates/<kind>/<pack>/, где <kind> — это ide, ai или git:

workspace/templates/
ide/
default/ # неявный fallback-пак
manifest.yml
.vscode/settings.json.tmpl
.devcontainer/devcontainer.json.tmpl
main-debug/ # пак с именем сервиса (или пин через render.ide.template)
manifest.yml
.vscode/launch.json.tmpl
.vscode/settings.json.tmpl
ai/
default/
manifest.yml
AGENTS.md.tmpl
git/
default/
manifest.yml
pre-commit.tmpl

Каждый пак — это каталог; рендерер никогда не идёт по симлинкам на паки. Template-файлы оканчиваются на .tmpl и используют синтаксис Go text/template.

Результат попадает в hub-каталог каждого включённого сервиса:

ВидКуда пишется результат
ide<svc.Dir>/<rel> — например, services/main/.vscode/settings.json
ai<svc.Dir>/<rel> — например, services/main/AGENTS.md
git<svc.Dir>/src/.git/hooks/<basename> — chmod 0755 на каждом прогоне

По умолчанию рендерятся только сервисы type: app (для всех трёх видов). Сервисы других типов подключаются явно через services.<name>.render.<kind>.enabled: true.

В корне каждого пака должен лежать manifest.yml. Это единственный источник правды о том, что рендерится — рендерер никогда не обходит пак самостоятельно.

render:
- from: .vscode/settings.json.tmpl
to: .vscode/settings.json
- from: .devcontainer/devcontainer.json.tmpl
to: .devcontainer/devcontainer.json
symlinks: # только ide / ai — git отвергает симлинки
- link: CLAUDE.md
to: AGENTS.md

Ограничения по видам:

ВидФорма toБлок symlinks
ideлюбой путь внутри hubразрешён
aiлюбой путь внутри hubразрешён; каждый to должен ссылаться на запись render
gitтолько basename (без слешей)запрещён

Неизвестные ключи в manifest.yml приводят к жёсткой ошибке (строгий YAML-декод). Файл внутри пака, не указанный в render:, молча игнорируется — чтобы его включить, добавьте его в манифест.

Разрешение пака: какой пак использует сервис?

Заголовок раздела «Разрешение пака: какой пак использует сервис?»

Сервис может явно зафиксировать пак:

workspace/services/api/service.yml
render:
ide:
template: corporate-vscode # использовать workspace/templates/ide/corporate-vscode/

Если render.<kind>.template задан, такой пак обязан существовать — опечатка приводит к жёсткой ошибке, а не к молчаливому откату на default/. Это защищает вас от того, что templete: corporete-vscode случайно отрендерит всё, что окажется в default/.

Когда render.<kind>.template не задан, резолвер обходит неявную цепочку — побеждает первое совпадение:

  1. workspace/templates/<kind>/<имя-сервиса>/
  2. каждый предок в цепочке extends: сервиса, по очереди
  3. workspace/templates/<kind>/default/

Это согласуется с тем, как работает extends: у сервисов: потомок вроде main-debug extends: main обычно наследует IDE-пак родителя, а не проваливается сразу в default/.

Когда два сервиса используют один и тот же dir: (классический случай — потомок extends: родителя, и оба указывают на services/main), для каждого вида рендеринга побеждает только один из них — но какой именно, зависит от вида:

ВидПолитика коллизийПочему
ideпобеждает самый глубокийIDE-конфиги задают поведение конкретного варианта (другой отладчик, другой launch-профиль). Отрендеренными файлами владеет наиболее специализированный вариант.
gitпобеждает самый глубокийТо же обоснование — хуки тоже обычно различаются от варианта к варианту.
aiпобеждает самый верхний (предок в цепочке extends)AGENTS.md описывает каноническую идентичность hub. Варианты её разделяют, а описанием владеет родитель.

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

dwe render ide main (с явным аргументом) тоже соблюдает политику коллизий: если main-debug — самый глубокий вариант, использующий services/main, рендерится именно он, а info-строка сообщает о подмене.

После правки manifest.yml или любого .tmpl запустите рендереры вручную, чтобы посмотреть на результат:

Окно терминала
dwe render ide # рендерим IDE-файлы для каждого подходящего сервиса
dwe render ai # рендерим AGENTS.md (и симлинки)
dwe render git # пишем исполняемые git-хуки (mode 0755)

Каждая подкоманда принимает необязательный аргумент [сервис], чтобы сузить область:

Окно терминала
dwe render ide api
dwe render ai api
dwe render git api

Если хотите посмотреть, что получится, без записи — сначала укажите один сервис, изучите результат, и только потом коммитьте. Отдельного флага --dry-run нет: команды перезаписывают обычные файлы по месту назначения без запроса, но отказываются перезаписывать симлинк (вы получите понятную ошибку и проблемный путь).

В повседневной работе deploy-пайплайны прогоняют это автоматически — вызывать вручную обычно нужно только когда вы пишете или отлаживаете пак.

Хотите личные настройки редактора, не коммитя их в командный пак? Положите рядом теневой пак:

workspace/templates/ide/
default/ # tracked, командный
manifest.yml
.vscode/settings.json.tmpl
default.local/ # gitignored, личный
.vscode/settings.json.tmpl # подменяет тот, что выше

Когда рендерер читает default/.vscode/settings.json.tmpl, он сначала проверяет default.local/.vscode/settings.json.tmpl. Если ваш локальный файл существует — источником берётся именно он, и рендерер печатает:

using local override: workspace/templates/ide/default.local/.vscode/settings.json.tmpl

Ключевые правила:

  • Теневой пак — это подмена входа, а не перенаправление выхода. Отрендеренный файл всё равно попадает в то же место (services/main/.vscode/settings.json).
  • Теневой пак должен содержать только те файлы, которые вы переопределяете. Собственный manifest.yml ему не нужен — что именно рендерится, по-прежнему определяет манифест канонического пака.
  • Добавьте workspace/templates/*/*.local/ (или более широкое правило *.local/) в .gitignore.

Это согласуется с общей конвенцией DWE про локальные оверрайды:

Канонический (tracked)Локальный сиблинг (gitignored)
workspace/workspace.ymlworkspace/local.yml
workspace/docker.ymlworkspace/docker.local.yml
workspace/templates/<kind>/<pack>/workspace/templates/<kind>/<pack>.local/

Для git отрендеренный результат попадает в .git/hooks/, который никогда не трекается — оверрайды полностью приватны и не создают трения.

Для ide и ai отрендеренный результат — это обычно трекаемый файл (.vscode/settings.json, AGENTS.md). Личный оверрайд, дающий другой файл, означает, что повторный dwe render ide создаст у вас diff в трекаемом файле. Не коммитьте такие diff-ы — git stash, git checkout -- <path> или личный pre-commit-хук одинаково хорошо позволяют держать их локально.

ПутьТрекается?Заметка
workspace/templates/<kind>/<pack>/даКомандный пак — источник правды.
workspace/templates/<kind>/<pack>.local/нетЛичные оверрайды. Игнорируйте паттерн .local/.
services/<name>/.vscode/settings.json (и подобные IDE-файлы)обычно даОтрендеренный результат; коммитьте, чтобы у коллег сразу был тот же конфиг редактора без вызова dwe render ide.
services/<name>/AGENTS.md, services/<name>/CLAUDE.mdобычно даОтрендеренный результат; то же обоснование.
services/<name>/src/.git/hooks/<name>никогдаЛежит внутри .git/, который git игнорирует сам.

Типичный проект коммитит отрендеренные файлы IDE и AI, чтобы свежий клон сразу имел рабочие конфиги, и затем перезапускает dwe render ide / dwe render ai при каждом изменении пака или service.yml. Git-хуки — исключение: они лежат внутри .git/ и должны рендериться заново после каждого клона.

  • индекс справочника render — полная схема, защита путей, краевые случаи
  • render ide — детали IDE и шаблонные переменные
  • render ai — рендеринг AGENTS.md и семантика симлинков
  • render git — рендеринг git-хуков и оговорки про worktree
  • add-a-service — добавление сервиса, участвующего в рендеринге IDE/AI/git