scaffold-project — bootstrap нового проекта
Когда пользователь говорит «новый проект» — этот скилл разворачивает
полный скелет за один диалог. После scaffold все задачи в проекте идут
через dev-workflow.
Шаг 0 — определить режим
Скилл различает три режима по триггер-фразе пользователя:
| Триггер | Режим |
|---|---|
| «новый проект», «init project», «scaffold проект», «развернуть проект», и т.п. | fresh / extension (Шаги 1–5 ниже) |
«причеши проект», «оформи как dev-проект», «back-fill бэклог», «добавь дев-обвязку», /scaffold-project --backfill | back-fill (секция «Back-fill mode» — пропускаем Шаги 1–5, идём туда) |
Если триггер двусмысленный (например, просто /scaffold-project в каталоге с CLAUDE.md) — спросить пользователя один раз: «у проекта уже есть CLAUDE.md. Это fresh-init где-то ещё, или back-fill сюда?».
Шаг 1 — pre-checks (fresh / extension режим)
Перед стартом скилл проверяет целевой каталог:
| Состояние | Действие |
|---|---|
| Каталог не существует / пустой | Продолжаем (mkdir создаст). |
Не пуст, нет CLAUDE.md/package.json/pyproject.toml | Продолжаем, но предупреждаем «каталог не пуст, продолжить?». |
Есть package.json или pyproject.toml без CLAUDE.md | Предлагаем extension mode: добавить недостающие base-файлы, не трогая существующее. |
Есть CLAUDE.md | Отказ + подсказка: «проект уже инициализирован. Если хочешь добавить недостающую дев-обвязку — скажи back-fill или причеши проект (см. секцию Back-fill mode)». |
Шаг 2 — диалог
Скилл задаёт пять вопросов. Не больше, не меньше.
- Имя проекта (kebab-case). Валидация:
^[a-z][a-z0-9-]{1,40}$. Не проходит — спрашиваем заново. - Однострочное описание — 1 предложение, чем проект полезен.
Если пользователь хочет дать развёрнутый scope — приветствуется,
уйдёт в
{{SCOPE_DESCRIPTION}}as-is. - Стек:
node-cli— Node 20+ CLI или библиотека, тесты черезnode --test.python-mcp— Python MCP-сервер или скрипт, тесты черезpytest.both— оба extension'а.none— только base, никакого языкового скелета.
- Внешние сервисы, которые предполагаются сразу (Notion / Gmail /
Stripe / Sentry / другое). Список справочный — попадёт в
.env.exampleи в комментарий к BL-001. Если ничего —none. - Работа с user data? —
yes/no. Это любые пользовательские данные: профили, контент пользователя, сообщения, email/telegram-чаты, транзакции. Еслиyes— обязательно подключаем extensionmulti-user-base(см. секцию «Identity & PII rules»). Это не «потом докрутим» — потом стоит недели работы.
Шаг 3 — preview + approve
Перед записью — плоский список файлов, которые скилл создаст:
<project-root>/
├── CLAUDE.md
├── README.md
├── DEVELOPMENT.md
├── CHANGELOG.md
├── incidents.md
├── .gitignore
├── .env.example
├── rfc/_README.md
├── docs/decisions/_README.md
├── private/backlog.base # Obsidian Bases view
├── private/backlog/_README.md # конвенции: frontmatter, статусы, теги версий
├── private/backlog/BL-1.md # первый таск (scaffold), in_progress
├── package.json (если node-cli)
├── engine/index.js (если node-cli)
├── engine/index.test.js (если node-cli)
├── pyproject.toml (если python-mcp)
├── server.py (если python-mcp)
└── tests/test_smoke.py (если python-mcp)
Жду явного «ok» от пользователя.
Шаг 4 — запись
По approve:
- Pre-flight check. До любых mkdir / write:
git --versionотвечает (git установлен).git config --get user.nameиgit config --get user.emailоба возвращают значение. Если что-то из этого не выполнено — отказ с понятным сообщением («настройgit config --global user.email …и попробуй заново»). Никаких файлов не создаём, пока pre-flight красный — иначе получим скаффолд без коммита и тупик в следующем запуске («есть CLAUDE.md, отказ»).
mkdir -p <project-root>если не существует. Запомним флагcreated_root = (true | false)— пригодится для отката.- Для каждого файла из
templates/base/(и выбранныхtemplates/extensions/<name>/):- читаем шаблон,
- подменяем плейсхолдеры (см. ниже),
- пишем в
<project-root>/<relative-path>без.tplв имени. - исключение: файл
README.mdв корне каждогоtemplates/extensions/<name>/— это документация самого extension'а (для скилла, не для проекта). Не копируется в проект. - запоминаем список записанных файлов (
created_files[]) — для отката.
- Sanity-check:
grep -l '{{' <created_files[]>(только по только-что-записанным файлам, не по всему каталогу — иначе ловим ложные срабатывания на_README.md-примерах). Если что-то осталось — error и откат:- fresh-mode (
created_root = true):rm -rfвсего каталога. - extension-mode (
created_root = false): удаляем толькоcreated_files[], не трогая ничего другого. Никогда не удаляем целиком чужой каталог.
- fresh-mode (
cd <project-root>→git init→git add .→git commit -m "scaffold from scaffold-project v{{SCAFFOLD_VERSION}}".- Спросить про push в origin (по правилу из workspace-CLAUDE.md
«после каждого коммита спрашивать про push»). Если remote ещё нет —
предложить
gh repo create(с подтверждением).
Плейсхолдеры
| Плейсхолдер | Источник |
|---|---|
{{PROJECT_NAME}} | ответ пользователя |
{{PROJECT_NAME_UPPER}} | UPPER_SNAKE_CASE из имени (- → _) |
{{SHORT_DESCRIPTION}} | ответ на вопрос 2, первое предложение |
{{SCOPE_DESCRIPTION}} | ответ на вопрос 2 целиком (или то же, что short) |
{{STACK}} | human-readable mapping: node-cli → Node.js 20+ (CLI / library), python-mcp → Python 3.11+ (MCP server), both → Node.js 20+ + Python 3.11+, none → TBD — choose during BL-001 |
{{DATE}} | сегодняшняя дата YYYY-MM-DD |
{{AUTHOR}} | git config user.name, или unknown |
{{SCAFFOLD_VERSION}} | версия скилла из его CHANGELOG.md |
{{EXTERNAL_SERVICES}} | ответ на вопрос 4, или none |
{{today}} | сегодняшняя дата YYYY-MM-DD (alias к {{DATE}} для frontmatter) |
{{project_name}} | то же что {{PROJECT_NAME}} (alias для frontmatter-шаблонов) |
Подмена — простой текстовый replaceAll по содержимому файла.
Шаг 5 — после scaffold
После первого коммита Claude:
- Резюмирует что создано (файлы, какие extensions подключены).
- Указывает на
private/backlog/BL-1.mdкак первую задачу (in_progress, scaffold). Открытьprivate/backlog.baseв Obsidian — увидишь backlog как таблицу с view'ми Active / Archived / Cards. - Напоминает: «дальше работаем через
dev-workflow. Все M/L задачи — через RFC, тесты, code-review».
Back-fill mode — добавить дев-обвязку в существующий проект
Режим для проектов, у которых уже есть CLAUDE.md и свой контент, но
нет (или есть не вся) дев-обвязка: private/backlog/, backlog.base,
rfc/, incidents.md, CHANGELOG.md. Скилл добавляет недостающее
из тех же templates/base/, чтобы формат был один к одному с тем,
что получают свежие проекты.
Зачем: раньше Claude в таких проектах делал обвязку руками, сочинял собственные поля в frontmatter, нарушал конвенции и потом приходилось переделывать. Back-fill mode закрывает эту дыру — формат всегда из templates, ничего не сочиняется.
Когда триггерится
- Триггер-фраза: «причеши проект», «оформи как dev-проект»,
«back-fill бэклог», «добавь дев-обвязку»,
/scaffold-project --backfill. - Каталог:
CLAUDE.mdуже существует (иначе это fresh-init, не back-fill).
Что back-fill делает (scope)
| Файл шаблона | Действие |
|---|---|
templates/base/CHANGELOG.md.tpl | добавить если нет |
templates/base/incidents.md.tpl | добавить если нет |
templates/base/rfc/_README.md | добавить если rfc/_README.md нет |
| `templates/base/docs/decisi |