Общий конфиг IDE и AI-агентов
Сделайте так, чтобы у каждого разработчика в команде были одинаковые настройки VS Code, одинаковые AGENTS.md / CLAUDE.md и одинаковые git-хуки — и при этом никто не правил бы эти файлы вручную. Три подкоманды рендеринга DWE (dwe render ide, dwe render ai, dwe render git) делают всё это из template-паков, закоммиченных в репозиторий.
Это руководство проведёт вас от нуля до работающего общего конфига с возможностью индивидуальных настроек для каждого разработчика. Полная схема и краевые случаи — в справочнике render.
Разделы
Заголовок раздела «Разделы»- Раскладка template-пака
- Файл
manifest.yml - Разрешение пака: какой пак использует сервис?
- Политики коллизий (deepest vs shallowest)
- Dry run — рендерим всё
- Личные оверрайды через
<pack>.local/ - Что трекается, а что в gitignore
Раскладка template-пака
Заголовок раздела «Раскладка template-пака»Все три рендерера читают паки из 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
Заголовок раздела «Файл manifest.yml»В корне каждого пака должен лежать 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:, молча игнорируется — чтобы его включить, добавьте его в манифест.
Разрешение пака: какой пак использует сервис?
Заголовок раздела «Разрешение пака: какой пак использует сервис?»Сервис может явно зафиксировать пак:
render: ide: template: corporate-vscode # использовать workspace/templates/ide/corporate-vscode/Если render.<kind>.template задан, такой пак обязан существовать — опечатка приводит к жёсткой ошибке, а не к молчаливому откату на default/. Это защищает вас от того, что templete: corporete-vscode случайно отрендерит всё, что окажется в default/.
Когда render.<kind>.template не задан, резолвер обходит неявную цепочку — побеждает первое совпадение:
workspace/templates/<kind>/<имя-сервиса>/- каждый предок в цепочке
extends:сервиса, по очереди workspace/templates/<kind>/default/
Это согласуется с тем, как работает extends: у сервисов: потомок вроде main-debug extends: main обычно наследует IDE-пак родителя, а не проваливается сразу в default/.
Политики коллизий (deepest vs shallowest)
Заголовок раздела «Политики коллизий (deepest vs shallowest)»Когда два сервиса используют один и тот же dir: (классический случай — потомок extends: родителя, и оба указывают на services/main), для каждого вида рендеринга побеждает только один из них — но какой именно, зависит от вида:
| Вид | Политика коллизий | Почему |
|---|---|---|
ide | побеждает самый глубокий | IDE-конфиги задают поведение конкретного варианта (другой отладчик, другой launch-профиль). Отрендеренными файлами владеет наиболее специализированный вариант. |
git | побеждает самый глубокий | То же обоснование — хуки тоже обычно различаются от варианта к варианту. |
ai | побеждает самый верхний (предок в цепочке extends) | AGENTS.md описывает каноническую идентичность hub. Варианты её разделяют, а описанием владеет родитель. |
Ничья на одной глубине разрешается лексикографически по имени сервиса. Проигравшие сервисы выдают предупреждение с именем победителя и спорным каталогом — это подсказка, что два сервиса случайно столкнулись.
dwe render ide main (с явным аргументом) тоже соблюдает политику коллизий: если main-debug — самый глубокий вариант, использующий services/main, рендерится именно он, а info-строка сообщает о подмене.
Dry run — рендерим всё
Заголовок раздела «Dry run — рендерим всё»После правки manifest.yml или любого .tmpl запустите рендереры вручную, чтобы посмотреть на результат:
dwe render ide # рендерим IDE-файлы для каждого подходящего сервисаdwe render ai # рендерим AGENTS.md (и симлинки)dwe render git # пишем исполняемые git-хуки (mode 0755)Каждая подкоманда принимает необязательный аргумент [сервис], чтобы сузить область:
dwe render ide apidwe render ai apidwe render git apiЕсли хотите посмотреть, что получится, без записи — сначала укажите один сервис, изучите результат, и только потом коммитьте. Отдельного флага --dry-run нет: команды перезаписывают обычные файлы по месту назначения без запроса, но отказываются перезаписывать симлинк (вы получите понятную ошибку и проблемный путь).
В повседневной работе deploy-пайплайны прогоняют это автоматически — вызывать вручную обычно нужно только когда вы пишете или отлаживаете пак.
Личные оверрайды через <pack>.local/
Заголовок раздела «Личные оверрайды через <pack>.local/»Хотите личные настройки редактора, не коммитя их в командный пак? Положите рядом теневой пак:
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.yml | workspace/local.yml |
workspace/docker.yml | workspace/docker.local.yml |
workspace/templates/<kind>/<pack>/ | workspace/templates/<kind>/<pack>.local/ |
Оговорка для оверрайдов IDE/AI
Заголовок раздела «Оговорка для оверрайдов IDE/AI»Для git отрендеренный результат попадает в .git/hooks/, который никогда не трекается — оверрайды полностью приватны и не создают трения.
Для ide и ai отрендеренный результат — это обычно трекаемый файл (.vscode/settings.json, AGENTS.md). Личный оверрайд, дающий другой файл, означает, что повторный dwe render ide создаст у вас diff в трекаемом файле. Не коммитьте такие diff-ы — git stash, git checkout -- <path> или личный pre-commit-хук одинаково хорошо позволяют держать их локально.
Что трекается, а что в gitignore
Заголовок раздела «Что трекается, а что в gitignore»| Путь | Трекается? | Заметка |
|---|---|---|
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