1
0

Перевод на zensical и актуализация

This commit is contained in:
2026-07-11 15:09:32 +08:00
parent 7ec67ef918
commit 82a98edf00
18 changed files with 1771 additions and 874 deletions
+384
View File
@@ -0,0 +1,384 @@
---
name: koda-zensical
description: Навык, который необходим для работы в этом репозитории и должен закружаться безусловно. Этот навык содержит инструкции, которые позволят правильно писать и форматировать исходные файлы документации.
---
# Документирование
## Принципы написания документации
### Язык и стиль
- Пиши простым и понятным языком
- Избегай просторечий и сложных технических терминов без объяснения
- Используй активный залог
- Обращайся к пользователю на "вы"
- Поддерживай единый стиль во всех документах
- Не злоупотребляй emoji
### Примеры
- Приводи примеры конфигурации
- Показывай скриншоты для важных шагов
- Добавляй таблицы для сравнения опций
### Исправление и избегание ошибок
- Синтаксические и грамматические ошибки должны исправляться в соответствии с правиламии и нормами естественного языка
- При изменении структуры документации:
- в новый документ следует добавить ссылки на другие релевантные документы или якоря
- ссылки на перемещённый или удалённый документ/якорь следует обновить в каждом существующем документе
- следует проверять вывод команды `make site` на наличие ошибок и предупреждений компилятора
## Синтаксис файлов
В основе документации лежит расширенный markdown.
Ниже описаны правила оформления и синтаксиса, которые отличаются от стандартного markdown и github-flavoured markdown.
Расширения синтаксиса предоставляются связкой:
- `zensical` (документация: <https://zensical.org/docs/>)
- `pymdown-extensions` (документация: <https://facelessuser.github.io/pymdown-extensions>)
Ниже только необходимые и достаточные правила:
- для качественной документации;
- хорошего человеческого восприятия;
- корректного формирования документации без ошибок.
Применение этих подходов необязательно, но требования к каждому требуется соблюдать строго.
Если приведены ссылки на документацию, можешь использовать их для получения актуальной информации.
Там так же могут быть описаные дополнительные приёмы для работы с документами.
### Frontmatter
Каждый документ должен начинаться с этого блока метаданных.
После frontmatter должна быть пустая строка.
Внутри должен быть валидный yaml.
Часто используются следующие опциональные параметры (* — желательны):
- *`title` — укорочечнное название документа для отображения в навигации (умолчание — заголовок 1 уровня)
- *`description` — небольшое осмысленное описание документа (умолчание — пусто)
- *`icon` — код иконки для отображения в навигации рядом с названием (умолчание — пусто)
- *`tags` — массив ключевых слов (тегов), описывающих документ (умолчание — пусто)
- `hide` — массив кодов элементов, которые нужно скрыть на странице документа:
- `navigation` — главная навигация (слева)
- `toc` — содержание страницы (справа)
- `path` — хлебные крошки (сверху)
- `status` — статус страницы (добавляет к пункту навигации слева иконку с подсказкой)
- `new` — новая информация
- `deprecated` — устаревшая информация
- `beta` — информация о нестабильном функционале
Параметр `title` не должен быть равен заголовку первого уровня.
В таком случае `title` следует убрать или не добавлять.
### Заголовки
На странице должен быть только один заголовок 1 уровня — сразу после Frontmatter.
До и после каждого заголовка должна быть 1 пустая строка.
### Абзацы
До и после каждого абзаца должна быть 1 пустая строка.
Каждое предложение внутри абзаца должно быть на новой строке.
### Списки
Вложенные уровни отступаются на 4 пробела слева.
До и после каждого списка должна быть 1 пустая строка.
Ненумерованные списки начинаются с `-`.
### Многострочные блоки кода
До и после каждого блока кода должна быть 1 пустая строка.
Каждый блок кода в заголовке может иметь атрибуты:
- `title="..."` — заголовок блока (например, название файла)
- `hl_lines="..."` — подсветка срок: номера через пробел и/или диапазоны через `-`
- `linenums="N"` — включить нумерацию строк, отсчитывая с указанного числа `N`
В конце строк внутри блока может быть любое число в формате `#(X)!` — это кликальбельные аннотации, содержимое которых будет взято из ближайшего нумерованного списка.
Полный пример:
```yaml title="config.yaml" hl_lines="6 8-10 13 17-20" linenums="1"
context:
- provider: code
# - provider: docs # сломан
- provider: diff #(2)!
- provider: terminal
- provider: problems
- provider: folder
- provider: codebase
params:
nFinal: 10
# - provider: file
# - provider: url
# - provider: search #(1)!
```
1. Подсказка 1
2. **Подсказка** 2
### Врезки
Позволяют акцентировать внимание на ключевых моментах, выделяя блок цветом и иконкой.
Документация: <https://raw.githubusercontent.com/zensical/docs/master/docs/authoring/admonitions.md>
Синтаксис:
```
!!! <тип> "Заголовок статичной врезки"
Содержимое, которое может
быть многострочным
??? <тип> "Заголовок разворачиваемой врезки"
Содержимое, которое может быть многострочным
и свёрнуто по умолчанию, но разворачивается по клику на заголовке
???+ <тип> "Заголовок сворачиваемой врезки"
Содержимое, которое может быть многострочным
и развёрнуто по умолчанию, но сворачивается по клику на заголовке
```
Типы, их цвета и пиктограммы:
| Тип | Цвет | Пиктограмма |
| ---------- | ------- | ------------------ |
| `note` | #448aff | карандаш в круге |
| `abstract` | #00b0ff | планшет для бумаги |
| `info` | #00b8d4 | `i` в круге |
| `tip` | #00bfa5 | пламя |
| `success` | #00c853 | галочка |
| `question` | #64dd17 | `?` в круге |
| `warning` | #ff9100 | `!` в треугольнике |
| `failure` | #ff5252 | крестик |
| `danger` | #ff1744 | молния в круге |
| `bug` | #f50057 | жук на щите |
| `example` | #7c4dff | пробирка |
| `quote` | #9e9e9e | двойная кавычка |
Заголовок может быть пустым, в этом случае:
- после типа указываются пустые двойные кавычки (иначе подставится название типа с заглавной буквы на английском языке)
- содержимое внутри блока обрамлён цветом своего типа
Если текста внутри врезки нет, отображается только яркий заголовок с иконкой.
Содержимое врезки отступается минимум на 4 пробела.
Содержимое без отступа (в начале строки) находится вне врезки.
Для содержимого врезки распространяются все те же markdown-правила, включая указанные в этом документе.
До и после каждой врезки должна быть 1 пустая строка.
### Сниппеты
Это переиспользуемые блоки markdown/html, хранящиеся в файлах.
- Директория: `snippets` в корне проекта
- Документация: <https://raw.githubusercontent.com/facelessuser/pymdown-extensions/refs/heads/main/pymdownx/snippets.py>
Как использовать:
1. создать файл с директории
2. наполнить содержимым
3. во всех местах документации вставить:
- пустая строка
- `--8<-- "filename.md"`
- пустая строка
4. если файлов несколько, вставить следующим образом:
- пустая строка
- `--8<--`
- `"filename1.md"`
- пустая строка
- `"filename2.md"`
- `--8<--`
- пустая строка
### Иконки
Каждая иконка определяется своим идентификатором, который делится на две части: код набора и код иконки.
Внутри frontmatter (параметр `icon`) используется формат: `набор/иконка`
В тексте документа используется формат: `:набор-иконка:`
Если иконка в начале строки, пробел ставится только после неё.
Если иконка в середине строки, пробелы ставятся до и после неё.
Если иконка в конце строки, пробел ставятся только до неё.
Доступны 4 встроенных набора иконок:
| Название | Код набора | Ссылка | Путь в проекте |
| --------------- | ------------- | ---------------------------------------------- | --------------------------- |
| Lucide | `lucide` | <https://lucide.dev/icons/> | - |
| Material Design | `material` | <https://pictogrammers.com/library/mdi/> | - |
| FontAwesome | `fontawesome` | <https://fontawesome.com/search> | - |
| Octicons | `octicons` | <https://primer.style/octicons/> | - |
| Simple Icons | `material` | <https://simpleicons.org/> | - |
| VSCode Codicons | `vscode` | <https://github.com/microsoft/vscode-codicons> | `./overrides/.icons/vscode` |
Полный список названий иконок здесь: <https://squidfunk.github.io/mkdocs-material/assets/javascripts/iconsearch_index.json>
Получить полный список иконок в этих наборах можно прочитав содержимое указанных директорий в проекте.
### Гриды (карточки)
Грид позволяет разместить короткие предложения в формате динамических карточек.
Он выглядит как markdown-список, обрамлённый в `<div>`.
До открывающего и после закрывающего тегов должна быть 1 пустая строка.
Пример простого грида с компактными карточками:
```
<div class="grid cards" markdown>
- :fontawesome-brands-html5: Карточка №1
- :fontawesome-brands-js: Карточка №2
- :fontawesome-brands-css3: Карточка №3
- :fontawesome-brands-internet-explorer: Карточка №4
</div>
```
Пример грида с многострочными карточками:
```
<div class="grid cards" markdown>
- :fontawesome-brands-html5: **Заголовок карточки №1**
---
Многострочное содержимое карточки №1
- :fontawesome-brands-js: **Заголовок карточки №2**
---
Многострочное содержимое карточки №2
- :fontawesome-brands-css3: **Заголовок карточки №3**
---
Многострочное содержимое карточки №3
- :fontawesome-brands-internet-explorer: **Заголовок карточки №4**
---
Многострочное содержимое карточки №4
</div>
```
### Вкладки (табы)
Позволяют уместить информацию на одном уровне, не растягивая страницу по высоте.
Синтаксис:
```
=== "Заголовок вкладки 1"
Содержимое вкладки 1
=== "Заголовок вкладки 2"
Содержимое вкладки 2
```
Содержимое вкладки отступается минимум на 4 пробела.
Содержимое без отступа (в начале строки) находится вне вкладки.
Для содержимого вкладки распространяются все те же markdown-правила, включая указанные в этом документе.
До и после каждого заголовка вкладки должна быть 1 пустая строка.
После содержимого последней вкладки должна быть 1 пустая строка.
### Сноски
Сноска позволяет добавить надстрочный индекс к слову, чтобы вынести пояснения в конец страницы, быстро переместиться к нему по клику на индекс и вернуться обратно.
Синтаксис:
```
Lorem[^1] ipsum[^2] dolor sit amet, consectetur adipiscing elit.
[^1]: однострочная сноска
[^2]:
многострочная сноска
с отступом 4 пробела слева
на каждой строке
```
### Подсказки (тултипы) и аббревиатуры
Они появляются при наведении мыши на какой-либо элемент на странице документа.
Пример 1: иконка с подсказкой:
`:material-information-outline:{ title="текст подсказки" }`
Пример 2: ссылка с подсказкой:
`[Hover me](https://example.com "I'm a tooltip!")`
Пример 3: альтернативная ссылка с подсказкой:
```
[Hover me][example]
[example]: https://example.com "I'm a tooltip!"
```
### Горячие клавиши
В общем случае, для указания корячих клавиш следует использовать тег `<kbd>`.
Примеры: `<kbd>B</kbd>`, `<kbd>Esc</kbd>`
Для описания комбинаций клавиш следует вставлять между каждой клавишей знак `+`, обрамлённый пробелами.
Примеры: `<kbd>Shift</kbd> + <kbd>A</kbd>`, `<kbd>Ctrl</kbd> + <kbd>K</kbd> + <kbd>4</kbd>`
Для MacOS-специфичных тем вставлять `+` не нужно.
Примеры: `<kbd>⌘</kbd><kbd>C</kbd>`, `<kbd>⇧</kbd><kbd>⌘</kbd><kbd>P</kbd>`
Сопоставление пиктограмм с названиями клавиш (служебных и модификаторов) MacOS:
- Базовые модификаторы:
- `` - `Command` (`Cmd`)
- `` - `Option` (`Alt`)
- `` - `Control` (`Ctrl`)
- `` - `Shift`
- `` - `Caps Lock`
- Навигация и управление:
- `` - `Delete` (Backspace, удаление символа слева)
- `` - `Forward Delete` (удаление символа справа, `Fn` + D`elete)
- `⏎` - `Return` (`Enter`)
- `⌕` - `Enter` на цифровой клавиатуре (в некоторых шрифтах)
- `⎋` - `Escape` (`Esc`)
- `⇥` - `Tab` (Табуляция)
- `⇤` - `Backtab` (`Shift` + `Tab`)
- `␣` - `Space` (Пробел)
- Перемещение по тексту:
- `↖` - `Home` (Начало документа, `Fn` + `←`)
- `↘` - `End` (Конец документа, `Fn` + `→`)
- `⇞` - `Page Up` (Страница вверх, `Fn` + `↑`)
- `⇟` - `Page Down` (Страница вниз, `Fn` + `↓`)
- Специальные и системные:
- `🌐` / `fn` — Функция (`Fn` / Кнопка смены языка/вызова эмодзи)
- `⏏``Eject` (Извлечение диска)
### Кнопки
- `[Серая кнопка](https://example.com/){ .md-button }`
- `[Синяя кнопка](https://example.com/){ .md-button .md-button--primary }`
- `[:fontawesome-solid-paper-plane: Кнопка серая с иконкой](https://example.com/){ .md-button }`
- `[:fontawesome-solid-paper-plane: Кнопка синяя с иконкой](https://example.com/){ .md-button .md-button--primary }`
+3 -2
View File
@@ -1,3 +1,4 @@
/.cache
/site
/.cache/
/site/
/__pycache__/
.DS_Store
+25
View File
@@ -0,0 +1,25 @@
- Всегда используй навык koda-zensical
- Всегда перечитывай файлы перед каждым изменением - пользователь уже мог внести изменения
- При изменениях структуры проекта всегда актуализируй AGENTS.md
- |
В структуре навигации файла `zensical.toml` всегда должен присутствовать закомментированный раздел `Debug`.
Это отладочные страницы с примерами, которые не должны попасть в итоговую документацию.
Этот раздел раскомментируется вручную по необходимости.
- |
Для отладки используй команду `make site`.
В выводе команды могу быть предупреждения и ошибки в следующем формате:
```
Warning: page does not exist
╭─[ test.md:695:10 ]
695 │ - [Edit](../edit/how-to-use-it.md) — редактирование кода
│ ────────────┬───────────
│ ╰───────────── page does not exist
─────╯
```
что означает буквально следующее: "в файле content/test.md в строке 695 в позиции 10 есть ссылка на несуществующую страницу."
Эти предупреждения надо всегда исправлять.
- При изменениях структуры проекта и только при корректной сборке (без предупреждений и ошибок) всегда актуализируй `./AGENTS.md`
- При доработке или расширении функционала этого проекта или синтаксиса всегда актуализируй скилл `./.agents/skills/koda-zensical`
+5
View File
@@ -0,0 +1,5 @@
{
"recommendations": [
"0x10.mkdocs-material-preview"
]
}
+5
View File
@@ -0,0 +1,5 @@
{
"files.associations": {
"*.md": "python-markdown"
}
}
+22
View File
@@ -0,0 +1,22 @@
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"label": "Живой предпросмотр (localhost:8000)",
"type": "shell",
"command": "make live"
},
{
"label": "Собрать статический сайт (./site)",
"type": "shell",
"command": "make site"
},
{
"label": "Собрать docker-образ со стат. сайтом",
"type": "shell",
"command": "make image"
}
]
}
+129
View File
@@ -0,0 +1,129 @@
# KODA.md — контекст проекта
## Обзор проекта
Бойлерплейт для документации на базе [Zensical](https://zensical.org) — системы документации, построенной на MkDocs Material.
Проект предназначен для быстрого старта документации к любому продукту или сервису: от локальной разработки с live-предпросмотром до сборки Docker-образа со статическим сайтом на nginx.
### Технологии
- **Zensical** — движок документации (форк MkDocs Material)
- **Docker** — контейнерная сборка и деплой
- **nginx:alpine** — раздача статического сайта
- **Python** — кастомный плагин `inline_badges.py` (inline-бейджи через HTML-комментарии)
- **TOML** — конфигурация проекта (`zensical.toml`)
### Архитектура
Проект использует двухэтапную сборку Docker-образа:
1. **Builder** (`zensical/zensical:latest`) — собирает статический сайт из Markdown-файлов в `content/`
2. **Runtime** (`nginx:alpine`) — раздаёт готовый статический сайт на порту 80
Вся разработка ведётся через Docker — локальная установка Zensical не требуется.
## Структура проекта
```
content/ — исходные страницы документации (.md)
index.md — главная страница
part1/ — пример раздела с вложенными страницами
sandbox.md — песочница с примерами синтаксиса (отладочная)
vscode-icons.md — справочник VSCode-иконок (отладочная)
_asseets/ — assets (изображения, стили, скрипты)
snippets/ — переиспользуемые блоки markdown
abbr.md — аббревиатуры
coming_soon.md — заглушка «скоро появится»
config_file_path.md — пример сниппета с путями конфигурации
overrides/ — кастомизация темы Zensical
.icons/ — кастомные наборы иконок (vscode/)
zensical.toml — конфигурация проекта (тема, навигация, расширения)
inline_badges.py — Python-плагин для inline-бейджей
Dockerfile — многоэтапная сборка: zensical build → nginx
Makefile — команды для разработки и деплоя
CONTRIBUTING.md — правила контрибуции
.editorconfig — настройки редактора (отступы, кодировка, переносы)
.dockerignore — исключения для Docker-контекста
.kodarules — правила для AI-ассистента
```
## Сборка и запуск
Все команды выполняются через `make` (требуется установленный Docker).
| Команда | Описание |
| ------------ | --------------------------------------------------------------------- |
| `make live` | Запуск в режиме живой перезагрузки на `http://localhost:8000` |
| `make site` | Генерация статического сайта с валидацией ссылок и якорей |
| `make image` | Сборка Docker-образа `harbor.example.com/boilerplate-docs:latest` |
| `make run` | Запуск контейнера из образа на `http://localhost:8001` |
| `make push` | Загрузка Docker-образа в реестр `harbor.example.com` |
| `make help` | Справка по командам (цель по умолчанию) |
### Валидация
При сборке (`make site`) включена валидация:
- битые ссылки (`invalid_links = true`)
- битые якоря (`invalid_link_anchors = true`)
Предупреждения и ошибки валидации необходимо исправлять перед отправкой изменений.
## Конфигурация
### zensical.toml
Основной конфигурационный файл. Ключевые настройки:
- **Документация:** `content/`, вывод в `site/`
- **Тема:** Material с поддержкой светлой/тёмной тем, шрифты Inter / JetBrains Mono
- **Навигация:** табы, секции, хлебные крошки, кнопка «наверх», прошлый/следующий документ
- **Расширения Markdown:** admonition, tabs, superfences, snippets, footnotes, emoji, highlight, inline badges
- **Иконки:** Lucide, Material Design, FontAwesome, Octicons, Simple Icons, VSCode Codicons (кастомные)
- **Теги:** настроены иконки для HTML, JS, CSS, VSCode, JetBrains, CLI, AI/LLM
- **Социальные ссылки:** Telegram, YouTube, GitHub (в футере)
- **Debug-раздел:** закомментированный блок в `nav` для отладочных страниц (`sandbox.md`, `vscode-icons.md`)
### inline_badges.py
Кастомный Python-плагин для Markdown. Преобразует HTML-комментарии в бейджи:
- `<!-- md:version 8.5.0 -->` — бейдж версии с иконкой `material/tag-outline`
- `<!-- md:default true -->` — бейдж значения по умолчанию с иконкой `material/water`
- `<!-- md:flag experimental -->` — бейдж экспериментального функционала с иконкой `material/test-tube`
## Правила разработки
### Стиль и форматирование
- Кодировка UTF-8, переносы строк LF
- Отступы: 4 пробела (2 для YAML/YML, табы для Makefile)
- В Markdown-файлах завершающие пробелы не обрезаются
- В остальных файлах — обрезаются
- В конце файла — пустая строка
### Документация
- Язык документации — русский
- Обращение к пользователю на «вы»
- Простой и понятный язык, активный залог
- Каждый документ начинается с frontmatter (YAML с метаданными)
- На странице — один заголовок 1 уровня
- До и после заголовков, абзацев, списков, блоков кода, врезок — пустая строка
- Вложенные уровни списков отступаются на 4 пробела
- Ненумерованные списки начинаются с `-`
- Подробные правила синтаксиса — в скилле `.agents/skills/koda-zensical`
### Отладка
- Для отладки использовать `make site` и проверять вывод на предупреждения
- Debug-страницы (`sandbox.md`, `vscode-icons.md`) не должны попадать в навигацию — раздел `Debug` в `zensical.toml` закомментирован
- Раскомментирование `Debug` выполняется вручную по необходимости
### Контрибуция
Подробные правила — в [CONTRIBUTING.md](CONTRIBUTING.md).
## Лицензия
MIT License
+16 -3
View File
@@ -1,8 +1,21 @@
FROM squidfunk/mkdocs-material AS builder
FROM zensical/zensical:latest AS builder
ENV PYTHONPATH=/docs
COPY . /docs
RUN mkdocs build
RUN zensical build --clean
FROM nginx:alpine AS boilerplate-docs
# LABEL org.opencontainers.image.revision="c76960ef08be04f397b72702eca4166c7b783176"
# LABEL org.opencontainers.image.description="Documentation for our services and products"
# LABEL org.opencontainers.image.url="https://example.com"
# LABEL org.opencontainers.image.vendor="Boilerplate"
# LABEL org.opencontainers.image.documentation="https://example.com"
# LABEL org.opencontainers.image.version="v0.0.46"
# LABEL org.opencontainers.image.created="2026-06-21T18:47:29.228Z"
# LABEL org.opencontainers.image.licenses="MIT"
# LABEL org.opencontainers.image.title="BoilerplateDocs"
# LABEL org.opencontainers.image.source=""
FROM nginx:alpine AS iptv-docs
COPY --from=builder /docs/site /usr/share/nginx/html
WORKDIR /usr/share/nginx/html
USER root
+34 -27
View File
@@ -1,47 +1,54 @@
.DEFAULT_GOAL := help
.PHONY: live site image run help
.PHONY: live site image push run help
## live: Run mkdocs with live-reloading (localhost:3000)
## live = Run zensical with live-reloading on http://localhost:8000
live:
@echo "Wait until container starts and open http://localhost:3000 to see live preview"
@docker run \
--pull always \
@echo "*** Wait until container starts and open http://localhost:8000 to see live preview"
@docker stop boilerplate-docs-dev 2>/dev/null; \
docker run \
--rm \
--interactive \
--tty \
--publish 3000:8000 \
--env PYTHONPATH=/docs \
--publish 8000:8000 \
--volume ${PWD}:/docs \
--name my-project-docs-dev \
squidfunk/mkdocs-material:9.6.20
--name boilerplate-docs-dev \
zensical/zensical:latest
## site: Build local static site
## site = Build a local static site
site:
@echo "Wait until mkdocs finish"
@docker run \
@echo "*** Wait until zensical finish"
@docker stop boilerplate-docs-dev 2>/dev/null; \
docker run \
--pull always \
--rm \
--interactive \
--tty \
--env PYTHONPATH=/docs \
--volume ${PWD}:/docs \
--name my-project-docs-dev \
squidfunk/mkdocs-material:9.6.20 build
--name boilerplate-docs-dev \
zensical/zensical:latest \
build \
--clean
## image: Build docker image
## image = Build a docker image
image:
@docker build \
--tag my-project-docs-dev:latest \
.
@docker build --tag harbor.example.com/boilerplate-docs:latest .
## run: Run docker image (localhost:3001)
## run = Run docker container from image built with `make image` on http://localhost:8001
run:
@echo "Wait until container starts and open http://localhost:3001 to see ready static website"
@docker run \
@echo "*** Wait until container starts and open http://localhost:8001 to see ready static website"
@docker stop boilerplate-docs 2>/dev/null; \
docker run \
--rm \
--publish 3001:80 \
--name my-project-docs-dev \
my-project-docs-dev:latest
--publish 8001:80 \
--name boilerplate-docs \
harbor.example.com/boilerplate-docs:latest
## help: Show this message and exit
## push = Push docker image built with `make image` to harbor.example.com
push:
@docker login harbor.example.com; \
docker push harbor.example.com/boilerplate-docs:latest
## help = Show this message and exit (default)
help: Makefile
@echo "Available recipes:"
@sed -n 's/^##/ /p' $< | column -t -s ':'
@sed -n 's/^##/ /p' $< | column -t -s '='
+53 -6
View File
@@ -1,7 +1,54 @@
# Пример документации к проекту
# Документация к проекту
* `make live` -- запуск в режиме живой перезагрузки для отладки
* `make site` -- генерация статического сайта
* `make image` -- генерация docker-образа
* `make run` -- запуск контейнера из docker-образа
* `make help` -- справка по командам
Бойлерплейт для документации на базе [Zensical](https://zensical.org) — системы документации, построенной на MkDocs Material.
## Возможности
- Live-предпросмотр с автоматической перезагрузкой
- Сборка статического сайта в Docker-образ на базе nginx
- Светлая и тёмная темы оформления
- Расширенный Markdown: врезки, вкладки, гриды, сноски, иконки
- Валидация ссылок и якорей при сборке
- Поддержка сниппетов и переиспользуемых блоков
- Кастомные inline-бейджи через `inline_badges.py`
## Структура проекта
```
content/ — исходные страницы документации (.md)
snippets/ — переиспользуемые блоки markdown
overrides/ — кастомизация темы: иконки, шаблоны, стили
zensical.toml — конфигурация проекта
inline_badges.py — плагин inline-бейджей
Dockerfile — многоэтапная сборка: zensical build → nginx
Makefile — команды для разработки и деплоя
```
## Быстрый старт
### Требования
- [Docker](https://docs.docker.com/get-docker/)
### Команды
| Команда | Описание |
| ------------ | --------------------------------------------------------------- |
| `make live` | Запуск в режиме живой перезагрузки на `http://localhost:8000` |
| `make site` | Генерация статического сайта (с валидацией ссылок и якорей) |
| `make image` | Сборка Docker-образа |
| `make run` | Запуск контейнера на `http://localhost:8001` |
| `make push` | Загрузка Docker-образа в реестр |
| `make help` | Справка по командам (по умолчанию) |
## Разработка
Для локальной отладки используйте `make live` — откройте `http://localhost:8000` после запуска контейнера.
Для проверки сборки без предупреждений используйте `make site`.
Подробности о форматировании и стиле — в [CONTRIBUTING.md](CONTRIBUTING.md).
## Лицензия
MIT License
-130
View File
@@ -1,130 +0,0 @@
---
title: Глоссарий терминов
icon: material/format-text
---
# Глоссарий терминов
Справочник терминов, используемых в документации Koda.
## A
**Agent (Агент)** — режим работы Koda, в котором AI самостоятельно выполняет многошаговые задачи, используя различные инструменты.
**API Key (API-ключ)** — уникальный ключ для доступа к API провайдера моделей (OpenAI, Anthropic и др.).
**Autocomplete (Автодополнение)** — режим автоматического предложения продолжения кода при наборе.
## C
**Chat (Чат)** — режим диалога с AI-моделью для решения задач, объяснения кода и получения рекомендаций.
**Completion** — см. Autocomplete.
**Config (Конфигурация)** — файл настроек Koda (`config.yaml`), определяющий модели, провайдеров и параметры.
**Context (Контекст)** — информация, которую Koda использует для генерации ответов (файлы, код, документация).
**Context Provider (Контекстный провайдер)** — компонент, автоматически добавляющий релевантную информацию в запросы через символ <kbd>@</kbd> (file, code, docs, codebase, diff, terminal и др.). Подробнее в [Контекст-провайдеры](context-providers.md).
## D
**Diff (Дифф)** — разница между двумя версиями файла, показывающая изменения.
## E
**Edit (Редактирование)** — режим изменения выделенного кода по инструкции пользователя.
**Embeddings (Эмбеддинги)** — векторные представления текста для поиска по семантическому сходству.
## F
**FIM (Fill-In-Middle)** — техника автодополнения, когда модель заполняет текст между префиксом и суффиксом.
## I
**Indexing (Индексация)** — процесс анализа и векторизации кодовой базы или документации для быстрого поиска.
## L
**LLM (Large Language Model)** — большая языковая модель, используемая для генерации текста и кода.
## M
**Model (Модель)** — AI-модель, используемая для генерации ответов (GPT-4, Claude, Llama и др.).
**Model Role (Роль модели)** — назначение модели в Koda (chat, edit, agent, autocomplete, embed, rerank).
## P
**Provider (Провайдер)** — сервис, предоставляющий доступ к AI-моделям (OpenAI, Anthropic, Ollama и др.).
**Prompt (Промпт)** — текстовый запрос к AI-модели.
## R
**RAG (Retrieval-Augmented Generation)** — техника генерации ответов с использованием поиска по внешней базе знаний.
**Retrieval (Поиск)** — режим поиска по документации и другим источникам информации.
**Roles (Роли)** — см. Model Role.
## S
**Session (Сессия)** — отдельный диалог в чате Koda со своей историей и контекстом.
**Session History (История сессий)** — список всех предыдущих сессий с возможностью поиска, переключения и удаления.
**Session Metadata (Метаданные сессии)** — информация о сессии: ID, заголовок, дата создания, режим работы, рабочая директория.
**Session Storage (Хранилище сессий)** — место сохранения данных сессий (локальные файлы `~/.koda/sessions/` или серверное хранилище).
**Summarization (Суммаризация)** — процесс сжатия длинной истории диалога в краткое содержание для экономии токенов.
**SummaryMarker (Маркер суммаризации)** — визуальный индикатор в истории чата, показывающий где была применена суммаризация.
**Auto-Summarize (Автосуммаризация)** — автоматическая суммаризация при достижении 75% использования контекста (только Agent режим).
**Skill (Навык)** — переиспользуемый набор инструкций для AI-модели, хранящийся в отдельном файле.
**Slash Command (Slash-команда)** — специальная команда, начинающаяся с <kbd>@</kbd> (например, /share, /commit, /summarize).
## T
**Token (Токен)** — единица измерения длины текста для AI-моделей (примерно ¾ слова).
**Tool (Инструмент)** — действие, которое агент может выполнить (читать файл, редактировать код, запускать команду).
## V
:material-microsoft-visual-studio-code: **VS Code** — Visual Studio Code, среда разработки от Microsoft.
## W
**Workspace (Рабочая область)** — проект или директория, открытая в IDE.
## Ё
**Ёфикация** — использование буквы "ё" вместо "е" в русских текстах документации.
---
## Сокращения
| Сокращение | Расшифровка |
|------------|-------------|
| AI | Artificial Intelligence (Искусственный интеллект) |
| API | Application Programming Interface |
| IDE | Integrated Development Environment |
| LLM | Large Language Model |
| [RAG] | Retrieval-Augmented Generation |
| :material-microsoft-visual-studio-code: VS Code | Visual Studio Code |
| FIM | Fill-In-Middle |
---
## Дополнительные ресурсы
- [Основная документация](README.md)
- [Режимы работы](modes.md)
- [Инструменты агента](agent-tools.md)
+284
View File
@@ -0,0 +1,284 @@
# Песочница
## Мелочёвка
=== "Frontmatter"
```yaml
---
title: My Page
description: Some page description
icon: material/star
tags: [tag1, tag2]
hide: [navigation, toc, path]
status: new
#status: deprecated
#status: beta
---
# My Super-Duper Page
# Markdown content goes here
```
=== "Бейджи"
<!-- md:version 8.5.0 --> <!-- md:default true --> <!-- md:flag experimental -->
=== "Тултипы"
:material-information-outline:{ title="текст подсказки" }
[Hover me 1](https://example.com "I'm first tooltip!")
[Hover me 2][example]
[example]: https://example.com "I'm second tooltip!"
=== "Кнопки"
[Серая кнопка](https://example.com/){ .md-button }
[Синяя кнопка](https://example.com/){ .md-button .md-button--primary }
[:fontawesome-solid-paper-plane: Кнопка серая с иконкой и подсказкой](https://example.com/){ .md-button title="текст подсказки 2" }
[:fontawesome-solid-paper-plane: Кнопка синяя с иконкой](https://example.com/){ .md-button .md-button--primary }
---
=== "Простой блок"
```python
def _render_icon(shortcode: str, md) -> str:
emoji_pattern = md.inlinePatterns.get("emoji")
if emoji_pattern is None:
return escape(shortcode)
```
=== "С аннотациями"
```python
def _render_icon(shortcode: str, md) -> str: #(1)!
emoji_pattern = md.inlinePatterns.get("emoji") #(2)!
if emoji_pattern is None:
return escape(shortcode) #(3)!
```
1. сигнатура функции
2. инициализация переменной
3. возврат результата
=== "С заголовком"
```python title="example.py"
def _render_icon(shortcode: str, md) -> str:
emoji_pattern = md.inlinePatterns.get("emoji")
if emoji_pattern is None:
return escape(shortcode)
```
=== "С нумерацией с 5"
```python linenums="5"
def _render_icon(shortcode: str, md) -> str:
emoji_pattern = md.inlinePatterns.get("emoji")
if emoji_pattern is None:
return escape(shortcode)
```
=== "С выделением"
```python linenums="1" hl_lines="2-5 8 9 22"
def _render_icon(shortcode: str, md) -> str:
try:
emoji_pattern = md.inlinePatterns["emoji"]
except KeyError:
return escape(shortcode)
icon = emoji_pattern.emoji_index["emoji"].get(shortcode)
if icon is None:
return escape(shortcode)
element = emoji_pattern.generator(
emoji_pattern.emoji_index["name"],
shortcode,
None,
None,
shortcode,
"",
icon.get("category", ""),
emoji_pattern.options,
md,
)
return tostring(element, encoding="unicode", method="html")
```
---
## Врезки
=== "Полные"
!!! note "Заголовок статичной врезки"
Содержимое, которое может
быть многострочным
!!! abstract "Заголовок статичной врезки"
Содержимое, которое может
быть многострочным
!!! info "Заголовок статичной врезки"
Содержимое, которое может
быть многострочным
!!! tip "Заголовок статичной врезки"
Содержимое, которое может
быть многострочным
!!! success "Заголовок статичной врезки"
Содержимое, которое может
быть многострочным
!!! question "Заголовок статичной врезки"
Содержимое, которое может
быть многострочным
!!! warning "Заголовок статичной врезки"
Содержимое, которое может
быть многострочным
!!! failure "Заголовок статичной врезки"
Содержимое, которое может
быть многострочным
!!! danger "Заголовок статичной врезки"
Содержимое, которое может
быть многострочным
!!! bug "Заголовок статичной врезки"
Содержимое, которое может
быть многострочным
!!! example "Заголовок статичной врезки"
Содержимое, которое может
быть многострочным
!!! quote "Заголовок статичной врезки"
Содержимое, которое может
быть многострочным
=== "Свёрнутые"
??? note "Заголовок свёрнутой врезки"
Содержимое, которое может
быть многострочным
??? abstract "Заголовок свёрнутой врезки"
Содержимое, которое может
быть многострочным
??? info "Заголовок свёрнутой врезки"
Содержимое, которое может
быть многострочным
??? tip "Заголовок свёрнутой врезки"
Содержимое, которое может
быть многострочным
??? success "Заголовок свёрнутой врезки"
Содержимое, которое может
быть многострочным
??? question "Заголовок свёрнутой врезки"
Содержимое, которое может
быть многострочным
??? warning "Заголовок свёрнутой врезки"
Содержимое, которое может
быть многострочным
??? failure "Заголовок свёрнутой врезки"
Содержимое, которое может
быть многострочным
??? danger "Заголовок свёрнутой врезки"
Содержимое, которое может
быть многострочным
??? bug "Заголовок свёрнутой врезки"
Содержимое, которое может
быть многострочным
??? example "Заголовок свёрнутой врезки"
Содержимое, которое может
быть многострочным
??? quote "Заголовок свёрнутой врезки"
Содержимое, которое может
быть многострочным
=== "Сворачиваемые"
???+ note "Заголовок развёрнутой врезки"
Содержимое, которое может
быть многострочным
???+ abstract "Заголовок развёрнутой врезки"
Содержимое, которое может
быть многострочным
???+ info "Заголовок развёрнутой врезки"
Содержимое, которое может
быть многострочным
???+ tip "Заголовок развёрнутой врезки"
Содержимое, которое может
быть многострочным
???+ success "Заголовок развёрнутой врезки"
Содержимое, которое может
быть многострочным
???+ question "Заголовок развёрнутой врезки"
Содержимое, которое может
быть многострочным
???+ warning "Заголовок развёрнутой врезки"
Содержимое, которое может
быть многострочным
???+ failure "Заголовок развёрнутой врезки"
Содержимое, которое может
быть многострочным
???+ danger "Заголовок развёрнутой врезки"
Содержимое, которое может
быть многострочным
???+ bug "Заголовок развёрнутой врезки"
Содержимое, которое может
быть многострочным
???+ example "Заголовок развёрнутой врезки"
Содержимое, которое может
быть многострочным
???+ quote "Заголовок развёрнутой врезки"
Содержимое, которое может
быть многострочным
=== "Короткие"
!!! note
Дефолтный заголовок
!!! abstract ""
Пустой заголовок
!!! info "Пустое содержимое"
---
-14
View File
@@ -1,14 +0,0 @@
---
title: Теги
icon: material/tag-text
---
# Теги документации
Здесь перечислены все теги, которые встречаются на страницах документации.
Нажмите на ссылку для перехода к странице, которая содержит тег.
---
<!-- material/tags -->
+549 -548
View File
File diff suppressed because it is too large Load Diff
+49
View File
@@ -0,0 +1,49 @@
from __future__ import annotations
import re
from html import escape
from markdown.extensions import Extension
from markdown.preprocessors import Preprocessor
SHORTCODE_RE = re.compile(r"<!--\s*md:(version|default|flag)\s*(.*?)\s*-->", re.I)
class BadgePreprocessor(Preprocessor):
def run(self, lines: list[str]) -> list[str]:
return [SHORTCODE_RE.sub(self._replace, line) for line in lines]
def _replace(self, match: re.Match[str]) -> str:
kind, args = match.groups()
args = args.strip()
if kind == "version":
return _badge(":material-tag-outline:", escape(args))
if kind == "default":
value = escape(args or "none")
return _badge(":material-water:", f"<code>{value}</code>")
if kind == "flag" and args == "experimental":
return _badge(":material-test-tube:")
return match.group(0)
# Формирует HTML-разметку бейджа. Иконки остаются Zensical-шорткодами
# и рендерятся штатным `pymdownx.emoji` на следующем этапе обработки Markdown.
def _badge(icon: str, text: str = "") -> str:
return "".join([
'<span class="mdx-badge">',
f'<span class="mdx-badge__icon">{icon}</span>',
*([f'<span class="mdx-badge__text">{text}</span>'] if text else []),
'</span>',
])
class InlineBadgeExtension(Extension):
def extendMarkdown(self, md):
md.preprocessors.register(BadgePreprocessor(md), "inline_badges", 175)
def makeExtension(**kwargs):
return InlineBadgeExtension(**kwargs)
-142
View File
@@ -1,142 +0,0 @@
site_name: Документация
site_description: Описание проекта и его компонентов
site_author: Иван Иванов
copyright: Иван Иванов &copy; 2026, MIT License
repo_name: Репозиторий
repo_url: https://git.axenov.dev/anthony/mkdocs-boilerplate
edit_uri: src/branch/master/content/
remote_branch: master
docs_dir: ./content
use_directory_urls: false
watch:
- content
- snippets
extra_css:
- css/custom.css
# extra_javascript:
# - https://unpkg.com/ionicons@7.1.0/dist/ionicons/ionicons.js
extra:
homepage: /docs
logo: assets/img/favicon/logo.png
favicon: assets/img/favicon/logo.png
social:
- name: Telegram
icon: simple/telegram
link: https://t.me/
- name: YouTube
icon: simple/youtube
link: https://www.youtube.com/
alternate:
- name: Русский
link: /
lang: ru
- name: English
link: /en/
lang: en
theme:
name: 'material'
language: ru
custom_dir: overrides
features:
- content.action.edit
- content.tabs.link
- navigation.footer
- navigation.indexes
- navigation.path
- navigation.sections
# - navigation.expand
- navigation.tabs
- navigation.top
- navigation.tracking
- search.suggest
- toc.follow
icon:
repo: simple/github
edit: material/pencil
view: material/eye
annotation: material/chevron-right-circle
palette:
# Автотема
- media: "(prefers-color-scheme)"
toggle:
icon: material/brightness-auto
name: Включить тёмную тему
# Тёмная тема
- scheme: slate
media: "(prefers-color-scheme: light)"
accent: teal
primary: black
toggle:
name: Включить светлую тему
icon: material/weather-sunny
# Светлая тема
- scheme: default
media: "(prefers-color-scheme: dark)"
accent: teal
primary: teal
toggle:
name: Предпочесть системную тему
icon: material/weather-night
plugins:
- minify:
minify_html: true
- tags:
listings: true
tags_hierarchy: true
tags_hierarchy_separator: /
tags_name_property: keywords
# shadow: true
export: true
listings_toc: true
- social:
cards_layout_options:
background_color: teal
background_image: null
- search:
separator: '[\s\-\.]+'
# indexing: 'full'
validation:
omitted_files: warn
absolute_links: warn
unrecognized_links: warn
anchors: warn
markdown_extensions:
- admonition
- attr_list
- md_in_html
- footnotes
- pymdownx.details
- pymdownx.superfences
- pymdownx.tasklist:
clickable_checkbox: false
- pymdownx.snippets:
base_path: snippets
# auto_append:
# - abbr.md
- toc:
permalink: true
- pymdownx.tabbed:
alternate_style: true
- pymdownx.emoji:
emoji_index: !!python/name:material.extensions.emoji.twemoji
emoji_generator: !!python/name:material.extensions.emoji.to_svg
options:
custom_icons:
- overrides/.icons
nav:
- index.md
- "Раздел 1":
- part1/page1.md
- part1/page2.md
- "Доп. сведения":
- vscode-icons.md # debug
- glossary.md
- tags.md
+2 -2
View File
@@ -1,4 +1,4 @@
Расположение файла конфигурации:
- :fontawesome-brands-windows: Windows: `%USERPROFILE%/.koda/config.yaml`
- :simple-linux: Linux / :simple-apple: MacOS: `$HOME/.koda/config.yaml`
- :fontawesome-brands-windows: Windows: `%USERPROFILE%/.example/config.yaml`
- :simple-linux: Linux / :simple-apple: MacOS: `$HOME/.example/config.yaml`
+211
View File
@@ -0,0 +1,211 @@
# https://zensical.org/docs/setup/basics
[project]
site_name = "Документация"
site_url = "https://example.com"
site_description = "Описание проекта и его компонентов"
site_author = "Иван Иванов"
copyright = "Иван Иванов &copy; 2026, MIT License"
# copyright = "Иван Иванов &copy; 2026, MIT License | <a href="#__consent">Настройки cookie</a>"
# repo_url = "https://git.axenov.dev/anthony/zensical-boilerplate"
# repo_name = "anthony/zensical-boilerplate"
# edit_uri = "src/branch/master/content/"
docs_dir = "./content"
site_dir = "./site"
use_directory_urls = false
dev_addr = "localhost:8000"
watch = ["content", "snippets"]
extra_css = ["_css/extra.css"]
# extra_javascript = [
# "_js/extra.js",
# "https://unpkg.com/ionicons@7.1.0/dist/ionicons/ionicons.js",
# ]
nav = [
"index.md",
{"Раздел 1" = [
"part1/page1.md",
"part1/page2.md",
]},
# {"Debug" = [
# "vscode-icons.md",
# "sandbox.md",
# ]},
]
[project.validation] # валидация контента при сборке
invalid_links = true # битые ссылки
invalid_link_anchors = true # битые якоря
[project.extra]
homepage = "/index.html" # ссылка на логотипе
generator = false # убрать из футера ссылку на Zensical
# [project.extra.consent] # предупреждение о куках
# title = "Уведомление о сookies"
# description = """
# Мы используем cookie-файлы для улучшения пользовательского опыта и сбора статистики.
# Для получения дополнительной информации вы можете ознакомиться с нашей <a href="basics/legal/cookies.html">Политикой использования cookie-файлов</a>.
# """
# actions = [
# "accept",
# # "reject,
# ]
# [project.extra.analytics.feedback]
# title = "Полезна ли эта страница?"
# [[project.extra.analytics.feedback.ratings]]
# icon = "material/emoticon-happy-outline"
# name = "Да, всё понятно"
# data = 1
# note = "Спасибо за отзыв!"
# [[project.extra.analytics.feedback.ratings]]
# icon = "material/emoticon-sad-outline"
# name = "Нет, нужны уточнения"
# data = 0
# note = "Спасибо за отзыв!"
[[project.extra.social]] # соц. кнопка в футере
name = "Новостной канал в Telegram"
icon = "simple/telegram"
link = "https://t.me/"
[[project.extra.social]] # соц. кнопка в футере
name = "Сообщество в Telegram"
icon = "simple/telegram"
link = "https://t.me/"
[[project.extra.social]] # соц. кнопка в футере
name = "YouTube"
icon = "simple/youtube"
link = "https://www.youtube.com/"
[[project.extra.social]] # соц. кнопка в футере
name = "GitHub"
icon = "fontawesome/brands/git"
link = "https://git.axenov.dev/anthony/zensical-boilerplate"
[project.extra.status]
beta = "Нестабильный функционал"
[project.theme] # общие настройки темы
custom_dir = "./overrides"
language = "ru"
logo = "/_assets/logo-mid.png" # относительно docs_dir
# favicon = "/_assets/favicon-32x32.png" # относительно docs_dir
features = [
# "header.autohide", # скрывать заголовок при скролле
"content.code.annotate",
"content.code.copy",
"content.code.select",
"content.footnote.tooltips",
"content.tabs.link",
"content.tooltips",
# "navigation.instant",
# "navigation.instant.prefetch",
# "navigation.instant.progress",
"navigation.tabs", # 1 уровень навигации превращаются в табы в шапке
# "navigation.tabs.sticky", # не скрывать табы под заголовком при скролле
"navigation.sections", # заголовки секций меню сворачиваются или статичны
"navigation.tracking", # подстановка якорей страницы в урлу при скролле
# "navigation.expand", # развёрнутые подменю по умолчанию
"navigation.path", # хлебные крошки над H1 страницы
"navigation.indexes", # если есть index.md, то пункт меню разворачиваблен и открывает свой index.md
"navigation.footer", # прошлый/следующий документ в футере
"navigation.top", # кнопка возврата наверх
"toc.follow", # подсветка загловков содержания при скролле
"search.highlight", # подсвечивать поисковый запрос на странице при переходе из поиска
# "content.action.edit", # редактирование страницы в repo_url
# "content.action.view", # исходник страницы в repo_url
]
[project.theme.font]
text = "Inter"
code = "Jetbrains Mono"
[[project.theme.palette]] # Светлая тема
media = "(prefers-color-scheme: light)"
scheme = "default"
# primary = "white"
accent = "teal"
toggle.icon = "lucide/moon"
toggle.name = "Включить тёмную тему"
[[project.theme.palette]] # Тёмная тема
media = "(prefers-color-scheme: dark)"
scheme = "slate"
# primary = "black"
accent = "teal"
toggle.icon = "lucide/sun"
toggle.name = "Включить светлую тему"
[project.theme.icon]
repo = "fontawesome/brands/github"
edit = "material/pencil"
view = "material/eye"
[project.theme.icon.tag]
default = "lucide/hash"
html = "fontawesome/brands/html5"
js = "fontawesome/brands/js"
css = "fontawesome/brands/css3"
vscode = "material/microsoft-visual-studio-code"
intellij = "simple/jetbrains"
jetbrains = "simple/jetbrains"
cli = "material/console"
brain = "material/brain"
[project.extra.tags]
HTML5 = "html"
JavaScript = "js"
CSS = "css"
VSCode = "vscode"
"VS Code" = "vscode"
IntelliJ = "intellij"
JetBrains = "jetbrains"
CLI = "cli"
"модель" = "brain"
"модели" = "brain"
"ии" = "brain"
AI = "brain"
LLM = "brain"
[project.markdown_extensions.pymdownx.highlight]
anchor_linenums = true
pygments_lang_class = true
[project.markdown_extensions.pymdownx.emoji]
emoji_index = "zensical.extensions.emoji.twemoji"
emoji_generator = "zensical.extensions.emoji.to_svg"
options.custom_icons = ["./overrides/.icons"]
[project.markdown_extensions.pymdownx.snippets]
base_path = "./snippets"
[project.markdown_extensions.pymdownx.tabbed]
alternate_style = true
[project.markdown_extensions.toc]
permalink = true
# title = "На этой странице:"
[project.markdown_extensions.abbr]
[project.markdown_extensions.admonition]
[project.markdown_extensions.attr_list]
[project.markdown_extensions.def_list]
[project.markdown_extensions.footnotes]
[project.markdown_extensions.md_in_html]
[project.markdown_extensions.inline_badges]
[project.markdown_extensions.pymdownx.inlinehilite]
[project.markdown_extensions.pymdownx.superfences]
# [project.markdown_extensions.pymdownx.keys]
[project.markdown_extensions.pymdownx.details]
[project.markdown_extensions.pymdownx.caret]
[project.markdown_extensions.pymdownx.mark]
[project.markdown_extensions.pymdownx.tilde]