fix(readme): russian heading, simplified support, access_url, env username (#118)

* fix(readme): russian heading, simplified support, access_url, env username

* fix(ci): wrap long assert to satisfy ruff E501 in test_permissions.py

* docs(project-map): add PR#118 tags (create-readme, repo-readme, .env.example)

* fix(ci): format test_permissions.py for ruff format check

---------

Co-authored-by: opencode-agent <agent@opencode.local>
This commit is contained in:
Sergey 2026-07-29 04:56:35 +03:00 committed by GitHub
parent 464fa6ec83
commit 4e926a43a7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 162 additions and 18 deletions

View file

@ -12,6 +12,7 @@ MEMORY_CHUNK_SIZE=512
MEMORY_CHUNK_OVERLAP=64
# OpenCode Server
OPENCODE_SERVER_USERNAME=your-opencode-server-username
OPENCODE_SERVER_PASSWORD=your-opencode-server-password
# GitHub

View file

@ -75,7 +75,7 @@ repos/{owner}/{repo}/contents/README.md` с base64-контентом и SHA.
# 🚀 {repo_name}
> {tagline}
[English](#-english) | [Русский](#-русская-версия)
[English](#-english) | [Русский](#-русский)
---
@ -104,10 +104,11 @@ repos/{owner}/{repo}/contents/README.md` с base64-контентом и SHA.
git clone https://github.com/slaid098/{repo_name}.git
{quick_start}
\`\`\`
{access_url строка если передан — Access at {url}}
---
## 🇷🇺 Русская версия
## 🇷🇺 Русский
<!-- summary-ru:start -->
### ❓ Зачем
@ -132,12 +133,12 @@ git clone https://github.com/slaid098/{repo_name}.git
git clone https://github.com/slaid098/{repo_name}.git
{quick_start}
\`\`\`
{access_url строка если передан — Доступ: {url}}
---
## 💬 Support and contacts / Поддержка и контакты
Have questions or want to support?
👉 **[slaid098.dev/support](https://slaid098.dev/support)**
{telegram строка, если передан}
```
@ -145,7 +146,8 @@ Have questions or want to support?
`validate` проверяет: наличие всех 4 пар EN/RU разделителей (summary +
features), непустой контент между ними, ссылку `slaid098.dev/support`, секции
Quick Start (EN) и Быстрый старт (RU), language switcher `[English]` /
`[Русский]`.
`[Русский]`, заголовок `## 🇷🇺 Русский` (не "Русская версия"), anchor
`[Русский](#-русский)` (не `#-русская-версия`).
## 6. Независимость от repo-init
@ -167,5 +169,7 @@ Quick Start (EN) и Быстрый старт (RU), language switcher `[English]
- `custom_sections_en` / `custom_sections_ru` — массивы
`{ title, content }` (optional).
- `telegram` — username без `@` (optional).
- `access_url` — URL для Access/Доступ строки после Quick Start bash-блока
(optional). EN: `Access at {url}`, RU: `Доступ: {url}`. Omit if no web access.
- `repo``owner/name` для удалённой операции (optional).
- `file_path` — локальный путь (default `README.md`).

View file

@ -17,6 +17,7 @@ type CreateArgs = {
features_en: Feature[]
features_ru: Feature[]
telegram?: string
access_url?: string
custom_sections_en?: CustomSection[]
custom_sections_ru?: CustomSection[]
}
@ -48,11 +49,13 @@ function generateReadme(args: CreateArgs): string {
const telegramLine = args.telegram
? `\n💬 **Direct Telegram:** [@${args.telegram}](https://t.me/${args.telegram})`
: ""
const accessLineEn = args.access_url ? `\nAccess at ${args.access_url}\n` : ""
const accessLineRu = args.access_url ? `\оступ: ${args.access_url}\n` : ""
return `# 🚀 ${args.repo_name}
> ${args.tagline}
[English](#-english) | [Русский](#-русская-версия)
[English](#-english) | [Русский](#-русский)
---
@ -74,11 +77,10 @@ ${renderFeaturesTable(args.features_en, false)}
\`\`\`bash
git clone https://github.com/slaid098/${args.repo_name}.git
${args.quick_start}
\`\`\`
\`\`\`${accessLineEn}
---
## 🇷🇺 Русская версия
## 🇷🇺 Русский
<!-- summary-ru:start -->
### Зачем
@ -96,13 +98,11 @@ ${renderFeaturesTable(args.features_ru, true)}
\`\`\`bash
git clone https://github.com/slaid098/${args.repo_name}.git
${args.quick_start}
\`\`\`
\`\`\`${accessLineRu}
---
## 💬 Support and contacts / Поддержка и контакты
Have questions or want to support?
👉 **[slaid098.dev/support](https://slaid098.dev/support)**${telegramLine}
`
}
@ -147,13 +147,17 @@ function validateReadme(content: string): { ok: boolean; issues: string[] } {
issues.push("Missing [English] language switcher link")
if (!content.includes("[Русский]"))
issues.push("Missing [Русский] language switcher link")
if (!content.includes("## 🇷🇺 Русский"))
issues.push("Missing '## 🇷🇺 Русский' header (should be 'Русский', not 'Русская версия')")
if (!content.includes("[Русский](#-русский)"))
issues.push("Missing or wrong [Русский](#-русский) switcher link (should be #-русский, not #-русская-версия)")
return { ok: issues.length === 0, issues }
}
export default tool({
description:
"Create or validate README.md for slaid098 repositories. 'create' mode generates a standardized bilingual README with delimiter tags (<!-- summary-en:start/end -->, <!-- features-en:start/end -->, <!-- summary-ru:start/end -->, <!-- features-ru:start/end -->) parsed by the slaid098.dev showcase. 'validate' mode checks an existing README against the standard. Supports local file (fs) and remote (gh api repos/{owner}/{repo}/contents/README.md) operation.",
"Create or validate README.md for slaid098 repositories. 'create' mode generates a standardized bilingual README with delimiter tags (<!-- summary-en:start/end -->, <!-- features-en:start/end -->, <!-- summary-ru:start/end -->, <!-- features-ru:start/end -->) parsed by the slaid098.dev showcase. 'validate' mode checks an existing README against the standard, including the '## 🇷🇺 Русский' header and the [Русский](#-русский) switcher anchor. Supports local file (fs) and remote (gh api repos/{owner}/{repo}/contents/README.md) operation.",
args: {
mode: tool.schema
.enum(["create", "validate"])
@ -236,6 +240,10 @@ export default tool({
.string()
.optional()
.describe("Local file path (local mode only). Default: 'README.md'."),
access_url: tool.schema
.string()
.optional()
.describe("Optional URL for Access/Доступ line after Quick Start bash block. EN: 'Access at {url}', RU: 'Доступ: {url}'. Omit if no web access."),
},
async execute(args, context) {
try {
@ -270,6 +278,7 @@ export default tool({
features_en: args.features_en!,
features_ru: args.features_ru!,
telegram: args.telegram,
access_url: args.access_url,
custom_sections_en: args.custom_sections_en,
custom_sections_ru: args.custom_sections_ru,
})

View file

@ -1,7 +1,7 @@
# 🚀 opencode-config
> Portable AI coding assistant config with memory & subagent pipeline
[English](#-english) | [Русский](#-русская-версия)
[English](#-english) | [Русский](#-русский)
---
@ -40,10 +40,11 @@ cd opencode-config
cp .env.example .env
docker compose up -d
```
Access at http://localhost:4096
---
## 🇷🇺 Русская версия
## 🇷🇺 Русский
<!-- summary-ru:start -->
### ❓ Зачем
@ -78,10 +79,14 @@ cd opencode-config
cp .env.example .env
docker compose up -d
```
Доступ: http://localhost:4096
---
## 💬 Support and contacts / Поддержка и контакты
Have questions or want to support?
👉 **[slaid098.dev/support](https://slaid098.dev/support)**
## License
MIT — see [LICENSE](LICENSE).

View file

@ -0,0 +1,48 @@
# ADR-052: README fixes — Russian heading, simplified support, access_url
## Статус
Accepted (2026-07-29)
## Контекст
Стандарт v2 (ADR-051, PR#116) оставил несколько шероховатостей:
- RU заголовок `## 🇷🇺 Русская версия` — длиннее нужного, anchor
`#-русская-версия` многословен. "Русский" короче и естественнее.
- Support блок содержал строку `Have questions or want to support?`
избыточно, ссылка `slaid098.dev/support` самодостаточна.
- Не было параметра для указания URL web-доступа после Quick Start. Репо с
web-интерфейсом (opencode-config — http://localhost:4096) не показывали
пользователю куда идти.
- `OPENCODE_SERVER_USERNAME` отсутствовал в `.env.example` — opencode server
требует username, но шаблон не упоминал его.
## Решение
4 фикса + усиление validate:
- **RU заголовок:** `## 🇷🇺 Русская версия``## 🇷🇺 Русский`. Switcher
anchor: `[Русский](#-русская-версия)``[Русский](#-русский)`.
- **Support блок:** убрана строка `Have questions or want to support?`,
оставлена только ссылка `👉 **[slaid098.dev/support]...`.
- **`access_url`** — новый optional параметр тулзы `create-readme`. Если
передан, после Quick Start bash-блока добавляется `Access at {url}` (EN) и
`Доступ: {url}` (RU). Если не передан — ничего не добавляется (обратно
совместимо).
- **`OPENCODE_SERVER_USERNAME`** добавлен в `.env.example` (перед
`OPENCODE_SERVER_PASSWORD`).
- **`validate`** — 2 новые проверки: заголовок `## 🇷🇺 Русский` и anchor
`[Русский](#-русский)`. Существующие README со старым "Русская версия" не
пройдут валидацию — требуют перегенерации.
## Альтернативы
- **Сохранить "Русская версия"** — отвергнуто: длиннее, anchor
`#-русская-версия` многословен. "Русский" короче и естественнее для
носителя языка.
- **Оставить "Have questions or want to support?" в Support** — отвергнуто:
избыточно. Ссылка `slaid098.dev/support` самодостаточна, описание
перегружает блок.
- **`access_url` как обязательный параметр** — отвергнуто: не все репо имеют
web-доступ (CLI-утилиты, библиотеки). Optional — обратно совместимо, репо
без web-доступа просто не передают параметр.

View file

@ -0,0 +1,63 @@
---
pr: 118
title: fix(readme): russian heading, simplified support, access_url, env username
---
## Что сделано
4 фикса в `create-readme` tool (`.opencode/tools/create-readme.ts`):
- **RU заголовок:** `## 🇷🇺 Русская версия``## 🇷🇺 Русский`.
- **Switcher anchor:** `[Русский](#-русская-версия)`
`[Русский](#-русский)`.
- **Support блок** — убрана строка `Have questions or want to support?`,
оставлена только ссылка `👉 **[slaid098.dev/support]...`.
- **`access_url`** — новый optional параметр. Если передан, после Quick Start
bash-блока добавляется `Access at {url}` (EN) и `Доступ: {url}` (RU).
`validateReadme()` — добавлены 2 проверки:
- `## 🇷🇺 Русский` header (не "Русская версия").
- `[Русский](#-русский)` switcher link (не `#-русская-версия`).
Schema: добавлен `access_url` (optional string). `execute()` передаёт
`access_url` в `generateReadme()`. `description` обновлён (упоминание RU header
+ anchor checks).
Обновлён скилл `repo-readme` (`.opencode/skills/repo-readme/SKILL.md`):
- §5 (Шаблон README) — `## 🇷🇺 Русский`, `[Русский](#-русский)`, Support без
"Have questions", `access_url` строки после Quick Start bash-блоков.
- §5 — описание `validate` дополнено (RU header + anchor checks).
- §7 (Параметры тулзы) — добавлен `access_url`.
`.env.example`: добавлен `OPENCODE_SERVER_USERNAME` (отсутствовал).
`tests/test_permissions.py`: добавлен
`test_opencode_server_username_present_in_env_example`.
`README.md`: перегенерирован по обновлённому шаблону (Русский, упрощённый
Support, Access at / Доступ: http://localhost:4096, License секция).
`docs/project-map/README.md`: описание `create-readme.ts` обновлено (добавлено
`access_url`).
Проверки: `tsc --noEmit` (с `--types node`) чисто; `pytest
tests/test_permissions.py` OK (13 passed); `check-permissions.py` OK.
## Почему
Polish после PR#116 (v2). "Русская версия" — длинно, "Русский" короче и
соответствует anchor. Support блок перегружен описанием — достаточно ссылки.
`OPENCODE_SERVER_USERNAME` отсутствовал в `.env.example` (opencode server
требует username). `access_url` нужен для репо с web-доступом (например,
opencode-config — http://localhost:4096).
## Pending
## Watch out
`access_url` — optional. Если не передан, Access/Доступ строки не
добавляются (обратно совместимо). `validate` теперь проверяет RU header
(`## 🇷🇺 Русский`) и anchor (`[Русский](#-русский)`) — существующие README,
сгенерированные старой версией тулзы (с "Русская версия"), не пройдут
валидацию. Требуется перегенерация через `create-readme` (mode: create).

View file

@ -35,7 +35,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) — PR#112, PR#116
│ │ ├── repo-readme/SKILL.md # Standardized README generation (create-readme tool: create vs validate, bilingual Why/What + Features table, GitHub metadata) — PR#112, PR#116, PR#118
│ │ ├── 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
@ -44,7 +44,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, 4 delimiter pairs for slaid098.dev; local fs + remote gh api) — PR#112, PR#116
│ │ ├── create-readme.ts # create-readme tool (TS plugin, modes: create/validate; standardized bilingual README with features table, access_url, RU heading 'Русский' + anchor checks, 4 delimiter pairs for slaid098.dev; local fs + remote gh api) — PR#112, PR#116, PR#118
│ │ ├── 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
│ │ ├── memory-doctor.ts # memory-doctor tool (read-only diagnostics: rg, Python src.memory importability, env vars, memory dir, RAG index; markdown ✅/❌ report) — PR#101
@ -124,7 +124,7 @@ opencode-config/
├── docker-compose.yml # 2 services (dind + opencode), opencode_network, 4 bind mounts, port 4096 on 0.0.0.0 — PR#24, PR#51
├── Dockerfile # node:22-trixie-slim (Debian 13 trixie, glibc 2.41) + uv + gh + chromium + docker.io + opencode-ai + repomix + cloudflared (@mathew-cf/opencode-memory REMOVED PR#103) — PR#24, PR#34, PR#57, PR#71, PR#103
│ # Memory deps install layers (PR#107): COPY .opencode/package.json → npm install --omit=dev (runtime: @vscode/ripgrep for memory-search.ts); COPY pyproject.toml uv.lock → uv sync --no-dev --frozen (runtime: httpx, numpy, tenacity for python -m src.memory)
├── .env.example # Placeholder-only env template (user copies to .env) — PR#24, PR#34 (TUNNEL_DOMAIN), PR#36 (OPENCODE_MEMORY_REMOTE/DIR), PR#106 (AI_PROVIDER_* removed, OPENCODE_MEMORY_REMOTE now optional)
├── .env.example # Placeholder-only env template (user copies to .env) — PR#24, PR#34 (TUNNEL_DOMAIN), PR#36 (OPENCODE_MEMORY_REMOTE/DIR), PR#106 (AI_PROVIDER_* removed, OPENCODE_MEMORY_REMOTE now optional), PR#118 (OPENCODE_SERVER_USERNAME)
├── app_data/
│ ├── opencode-memory/ # Persistent memory (separate git repo, gitignored) — PR#36
│ ├── workspaces/ # Agent working directory (.gitkeep)

View file

@ -57,6 +57,20 @@ def test_context7_api_key_absent_in_opencode_json():
# ── global deny rules ───────────────────────────────────────────────────────
# ── OPENCODE_SERVER_USERNAME in .env.example (issue #117) ───────────────────
def test_opencode_server_username_present_in_env_example():
"""OPENCODE_SERVER_USERNAME is present in .env.example."""
content = ENV_EXAMPLE.read_text()
assert "OPENCODE_SERVER_USERNAME" in content, (
"OPENCODE_SERVER_USERNAME missing from .env.example"
)
# ── global deny rules ───────────────────────────────────────────────────────
def test_global_deny_rules_present():
"""The 4 deny rules exist in permission.bash and are set to 'deny'."""
bash = _load_config()["permission"]["bash"]