Монорепозиторий для сайтов и shared-пакетов Шелково.
Это эксперимент, где в проекте не написано ни строчки кода руками. Руками редко, но правится только markdown-документы.
apps/
www/ # основное Astro-приложение kpshelkovo.online, включая /815/compare
media/ # статическая 404 для media.kpshelkovo.online
packages/
ui/ # shared styles / UI primitives
url/
format/
geo/
docs/ # документация и дизайн-гайды
ops/ # nginx и deploy-конфиги
Установка окружения разработки из чистого checkout:
pnpm agents:setupНужны Git, Node.js 24+ и версия pnpm из packageManager. Подробности восстановления skills, генерации OpenSpec, проверок, обновления и отката — в руководстве разработчика. После изменения интеграции перезапусти OpenCode.
Работа начинается с обычного запроса. Агент выбирает OpenSpec или короткий путь по разделу «Жизненный цикл изменений» — это единый источник политики проекта.
# основной сайт на :4321 и media app на :4322
pnpm dev
# проверки
pnpm lint
pnpm typecheck
pnpm test
# сборка
pnpm builddist/www— основной сайтkpshelkovo.onlinedist/media— статическая 404 дляmedia.kpshelkovo.online
kpshelkovo.onlineполучает содержимоеdist/wwwmedia.kpshelkovo.onlineполучает error app изdist/media, а остальные запросы проксирует в S3- старый compare-домен обслуживается nginx-редиректами
- nginx-конфиги лежат в
ops/nginx/
Политика «только новые индексируемые страницы» и её причины — в ADR-027. Порядок production-публикации задаёт CI/CD workflow, подготовку ключа и отправку выполняет scripts/indexnow.ts.
- Build сохраняет URL после sitemap-фильтров в приватный
apps/www/dist/indexnow-urls.json. Он формируется из того же прохода сериализации, что и sitemap, остаётся вне публичногоdist/wwwи не требует обратного чтения XML. - Из repository secret
INDEXNOW_KEYкомандаprepareсоздаёт UTF-8 файлdist/www/{key}.txt. Helper проверяет формат и зарезервированные имена, не перезаписывает уже существующий файл. Ключ не коммитят; при ротации меняют secret, следующий deploy публикует новый файл и удаляет старый черезrsync --delete. - До синхронизации dry-run
rsyncс теми же checksum, delete и filter options записывает itemized changes. Workflow дописывает их вINDEXNOW_PENDING_PATHв домашнем каталоге deploy-пользователя на VPS, вне web root, и забирает накопленный файл на runner. Сохранение до deploy удерживает маркер нового файла при сбое и повторном запуске. - После публикации сайта команда
submitвыбирает только новые обычные файлыindex.htmlс rsync-маркером<f+++++++++, пересекает их URL с манифестом текущей сборки и удаляет дубли. Изменения, удаления, assets и отсутствующие в манифесте URL, включая исключённыеnoindex-страницы, не отправляются. Существующая страница, ставшая индексируемой, нового файла не создаёт. submitзагружает публичныйhttps://kpshelkovo.online/{key}.txtбез кеша и редиректов и проверяет точное содержимое. Проверка выполняется и при пустом списке URL; в этом случае POST не нужен. Непустой список отправляется в IndexNow пачками в пределах лимита helper-а; только HTTP 200 и 202 считаются успешными ответами. После успешного завершения всей команды workflow удаляет pending-файл на VPS.
- При ошибке публичного ключа, сети или ответа IndexNow job завершается ошибкой. Уже опубликованный сайт остаётся доступен, pending сохраняется. Исправь причину по логу шага и повтори deploy job; не удаляй pending вручную ради зелёного статуса.
- Повтор добавляет новый dry-run к сохранённому списку и снова фильтрует его по текущему sitemap-манифесту. Уже опубликованные новые страницы сохраняют исходный маркер добавления; URL, переставшие входить в индексируемый набор, отсеиваются.
- Если одна из пачек принята, а следующая завершилась ошибкой, pending остаётся целиком. Повторная отправка уже принятой пачки допустима; отдельного журнала подтверждений по пачкам нет. При успехе сводка job показывает отправленные URL и количество принятых запросов.
Точные пути и rsync-параметры принадлежат workflow, формат ключа, endpoint, лимит пачки и таймаут — helper-у. Раздачу key-файла как text/plain с Cache-Control: no-store задаёт nginx-конфиг. Отсутствие ключа останавливает подготовку до публикации; доступность его публичной копии проверяется после неё. Справка по настройке secret — GitHub Actions.
Флаг analytics.metrika.enabled в конфиге аналитики управляет подключением счётчика только при сборке. Сейчас Метрика временно выключена (false). Чтобы вернуть её, установи true, выполни pnpm build и опубликуй новую сборку через обычный deploy. Для отключения установи false и повтори сборку и публикацию.
Клиентский runtime не читает конфиг. При отключении готовый HTML не содержит маркера счётчика и noscript-пикселя; загрузка Метрики, просмотры и цели не запускаются. В dev Метрика всегда выключена; LIGHTHOUSE_DISABLE_ANALYTICS=true принудительно выключает её и при enabled: true.
Часть данных проекта обновляет Hermes Agent, который авторизуется через GitHub App kpshelkovo-hermes-agent. Агент создаёт отдельную ветку, запускает проверки и предлагает изменения через pull request — напрямую в master данные не записываются.
- www-specific правила:
apps/www/AGENTS.md - дизайн-гайд и визуальные правила:
docs/design/design-code-shelkovo.md