feat(create-readme): add bilingual tagline and repo_name validation (#151)
* feat(create-readme): add bilingual tagline and repo_name validation * docs(repo-readme): bilingual tagline + repo_name validation rules * docs(handoff): add handoff and ADR-064 for bilingual tagline * docs(handoff): set PR number * docs(project-map): update after PR#151 bilingual tagline changes --------- Co-authored-by: opencode-agent <agent@opencode.local>
This commit is contained in:
parent
4bb504a604
commit
6c80eb8458
5 changed files with 226 additions and 18 deletions
|
|
@ -54,6 +54,10 @@ repos/{owner}/{repo}/contents/README.md` с base64-контентом и SHA.
|
|||
Витрина **slaid098.dev** скачивает raw `README.md` из каждого репо и
|
||||
извлекает фрагменты между разделителями:
|
||||
|
||||
- `<!-- tagline-en:start -->` ... `<!-- tagline-en:end -->` — английский
|
||||
tagline (короткая фраза для карточки).
|
||||
- `<!-- tagline-ru:start -->` ... `<!-- tagline-ru:end -->` — русский
|
||||
tagline.
|
||||
- `<!-- summary-en:start -->` ... `<!-- summary-en:end -->` — английский
|
||||
блок Why/What для карточки.
|
||||
- `<!-- features-en:start -->` ... `<!-- features-en:end -->` — английская
|
||||
|
|
@ -73,7 +77,12 @@ repos/{owner}/{repo}/contents/README.md` с base64-контентом и SHA.
|
|||
|
||||
```markdown
|
||||
# 🚀 {repo_name}
|
||||
> {tagline}
|
||||
<!-- tagline-en:start -->
|
||||
> {tagline_en}
|
||||
<!-- tagline-en:end -->
|
||||
<!-- tagline-ru:start -->
|
||||
> {tagline_ru}
|
||||
<!-- tagline-ru:end -->
|
||||
|
||||
[English](#-english) | [Русский](#-русский)
|
||||
|
||||
|
|
@ -146,12 +155,13 @@ repos/{owner}/{repo}/contents/README.md` с base64-контентом и SHA.
|
|||
👉 **[slaid098.dev/support](https://slaid098.dev/support)**
|
||||
```
|
||||
|
||||
`validate` проверяет: наличие всех 4 пар EN/RU разделителей (summary +
|
||||
features), непустой контент между ними, ссылку `slaid098.dev/support`, секции
|
||||
Quick Start (EN) и Быстрый старт (RU), language switcher `[English]` /
|
||||
`[Русский]`, заголовок `## 🇷🇺 Русский` (не "Русская версия"), anchor
|
||||
`[Русский](#-русский)` (не `#-русская-версия`). Шаги `quick_start_steps_*`
|
||||
не влияют на валидацию — они рендерятся вне delimiter-пар (summary/features).
|
||||
`validate` проверяет: наличие всех 6 пар EN/RU разделителей (tagline + summary +
|
||||
features), непустой контент между ними, H1 title prefix `# 🚀 `, ссылку
|
||||
`slaid098.dev/support`, секции Quick Start (EN) и Быстрый старт (RU), language
|
||||
switcher `[English]` / `[Русский]`, заголовок `## 🇷🇺 Русский` (не "Русская
|
||||
версия"), anchor `[Русский](#-русский)` (не `#-русская-версия`). Шаги
|
||||
`quick_start_steps_*` не влияют на валидацию — они рендерятся вне delimiter-пар
|
||||
(summary/features).
|
||||
|
||||
## 6. Независимость от repo-init
|
||||
|
||||
|
|
@ -167,8 +177,17 @@ Quick Start (EN) и Быстрый старт (RU), language switcher `[English]
|
|||
`create-readme`:
|
||||
|
||||
- `mode` — `"create"` | `"validate"` (обязательный).
|
||||
- `repo_name`, `tagline`, `why_en`, `what_en`, `why_ru`, `what_ru`,
|
||||
`quick_start`, `features_en`, `features_ru` — обязательны для `create`.
|
||||
- `repo_name`, `tagline_en`, `tagline_ru`, `why_en`, `what_en`, `why_ru`,
|
||||
`what_ru`, `quick_start`, `features_en`, `features_ru` — обязательны для
|
||||
`create`.
|
||||
- `repo_name` — должен быть **lowercase kebab-case** (regex
|
||||
`^[a-z0-9]+(-[a-z0-9]+)*$`): только `a-z`, `0-9`, одиночные дефисы. Uppercase,
|
||||
underscores, пробелы, leading/trailing/consecutive dashes — отвергаются.
|
||||
- `tagline_en` — короткий английский tagline (1 предложение). **Не должен
|
||||
содержать кириллицы** (валидируется regex `/[ЁА-яё]/`).
|
||||
- `tagline_ru` — короткий русский tagline (1 предложение). **Должен содержать
|
||||
кириллицу** (валидируется regex `/[ЁА-яё]/`). Гарантирует, что русский
|
||||
tagline реально на русском, а не копия английского.
|
||||
- `features_en` / `features_ru` — массив `{ emoji, name, description }[]`.
|
||||
- `custom_sections_en` / `custom_sections_ru` — массивы
|
||||
`{ title, content }` (optional).
|
||||
|
|
@ -213,7 +232,8 @@ Quick Start (EN) и Быстрый старт (RU), language switcher `[English]
|
|||
{
|
||||
"mode": "create",
|
||||
"repo_name": "my-userscript",
|
||||
"tagline": "One-line tagline.",
|
||||
"tagline_en": "One-line tagline.",
|
||||
"tagline_ru": "Короткий теглайн.",
|
||||
"why_en": "Why this exists.",
|
||||
"what_en": "What it does.",
|
||||
"why_ru": "Зачем этот проект.",
|
||||
|
|
@ -249,3 +269,19 @@ Access at [http://localhost:4096](http://localhost:4096)
|
|||
|
||||
`include_clone: false` + `quick_start: ""` → bash-блок не рендерится (только
|
||||
шаги). Если `quick_start` непустой — bash-блок рендерится перед шагами.
|
||||
|
||||
## 9. Breaking change: tagline → tagline_en + tagline_ru
|
||||
|
||||
Параметр `tagline` **удалён** (PR #150). Раньше был один английский tagline;
|
||||
теперь два — `tagline_en` (EN) и `tagline_ru` (RU) — оба обязательны для
|
||||
`create`. Витрина slaid098.dev парсит оба через delimiter-теги
|
||||
`<!-- tagline-en:start/end -->` и `<!-- tagline-ru:start/end -->`.
|
||||
|
||||
**Миграция:** замени `"tagline": "..."` на `"tagline_en": "..."` +
|
||||
`"tagline_ru": "..."`. Старые вызовы с `tagline` падают с
|
||||
`❌ tagline_en is required for create mode`.
|
||||
|
||||
**Существующие README** (без tagline delimiter-тегов) станут invalid при
|
||||
`validate` — `Missing <!-- tagline-en:start --> delimiter` и
|
||||
`Missing <!-- tagline-ru:start --> delimiter`. Регенерация README через
|
||||
`create` (с новыми параметрами) делается отдельным шагом после merge.
|
||||
|
|
|
|||
|
|
@ -8,7 +8,8 @@ type CustomSection = { title: string; content: string }
|
|||
|
||||
type CreateArgs = {
|
||||
repo_name: string
|
||||
tagline: string
|
||||
tagline_en: string
|
||||
tagline_ru: string
|
||||
why_en: string
|
||||
what_en: string
|
||||
why_ru: string
|
||||
|
|
@ -79,7 +80,12 @@ function generateReadme(args: CreateArgs): string {
|
|||
const stepsRu = renderSteps(args.quick_start_steps_ru)
|
||||
|
||||
return `# 🚀 ${args.repo_name}
|
||||
> ${args.tagline}
|
||||
<!-- tagline-en:start -->
|
||||
> ${args.tagline_en}
|
||||
<!-- tagline-en:end -->
|
||||
<!-- tagline-ru:start -->
|
||||
> ${args.tagline_ru}
|
||||
<!-- tagline-ru:end -->
|
||||
|
||||
[English](#-english) | [Русский](#-русский)
|
||||
|
||||
|
|
@ -131,6 +137,10 @@ function validateReadme(content: string): { ok: boolean; issues: string[] } {
|
|||
const issues: string[] = []
|
||||
|
||||
const delimiters = [
|
||||
"tagline-en:start",
|
||||
"tagline-en:end",
|
||||
"tagline-ru:start",
|
||||
"tagline-ru:end",
|
||||
"summary-en:start",
|
||||
"summary-en:end",
|
||||
"features-en:start",
|
||||
|
|
@ -146,6 +156,8 @@ function validateReadme(content: string): { ok: boolean; issues: string[] } {
|
|||
}
|
||||
|
||||
const pairs = [
|
||||
{ start: "<!-- tagline-en:start -->", end: "<!-- tagline-en:end -->", label: "EN tagline" },
|
||||
{ start: "<!-- tagline-ru:start -->", end: "<!-- tagline-ru:end -->", label: "RU tagline" },
|
||||
{ start: "<!-- summary-en:start -->", end: "<!-- summary-en:end -->", label: "EN summary" },
|
||||
{ start: "<!-- features-en:start -->", end: "<!-- features-en:end -->", label: "EN features" },
|
||||
{ start: "<!-- summary-ru:start -->", end: "<!-- summary-ru:end -->", label: "RU summary" },
|
||||
|
|
@ -157,6 +169,8 @@ function validateReadme(content: string): { ok: boolean; issues: string[] } {
|
|||
issues.push(`${p.label} content between delimiters is empty`)
|
||||
}
|
||||
|
||||
if (!content.includes("# 🚀 "))
|
||||
issues.push("Missing H1 title prefix '# 🚀 '")
|
||||
if (!content.includes("slaid098.dev/support"))
|
||||
issues.push("Missing Support link (slaid098.dev/support)")
|
||||
if (!content.includes("Quick Start"))
|
||||
|
|
@ -188,10 +202,14 @@ export default tool({
|
|||
.string()
|
||||
.optional()
|
||||
.describe("Repository name (e.g. 'anti-detect-mcp'). Required for create mode."),
|
||||
tagline: tool.schema
|
||||
tagline_en: tool.schema
|
||||
.string()
|
||||
.optional()
|
||||
.describe("Short English tagline (1 sentence). Required for create mode."),
|
||||
.describe("Short English tagline (1 sentence). Required for create mode. Must not contain Cyrillic."),
|
||||
tagline_ru: tool.schema
|
||||
.string()
|
||||
.optional()
|
||||
.describe("Short Russian tagline (1 sentence). Required for create mode. Must contain Cyrillic."),
|
||||
why_en: tool.schema
|
||||
.string()
|
||||
.optional()
|
||||
|
|
@ -290,7 +308,8 @@ export default tool({
|
|||
if (args.mode === "create") {
|
||||
const required: Record<string, string | undefined> = {
|
||||
repo_name: args.repo_name,
|
||||
tagline: args.tagline,
|
||||
tagline_en: args.tagline_en,
|
||||
tagline_ru: args.tagline_ru,
|
||||
why_en: args.why_en,
|
||||
what_en: args.what_en,
|
||||
why_ru: args.why_ru,
|
||||
|
|
@ -304,6 +323,13 @@ export default tool({
|
|||
if (!args.features_ru || args.features_ru.length === 0)
|
||||
return `❌ features_ru is required for create mode`
|
||||
|
||||
if (!/^[a-z0-9]+(-[a-z0-9]+)*$/.test(args.repo_name!))
|
||||
return `❌ repo_name must be lowercase kebab-case (a-z0-9 with single dashes), got: "${args.repo_name}"`
|
||||
if (/[ЁА-яё]/.test(args.tagline_en!))
|
||||
return `❌ tagline_en must be English (no Cyrillic), got Cyrillic chars`
|
||||
if (!/[ЁА-яё]/.test(args.tagline_ru!))
|
||||
return `❌ tagline_ru must contain Cyrillic (Russian text), got: "${args.tagline_ru}"`
|
||||
|
||||
const hasBash = args.include_clone !== false || (args.quick_start ?? "") !== ""
|
||||
const hasStepsEn = !!args.quick_start_steps_en && args.quick_start_steps_en.length > 0
|
||||
const hasStepsRu = !!args.quick_start_steps_ru && args.quick_start_steps_ru.length > 0
|
||||
|
|
@ -314,7 +340,8 @@ export default tool({
|
|||
|
||||
const content = generateReadme({
|
||||
repo_name: args.repo_name!,
|
||||
tagline: args.tagline!,
|
||||
tagline_en: args.tagline_en!,
|
||||
tagline_ru: args.tagline_ru!,
|
||||
why_en: args.why_en!,
|
||||
what_en: args.what_en!,
|
||||
why_ru: args.why_ru!,
|
||||
|
|
|
|||
87
docs/decisions/064-pr-151-bilingual-tagline.md
Normal file
87
docs/decisions/064-pr-151-bilingual-tagline.md
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
# ADR-064: Bilingual tagline and repo_name validation (PR-151)
|
||||
|
||||
## Статус
|
||||
Accepted (2026-07-30)
|
||||
|
||||
## Контекст
|
||||
ADR-062 (PR-146) и ADR-063 (PR-149) эволюционировали тулзу `create-readme`
|
||||
вокруг Quick Start. Параметр `tagline` оставался единым английским теглайном
|
||||
с момента ADR-058 (PR-116, README standard v2). Витрина **slaid098.dev**
|
||||
парсит README через delimiter-теги (summary/features), но tagline
|
||||
рендерился вне delimiterов — парсер не мог его надёжно извлечь, и RU tagline
|
||||
отсутствовал вообще. Дополнительно: `repo_name` принимал любой строки
|
||||
(uppercase, underscores, пробелы) — генерировал `git clone` ссылки вида
|
||||
`https://github.com/slaid098/MyRepo.git` (валидные, но не matching actual
|
||||
repo slug); `tagline_en` никто не проверял на отсутствие кириллицы, а
|
||||
`tagline_ru` не существовало. Issue #150 требует: (A) билингвальный tagline
|
||||
EN+RU с delimiter-тегами, (B) валидация английского `repo_name` (lowercase
|
||||
kebab-case) и `tagline_en` (no Cyrillic), `tagline_ru` (require Cyrillic).
|
||||
|
||||
## Решение
|
||||
1. **`CreateArgs` type** — `tagline: string` переименован в `tagline_en:
|
||||
string` + `tagline_ru: string` (оба required, без `?`). Старый параметр
|
||||
удалён (breaking).
|
||||
2. **Рендер top-блока** — tagline обёрнут в delimiter-пары:
|
||||
```
|
||||
# 🚀 {repo_name}
|
||||
<!-- tagline-en:start -->
|
||||
> {tagline_en}
|
||||
<!-- tagline-en:end -->
|
||||
<!-- tagline-ru:start -->
|
||||
> {tagline_ru}
|
||||
<!-- tagline-ru:end -->
|
||||
|
||||
[English](#-english) | [Русский](#-русский)
|
||||
```
|
||||
EN-пара идёт первой, затем RU-пара, подряд без пустых строк между ними;
|
||||
пустая строка перед language switcher. Spacing критичен для парсера.
|
||||
3. **Content-валидация в `execute()`** — после presence-чеков (required
|
||||
Record, falsy `!v`), ДО Quick Start guard (PR #149), добавлены:
|
||||
- `repo_name`: `^[a-z0-9]+(-[a-z0-9]+)*$` — lowercase kebab-case, только
|
||||
`a-z`/`0-9`, одиночные дефисы (не leading/trailing/consecutive).
|
||||
- `tagline_en`: `/[ЁА-яё]/` reject — если есть кириллица → ошибка.
|
||||
- `tagline_ru`: `/[ЁА-яё]/` require — если нет кириллицы → ошибка
|
||||
(ловит копию английского tagline).
|
||||
Порядок: presence → content (regex) → Quick Start guard.
|
||||
4. **`validateReadme`** — добавлено 4 delimiter'а в массив (`tagline-en/ru
|
||||
start/end`, итого 12), +2 пары в `pairs` (EN/RU tagline, с empty-content
|
||||
check), +check H1 prefix `# 🚀 ` (substring). repo_name regex в validate
|
||||
НЕ добавлен — legacy README с uppercase repo_name не должны ломаться
|
||||
(валидируется только в create mode).
|
||||
5. **Schema** — `tagline` переименован в `tagline_en`, обновлён `.describe()`
|
||||
("Must not contain Cyrillic"); добавлен `tagline_ru` (".describe": "Must
|
||||
contain Cyrillic"). Оба `.optional()` (required-логика в `execute()`).
|
||||
6. **SKILL.md** — раздел 4 (delimiters): +tagline-en/ru; раздел 5 (шаблон):
|
||||
top-блок с delimiter-тегами; раздел 5 (validate): "6 пар EN/RU
|
||||
разделителей (tagline + summary + features)" + H1 prefix; раздел 7
|
||||
(параметры): `tagline_en`/`tagline_ru` с правилами, `repo_name` с regex;
|
||||
раздел 8 (пример): `tagline_en`/`tagline_ru`; новый раздел 9 "Breaking
|
||||
change: tagline → tagline_en + tagline_ru" с инструкцией миграции.
|
||||
7. **Backward compatibility** — BREAKING: `tagline` удалён, старые вызовы
|
||||
падают с `❌ tagline_en is required for create mode`. Существующие README
|
||||
(без tagline delimiter-тегов) станут invalid при `validate` —
|
||||
`Missing <!-- tagline-en:start --> delimiter` и тег. Регенерация README
|
||||
отдельный шаг после merge.
|
||||
|
||||
## Альтернативы
|
||||
- **Оставить `tagline` как alias к `tagline_en`** — отвергнуто: молчаливый
|
||||
дуализм (то `tagline`, то `tagline_en`) запутывает пользователей и парсер.
|
||||
Явный breaking с понятным сообщением `❌ tagline_en is required` лучше для
|
||||
миграции (одна правка вызова, а не поиск «почему RU tagline пустой»).
|
||||
- **Один `tagline` + авто-перевод** — отвергнуто: перевод tagline — не
|
||||
responsibility тулзы, качество перевода критично для карточки slaid098.dev.
|
||||
Явный `tagline_ru` с require-Cyrillic-чеком гарантирует осмысленный русский.
|
||||
- **Валидировать `repo_name` в `validateReadme`** — отвергнуто: legacy README
|
||||
с uppercase repo_name (например, старые репо до стандарта) не должны
|
||||
ломаться при `validate`. Regex только в `create` (новые README генерируются
|
||||
по стандарту). `validate` проверяет структуру (delimiterы, заголовки), не
|
||||
контент repo_name.
|
||||
- **Строгий H1 check (regex на полный `# 🚀 {repo_name}`)** — отвергнуто:
|
||||
`validate` не знает `repo_name` (работает с произвольным README).
|
||||
Substring-чек `# 🚀 ` ловит отсутствие префикса, не валидирует что после
|
||||
него. Достаточно для regression-детекции.
|
||||
- **Три отдельных tagline-чек (presence + regex EN + regex RU) как один
|
||||
guard** — отвергнуто: три независимых `if return` с разными сообщениями
|
||||
читаемее, чем комбинированный guard. Пользователь видит конкретную ошибку
|
||||
(repo_name / tagline_en / tagline_ru), а не «одна из трёх валидаций не
|
||||
прошла».
|
||||
58
docs/handoff/pr-151-bilingual-tagline.md
Normal file
58
docs/handoff/pr-151-bilingual-tagline.md
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
---
|
||||
pr: 151
|
||||
title: feat(create-readme): add bilingual tagline and repo_name validation
|
||||
---
|
||||
|
||||
## Что сделано
|
||||
|
||||
В `.opencode/tools/create-readme.ts` (mode `create`): параметр `tagline`
|
||||
переименован в `tagline_en` + добавлен `tagline_ru` (оба required). Рендер
|
||||
top-блока теперь обёрнут в delimiter-теги `<!-- tagline-en:start/end -->` и
|
||||
`<!-- tagline-ru:start/end -->` (для парсера slaid098.dev). Добавлена
|
||||
content-валидация в `execute()` ПОСЛЕ presence-чеков, ДО Quick Start guard:
|
||||
`repo_name` — lowercase kebab-case regex `^[a-z0-9]+(-[a-z0-9]+)*$`;
|
||||
`tagline_en` — no Cyrillic (`/[ЁА-яё]/`); `tagline_ru` — require Cyrillic.
|
||||
`validateReadme`: +4 delimiter'а (tagline-en/ru start/end, итого 12),
|
||||
+2 пары (EN/RU tagline), +check H1 prefix `# 🚀 `. Schema обновлена
|
||||
(`tagline_en`/`tagline_ru` с обновлёнными `.describe()`). SKILL.md обновлён:
|
||||
разделители tagline в список, шаблон top-блока, таблица параметров, пример
|
||||
вызова, новый раздел 9 «Breaking change: tagline → tagline_en + tagline_ru».
|
||||
Smoke-тест: 7 сценариев, 16 assertion'ов, все PASS (happy path + validate ok,
|
||||
repo_name uppercase, repo_name underscore, tagline_en Cyrillic, tagline_ru no
|
||||
Cyrillic, old tagline breaking, validateReadme на старом README без tagline
|
||||
delimiterов).
|
||||
|
||||
## Почему
|
||||
|
||||
Issue #150: slaid098.dev парсер нуждается в отдельном RU tagline (раньше был
|
||||
только один английский `tagline`). Валидация гарантирует: `repo_name` —
|
||||
строго английский kebab-case (lowercase, без uppercase/underscore/пробелов);
|
||||
`tagline_en` — реально на английском (без кириллицы); `tagline_ru` — реально
|
||||
на русском (содержит кириллицу, не копия английского). Breaking change:
|
||||
параметр `tagline` удалён — миграция на `tagline_en` + `tagline_ru`.
|
||||
|
||||
## Pending
|
||||
|
||||
Регенерация существующих README в репо slaid098 через `create-readme` с
|
||||
новыми параметрами (`tagline_en`/`tagline_ru`) — отдельный шаг после merge
|
||||
(PR/issue вне scope #150). Существующие README без tagline delimiter-тегов
|
||||
станут invalid при `validate` (ожидаемо).
|
||||
|
||||
## Watch out
|
||||
|
||||
**BREAKING CHANGE**: параметр `tagline` удалён из `create-readme` (mode
|
||||
`create`). Старые вызовы с `tagline` падают с `❌ tagline_en is required for
|
||||
create mode`. Миграция: заменить `tagline` на `tagline_en` + добавить
|
||||
`tagline_ru`. Существующие README без tagline delimiter-тегов станут
|
||||
invalid при `validate` (`Missing <!-- tagline-en:start --> delimiter`) —
|
||||
регенерация отдельный шаг (см. Pending).
|
||||
|
||||
Порядок валидации в `execute()` (create mode): presence-чеки (required
|
||||
Record) → content-чеки (regex: repo_name, tagline_en, tagline_ru) → Quick
|
||||
Start guard (PR #149). Content-чеки используют non-null assertion `args.x!`
|
||||
— безопасно, т.к. presence-чеки уже прошли. `validateReadme` НЕ проверяет
|
||||
repo_name regex — только create mode (legacy README с uppercase repo_name не
|
||||
должны ломаться). H1 prefix check `# 🚀 ` — substring-чек, не строгий (ищет
|
||||
presence префикса, не валидирует что после него). ADR-064 отмечает
|
||||
backward-compat альтернативу «оставить tagline alias» — отвергнута (явный
|
||||
breaking лучше молчаливого дуализма).
|
||||
|
|
@ -36,7 +36,7 @@ opencode-config/
|
|||
│ │ ├── python-development/SKILL.md # Python dev patterns
|
||||
│ │ ├── release/SKILL.md # Tag + GitHub Release
|
||||
│ │ ├── repo-init/SKILL.md # New repository bootstrap
|
||||
│ │ ├── repo-readme/SKILL.md # Standardized README generation (create-readme tool: create vs validate, bilingual Why/What + Features table, GitHub metadata, quick_start_steps clickable steps + conditional bash block) — PR#112, PR#116, PR#118, PR#130, PR#146
|
||||
│ │ ├── repo-readme/SKILL.md # Standardized README generation (create-readme tool: create vs validate, bilingual Why/What + Features table, GitHub metadata, quick_start_steps clickable steps + conditional bash block; tagline_en/tagline_ru required + delimiter-теги, breaking change note) — PR#112, PR#116, PR#118, PR#130, PR#146, PR#151
|
||||
│ │ ├── tunnel/SKILL.md # Cloudflare tunnel toggle (tool `tunnel()`: 1-й вызов start, 2-й stop) — PR#63 (восстановлен, удалён в PR#42)
|
||||
│ │ ├── run-tests/SKILL.md # Test runner guide
|
||||
│ │ └── spec/SKILL.md # 9-phase spec generation
|
||||
|
|
@ -45,7 +45,7 @@ opencode-config/
|
|||
│ │ ├── commit.ts # commit tool wrapper (1 arg message, validates format+staged) — PR#38
|
||||
│ │ ├── create-issue.ts # create-issue tool wrapper (3 args, validates format+labels; optional repo?: string) — PR#38, PR#65
|
||||
│ │ ├── create-pr.ts # create-pr tool wrapper (3 args, validates format+Closes #N; optional repo?: string) — PR#38, PR#65
|
||||
│ │ ├── create-readme.ts # create-readme tool (TS plugin, modes: create/validate; standardized bilingual README with features table, include_clone/development_en/ru/quick_start_steps_en/ru optional params, clickable access_url [url](url), conditional bash block via hasBashBlock, RU heading 'Русский' + anchor checks, 4 delimiter pairs for slaid098.dev; local fs + remote gh api) — PR#112, PR#116, PR#118, PR#130, PR#146, PR#149 (quick_start optional + guard: Quick Start non-empty per-lang via hasBash/hasStepsEn/hasStepsRu; hasBashBlock handles undefined via ?? "")
|
||||
│ │ ├── create-readme.ts # create-readme tool (TS plugin, modes: create/validate; standardized bilingual README with features table, include_clone/development_en/ru/quick_start_steps_en/ru optional params, clickable access_url [url](url), conditional bash block via hasBashBlock, RU heading 'Русский' + anchor checks, 6 delimiter pairs for slaid098.dev (summary-en/ru, features-en/ru, tagline-en/ru); tagline_en+tagline_ru required (BREAKING: tagline removed PR#151), content-валидация repo_name (lowercase kebab-case) + tagline_en (no Cyrillic) + tagline_ru (require Cyrillic), validateReadme H1 prefix check `# 🚀 `; local fs + remote gh api) — PR#112, PR#116, PR#118, PR#130, PR#146, PR#149 (quick_start optional + guard), PR#151 (bilingual tagline + repo_name validation, breaking)
|
||||
│ │ ├── draw-image.ts # draw-image tool wrapper (opencode plugin, 5 args: template/title/subtitle?/slots?/out?; spawnSync node cli.ts render → sharp PNG) — PR#133
|
||||
│ │ ├── merge-pr.ts # merge-pr tool wrapper (orchestrator-safe gh pr merge; optional repo?: string) — PR#30, PR#65
|
||||
│ │ ├── memory-access.ts # memory-access tool (bump frontmatter last_accessed/access_count, regex replace, atomic write tmp+rename) — PR#101
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue