@dzhechkov/keysarium 1.4.0 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +50 -3
- package/bin/cli.js +0 -0
- package/package.json +5 -3
- package/templates/.claude/commands/analyst-manual.md +38 -0
- package/templates/.claude/commands/casarium.md +55 -4
- package/templates/.claude/commands/feature-adr.md +8 -0
- package/templates/.claude/rules/trust-tiers.md +5 -0
- package/templates/.claude/shards/feature-adr.shard.md +64 -10
- package/templates/.claude/shards/phase-ai-factory.shard.md +109 -0
- package/templates/.claude/skills/ai-factory-mapper/README.md +90 -0
- package/templates/.claude/skills/ai-factory-mapper/SKILL.md +309 -0
- package/templates/.claude/skills/ai-factory-mapper/assets/report-template.md +123 -0
- package/templates/.claude/skills/ai-factory-mapper/references/catalog.md +230 -0
- package/templates/.claude/skills/ai-factory-mapper/references/coverage-formula.md +219 -0
- package/templates/.claude/skills/ai-factory-mapper/references/decomposition-checklist.md +183 -0
- package/templates/.claude/skills/ai-factory-mapper/references/pattern-library.md +312 -0
- package/templates/.claude/skills/ai-factory-mapper/scripts/build_docx_report.js +423 -0
- package/templates/.claude/skills/analyst-manual-full/SKILL.md +286 -0
- package/templates/.claude/skills/edu-site-generator/SKILL.md +254 -0
- package/templates/.claude/skills/edu-site-generator/examples/sample-course-structure.md +116 -0
- package/templates/.claude/skills/edu-site-generator/modules/00-content-analysis.md +84 -0
- package/templates/.claude/skills/edu-site-generator/modules/01-course-structure.md +75 -0
- package/templates/.claude/skills/edu-site-generator/modules/02-data-generation.md +186 -0
- package/templates/.claude/skills/edu-site-generator/modules/03-scaffold.md +249 -0
- package/templates/.claude/skills/edu-site-generator/modules/04-components.md +130 -0
- package/templates/.claude/skills/edu-site-generator/modules/05-gamification.md +163 -0
- package/templates/.claude/skills/edu-site-generator/modules/06-deploy.md +88 -0
- package/templates/.claude/skills/edu-site-generator/modules/07-verification.md +97 -0
- package/templates/.claude/skills/edu-site-generator/references/component-templates.md +436 -0
- package/templates/.claude/skills/edu-site-generator/references/data-schemas.md +164 -0
- package/templates/.claude/skills/edu-site-generator/references/exercise-catalog.md +110 -0
- package/templates/.claude/skills/edu-site-generator/references/tech-stack.md +69 -0
- package/templates/.claude/skills/feature-adr/SKILL.md +245 -59
- package/templates/.claude/skills/feature-adr/modules/03-adr.md +43 -0
- package/templates/.claude/skills/feature-adr/modules/03.5-ideation-swarm.md +180 -0
- package/templates/.claude/skills/feature-adr/modules/06-implementation-plan.md +56 -7
- package/templates/.claude/skills/feature-adr/modules/08-qe.md +87 -23
- package/templates/.claude/skills/feature-adr/modules/09-fleet-qe.md +305 -0
- package/templates/.claude/skills/feature-adr/references/agentic-qe/README.md +143 -0
- package/templates/.claude/skills/feature-adr/references/agentic-qe/brutal-honesty-review.md +240 -0
- package/templates/.claude/skills/feature-adr/references/agentic-qe/chaos-engineering-resilience.md +163 -0
- package/templates/.claude/skills/feature-adr/references/agentic-qe/code-goal-planner.md +446 -0
- package/templates/.claude/skills/feature-adr/references/agentic-qe/enterprise-integration-testing.md +111 -0
- package/templates/.claude/skills/feature-adr/references/agentic-qe/mutation-testing.md +236 -0
- package/templates/.claude/skills/feature-adr/references/agentic-qe/performance-testing.md +315 -0
- package/templates/.claude/skills/feature-adr/references/agentic-qe/qcsd-ideation-swarm.md +126 -0
- package/templates/.claude/skills/feature-adr/references/agentic-qe/qcsd-production-swarm.md +108 -0
- package/templates/.claude/skills/feature-adr/references/agentic-qe/qe-coverage-analysis.md +193 -0
- package/templates/.claude/skills/feature-adr/references/agentic-qe/qe-requirements-validation.md +254 -0
- package/templates/.claude/skills/feature-adr/references/agentic-qe/regression-testing.md +233 -0
- package/templates/.claude/skills/feature-adr/references/agentic-qe/risk-based-testing.md +212 -0
- package/templates/.claude/skills/feature-adr/references/agentic-qe/security-testing.md +311 -0
- package/templates/.claude/skills/feature-adr/references/agentic-qe/shift-left-testing.md +231 -0
- package/templates/.claude/skills/feature-adr/references/agentic-qe/tdd-london-chicago.md +249 -0
- package/templates/.claude/skills/transcript-site-generator/SKILL.md +287 -0
- package/templates/.claude/skills/transcript-site-generator/examples/sample-text-only-site.md +123 -0
- package/templates/.claude/skills/transcript-site-generator/examples/sample-transcript-site.md +134 -0
- package/templates/.claude/skills/transcript-site-generator/modules/00-input-analysis.md +132 -0
- package/templates/.claude/skills/transcript-site-generator/modules/01-content-parsing.md +117 -0
- package/templates/.claude/skills/transcript-site-generator/modules/02-site-generation.md +293 -0
- package/templates/.claude/skills/transcript-site-generator/modules/03-interactivity.md +406 -0
- package/templates/.claude/skills/transcript-site-generator/modules/04-deploy.md +130 -0
- package/templates/.claude/skills/transcript-site-generator/modules/05-verification.md +155 -0
- package/templates/.claude/skills/transcript-site-generator/references/component-catalog.md +86 -0
- package/templates/.claude/skills/transcript-site-generator/references/data-schemas.md +123 -0
- package/templates/.claude/skills/transcript-site-generator/references/tech-stack.md +132 -0
- package/templates/CLAUDE.md +9 -2
- package/templates/docs/edu-site-generator/01-deployment-guide.md +911 -0
- package/templates/docs/edu-site-generator/02-admin-guide.md +901 -0
- package/templates/docs/edu-site-generator/03-user-guide.md +1008 -0
- package/templates/docs/edu-site-generator/04-infrastructure-requirements.md +489 -0
- package/templates/docs/edu-site-generator/05-architecture.md +902 -0
- package/templates/docs/edu-site-generator/06-user-flows.md +759 -0
- package/templates/docs/transcript-site-generator/01-deployment-guide.md +1042 -0
- package/templates/docs/transcript-site-generator/02-admin-guide.md +918 -0
- package/templates/docs/transcript-site-generator/03-user-guide.md +925 -0
- package/templates/docs/transcript-site-generator/04-infrastructure-requirements.md +482 -0
- package/templates/docs/transcript-site-generator/05-architecture.md +1068 -0
- package/templates/docs/transcript-site-generator/06-user-flows.md +855 -0
|
@@ -0,0 +1,918 @@
|
|
|
1
|
+
# Руководство администратора @dzhechkov/skills-transcript-site
|
|
2
|
+
|
|
3
|
+
Это руководство описывает управление, настройку и обслуживание Transcript Site skill pack. Предназначено для администраторов, которые управляют компонентами скилла, настраивают пайплайн генерации, конфигурируют языковые настройки, SEO и безопасность.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Содержание
|
|
8
|
+
|
|
9
|
+
1. [Управление компонентами скилла](#1-управление-компонентами-скилла)
|
|
10
|
+
2. [Конфигурация пайплайна (6 шагов)](#2-конфигурация-пайплайна-6-шагов)
|
|
11
|
+
3. [Языковая конфигурация](#3-языковая-конфигурация)
|
|
12
|
+
4. [SEO конфигурация](#4-seo-конфигурация)
|
|
13
|
+
5. [YouTube интеграция](#5-youtube-интеграция)
|
|
14
|
+
6. [Управление выходной директорией](#6-управление-выходной-директорией)
|
|
15
|
+
7. [Tailwind CDN vs self-hosted](#7-tailwind-cdn-vs-self-hosted)
|
|
16
|
+
8. [Dark mode конфигурация](#8-dark-mode-конфигурация)
|
|
17
|
+
9. [Print stylesheet управление](#9-print-stylesheet-управление)
|
|
18
|
+
10. [Производительность и большие транскрипты](#10-производительность-и-большие-транскрипты)
|
|
19
|
+
11. [Безопасность](#11-безопасность)
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## 1. Управление компонентами скилла
|
|
24
|
+
|
|
25
|
+
### 1.1. Текущие компоненты
|
|
26
|
+
|
|
27
|
+
После установки Transcript Site включает следующие компоненты:
|
|
28
|
+
|
|
29
|
+
| Компонент | Путь | Назначение |
|
|
30
|
+
|-----------|------|------------|
|
|
31
|
+
| Skill | `.claude/skills/transcript-site-generator/` | Основной оркестратор: загружается командами |
|
|
32
|
+
| SKILL.md | `.claude/skills/transcript-site-generator/SKILL.md` | Точка входа, документирует все шесть модулей |
|
|
33
|
+
| Модуль Input Analysis | `.claude/skills/transcript-site-generator/modules/input-analysis.md` | Шаг 1: определение source type, извлечение метаданных |
|
|
34
|
+
| Модуль Content Parsing | `.claude/skills/transcript-site-generator/modules/content-parsing.md` | Шаг 2: разбиение на секции, определение спикеров |
|
|
35
|
+
| Модуль Site Generation | `.claude/skills/transcript-site-generator/modules/site-generation.md` | Шаг 3: генерация HTML, Tailwind, SEO meta |
|
|
36
|
+
| Модуль Interactivity | `.claude/skills/transcript-site-generator/modules/interactivity.md` | Шаг 4: search, TOC, dark mode, YouTube sync |
|
|
37
|
+
| Модуль Deploy | `.claude/skills/transcript-site-generator/modules/deploy.md` | Шаг 5: GitHub Pages, robots.txt, sitemap |
|
|
38
|
+
| Модуль Verification | `.claude/skills/transcript-site-generator/modules/verification.md` | Шаг 6: HTML/JS/CSS/SEO/a11y проверки |
|
|
39
|
+
| HTML шаблон | `.claude/skills/transcript-site-generator/references/html-template.md` | Базовая структура HTML |
|
|
40
|
+
| Tailwind конфиг | `.claude/skills/transcript-site-generator/references/tailwind-config.md` | Конфигурация Tailwind Play CDN |
|
|
41
|
+
| SEO чеклист | `.claude/skills/transcript-site-generator/references/seo-checklist.md` | Полный чеклист SEO-тегов |
|
|
42
|
+
| A11y руководство | `.claude/skills/transcript-site-generator/references/accessibility-guide.md` | Чеклист доступности |
|
|
43
|
+
| Пример подкаста | `.claude/skills/transcript-site-generator/examples/sample-podcast.md` | Пример: подкаст |
|
|
44
|
+
| Пример YouTube | `.claude/skills/transcript-site-generator/examples/sample-youtube.md` | Пример: YouTube видео |
|
|
45
|
+
| Команда /transcript-site | `.claude/commands/transcript-site.md` | Полный пайплайн |
|
|
46
|
+
| Команда /transcript-site-generate | `.claude/commands/transcript-site-generate.md` | Только генерация HTML |
|
|
47
|
+
| Команда /transcript-site-deploy | `.claude/commands/transcript-site-deploy.md` | Только деплой конфигурация |
|
|
48
|
+
| Правила качества | `.claude/rules/transcript-site-quality.md` | Автоматически применяемые правила |
|
|
49
|
+
|
|
50
|
+
### 1.2. Проверка компонентов
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
# Полная диагностика установки
|
|
54
|
+
npx @dzhechkov/skills-transcript-site doctor
|
|
55
|
+
|
|
56
|
+
# Листинг установленных файлов
|
|
57
|
+
npx @dzhechkov/skills-transcript-site list
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### 1.3. Обновление отдельных компонентов
|
|
61
|
+
|
|
62
|
+
Команда `update` обновляет все компоненты из последней версии пакета. Для обновления отдельного файла:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
# Шаг 1: просмотрите diff без применения
|
|
66
|
+
npx @dzhechkov/skills-transcript-site update --dry-run
|
|
67
|
+
|
|
68
|
+
# Шаг 2: скопируйте нужный файл из шаблонов пакета вручную
|
|
69
|
+
node -e "console.log(require.resolve('@dzhechkov/skills-transcript-site/package.json').replace('package.json', 'templates/'))"
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### 1.4. Добавление пользовательских расширений
|
|
73
|
+
|
|
74
|
+
Для добавления собственных ссылочных материалов без изменения базовых файлов пакета создайте файлы с собственными именами:
|
|
75
|
+
|
|
76
|
+
```
|
|
77
|
+
.claude/skills/transcript-site-generator/references/
|
|
78
|
+
+-- html-template.md <-- базовый (не изменять)
|
|
79
|
+
+-- tailwind-config.md <-- базовый
|
|
80
|
+
+-- seo-checklist.md <-- базовый
|
|
81
|
+
+-- accessibility-guide.md <-- базовый
|
|
82
|
+
+-- custom-theme-corporate.md <-- ваш файл (не перезапишется при update)
|
|
83
|
+
+-- custom-seo-banking.md <-- ваш файл
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### 1.5. Структура скилл-директории
|
|
87
|
+
|
|
88
|
+
Полная структура скилла:
|
|
89
|
+
|
|
90
|
+
```
|
|
91
|
+
.claude/skills/transcript-site-generator/
|
|
92
|
+
+-- SKILL.md <-- Оркестратор 6-шагового пайплайна
|
|
93
|
+
+-- modules/
|
|
94
|
+
| +-- input-analysis.md <-- Шаг 1: source detection, yt-dlp, language
|
|
95
|
+
| +-- content-parsing.md <-- Шаг 2: sections, speakers, timestamps
|
|
96
|
+
| +-- site-generation.md <-- Шаг 3: HTML template, Tailwind, SEO
|
|
97
|
+
| +-- interactivity.md <-- Шаг 4: search, TOC, dark mode, sync
|
|
98
|
+
| +-- deploy.md <-- Шаг 5: GitHub Pages, robots, sitemap
|
|
99
|
+
| +-- verification.md <-- Шаг 6: HTML/JS/CSS/SEO/a11y checks
|
|
100
|
+
+-- references/
|
|
101
|
+
| +-- html-template.md <-- Базовая HTML-структура
|
|
102
|
+
| +-- tailwind-config.md <-- Tailwind Play CDN конфигурация
|
|
103
|
+
| +-- seo-checklist.md <-- OG, Twitter Cards, JSON-LD
|
|
104
|
+
| +-- accessibility-guide.md <-- Skip-nav, ARIA, keyboard nav
|
|
105
|
+
+-- examples/
|
|
106
|
+
+-- sample-podcast.md <-- Пример: подкаст-транскрипт
|
|
107
|
+
+-- sample-youtube.md <-- Пример: YouTube-видео
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
## 2. Конфигурация пайплайна (6 шагов)
|
|
113
|
+
|
|
114
|
+
### 2.1. Архитектура пайплайна
|
|
115
|
+
|
|
116
|
+
Transcript Site использует линейный 6-шаговый пайплайн. Каждый шаг является предусловием для следующего:
|
|
117
|
+
|
|
118
|
+
```
|
|
119
|
+
Step 1 Step 2 Step 3 Step 4 Step 5 Step 6
|
|
120
|
+
INPUT --> CONTENT --> SITE --> INTERACTIVITY --> DEPLOY --> VERIFICATION
|
|
121
|
+
ANALYSIS PARSING GENERATION CONFIG
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
**Ключевое правило:** Каждый шаг завершается checkpoint-ом. Пользователь может дать обратную связь или подтвердить продолжение.
|
|
125
|
+
|
|
126
|
+
### 2.2. Customization points по шагам
|
|
127
|
+
|
|
128
|
+
| Шаг | Параметры настройки | Файл конфигурации |
|
|
129
|
+
|-----|-------------------|--------------------|
|
|
130
|
+
| Step 1 | yt-dlp опции, language detection override | `modules/input-analysis.md` |
|
|
131
|
+
| Step 2 | Section splitting strategy, speaker detection | `modules/content-parsing.md` |
|
|
132
|
+
| Step 3 | Theme color, HTML template, SEO tags | `modules/site-generation.md`, `references/html-template.md` |
|
|
133
|
+
| Step 4 | Feature toggles (search, dark mode, copy, stats) | `modules/interactivity.md` |
|
|
134
|
+
| Step 5 | Output directory, deploy target | `modules/deploy.md` |
|
|
135
|
+
| Step 6 | Verification strictness, custom checks | `modules/verification.md` |
|
|
136
|
+
|
|
137
|
+
### 2.3. Отключение шагов
|
|
138
|
+
|
|
139
|
+
Для пропуска отдельных шагов (не рекомендуется, но возможно):
|
|
140
|
+
|
|
141
|
+
```
|
|
142
|
+
/transcript-site [source] --skip-deploy # Пропустить шаг 5
|
|
143
|
+
/transcript-site [source] --skip-verify # Пропустить шаг 6
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
Шаги 1-4 являются обязательными и не могут быть пропущены.
|
|
147
|
+
|
|
148
|
+
### 2.4. Изменение порядка исполнения
|
|
149
|
+
|
|
150
|
+
Порядок шагов фиксирован и не подлежит изменению. Данные передаются последовательно: output каждого шага является input следующего.
|
|
151
|
+
|
|
152
|
+
Цепочка данных:
|
|
153
|
+
|
|
154
|
+
```
|
|
155
|
+
Step 1 output: { sourceType, metadata, rawTranscript, language }
|
|
156
|
+
Step 2 output: { sections[], speakers[], timestamps[], quotes[] }
|
|
157
|
+
Step 3 output: { htmlContent, cssConfig, seoTags }
|
|
158
|
+
Step 4 output: { htmlWithJS, features[] }
|
|
159
|
+
Step 5 output: { deployConfig, robotsTxt, sitemap }
|
|
160
|
+
Step 6 output: { validationReport, status }
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
|
|
165
|
+
## 3. Языковая конфигурация
|
|
166
|
+
|
|
167
|
+
### 3.1. Автоматическое определение языка
|
|
168
|
+
|
|
169
|
+
Шаг 1 (Input Analysis) автоматически определяет язык транскрипта:
|
|
170
|
+
|
|
171
|
+
- **YouTube URL:** Язык берётся из метаданных субтитров (поле `lang`)
|
|
172
|
+
- **Текстовый ввод:** Эвристика по частотности символов и стоп-слов
|
|
173
|
+
- **Файл:** Анализ первых 500 слов
|
|
174
|
+
|
|
175
|
+
Поддерживаемые языки: `ru` (русский), `en` (английский), `de`, `fr`, `es`, `pt`, `ja`, `zh`, `ko`.
|
|
176
|
+
|
|
177
|
+
### 3.2. Override языка
|
|
178
|
+
|
|
179
|
+
Для принудительной установки языка:
|
|
180
|
+
|
|
181
|
+
```
|
|
182
|
+
/transcript-site [source] --lang ru
|
|
183
|
+
/transcript-site [source] --lang en
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
### 3.3. UI String Tables
|
|
187
|
+
|
|
188
|
+
Интерфейс сгенерированного сайта (кнопки, подписи, placeholder-ы) переводится автоматически.
|
|
189
|
+
|
|
190
|
+
Таблица строк для русского (`ru`):
|
|
191
|
+
|
|
192
|
+
| Ключ | Значение |
|
|
193
|
+
|------|---------|
|
|
194
|
+
| `search.placeholder` | "Поиск по транскрипту... (Ctrl+K)" |
|
|
195
|
+
| `search.no_results` | "Ничего не найдено" |
|
|
196
|
+
| `search.results_count` | "Найдено: {count}" |
|
|
197
|
+
| `toc.title` | "Содержание" |
|
|
198
|
+
| `dark_mode.toggle` | "Тёмная тема" |
|
|
199
|
+
| `copy.button` | "Скопировать" |
|
|
200
|
+
| `copy.success` | "Скопировано!" |
|
|
201
|
+
| `back_to_top` | "Наверх" |
|
|
202
|
+
| `stats.words` | "слов" |
|
|
203
|
+
| `stats.reading_time` | "мин. чтения" |
|
|
204
|
+
| `stats.sections` | "разделов" |
|
|
205
|
+
| `print.title` | "Версия для печати" |
|
|
206
|
+
|
|
207
|
+
Таблица строк для английского (`en`):
|
|
208
|
+
|
|
209
|
+
| Ключ | Значение |
|
|
210
|
+
|------|---------|
|
|
211
|
+
| `search.placeholder` | "Search transcript... (Ctrl+K)" |
|
|
212
|
+
| `search.no_results` | "No results found" |
|
|
213
|
+
| `search.results_count` | "Found: {count}" |
|
|
214
|
+
| `toc.title` | "Table of Contents" |
|
|
215
|
+
| `dark_mode.toggle` | "Dark mode" |
|
|
216
|
+
| `copy.button` | "Copy" |
|
|
217
|
+
| `copy.success` | "Copied!" |
|
|
218
|
+
| `back_to_top` | "Back to top" |
|
|
219
|
+
| `stats.words` | "words" |
|
|
220
|
+
| `stats.reading_time` | "min read" |
|
|
221
|
+
| `stats.sections` | "sections" |
|
|
222
|
+
| `print.title` | "Print version" |
|
|
223
|
+
|
|
224
|
+
### 3.4. Добавление нового языка
|
|
225
|
+
|
|
226
|
+
Для добавления поддержки нового языка создайте пользовательский reference-файл:
|
|
227
|
+
|
|
228
|
+
```
|
|
229
|
+
.claude/skills/transcript-site-generator/references/custom-strings-ja.md
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
Формат:
|
|
233
|
+
|
|
234
|
+
```markdown
|
|
235
|
+
# UI Strings: Japanese (ja)
|
|
236
|
+
|
|
237
|
+
| Key | Value |
|
|
238
|
+
|-----|-------|
|
|
239
|
+
| search.placeholder | "... (Ctrl+K)" |
|
|
240
|
+
| ...
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
Затем при вызове укажите:
|
|
244
|
+
|
|
245
|
+
```
|
|
246
|
+
/transcript-site [source] --lang ja --strings references/custom-strings-ja.md
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
### 3.5. Двуязычные сайты
|
|
250
|
+
|
|
251
|
+
Для генерации сайта с двуязычным интерфейсом:
|
|
252
|
+
|
|
253
|
+
```
|
|
254
|
+
/transcript-site [source] --lang ru --ui-lang en
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
Контент будет на русском (определён из транскрипта), а интерфейс (кнопки, лейблы) — на английском.
|
|
258
|
+
|
|
259
|
+
---
|
|
260
|
+
|
|
261
|
+
## 4. SEO конфигурация
|
|
262
|
+
|
|
263
|
+
### 4.1. Open Graph теги
|
|
264
|
+
|
|
265
|
+
Шаг 3 (Site Generation) автоматически генерирует OG-теги:
|
|
266
|
+
|
|
267
|
+
```html
|
|
268
|
+
<meta property="og:title" content="[Title from metadata or first section]">
|
|
269
|
+
<meta property="og:description" content="[First 200 chars of transcript]">
|
|
270
|
+
<meta property="og:type" content="article">
|
|
271
|
+
<meta property="og:url" content="[canonical URL]">
|
|
272
|
+
<meta property="og:image" content="[YouTube thumbnail or placeholder]">
|
|
273
|
+
<meta property="og:locale" content="[detected language]">
|
|
274
|
+
<meta property="og:site_name" content="[repository name]">
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
Для YouTube-источников `og:image` автоматически берётся из thumbnail видео (maxresdefault.jpg).
|
|
278
|
+
|
|
279
|
+
### 4.2. Twitter Card теги
|
|
280
|
+
|
|
281
|
+
```html
|
|
282
|
+
<meta name="twitter:card" content="summary_large_image">
|
|
283
|
+
<meta name="twitter:title" content="[Title]">
|
|
284
|
+
<meta name="twitter:description" content="[Description]">
|
|
285
|
+
<meta name="twitter:image" content="[Image URL]">
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
### 4.3. JSON-LD Structured Data
|
|
289
|
+
|
|
290
|
+
Для YouTube-транскриптов генерируется `VideoObject`:
|
|
291
|
+
|
|
292
|
+
```html
|
|
293
|
+
<script type="application/ld+json">
|
|
294
|
+
{
|
|
295
|
+
"@context": "https://schema.org",
|
|
296
|
+
"@type": "VideoObject",
|
|
297
|
+
"name": "[Title]",
|
|
298
|
+
"description": "[Description]",
|
|
299
|
+
"thumbnailUrl": "[Thumbnail URL]",
|
|
300
|
+
"uploadDate": "[Upload date ISO-8601]",
|
|
301
|
+
"duration": "[Duration ISO-8601]",
|
|
302
|
+
"embedUrl": "https://www.youtube.com/embed/[VIDEO_ID]",
|
|
303
|
+
"transcript": "[Full transcript text]"
|
|
304
|
+
}
|
|
305
|
+
</script>
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
Для текстовых транскриптов генерируется `Article`:
|
|
309
|
+
|
|
310
|
+
```html
|
|
311
|
+
<script type="application/ld+json">
|
|
312
|
+
{
|
|
313
|
+
"@context": "https://schema.org",
|
|
314
|
+
"@type": "Article",
|
|
315
|
+
"headline": "[Title]",
|
|
316
|
+
"description": "[Description]",
|
|
317
|
+
"datePublished": "[Date]",
|
|
318
|
+
"wordCount": [word count],
|
|
319
|
+
"articleBody": "[Full transcript text]"
|
|
320
|
+
}
|
|
321
|
+
</script>
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
### 4.4. Настройка SEO
|
|
325
|
+
|
|
326
|
+
Для override SEO-параметров:
|
|
327
|
+
|
|
328
|
+
```
|
|
329
|
+
/transcript-site [source] --title "Custom Title" --description "Custom description" --image "https://example.com/og-image.jpg"
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
Для полного контроля создайте файл конфигурации:
|
|
333
|
+
|
|
334
|
+
```json
|
|
335
|
+
{
|
|
336
|
+
"seo": {
|
|
337
|
+
"title": "My Transcript",
|
|
338
|
+
"description": "A detailed transcript of...",
|
|
339
|
+
"image": "https://example.com/image.png",
|
|
340
|
+
"canonical": "https://example.com/transcript/",
|
|
341
|
+
"locale": "ru_RU",
|
|
342
|
+
"twitter_creator": "@username"
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
Передайте путь через:
|
|
348
|
+
|
|
349
|
+
```
|
|
350
|
+
/transcript-site [source] --seo-config seo.json
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
### 4.5. robots.txt и sitemap.xml
|
|
354
|
+
|
|
355
|
+
Шаг 5 (Deploy) автоматически генерирует:
|
|
356
|
+
|
|
357
|
+
**robots.txt:**
|
|
358
|
+
```
|
|
359
|
+
User-agent: *
|
|
360
|
+
Allow: /
|
|
361
|
+
Sitemap: https://[user].github.io/[repo]/sitemap.xml
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
**sitemap.xml:**
|
|
365
|
+
```xml
|
|
366
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
367
|
+
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
|
368
|
+
<url>
|
|
369
|
+
<loc>https://[user].github.io/[repo]/</loc>
|
|
370
|
+
<lastmod>[current date]</lastmod>
|
|
371
|
+
<changefreq>monthly</changefreq>
|
|
372
|
+
<priority>1.0</priority>
|
|
373
|
+
</url>
|
|
374
|
+
</urlset>
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
---
|
|
378
|
+
|
|
379
|
+
## 5. YouTube интеграция
|
|
380
|
+
|
|
381
|
+
### 5.1. yt-dlp конфигурация
|
|
382
|
+
|
|
383
|
+
Шаг 1 использует `yt-dlp` для извлечения данных из YouTube. Параметры по умолчанию:
|
|
384
|
+
|
|
385
|
+
```bash
|
|
386
|
+
# Извлечение субтитров
|
|
387
|
+
yt-dlp --write-auto-sub --sub-lang en,ru --skip-download --print-json [URL]
|
|
388
|
+
|
|
389
|
+
# Извлечение только метаданных
|
|
390
|
+
yt-dlp --dump-json [URL]
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
Для изменения параметров yt-dlp отредактируйте `modules/input-analysis.md`, секция "YouTube Extraction Protocol".
|
|
394
|
+
|
|
395
|
+
### 5.2. Приоритет субтитров
|
|
396
|
+
|
|
397
|
+
Порядок приоритета при выборе субтитров:
|
|
398
|
+
|
|
399
|
+
1. Ручные субтитры на определённом языке (`--lang`)
|
|
400
|
+
2. Ручные субтитры на языке видео
|
|
401
|
+
3. Авто-сгенерированные субтитры на определённом языке
|
|
402
|
+
4. Авто-сгенерированные субтитры на языке видео
|
|
403
|
+
5. Fallback: предложить пользователю вставить текст вручную
|
|
404
|
+
|
|
405
|
+
### 5.3. YouTube iframe API
|
|
406
|
+
|
|
407
|
+
Сгенерированный сайт использует YouTube iframe API для синхронизации:
|
|
408
|
+
|
|
409
|
+
```html
|
|
410
|
+
<iframe
|
|
411
|
+
id="yt-player"
|
|
412
|
+
src="https://www.youtube.com/embed/[VIDEO_ID]?enablejsapi=1&origin=[ORIGIN]"
|
|
413
|
+
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
|
|
414
|
+
allowfullscreen
|
|
415
|
+
></iframe>
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
Параметр `enablejsapi=1` обязателен для работы `seekTo()`.
|
|
419
|
+
|
|
420
|
+
### 5.4. Timestamp формат
|
|
421
|
+
|
|
422
|
+
Временные метки в транскрипте конвертируются в `data-seek` атрибуты:
|
|
423
|
+
|
|
424
|
+
```html
|
|
425
|
+
<a href="#" data-seek="125" class="timestamp-link text-indigo-600 hover:underline">
|
|
426
|
+
[2:05]
|
|
427
|
+
</a>
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
JavaScript обработчик (event delegation через `data-seek`):
|
|
431
|
+
|
|
432
|
+
```javascript
|
|
433
|
+
document.addEventListener('click', function(e) {
|
|
434
|
+
const seekTarget = e.target.closest('[data-seek]');
|
|
435
|
+
if (seekTarget) {
|
|
436
|
+
e.preventDefault();
|
|
437
|
+
const seconds = parseInt(seekTarget.dataset.seek);
|
|
438
|
+
player.seekTo(seconds, true);
|
|
439
|
+
}
|
|
440
|
+
});
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
### 5.5. Отключение YouTube embed
|
|
444
|
+
|
|
445
|
+
Для генерации сайта без YouTube embed (только текст, даже при наличии URL):
|
|
446
|
+
|
|
447
|
+
```
|
|
448
|
+
/transcript-site [URL] --no-embed
|
|
449
|
+
```
|
|
450
|
+
|
|
451
|
+
Временные метки останутся как текст, но без интерактивной синхронизации с видео.
|
|
452
|
+
|
|
453
|
+
---
|
|
454
|
+
|
|
455
|
+
## 6. Управление выходной директорией
|
|
456
|
+
|
|
457
|
+
### 6.1. Директория по умолчанию
|
|
458
|
+
|
|
459
|
+
По умолчанию: `docs/` — стандартная директория для GitHub Pages.
|
|
460
|
+
|
|
461
|
+
### 6.2. Изменение директории
|
|
462
|
+
|
|
463
|
+
При инициализации:
|
|
464
|
+
|
|
465
|
+
```bash
|
|
466
|
+
npx @dzhechkov/skills-transcript-site init --output-dir public/
|
|
467
|
+
```
|
|
468
|
+
|
|
469
|
+
При запуске пайплайна:
|
|
470
|
+
|
|
471
|
+
```
|
|
472
|
+
/transcript-site [source] --output docs/my-transcript/
|
|
473
|
+
```
|
|
474
|
+
|
|
475
|
+
### 6.3. Структура выходных файлов
|
|
476
|
+
|
|
477
|
+
```
|
|
478
|
+
docs/
|
|
479
|
+
+-- index.html <-- Основная страница транскрипта
|
|
480
|
+
+-- robots.txt <-- Конфигурация для поисковых роботов
|
|
481
|
+
+-- sitemap.xml <-- Карта сайта
|
|
482
|
+
```
|
|
483
|
+
|
|
484
|
+
При multi-page chunking:
|
|
485
|
+
|
|
486
|
+
```
|
|
487
|
+
docs/
|
|
488
|
+
+-- index.html <-- Главная страница с навигацией
|
|
489
|
+
+-- section-01.html <-- Секция 1
|
|
490
|
+
+-- section-02.html <-- Секция 2
|
|
491
|
+
+-- ...
|
|
492
|
+
+-- robots.txt
|
|
493
|
+
+-- sitemap.xml
|
|
494
|
+
```
|
|
495
|
+
|
|
496
|
+
### 6.4. Очистка выходной директории
|
|
497
|
+
|
|
498
|
+
Скилл НЕ очищает директорию автоматически. Если вы перегенерируете сайт:
|
|
499
|
+
|
|
500
|
+
```bash
|
|
501
|
+
# Очистить вручную перед перегенерацией
|
|
502
|
+
rm docs/index.html docs/robots.txt docs/sitemap.xml
|
|
503
|
+
|
|
504
|
+
# Или через пайплайн с флагом
|
|
505
|
+
/transcript-site [source] --clean
|
|
506
|
+
```
|
|
507
|
+
|
|
508
|
+
Флаг `--clean` удалит только файлы, сгенерированные скиллом (по манифесту), не затрагивая пользовательские файлы в `docs/`.
|
|
509
|
+
|
|
510
|
+
### 6.5. Множественные сайты в одном репозитории
|
|
511
|
+
|
|
512
|
+
Для нескольких транскриптов в одном репозитории:
|
|
513
|
+
|
|
514
|
+
```
|
|
515
|
+
/transcript-site [source1] --output docs/podcast-ep1/
|
|
516
|
+
/transcript-site [source2] --output docs/podcast-ep2/
|
|
517
|
+
/transcript-site [source3] --output docs/conference-talk/
|
|
518
|
+
```
|
|
519
|
+
|
|
520
|
+
Каждый сайт будет независим и доступен по своему пути на GitHub Pages.
|
|
521
|
+
|
|
522
|
+
---
|
|
523
|
+
|
|
524
|
+
## 7. Tailwind CDN vs self-hosted
|
|
525
|
+
|
|
526
|
+
### 7.1. Tailwind Play CDN (по умолчанию)
|
|
527
|
+
|
|
528
|
+
По умолчанию сгенерированные сайты используют Tailwind CSS Play CDN:
|
|
529
|
+
|
|
530
|
+
```html
|
|
531
|
+
<script src="https://cdn.tailwindcss.com"></script>
|
|
532
|
+
<script>
|
|
533
|
+
tailwind.config = {
|
|
534
|
+
darkMode: 'class',
|
|
535
|
+
theme: {
|
|
536
|
+
extend: {
|
|
537
|
+
colors: {
|
|
538
|
+
primary: {
|
|
539
|
+
50: '#eef2ff',
|
|
540
|
+
// ... full palette
|
|
541
|
+
900: '#312e81'
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
</script>
|
|
548
|
+
```
|
|
549
|
+
|
|
550
|
+
**Преимущества Play CDN:**
|
|
551
|
+
- Нет шага сборки
|
|
552
|
+
- Нет node_modules
|
|
553
|
+
- Автоматическая обработка всех utility classes
|
|
554
|
+
- Конфигурация в JS-объекте прямо в HTML
|
|
555
|
+
|
|
556
|
+
**Ограничения Play CDN:**
|
|
557
|
+
- Требует подключения к интернету при первой загрузке
|
|
558
|
+
- Не рекомендуется для production (по документации Tailwind)
|
|
559
|
+
- ~300 KB загрузки (кешируется браузером)
|
|
560
|
+
|
|
561
|
+
### 7.2. Self-hosted Tailwind (production)
|
|
562
|
+
|
|
563
|
+
Для production-окружений рекомендуется self-hosted Tailwind:
|
|
564
|
+
|
|
565
|
+
```
|
|
566
|
+
/transcript-site [source] --tailwind inline
|
|
567
|
+
```
|
|
568
|
+
|
|
569
|
+
Этот режим:
|
|
570
|
+
1. Определяет используемые utility classes в HTML
|
|
571
|
+
2. Генерирует минифицированный CSS только с нужными классами
|
|
572
|
+
3. Инлайнит CSS в `<style>` тег
|
|
573
|
+
4. Убирает зависимость от CDN
|
|
574
|
+
|
|
575
|
+
Результат: ~10-20 KB инлайн CSS вместо ~300 KB CDN загрузки.
|
|
576
|
+
|
|
577
|
+
### 7.3. Сравнение режимов
|
|
578
|
+
|
|
579
|
+
| Параметр | Play CDN | Self-hosted (inline) |
|
|
580
|
+
|----------|----------|---------------------|
|
|
581
|
+
| Интернет при просмотре | Требуется (первая загрузка) | Не требуется |
|
|
582
|
+
| Шаг сборки | Нет | Нет (генерируется скиллом) |
|
|
583
|
+
| Размер HTML | ~50 KB + ~300 KB CDN | ~70 KB (всё включено) |
|
|
584
|
+
| Кастомизация | tailwind.config в JS | Ограничена сгенерированными классами |
|
|
585
|
+
| Production-ready | Нет (по документации Tailwind) | Да |
|
|
586
|
+
|
|
587
|
+
### 7.4. Переключение режимов
|
|
588
|
+
|
|
589
|
+
Для существующего сайта:
|
|
590
|
+
|
|
591
|
+
```
|
|
592
|
+
/transcript-site-generate [source] --tailwind inline # Перегенерировать с inline CSS
|
|
593
|
+
/transcript-site-generate [source] --tailwind cdn # Перегенерировать с CDN
|
|
594
|
+
```
|
|
595
|
+
|
|
596
|
+
---
|
|
597
|
+
|
|
598
|
+
## 8. Dark mode конфигурация
|
|
599
|
+
|
|
600
|
+
### 8.1. Реализация
|
|
601
|
+
|
|
602
|
+
Dark mode реализован через CSS-класс `dark` на элементе `<html>`:
|
|
603
|
+
|
|
604
|
+
```html
|
|
605
|
+
<html lang="en" class="">
|
|
606
|
+
<!-- class="dark" добавляется при активации -->
|
|
607
|
+
```
|
|
608
|
+
|
|
609
|
+
Tailwind утилиты:
|
|
610
|
+
|
|
611
|
+
```html
|
|
612
|
+
<body class="bg-white dark:bg-gray-900 text-gray-900 dark:text-gray-100">
|
|
613
|
+
```
|
|
614
|
+
|
|
615
|
+
### 8.2. Кнопка переключения
|
|
616
|
+
|
|
617
|
+
```html
|
|
618
|
+
<button id="dark-mode-toggle" aria-label="Toggle dark mode"
|
|
619
|
+
class="p-2 rounded-lg hover:bg-gray-200 dark:hover:bg-gray-700">
|
|
620
|
+
<svg id="icon-sun" class="hidden dark:block w-5 h-5">...</svg>
|
|
621
|
+
<svg id="icon-moon" class="block dark:hidden w-5 h-5">...</svg>
|
|
622
|
+
</button>
|
|
623
|
+
```
|
|
624
|
+
|
|
625
|
+
### 8.3. Persistence через localStorage
|
|
626
|
+
|
|
627
|
+
```javascript
|
|
628
|
+
// При загрузке страницы
|
|
629
|
+
if (localStorage.getItem('theme') === 'dark' ||
|
|
630
|
+
(!localStorage.getItem('theme') && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
|
|
631
|
+
document.documentElement.classList.add('dark');
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
// При переключении
|
|
635
|
+
function toggleDarkMode() {
|
|
636
|
+
const isDark = document.documentElement.classList.toggle('dark');
|
|
637
|
+
localStorage.setItem('theme', isDark ? 'dark' : 'light');
|
|
638
|
+
}
|
|
639
|
+
```
|
|
640
|
+
|
|
641
|
+
### 8.4. Порядок приоритетов
|
|
642
|
+
|
|
643
|
+
1. Явная настройка в localStorage (`theme: 'dark'` или `theme: 'light'`)
|
|
644
|
+
2. Системная настройка (`prefers-color-scheme: dark`)
|
|
645
|
+
3. По умолчанию: light
|
|
646
|
+
|
|
647
|
+
### 8.5. Отключение dark mode
|
|
648
|
+
|
|
649
|
+
```
|
|
650
|
+
/transcript-site [source] --no-dark-mode
|
|
651
|
+
```
|
|
652
|
+
|
|
653
|
+
Убирает кнопку переключения, все `dark:` утилиты и localStorage логику.
|
|
654
|
+
|
|
655
|
+
### 8.6. Кастомные цвета dark mode
|
|
656
|
+
|
|
657
|
+
Для изменения палитры dark mode отредактируйте `references/tailwind-config.md`:
|
|
658
|
+
|
|
659
|
+
```javascript
|
|
660
|
+
tailwind.config = {
|
|
661
|
+
darkMode: 'class',
|
|
662
|
+
theme: {
|
|
663
|
+
extend: {
|
|
664
|
+
colors: {
|
|
665
|
+
// Кастомная палитра для dark mode
|
|
666
|
+
dark: {
|
|
667
|
+
bg: '#0f172a', // вместо gray-900
|
|
668
|
+
text: '#e2e8f0', // вместо gray-100
|
|
669
|
+
accent: '#818cf8' // вместо indigo-400
|
|
670
|
+
}
|
|
671
|
+
}
|
|
672
|
+
}
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
```
|
|
676
|
+
|
|
677
|
+
---
|
|
678
|
+
|
|
679
|
+
## 9. Print stylesheet управление
|
|
680
|
+
|
|
681
|
+
### 9.1. Print-специфичные стили
|
|
682
|
+
|
|
683
|
+
Сгенерированные сайты включают print stylesheet для корректной печати:
|
|
684
|
+
|
|
685
|
+
```html
|
|
686
|
+
<style media="print">
|
|
687
|
+
@media print {
|
|
688
|
+
/* Скрыть интерактивные элементы */
|
|
689
|
+
#dark-mode-toggle,
|
|
690
|
+
#search-container,
|
|
691
|
+
#back-to-top,
|
|
692
|
+
.copy-button,
|
|
693
|
+
.timestamp-link,
|
|
694
|
+
#yt-player,
|
|
695
|
+
nav { display: none !important; }
|
|
696
|
+
|
|
697
|
+
/* Типографика для печати */
|
|
698
|
+
body {
|
|
699
|
+
font-size: 11pt;
|
|
700
|
+
line-height: 1.5;
|
|
701
|
+
color: #000;
|
|
702
|
+
background: #fff;
|
|
703
|
+
}
|
|
704
|
+
|
|
705
|
+
/* Разрывы страниц */
|
|
706
|
+
h2 { page-break-before: always; }
|
|
707
|
+
h2:first-of-type { page-break-before: avoid; }
|
|
708
|
+
blockquote { page-break-inside: avoid; }
|
|
709
|
+
|
|
710
|
+
/* Показать URL-ы ссылок */
|
|
711
|
+
a[href]::after { content: " (" attr(href) ")"; }
|
|
712
|
+
}
|
|
713
|
+
</style>
|
|
714
|
+
```
|
|
715
|
+
|
|
716
|
+
### 9.2. Отключение print stylesheet
|
|
717
|
+
|
|
718
|
+
```
|
|
719
|
+
/transcript-site [source] --no-print-styles
|
|
720
|
+
```
|
|
721
|
+
|
|
722
|
+
### 9.3. Кастомизация print стилей
|
|
723
|
+
|
|
724
|
+
Для изменения print стилей добавьте кастомный reference:
|
|
725
|
+
|
|
726
|
+
```
|
|
727
|
+
.claude/skills/transcript-site-generator/references/custom-print.md
|
|
728
|
+
```
|
|
729
|
+
|
|
730
|
+
Укажите при генерации:
|
|
731
|
+
|
|
732
|
+
```
|
|
733
|
+
/transcript-site [source] --print-styles references/custom-print.md
|
|
734
|
+
```
|
|
735
|
+
|
|
736
|
+
---
|
|
737
|
+
|
|
738
|
+
## 10. Производительность и большие транскрипты
|
|
739
|
+
|
|
740
|
+
### 10.1. Рекомендации по размеру
|
|
741
|
+
|
|
742
|
+
| Размер транскрипта | Стратегия | Ожидаемый размер HTML |
|
|
743
|
+
|-------------------|-----------|---------------------|
|
|
744
|
+
| До 5,000 слов | Single page, без chunking | ~30-50 KB |
|
|
745
|
+
| 5,000 - 15,000 слов | Single page, рекомендуется lazy TOC | ~50-100 KB |
|
|
746
|
+
| 15,000 - 30,000 слов | Single page с lazy loading контента | ~100-200 KB |
|
|
747
|
+
| Более 30,000 слов | Multi-page chunking | ~50 KB на страницу |
|
|
748
|
+
|
|
749
|
+
### 10.2. Chunking стратегия
|
|
750
|
+
|
|
751
|
+
При chunking транскрипт разбивается по секциям (определённым в Шаге 2). Каждая секция или группа секций становится отдельной HTML-страницей.
|
|
752
|
+
|
|
753
|
+
Настройки chunking в `modules/content-parsing.md`:
|
|
754
|
+
|
|
755
|
+
```markdown
|
|
756
|
+
## Chunking Configuration
|
|
757
|
+
|
|
758
|
+
- max_words_per_page: 10000
|
|
759
|
+
- min_words_per_page: 2000
|
|
760
|
+
- split_strategy: by_section (альтернатива: by_word_count)
|
|
761
|
+
- navigation: prev/next + TOC on each page
|
|
762
|
+
```
|
|
763
|
+
|
|
764
|
+
### 10.3. Оптимизация поиска для больших транскриптов
|
|
765
|
+
|
|
766
|
+
Для транскриптов свыше 10,000 слов поиск использует debounce (300ms) и ограничивает количество подсвеченных результатов до 50 для предотвращения зависания DOM.
|
|
767
|
+
|
|
768
|
+
Настраиваемые параметры в `modules/interactivity.md`:
|
|
769
|
+
|
|
770
|
+
```markdown
|
|
771
|
+
## Search Configuration
|
|
772
|
+
|
|
773
|
+
- debounce_ms: 300
|
|
774
|
+
- max_highlights: 50
|
|
775
|
+
- min_query_length: 2
|
|
776
|
+
- case_sensitive: false
|
|
777
|
+
```
|
|
778
|
+
|
|
779
|
+
### 10.4. Lazy loading для длинных страниц
|
|
780
|
+
|
|
781
|
+
При single-page стратегии для транскриптов свыше 15,000 слов:
|
|
782
|
+
|
|
783
|
+
- Контент ниже 3-го viewport загружается через `IntersectionObserver`
|
|
784
|
+
- Placeholder-ы заменяются реальным контентом при приближении к viewport
|
|
785
|
+
- Первоначальная загрузка: только первые 5,000 слов + все заголовки секций
|
|
786
|
+
|
|
787
|
+
### 10.5. Метрики производительности
|
|
788
|
+
|
|
789
|
+
Шаг 6 (Verification) проверяет:
|
|
790
|
+
|
|
791
|
+
| Метрика | Порог | Действие при превышении |
|
|
792
|
+
|---------|-------|------------------------|
|
|
793
|
+
| HTML размер | < 200 KB | Предложить chunking |
|
|
794
|
+
| DOM nodes | < 5,000 | Предложить lazy loading |
|
|
795
|
+
| JS execution time (estimated) | < 100ms | Упростить search logic |
|
|
796
|
+
| First paint (estimated) | < 1s | Уменьшить inline CSS |
|
|
797
|
+
|
|
798
|
+
---
|
|
799
|
+
|
|
800
|
+
## 11. Безопасность
|
|
801
|
+
|
|
802
|
+
### 11.1. XSS предотвращение
|
|
803
|
+
|
|
804
|
+
Весь пользовательский контент (транскрипт, метаданные, спикеры) проходит через `escapeHtml()` перед вставкой в DOM:
|
|
805
|
+
|
|
806
|
+
```javascript
|
|
807
|
+
function escapeHtml(str) {
|
|
808
|
+
const div = document.createElement('div');
|
|
809
|
+
div.appendChild(document.createTextNode(str));
|
|
810
|
+
return div.innerHTML;
|
|
811
|
+
}
|
|
812
|
+
```
|
|
813
|
+
|
|
814
|
+
Поисковые запросы дополнительно проходят через `escapeRegex()`:
|
|
815
|
+
|
|
816
|
+
```javascript
|
|
817
|
+
function escapeRegex(str) {
|
|
818
|
+
return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
819
|
+
}
|
|
820
|
+
```
|
|
821
|
+
|
|
822
|
+
### 11.2. Event delegation через data-* атрибуты
|
|
823
|
+
|
|
824
|
+
Сгенерированные сайты НЕ используют inline event handlers (`onclick`, `onload`, etc.). Вся интерактивность реализована через event delegation:
|
|
825
|
+
|
|
826
|
+
```javascript
|
|
827
|
+
// Правильно: event delegation
|
|
828
|
+
document.addEventListener('click', function(e) {
|
|
829
|
+
const copyBtn = e.target.closest('[data-copy]');
|
|
830
|
+
if (copyBtn) {
|
|
831
|
+
// handle copy
|
|
832
|
+
}
|
|
833
|
+
|
|
834
|
+
const seekBtn = e.target.closest('[data-seek]');
|
|
835
|
+
if (seekBtn) {
|
|
836
|
+
// handle YouTube seek
|
|
837
|
+
}
|
|
838
|
+
});
|
|
839
|
+
```
|
|
840
|
+
|
|
841
|
+
Это позволяет использовать строгий CSP без `'unsafe-inline'` для скриптов.
|
|
842
|
+
|
|
843
|
+
### 11.3. SRI (Subresource Integrity) хеши
|
|
844
|
+
|
|
845
|
+
Для Tailwind CDN и Font Awesome CDN генерируются SRI хеши:
|
|
846
|
+
|
|
847
|
+
```html
|
|
848
|
+
<script src="https://cdn.tailwindcss.com"
|
|
849
|
+
integrity="sha384-[hash]"
|
|
850
|
+
crossorigin="anonymous"></script>
|
|
851
|
+
|
|
852
|
+
<link rel="stylesheet"
|
|
853
|
+
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css"
|
|
854
|
+
integrity="sha384-[hash]"
|
|
855
|
+
crossorigin="anonymous">
|
|
856
|
+
```
|
|
857
|
+
|
|
858
|
+
SRI гарантирует, что CDN-ресурсы не были модифицированы.
|
|
859
|
+
|
|
860
|
+
### 11.4. Content Security Policy (CSP)
|
|
861
|
+
|
|
862
|
+
Рекомендуемый CSP для сгенерированных сайтов:
|
|
863
|
+
|
|
864
|
+
```html
|
|
865
|
+
<meta http-equiv="Content-Security-Policy" content="
|
|
866
|
+
default-src 'self';
|
|
867
|
+
script-src 'self' https://cdn.tailwindcss.com https://www.youtube.com;
|
|
868
|
+
style-src 'self' 'unsafe-inline' https://cdnjs.cloudflare.com;
|
|
869
|
+
frame-src https://www.youtube.com;
|
|
870
|
+
img-src 'self' https://i.ytimg.com https://img.youtube.com data:;
|
|
871
|
+
connect-src 'self';
|
|
872
|
+
">
|
|
873
|
+
```
|
|
874
|
+
|
|
875
|
+
CSP включается по умолчанию. Для отключения:
|
|
876
|
+
|
|
877
|
+
```
|
|
878
|
+
/transcript-site [source] --no-csp
|
|
879
|
+
```
|
|
880
|
+
|
|
881
|
+
### 11.5. postMessage origin restriction
|
|
882
|
+
|
|
883
|
+
При использовании YouTube iframe API, обработчик `message` событий проверяет origin:
|
|
884
|
+
|
|
885
|
+
```javascript
|
|
886
|
+
window.addEventListener('message', function(event) {
|
|
887
|
+
if (event.origin !== 'https://www.youtube.com') return;
|
|
888
|
+
// handle message
|
|
889
|
+
});
|
|
890
|
+
```
|
|
891
|
+
|
|
892
|
+
Это предотвращает XSS через iframe postMessage от сторонних доменов.
|
|
893
|
+
|
|
894
|
+
### 11.6. Чеклист безопасности
|
|
895
|
+
|
|
896
|
+
Шаг 6 (Verification) включает следующие проверки безопасности:
|
|
897
|
+
|
|
898
|
+
| Проверка | Описание |
|
|
899
|
+
|---------|---------|
|
|
900
|
+
| SEC-01 | Нет inline event handlers (onclick, onload, onerror) |
|
|
901
|
+
| SEC-02 | escapeHtml() вызывается для всего пользовательского контента |
|
|
902
|
+
| SEC-03 | escapeRegex() вызывается для поисковых запросов |
|
|
903
|
+
| SEC-04 | Event delegation через data-* атрибуты |
|
|
904
|
+
| SEC-05 | SRI хеши на всех CDN-ресурсах |
|
|
905
|
+
| SEC-06 | CSP meta-тег присутствует |
|
|
906
|
+
| SEC-07 | postMessage origin проверяется |
|
|
907
|
+
| SEC-08 | Нет eval(), innerHTML с пользовательскими данными, document.write() |
|
|
908
|
+
|
|
909
|
+
### 11.7. Безопасность для банковского домена
|
|
910
|
+
|
|
911
|
+
При обнаружении банковского контекста в транскрипте (ключевые слова: банк, ФЗ-152, ЦБ, персональные данные) скилл автоматически:
|
|
912
|
+
|
|
913
|
+
1. Применяет максимально строгий CSP
|
|
914
|
+
2. Убирает все внешние CDN-зависимости (inline всё)
|
|
915
|
+
3. Добавляет disclaimer о конфиденциальности
|
|
916
|
+
4. Предлагает self-hosted вместо GitHub Pages
|
|
917
|
+
|
|
918
|
+
Это поведение наследуется из Keysarium domain-specific rules.
|