* feat(cover): add /cover command for branded cover generation * chore(env): add VERCEL_TOKEN placeholder to .env.example * docs(project-map): add cover command, ADR-088 and handoff for PR #199 --------- Co-authored-by: opencode-agent <agent@opencode.local>
31 lines
4.9 KiB
Markdown
31 lines
4.9 KiB
Markdown
# ADR-088: /cover command — hardcoded Lime standard + VERCEL_TOKEN placeholder (PR#199)
|
||
|
||
## Статус
|
||
Accepted (2026-07-31)
|
||
|
||
## Контекст
|
||
Генерация брендового кавера 1024×1024 для репозиториев slaid098 ранее требовала повторного объяснения Lime-стиля (палитра, lowercase-заголовок, отсутствие subtitle) в каждом новом чате — детерминированного способа одной командой не было (issue #198). `draw-image` tool (PR#133) и `repo-readme` skill (PR#158) уже формируют cover-pipeline, но стиль оставался на усмотрение агента/пользователя, что рисковало сломать единый вид витрины slaid098.dev кастомной палитрой или путём вывода.
|
||
|
||
Дополнительно: будущая интеграция с Vercel потребует токен `VERCEL_TOKEN`, но код ещё не готов — нужен placeholder в `.env.example`, чтобы переменную не забыть при подключении (доп. scope, одобренный пользователем в issue #198).
|
||
|
||
Рассматривались варианты:
|
||
- Сделать `/cover` параметризуемой командой (палитра/шаблон/subtitle — на выбор пользователя): ломает единый бренд-стандарт витрины, пользователь может вывести не-Lime кавер.
|
||
- Вынести стиль в отдельный skill `cover`: issue #198 явно выводит skill вне scope — команда должна быть самодостаточной.
|
||
- Не добавлять `VERCEL_TOKEN` пока код не готов: риск забыть переменную при будущей интеграции.
|
||
|
||
## Решение
|
||
1. **Команда `/cover`** (`.opencode/commands/cover.md`, frontmatter `agent: build`) — самодостаточная, без отдельного skill. Стиль **захардкожен** и НЕ спрашивается/НЕ переопределяется:
|
||
- `template` = `cover` (единственный шаблон в `draw-image/templates/cover.svg`).
|
||
- Палитра = Lime из `draw-image/brand.json` (base `#0a0a0a`, accent `#ccff00`, fg `#ededed`).
|
||
- `title`: ровно ОДИН заголовок, lowercase English, авто-деривация из имени репо (`opencode-voice-dictation` → `opencode voice dictation`).
|
||
- `subtitle`: **запрещён** стандартом — передача = ошибка команды.
|
||
- `out` = `assets/cover.png` (глобальный путь для витрины, без исключений).
|
||
2. **Слоты**: `icon` (обязательный — Lucide из `icons/lucide/` или brand-logo из `brand-logos/`), `sub-icon` (опц.), `badge` (опц.).
|
||
3. **Flow**: read repo → infer title/icon/sub-icon → ask user 2-3 content-вопроса (НЕ по стилю) → `draw-image` tool → validate README ``.
|
||
4. **Extension-механизм**: команда НЕ хардкодит бренды — OpenCode упомянут только как пример. Расширение = добавление brand-logo SVG в `draw-image/brand-logos/`, а не изменение команды.
|
||
5. **`VERCEL_TOKEN` в `.env.example`** — optional-плейсхолдер `VERCEL_TOKEN=` после секции Cloudflare Tunnel, в стиле соседних optional-секций. В коде пока не задействован — placeholder-пример. Существующие записи и тесты `tests/test_permissions.py` не затронуты.
|
||
|
||
## Альтернативы
|
||
- **Параметризуемая команда (палитра/шаблон/subtitle на выбор)**: отвергнуто — ломает единый бренд-стандарт витрины slaid098.dev, пользователь может вывести не-Lime кавер или добавить subtitle. Захардкоженный стандарт гарантирует консистентность.
|
||
- **Отдельный skill `cover`**: отвергнуто — issue #198 явно выводит skill вне scope. Команда самодостаточна (frontmatter + инструкции в одном файле), skill избыточен.
|
||
- **Не добавлять `VERCEL_TOKEN` до готовности кода**: отвергнуто — placeholder фиксирует намерение и стиль (optional-секция), чтобы переменную не забыть при будущей интеграции. Добавление пустого плейсхолдера не ломает существующие тесты и записи.
|