* feat(spec): add project-template skill init and check flow * refactor(spec): remove repo-init migrate references to project-template * test(spec): structural tests for project-template skill and command * fix(test): wrap long lines and use non_templated var in project template tests * fix(ci): reformat test_project_template_skill.py for ruff format --------- Co-authored-by: opencode-agent <agent@opencode.local>
17 KiB
| name | description |
|---|---|
| project-template | Init new project from cookiecutter template by type + GitHub remote + branch protection, or audit existing project via project-status. Replaces repo-init. Also when user says "новый проект", "инициализируй репо", "проверь проект", "create project", "project template". |
Project Template
Два flow: init (новый проект: cookiecutter по типу + GitHub remote) и check (существующий проект: project-status аудит с рекомендациями).
Замена монолитному repo-init: Phase A (GitHub remote + branch protection)
мигрирована без изменений, Phase B (ручное scaffolding) заменена на cookiecutter
шаблоны из .opencode/templates/<type>/ (issue #229 / PR #235). Проверка
архитектуры — через project-status tool (issue #228 / PR #233).
ПРОТОКОЛ (ЖЁСТКО)
- Определи flow (вопрос юзеру, см. ниже).
- init flow → шаги 1-6 (см. ниже).
- check flow → шаги 1-3 (см. ниже).
- После каждого шага → 1 строка прогресса юзеру (формат:
✅ <step> — <done>).
ЗАПРЕЩЕНО
- Запускать cookiecutter / git / gh напрямую из main agent — делегируй subagent
(Template INIT, Template GITHUB). Main agent = оркестратор: вопросы юзеру +
project-statustool (read-only oracle) + делегирование. gh repo createБЕЗ предварительного git init + initial commit (bare-repo → empty push → main branch не появляется → branch protection падает).- Импровизировать тип проекта вне
VALID_TYPESизspec-status.py(см. ниже). - Запускать
/run-pipelineавтоматически — стоп после init/check, дальше юзер сам.
Остановы
- Subagent error → 1 retry, потом STOP + report пользователю.
- cookiecutter не установлен → WARN + инструкция, STOP init flow.
- Template для типа не найден → WARN, STOP init flow (предложи check flow или тип из доступных).
project-statustool вернул⚠️ ...failed→ WARN, сообщи пользователю, продолжай без отчёта (не блокирующий).
Определение flow
Вопрос юзеру (один вопрос, multiple choice):
Это новый проект или проверка существующего?
[1] init — новый проект: cookiecutter по типу + GitHub remote + branch protection
[2] check — аудит существующего: project-status (структура, роуты, качество, README, infra)
Если юзер выбрал init, но cwd уже git-репо с коммитами и файлами → предложи check flow (см. Граничные случаи). Если cwd пустой или юзер подтвердил init → init flow.
init flow
Шаг 1: Вопрос — тип проекта
Выбери тип проекта (из spec-status VALID_TYPES):
[1] backend — FastAPI + Tortoise, REST API (cookiecutter template)
[2] fullstack — backend + SvelteKit frontend (cookiecutter template)
[3] cli — Python CLI tool, Typer (cookiecutter template)
[4] mcp-server — MCP + REST сервер (нет cookiecutter template — ручная инициализация)
[5] bot — Telegram bot, aiogram 3 (нет cookiecutter template — ручная инициализация)
[6] worker — Prefect flows (нет cookiecutter template — ручная инициализация)
Cookiecutter templates доступны для типов: backend, fullstack, cli
(директории в .opencode/templates/). Для mcp-server, bot, worker
шаблонов нет → WARN: "cookiecutter template not found for type <type>.
Доступные: backend, fullstack, cli. Для остальных типов используй check flow
или создай issue на добавление template." → STOP init flow.
Шаг 2: Вопрос — имя, описание, опции
Имя проекта (kebab-case, станет package name и GitHub repo name): ___
Описание (1 строка): ___
GitHub owner: ___
use_auth: [1] no (default) / [2] yes
use_db: [1] yes (default) / [2] no
Опции use_auth / use_db — переменные cookiecutter (см. cookiecutter.json).
Значения: "no" или "yes" (строки, lowercase).
Шаг 3: Делегирование — cookiecutter + git init + initial commit
Subagent (general) — Template INIT ниже. Cookiecutter рендерит проект в
./<project_name>/, post_gen_project hook удаляет файлы условные на
use_auth/use_db. Затем git init + initial commit внутри ./<project_name>/.
Шаг 4: Делегирование — GitHub remote + branch protection
Subagent (general) — Template GITHUB ниже. Мигрировано из repo-init Phase A
(steps 1-3) БЕЗ изменений: gh repo create, squash-only merge settings, branch
protection на main. Требует локальный git-репо с initial commit (из шага 3).
Шаг 5: Оркестратор — project-status
Вызови project-status tool напрямую (read-only oracle, ALLOWED для
оркестратора — как pipeline-status / spec-status):
project-status({})
Tool вернёт отчёт: Project: <type>, 7 групп [OK]/[WARN]/[FAIL], Итог:,
Рекомендации:. Покажи отчёт юзеру. Если tool вернул ⚠️ ...failed → WARN,
продолжай без отчёта.
Шаг 6: Финальный репорт
Project <project_name> created at ./<project_name>/.
GitHub: https://github.com/<owner>/<project_name>
Branch protection: main (PR + required_status_checks + linear history)
Project-status: <summary из шага 5>
Дальше: /run-pipeline для реализации фич, или /spec для генерации spec.
check flow
Шаг 1: Оркестратор — project-status
project-status({})
Для строгого режима (exit 1 на FAIL) — project-status({ check: true }).
Для пропуска медленных remote-проверок (branch protection via gh) —
project-status({ fast: true }). По умолчанию — non-blocking (exit 0).
Шаг 2: Оркестратор — отчёт + рекомендации
Покажи полный отчёт юзеру. В разделе Рекомендации: — список FAIL-чеков с
путями. Сгруппируй по категориям (Структура / Качество кода / Тесты / README /
Infra / Coverage).
Шаг 3: Вопрос — чинить?
Найдены проблемы: <N FAIL, M WARN>.
Запустить fix-subagents для рекомендаций?
[1] да — делегируй subagent(ов) для каждого FAIL
[2] нет — только отчёт, я починю сам
Если да → для каждого FAIL из Рекомендации: создай subagent (general) с
Template FIX (ниже), передав путь и описание проблемы. Subagent чинит, коммитит
через commit tool, push. Один FAIL = один subagent (последовательно, не
параллельно — см. AGENTS.md Linear Execution). После всех фиксов → re-run
project-status для верификации.
Если нет → STOP, отчёт у юзера.
Граничные случаи
- Существующий репо (не пустой) → init flow: предложи check flow. Если юзер
настаивает на init → cookiecutter создаст
./<project_name>/рядом (не перезапишет текущий репо). Уточни: "cwd уже git-репо с файлами. Init создаст новый проект в подкаталоге./<project_name>/. Продолжить? [1] да / [2] нет, лучше check flow". - GitHub repo уже существует → skip
gh repo create, только branch protection (если ещё не настроена). Subagent проверяет:gh repo view <owner>/<name>— если существует, пропускает create, переходит к settings + branch protection. - cookiecutter не установлен → WARN: "cookiecutter не найден. Установи:
uv tool install cookiecutter(илиpipx install cookiecutter). После установки повтори init." → STOP init flow. - project-status не найден → WARN: "project-status tool не доступен (issue #228 / PR #233 не завершён или tool не зарегистрирован). Пропускаю project-status проверку." → продолжай без отчёта (не блокирующий).
- Template для типа не найден (mcp-server/bot/worker) → WARN (см. Шаг 1).
- gh auth не настроен → subagent упадёт на
gh repo create. Сообщи юзеру: "запустиgh auth loginи повтори".
Prompt templates
Template INIT (cookiecutter + git init + initial commit)
Создай новый проект типа <type> с именем <project_name>.
Контекст: init flow project-template skill, cwd = <cwd>.
1. Проверь cookiecutter: `cookiecutter --version`. Если не установлен → STOP,
верни: "cookiecutter не установлен. Установи: `uv tool install cookiecutter`".
2. Запусти cookiecutter (no-input, переменные из ответов юзера):
`cookiecutter .opencode/templates/<type>/ --no-input \
project_name=<project_name> \
project_type=<type> \
description="<description>" \
use_auth=<auth> \
use_db=<db> \
python_version=3.13`
Cookiecutter создаст каталог `./<project_name>/` с рендеренным проектом.
post_gen_project hook удалит файлы условные на use_auth/use_db.
3. `cd <project_name>` (все дальнейшие команды — внутри этого каталога).
4. `git init`
5. `git add .` затем `git status` — проверь staged set (только файлы проекта,
без лишнего). Если лишнее — `git restore --staged <file>`.
6. `commit({ message: "chore: initial commit" })` tool (НЕ raw `git commit` —
заблокирован deny).
7. Верни: "done: project created at ./<project_name>/, git init + initial commit".
Если найдёшь баг вне scope — загрузи skill `bug-discovery` через
`skill("bug-discovery")` и следуй протоколу. НЕ чини баг сам.
Template GITHUB (gh repo create + settings + branch protection)
Мигрировано из repo-init Phase A (steps 1-3) БЕЗ изменений. Требует локальный git-репо с initial commit (из Template INIT).
Настрой GitHub remote для проекта <project_name> (cwd = <cwd>/<project_name>).
owner = <owner>, visibility = public (или private если internal).
0. Проверь: GitHub repo уже существует?
`gh repo view <owner>/<project_name>` — если exit 0, skip step 1 (create),
переходи к step 2 (settings) и step 3 (branch protection).
1. Создание репозитория:
`gh repo create <owner>/<project_name> --public --source=. --remote=origin --push`
(или --private если internal)
После создания: `gh auth setup-git`
2. Настройки репозитория (squash-only merge, auto-delete branch):
`gh api repos/<owner>/<project_name> \
--method PATCH \
-f allow_squash_merge=true \
-f allow_merge_commit=false \
-f allow_rebase_merge=false \
-f delete_branch_on_merge=true \
-f squash_merge_commit_title=COMMIT_OR_PR_TITLE \
-f squash_merge_commit_message=COMMIT_MESSAGES`
3. Защита ветки main (требовать PR, required_status_checks, linear history):
`gh api repos/<owner>/<project_name>/rules/branches/main \
--method POST \
-F target=branch \
-f enforcement=active \
--input - <<'EOF'
{
"conditions": {
"ref_name": {
"include": ["refs/heads/main"],
"exclude": []
}
},
"rules": [
{
"type": "pull_request",
"parameters": {
"required_approving_review_count": 0,
"dismiss_stale_reviews_on_push": false,
"require_code_owner_review": false,
"require_last_push_approval": false,
"required_review_thread_resolution": false
}
},
{
"type": "required_status_checks",
"parameters": {
"strict_required_status_checks": true,
"do_not_enforce_on_create": false,
"required_status_checks": []
}
},
{
"type": "deletion"
},
{
"type": "non_fast_forward"
}
]
}
EOF`
`required_status_checks` заполняется именами CI-джобов после первого пуша
(имена из cookiecutter CI: `lint`, `typecheck`, `test`, `complexity` для
Python; `check` для JS/TS). На этом этапе оставь пустой массив — обновится
после первого CI-прогона.
4. Верни: "done: GitHub remote created/verified, squash-only merge, branch
protection on main".
Если найдёшь баг вне scope — загрузи skill `bug-discovery` через
`skill("bug-discovery")` и следуй протоколу. НЕ чини баг сам.
Template FIX (check flow — починить FAIL из project-status)
Почини проблему из project-status отчёта.
Категория: <category> (Структура / Качество кода / Тесты / README / Infra / Coverage)
Проблема: <name>: <detail>
Путь: <path из рекомендации>
1. Прочитай контекст проблемы (файл по пути из рекомендации).
2. Минимальный фикс: добавь/исправь только то, что указано в рекомендации.
Не рефактори unrelated код.
3. Перед коммитом — `git status` для проверки staged set (`commit` tool НЕ
делает `git add` — коммитит только staged; используй
`git add <конкретные-пути>`, НЕ `git add -A`).
4. `commit({ message: "fix(<scope>): <description>" })` tool (НЕ raw
`git commit`), push.
5. Верни: "done: fixed <name>, commit <hash>".
Если найдёшь баг вне scope — загрузи skill `bug-discovery` через
`skill("bug-discovery")` и следуй протоколу. НЕ чини баг сам.
VALID_TYPES (из spec-status.py)
backend, fullstack, mcp-server, cli, bot, worker
Cookiecutter templates доступны для: backend, fullstack, cli
(директории .opencode/templates/<type>/).
Rules
- Main agent = оркестратор: вопросы юзеру +
project-statustool (read-only) + делегирование subagent'ам (Template INIT / GITHUB / FIX). Не делает cookiecutter/git/gh напрямую. project-statustool — read-only oracle, ALLOWED для оркестратора (какpipeline-status/spec-status).- init flow порядок: cookiecutter → git init/commit → gh repo create → branch protection → project-status. Не меняй порядок.
- check flow: project-status → отчёт → рекомендации → subagents (последовательно).
- Subagent error → 1 retry, потом STOP + report.
- Совместим с spec-pipeline: Phase 8 EXECUTE (spec/SKILL.md Template I) может вызывать project-template init для scaffolding issue.
committool НЕ делаетgit add— коммитит только staged. Используйgit add <конкретные-пути>, НЕgit add -A.