opencode-config/docs/decisions/063-pr-149-empty-quick-start.md
Sergey 4bb504a604
fix(create-readme): allow empty quick_start with steps-only Quick Start (#149)
* fix(create-readme): allow empty quick_start with steps-only Quick Start

* docs(handoff): add handoff + ADR for empty-quick-start

* docs(handoff): set PR number

* docs(project-map): update create-readme.ts role for PR#149

---------

Co-authored-by: opencode-agent <agent@opencode.local>
2026-07-30 04:06:52 +03:00

66 lines
No EOL
5.5 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-063: Allow empty quick_start with steps-only Quick Start (PR-149)
## Статус
Accepted (2026-07-30)
## Контекст
ADR-062 (PR-146) добавил параметры `quick_start_steps_en/ru` и условный
`hasBashBlock` (`include_clone !== false || quick_start !== ""`), чтобы
поддержать userscript-README с кликабельными шагами вместо bash-команды. Однако
валидация в `execute()` (mode `create`) по-прежнему требовала непустой
`quick_start` через falsy-чек `!v` в required-Record — пустая строка `""`
считалась отсутствующей, тулза возвращала `quick_start is required for create
mode`. Скилл `repo-readme` (раздел 8 «Кейс: userscript / web-app / npm-package»)
документирует комбинацию `include_clone: false` + `quick_start: ""` +
`quick_start_steps_*` как supported — но тулза её отвергала. Дополнительно:
`hasBashBlock` использовал `args.quick_start !== ""`, что для `undefined`
давало `true` (undefined !== ""), и bash-блок рендерил literal `undefined`
в теле code-fence. ADR-062 явно отметил в «Альтернативах», что ослабление
required-чек — отдельное решение вне scope того PR.
## Решение
1. **`CreateArgs.quick_start`** — сделан optional (`quick_start?: string`),
чтобы отражать реальную опциональность параметра.
2. **Required-валидация в `execute()`**`quick_start` убран из required-Record.
Вместо него добавлен guard после общих required-чеков:
- `hasBash = include_clone !== false || (quick_start ?? "") !== ""`
- `hasStepsEn = !!quick_start_steps_en && length > 0`
- `hasStepsRu = !!quick_start_steps_ru && length > 0`
- Если `!hasBash && !hasStepsEn` → ошибка `quick_start or
quick_start_steps_en required (Quick Start EN would be empty)`
- Если `!hasBash && !hasStepsRu` → аналогичная ошибка для RU.
Guard гарантирует, что Quick Start секция не пуста в ОБОИХ языках. Если
bash-блок рендерится — steps опциональны (backward compat).
3. **`hasBashBlock` и тела bash-блоков** — `args.quick_start ?? ""` вместо
`args.quick_start`: обрабатывает `undefined` (когда параметр не передан
вообще), иначе `undefined !== ""` даёт `true` и bash-блок рендерит literal
`undefined`. Локальная переменная `qs = args.quick_start ?? ""` переиспользуется
в обоих bash-блоках (EN/RU).
4. **Schema `.describe()`** — убрано "Required for create mode.", добавлено
пояснение: параметр optional, пустая строка/absent допустимы когда есть
`quick_start_steps_*`, bash-блок опускается при пустом AND `include_clone=false`.
5. **`validateReadme`** — без изменений: проверяет наличие строк "Quick Start" /
"Быстрый старт" в заголовках (`### ⚡ Quick Start` / `### ⚡ Быстрый старт`),
которые рендерятся всегда. README без bash-блока (только steps) проходит
валидацию. Подтверждено smoke-тестом (сценарий 1).
6. **Backward compatibility** — все существующие вызовы с непустым `quick_start`
и без steps работают идентично (сценарий 2 smoke-теста: git clone + pip
install, без шагов, без `undefined`).
## Альтернативы
- **Сделать `quick_start` required только когда нет steps** — отвергнуто:
сложная условная required-логика в одном Record, тяжело читать. Cleaner —
убрать из required и добавить явный guard с понятными сообщениями ошибок
для каждого языка отдельно.
- **Один общий guard «есть bash ИЛИ (steps EN И steps RU)»** — отвергнуто:
это допустило бы пустую RU-секцию когда есть bash + steps EN (но это
backward-compat кейс, где bash рендерится в обеих секциях). Текущий guard
(`!hasBash && !hasStepsX`) срабатывает ТОЛЬКО когда bash-блока нет —
тогда steps нужны в обоих языках. Когда bash есть — steps опциональны.
- **Валидировать steps в `validateReadme`** — отвергнуто: validate проверяет
структуру delimiter-пар и наличие секций, не содержимое Quick Start.
Заголовки рендерятся всегда; проверять пустоту секции — responsibility
`execute()`, не `validateReadme`.
- **Не вводить `qs` локальную переменную** — отвергнуто: повторение
`args.quick_start ?? ""` в трёх местах (hasBashBlock + 2 bash-блока) хуже
для читаемости, чем одна переменная.