Skip to content

Commit 0cd53d9

Browse files
committed
Initial commit
0 parents  commit 0cd53d9

149 files changed

Lines changed: 16436 additions & 0 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.claude/skills/seo-sync/SKILL.md

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
---
2+
name: seo-sync
3+
description: Синхронизирует public/sitemap.xml, public/robots.txt и public/llms.txt с реальным содержимым сайта. Запускать при добавлении/удалении страниц или статей. Триггеры: «обнови sitemap», «обнови SEO-файлы», «синхронизируй llms.txt», «добавь статью в sitemap», «seo sync», «обнови мета-файлы».
4+
user_invocable: true
5+
---
6+
7+
# SEO Sync — процедура синхронизации SEO-файлов
8+
9+
Синхронизирует `public/sitemap.xml`, `public/robots.txt` и `public/llms.txt` с актуальным содержимым сайта.
10+
11+
**Базовый URL:** `https://roman-purtow.ru`
12+
13+
---
14+
15+
## Шаг 1: Сбор данных
16+
17+
1. Прочитать `src/data/articles.ts` — массив `articles` со всеми статьями (title, href, date, dateISO, sourceName).
18+
2. Просканировать `src/pages/` через glob (`src/pages/**/*.astro`) — определить все существующие страницы.
19+
3. Классифицировать:
20+
- **Публичные**: `index.astro` + `articles/*.astro`
21+
- **Скрытые**: `offer/*.astro` + любые другие директории в `src/pages/`, не входящие в `articles/`
22+
4. Прочитать текущий `public/robots.txt` — сохранить существующие Disallow-правила для `/glavred-calls/` и `/helpa-research/` (исторические пути, закрытые по решению пользователя, не имеют соответствующих страниц в `src/pages/`).
23+
24+
---
25+
26+
## Шаг 2: Генерация `public/sitemap.xml`
27+
28+
Перезаписать файл полностью. Формат:
29+
30+
```xml
31+
<?xml version="1.0" encoding="UTF-8"?>
32+
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
33+
<url>
34+
<loc>https://roman-purtow.ru/</loc>
35+
<lastmod>YYYY-MM-DD</lastmod>
36+
<priority>1.0</priority>
37+
</url>
38+
<!-- Для каждой статьи из src/pages/articles/*.astro -->
39+
<url>
40+
<loc>https://roman-purtow.ru/articles/{slug}/</loc>
41+
<lastmod>YYYY-MM-DD</lastmod>
42+
<priority>0.8</priority>
43+
</url>
44+
</urlset>
45+
```
46+
47+
Правила:
48+
- `lastmod` — текущая дата в формате `YYYY-MM-DD`
49+
- Статьи сортировать по имени файла (алфавитно)
50+
- **Не включать** страницы из `offer/` и других скрытых директорий
51+
52+
---
53+
54+
## Шаг 3: Генерация `public/robots.txt`
55+
56+
Перезаписать файл полностью. Формат:
57+
58+
```
59+
User-agent: *
60+
Allow: /
61+
Disallow: /glavred-calls/
62+
Disallow: /helpa-research/
63+
Disallow: /offer/
64+
```
65+
66+
Правила:
67+
- `Disallow:` для каждой скрытой директории в `src/pages/` (всё кроме `articles/`): например `/offer/`
68+
- **Всегда сохранять** исторические Disallow: `/glavred-calls/`, `/helpa-research/`
69+
- Если обнаружены новые скрытые директории (помимо `offer/`), добавить Disallow и для них
70+
- Завершить пустой строкой и строкой `Sitemap: https://roman-purtow.ru/sitemap.xml`
71+
72+
---
73+
74+
## Шаг 4: Обновление `public/llms.txt`
75+
76+
**Не перезаписывать весь файл** — обновить только секцию `## Статьи`.
77+
78+
1. Прочитать `public/llms.txt`.
79+
2. Из `src/data/articles.ts` собрать полный список статей **в порядке массива**.
80+
3. Формат каждой записи:
81+
- Внешние (href начинается с `https://`): `- [title](href) (date, sourceName)`
82+
- Внутренние (href начинается с `/`): `- [title](https://roman-purtow.ru{href}) (date, sourceName)`
83+
4. В title заменить `\u00A0` (неразрывный пробел) на обычный пробел.
84+
5. Заменить содержимое от `## Статьи\n\n` до конца файла (или до следующей секции `## `).
85+
86+
---
87+
88+
## Шаг 5: Проверка
89+
90+
1. Запустить `npm run build`.
91+
2. Убедиться, что `dist/sitemap.xml`, `dist/robots.txt`, `dist/llms.txt` существуют и содержат актуальные данные.
92+
3. Сообщить пользователю итог: сколько статей в sitemap, сколько Disallow-правил в robots.txt, сколько записей в llms.txt.
93+
94+
---
95+
96+
## Ключевые файлы
97+
98+
| Файл | Роль |
99+
|---|---|
100+
| `src/data/articles.ts` | Массив всех статей с title, href, date, dateISO, sourceName |
101+
| `src/pages/**/*.astro` | Все страницы сайта (glob-сканирование) |
102+
| `public/sitemap.xml` | Целевой файл — перезаписывается полностью |
103+
| `public/robots.txt` | Целевой файл — перезаписывается полностью |
104+
| `public/llms.txt` | Целевой файл — обновляется только секция «Статьи» |

.github/workflows/deploy.yml

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
name: Deploy to GitHub Pages
2+
3+
on:
4+
push:
5+
branches: [main]
6+
workflow_dispatch:
7+
8+
permissions:
9+
contents: read
10+
pages: write
11+
id-token: write
12+
13+
concurrency:
14+
group: pages
15+
cancel-in-progress: false
16+
17+
jobs:
18+
build:
19+
runs-on: ubuntu-latest
20+
steps:
21+
- uses: actions/checkout@v4
22+
- uses: actions/setup-node@v4
23+
with:
24+
node-version: 22
25+
cache: npm
26+
- run: npm ci
27+
- run: npm run build
28+
- uses: actions/upload-pages-artifact@v3
29+
with:
30+
path: dist/
31+
32+
deploy:
33+
needs: build
34+
runs-on: ubuntu-latest
35+
environment:
36+
name: github-pages
37+
url: ${{ steps.deployment.outputs.page_url }}
38+
steps:
39+
- id: deployment
40+
uses: actions/deploy-pages@v4

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
node_modules/
2+
dist/
3+
.astro/

.mcp.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"mcpServers": {
3+
"chrome-devtools": {
4+
"command": "cmd",
5+
"args": ["/c", "npx", "-y", "chrome-devtools-mcp@latest"]
6+
}
7+
}
8+
}

CLAUDE.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Инструкции для Claude Code
2+
3+
---
4+
5+
## RULE: Сборка (Astro)
6+
7+
Пайплайн: `src/**/*.astro` + `src/styles/input.css` → Astro build → `dist/`
8+
9+
**Команды:**
10+
```bash
11+
npm run dev # Dev-сервер с HMR
12+
npm run build # Продакшн-сборка в dist/
13+
npm run preview # Превью продакшн-билда
14+
```
15+
16+
**Структура:**
17+
- `src/components/` — Astro-компоненты (BentoCard, CardProfile, CornerNav и др.)
18+
- `src/layouts/` — layouts (Base, Article)
19+
- `src/pages/` — страницы (index.astro, articles/*.astro)
20+
- `src/data/cards.ts` — данные карточек
21+
- `src/styles/input.css` — исходный Tailwind CSS
22+
- `public/` — статические ассеты (images, videos, js/app.js, CNAME и др.)
23+
24+
**Важно:**
25+
- `dist/` — результат сборки, **не коммитится** (в .gitignore)
26+
- CSS обрабатывается через `@tailwindcss/vite` плагин автоматически
27+
- Деплой через GitHub Actions → GitHub Pages из `dist/`

README.md

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
# Роман Пуртов — Agentic Engineer & маркетолог & дизайнер
2+
3+
<img src="https://roman-purtow.ru/images/roman.jpg" alt="Роман Пуртов" width="120" height="120" style="border-radius: 50%;" />
4+
5+
Сайт-визитка с портфолио, статьями, контактами и ссылками на соцсети.
6+
7+
---
8+
9+
## Технологии
10+
11+
[Astro 5](https://astro.build/) · [Tailwind CSS v4](https://tailwindcss.com/) · [Lenis](https://lenis.darkroom.engineering/) (smooth scroll) · GitHub Actions (CI/CD)
12+
13+
## Разработка
14+
15+
**Быстрый старт:**
16+
17+
```bash
18+
npm install && npm run dev
19+
```
20+
21+
**Все команды:**
22+
23+
```bash
24+
npm install # установка зависимостей
25+
npm run dev # dev-сервер с HMR
26+
npm run build # продакшн-сборка в dist/
27+
npm run preview # превью продакшн-билда
28+
```
29+
30+
## Структура
31+
32+
```
33+
src/
34+
components/ # Astro-компоненты (BentoCard, CardProfile, CornerNav и др.)
35+
layouts/ # Base, Article
36+
pages/ # index.astro, articles/*.astro
37+
data/ # cards.ts, articles.ts — данные карточек и статей
38+
styles/ # input.css — Tailwind CSS
39+
public/
40+
js/ # app.js, i18n-articles.js — клиентские скрипты
41+
images/ # Изображения
42+
videos/ # Фоновое видео
43+
.github/
44+
workflows/ # deploy.yml — автодеплой на GitHub Pages
45+
dist/ # Результат сборки (не коммитится)
46+
```
47+
48+
## Возможности
49+
50+
- Bento-grid из 13 карточек (работа, контакты, соцсети, проекты)
51+
- Переключение языков (RU/EN) с полной локализацией
52+
- Тёмная / светлая тема
53+
- Фоновое видео
54+
- Адаптивный дизайн
55+
- Smooth scroll (Lenis)
56+
- Секция статей и кейсов
57+
- Футер с реквизитами ИП
58+
- Автодеплой через GitHub Actions → GitHub Pages
59+
60+
---
61+
62+
## Контакты
63+
64+
- **Телефон:** +7 952 679-77-76
65+
- **Почта:** [rytrycon@gmail.com](mailto:rytrycon@gmail.com)
66+
- **Telegram:** [@roman_purtow](https://t.me/roman_purtow)
67+
- **MAX:** [+7 952 679-77-76](https://max.ru/u/f9LHodD0cOLZogeP1J-Ng0ZKPflLiTQQTDGVkS9WbDT82Up2fxhxm9GxuQU)
68+
- **Instagram:** [@roman.purtow](https://instagram.com/roman.purtow)
69+
- **ВКонтакте:** [@roman_purtow](https://vk.com/roman_purtow)
70+
- **YouTube:** [@roman-purtow](https://www.youtube.com/@roman-purtow)
71+
- **GitHub:** [@baslie](https://github.com/baslie)

astro.config.mjs

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import { defineConfig } from 'astro/config';
2+
import tailwindcss from '@tailwindcss/vite';
3+
import sitemap from '@astrojs/sitemap';
4+
import { articles } from './src/data/articles/index';
5+
6+
const EXCLUDED_PREFIXES = ['/archive/', '/glavred-calls/', '/helpa-research/'];
7+
8+
const articleLastmod = new Map(
9+
articles.map((a) => [a.slug, a.dateModified || a.datePublished]),
10+
);
11+
12+
export default defineConfig({
13+
site: 'https://roman-purtow.ru',
14+
i18n: {
15+
defaultLocale: 'ru',
16+
locales: ['ru', 'en'],
17+
routing: {
18+
prefixDefaultLocale: false,
19+
redirectToDefaultLocale: false,
20+
},
21+
},
22+
redirects: {
23+
'/offer': '/offer/1',
24+
},
25+
integrations: [
26+
sitemap({
27+
i18n: {
28+
defaultLocale: 'ru',
29+
locales: { ru: 'ru-RU', en: 'en-US' },
30+
},
31+
filter: (page) => {
32+
const url = new URL(page);
33+
return !EXCLUDED_PREFIXES.some((prefix) => url.pathname.startsWith(prefix));
34+
},
35+
serialize: (item) => {
36+
const url = new URL(item.url);
37+
if (url.pathname === '/' || url.pathname === '/en/') {
38+
item.priority = 1.0;
39+
item.changefreq = 'monthly';
40+
} else if (url.pathname.startsWith('/offer/')) {
41+
item.priority = 0.8;
42+
item.changefreq = 'monthly';
43+
} else if (
44+
url.pathname.startsWith('/articles/') ||
45+
url.pathname.startsWith('/en/articles/')
46+
) {
47+
item.priority = 0.8;
48+
item.changefreq = 'yearly';
49+
const slug = url.pathname.replace(/^\/(en\/)?articles\//, '').replace(/\/$/, '');
50+
const lastmod = articleLastmod.get(slug);
51+
if (lastmod) {
52+
item.lastmod = lastmod;
53+
}
54+
}
55+
return item;
56+
},
57+
}),
58+
],
59+
vite: {
60+
plugins: [tailwindcss()]
61+
}
62+
});

0 commit comments

Comments
 (0)