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

Создание нового проекта с dwe init

Вы хотите завести под DWE совершенно новый проект. workspace.yml ещё нет, а собирать конфигурацию файл за файлом вручную утомительно и легко ошибиться в мелочах. dwe init берёт начальную настройку на себя: одна команда создаёт минимальный, но полноценный проект, который при первом же запуске чисто загружается и проходит dwe validate.

Это зеркальное отражение Подключения к проекту DWE: то руководство — про репозиторий, в котором конфигурация DWE уже есть; это — про создание такой конфигурации с нуля.

dwe init — единственная команда DWE, которая работает вне проекта: она его создаёт, а не действует внутри. Она:

  • Каркас, который нужно настроить, а не готовый стек. Создаёт минимальную, но валидную структуру проекта — workspace.yml, workspace/defaults.yml, один включённый сервис app, базовый compose.yaml, AI-пак шаблонов, стартовый тест-сценарий и набор закомментированных файлов-переопределений. Реальную конфигурацию сервиса — образ или сборку, порты, хосты — вы дописываете сами. Файлы-переопределения поставляются полностью закомментированными, поэтому встроенные пайплайны deploy/lifecycle остаются активными, пока вы сознательно не возьмёте какой-то из них под контроль.
  • Безопасна для перезапуска. В каталоге без workspace.yml она заполняет пробелы и никогда не перезаписывает существующий файл без --force. Если проект там уже есть, она не затирает его молча: в интерактивном режиме спрашивает подтверждение пересоздания, а в неинтерактивном — останавливается, пока не передан --force.

В пустом каталоге просто выполните:

Окно терминала
dwe init

Короткая форма спросит:

  • Имя проекта (обязательно) — пишется в workspace.yml как project.name.
  • Префикс compose (по умолчанию dwe) — project.prefix, который разводит ваши Docker-ресурсы по пространствам имён.
  • Брендирование (необязательно) — заголовок, слоган (короткий подзаголовок под шапкой) и акцентный цвет (6-значный hex-код, например #2EC3EB), попадающие в workspace/styles.yml. Каждое поле проверяется по мере ввода. Оставьте поля пустыми, чтобы получить стандартную шапку; оформить проект можно и позже.

Вся форма собирается до записи на диск, так что Ctrl-C посреди формы оставит каталог нетронутым.

dwe init автоматически переходит в режим, управляемый флагами, когда stdin/stdout не TTY (CI, скрипты, пайпы), либо когда передан --default или --output json. Всё задаётся флагами:

Окно терминала
dwe init --name my-project --prefix acme --service api

Либо взять все значения по умолчанию без формы:

Окно терминала
dwe init my-project --default

Позиционный [name] создаёт проект в ./<name>/, а не в текущем каталоге. Имя выбирается в таком порядке приоритета: --name → позиционный [name] → имя текущего каталога.

ФлагПо умолчаниюЭффект
--nameаргумент [name], иначе имя каталогаимя проекта в workspace.yml
--prefixdweпрефикс compose/проекта
--brand-title / --tagline / --accentпустобрендирование workspace/styles.yml (accent — 6-значный hex, например #2EC3EB)
--serviceappимя папки стартового сервиса; "" — не создавать
-f, --forceвыклпересоздать существующий проект / перезаписать существующие файлы
-d, --defaultвыклпропустить форму, взять значения по умолчанию
--output jsonтекстмашиночитаемый отчёт (подразумевает неинтерактивный режим)

С --output json вместо прозы вы получаете структурированный отчёт:

{
"target": "/abs/path/to/project",
"created": ["workspace.yml", "workspace/defaults.yml", "..."],
"skipped": [],
"symlink_fallback": false,
"nested_warning": false
}

skipped перечисляет уже существовавшие файлы (оставленные как есть), symlink_fallback равен true, когда CLAUDE.md пришлось записать копией вместо символической ссылки, а nested_warning — true, когда выше по дереву найден workspace.yml.

<target>/
├─ workspace.yml project.name + project.prefix (+ закомментированные опциональные поля)
├─ compose.yaml базовый compose-файл, на который ссылается defaults.yml
├─ .gitignore записи DWE для runtime (дописываются, если файл уже есть)
├─ .editorconfig соглашения репозитория (пишется только при отсутствии)
├─ AGENTS.md краткий промпт о проекте для ИИ-агентов
├─ CLAUDE.md → симлинк на AGENTS.md (копия там, где симлинки недоступны)
├─ .dwe/
│ └─ config игнорируемый git, полностью закомментированный персональный шаблон пользовательской конфигурации
└─ workspace/
├─ defaults.yml переключатель стартового сервиса + закомментированные примеры runtime/exports
├─ styles.yml брендирование из формы + закомментированный остаток
├─ deploy.yml инертная копия встроенного пайплайна deploy
├─ lifecycle.yml инертная копия встроенного пайплайна lifecycle
├─ info.yml инертная копия конфигурации дашборда
├─ docker.yml инертная копия политики compose
├─ services/app/
│ ├─ service.yml активны type, container, исходный хаб, icon и info.title
│ └─ deploy.yml инертный скелет пайплайна сервиса (source → image → bootstrap → render)
├─ templates/ai/default/
│ ├─ manifest.yml АКТИВНЫЙ AI-пак шаблонов
│ └─ AGENTS.md.tmpl рендерится в хаб сервиса командой `dwe render ai`
└─ tests/
└─ smoke.yml АКТИВНЫЙ стартовый сценарий (описание, пока без проверок)

Стоит обратить внимание на четыре момента:

  • Файлы-переопределения специально поставляются закомментированными. Композиция пайплайнов DWE работает по принципу полной замены: активный workspace/deploy.yml заменяет весь встроенный пайплайн deploy, поэтому в недоредактированном файле незаметно потеряется часть фаз. Именно поэтому deploy.yml, lifecycle.yml и info.yml поставляются полностью закомментированными — как и пайплайн сервиса services/app/deploy.yml; встроенный дефолт остаётся активным, пока вы сознательно не раскомментируете файл и не возьмёте весь пайплайн под свой контроль. docker.yml закомментирован по той же причине, но переопределяется по ключам, а не целым файлом: раскомментировав один ключ, для остальных вы оставляете встроенные дефолты. В шапке каждого файла указано, какой авторитетный дефолт он повторяет.
  • Два файла поставляются активными, потому что закомментированными быть не могут. manifest.yml пака шаблонов декодируется строго и обязан объявить хотя бы одну запись; загрузчик тест-сценариев отвергает пустой документ. Поэтому workspace/tests/smoke.yml — настоящий сценарий с description: и steps: [], намеренно без проверок: в свежем каркасе compose.yaml не объявляет ни одного сервиса, поэтому деплой, который оборачивает сценарий, падает на start/up с «empty compose file», и dwe test run smoke сообщает об ошибке. Сценарий обретает смысл, когда ваш сервис появится в compose — тогда и добавьте шаги.
  • Файлов AGENTS.md два, и править вручную предназначен только один. Корневой AGENTS.md создаётся каркасом один раз и рассчитан на ручное редактирование. Тот, что рендерит AI-пак, попадает в хаб сервиса (services/app/, игнорируется git и отсутствует до первого клонирования) — правьте workspace/templates/ai/default/AGENTS.md.tmpl и перерендеривайте через dwe render ai.
  • .gitignore дополняется, а не перезаписывается. Если в каталоге уже есть .gitignore, dwe init дописывает только недостающие строки DWE под маркером # dwe. Повторный запуск ничего не меняет. Весь каталог .dwe/ игнорируется целиком — в нём лежат управляемые CLI runtime-данные и персональный конфиг .dwe/config, которым не место в системе контроля версий.
Окно терминала
dwe validate # убедиться, что свежий проект внутренне согласован

Свежий dwe init рассчитан на то, чтобы сразу же проходить валидацию. У сервиса app заполнены идентичность и исходный хаб, но запускать пока нечего: перед подъёмом стека настройте его — образ или сборку, порты, хосты — в workspace/services/app/service.yml и добавьте соответствующий сервис в compose.yaml:

Окно терминала
dwe deploy run # поднять настроенный стек

Две связки каркас описывает в комментариях, но проверить их за вас не может ни один валидатор:

  • Порт остаётся чисто отображаемым, пока не экспортирован. ports: в service.yml питает dwe status и info-блоки; сам по себе он ничего не привязывает. Раскомментируйте его вместе с парным правилом exports.env в workspace/defaults.yml — именно оно превращает порт в переменную окружения, на которую может ссылаться compose.yaml. PROJECT, UID и GID подставляются автоматически, переобъявлять их там нельзя.
  • Монтируйте весь хаб, а не только исходники. dir — каталог на хосте с чекаутом и всем, что лежит рядом (артефакты сборки, кэши, состояние инструментов); dir_internal — куда этот каталог целиком попадает в контейнере, а work_dir_internal — где внутри него выполняются команды.

Дальше идёт обычная работа над конфигурацией: добавить сервис, написать команды проекта, оформить дашборд и раскомментировать файл-переопределение, когда действительно нужно перекроить пайплайн. Для обзорного прохода по свежему проекту — сервисы, команды, билтины пайплайна, диагностические флаги — запустите dwe docs llms-txt --lang en.

  • Проект уже существует. Если в целевом каталоге уже есть workspace.yml, dwe init не станет молча его перезаписывать. В интерактивном режиме команда спросит подтверждение пересоздания (и пересоздаёт всё с --force при согласии); в неинтерактивном — остановится с ошибкой, предлагая передать --force.
  • Существующие .gitignore / .editorconfig. .gitignore дополняется; .editorconfig пишется только при отсутствии. Ни один не затирается.
  • Вложенные проекты. Если в каталоге выше уже есть workspace.yml, dwe init предупреждает (nested_warning в JSON), но не блокирует — иногда вложенный проект и нужен.
  • Без стартового сервиса. --service "" создаёт валидный проект без сервисов. Всё, что ссылается на стартовый сервис, удаляется вместе с ним — его папка, AI-пак шаблонов и стартовый сценарий, — так что висящих ссылок не остаётся. Сервисы добавляются позже папками под workspace/services/.
  • Симлинки в Windows. Там, где CLAUDE.md нельзя сделать символической ссылкой на AGENTS.md, он записывается копией, и запуск отмечает этот fallback.