opencode-config/.opencode/skills/project-template/SKILL.md
Sergey ca2a04ce47
refactor(templates): drop README from cookiecutter templates (#272)
* refactor(templates): remove README.md from cookiecutter templates

* test(templates): drop README expectations, expect WARN instead

* docs(skills): note README is generated post-init via repo-readme

* docs(skills): repo-readme creates README from scratch post-init

* fix(templates): drop readme field from pyproject after README removal

---------

Co-authored-by: opencode-agent <agent@opencode.local>
2026-08-05 04:15:43 +03:00

18 KiB
Raw Blame History

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).

ПРОТОКОЛ (ЖЁСТКО)

  1. Определи flow (вопрос юзеру, см. ниже).
  2. init flow → шаги 1-6 (см. ниже).
  3. check flow → шаги 1-3 (см. ниже).
  4. После каждого шага → 1 строка прогресса юзеру (формат: ✅ <step> — <done>).

ЗАПРЕЩЕНО

  • Запускать cookiecutter / git / gh напрямую из main agent — делегируй subagent (Template INIT, Template GITHUB). Main agent = оркестратор: вопросы юзеру + project-status tool (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-status tool вернул ⚠️ ...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 + Tailwind v4 + shadcn-svelte dashboard (TypeScript, 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, продолжай без отчёта.

README у свежего проекта отсутствует (issue #269) — README генерируется позже через repo-readme skill по ручному вызову. Поэтому группа README даст WARN «README.md отсутствует» (не FAIL, exit code 0 в non-blocking режиме). Это ожидаемое поведение, не ошибка — упомяни в отчёте.

Шаг 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>
README: отсутствует (WARN у project-status) — появится позже через repo-readme
Дальше: /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".

README.md в рендеренном проекте НЕТ (issue #269) — шаблоны его больше не
содержат. README появится позже через repo-readme skill по ручному вызову
(сначала юзер смотрит контент и cover.png из draw-image). project-status на
свежем проекте даст WARN по отсутствующему README — это ожидаемо, не чинить.

Если найдёшь баг вне 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-status tool (read-only) + делегирование subagent'ам (Template INIT / GITHUB / FIX). Не делает cookiecutter/git/gh напрямую.
  • project-status tool — read-only oracle, ALLOWED для оркестратора (как pipeline-status / spec-status).
  • init flow порядок: cookiecutter → git init/commit → gh repo create → branch protection → project-status. Не меняй порядок. README в init flow НЕ генерируется — только по ручному вызову repo-readme (issue #269).
  • 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.
  • commit tool НЕ делает git add — коммитит только staged. Используй git add <конкретные-пути>, НЕ git add -A.