opencode-config/docs/decisions/049-pr-112-add-repo-readme-skill-and-tool.md
Sergey 7ea12b982d
feat(skills): add repo-readme skill and create-readme tool (#112)
* feat(tools): add create-readme tool

* feat(skills): add repo-readme skill

* docs(handoff): add handoff and ADR

* docs(handoff): set PR number

* docs(project-map): update after structural changes

---------

Co-authored-by: opencode-agent <agent@opencode.local>
2026-07-29 01:04:51 +03:00

60 lines
4.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# ADR-049: create-readme tool + repo-readme skill for standardized README
## Статус
Accepted (2026-07-28)
## Контекст
Витрина slaid098.dev парсит `README.md` из каждого репозитория: скачивает raw
файл и извлекает фрагмент между разделителями `<!-- summary-en:start/end -->` и
`<!-- summary-ru:start/end -->`. До сих пор README формировался агентом вручную
через Write/Edit — это недетерминированно: разделители могли отсутствовать,
секции Support/Quick Start/language switcher — расходиться со стандартом, из-за
чего витрина не могла корректно отрендерить карточку. Issue #111 требует тулзу,
гарантирующую структуру, и скилл, дающий агенту контекст.
## Решение
Реализовать TS-плагин `create-readme` (`.opencode/tools/create-readme.ts`) с
двумя режимами:
- `create` — генерирует README по фиксированному шаблону через template
literal, подставляя параметры. Структура (разделители, Support block, Quick
Start, language switcher) зашита в тулзе, а не в агенте.
- `validate` — проверяет существующий README на соответствие стандарту (6
проверок).
Параметр `mode` = `tool.schema.enum(["create","validate"])` (zod через
`tool.schema` = `typeof z`, подтверждено `tool.d.ts`). `tier` (flagship/utility)
и `file_path` реализованы через `.optional()` + fallback в handler (`args.tier
?? "utility"`) вместо zod `.default()` — консистентно с существующими тулзами
(они `.default()` не используют) и надёжно независимо от того, парсит opencode
args через zod или передаёт raw.
Локальный режим: `fs.writeFileSync`/`readFileSync`. Удалённый режим: `gh api`
через `spawnSync` (GET для SHA, PUT с base64+content+message+sha) — как
`create-issue.ts`/`commit.ts` используют `spawnSync` напрямую. `gh api -X PUT`
помечен как destructive в `check-permissions.py`, но это правило проверяет
bash allow-rules конфига, а не `spawnSync` внутри плагина — тулзе allow-rule не
нужен.
Скилл `repo-readme` описывает: когда вызывать create vs validate, tier system,
GitHub metadata как отдельный шаг (`gh repo edit`, не в тулзе), workflow
(create → ручные правки → validate), зачем разделители, шаблон как reference,
независимость от repo-init.
## Альтернативы
- **zod `discriminatedUnion("mode", [createSchema, validateSchema])`** —
отвергнуто: `tool()` принимает `args: Args extends z.ZodRawShape` (plain
object of zod schemas), а не `ZodDiscriminatedUnion`. Использована плоская
schema с `mode: enum` + ручная валидация обязательных полей в handler.
- **zod `.default()` для tier/file_path** — отвергнуто ради консистентности с
существующими тулзами и независимости от того, вызывает opencode zod-parse.
Использован `.optional()` + fallback `??`.
- **Импорт zod напрямую** — отвергнут: `tool.schema` уже re-export'ит полный
zod (`var schema: typeof z`), отдельный импорт и зависимость `zod` в
package.json не нужны (его нет в dependencies, и существующие тулзы его не
импортируют).
- **Регистрация тулзы в `opencode.json` (agent.tools)** — не требуется:
плагины авто-дискаверятся из `.opencode/tools/*.ts` (как `tunnel.ts`,
которого нет в конфиге).