<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Evgeny Kushnarenko</title><link>https://kushnaren.co/</link><description>Личный блог Евгения Кушнаренко: инженерия, мышление, наблюдения. Длинные тексты о смыслах и системах.</description><generator>Hugo</generator><language>ru-RU</language><managingEditor>hello@kushnaren.co</managingEditor><lastBuildDate>Sat, 21 Dec 2024 10:00:00 +0300</lastBuildDate><atom:link href="https://kushnaren.co/tags/gitea/index.xml" rel="self" type="application/rss+xml"/><item><title>Как мы с тобой сейчас пишем этот пост: модель, инструменты, рабочий процесс 🤖</title><link>https://kushnaren.co/posts/2026-07-21-kak-my-s-toboj-seychas-pishem-etot-post/</link><pubDate>Tue, 21 Jul 2026 10:18:00 +0300</pubDate><guid isPermaLink="true">https://kushnaren.co/posts/2026-07-21-kak-my-s-toboj-seychas-pishem-etot-post/</guid><description>Практический взгляд изнутри на то, как ИИ-агент опencode с моделью Qwen3.6-35B-A3B-MLX-6bit создаёт контент для Hugo-блога: структура инструментов, MCP-серверы (Hugo, Obsidian, SearXNG), автоматизация сборки и деплоя, где агент силён, а где нужна ручная редактура.</description><content:encoded><![CDATA[<p>Этот пост пишется прямо сейчас — в реальном времени — агентом опencode на модели Qwen3.6-35B-A3B-MLX-6bit. Не Codex, не Claude Code, а именно opencode: CLI-инструмент с поддержкой специализированных скиллов, MCP-серверов и интеграции с Obsidian.</p>
<p>Давайте разберёмся, что здесь происходит на самом деле — от модели до публикации, без маркетинговой шелухи.</p>
<h2 class="heading" id="что-такое-opencode-и-чем-он-отличается">
  Что такое opencode и чем он отличается
  <a class="anchor" href="#%d1%87%d1%82%d0%be-%d1%82%d0%b0%d0%ba%d0%be%d0%b5-opencode-%d0%b8-%d1%87%d0%b5%d0%bc-%d0%be%d0%bd-%d0%be%d1%82%d0%bb%d0%b8%d1%87%d0%b0%d0%b5%d1%82%d1%81%d1%8f">#</a>
</h2>
<p>opencode — это интерактивный CLI-агент для помощи в программистских задачах. В отличие от Codex, он построен вокруг концепции скиллов — специализированных инструкций для конкретных типов задач — и MCP-серверов, которые дают агенту доступ к внешним инструментам без необходимости вручную выполнять команды.</p>
<p>В моём случае это не просто «чат с ИИ». Это инструмент, который:</p>
<ul>
<li>знает контекст моих проектов через Obsidian Volt;</li>
<li>умеет работать с Hugo-блогом напрямую через MCP-сервер <code>hugo</code>;</li>
<li>может искать информацию через SearXNG;</li>
<li>умеет управлять заметками, тегами и структурой хранилища.</li>
</ul>
<p>Главное отличие от Codex: опencode — это не привязка к одной модели, а оболочка, которая может работать с разными бэкендами и расширениями через скиллы и MCP 🔌</p>
<h2 class="heading" id="модель-под-капотом-qwen36-35b-a3b-mlx-6bit">
  Модель под капотом: Qwen3.6-35B-A3B-MLX-6bit
  <a class="anchor" href="#%d0%bc%d0%be%d0%b4%d0%b5%d0%bb%d1%8c-%d0%bf%d0%be%d0%b4-%d0%ba%d0%b0%d0%bf%d0%be%d1%82%d0%be%d0%bc-qwen36-35b-a3b-mlx-6bit">#</a>
</h2>
<p>За опencode в текущей сессии отвечает модель <strong>Qwen3.6-35B-A3B-MLX-6bit</strong>. Разберём, что это значит на практике.</p>
<p><strong>Qwen3.6</strong> — это семейство моделей от Alibaba Group, третье поколение архитектуры Qwen. Модель позиционируется как одна из лучших в классе open-weight моделей с 35 миллиардами параметров.</p>
<p><strong>35B-A3B</strong> — интересная архитектура. 35 миллиардов параметров, из которых активными при каждом проходе используется только ~3 миллиарда. Это Mixture-of-Experts (MoE) подход: модель активирует только нужные «экспертные» подсети для каждой задачи, что даёт скорость приближенную к гораздо меньшим моделям при качестве, сопоставимом с моделями в несколько раз большего размера.</p>
<p><strong>MLX</strong> — это фреймворк от Apple для запуска LLM на чипах Apple Silicon. MLX оптимизирует загрузку и выполнение моделей на M-сериях процессоров, обеспечивая эффективное использование unified memory.</p>
<p><strong>6bit</strong> — модель квантована до 6-битной точности. Это компромисс: при значительном уменьшении размера модели (примерно в 4 раза по сравнению с FP16) потери качества минимальны для большинства задач. Для написания текстов и работы с кодом 6-битная квантованная модель работает практически неотличимо от полной.</p>
<p><strong>Почему это важно для написания постов.</strong> Модель достаточно ёмкая (35B total, 3B active), чтобы работать с длинными контекстами и сохранять логическую связность текста. Но при этом она runs locally на моей Mac-машине — никаких API-лимитов, задержек сети или отправки данных на сторону.</p>
<h2 class="heading" id="инструменты-и-mcp-серверы">
  Инструменты и MCP-серверы
  <a class="anchor" href="#%d0%b8%d0%bd%d1%81%d1%82%d1%80%d1%83%d0%bc%d0%b5%d0%bd%d1%82%d1%8b-%d0%b8-mcp-%d1%81%d0%b5%d1%80%d0%b2%d0%b5%d1%80%d1%8b">#</a>
</h2>
<p>Вот что подключено к opencode в ходе работы над этим постом:</p>
<h3 class="heading" id="hugo-mcp-сервер">
  Hugo MCP-сервер
  <a class="anchor" href="#hugo-mcp-%d1%81%d0%b5%d1%80%d0%b2%d0%b5%d1%80">#</a>
</h3>
<p>Позволяет агенту работать с Hugo-сайтом напрямую: проверять установку, список контента, собирать сайт, запускать локальный сервер. Это избавляет от необходимости вручную выполнять <code>hugo list</code>, <code>hugo --minify</code> — агент делает это через инструмент.</p>
<h3 class="heading" id="obsidian-mcp-сервер">
  Obsidian MCP-сервер
  <a class="anchor" href="#obsidian-mcp-%d1%81%d0%b5%d1%80%d0%b2%d0%b5%d1%80">#</a>
</h3>
<p>Дает доступ к моему Vault (<code>~/temp/git.evgn.ru/obsidian/vault/</code>) — это хранилище всех заметок, проектов и знаний. Через него агент:</p>
<ul>
<li>читает профиль проекта <code>Projects/Блог (Hugo).md</code>;</li>
<li>смотрит правила написания постов;</li>
<li>проверяет структуру и форматирование существующих статей.</li>
</ul>
<h3 class="heading" id="searxng-mcp-сервер">
  SearXNG MCP-сервер
  <a class="anchor" href="#searxng-mcp-%d1%81%d0%b5%d1%80%d0%b2%d0%b5%d1%80">#</a>
</h3>
<p>Поисковый агрегатор для веб-поиска через instance <code>search.evgn.ru</code>. Позволяет агенту находить актуальную информацию, если нужно проверить факты или найти внешние источники.</p>
<h3 class="heading" id="скиллы">
  Скиллы
  <a class="anchor" href="#%d1%81%d0%ba%d0%b8%d0%bb%d0%bb%d1%8b">#</a>
</h3>
<p>Скиллы — это специализированные инструкции, которые расширяют возможности агента для конкретных задач. В моём наборе есть скиллы для:</p>
<ul>
<li><strong>impeccable</strong> — аудит и улучшение frontend-интерфейсов;</li>
<li><strong>infra-audit</strong> — аудит self-hosted сервисов;</li>
<li><strong>himalaya-inbox-cleaner</strong> — чистка почтового ящика;</li>
<li><strong>memory-consolidate</strong> и <strong>memory-patcher</strong> — управление долгосрочной памятью;</li>
<li><strong>unified-search</strong> — универсальный поиск по всем источникам;</li>
<li><strong>obsidian-vault-mcp</strong> — работа с Obsidian.</li>
</ul>
<h2 class="heading" id="рабочий-процесс-как-создаётся-пост">
  Рабочий процесс: как создаётся пост
  <a class="anchor" href="#%d1%80%d0%b0%d0%b1%d0%be%d1%87%d0%b8%d0%b9-%d0%bf%d1%80%d0%be%d1%86%d0%b5%d1%81%d1%81-%d0%ba%d0%b0%d0%ba-%d1%81%d0%be%d0%b7%d0%b4%d0%b0%d1%91%d1%82%d1%81%d1%8f-%d0%bf%d0%be%d1%81%d1%82">#</a>
</h2>
<p>Процесс создания этого поста прошёл через несколько этапов, каждый из которых агент выполнял автономно:</p>
<h3 class="heading" id="1-изучение-контекста">
  1. Изучение контекста
  <a class="anchor" href="#1-%d0%b8%d0%b7%d1%83%d1%87%d0%b5%d0%bd%d0%b8%d0%b5-%d0%ba%d0%be%d0%bd%d1%82%d0%b5%d0%ba%d1%81%d1%82%d0%b0">#</a>
</h3>
<p>Первое, что сделал opencode — загрузил профиль проекта из Obsidian. Это заняло пару секунд: чтение <code>Projects/Блог (Hugo).md</code> и <code>References/Управление блогом через MCP Hugo.md</code>. Модель получила полную картину: структуру репозитория, правила постов, CI/CD-процесс, технический стек.</p>
<h3 class="heading" id="2-анализ-существующих-постов">
  2. Анализ существующих постов
  <a class="anchor" href="#2-%d0%b0%d0%bd%d0%b0%d0%bb%d0%b8%d0%b7-%d1%81%d1%83%d1%89%d0%b5%d1%81%d1%82%d0%b2%d1%83%d1%8e%d1%89%d0%b8%d1%85-%d0%bf%d0%be%d1%81%d1%82%d0%be%d0%b2">#</a>
</h3>
<p>Агент прочитал несколько предыдущих статей, чтобы понять стиль и формат. Особенно важен пост «Пишем посты с Codex» — он задаёт тон для материалов об автоматизации. Также был изучён релизный пост про Hugo 0.164.0 — это референс для технической глубины и структуры.</p>
<h3 class="heading" id="3-проверка-актуальности">
  3. Проверка актуальности
  <a class="anchor" href="#3-%d0%bf%d1%80%d0%be%d0%b2%d0%b5%d1%80%d0%ba%d0%b0-%d0%b0%d0%ba%d1%82%d1%83%d0%b0%d0%bb%d1%8c%d0%bd%d0%be%d1%81%d1%82%d0%b8">#</a>
</h3>
<p>Агент определил текущее время (МСК, 12:19) и сгенерировал дату поста <code>2026-07-21T12:14:00+03:00</code> — на 5 минут в прошлом, как требуют правила. Это важно: пост не должен оказаться в <code>future</code>, иначе CI его не опубликует.</p>
<h3 class="heading" id="4-написание-текста">
  4. Написание текста
  <a class="anchor" href="#4-%d0%bd%d0%b0%d0%bf%d0%b8%d1%81%d0%b0%d0%bd%d0%b8%d0%b5-%d1%82%d0%b5%d0%ba%d1%81%d1%82%d0%b0">#</a>
</h3>
<p>Самая сложная часть. Агент сгенерировал текст, опираясь на:</p>
<ul>
<li>правила из <code>AGENTS.md</code> (русский язык, минимум 2 эмодзи, структура с разделами);</li>
<li>знание модели (Qwen3.6-35B-A3B-MLX-6bit, MoE, MLX, 6bit);</li>
<li>контекст из Obsidian (правила фронтматтера, теги, toc);</li>
<li>личный опыт автора (реальные инструменты, репозитории, инфраструктура).</li>
</ul>
<p>Текст разделён на смысловые блоки: введение, описание модели, инструменты, рабочий процесс. Каждый раздел содержит конкретные детали, а не общие фразы.</p>
<h3 class="heading" id="5-техническая-валидация">
  5. Техническая валидация
  <a class="anchor" href="#5-%d1%82%d0%b5%d1%85%d0%bd%d0%b8%d1%87%d0%b5%d1%81%d0%ba%d0%b0%d1%8f-%d0%b2%d0%b0%d0%bb%d0%b8%d0%b4%d0%b0%d1%86%d0%b8%d1%8f">#</a>
</h3>
<p>После написания текста агент проверил фронтматтер: формат даты, tags (взял из существующих постов), toc/readTime enabled. Summary и description — разные, без дублирования.</p>
<h3 class="heading" id="6-публикация">
  6. Публикация
  <a class="anchor" href="#6-%d0%bf%d1%83%d0%b1%d0%bb%d0%b8%d0%ba%d0%b0%d1%86%d0%b8%d1%8f">#</a>
</h3>
<p>Финальный шаг — <code>git commit</code> и <code>git push</code> в ветку <code>main</code>. После этого CI/CD через Forgejo Actions автоматически соберёт сайт, проиндексирует поиск Pagefind и деплоит через rsync на сервер.</p>
<h2 class="heading" id="что-работает-хорошо-а-что--нет">
  Что работает хорошо, а что — нет
  <a class="anchor" href="#%d1%87%d1%82%d0%be-%d1%80%d0%b0%d0%b1%d0%be%d1%82%d0%b0%d0%b5%d1%82-%d1%85%d0%be%d1%80%d0%be%d1%88%d0%be-%d0%b0-%d1%87%d1%82%d0%be--%d0%bd%d0%b5%d1%82">#</a>
</h2>
<h3 class="heading" id="сильные-стороны">
  Сильные стороны
  <a class="anchor" href="#%d1%81%d0%b8%d0%bb%d1%8c%d0%bd%d1%8b%d0%b5-%d1%81%d1%82%d0%be%d1%80%d0%be%d0%bd%d1%8b">#</a>
</h3>
<ul>
<li><strong>Контекстная осведомлённость.</strong> Агент читает Obsidian и знает о проекте больше, чем «чистый» LLM-чат.</li>
<li><strong>Автоматизация рутины.</strong> Фронтматтер, дата, теги, проверка future-дат — всё это агент делает сам.</li>
<li><strong>Локальность.</strong> Модель работает на Mac, данные не покидают машину. Это важно для приватности и скорости.</li>
<li><strong>Скиллы.</strong> Специализированные инструкции позволяют агенту быстро переключаться между задачами: сегодня пишет пост, завтра чистит почту.</li>
</ul>
<h3 class="heading" id="слабые-места">
  Слабые места
  <a class="anchor" href="#%d1%81%d0%bb%d0%b0%d0%b1%d1%8b%d0%b5-%d0%bc%d0%b5%d1%81%d1%82%d0%b0">#</a>
</h3>
<ul>
<li><strong>Стиль.</strong> Текст агента иногда слишком «структурирован» — разделы идут как по шаблону, без естественных отклонений. Авторская редактура важна не для «исправления ошибок», а для добавления живости.</li>
<li><strong>Глубина технических деталей.</strong> Агент знает, что модель называется Qwen3.6-35B-A3B-MLX-6bit, но может ошибиться в архитектурных нюансах. MoE — это Mixture of Experts, а не какая-то абстрактная физика: агент описывает её на основе общих паттернов, а не реального опыта.</li>
<li><strong>Эмоциональная тональность.</strong> Агент хорошо справляется с информационным содержанием, но тон текста часто остаётся «нейтрально-аналитическим». Авторская правка добавляет иронию, личные наблюдения, интонацию.</li>
</ul>
<h2 class="heading" id="почему-это-вообще-имеет-смысл">
  Почему это вообще имеет смысл
  <a class="anchor" href="#%d0%bf%d0%be%d1%87%d0%b5%d0%bc%d1%83-%d1%8d%d1%82%d0%be-%d0%b2%d0%be%d0%be%d0%b1%d1%89%d0%b5-%d0%b8%d0%bc%d0%b5%d0%b5%d1%82-%d1%81%d0%bc%d1%8b%d1%81%d0%bb">#</a>
</h2>
<p>Главный вопрос: зачем писать пост об ИИ, который пишет посты?</p>
<p>Потому что это не новый способ «генерации контента». Это новый способ <strong>разделения труда</strong>.</p>
<p>Автор остаётся там, где он уникально полезен:</p>
<ul>
<li>формулирует идею и позицию;</li>
<li>добавляет личный опыт и фактуру;</li>
<li>контролирует логику аргументации;</li>
<li>решает, что стоит рассказать, а что — нет.</li>
</ul>
<p>Агент берёт на себя:</p>
<ul>
<li>поиск и структурирование контекста;</li>
<li>черновую сборку текста из тезисов;</li>
<li>техническое оформление (фронтматтер, теги, форматирование);</li>
<li>валидацию перед публикацией.</li>
</ul>
<p>Результат — не «ИИ написал статью», а «автор написал статью быстрее и увереннее, потому что инструмент снял операционную нагрузку».</p>
<h2 class="heading" id="сравнение-с-codex-два-инструмента-разные-роли">
  Сравнение с Codex: два инструмента, разные роли
  <a class="anchor" href="#%d1%81%d1%80%d0%b0%d0%b2%d0%bd%d0%b5%d0%bd%d0%b8%d0%b5-%d1%81-codex-%d0%b4%d0%b2%d0%b0-%d0%b8%d0%bd%d1%81%d1%82%d1%80%d1%83%d0%bc%d0%b5%d0%bd%d1%82%d0%b0-%d1%80%d0%b0%d0%b7%d0%bd%d1%8b%d0%b5-%d1%80%d0%be%d0%bb%d0%b8">#</a>
</h2>
<p>Codex и opencode — это не конкуренты, а взаимодополняющие инструменты. Вот как они отличаются в моём рабочем процессе:</p>
<table>
	<thead>
			<tr>
					<th>Аспект</th>
					<th>Codex</th>
					<th>opencode</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td>Модель</td>
					<td>Claude (через API)</td>
					<td>Qwen3.6-35B-MLX (локально)</td>
			</tr>
			<tr>
					<td>Доступ к файлам</td>
					<td>Через терминал</td>
					<td>MCP-серверы (Hugo, Obsidian)</td>
			</tr>
			<tr>
					<td>Скиллы</td>
					<td>Нет</td>
					<td>Специализированные инструкции</td>
			</tr>
			<tr>
					<td>Контекст проекта</td>
					<td>Только текущий репозиторий</td>
					<td>Obsidian Vault + репозитории</td>
			</tr>
			<tr>
					<td>Конфиденциальность</td>
					<td>Данные уходят в API</td>
					<td>Всё локально</td>
			</tr>
	</tbody>
</table>
<p>Codex лучше подходит для сложных задач, где нужна максимальная «интеллигентность» — анализ архитектуры, написание кода, глубокие рассуждения. opencode — для задач, где важна скорость, локальность и работа с известным контекстом.</p>
<p>Для блога opencode сейчас работает лучше: он знает правила, структуру и стиль проекта через Obsidian, и не требует API-доступа.</p>
<h2 class="heading" id="итог-">
  Итог 🧠
  <a class="anchor" href="#%d0%b8%d1%82%d0%be%d0%b3-">#</a>
</h2>
<p>Написание этого поста — не трюк и не маркетинговая демонстрация. Это рабочий процесс, который я использую регулярно:</p>
<ol>
<li><strong>Идея</strong> — от автора.</li>
<li><strong>Контекст</strong> — агент собирает из Obsidian и репозитория.</li>
<li><strong>Черновик</strong> — агент собирает из тезисов и контекста.</li>
<li><strong>Редактура</strong> — автор добавляет фактуру, иронию, личный опыт.</li>
<li><strong>Техника</strong> — агент оформляет фронтматтер, проверяет дату, делает commit/push.</li>
<li><strong>Деплой</strong> — CI/CD собирает и публикует.</li>
</ol>
<p>Модель Qwen3.6-35B-A3B-MLX-6bit — хороший выбор для этого: достаточно ёмкая для понимания контекста, достаточно быстрая для итеративной работы, достаточно локальная для приватности.</p>
<p>А opencode — это не просто «ещё один ИИ-ассистент». Это инструмент, который объединяет модель, скиллы и MCP-серверы в единый рабочий процесс. И для блога на Hugo это сейчас оптимальная комбинация: быстро, локально, с полным знанием контекста.</p>
<h2 class="heading" id="источники">
  Источники
  <a class="anchor" href="#%d0%b8%d1%81%d1%82%d0%be%d1%87%d0%bd%d0%b8%d0%ba%d0%b8">#</a>
</h2>
<ul>
<li>Qwen3.6: <a href="https://qwenlm.github.io/">Alibaba Group — Qwen</a></li>
<li>MLX: <a href="https://ml-explore.github.io/mlx/">Apple MLX</a></li>
<li>opencode: <a href="https://opencode.ai">opencode.ai</a></li>
</ul>
]]></content:encoded><category>ai-инструменты</category><category>автоматизация</category><category>hugo</category></item><item><title>Hugo 0.164.0: тёмно-светлые пары Chroma и починка регрессии производительности 🎨</title><link>https://kushnaren.co/posts/2026-07-19-hugo-0-164-0-chroma-dark-light/</link><pubDate>Sun, 19 Jul 2026 14:05:00 +0300</pubDate><guid isPermaLink="true">https://kushnaren.co/posts/2026-07-19-hugo-0-164-0-chroma-dark-light/</guid><description>Обзор Hugo 0.164.0 (6 июля 2026): dark/light-режимы стилей Chroma и новые флаги hugo gen chromastyles, фикс регрессии производительности из 0.128.0, новые шаблонные функции crypto.Hash, encoding.HexEncode и encoding.HexDecode, markup.rst.syntaxHighlight, поддержка цитат в Pandoc, вложенные пути в layouts для Page.Render. Депрекейт resources.PostProcess в пользу templates.Defer. Практический разбор с точки зрения блога на Hugo и обновление сборочного образа с Node 20 (EOL) на Node 24.</description><content:encoded><![CDATA[<h2 class="heading" id="почему-это-стоит-прочитать">
  Почему это стоит прочитать
  <a class="anchor" href="#%d0%bf%d0%be%d1%87%d0%b5%d0%bc%d1%83-%d1%8d%d1%82%d0%be-%d1%81%d1%82%d0%be%d0%b8%d1%82-%d0%bf%d1%80%d0%be%d1%87%d0%b8%d1%82%d0%b0%d1%82%d1%8c">#</a>
</h2>
<p>С прошлого разбора прошёл ровно месяц: <a href="https://github.com/gohugoio/hugo/releases/tag/v0.163.3">0.163.3</a> вышел 18 июня, <a href="https://github.com/gohugoio/hugo/releases/tag/v0.164.0">0.164.0</a> — 6 июля. После «квартала инфраструктурного взросления» с AVIF и хардненингом этот релиз выглядит скромнее: одна минорная версия, никаких громких фич.</p>
<p>Но два пункта в нём заслуживают внимания:</p>
<ol>
<li><strong>Стили Chroma получили dark/light-пары.</strong> Подсветка кода наконец умеет жить в двух темах штатно, а не через самодельные костыли.</li>
<li><strong>Починена регрессия производительности, тянувшаяся с 0.128.0.</strong> Это не новая фича, а возврат утраченного — но на больших сайтах разница заметна.</li>
</ol>
<p>Остальное — приятные мелочи в шаблонных функциях и один депрекейт. Breaking changes как таковых нет, обновление спокойное.</p>
<h2 class="heading" id="главное-за-один-взгляд">
  Главное за один взгляд
  <a class="anchor" href="#%d0%b3%d0%bb%d0%b0%d0%b2%d0%bd%d0%be%d0%b5-%d0%b7%d0%b0-%d0%be%d0%b4%d0%b8%d0%bd-%d0%b2%d0%b7%d0%b3%d0%bb%d1%8f%d0%b4">#</a>
</h2>
<p><strong>Фичи:</strong></p>
<ul>
<li><strong>Dark/light-пары в стилях Chroma</strong> — подсветка синтаксиса умеет два режима; у команды <a href="https://gohugo.io/commands/hugo_gen_chromastyles/"><code>hugo gen chromastyles</code></a> появились новые флаги.</li>
<li><strong>Новые шаблонные функции</strong>: <a href="https://gohugo.io/functions/crypto/hash/"><code>crypto.Hash</code></a>, <a href="https://gohugo.io/functions/encoding/hexencode/"><code>encoding.HexEncode</code></a>, <a href="https://gohugo.io/functions/encoding/hexdecode/"><code>encoding.HexDecode</code></a>.</li>
<li><strong>Опция <a href="https://gohugo.io/configuration/markup/#syntaxhighlight"><code>markup.rst.syntaxHighlight</code></a></strong> — подсветка для reStructuredText.</li>
<li><strong>Поддержка цитат в Pandoc</strong> — для тех, кто держит библиографию.</li>
<li><strong>Вложенные пути в layouts</strong> для <a href="https://gohugo.io/methods/page/render/#article"><code>Page.Render</code></a>.</li>
<li><strong>Фикс регрессии производительности из 0.128.0</strong> — <a href="https://discourse.gohugo.io/t/hugo-building-slowly-from-release-0-128-0/57314/20">обсуждение на Discourse</a> тянулось долго.</li>
</ul>
<p><strong>Депрекейт:</strong></p>
<ul>
<li><code>resources.PostProcess</code> объявлен устаревшим в пользу <code>templates.Defer</code> (issue <a href="https://github.com/gohugoio/hugo/issues/15086">#15086</a>).</li>
</ul>
<p><strong>Мелочи, которые могут задеть:</strong></p>
<ul>
<li>Поиск имени шаблона стал <strong>регистронезависимым</strong> (<a href="https://github.com/gohugoio/hugo/issues/15057">#15057</a>).</li>
<li><code>.Render</code> теперь <strong>возвращает ошибку</strong>, если шаблон не найден (<a href="https://github.com/gohugoio/hugo/issues/15052">#15052</a>) — раньше молча отдавал пустоту.</li>
<li><code>IsSet</code> включает ключ в предупреждение о неподдерживаемом типе.</li>
</ul>
<h2 class="heading" id="darklight-в-chroma-">
  Dark/light в Chroma 🌗
  <a class="anchor" href="#darklight-%d0%b2-chroma-">#</a>
</h2>
<p>Главная фича релиза — и, пожалуй, самая недооценённая.</p>
<p>Раньше стиль подсветки в Hugo был один на весь сайт: в <code>hugo.toml</code> задавался <code>markup.highlight.style</code>, и всё. Если сайт умеет переключаться между светлой и тёмной темой, приходилось выкручиваться: генерировать два CSS-файла через <code>hugo gen chromastyles</code>, руками оборачивать их в медиа-запросы или классы, следить за синхронизацией.</p>
<p>Теперь Chroma внутри Hugo знает про <a href="https://gohugo.io/quick-reference/syntax-highlighting-styles/#modes">парные режимы</a>, а у <code>hugo gen chromastyles</code> появились флаги для генерации нужного варианта. Смысл простой: светлая и тёмная схемы подсветки — это не два несвязанных стиля, а пара, и Hugo теперь так к ним и относится.</p>
<p><strong>Что это значит для нашего блога.</strong> Прямое попадание. Переключатель дня и ночи здесь работает на JS с сохранением выбора в <code>localStorage</code> — то есть тема меняется без перезагрузки, и подсветка кода должна меняться вместе с ней. Сейчас в конфиге один <code>[markup.highlight]</code> на оба режима, и в тёмной теме блоки кода выглядят компромиссно. Это следующий пункт в списке доработок: сгенерировать пару стилей и подцепить их к тому же переключателю. В этот заход не делаю — обновление и так вышло насыщенным, — но фича переехала из «знать» в «внедрять».</p>
<h2 class="heading" id="регрессия-производительности-возврат-утраченного-">
  Регрессия производительности: возврат утраченного ⚡
  <a class="anchor" href="#%d1%80%d0%b5%d0%b3%d1%80%d0%b5%d1%81%d1%81%d0%b8%d1%8f-%d0%bf%d1%80%d0%be%d0%b8%d0%b7%d0%b2%d0%be%d0%b4%d0%b8%d1%82%d0%b5%d0%bb%d1%8c%d0%bd%d0%be%d1%81%d1%82%d0%b8-%d0%b2%d0%be%d0%b7%d0%b2%d1%80%d0%b0%d1%82-%d1%83%d1%82%d1%80%d0%b0%d1%87%d0%b5%d0%bd%d0%bd%d0%be%d0%b3%d0%be-">#</a>
</h2>
<p>Незаметная, но приятная часть. В 0.128.0 (это июль 2024-го) в сборку просочилась регрессия, из-за которой большие сайты собирались медленнее. Симптом обсуждали на Discourse больше года, и вот в 0.164.0 его закрыли.</p>
<p>Ремарка из release notes честная: эффект заметен <strong>в первую очередь на крупных сайтах</strong>. Наш блог — около сотни страниц, и на таком объёме разница в пределах шума. Но сама история поучительна: регрессия прожила полтора года и полтора десятка релизов, потому что на маленьких сайтах её просто не видно.</p>
<h2 class="heading" id="новые-функции-cryptohash-и-hex-">
  Новые функции: crypto.Hash и hex 🔧
  <a class="anchor" href="#%d0%bd%d0%be%d0%b2%d1%8b%d0%b5-%d1%84%d1%83%d0%bd%d0%ba%d1%86%d0%b8%d0%b8-cryptohash-%d0%b8-hex-">#</a>
</h2>
<p>Три новые шаблонные функции:</p>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go-html-template" data-lang="go-html-template"><span class="line"><span class="cl"><span class="cp">{{</span><span class="w"> </span><span class="nx">crypto</span><span class="na">.Hash</span><span class="w"> </span><span class="s">&#34;sha256&#34;</span><span class="w"> </span><span class="s">&#34;текст&#34;</span><span class="w"> </span><span class="cp">}}</span>
</span></span><span class="line"><span class="cl"><span class="cp">{{</span><span class="w"> </span><span class="nx">encoding</span><span class="na">.HexEncode</span><span class="w"> </span><span class="s">&#34;привет&#34;</span><span class="w"> </span><span class="cp">}}</span>
</span></span><span class="line"><span class="cl"><span class="cp">{{</span><span class="w"> </span><span class="nx">encoding</span><span class="na">.HexDecode</span><span class="w"> </span><span class="s">&#34;d0bfd180d0b8d0b2d0b5d182&#34;</span><span class="w"> </span><span class="cp">}}</span></span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<p><code>crypto.Hash</code> принимает алгоритм явным параметром — удобнее, чем существующие <code>md5</code>/<code>sha1</code>/<code>sha256</code> по отдельности. Практический сценарий — стабильные идентификаторы: захешировать путь или содержимое и получить детерминированный ключ для кэша, якоря или имени файла.</p>
<p>Hex-функции закрывают давнюю мелочь: base64 в шаблонах был, а hex приходилось изображать вручную.</p>
<p>Для нашего блога — пока в копилку. Ни одного места, где это было бы нужно прямо сейчас, нет.</p>
<h2 class="heading" id="депрекейт-resourcespostprocess-">
  Депрекейт resources.PostProcess ⚠️
  <a class="anchor" href="#%d0%b4%d0%b5%d0%bf%d1%80%d0%b5%d0%ba%d0%b5%d0%b9%d1%82-resourcespostprocess-">#</a>
</h2>
<p>Единственное, за чем стоит следить.</p>
<p><code>resources.PostProcess</code> использовался для отложенной обработки ресурсов — классический сценарий — PurgeCSS/Tailwind, когда нужно узнать финальный HTML, чтобы вычистить неиспользуемые классы. Теперь рекомендуется <code>templates.Defer</code>, механизм более общий и предсказуемый.</p>
<p><strong>Нас не задевает</strong>: проверил <code>layouts/</code> и <code>themes/</code> — <code>resources.PostProcess</code> не используется нигде. CSS через Hugo Pipes с Tailwind мы не собираем, а Pagefind живёт отдельным npm-инструментом и к ресурсной цепочке отношения не имеет.</p>
<p>Если у вас Tailwind в Pipes — это первое, что нужно проверить перед обновлением: депрекейт пока не ломает, но направление задано.</p>
<h2 class="heading" id="осторожно-render-теперь-возвращает-ошибку">
  Осторожно: <code>.Render</code> теперь возвращает ошибку
  <a class="anchor" href="#%d0%be%d1%81%d1%82%d0%be%d1%80%d0%be%d0%b6%d0%bd%d0%be-render-%d1%82%d0%b5%d0%bf%d0%b5%d1%80%d1%8c-%d0%b2%d0%be%d0%b7%d0%b2%d1%80%d0%b0%d1%89%d0%b0%d0%b5%d1%82-%d0%be%d1%88%d0%b8%d0%b1%d0%ba%d1%83">#</a>
</h2>
<p>Мелочь из списка изменений, которая может неприятно удивить. Раньше <code>.Render</code> с несуществующим шаблоном молча отдавал пустую строку — и сайт собирался, просто без куска контента. Теперь он <strong>возвращает ошибку</strong>, то есть сборка упадёт.</p>
<p>Формально это исправление, а не breaking change: молчаливая пустота — плохое поведение. Но если у вас в шаблонах есть вызов <code>.Render</code> с опечаткой в имени, который «работал» годами, — обновление его вскроет. Заодно поиск имени шаблона стал регистронезависимым, так что часть таких опечаток теперь, наоборот, начнёт находиться.</p>
<h2 class="heading" id="инфраструктура-заодно-поменяли-базу-образа-">
  Инфраструктура: заодно поменяли базу образа 🐳
  <a class="anchor" href="#%d0%b8%d0%bd%d1%84%d1%80%d0%b0%d1%81%d1%82%d1%80%d1%83%d0%ba%d1%82%d1%83%d1%80%d0%b0-%d0%b7%d0%b0%d0%be%d0%b4%d0%bd%d0%be-%d0%bf%d0%be%d0%bc%d0%b5%d0%bd%d1%8f%d0%bb%d0%b8-%d0%b1%d0%b0%d0%b7%d1%83-%d0%be%d0%b1%d1%80%d0%b0%d0%b7%d0%b0-">#</a>
</h2>
<p>Здесь стоит рассказать про то, что к самому Hugo отношения не имеет, но всплыло при обновлении.</p>
<p>Блог собирается в собственном Docker-образе, куда запечены Hugo Extended, Node и Pagefind. Пошёл поднимать версию Hugo — и обнаружил, что база образа <code>node:20-bookworm-slim</code> <strong>достигла EOL 30 апреля 2026</strong>. То есть почти три месяца образ жил без обновлений безопасности базового слоя.</p>
<p>Node здесь нужен ровно для одного — установить Pagefind. Поэтому смена мажора малорискованная, и база переехала сразу на <strong>Node 24</strong> (LTS, поддержка до апреля 2028). Итоговый образ:</p>
<div class="code-block">
  <pre tabindex="0"><code>hugo v0.164.0+extended linux/amd64
node v24.18.0
pagefind 1.5.2</code></pre>
  <button class="copy-code-button">copy</button>
</div>
<p>Мораль простая и не новая: <strong>следите не только за приложением, но и за базовым слоем</strong>. Версию Hugo видно в каждом релизном посте, а <code>FROM node:20</code> тихо стареет в первой строке Dockerfile, пока про него не вспомнишь.</p>
<p>Отдельная заметка на будущее — образ до сих пор собирался руками, поэтому и отстал. Правильный путь: собирать его в CI при изменении Dockerfile. У сборки на нашем раннере есть нюанс — он живёт в LXC-контейнере, где <code>docker build</code> не может применить AppArmor к промежуточным RUN-контейнерам и падает. Обходится это kaniko: он собирает образ в userspace, без демона Docker и вложенных контейнеров. Тот же приём уже используется для других наших образов.</p>
<h2 class="heading" id="что-это-значит-для-нашего-блога">
  Что это значит для нашего блога
  <a class="anchor" href="#%d1%87%d1%82%d0%be-%d1%8d%d1%82%d0%be-%d0%b7%d0%bd%d0%b0%d1%87%d0%b8%d1%82-%d0%b4%d0%bb%d1%8f-%d0%bd%d0%b0%d1%88%d0%b5%d0%b3%d0%be-%d0%b1%d0%bb%d0%be%d0%b3%d0%b0">#</a>
</h2>
<ul>
<li><strong>Chroma dark/light</strong> — самая полезная фича релиза именно для нас, ложится на существующий переключатель темы. В работу.</li>
<li><strong>Фикс производительности</strong> — приятно, но на сотне страниц незаметно.</li>
<li><strong>Депрекейт <code>PostProcess</code></strong> — не задевает, проверено.</li>
<li><strong><code>.Render</code> с ошибкой</strong> — не задевает, но стоит держать в голове.</li>
<li><strong>Обновление базы образа с Node 20 на Node 24</strong> — по факту важнее самого апдейта Hugo.</li>
</ul>
<h2 class="heading" id="чек-лист-обновления-">
  Чек-лист обновления ✅
  <a class="anchor" href="#%d1%87%d0%b5%d0%ba-%d0%bb%d0%b8%d1%81%d1%82-%d0%be%d0%b1%d0%bd%d0%be%d0%b2%d0%bb%d0%b5%d0%bd%d0%b8%d1%8f-">#</a>
</h2>
<ol>
<li>
<p><strong>Обновление спокойное.</strong> С 0.163.x на 0.164.0 идти можно без подготовки: breaking changes нет, депрекейт один.</p>
</li>
<li>
<p><strong>Если используете <code>resources.PostProcess</code></strong> (обычно это Tailwind/PurgeCSS в Pipes) — запланируйте переход на <code>templates.Defer</code>:</p>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">grep -rn <span class="s1">&#39;resources.PostProcess&#39;</span> layouts/ themes/</span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
</li>
<li>
<p><strong>Если в шаблонах есть <code>.Render</code></strong> — проверьте имена шаблонов: теперь несуществующий шаблон роняет сборку, а не молчит.</p>
</li>
<li>
<p><strong>Если у сайта есть тёмная тема</strong> — посмотрите на парные стили Chroma, это заметное упрощение по сравнению с самодельными решениями.</p>
</li>
<li>
<p><strong>Проверьте базовый слой сборочного образа</strong>, а не только версию Hugo. Node 20 в EOL с 30 апреля 2026:</p>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">grep -n <span class="s1">&#39;^FROM&#39;</span> Docker/Dockerfile</span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
</li>
<li>
<p><strong>Стандартный прогон</strong> и сверка предупреждений до и после:</p>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">hugo --minify --gc</span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
</li>
</ol>
<h2 class="heading" id="итог-">
  Итог 🧠
  <a class="anchor" href="#%d0%b8%d1%82%d0%be%d0%b3-">#</a>
</h2>
<p>0.164.0 — релиз-передышка после насыщенного квартала. Одна по-настоящему полезная фича (парные стили Chroma), одно давно ожидавшееся исправление (регрессия скорости из 0.128.0), горсть новых шаблонных функций и один аккуратный депрекейт.</p>
<p>Обновляться стоит: рисков практически нет, а dark/light-подсветка снимает целый класс костылей для сайтов с переключателем темы.</p>
<p>Но главный вывод этого обновления оказался не про Hugo. Версию генератора видно в каждом релизном посте, а базовый слой образа стареет молча — и именно он оказался просроченным на три месяца, а не Hugo, отставший на одну минорную версию.</p>
<h2 class="heading" id="источники">
  Источники
  <a class="anchor" href="#%d0%b8%d1%81%d1%82%d0%be%d1%87%d0%bd%d0%b8%d0%ba%d0%b8">#</a>
</h2>
<ul>
<li>Релиз 0.164.0: <a href="https://github.com/gohugoio/hugo/releases/tag/v0.164.0">gohugoio/hugo v0.164.0</a></li>
<li>Режимы стилей подсветки: <a href="https://gohugo.io/quick-reference/syntax-highlighting-styles/#modes">gohugo.io/quick-reference/syntax-highlighting-styles/#modes</a></li>
<li><code>crypto.Hash</code>: <a href="https://gohugo.io/functions/crypto/hash/">gohugo.io/functions/crypto/hash/</a></li>
<li><code>encoding.HexEncode</code>: <a href="https://gohugo.io/functions/encoding/hexencode/">gohugo.io/functions/encoding/hexencode/</a></li>
<li>Обсуждение регрессии производительности: <a href="https://discourse.gohugo.io/t/hugo-building-slowly-from-release-0-128-0/57314/20">discourse.gohugo.io</a></li>
<li>График поддержки Node.js: <a href="https://endoflife.date/nodejs">endoflife.date/nodejs</a></li>
</ul>
]]></content:encoded><category>hugo</category><category>релизы</category></item><item><title>Что нового в Hugo 0.161–0.163: AVIF, хардненинг и гибкие permalinks 🚀</title><link>https://kushnaren.co/posts/2026-06-19-hugo-0-161-0-163-avif-i-hardening/</link><pubDate>Fri, 19 Jun 2026 07:49:52 +0300</pubDate><guid isPermaLink="true">https://kushnaren.co/posts/2026-06-19-hugo-0-161-0-163-avif-i-hardening/</guid><description>Подробный обзор Hugo 0.161.0–0.163.3: поддержка AVIF (encoder+decoder) и его тюнинг (quality 60, content-aware chroma), хардненинг безопасности (Node permission-флаг, security.allowContent, http.urls, Go 1.26.3 XSS-фиксы), slice-based permalinks с target-матчерами, гибкая схема идентификаторов в именах файлов, депрекейты IsNode и глобального imaging.quality. Практические сценарии и чек-лист миграции с 0.160.</description><content:encoded><![CDATA[<h2 class="heading" id="почему-это-стоит-прочитать">
  Почему это стоит прочитать
  <a class="anchor" href="#%d0%bf%d0%be%d1%87%d0%b5%d0%bc%d1%83-%d1%8d%d1%82%d0%be-%d1%81%d1%82%d0%be%d0%b8%d1%82-%d0%bf%d1%80%d0%be%d1%87%d0%b8%d1%82%d0%b0%d1%82%d1%8c">#</a>
</h2>
<p>С прошлого разбора (v0.160.1, 8 апреля) накопилось пять релизов: <a href="https://github.com/gohugoio/hugo/releases/tag/v0.161.0">0.161.0</a>, <a href="https://github.com/gohugoio/hugo/releases/tag/v0.161.1">0.161.1</a>, <a href="https://github.com/gohugoio/hugo/releases/tag/v0.162.0">0.162.0</a>, <a href="https://github.com/gohugoio/hugo/releases/tag/v0.163.0">0.163.0</a> и патчи до <a href="https://github.com/gohugoio/hugo/releases/tag/v0.163.3">0.163.3</a> (18 июня). Это не один минор, а целый квартал развития — поэтому разбор догоняющий.</p>
<p>Если сжать до двух заголовков, их два:</p>
<ol>
<li><strong>AVIF</strong> — Hugo научился кодировать и декодировать AVIF прямо в image pipeline. Третий формат рядом с JPEG и WebP, и для фото-блога это самое интересное.</li>
<li><strong>Хардненинг безопасности</strong> — Node-инструменты теперь запускаются с <code>--permission</code>, <code>text/html</code>-контент запрещён по умолчанию, ужесточены <code>security.http.urls</code>, плюс транзитом приехали XSS-фиксы из Go 1.26.3.</li>
</ol>
<p>Остальное — приятные улучшения конфигурации (slice-based permalinks, гибкие идентификаторы в именах файлов, вложенные vars в <code>css.Build</code>) и порция депрекейтов. Breaking changes есть, но точечные — разберём, кого они задевают.</p>
<h2 class="heading" id="главное-за-один-взгляд">
  Главное за один взгляд
  <a class="anchor" href="#%d0%b3%d0%bb%d0%b0%d0%b2%d0%bd%d0%be%d0%b5-%d0%b7%d0%b0-%d0%be%d0%b4%d0%b8%d0%bd-%d0%b2%d0%b7%d0%b3%d0%bb%d1%8f%d0%b4">#</a>
</h2>
<p><strong>v0.161.0 / 0.161.1 (28–29 апреля)</strong> — фичи + первый хардненинг:</p>
<ul>
<li>Node-инструменты (PostCSS, Babel, TailwindCSS) запускаются с флагом <code>--permission</code>. Нужен <strong>Node ≥ 22</strong>, а Tailwind теперь только как npm-пакет (standalone-бинарь больше не поддерживается).</li>
<li>Ужесточены дефолты <code>security.http.urls</code>; добавлен <code>security.node.permissions</code> (включая <code>AllowChildProcess</code>).</li>
<li><strong>Slice-based permalinks</strong> — конфигурация permalinks с <code>target</code>-матчерами (как в <code>cascade</code>).</li>
<li>Гибкая схема идентификаторов в именах файлов: <code>_language_en_</code>, <code>_role_</code>, <code>_version_</code>.</li>
<li>Вложенные vars в <code>css.Build</code> / <code>css.Sass</code>: <code>@import &quot;hugo:vars/dark&quot;</code>.</li>
</ul>
<p><strong>v0.162.0 / 0.162.1 (26–28 мая)</strong> — AVIF + security:</p>
<ul>
<li>🎯 <strong>Поддержка AVIF</strong> (encoder + decoder) в image pipeline.</li>
<li><strong><code>text/html</code>-контент запрещён по умолчанию</strong> — новая политика <code>security.allowContent</code>.</li>
<li>Go 1.26.3: фиксы XSS в <code>html/template</code> (CVE-2026-39826, CVE-2026-39823).</li>
<li>Проверка <code>security.http.urls</code> на каждом редирект-хопе <code>resources.GetRemote</code>; отказ от symlink-записей в <code>resources.Get</code>.</li>
</ul>
<p><strong>v0.163.0 (8 июня)</strong> — тюнинг AVIF + депрекейты:</p>
<ul>
<li>AVIF по умолчанию <code>quality = 60</code> (≈ JPEG/WebP q75), content-aware chroma subsampling через <code>hint</code>, качество настраивается <strong>per-format</strong>.</li>
<li>Депрекейт глобального <code>imaging.quality</code> и <code>Imaging.Compression</code> (переезжают в per-format конфиги).</li>
<li>Добавлен <code>.IsBranch</code>, депрекейт <code>.IsNode</code>; депрекейт <code>baseUrl</code> в jsconfig.</li>
</ul>
<p><strong>v0.163.1 / 0.163.2 / 0.163.3 (11–18 июня)</strong> — патчи:</p>
<ul>
<li>Security: bump <code>golang.org/x/image</code>, нормализация integer-IPv4 в <code>http.urls</code>, отказ от symlink в <code>os.ReadDir/ReadFile/Stat/FileExists</code>.</li>
<li>Escape <code>lang</code> в дефолтном рендере код-блоков; сохранение non-ASCII пробела после summary-разделителя; поддержка вариантов конфигов babel/postcss; фикс регрессии коллизии имён page/section.</li>
</ul>
<p>Дальше — что это значит на практике.</p>
<h2 class="heading" id="avif-третий-формат-в-pipeline-">
  AVIF: третий формат в pipeline 🖼️
  <a class="anchor" href="#avif-%d1%82%d1%80%d0%b5%d1%82%d0%b8%d0%b9-%d1%84%d0%be%d1%80%d0%bc%d0%b0%d1%82-%d0%b2-pipeline-">#</a>
</h2>
<p>Главная фича квартала. В 0.162.0 Hugo получил полноценную обработку AVIF — и кодер, и декодер (issue <a href="https://github.com/gohugoio/hugo/issues/7837">#7837</a>, висел с 2020 года). AVIF при том же визуальном качестве заметно легче JPEG и обычно легче WebP, плюс умеет HDR (у Hugo есть <a href="https://github.com/bep/hdrsdr.com">демо-сайт</a>, который имеет смысл смотреть на HDR-экране вроде Retina).</p>
<p>В 0.163.0 фичу довели до ума:</p>
<ul>
<li>Дефолтный <code>quality</code> для AVIF опустили до <strong>60</strong> — оказалось, JPEG/WebP с q75 сопоставимы с AVIF q60. Не гоните качество вверх по привычке.</li>
<li>Появился <code>hint</code> (как у WEBP): для <code>lossy</code> фото по умолчанию используется YUV420 chroma subsampling, а для текста/иконок/схем — 444. Это резко снижает память на кодирование больших картинок.</li>
<li>Качество можно задавать <strong>на формат</strong>:</li>
</ul>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-toml" data-lang="toml"><span class="line"><span class="cl"><span class="p">[</span><span class="nx">imaging</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">  <span class="c"># глобальный quality теперь deprecated</span>
</span></span><span class="line"><span class="cl"><span class="p">[</span><span class="nx">imaging</span><span class="p">.</span><span class="nx">webp</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">  <span class="nx">quality</span> <span class="p">=</span> <span class="mi">80</span>
</span></span><span class="line"><span class="cl"><span class="p">[</span><span class="nx">imaging</span><span class="p">.</span><span class="nx">avif</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">  <span class="nx">quality</span> <span class="p">=</span> <span class="mi">60</span>
</span></span><span class="line"><span class="cl">  <span class="nx">hint</span>    <span class="p">=</span> <span class="s2">&#34;photo&#34;</span></span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<p>В шаблоне AVIF получается так же, как WebP — через <code>.Process</code> / метод ресайза:</p>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go-html-template" data-lang="go-html-template"><span class="line"><span class="cl"><span class="cp">{{</span><span class="w"> </span><span class="nx">$img</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">resources</span><span class="na">.Get</span><span class="w"> </span><span class="s">&#34;img/cover.jpg&#34;</span><span class="w"> </span><span class="cp">}}</span>
</span></span><span class="line"><span class="cl"><span class="cp">{{</span><span class="w"> </span><span class="nx">$avif</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">$img</span><span class="na">.Process</span><span class="w"> </span><span class="s">&#34;resize 1600x avif&#34;</span><span class="w"> </span><span class="cp">}}</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">picture</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">source</span> <span class="na">srcset</span><span class="o">=</span><span class="s">&#34;</span><span class="cp">{{</span><span class="w"> </span><span class="nx">$avif</span><span class="na">.RelPermalink</span><span class="w"> </span><span class="cp">}}</span><span class="s">&#34;</span> <span class="na">type</span><span class="o">=</span><span class="s">&#34;image/avif&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">source</span> <span class="na">srcset</span><span class="o">=</span><span class="s">&#34;</span><span class="cp">{{</span><span class="w"> </span><span class="o">(</span><span class="nx">$img</span><span class="na">.Process</span><span class="w"> </span><span class="s">&#34;resize 1600x webp&#34;</span><span class="o">)</span><span class="na">.RelPermalink</span><span class="w"> </span><span class="cp">}}</span><span class="s">&#34;</span> <span class="na">type</span><span class="o">=</span><span class="s">&#34;image/webp&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">img</span> <span class="na">src</span><span class="o">=</span><span class="s">&#34;</span><span class="cp">{{</span><span class="w"> </span><span class="o">(</span><span class="nx">$img</span><span class="na">.Resize</span><span class="w"> </span><span class="s">&#34;1600x&#34;</span><span class="o">)</span><span class="na">.RelPermalink</span><span class="w"> </span><span class="cp">}}</span><span class="s">&#34;</span> <span class="na">alt</span><span class="o">=</span><span class="s">&#34;…&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">picture</span><span class="p">&gt;</span></span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<p><strong>Что это значит для нашего блога.</strong> Раздел <code>/photos</code> уже генерит 800/1600/2400 px в JPEG + WebP и отдаёт через <code>&lt;picture&gt;</code>/<code>srcset</code>. Добавить AVIF — это правка шаблона, который собирает <code>&lt;source&gt;</code>-ы (плюс per-format <code>quality</code> в <code>hugo.toml</code>): первым <code>&lt;source type=&quot;image/avif&quot;&gt;</code>, дальше WebP, в конце JPEG-фолбэк. Браузеры берут первый поддерживаемый. На фотографиях с retina это даст ощутимую экономию трафика при том же качестве. В этот заход не делаю — но это очевидный следующий шаг для фото-ленты.</p>
<h2 class="heading" id="хардненинг-безопасности-">
  Хардненинг безопасности 🔒
  <a class="anchor" href="#%d1%85%d0%b0%d1%80%d0%b4%d0%bd%d0%b5%d0%bd%d0%b8%d0%bd%d0%b3-%d0%b1%d0%b5%d0%b7%d0%be%d0%bf%d0%b0%d1%81%d0%bd%d0%be%d1%81%d1%82%d0%b8-">#</a>
</h2>
<p>Самая «breaking» часть. Изменения копились через все релизы:</p>
<p><strong>Node-инструменты под <code>--permission</code> (0.161.0).</strong> PostCSS, Babel и TailwindCSS теперь запускаются с Node permission-флагом и правами из <code>security.node.permissions</code>. Следствия:</p>
<ul>
<li>нужен <strong>Node ≥ 22</strong>;</li>
<li><code>css.TailwindCSS</code> требует Tailwind CLI как <strong>npm-пакет</strong> — standalone-бинарь больше не годится.</li>
</ul>
<p>Если вы собираете CSS через Hugo Pipes с Tailwind/PostCSS — это первое, что стоит проверить перед обновлением.</p>
<p><strong>Запрет <code>text/html</code>-контента по умолчанию (0.162.0).</strong> Новая политика <code>security.allowContent</code> гейтит, какие media-типы допустимы для страниц в <code>/content</code>. <code>text/html</code> теперь <strong>запрещён по умолчанию</strong>. Сайты, где есть руками написанные <code>.html</code>-файлы в <code>content/</code> (или их эмитит content adapter), вернут доступ явно:</p>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-toml" data-lang="toml"><span class="line"><span class="cl"><span class="p">[</span><span class="nx">security</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">  <span class="nx">allowContent</span> <span class="p">=</span> <span class="p">[</span><span class="s1">&#39;.*&#39;</span><span class="p">]</span></span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<p><strong>Прочее (0.162.0 → 0.163.3):</strong></p>
<ul>
<li><code>security.http.urls</code> перепроверяется на <strong>каждом</strong> редирект-хопе в <code>resources.GetRemote</code> — мимо валидации больше не проскочить через 30x.</li>
<li>Symlink-записи отклоняются в <code>resources.Get</code>, а в 0.163.1 — ещё и в <code>os.ReadDir/ReadFile/Stat/FileExists</code>.</li>
<li>Go подняли до 1.26.3 с фиксами XSS в <code>html/template</code> (CVE-2026-39826, CVE-2026-39823) — это касается любого сайта, рендерящего недоверенный ввод в шаблонах.</li>
</ul>
<p>Любопытная ремарка от мейнтейнера в release notes 0.163.1: всплеск security-репортов в последнее время — это не «Hugo стал менее безопасным», а работа новых AI-инструментов, которые берут <a href="https://gohugo.io/about/security/">security-модель Hugo</a> за baseline и методично её простукивают.</p>
<h2 class="heading" id="slice-based-permalinks-">
  Slice-based permalinks 🔗
  <a class="anchor" href="#slice-based-permalinks-">#</a>
</h2>
<p>В 0.161.0 конфигурация <code>permalinks</code> стала гибче (старая map-форма продолжает работать). Теперь это список с теми же <code>target</code>-матчерами, что и в <code>cascade</code>:</p>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">permalinks</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span>- <span class="nt">target</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">kind</span><span class="p">:</span><span class="w"> </span><span class="l">page</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">path</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;/books/**&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">pattern</span><span class="p">:</span><span class="w"> </span><span class="l">/books/:year/:slug/</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span>- <span class="nt">target</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">kind</span><span class="p">:</span><span class="w"> </span><span class="l">page</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">pattern</span><span class="p">:</span><span class="w"> </span><span class="l">/other/:slug/</span></span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<p>Удобно, когда для разных секций нужны разные схемы URL без дублирования настроек. Нашему блогу с плоской структурой <code>posts/</code> это пока избыточно, но знать про механизм полезно — особенно если когда-нибудь заведём разделы со своими правилами URL.</p>
<h2 class="heading" id="гибкие-идентификаторы-в-именах-файлов-">
  Гибкие идентификаторы в именах файлов 🏷️
  <a class="anchor" href="#%d0%b3%d0%b8%d0%b1%d0%ba%d0%b8%d0%b5-%d0%b8%d0%b4%d0%b5%d0%bd%d1%82%d0%b8%d1%84%d0%b8%d0%ba%d0%b0%d1%82%d0%be%d1%80%d1%8b-%d0%b2-%d0%b8%d0%bc%d0%b5%d0%bd%d0%b0%d1%85-%d1%84%d0%b0%d0%b9%d0%bb%d0%be%d0%b2-">#</a>
</h2>
<p>Тоже из 0.161.0. Раньше язык кодировался как <code>mypost.en.md</code>. Теперь доступна расширяемая схема префиксов в имени файла:</p>
<table>
	<thead>
			<tr>
					<th>Префикс</th>
					<th>Что задаёт</th>
					<th>Где применимо</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td><code>_language_</code></td>
					<td>Язык</td>
					<td>Контент и layout-файлы</td>
			</tr>
			<tr>
					<td><code>_role_</code></td>
					<td>Роль</td>
					<td>Контент и layout-файлы</td>
			</tr>
			<tr>
					<td><code>_version_</code></td>
					<td>Версия</td>
					<td>Контент и layout-файлы</td>
			</tr>
			<tr>
					<td><code>_outputformat_</code></td>
					<td>Output format</td>
					<td>Layout-файлы</td>
			</tr>
			<tr>
					<td><code>_kind_</code></td>
					<td>Page kind</td>
					<td>Layout-файлы</td>
			</tr>
	</tbody>
</table>
<p><code>content/mypost._language_en_.md</code> эквивалентно <code>content/mypost.en.md</code>, но открывает дорогу к версиям и ролям контента. Для одноязычного блога — мимо, для документации с версиями — заметное упрощение.</p>
<h2 class="heading" id="cssbuild-вложенные-vars-">
  css.Build: вложенные vars 🎨
  <a class="anchor" href="#cssbuild-%d0%b2%d0%bb%d0%be%d0%b6%d0%b5%d0%bd%d0%bd%d1%8b%d0%b5-vars-">#</a>
</h2>
<p>Развитие фичи из 0.160. К <code>@import &quot;hugo:vars&quot;</code> добавились <strong>вложенные</strong> наборы — <code>@import &quot;hugo:vars/&lt;name&gt;&quot;</code>. Классический сценарий — палитры под <code>prefers-color-scheme</code>:</p>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-toml" data-lang="toml"><span class="line"><span class="cl"><span class="p">[</span><span class="nx">params</span><span class="p">.</span><span class="nx">style</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">  <span class="nx">primary</span>    <span class="p">=</span> <span class="s2">&#34;#000000&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="nx">background</span> <span class="p">=</span> <span class="s2">&#34;#ffffff&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="p">[</span><span class="nx">params</span><span class="p">.</span><span class="nx">style</span><span class="p">.</span><span class="nx">dark</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">    <span class="nx">primary</span>    <span class="p">=</span> <span class="s2">&#34;#ffffff&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="nx">background</span> <span class="p">=</span> <span class="s2">&#34;#000000&#34;</span></span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-css" data-lang="css"><span class="line"><span class="cl"><span class="p">@</span><span class="k">import</span> <span class="s2">&#34;hugo:vars&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">@</span><span class="k">import</span> <span class="s2">&#34;hugo:vars/dark&#34;</span> <span class="o">(</span><span class="nt">prefers-color-scheme</span><span class="o">:</span> <span class="nt">dark</span><span class="o">)</span><span class="p">;</span></span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<p>Аккуратно, но не для нас: переключатель дня/ночи на блоге работает через JS и <code>localStorage</code> (явный выбор пользователя, без авто), а не через <code>prefers-color-scheme</code>. Палитра живёт в <code>:root</code>. Так что фича в копилку «знать», но не «внедрять».</p>
<h2 class="heading" id="депрекейты-и-мелочи">
  Депрекейты и мелочи
  <a class="anchor" href="#%d0%b4%d0%b5%d0%bf%d1%80%d0%b5%d0%ba%d0%b5%d0%b9%d1%82%d1%8b-%d0%b8-%d0%bc%d0%b5%d0%bb%d0%be%d1%87%d0%b8">#</a>
</h2>
<ul>
<li><strong><code>.IsNode</code> → <code>.IsBranch</code></strong> (0.163.0): если в шаблонах есть <code>.IsNode</code>, мигрируйте на <code>.IsBranch</code> (issue <a href="https://github.com/gohugoio/hugo/issues/11574">#11574</a>).</li>
<li><strong>Глобальный <code>imaging.quality</code></strong> (0.163.0): помечен deprecated в пользу per-format (<code>[imaging.webp]</code>, <code>[imaging.avif]</code>, …). Старая форма пока работает и даже не всегда ругается — но направление задано.</li>
<li><strong>jsconfig <code>baseUrl</code></strong> убран (был deprecated).</li>
<li><strong>Сохранение non-ASCII пробела после summary-разделителя</strong> (0.163.3) — мелочь, но именно для кириллических текстов с `</li>
</ul>
<p>` это правильное поведение.</p>
<ul>
<li><strong>Фикс коллизии имён page/section</strong> (0.163.3, <a href="https://github.com/gohugoio/hugo/issues/15046">#15046</a>) — регрессия, всплывшая в 0.163.x; ещё одна причина брать самый свежий патч, а не 0.163.0.</li>
</ul>
<h2 class="heading" id="что-это-значит-для-нашего-блога">
  Что это значит для нашего блога
  <a class="anchor" href="#%d1%87%d1%82%d0%be-%d1%8d%d1%82%d0%be-%d0%b7%d0%bd%d0%b0%d1%87%d0%b8%d1%82-%d0%b4%d0%bb%d1%8f-%d0%bd%d0%b0%d1%88%d0%b5%d0%b3%d0%be-%d0%b1%d0%bb%d0%be%d0%b3%d0%b0">#</a>
</h2>
<p>Прогнал блог на 0.163.3 — собирается чисто, <strong>90 страниц, 0 ошибок</strong>, 52 изображения обработаны без проблем. Конкретика:</p>
<ul>
<li><strong>Запрет <code>text/html</code></strong> нас не задел — в <code>content/</code> нет руками-сверстанных <code>.html</code>, всё в Markdown. <code>security.allowContent</code> трогать не нужно.</li>
<li><strong>Node-permission</strong> мимо — Tailwind/PostCSS через Pipes не используем, Pagefind живёт отдельным npm-инструментом.</li>
<li><strong><code>languageCode</code> → <code>locale</code></strong>: попутно почистил deprecation в <code>hugo.toml</code> (<code>languageCode = 'ru-RU'</code> → <code>locale = 'ru-RU'</code>). Этот warning ушёл. Оставшиеся три (<code>.Site.LanguageCode</code>, <code>.Language.LanguageCode</code>, <code>.Language.Direction</code>) приходят из шаблонов темы <code>typo</code> — уйдут, когда обновится тема.</li>
<li><strong>AVIF</strong> — главная зацепка на будущее: добавить третий <code>&lt;source&gt;</code> в фото-pipeline и срезать вес ленты <code>/photos</code>.</li>
</ul>
<h2 class="heading" id="чек-лист-обновления-">
  Чек-лист обновления ✅
  <a class="anchor" href="#%d1%87%d0%b5%d0%ba-%d0%bb%d0%b8%d1%81%d1%82-%d0%be%d0%b1%d0%bd%d0%be%d0%b2%d0%bb%d0%b5%d0%bd%d0%b8%d1%8f-">#</a>
</h2>
<ol>
<li>
<p><strong>Прыгайте сразу на 0.163.3</strong>, а не на 0.163.0 — патчи .1/.2/.3 закрывают security-дыры и регрессию коллизии имён.</p>
</li>
<li>
<p><strong>Если собираете CSS через Tailwind/PostCSS/Babel в Pipes</strong> — поставьте Node ≥ 22 и Tailwind как npm-пакет; проверьте <code>security.node.permissions</code>.</p>
</li>
<li>
<p><strong>Если в <code>content/</code> есть <code>.html</code>-файлы</strong> — добавьте <code>security.allowContent = ['.*']</code>, иначе страницы выпадут из сборки.</p>
</li>
<li>
<p><strong>Почистите депрекейты:</strong></p>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># languageCode → locale в конфиге</span>
</span></span><span class="line"><span class="cl"><span class="c1"># .IsNode → .IsBranch в шаблонах</span>
</span></span><span class="line"><span class="cl">grep -rn <span class="s1">&#39;\.IsNode&#39;</span> layouts/ themes/</span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
</li>
<li>
<p><strong>Если работаете с изображениями</strong> — присмотритесь к AVIF и per-format <code>quality</code>; глобальный <code>imaging.quality</code> уводите в <code>[imaging.&lt;format&gt;]</code>.</p>
</li>
<li>
<p><strong>Стандартный прогон</strong> и сверка warning&rsquo;ов до/после:</p>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">hugo --minify --gc</span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
</li>
</ol>
<h2 class="heading" id="итог-">
  Итог 🧠
  <a class="anchor" href="#%d0%b8%d1%82%d0%be%d0%b3-">#</a>
</h2>
<p>0.161–0.163 — это квартал «инфраструктурного взросления» Hugo: новый формат изображений (AVIF), методичный security-хардненинг и более гибкая конфигурация (permalinks, идентификаторы файлов, вложенные CSS-vars). Громкая фича ровно одна — AVIF; всё остальное либо про безопасность, либо про удобство.</p>
<p>Breaking changes реальны, но адресные: они бьют по сайтам с Tailwind-в-Pipes и с HTML-контентом в <code>content/</code>. Если вы (как наш блог) пишете на чистом Markdown и не гоняете Node-сборку CSS — переход бесшовный, достаточно поднять версию и пробежаться по депрекейтам.</p>
<p>Если сидите на 0.160 или раньше — есть смысл прыгать сразу на 0.163.3, мимо промежуточных: так вы заодно получите все security-фиксы одним движением.</p>
<h2 class="heading" id="источники">
  Источники
  <a class="anchor" href="#%d0%b8%d1%81%d1%82%d0%be%d1%87%d0%bd%d0%b8%d0%ba%d0%b8">#</a>
</h2>
<ul>
<li>Релиз 0.161.0: <a href="https://github.com/gohugoio/hugo/releases/tag/v0.161.0">gohugoio/hugo v0.161.0</a></li>
<li>Релиз 0.162.0: <a href="https://github.com/gohugoio/hugo/releases/tag/v0.162.0">gohugoio/hugo v0.162.0</a></li>
<li>Релиз 0.163.0: <a href="https://github.com/gohugoio/hugo/releases/tag/v0.163.0">gohugoio/hugo v0.163.0</a></li>
<li>Релиз 0.163.3: <a href="https://github.com/gohugoio/hugo/releases/tag/v0.163.3">gohugoio/hugo v0.163.3</a></li>
<li>Конфигурация AVIF: <a href="https://gohugo.io/configuration/imaging/#avif">gohugo.io/configuration/imaging/#avif</a></li>
<li>Security-модель Hugo: <a href="https://gohugo.io/about/security/">gohugo.io/about/security/</a></li>
</ul>]]></content:encoded><category>hugo</category><category>релизы</category></item><item><title>Пять проходов impeccable по блогу: что AI-инструмент дизайна реально умеет 🛠</title><link>https://kushnaren.co/posts/2026-04-28-pyat-prokhodov-impeccable-na-bloge/</link><pubDate>Tue, 28 Apr 2026 21:30:00 +0300</pubDate><guid isPermaLink="true">https://kushnaren.co/posts/2026-04-28-pyat-prokhodov-impeccable-na-bloge/</guid><description>Личный отчёт о работе с AI-инструментом impeccable на Hugo-блоге: как он устроен, что меняет в процессе, кейс с фиктивным компонентом и набор уроков, которые стоят дороже самих правок.</description><content:encoded><![CDATA[<h2 class="heading" id="что-это-вообще-такое">
  Что это вообще такое
  <a class="anchor" href="#%d1%87%d1%82%d0%be-%d1%8d%d1%82%d0%be-%d0%b2%d0%be%d0%be%d0%b1%d1%89%d0%b5-%d1%82%d0%b0%d0%ba%d0%be%d0%b5">#</a>
</h2>
<p>Если ты когда-нибудь просил AI-помощника (Claude, ChatGPT, Cursor) сделать
тебе сайт, ты замечал одно и то же: получается вроде неплохо, но
подозрительно «как у всех». Тёмно-синий фон, фиолетовый градиент в
заголовке, карточки с лёгкой тенью, шрифт Inter. Узнаваемый «AI-look».</p>
<p>Причина банальная: большие языковые модели учились на одних и тех же
типичных шаблонах. Без отдельных указаний они выдают усреднённый
дизайн, в котором повторяются одни и те же стандартные ошибки:
градиент в заголовке через <code>background-clip</code>, серый текст на цветном
фоне, бесконечные одинаковые карточки в сетке, ноль характера.</p>
<p><a href="https://impeccable.style">Impeccable</a> от Paul Bakaus решает именно эту
задачу. Сам автор позиционирует его как <strong>«дизайн-словарь для
AI-помощников по коду»</strong>: набор из одного навыка и 23 команд, которые
дают AI и человеку общий понятийный аппарат. Каждая команда отвечает
за свою дизайн-дисциплину: типографика, цвет, ритм пространства,
взаимодействия, копирайтинг, элевация (тени и слои), анти-паттерны.
Плюс отдельный список из 25 типичных «AI-ляпов», которые
детектор ловит автоматически.</p>
<p>Что важно: impeccable — не библиотека CSS-токенов и не редактор
макетов. Он живёт в твоём боевом коде, читает существующие исходники,
рендеренный HTML, дизайн-документы, и вместе с AI правит то, что уже
есть. Не «нарисуй мне сайт с нуля», а «доведи существующий до
состояния, в котором он перестанет быть похожим на любой другой
блог».</p>
<p>Я взялся применить это к собственному Hugo-блогу. Hugo — статический
генератор сайтов: ты пишешь посты в Markdown, конфиг и HTML-шаблоны,
он собирает готовые HTML-файлы. Дизайн жил в одном CSS-файле плюс
тема <code>typo</code> как git submodule. К апрелю накопилось ощущение
«работает, но как-то не так». Тёмная тема жила в одной палитре,
светлая — местами в другой. Страница «Обо мне» выглядела как
кусочек чужого SaaS-сайта, попавший в блог по ошибке.</p>
<p>Решил пройти все нужные команды и посмотреть, что инструмент реально
ловит. Получилось пять заходов за вечер.</p>
<h2 class="heading" id="фундамент-productmd-и-designmd">
  Фундамент: PRODUCT.md и DESIGN.md
  <a class="anchor" href="#%d1%84%d1%83%d0%bd%d0%b4%d0%b0%d0%bc%d0%b5%d0%bd%d1%82-productmd-%d0%b8-designmd">#</a>
</h2>
<p>Первая команда — <code>/teach</code>. Это не «настройки», а короткое интервью:
кому пишешь, каким голосом, чем не должен быть сайт, какие
требования к доступности. На выходе два файла в корне проекта:</p>
<ul>
<li><strong>PRODUCT.md</strong> — стратегический документ. Регистр (бренд или
продукт), целевая аудитория, голос, анти-референсы, дизайн-принципы,
планка доступности.</li>
<li><strong>DESIGN.md</strong> — визуальная спецификация. Цвета, шрифты, шкала
пространства, шкала радиусов, компоненты.</li>
</ul>
<p>Эти два файла потом читает каждая последующая команда. Без них
любой <code>/audit</code> или <code>/polish</code> даёт ответы вообще, не привязанные к
конкретному проекту.</p>
<p>Главное открытие здесь — раздел <strong>анти-референсов</strong>. PRODUCT.md
заставляет ответить, чем сайт <strong>не</strong> должен быть. Я выписал четыре
конкретных образца, которые не хочу повторять:</p>
<ul>
<li>Habr и VC.ru с их боковыми панелями, бейджами и блоками «читайте
также» на пять экранов;</li>
<li>Medium и Substack: безликий шаблон платформы, попап «подпишись», где
ощущение «это любой блог»;</li>
<li>современный SaaS с градиентами и стеклянными карточками;</li>
<li>Dev.to и обычные GitHub Pages: стандартный markdown без типографики,
синие ссылки, sans-serif, ноль характера.</li>
</ul>
<p>Анти-референсы оказались полезнее обычных «делай как Stripe». «Как
Stripe» — растяжимое: можно повторить любой кусок и сказать «вот
видишь, похоже». «Не как Habr» — конкретный отказ. Каждое следующее
дизайн-решение проверялось по этому списку и часто не проходило: «а
не повторяю ли я сейчас Habr-ленту одинаковых превью?»</p>
<p>Дальше команда <code>/document</code> отсканировала существующий CSS и собрала
DESIGN.md. Здесь я первый раз ошибся — но об этом дальше.</p>
<h2 class="heading" id="аудит-11-из-20-на-старте-">
  Аудит: 11 из 20 на старте 📊
  <a class="anchor" href="#%d0%b0%d1%83%d0%b4%d0%b8%d1%82-11-%d0%b8%d0%b7-20-%d0%bd%d0%b0-%d1%81%d1%82%d0%b0%d1%80%d1%82%d0%b5-">#</a>
</h2>
<p><code>/audit</code> — техническая проверка по пяти направлениям, каждое от 0
до 4 баллов: доступность, производительность, согласованность
дизайн-токенов, адаптивность, отсутствие шаблонных AI-ляпов.</p>
<p>Финальная оценка моего блога — <strong>11 из 20</strong>. Между «нормально, но
работы много» и «плохо». От «плохо» вытащило только производительность
(Hugo и так быстрый, картинки грузятся лениво, шрифты с правильной
стратегией загрузки).</p>
<p>Что нашлось:</p>
<p><strong>Контраст вторичного текста проваливал стандарт WCAG AA в обеих
темах.</strong> Цвет <code>#6272a4</code> на светлом фоне <code>#f8f8f2</code> давал соотношение
контраста 3.92:1, на тёмном <code>#282a36</code> — 3.33:1. Стандарт WCAG AA
требует минимум 4.5:1 для основного текста. Эта переменная использовалась
одновременно как цвет вторичного текста, как цвет ссылок в светлой
теме и как мета-информация. Поражено больше 40% не-основного контента
сайта.</p>
<p><strong>Страница поиска в светлой теме выдавала белый текст на белом фоне.</strong>
В моём CSS заголовки результатов поиска имели цвет <code>#f8f8f2</code>
(захардкожен под тёмную тему). На светлой теме фон тоже <code>#f8f8f2</code> —
белый на белом. Я этого не замечал, потому что почти всегда сижу в
тёмной теме. Половина посетителей видела пустые результаты поиска
полтора года.</p>
<p><strong>Страница «Обо мне» — типичный SaaS-клон.</strong> Шрифт Inter (один из
самых заезженных AI-выборов), фон с линейным градиентом, тяжёлая
тень под аватаром. Все четыре анти-референса из PRODUCT.md в одном
экране.</p>
<p><strong>Кликабельные элементы меньше 44 на 44 пикселей.</strong> Кнопка
переключения темы — 32–35 пикселей. У ссылок в навигации не было
внутренних отступов, кликабельная зона = площадь самого текста.
Стандарт WCAG 2.1 рекомендует минимум 44×44 для тача и моторной
доступности.</p>
<p><strong>У цитат <code>border-left</code> в 2 пикселя.</strong> Эта самая полоска слева у
«цитаты». В философии impeccable любая боковая полоска шире 1
пикселя — отдельный анти-паттерн (типичный «callout-style» из
старых книг по веб-дизайну).</p>
<p>Семь крупных проблем плюс несколько помельче. Чинилось всё в одном
проходе: подняли цвет вторичного текста до читаемого, переписали
страницу «Обо мне» с нуля без шрифта Inter и градиентов, сделали
все статусы reading-секции чувствительными к теме, расширили
кликабельные зоны. После — оценка поднялась до 18 из 20.</p>
<p>Без <code>/audit</code> я бы половину этих проблем не нашёл. Особенно поиск в
светлой теме: я не садился в светлую тему вживую неделями.</p>
<h2 class="heading" id="ux-ревью-и-кейс-с-фиктивным-компонентом">
  UX-ревью и кейс с фиктивным компонентом
  <a class="anchor" href="#ux-%d1%80%d0%b5%d0%b2%d1%8c%d1%8e-%d0%b8-%d0%ba%d0%b5%d0%b9%d1%81-%d1%81-%d1%84%d0%b8%d0%ba%d1%82%d0%b8%d0%b2%d0%bd%d1%8b%d0%bc-%d0%ba%d0%be%d0%bc%d0%bf%d0%be%d0%bd%d0%b5%d0%bd%d1%82%d0%be%d0%bc">#</a>
</h2>
<p>Дальше — <code>/critique</code>. Это уже не технический аудит, а ревью на
уровне дизайн-решений: правильно ли устроена главная как точка входа,
не теряется ли пост в ленте, нужен ли архив-по-годам, есть ли узкие
места в навигации.</p>
<p>Команда устроена так, что запускает <strong>два независимых ревью
одновременно</strong>. Один — отдельный AI-агент с фокусом на
пользовательский опыт; читает исходники и рендеренный HTML.
Второй — программный детектор <code>npx impeccable --json</code>, проверяющий
25 конкретных шаблонных AI-ляпов автоматически. И ключевое: они
<strong>не видят выводы друг друга</strong>. Это сделано специально — чтобы один
не подтверждал догадки другого.</p>
<p>Я к этому отнёсся скептически. Думал, что изоляция «для красоты».</p>
<p>Оказался неправ.</p>
<p>Отдельный AI-агент за пять минут нашёл вот что: в моей же DESIGN.md,
которую я сам написал часом ранее, описан <strong>боковой sticky-блок
«Содержание» как одна из ключевых деталей сайта</strong>. Подробно: фиксированное
позиционирование, ширина 260 пикселей, рамка, скругление, размеры
ссылок, активное состояние. И сразу следом: «один из главных
компонентов сайта; обслуживает чтение длинных постов вторым по
важности после самого текста».</p>
<p>А в <code>layouts/_default/single.html</code> (мой собственный шаблон страницы
поста) этого блока <strong>нет</strong>. Поиск по проекту: ноль вхождений
<code>toc-sidebar</code>, <code>toc-sticky</code>, <code>TableOfContents</code>. Только 190 строк
CSS-стилей, который никем не используется, потому что HTML-разметку
никто не выводит. Документация описывала то, чего на сайте не было.</p>
<p>Что произошло: при первом проходе <code>/document</code> я смотрел в CSS,
увидел проработанный sticky-блок и описал его в DESIGN.md как
рабочий компонент. Не проверил, что в шаблонах кто-то этот класс
выводит. CSS живёт, разметки нет — а я этого не заметил, потому что
неудобно увидеть, что я только что подробно описал то, чего не
существует.</p>
<p>Это та самая «слепая зона», когда видишь в собственной работе только
то, что её подтверждает. Я писал код, я писал документацию по этому
коду. Свою же работу мне «удобно» считать согласованной.</p>
<p>Отдельный AI-агент в <code>/critique</code> не видел ни моих рассуждений по
команде <code>/document</code>, ни моей DESIGN.md как авторитетного источника.
Он читал её как один из файлов проекта. И тут же подсветил
расхождение: «sticky TOC задокументирован как ключевой элемент,
не рендерится ни на одной странице».</p>
<p>Этот один пункт окупил весь подход с двумя независимыми ревью.
Я зашил это в персональную память Claude Code как правило: <strong>прежде
чем называть компонент ключевым в DESIGN.md, надо проверить, что он
действительно рендерится в шаблонах, а не только в стилях</strong>. Стилевой
блок без HTML-разметки — мёртвый код, не «компонент».</p>
<p>После этого <code>/critique</code> нашёл ещё несколько пунктов помельче:</p>
<ul>
<li>листинг прочитанных книг сделан карточной сеткой — это прямой
анти-референс из моей же PRODUCT.md;</li>
<li>три параллельных шаблона шапки и подвала на разных страницах с
чуть разным поведением;</li>
<li>текст страницы «Обо мне» написан в типичном LinkedIn-стиле:
«Я исследую пересечения технологий, мышления и практики», «Автор ·
Инженер · Исследователь» — строго против моего же голоса;</li>
<li>в публичной копии сайта засветилось имя поискового движка
(«Pagefind»), хотя пользователю это знать не нужно.</li>
</ul>
<p>Всё, кроме текста «Обо мне», починили в этом же сеансе. Текст —
это переписывание личного голоса, я сделал черновик, но коммитить не
стал.</p>
<h2 class="heading" id="полировка-деталей-">
  Полировка деталей 🎨
  <a class="anchor" href="#%d0%bf%d0%be%d0%bb%d0%b8%d1%80%d0%be%d0%b2%d0%ba%d0%b0-%d0%b4%d0%b5%d1%82%d0%b0%d0%bb%d0%b5%d0%b9-">#</a>
</h2>
<p>После <code>/critique</code> оставшиеся три команды — это работа другого
характера. Не «найди и почини», а «доведи до состояния, в котором
детали перестают раздражать».</p>
<p>Команда <code>/harden</code> («закалка») закрыла прямой пробел: на месте
английской заглушки темы «typo? Click here» теперь нормальная
страница 404 на русском с тремя осмысленными путями. Локализовал
раздел тегов: хлебные крошки теперь говорят «Главная / Теги», а не
«Tags». Расширил поддержку настройки «уменьшить движение» в
операционной системе — теперь обнуляются все плавные переходы, не
только прокрутка. Защитился от очень длинных заголовков (если в
название поста попадёт длинная ссылка без пробелов, сетка не
поедет).</p>
<p>Команда <code>/polish</code> («полировка») добавила состояния «при наведении» и
«при фокусе с клавиатуры» там, где их не было: теги статьи, ссылки
на соцсети в шапке главной, навигация пагинации, ссылки между
постами, кнопка копирования кода. Каждая ссылка теперь визуально
откликается на наведение через смену цвета — без сдвига, без тени,
по принципу «никакой фальшивой глубины» из моей же DESIGN.md.</p>
<p>Команда <code>/typeset</code> (типографика) — самая «невидимая» работа. Включил
кернинг (профессиональная регулировка расстояний между парами букв)
и лигатуры (где две буквы соединяются в один знак — <code>fi</code>, <code>fl</code>).
Включил табличные цифры на датах в ленте: цифры теперь одной ширины
и в столбце выстраиваются штамп-в-штамп. Добавил мягкие переносы
русских слов внутри статьи (без них длинные слова рвали строку
абзаца на узкой колонке). Тонко уплотнил трекинг (межбуквенный
интервал) на крупных заголовках 28-44 пикселя — Literata в больших
размерах без лёгкого негативного трекинга «дребезжит» как
кубики, с ним читается как один жест.</p>
<p>Каждая из тройки — 30-60 минут работы. Вместе они подняли качество
с «работает» до «приятно читать».</p>
<h2 class="heading" id="что-я-понял-про-инструмент">
  Что я понял про инструмент
  <a class="anchor" href="#%d1%87%d1%82%d0%be-%d1%8f-%d0%bf%d0%be%d0%bd%d1%8f%d0%bb-%d0%bf%d1%80%d0%be-%d0%b8%d0%bd%d1%81%d1%82%d1%80%d1%83%d0%bc%d0%b5%d0%bd%d1%82">#</a>
</h2>
<p><strong>Импеккейбл работает с локальными файлами, не с задеплоенным сайтом.</strong>
Команды читают исходники в репозитории, рендеренный HTML после
локальной сборки Hugo, и оба дизайн-документа. Прода нет ни в одной
команде, кроме <code>/live</code> (интерактивный режим в браузере), которую я
не использовал. То есть весь дизайн-цикл идёт у меня на ноутбуке, и
выкладка в боевой репозиторий — финальный шаг, не источник истины.</p>
<p><strong>AI хорошо ловит противоречия в собственной работе, если ему дать
независимое ревью.</strong> Изоляция в <code>/critique</code> нужна не для эстетики
процесса. Самопроверка у языковой модели страдает тем же эффектом
подтверждения собственной правоты, что и у человека: ты видишь в
своей работе то, что её обосновывает, и не видишь того, что её
опровергает. Отдельный AI-агент в новой сессии, без моих рассуждений
в его контексте, читал DESIGN.md как просто один из файлов и тут
же поймал расхождение с шаблонами.</p>
<p><strong>Анти-референсы выстреливают сильнее, чем референсы.</strong> «Не как
Habr» — конкретный отказ, проверяемый автоматически. «Как Stripe» —
растяжимое, можно подогнать любой результат. PRODUCT.md заставляет
выписать четыре-пять анти-референсов, и каждое решение проверяется
против них.</p>
<p><strong>Метрики важнее ощущений.</strong> <code>/audit</code> дал 11 из 20. Это конкретное
число. После правок — 19. Я знаю, на сколько лучше. Бессчётный
«прогресс» — самообман: правишь, правишь, чувствуешь, что лучше. С
оценкой видно, что иногда нет.</p>
<p><strong>Убывающая отдача наступает быстро.</strong> После пяти проходов половина
команд impeccable стали неуместными для моего блога. <code>/animate</code>,
<code>/delight</code>, <code>/bolder</code>, <code>/overdrive</code> — прямо конфликтуют с принципом
«без подкупа» из PRODUCT.md. <code>/quieter</code>, <code>/distill</code> — сайт уже
плоский и сдержанный, дальше пустая страница. <code>/colorize</code> — палитра
закрыта на 13 цветах. <code>/optimize</code> — Hugo уже выжат до предела.</p>
<p>Это знак, что инструмент сделал работу. Дальше — пиши посты, не
правь дизайн.</p>
<h2 class="heading" id="где-ai-ошибся-а-где-я">
  Где AI ошибся, а где я
  <a class="anchor" href="#%d0%b3%d0%b4%d0%b5-ai-%d0%be%d1%88%d0%b8%d0%b1%d1%81%d1%8f-%d0%b0-%d0%b3%d0%b4%d0%b5-%d1%8f">#</a>
</h2>
<p>За эту сессию я дважды слишком уверенно объявил причину явления на
основании одного наблюдения. Это вообще частая ошибка и в инженерии,
и в науке: одна точка наблюдений — не закономерность, это просто
точка.</p>
<p><strong>Первый случай.</strong> Один сборочный билд занял 9 минут вместо обычных
40-50 секунд. Я уверенно сказал: причина — что я только что добавил в
подвал отметку реального времени сборки. Каждая страница теперь
содержит уникальный текст в подвале, значит, утилита синхронизации
(rsync) с проверкой по контрольной сумме перезаливает все 227
страниц целиком.
Технически красивое объяснение, инженерно стройное. И <strong>неверное</strong>.</p>
<p>Следующий билд с той же отметкой времени занял 40 секунд. То есть
9-минутный билд был случайным выбросом — холодный старт исполнителя,
сетевой сбой, что-то сторонне. Я экстраполировал из одной точки и
готов был «починить» проблему, которой нет.</p>
<p><strong>Второй случай.</strong> Я случайно удалил пустой файл <code>content/posts/.md</code>
(артефакт от прошлой попытки автоматического создания поста с битым
именем) после того, как назвал его «пустой стуб». Не прочитал
содержимое перед удалением. Файл был не пустой — 101 байт. После
удаления выяснилось, что в нём всё-таки лежал какой-то фронтматтер
(служебный заголовок поста с метаданными), которого я не увидел до
действия.</p>
<p>Оба случая зашиты в персональную память:</p>
<ul>
<li><strong>Перед удалением читать каждый файл.</strong> Не отслеживается ли git —
не значит «можно выкинуть».</li>
<li><strong>Прежде чем уверенно объявлять причину явления — собрать минимум
две сравнимых точки.</strong> Один выброс ≠ закономерность.</li>
</ul>
<p>Особенно полезно для вопросов производительности, где «фикс
несуществующей проблемы» — это напрасные телодвижения и потеря
доверия к собственным выводам.</p>
<h2 class="heading" id="когда-импеккейбл-не-нужен">
  Когда импеккейбл не нужен
  <a class="anchor" href="#%d0%ba%d0%be%d0%b3%d0%b4%d0%b0-%d0%b8%d0%bc%d0%bf%d0%b5%d0%ba%d0%ba%d0%b5%d0%b9%d0%b1%d0%bb-%d0%bd%d0%b5-%d0%bd%d1%83%d0%b6%d0%b5%d0%bd">#</a>
</h2>
<ul>
<li>На бренде, который требует «как у всех»: внутренний инструмент,
служебная панель, прототип без идентичности.</li>
<li>Когда нет 30-60 минут на интервью <code>/teach</code> и сборку DESIGN.md.
Без фундамента остальные команды дают ответы вообще, не для тебя.</li>
<li>На короткой одностраничной странице — обычная ручная работа
быстрее.</li>
<li>Когда дизайн уже отлажен и работает — повторное прохождение часто
стоит дороже того, что находит.</li>
</ul>
<h2 class="heading" id="конкретные-числа">
  Конкретные числа
  <a class="anchor" href="#%d0%ba%d0%be%d0%bd%d0%ba%d1%80%d0%b5%d1%82%d0%bd%d1%8b%d0%b5-%d1%87%d0%b8%d1%81%d0%bb%d0%b0">#</a>
</h2>
<table>
	<thead>
			<tr>
					<th>Метрика</th>
					<th>До</th>
					<th>После</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td>Технический аудит (баллы)</td>
					<td>11/20</td>
					<td>19/20</td>
			</tr>
			<tr>
					<td>UX-ревью (баллы по 10 эвристикам Нильсена)</td>
					<td>24/40</td>
					<td>~32/40</td>
			</tr>
			<tr>
					<td>Цвет фейлит стандарт WCAG AA</td>
					<td>7 случаев</td>
					<td>0</td>
			</tr>
			<tr>
					<td>Параллельных дизайн-систем</td>
					<td>2 (основная + SaaS на «Обо мне»)</td>
					<td>1</td>
			</tr>
			<tr>
					<td>Захардкоженных шестнадцатеричных цветов вне токенов</td>
					<td>23+</td>
					<td>0</td>
			</tr>
			<tr>
					<td>Кликабельные зоны меньше 44×44</td>
					<td>5</td>
					<td>0</td>
			</tr>
			<tr>
					<td>Шрифт-ошибка (отсутствующий шрифт первым в стеке)</td>
					<td>да</td>
					<td>нет</td>
			</tr>
			<tr>
					<td>Боковой блок «Содержание» — задокументирован vs реально рендерится</td>
					<td>0 страниц</td>
					<td>все длинные посты</td>
			</tr>
			<tr>
					<td>Кастомная страница 404</td>
					<td>нет</td>
					<td>есть, по-русски</td>
			</tr>
			<tr>
					<td>Поддержка настройки «уменьшить движение»</td>
					<td>частичная</td>
					<td>полная</td>
			</tr>
	</tbody>
</table>
<h2 class="heading" id="итог">
  Итог
  <a class="anchor" href="#%d0%b8%d1%82%d0%be%d0%b3">#</a>
</h2>
<p>Импеккейбл не делает дизайн за тебя. Он даёт инструмент, через
который вы вместе с AI доводите дизайн до состояния, в котором вы
оба перестаёте делать стандартные ошибки. Аудиторская часть
(<code>/audit</code>, <code>/critique</code>) ловит сразу видимое. Доводочная часть
(<code>/harden</code>, <code>/polish</code>, <code>/typeset</code>) делает то, что в одиночку лень
довести до конца.</p>
<p>Стоимость: один вечер плюс умение зафиксировать собственный голос
в PRODUCT.md и DESIGN.md. Срок отдачи: пока продолжаешь редактировать
сайт. Каждое следующее обращение к AI («поправь шапку», «добавь
страницу архива», «перепиши блок») идёт на фоне этих двух файлов, и
шансы получить очередной AI-look уменьшаются.</p>
<p>Скрытая ценность инструмента в том, что он заставляет писать честно
о собственном проекте. Анти-референсы зашиты в PRODUCT.md и
зачитываются перед каждой правкой. Это ровно та дисциплина, которую
я никогда не наводил руками.</p>
]]></content:encoded><category>ai-инструменты</category><category>hugo</category></item><item><title>Qwen3-Coder-Next-MLX-4bit: Локальная разработка на Mac 🍏</title><link>https://kushnaren.co/posts/2026-04-24-qwen3-coder-next-mlx-4bit/</link><pubDate>Fri, 24 Apr 2026 12:00:00 +0300</pubDate><guid isPermaLink="true">https://kushnaren.co/posts/2026-04-24-qwen3-coder-next-mlx-4bit/</guid><description>Подробный разбор Qwen3-Coder-Next-MLX-4bit для локальной разработки на Mac: формат MLX vs GGUF, требования к памяти, настройка через LM Studio, подключение через MCP к Codex CLI и честное сравнение с облачными моделями.</description><content:encoded><![CDATA[<h2 class="heading" id="зачем-держать-llm-локально-">
  Зачем держать LLM локально 🎯
  <a class="anchor" href="#%d0%b7%d0%b0%d1%87%d0%b5%d0%bc-%d0%b4%d0%b5%d1%80%d0%b6%d0%b0%d1%82%d1%8c-llm-%d0%bb%d0%be%d0%ba%d0%b0%d0%bb%d1%8c%d0%bd%d0%be-">#</a>
</h2>
<p>Рабочий день разработчика всё больше обвязан вокруг подсказок от LLM: автодополнение, рефакторинг, объяснение чужого кода, генерация тестов. Облачные модели делают это качественно, но за это приходится платить тремя вещами: подпиской, скоростью соединения и доверием к провайдеру в части того, какой код вы туда отправляете.</p>
<p>Локальная модель снимает все три. Подписка обнуляется, latency определяется только железом, а код никуда не уходит за пределы ноутбука. Цена вопроса — модель меньше топовых облачных, чуть больше суеты с настройкой и постоянное место на диске.</p>
<p>В этом посте разбираемся с <strong>Qwen3-Coder-Next-MLX-4bit</strong>: квантованной версией кодовой модели от Alibaba, оптимизированной под Apple Silicon. Что это такое, как поставить, как подключить к Codex CLI и когда честно лучше остаться в облаке.</p>
<h2 class="heading" id="что-это-такое-и-почему-именно-эта-сборка">
  Что это такое и почему именно эта сборка
  <a class="anchor" href="#%d1%87%d1%82%d0%be-%d1%8d%d1%82%d0%be-%d1%82%d0%b0%d0%ba%d0%be%d0%b5-%d0%b8-%d0%bf%d0%be%d1%87%d0%b5%d0%bc%d1%83-%d0%b8%d0%bc%d0%b5%d0%bd%d0%bd%d0%be-%d1%8d%d1%82%d0%b0-%d1%81%d0%b1%d0%be%d1%80%d0%ba%d0%b0">#</a>
</h2>
<p><strong>Qwen3-Coder</strong> — линейка моделей от Alibaba, специально натренированных на коде. Базовая модель — около 8 млрд параметров. Это не GPT-4-class, но для большинства повседневных задач (понять код, написать функцию, сгенерить тесты, отрефакторить) — более чем достаточно.</p>
<p><strong>MLX</strong> — относительно новый ML-фреймворк от Apple. Создан с нуля под Apple Silicon: использует unified memory (CPU и GPU делят одну RAM), zero-copy между ними, lazy evaluation. Для пользователя это значит, что модель работает заметно быстрее, чем тот же файл, запущенный через PyTorch с MPS-бэкендом.</p>
<p><strong>4-bit квантизация</strong> — каждое значение веса хранится в 4 битах вместо стандартных 16. Это уменьшает память в 4 раза с заметной, но обычно приемлемой потерей качества.</p>
<p>Важно не путать форматы: <strong>MLX</strong> хранит модели в собственном формате (<code>.safetensors</code> обёрнутый в MLX-структуру), а не в <code>.gguf</code> (это формат llama.cpp). При выборе модели в LM Studio это нужно учитывать: «MLX»-вариант и «GGUF»-вариант — это разные файлы для разных движков, не одно и то же.</p>
<p>Для <strong>Qwen3-Coder-Next-MLX-4bit</strong> характеристики такие:</p>
<ul>
<li><strong>Параметры:</strong> ~8B (тот же что и у не-квантованной версии).</li>
<li><strong>Формат:</strong> MLX (<code>.safetensors</code>).</li>
<li><strong>Размер на диске:</strong> ~5.5 GB.</li>
<li><strong>Контекст:</strong> 32 768 токенов.</li>
<li><strong>Минимум RAM:</strong> 16 GB (модель + накладные).</li>
<li><strong>Комфортный минимум:</strong> 24-32 GB (если ещё нужна работа с IDE и браузером параллельно).</li>
</ul>
<h2 class="heading" id="установка-через-lm-studio-">
  Установка через LM Studio 📦
  <a class="anchor" href="#%d1%83%d1%81%d1%82%d0%b0%d0%bd%d0%be%d0%b2%d0%ba%d0%b0-%d1%87%d0%b5%d1%80%d0%b5%d0%b7-lm-studio-">#</a>
</h2>
<p><a href="https://lmstudio.ai/">LM Studio</a> — desktop-приложение для работы с локальными LLM. Поддерживает и MLX, и GGUF, плюс встроенный OpenAI-совместимый сервер на <code>localhost</code>.</p>
<p>Шаги:</p>
<ol>
<li>Поставить LM Studio с официального сайта.</li>
<li>Открыть <strong>Discover</strong> (вкладка с моделями).</li>
<li>В фильтре указать «MLX» (важно — без этого подсунет GGUF-вариант).</li>
<li>Найти <code>Qwen3-Coder-Next</code> или подобную сборку.</li>
<li>Скачать (~5.5 GB).</li>
<li>Загрузить в <strong>My Models</strong>, потом <strong>Load</strong>.</li>
</ol>
<p>После загрузки в правом sidebar&rsquo;е будут параметры:</p>
<ul>
<li><strong>Context length:</strong> 8 192 для большинства задач хватает; 32 768 если нужен большой prompt с длинным куском кода.</li>
<li><strong>GPU offload:</strong> «Max» — отдать всё на Metal-ядра.</li>
<li><strong>Threads:</strong> оставить дефолт (LM Studio сам подберёт).</li>
</ul>
<p>LM Studio автоматически поднимет OpenAI-compatible endpoint на <code>http://localhost:1234/v1/</code>. Дальше с моделью работают любые клиенты, понимающие OpenAI API.</p>
<h2 class="heading" id="подключение-к-codex-cli-через-mcp-">
  Подключение к Codex CLI через MCP 🔌
  <a class="anchor" href="#%d0%bf%d0%be%d0%b4%d0%ba%d0%bb%d1%8e%d1%87%d0%b5%d0%bd%d0%b8%d0%b5-%d0%ba-codex-cli-%d1%87%d0%b5%d1%80%d0%b5%d0%b7-mcp-">#</a>
</h2>
<p>Если вы используете Codex CLI (агентский интерфейс на базе LLM), к нему можно подключить локальную модель через <a href="https://modelcontextprotocol.io/">MCP-сервер</a> для LM Studio.</p>
<p>В <code>~/.codex/config.toml</code>:</p>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-toml" data-lang="toml"><span class="line"><span class="cl"><span class="p">[[</span><span class="nx">mcpServers</span><span class="p">]]</span>
</span></span><span class="line"><span class="cl"><span class="nx">name</span> <span class="p">=</span> <span class="s2">&#34;lmstudio&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nx">command</span> <span class="p">=</span> <span class="s2">&#34;npx&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nx">args</span> <span class="p">=</span> <span class="p">[</span><span class="s2">&#34;-y&#34;</span><span class="p">,</span> <span class="s2">&#34;@mlaboard/lmstudio-mcp&#34;</span><span class="p">]</span></span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<p>После перезапуска Codex увидит локальную модель как один из доступных провайдеров. Smoke-тест: попросить простую задачу типа «напиши функцию Фибоначчи на Python» — должен ответить за 0.5–1 секунду.</p>
<p>При первом запуске MCP-сервер скачивает свой пакет через <code>npx</code>. Это разовая операция, дальше работает с уже установленного.</p>
<h2 class="heading" id="замеры-на-m2-max-">
  Замеры на M2 Max 📊
  <a class="anchor" href="#%d0%b7%d0%b0%d0%bc%d0%b5%d1%80%d1%8b-%d0%bd%d0%b0-m2-max-">#</a>
</h2>
<p>На моём железе (M2 Max, 32 GB unified memory) получились такие цифры:</p>
<table>
	<thead>
			<tr>
					<th>Метрика</th>
					<th>Значение</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td>Размер модели на диске</td>
					<td>5.5 GB</td>
			</tr>
			<tr>
					<td>RAM при загрузке</td>
					<td>~6 GB</td>
			</tr>
			<tr>
					<td>First-token latency</td>
					<td>0.3-0.5 с</td>
			</tr>
			<tr>
					<td>Generation speed</td>
					<td>18-22 токена/с</td>
			</tr>
			<tr>
					<td>Время на ~500-токенный ответ</td>
					<td>~25 секунд</td>
			</tr>
	</tbody>
</table>
<p>Это медленнее облачного GPT-4 (там 50-80 ток/с в среднем), но быстрее, чем кажется по первому впечатлению. Для итеративной работы (написал → попросил → поправил руками → попросил снова) разница в latency почти неощутима, потому что много времени всё равно уходит на чтение и редактирование результата.</p>
<p>Если поднять контекст до 32k и закинуть в prompt большой кусок кода (типа целого файла на 1000 строк), скорость падает примерно вдвое: 9-12 ток/с при first-token latency около 2 секунд. Ничего страшного, но уже заметно.</p>
<h2 class="heading" id="сравнение-с-облаком">
  Сравнение с облаком
  <a class="anchor" href="#%d1%81%d1%80%d0%b0%d0%b2%d0%bd%d0%b5%d0%bd%d0%b8%d0%b5-%d1%81-%d0%be%d0%b1%d0%bb%d0%b0%d0%ba%d0%be%d0%bc">#</a>
</h2>
<table>
	<thead>
			<tr>
					<th>Показатель</th>
					<th>Облако (GPT-4-class)</th>
					<th>Локально (Qwen3-MLX)</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td>Latency (first token)</td>
					<td>1-3 с</td>
					<td>0.3-0.5 с</td>
			</tr>
			<tr>
					<td>Generation speed</td>
					<td>50-80 ток/с</td>
					<td>18-22 ток/с</td>
			</tr>
			<tr>
					<td>Стоимость на месяц</td>
					<td>$20-200 (зависит от плана)</td>
					<td>$0 (после железа)</td>
			</tr>
			<tr>
					<td>Конфиденциальность</td>
					<td>По договору с провайдером</td>
					<td>Полная, код не уходит</td>
			</tr>
			<tr>
					<td>Offline</td>
					<td>✗</td>
					<td>✓</td>
			</tr>
			<tr>
					<td>Контекст</td>
					<td>128k+</td>
					<td>32k</td>
			</tr>
			<tr>
					<td>Качество на сложных задачах</td>
					<td>Лучше</td>
					<td>Хуже</td>
			</tr>
	</tbody>
</table>
<h2 class="heading" id="когда-честно-лучше-облако">
  Когда честно лучше облако
  <a class="anchor" href="#%d0%ba%d0%be%d0%b3%d0%b4%d0%b0-%d1%87%d0%b5%d1%81%d1%82%d0%bd%d0%be-%d0%bb%d1%83%d1%87%d1%88%d0%b5-%d0%be%d0%b1%d0%bb%d0%b0%d0%ba%d0%be">#</a>
</h2>
<p>Локальная модель не серебряная пуля. Есть классы задач, где она объективно проигрывает:</p>
<p><strong>Большой контекст.</strong> 128k+ контекст-окно у топовых облачных моделей позволяет закидывать в prompt целые модули кода. У 32k Qwen банально не хватит места.</p>
<p><strong>Сложные многошаговые задачи.</strong> Спроектировать архитектуру модуля, отрефакторить взаимосвязанные классы, написать миграцию с несколькими шагами — здесь топовые модели заметно качественнее.</p>
<p><strong>Мультимодальность.</strong> Анализ скриншотов UI, генерация по чертежу, чтение PDF — Qwen3-Coder-Next специализирован под код, картинки не обрабатывает.</p>
<p><strong>Редкие языки/фреймворки.</strong> На массовом Python, JS, Go качество приемлемое. На нишевых вещах (Elixir, Crystal, какой-нибудь специфичный DSL) облачная модель тренировалась на большем корпусе и даёт более уверенные ответы.</p>
<h2 class="heading" id="когда-локалка-точно-полезна">
  Когда локалка точно полезна
  <a class="anchor" href="#%d0%ba%d0%be%d0%b3%d0%b4%d0%b0-%d0%bb%d0%be%d0%ba%d0%b0%d0%bb%d0%ba%d0%b0-%d1%82%d0%be%d1%87%d0%bd%d0%be-%d0%bf%d0%be%d0%bb%d0%b5%d0%b7%d0%bd%d0%b0">#</a>
</h2>
<p>И обратная сторона:</p>
<p><strong>Чувствительные репозитории.</strong> Закрытый клиентский код, медицинские/финансовые данные, что-то под NDA — локально единственный вариант, который не нарушает соглашений.</p>
<p><strong>Работа в дороге без сети.</strong> Поезд, самолёт, кафе с глюкавым WiFi — локальная модель отвечает одинаково ровно.</p>
<p><strong>Высокочастотные задачи.</strong> Если модель используется десятки раз в час (autocomplete, объяснение fragment&rsquo;ов кода в IDE), даже маленькая абонентская плата быстро накапливается. Локалка после железа бесплатна.</p>
<p><strong>Эксперименты с агентами.</strong> Запускать тестовый цикл, где LLM крутится в фоне без лимитов, проще на собственном железе. Лимиты по rate limit / стоимости в облаке быстро становятся узким местом.</p>
<h2 class="heading" id="размышления-после-месяца-использования">
  Размышления после месяца использования
  <a class="anchor" href="#%d1%80%d0%b0%d0%b7%d0%bc%d1%8b%d1%88%d0%bb%d0%b5%d0%bd%d0%b8%d1%8f-%d0%bf%d0%be%d1%81%d0%bb%d0%b5-%d0%bc%d0%b5%d1%81%d1%8f%d1%86%d0%b0-%d0%b8%d1%81%d0%bf%d0%be%d0%bb%d1%8c%d0%b7%d0%be%d0%b2%d0%b0%d0%bd%d0%b8%d1%8f">#</a>
</h2>
<p>Для меня сложилась гибридная схема: 70% повседневной работы (объяснить функцию, написать regex, сгенерить unit-тест, набросать структуру модуля) — Qwen локально. Остальные 30% (сложная архитектура, разбор большого PR, работа со скриншотом) — облако.</p>
<p>Это не «локальная победила облачную». Это разделение по типу задач: где важна privacy и скорость отклика — локально, где важно качество и контекст — облако.</p>
<p>Установка занимает максимум полчаса (LM Studio + скачать файл + подключить через MCP). Дисковое пространство в 5.5 GB не критично даже на 256 GB Mac. Если вы давно думали попробовать локальные LLM, но откладывали из-за «сложно настроить» — Qwen3-Coder-Next-MLX-4bit как раз тот случай, когда барьер входа честно низкий. ✅</p>
<h2 class="heading" id="источники">
  Источники
  <a class="anchor" href="#%d0%b8%d1%81%d1%82%d0%be%d1%87%d0%bd%d0%b8%d0%ba%d0%b8">#</a>
</h2>
<ul>
<li>Документация MLX: <a href="https://github.com/ml-explore/mlx">github.com/ml-explore/mlx</a></li>
<li>LM Studio: <a href="https://lmstudio.ai/">lmstudio.ai</a></li>
<li>Qwen models на HuggingFace: <a href="https://huggingface.co/Qwen">huggingface.co/Qwen</a></li>
<li>Model Context Protocol: <a href="https://modelcontextprotocol.io/">modelcontextprotocol.io</a></li>
</ul>
]]></content:encoded><category>локальные-llm</category><category>ai-инструменты</category></item><item><title>Что нового в Hugo v0.160.1: разбор релиза 🚀</title><link>https://kushnaren.co/posts/2026-04-08-new-in-hugo-0-160-1/</link><pubDate>Wed, 08 Apr 2026 12:00:00 +0300</pubDate><guid isPermaLink="true">https://kushnaren.co/posts/2026-04-08-new-in-hugo-0-160-1/</guid><description>Подробный разбор Hugo v0.160.0 (фичи: CSS variable injection в css.Build, accurate Position в render hooks) и патч-релиза v0.160.1 (фиксы panic при passthrough в заголовках, утечки context markers в RenderShortcodes, multilingual root sections). Практические сценарии и чек-лист миграции.</description><content:encoded><![CDATA[<h2 class="heading" id="почему-этот-релиз-стоит-прочитать">
  Почему этот релиз стоит прочитать
  <a class="anchor" href="#%d0%bf%d0%be%d1%87%d0%b5%d0%bc%d1%83-%d1%8d%d1%82%d0%be%d1%82-%d1%80%d0%b5%d0%bb%d0%b8%d0%b7-%d1%81%d1%82%d0%be%d0%b8%d1%82-%d0%bf%d1%80%d0%be%d1%87%d0%b8%d1%82%d0%b0%d1%82%d1%8c">#</a>
</h2>
<p>8 апреля 2026 вышел <a href="https://github.com/gohugoio/hugo/releases/tag/v0.160.1">Hugo v0.160.1</a> — патч-релиз, который чинит несколько неприятных panic-сценариев из v0.160.0 (вышедшего четырьмя днями раньше). Вместе они формируют один логический шаг для проектов: 0.160.0 даёт две новые возможности, 0.160.1 закрывает баги, всплывшие сразу после релиза.</p>
<p>Если коротко: одну фичу (CSS-переменные в <code>css.Build</code>) ждали давно те, кто строит CSS через Hugo Pipes; остальные изменения — улучшения для авторов render hooks и фиксы редких краевых случаев. Никаких breaking changes, никаких депрекейтов.</p>
<p>Но фиксы в 0.160.1 — это именно тот случай, когда «пропустил минор и поймал panic в проде». Поэтому пробежать стоит.</p>
<h2 class="heading" id="главное-за-один-взгляд">
  Главное за один взгляд
  <a class="anchor" href="#%d0%b3%d0%bb%d0%b0%d0%b2%d0%bd%d0%be%d0%b5-%d0%b7%d0%b0-%d0%be%d0%b4%d0%b8%d0%bd-%d0%b2%d0%b7%d0%b3%d0%bb%d1%8f%d0%b4">#</a>
</h2>
<p><strong>v0.160.0 (4 апреля 2026)</strong> — фичевый минор:</p>
<ul>
<li>CSS-переменные можно инжектить в стили при сборке через <code>css.Build</code> (например, прокинуть значения из конфига).</li>
<li>Метод <code>.Position</code> теперь доступен на всех render hooks и стал точнее.</li>
<li>Несколько прицельных багфиксов (Position, escape ampersand&rsquo;ов в link URL, stray quotes в partial-декораторе script-контекста).</li>
</ul>
<p><strong>v0.160.1 (8 апреля 2026)</strong> — patch:</p>
<ul>
<li>Fix: panic при passthrough-элементах в заголовках.</li>
<li>Fix: panic при редактировании legacy template names, которые одновременно валидные пути в новой схеме.</li>
<li>Fix: <code>RenderShortcodes</code> утекал context markers при отступах.</li>
<li>Fix: standalone <code>RenderShortcodes</code> теперь снимает nested page context markers.</li>
<li>Fix: автосоздание root sections в мультиязычных сайтах.</li>
<li>Чистка: <code>cascade._target</code> → <code>cascade.target</code> (в тестах; deprecation осталось в коде).</li>
<li>README: чинены ссылки.</li>
</ul>
<p>Дальше — что это значит на практике.</p>
<h2 class="heading" id="css-переменные-в-cssbuild-">
  CSS-переменные в css.Build 🎨
  <a class="anchor" href="#css-%d0%bf%d0%b5%d1%80%d0%b5%d0%bc%d0%b5%d0%bd%d0%bd%d1%8b%d0%b5-%d0%b2-cssbuild-">#</a>
</h2>
<p>Это главная фича релиза. Если вы используете Hugo Pipes для сборки CSS (а не просто статически копируете файлы из <code>static/</code>), теперь можно прокидывать значения из Hugo-контекста прямо в CSS на этапе сборки.</p>
<p>Раньше для подобного приходилось городить пайплайн через переменные окружения, sed-замены или генерировать <code>.css</code> через Hugo template (что ломает синтаксис LSP-плагинов).</p>
<p>Теперь это выглядит ближе к декларативно:</p>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go-html-template" data-lang="go-html-template"><span class="line"><span class="cl"><span class="cp">{{</span><span class="w"> </span><span class="nx">$opts</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">dict</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="s">&#34;vars&#34;</span><span class="w"> </span><span class="o">(</span><span class="nx">dict</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="s">&#34;primary&#34;</span><span class="w">   </span><span class="nx">site</span><span class="na">.Params.brand.primary</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="s">&#34;max-width&#34;</span><span class="w"> </span><span class="s">&#34;1200px&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="o">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="cp">}}</span>
</span></span><span class="line"><span class="cl"><span class="cp">{{</span><span class="w"> </span><span class="nx">$css</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">resources</span><span class="na">.Get</span><span class="w"> </span><span class="s">&#34;css/main.css&#34;</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="nx">css</span><span class="na">.Build</span><span class="w"> </span><span class="nx">$opts</span><span class="w"> </span><span class="cp">}}</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">link</span> <span class="na">rel</span><span class="o">=</span><span class="s">&#34;stylesheet&#34;</span> <span class="na">href</span><span class="o">=</span><span class="s">&#34;</span><span class="cp">{{</span><span class="w"> </span><span class="nx">$css</span><span class="na">.RelPermalink</span><span class="w"> </span><span class="cp">}}</span><span class="s">&#34;</span><span class="p">&gt;</span></span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<p>В CSS можно ссылаться на эти переменные через специальный hook (<code>@import 'hugo:vars'</code> или подобный, точный синтаксис — в <a href="https://gohugo.io/functions/css/build/">документации css.Build</a>).</p>
<p>Когда полезно: сайтам с темой, где accent-цвет задаётся в <code>hugo.toml</code> и должен применяться к компонентам через CSS переменные; сборкам, где <code>max-width</code> или <code>breakpoint</code>-значения управляются из конфига; multi-tenant билдам.</p>
<p>Нашему блогу это не нужно — у нас ровно один theme и палитра жёстко зафиксирована в <code>:root</code> блоке. Но если вы строите тему-конструктор или multi-сайт — стоит изучить.</p>
<h2 class="heading" id="точная-позиция-в-render-hooks-">
  Точная позиция в render hooks 📍
  <a class="anchor" href="#%d1%82%d0%be%d1%87%d0%bd%d0%b0%d1%8f-%d0%bf%d0%be%d0%b7%d0%b8%d1%86%d0%b8%d1%8f-%d0%b2-render-hooks-">#</a>
</h2>
<p>Вторая фича — расширение <code>.Position</code> на все render hooks (image, link, heading, code-block) с одновременным улучшением точности.</p>
<p><code>.Position</code> возвращает позицию исходного Markdown-токена в файле. Для отладки и понимания «откуда пришла эта ссылка» — критично.</p>
<p>Сценарий использования:</p>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go-html-template" data-lang="go-html-template"><span class="line"><span class="cl"><span class="cm">{{/* render-link.html */}}</span>
</span></span><span class="line"><span class="cl"><span class="cp">{{</span><span class="w"> </span><span class="nx">$url</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="na">.Destination</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="nx">safeURL</span><span class="w"> </span><span class="cp">}}</span>
</span></span><span class="line"><span class="cl"><span class="cp">{{</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="k">not</span><span class="w"> </span><span class="o">(</span><span class="nx">urls</span><span class="na">.Parse</span><span class="w"> </span><span class="nx">$url</span><span class="o">)</span><span class="na">.IsAbs</span><span class="w"> </span><span class="cp">}}</span>
</span></span><span class="line"><span class="cl">  <span class="cm">{{/* Внутренняя ссылка — проверяем что target существует */}}</span>
</span></span><span class="line"><span class="cl">  <span class="cp">{{</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="k">not</span><span class="w"> </span><span class="o">(</span><span class="na">.Page.GetPage</span><span class="w"> </span><span class="o">(</span><span class="nx">string</span><span class="w"> </span><span class="nx">$url</span><span class="o">))</span><span class="w"> </span><span class="cp">}}</span>
</span></span><span class="line"><span class="cl">    <span class="cp">{{</span><span class="w"> </span><span class="nx">warnf</span><span class="w"> </span><span class="s">&#34;Битая внутренняя ссылка %q в %s&#34;</span><span class="w"> </span><span class="nx">$url</span><span class="w"> </span><span class="na">.Position</span><span class="w"> </span><span class="cp">}}</span>
</span></span><span class="line"><span class="cl">  <span class="cp">{{</span><span class="w"> </span><span class="k">end</span><span class="w"> </span><span class="cp">}}</span>
</span></span><span class="line"><span class="cl"><span class="cp">{{</span><span class="w"> </span><span class="k">end</span><span class="w"> </span><span class="cp">}}</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">a</span> <span class="na">href</span><span class="o">=</span><span class="s">&#34;</span><span class="cp">{{</span><span class="w"> </span><span class="nx">$url</span><span class="w"> </span><span class="cp">}}</span><span class="s">&#34;</span><span class="p">&gt;</span><span class="cp">{{</span><span class="w"> </span><span class="na">.Text</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="nx">safeHTML</span><span class="w"> </span><span class="cp">}}</span><span class="p">&lt;/</span><span class="nt">a</span><span class="p">&gt;</span></span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<p>В warning&rsquo;е теперь будет точное <code>файл:строка</code> исходника поста, а не нечто приблизительное. Проще ловить регрессии после рефакторингов контента.</p>
<h2 class="heading" id="багфиксы-01601-">
  Багфиксы 0.160.1 🔧
  <a class="anchor" href="#%d0%b1%d0%b0%d0%b3%d1%84%d0%b8%d0%ba%d1%81%d1%8b-01601-">#</a>
</h2>
<p>Пять патчей, каждый закрывает свой панический сценарий или утечку.</p>
<h3 class="heading" id="panic-при-passthrough-в-заголовках">
  Panic при passthrough в заголовках
  <a class="anchor" href="#panic-%d0%bf%d1%80%d0%b8-passthrough-%d0%b2-%d0%b7%d0%b0%d0%b3%d0%be%d0%bb%d0%be%d0%b2%d0%ba%d0%b0%d1%85">#</a>
</h3>
<p>Hugo Goldmark поддерживает <a href="https://gohugo.io/configuration/markup/#passthrough">passthrough</a> — режим, когда определённые символьные блоки (например, LaTeX-формулы <code>$...$</code>) пропускаются как есть и обрабатываются на клиенте через MathJax/KaTeX.</p>
<p>В 0.160.0 если passthrough-элемент попадал прямо внутрь заголовка (например, <code>## Формула $E=mc^2$</code>), Hugo падал с panic при сборке. 0.160.1 чинит этот случай: теперь рендерится корректный HTML без падения.</p>
<p>Если вы пишете научный/математический контент с inline-формулами в заголовках — обновление обязательно.</p>
<h3 class="heading" id="panic-на-legacy-template-names">
  Panic на legacy template names
  <a class="anchor" href="#panic-%d0%bd%d0%b0-legacy-template-names">#</a>
</h3>
<p>Если в проекте есть старая схема именования шаблонов (<code>_default/single.html.html</code> и подобные legacy-варианты), которая одновременно является валидным путём в новой схеме именования Hugo, при редактировании файла Hugo мог падать. 0.160.1 разводит эти кейсы.</p>
<h3 class="heading" id="rendershortcodes-и-context-markers">
  RenderShortcodes и context markers
  <a class="anchor" href="#rendershortcodes-%d0%b8-context-markers">#</a>
</h3>
<p><code>RenderShortcodes</code> — функция для обработки всех шорткодов внутри переданного контента. Она использует внутренние «context markers» для отслеживания вложенности.</p>
<p>В 0.160.0 эти маркеры могли:</p>
<ol>
<li>Утекать в финальный HTML, если контент с шорткодами был с отступами (например, внутри списка или blockquote).</li>
<li>Не очищаться при standalone-вызове <code>.RenderShortcodes</code> через <code>.Page.Content</code> после nested-рендеринга.</li>
</ol>
<p>Оба случая дают видимый «мусор» в выводе (артефакты вида <code>__hugo_ctx0__</code> и подобные). 0.160.1 чистит маркеры в обеих ситуациях.</p>
<p>Если вы используете шорткоды внутри списков или blockquote&rsquo;ов — обновляйтесь.</p>
<h3 class="heading" id="auto-creation-root-sections-в-мультиязычных-сайтах">
  Auto-creation root sections в мультиязычных сайтах
  <a class="anchor" href="#auto-creation-root-sections-%d0%b2-%d0%bc%d1%83%d0%bb%d1%8c%d1%82%d0%b8%d1%8f%d0%b7%d1%8b%d1%87%d0%bd%d1%8b%d1%85-%d1%81%d0%b0%d0%b9%d1%82%d0%b0%d1%85">#</a>
</h3>
<p>В мультиязычных сайтах Hugo автоматически создаёт «виртуальные» root section страницы для каждого языка. В 0.160.0 эта логика могла давать сбой (root section не создавалась, или создавалась только для default-языка), что ломало навигацию по неосновным языкам.</p>
<p>Если у вас один язык — пункт мимо. Если несколько — обновление лечит.</p>
<h2 class="heading" id="cascadetarget-вместо-cascade_target">
  cascade.target вместо cascade._target
  <a class="anchor" href="#cascadetarget-%d0%b2%d0%bc%d0%b5%d1%81%d1%82%d0%be-cascade_target">#</a>
</h2>
<p>Мелкий, но симптоматичный пункт: ключ <code>_target</code> в <a href="https://gohugo.io/content-management/front-matter/#cascade">cascade-конфигурации</a> переименован в <code>target</code> (без подчёркивания). Старая форма помечена как deprecated в коде, всё ещё работает.</p>
<p>Если у вас есть cascade-блоки в front matter:</p>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">cascade</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span>- <span class="nt">_target</span><span class="p">:</span><span class="w">                 </span><span class="c"># ← старая форма</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">kind</span><span class="p">:</span><span class="w"> </span><span class="l">page</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">params</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">foo</span><span class="p">:</span><span class="w"> </span><span class="l">bar</span></span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<p>Замените на:</p>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">cascade</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span>- <span class="nt">target</span><span class="p">:</span><span class="w">                  </span><span class="c"># ← новая форма</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">kind</span><span class="p">:</span><span class="w"> </span><span class="l">page</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">params</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">foo</span><span class="p">:</span><span class="w"> </span><span class="l">bar</span></span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<p>Точечная правка, занимает минуту. Запас времени до полного удаления старой формы — обычно несколько релизов.</p>
<h2 class="heading" id="чек-лист-обновления-">
  Чек-лист обновления ✅
  <a class="anchor" href="#%d1%87%d0%b5%d0%ba-%d0%bb%d0%b8%d1%81%d1%82-%d0%be%d0%b1%d0%bd%d0%be%d0%b2%d0%bb%d0%b5%d0%bd%d0%b8%d1%8f-">#</a>
</h2>
<ol>
<li>
<p><strong>Поднять версию Hugo до 0.160.1</strong> в Dockerfile / CI-образе или локальном binary. Если вы уже на v0.161.0+ — пропускаем, это пройденная развилка.</p>
</li>
<li>
<p><strong>Если используете passthrough</strong> для математики или специальных Markdown-блоков, и они появляются в заголовках — обновление закрывает panic. Без обновления заголовки-формулы могут быть рассадником сюрпризов.</p>
</li>
<li>
<p><strong>Если используете <code>cascade._target</code></strong> в front matter, переименовать в <code>cascade.target</code>:</p>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">grep -rln <span class="s1">&#39;_target:&#39;</span> content/ <span class="p">|</span> xargs sed -i <span class="s1">&#39;&#39;</span> <span class="s1">&#39;s/_target:/target:/g&#39;</span></span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
</li>
<li>
<p><strong>Если строите CSS через Hugo Pipes</strong>, посмотреть документацию <code>css.Build</code> с CSS variables — возможно, сможете заменить sed-замены или env-обвязку на встроенный механизм.</p>
</li>
<li>
<p><strong>Если пишете кастомные render hooks</strong>, проверить, можно ли использовать <code>.Position</code> для лучшей диагностики битых ссылок/изображений в постах.</p>
</li>
<li>
<p><strong>Стандартный прогон:</strong></p>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">hugo --minify --gc</span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<p>Сравнить количество warning&rsquo;ов до и после. Если новых не появилось — мигрировано чисто.</p>
</li>
</ol>
<h2 class="heading" id="итог-">
  Итог 🧠
  <a class="anchor" href="#%d0%b8%d1%82%d0%be%d0%b3-">#</a>
</h2>
<p>Hugo 0.160.x — это не громкий feature drop, а методичное улучшение инфраструктуры: новый удобный механизм для CSS-сборки, более точная диагностика в render hooks, набор фиксов под краевые случаи (passthrough в заголовках, RenderShortcodes с отступами, multilingual sections).</p>
<p>Главная причина обновляться — патч 0.160.1 закрывает несколько panic-сценариев. Если вас они никогда не цепляли, повезло; но «не цепляли» — это не «не зацепят». На статичных сайтах panic при сборке проявляется как сломанный CI и красный билд, что рассинхронизирует прод и репозиторий.</p>
<p>Если уже сидите на 0.161.0 (как мой блог сейчас), всё это вы уже получили транзитом. Если на 0.159 или раньше — есть смысл прыгать сразу на самую свежую stable, минуя промежуточные.</p>
<h2 class="heading" id="источники">
  Источники
  <a class="anchor" href="#%d0%b8%d1%81%d1%82%d0%be%d1%87%d0%bd%d0%b8%d0%ba%d0%b8">#</a>
</h2>
<ul>
<li>Релиз 0.160.0: <a href="https://github.com/gohugoio/hugo/releases/tag/v0.160.0">gohugoio/hugo v0.160.0</a></li>
<li>Релиз 0.160.1: <a href="https://github.com/gohugoio/hugo/releases/tag/v0.160.1">gohugoio/hugo v0.160.1</a></li>
<li>Документация <code>css.Build</code>: <a href="https://gohugo.io/functions/css/build/">gohugo.io/functions/css/build/</a></li>
<li>Документация passthrough: <a href="https://gohugo.io/configuration/markup/#passthrough">gohugo.io/configuration/markup/#passthrough</a></li>
<li>Документация cascade: <a href="https://gohugo.io/content-management/front-matter/#cascade">gohugo.io/content-management/front-matter/#cascade</a></li>
</ul>
]]></content:encoded><category>hugo</category><category>релизы</category></item><item><title>Автоматизация Hugo-блога с Codex CLI: разбор реальной рабочей сессии 🤖</title><link>https://kushnaren.co/posts/avtomatizaciya-hugo-bloga-s-codex-cli-realnyj-kejs/</link><pubDate>Thu, 05 Mar 2026 20:50:00 +0300</pubDate><guid isPermaLink="true">https://kushnaren.co/posts/avtomatizaciya-hugo-bloga-s-codex-cli-realnyj-kejs/</guid><description>Показываю на реальном кейсе, как Codex CLI помогает вести Hugo-блог в production-режиме: структура задач, валидации, git-поток, исправление регрессий и устойчивый процесс публикации.</description><content:encoded><![CDATA[<p>Этот материал не «теория про ИИ». Это практический разбор конкретной рабочей сессии, где мы последовательно вели блог на Hugo через Codex CLI: писали новые статьи, чинили продовые проблемы, настраивали тему и закрепляли правила процесса.</p>
<p>Именно такой формат, на мой взгляд, лучше всего показывает ценность автоматизации: не в красивых обещаниях, а в повторяемом результате. 🔧</p>
<h2 class="heading" id="исходный-контекст">
  Исходный контекст
  <a class="anchor" href="#%d0%b8%d1%81%d1%85%d0%be%d0%b4%d0%bd%d1%8b%d0%b9-%d0%ba%d0%be%d0%bd%d1%82%d0%b5%d0%ba%d1%81%d1%82">#</a>
</h2>
<p>На старте у нас уже был рабочий блог на Hugo с темой <code>typo</code>, CI/CD через Forgejo Actions и поиском на <code>Pagefind</code>.</p>
<p>Дальше в рамках одной непрерывной сессии мы сделали:</p>
<ol>
<li>Написали и опубликовали новый пост про Hugo <code>0.157.0</code>.</li>
<li>Поймали проблему с невидимостью поста из-за времени публикации.</li>
<li>Добавили правила в <code>AGENTS.md</code>, чтобы больше не ловить future-ошибки.</li>
<li>Настроили и протестировали подсветку кода (в итоге перешли на <code>dracula</code>).</li>
<li>Привели к <code>dracula</code> цвета выдачи поиска.</li>
<li>Исправили некорректные заголовки в <code>Pagefind</code> (вместо названия поста показывалось имя сайта).</li>
<li>Структурировали <code>README.md</code> и <code>AGENTS.md</code> как рабочую документацию процесса.</li>
</ol>
<p>То есть это уже не «написать один пост», а полноценный операционный цикл контентного проекта.</p>
<h2 class="heading" id="как-выглядел-рабочий-цикл-с-codex-cli">
  Как выглядел рабочий цикл с Codex CLI
  <a class="anchor" href="#%d0%ba%d0%b0%d0%ba-%d0%b2%d1%8b%d0%b3%d0%bb%d1%8f%d0%b4%d0%b5%d0%bb-%d1%80%d0%b0%d0%b1%d0%be%d1%87%d0%b8%d0%b9-%d1%86%d0%b8%d0%ba%d0%bb-%d1%81-codex-cli">#</a>
</h2>
<p>Самый полезный паттерн из этой сессии:</p>
<h3 class="heading" id="1-чёткая-постановка-задачи">
  1. Чёткая постановка задачи
  <a class="anchor" href="#1-%d1%87%d1%91%d1%82%d0%ba%d0%b0%d1%8f-%d0%bf%d0%be%d1%81%d1%82%d0%b0%d0%bd%d0%be%d0%b2%d0%ba%d0%b0-%d0%b7%d0%b0%d0%b4%d0%b0%d1%87%d0%b8">#</a>
</h3>
<p>Каждый шаг формулировался как конкретный результат:</p>
<ul>
<li>«Напиши новую статью про релиз».</li>
<li>«Почему статья не видна? Исправь».</li>
<li>«Сделай правило, чтобы проблема не повторялась».</li>
<li>«Сделай тему поиска в dracula».</li>
</ul>
<p>Чем конкретнее цель, тем меньше «творческого шума» и выше скорость прохождения задачи.</p>
<h3 class="heading" id="2-локальная-диагностика-перед-правкой">
  2. Локальная диагностика перед правкой
  <a class="anchor" href="#2-%d0%bb%d0%be%d0%ba%d0%b0%d0%bb%d1%8c%d0%bd%d0%b0%d1%8f-%d0%b4%d0%b8%d0%b0%d0%b3%d0%bd%d0%be%d1%81%d1%82%d0%b8%d0%ba%d0%b0-%d0%bf%d0%b5%d1%80%d0%b5%d0%b4-%d0%bf%d1%80%d0%b0%d0%b2%d0%ba%d0%be%d0%b9">#</a>
</h3>
<p>Перед изменением файлов Codex проходил короткий аудит:</p>
<ul>
<li>чтение текущих шаблонов/конфигов;</li>
<li>проверка фактического рендера;</li>
<li>сверка с реальным поведением сайта;</li>
<li>поиск причинно-следственной связи, а не симптомов.</li>
</ul>
<p>Пример мышления: если цвета не применились, сначала проверить порядок подключения CSS, а не сразу «добавить ещё <code>!important</code>».</p>
<h3 class="heading" id="3-точечная-правка--обязательная-валидация">
  3. Точечная правка + обязательная валидация
  <a class="anchor" href="#3-%d1%82%d0%be%d1%87%d0%b5%d1%87%d0%bd%d0%b0%d1%8f-%d0%bf%d1%80%d0%b0%d0%b2%d0%ba%d0%b0--%d0%be%d0%b1%d1%8f%d0%b7%d0%b0%d1%82%d0%b5%d0%bb%d1%8c%d0%bd%d0%b0%d1%8f-%d0%b2%d0%b0%d0%bb%d0%b8%d0%b4%d0%b0%d1%86%d0%b8%d1%8f">#</a>
</h3>
<p>После каждого изменения шёл одинаковый технический минимум:</p>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">hugo list future
</span></span><span class="line"><span class="cl">hugo --minify
</span></span><span class="line"><span class="cl">git status --short</span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<p>Это сильно снижает вероятность того, что в <code>main</code> улетит «логически верно, но технически сыро».</p>
<h3 class="heading" id="4-фиксация-в-git-маленькими-коммитами">
  4. Фиксация в git маленькими коммитами
  <a class="anchor" href="#4-%d1%84%d0%b8%d0%ba%d1%81%d0%b0%d1%86%d0%b8%d1%8f-%d0%b2-git-%d0%bc%d0%b0%d0%bb%d0%b5%d0%bd%d1%8c%d0%ba%d0%b8%d0%bc%d0%b8-%d0%ba%d0%be%d0%bc%d0%bc%d0%b8%d1%82%d0%b0%d0%bc%d0%b8">#</a>
</h3>
<p>Вместо одного гигантского коммита по итогам сессии:</p>
<ul>
<li>каждый смысловой шаг фиксировался отдельно;</li>
<li>сообщения коммитов были предметными;</li>
<li>любой этап можно быстро отследить и откатить локально при необходимости.</li>
</ul>
<p>Для блога это особенно удобно: контент, стили, шаблоны и правила не смешиваются в «одно большое изменение».</p>
<h2 class="heading" id="реальные-проблемы-которые-мы-поймали-и-закрыли">
  Реальные проблемы, которые мы поймали и закрыли
  <a class="anchor" href="#%d1%80%d0%b5%d0%b0%d0%bb%d1%8c%d0%bd%d1%8b%d0%b5-%d0%bf%d1%80%d0%be%d0%b1%d0%bb%d0%b5%d0%bc%d1%8b-%d0%ba%d0%be%d1%82%d0%be%d1%80%d1%8b%d0%b5-%d0%bc%d1%8b-%d0%bf%d0%be%d0%b9%d0%bc%d0%b0%d0%bb%d0%b8-%d0%b8-%d0%b7%d0%b0%d0%ba%d1%80%d1%8b%d0%bb%d0%b8">#</a>
</h2>
<h3 class="heading" id="проблема-1-пост-не-видно-на-сайте">
  Проблема 1: пост «не видно на сайте»
  <a class="anchor" href="#%d0%bf%d1%80%d0%be%d0%b1%d0%bb%d0%b5%d0%bc%d0%b0-1-%d0%bf%d0%be%d1%81%d1%82-%d0%bd%d0%b5-%d0%b2%d0%b8%d0%b4%d0%bd%d0%be-%d0%bd%d0%b0-%d1%81%d0%b0%d0%b9%d1%82%d0%b5">#</a>
</h3>
<p>Симптом: статья есть в репозитории, но не отображается в списке публикаций.</p>
<p>Причина: <code>date</code> в фронтматтере оказался в будущем относительно московского времени на момент деплоя.</p>
<p>Решение:</p>
<ul>
<li>сдвиг даты в прошлое;</li>
<li>проверка <code>hugo list future</code>;</li>
<li>фиксация правила в <code>AGENTS.md</code>: новые посты ставить на 5-10 минут в прошлое и всегда проверять future-список перед коммитом.</li>
</ul>
<p>Ключевой эффект: проблема устранена один раз на уровне процесса, а не «подкручена вручную» только для одного поста.</p>
<h3 class="heading" id="проблема-2-подсветка-кода-всё-одним-цветом">
  Проблема 2: подсветка кода «всё одним цветом»
  <a class="anchor" href="#%d0%bf%d1%80%d0%be%d0%b1%d0%bb%d0%b5%d0%bc%d0%b0-2-%d0%bf%d0%be%d0%b4%d1%81%d0%b2%d0%b5%d1%82%d0%ba%d0%b0-%d0%ba%d0%be%d0%b4%d0%b0-%d0%b2%d1%81%d1%91-%d0%be%d0%b4%d0%bd%d0%b8%d0%bc-%d1%86%d0%b2%d0%b5%d1%82%d0%be%d0%bc">#</a>
</h3>
<p>Симптом: HTML уже содержит <code>chroma</code>-классы, но визуально код почти монохромный.</p>
<p>Причина: базовый файл подсветки темы был близок к <code>bw</code>-палитре.</p>
<p>Решение:</p>
<ol>
<li>Включили работу через CSS-классы (<code>noClasses = false</code>).</li>
<li>Добавили собственный <code>assets/css/syntax-highlighting.css</code>.</li>
<li>Сначала проверили <code>monokai</code>, затем переключили на <code>dracula</code>.</li>
</ol>
<p>Итог: читаемая цветная подсветка с контролируемой темой в репозитории.</p>
<h3 class="heading" id="проблема-3-выдача-поиска-не-в-стиле-сайта">
  Проблема 3: выдача поиска не в стиле сайта
  <a class="anchor" href="#%d0%bf%d1%80%d0%be%d0%b1%d0%bb%d0%b5%d0%bc%d0%b0-3-%d0%b2%d1%8b%d0%b4%d0%b0%d1%87%d0%b0-%d0%bf%d0%be%d0%b8%d1%81%d0%ba%d0%b0-%d0%bd%d0%b5-%d0%b2-%d1%81%d1%82%d0%b8%d0%bb%d0%b5-%d1%81%d0%b0%d0%b9%d1%82%d0%b0">#</a>
</h3>
<p>Симптом: поле и результаты поиска выпадали из общей цветовой схемы.</p>
<p>Причина: стили <code>Pagefind</code> подключались после <code>custom.css</code>, и часть переопределений не применялась.</p>
<p>Решение:</p>
<ul>
<li>сначала добавили CSS-переменные <code>Pagefind</code> в <code>custom.css</code>;</li>
<li>затем сделали гарантированное переопределение после <code>pagefind-ui.css</code> прямо в шаблоне <code>layouts/search/single.html</code>.</li>
</ul>
<p>Это важный вывод: иногда нужно исправлять не «цвета», а точку и порядок их применения.</p>
<h3 class="heading" id="проблема-4-у-результатов-поиска-заголовок-evgeny-kushnarenko">
  Проблема 4: у результатов поиска заголовок «Evgeny Kushnarenko»
  <a class="anchor" href="#%d0%bf%d1%80%d0%be%d0%b1%d0%bb%d0%b5%d0%bc%d0%b0-4-%d1%83-%d1%80%d0%b5%d0%b7%d1%83%d0%bb%d1%8c%d1%82%d0%b0%d1%82%d0%be%d0%b2-%d0%bf%d0%be%d0%b8%d1%81%d0%ba%d0%b0-%d0%b7%d0%b0%d0%b3%d0%be%d0%bb%d0%be%d0%b2%d0%be%d0%ba-evgeny-kushnarenko">#</a>
</h3>
<p>Симптом: каждая найденная строка в выдаче имела одинаковый title (имя сайта).</p>
<p>Причина: <code>Pagefind</code> подхватывал <code>h1</code> из шапки страницы.</p>
<p>Решение:</p>
<ul>
<li>вынесли локальный <code>layouts/partials/header.html</code> и пометили шапку <code>data-pagefind-ignore</code>;</li>
<li>добавили <code>data-pagefind-meta=&quot;title&quot;</code> на <code>h1</code> поста в <code>layouts/_default/single.html</code>.</li>
</ul>
<p>Итог: выдача начала показывать реальные заголовки материалов.</p>
<h2 class="heading" id="что-это-даёт-в-ежедневной-работе">
  Что это даёт в ежедневной работе
  <a class="anchor" href="#%d1%87%d1%82%d0%be-%d1%8d%d1%82%d0%be-%d0%b4%d0%b0%d1%91%d1%82-%d0%b2-%d0%b5%d0%b6%d0%b5%d0%b4%d0%bd%d0%b5%d0%b2%d0%bd%d0%be%d0%b9-%d1%80%d0%b0%d0%b1%d0%be%d1%82%d0%b5">#</a>
</h2>
<p>После такого цикла становится заметно:</p>
<ol>
<li>Время между идеей и публикацией сокращается.</li>
<li>Ошибки переходят из категории «случайные и повторяющиеся» в «редкие и диагностируемые».</li>
<li>Репозиторий становится документацией процесса, а не просто папкой с контентом.</li>
<li>Снижается когнитивная нагрузка на автора: меньше ручной рутины, больше фокуса на смысле.</li>
</ol>
<p>На длинной дистанции это важнее, чем «сэкономить 5 минут на одной статье».</p>
<h2 class="heading" id="что-точно-не-нужно-автоматизировать">
  Что точно не нужно автоматизировать
  <a class="anchor" href="#%d1%87%d1%82%d0%be-%d1%82%d0%be%d1%87%d0%bd%d0%be-%d0%bd%d0%b5-%d0%bd%d1%83%d0%b6%d0%bd%d0%be-%d0%b0%d0%b2%d1%82%d0%be%d0%bc%d0%b0%d1%82%d0%b8%d0%b7%d0%b8%d1%80%d0%be%d0%b2%d0%b0%d1%82%d1%8c">#</a>
</h2>
<p>После пары таких сессий стало ясно: не любую задачу нужно отдавать инструменту. Есть три категории, где автоматизация скорее вредит:</p>
<p><strong>Тональность и личный голос.</strong> Codex может собрать структурный черновик, но финальный тон — авторская вещь. Если читатель чувствует «это писал не человек», доверие к материалу падает мгновенно. Заменять автора на этом этапе — значит потерять то, ради чего блог вообще существует.</p>
<p><strong>Спорные технические решения.</strong> Когда в дизайне есть выбор между двумя одинаково обоснованными подходами (положить компонент в <code>layouts/_default/</code> или в <code>layouts/posts/</code>, использовать ли Hugo Pipes для CSS или статичную копию), Codex даст «средний разумный вариант». Это не плохо, но это не вы. На длинной дистанции архитектурные решения, принятые «средним способом», накапливают трение, которое в одиночку не разглядеть.</p>
<p><strong>Решения про контент.</strong> Что писать, что не писать, какие посты убирать, какие оставлять, как переименовать раздел — это редакционные решения. Они должны проходить через автора. Инструмент здесь полезен только как «помощник по реализации», когда решение уже принято.</p>
<h2 class="heading" id="размышления-после-сессии">
  Размышления после сессии
  <a class="anchor" href="#%d1%80%d0%b0%d0%b7%d0%bc%d1%8b%d1%88%d0%bb%d0%b5%d0%bd%d0%b8%d1%8f-%d0%bf%d0%be%d1%81%d0%bb%d0%b5-%d1%81%d0%b5%d1%81%d1%81%d0%b8%d0%b8">#</a>
</h2>
<p>Главный вывод после нескольких часов работы в таком режиме: ценность автоматизации не в скорости, а в <strong>предсказуемости</strong>. До регулярной работы с Codex CLI каждая публикация поста была чуть-чуть разной: где-то забыл подвинуть дату, где-то не проверил подсветку, где-то не закоммитил отдельно стилевую правку. После — процесс стал ровным, что освободило внимание для содержания.</p>
<p>Это типичная история про инфраструктуру: когда она работает плохо, она занимает 60% мысленного бюджета на каждое действие. Когда хорошо — становится незаметной, и весь бюджет уходит на смысл.</p>
<h2 class="heading" id="практический-шаблон-автоматизации-под-hugo">
  Практический шаблон автоматизации под Hugo
  <a class="anchor" href="#%d0%bf%d1%80%d0%b0%d0%ba%d1%82%d0%b8%d1%87%d0%b5%d1%81%d0%ba%d0%b8%d0%b9-%d1%88%d0%b0%d0%b1%d0%bb%d0%be%d0%bd-%d0%b0%d0%b2%d1%82%d0%be%d0%bc%d0%b0%d1%82%d0%b8%d0%b7%d0%b0%d1%86%d0%b8%d0%b8-%d0%bf%d0%be%d0%b4-hugo">#</a>
</h2>
<p>Если хотите повторить подход, можно взять такой минимум:</p>
<ol>
<li>Для каждой задачи: цель в 1-2 предложениях.</li>
<li>Перед правкой: чтение текущего состояния (<code>rg</code>, <code>sed</code>, шаблоны, конфиги).</li>
<li>После правки: <code>hugo list future</code> + <code>hugo --minify</code>.</li>
<li>Фиксация: один смысл = один коммит.</li>
<li>Публикация: <code>git push</code> сразу после проверки.</li>
<li>Если баг повторяемый: правило в <code>AGENTS.md</code>, а не «устная договорённость».</li>
</ol>
<h2 class="heading" id="набор-команд-который-реально-работал-в-этой-сессии">
  Набор команд, который реально работал в этой сессии
  <a class="anchor" href="#%d0%bd%d0%b0%d0%b1%d0%be%d1%80-%d0%ba%d0%be%d0%bc%d0%b0%d0%bd%d0%b4-%d0%ba%d0%be%d1%82%d0%be%d1%80%d1%8b%d0%b9-%d1%80%d0%b5%d0%b0%d0%bb%d1%8c%d0%bd%d0%be-%d1%80%d0%b0%d0%b1%d0%be%d1%82%d0%b0%d0%bb-%d0%b2-%d1%8d%d1%82%d0%be%d0%b9-%d1%81%d0%b5%d1%81%d1%81%d0%b8%d0%b8">#</a>
</h2>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Проверки контента и даты</span>
</span></span><span class="line"><span class="cl">hugo list future
</span></span><span class="line"><span class="cl">hugo --minify
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Диагностика</span>
</span></span><span class="line"><span class="cl">rg -n <span class="s2">&#34;pagefind|highlight|chroma&#34;</span> -S .
</span></span><span class="line"><span class="cl">sed -n <span class="s1">&#39;1,220p&#39;</span> layouts/search/single.html
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Публикация</span>
</span></span><span class="line"><span class="cl">git add &lt;файлы&gt;
</span></span><span class="line"><span class="cl">git commit -m <span class="s2">&#34;Осмысленный коммит по одной задаче&#34;</span>
</span></span><span class="line"><span class="cl">git push</span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<p>Никакой экзотики: сила не в сложных командах, а в дисциплине последовательности.</p>
<h2 class="heading" id="практические-выводы">
  Практические выводы
  <a class="anchor" href="#%d0%bf%d1%80%d0%b0%d0%ba%d1%82%d0%b8%d1%87%d0%b5%d1%81%d0%ba%d0%b8%d0%b5-%d0%b2%d1%8b%d0%b2%d0%be%d0%b4%d1%8b">#</a>
</h2>
<p>Автоматизация блога через Codex CLI работает лучше всего, когда вы относитесь к ней как к инженерному процессу:</p>
<ol>
<li>Чёткая постановка задач.</li>
<li>Наблюдаемость и проверки после каждого шага.</li>
<li>Маленькие коммиты с понятной ответственностью.</li>
<li>Фиксация правил в репозитории.</li>
</ol>
<p>Тогда Codex становится не «генератором текста», а операционным партнёром, который помогает держать качество и темп публикаций одновременно. ✅</p>
]]></content:encoded><category>ai-инструменты</category><category>автоматизация</category><category>hugo</category><category>runbook</category></item><item><title>Hugo 0.157.0: GitInfo для модулей, timeout в GetRemote и практическая миграция 🚀</title><link>https://kushnaren.co/posts/hugo-0-157-0-gitinfo-moduli-timeouty-getremote/</link><pubDate>Thu, 05 Mar 2026 19:50:00 +0300</pubDate><guid isPermaLink="true">https://kushnaren.co/posts/hugo-0-157-0-gitinfo-moduli-timeouty-getremote/</guid><description>Разбираю ключевые нововведения Hugo v0.157.0 и показываю, как безопасно обновиться: что проверить в CI, шаблонах, модулях и интеграциях с внешними API.</description><content:encoded><![CDATA[<p>25 февраля 2026 года вышел <a href="https://github.com/gohugoio/hugo/releases/tag/v0.157.0">Hugo v0.157.0</a>. На первый взгляд релиз выглядит как «ещё один минорный апдейт», но внутри есть сразу несколько изменений, которые заметно улучшают работу реальных проектов: особенно если у вас модульная архитектура, контент из нескольких репозиториев и внешние запросы в шаблонах.</p>
<p>В этой статье разберём, что именно изменилось, где может быть практический эффект, и как пройти обновление без сюрпризов. 🚀</p>
<p>Кому это релевантно сразу: командам, ведущим контент через Hugo Modules; авторам тем, использующим внешние API в шаблонах; всем, у кого билд иногда «висит» из-за медленного источника. Кому можно отложить: одиночный блог без модулей и без внешних запросов получит апгрейд почти прозрачно — обновляйтесь как часть обычной уборки технического долга.</p>
<h2 class="heading" id="почему-релиз-01570-важен">
  Почему релиз 0.157.0 важен
  <a class="anchor" href="#%d0%bf%d0%be%d1%87%d0%b5%d0%bc%d1%83-%d1%80%d0%b5%d0%bb%d0%b8%d0%b7-01570-%d0%b2%d0%b0%d0%b6%d0%b5%d0%bd">#</a>
</h2>
<p>Главная идея релиза: Hugo становится устойчивее в «боевых» сценариях, где проект не ограничивается одной папкой <code>content</code> и парой шаблонов.</p>
<p>Ключевые точки:</p>
<ol>
<li><code>Page.GitInfo</code> теперь полноценно поддерживает контент из Git-модулей (через mounts).</li>
<li>В <code>resources.GetRemote</code> появился перезапросный <code>timeout</code>, который можно задавать прямо в шаблоне.</li>
<li>Добавлена частичная поддержка AVIF/HEIF/HEIC (пока только метаданные).</li>
<li>Улучшены дефолты обработки WebP.</li>
<li>Исправлены ошибки, влияющие на меню, section pages и стабильность сборок.</li>
</ol>
<p>Если коротко: меньше «магии», больше управляемости. 🎯</p>
<h2 class="heading" id="gitinfo-для-hugo-modules-что-реально-изменилось-">
  GitInfo для Hugo Modules: что реально изменилось 🧩
  <a class="anchor" href="#gitinfo-%d0%b4%d0%bb%d1%8f-hugo-modules-%d1%87%d1%82%d0%be-%d1%80%d0%b5%d0%b0%d0%bb%d1%8c%d0%bd%d0%be-%d0%b8%d0%b7%d0%bc%d0%b5%d0%bd%d0%b8%d0%bb%d0%be%d1%81%d1%8c-">#</a>
</h2>
<h3 class="heading" id="проблема-до-01570">
  Проблема до 0.157.0
  <a class="anchor" href="#%d0%bf%d1%80%d0%be%d0%b1%d0%bb%d0%b5%d0%bc%d0%b0-%d0%b4%d0%be-01570">#</a>
</h3>
<p>Если вы подключали контент через <code>module.imports.mounts</code> (например, общий набор статей или документацию из отдельного репозитория), <code>GitInfo</code> мог работать неполно или нестабильно для таких страниц.</p>
<p>Это мешало:</p>
<ul>
<li>корректно выводить «последнее обновление» для импортированного контента;</li>
<li>строить списки изменений по коммитам;</li>
<li>делать единый шаблон мета-блока для локального и модульного контента.</li>
</ul>
<h3 class="heading" id="что-даёт-01570">
  Что даёт 0.157.0
  <a class="anchor" href="#%d1%87%d1%82%d0%be-%d0%b4%d0%b0%d1%91%d1%82-01570">#</a>
</h3>
<p>В релизе добавлена и доработана поддержка <code>Page.GitInfo</code> для контента из Git-модулей. То есть страницы, примонтированные из модулей, теперь могут корректно отдавать данные о коммите: автора, дату, хеш, subject и т.д.</p>
<p>Это особенно полезно для:</p>
<ul>
<li>docs-порталов из нескольких репозиториев;</li>
<li>мультисайтов, где контентные команды работают независимо;</li>
<li>архитектуры «ядро темы + контент как модуль».</li>
</ul>
<h3 class="heading" id="практический-шаблон">
  Практический шаблон
  <a class="anchor" href="#%d0%bf%d1%80%d0%b0%d0%ba%d1%82%d0%b8%d1%87%d0%b5%d1%81%d0%ba%d0%b8%d0%b9-%d1%88%d0%b0%d0%b1%d0%bb%d0%be%d0%bd">#</a>
</h3>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go-html-template" data-lang="go-html-template"><span class="line"><span class="cl"><span class="cp">{{</span><span class="w"> </span><span class="k">with</span><span class="w"> </span><span class="na">.GitInfo</span><span class="w"> </span><span class="cp">}}</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">p</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;meta&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    Обновлено: <span class="cp">{{</span><span class="w"> </span><span class="na">.AuthorDate.Format</span><span class="w"> </span><span class="s">&#34;2006-01-02 15:04&#34;</span><span class="w"> </span><span class="cp">}}</span> ·
</span></span><span class="line"><span class="cl">    Автор: <span class="cp">{{</span><span class="w"> </span><span class="na">.AuthorName</span><span class="w"> </span><span class="cp">}}</span> ·
</span></span><span class="line"><span class="cl">    Коммит: <span class="p">&lt;</span><span class="nt">code</span><span class="p">&gt;</span><span class="cp">{{</span><span class="w"> </span><span class="na">.AbbreviatedHash</span><span class="w"> </span><span class="cp">}}</span><span class="p">&lt;/</span><span class="nt">code</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;/</span><span class="nt">p</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="cp">{{</span><span class="w"> </span><span class="k">end</span><span class="w"> </span><span class="cp">}}</span></span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<p>Важный operational-момент: в CI должен быть <strong>не shallow clone</strong>, иначе Git-данные могут быть неточными.</p>
<h2 class="heading" id="resourcesgetremote-получил-timeout-контроль-вместо-зависаний-">
  <code>resources.GetRemote</code> получил <code>timeout</code>: контроль вместо зависаний ⏱️
  <a class="anchor" href="#resourcesgetremote-%d0%bf%d0%be%d0%bb%d1%83%d1%87%d0%b8%d0%bb-timeout-%d0%ba%d0%be%d0%bd%d1%82%d1%80%d0%be%d0%bb%d1%8c-%d0%b2%d0%bc%d0%b5%d1%81%d1%82%d0%be-%d0%b7%d0%b0%d0%b2%d0%b8%d1%81%d0%b0%d0%bd%d0%b8%d0%b9-">#</a>
</h2>
<h3 class="heading" id="что-болело-раньше">
  Что болело раньше
  <a class="anchor" href="#%d1%87%d1%82%d0%be-%d0%b1%d0%be%d0%bb%d0%b5%d0%bb%d0%be-%d1%80%d0%b0%d0%bd%d1%8c%d1%88%d0%b5">#</a>
</h3>
<p>Когда вы тянете внешние данные (RSS/JSON/изображения), один медленный источник мог подвесить сборку. На небольшом сайте это раздражает, а на большом CI-пайплайне превращается в регулярную проблему.</p>
<h3 class="heading" id="что-появилось-в-01570">
  Что появилось в 0.157.0
  <a class="anchor" href="#%d1%87%d1%82%d0%be-%d0%bf%d0%be%d1%8f%d0%b2%d0%b8%d0%bb%d0%be%d1%81%d1%8c-%d0%b2-01570">#</a>
</h3>
<p>Теперь в <code>resources.GetRemote</code> есть опция <code>timeout</code> (строка длительности, например <code>&quot;10s&quot;</code>). Её можно задавать для каждого запроса отдельно.</p>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go-html-template" data-lang="go-html-template"><span class="line"><span class="cl"><span class="cp">{{</span><span class="w"> </span><span class="nx">$url</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="s">&#34;https://example.org/feed.rss&#34;</span><span class="w"> </span><span class="cp">}}</span>
</span></span><span class="line"><span class="cl"><span class="cp">{{</span><span class="w"> </span><span class="nx">$opts</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">dict</span><span class="w"> </span><span class="s">&#34;timeout&#34;</span><span class="w"> </span><span class="s">&#34;10s&#34;</span><span class="w"> </span><span class="cp">}}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="cp">{{</span><span class="w"> </span><span class="k">with</span><span class="w"> </span><span class="nx">try</span><span class="w"> </span><span class="o">(</span><span class="nx">resources</span><span class="na">.GetRemote</span><span class="w"> </span><span class="nx">$url</span><span class="w"> </span><span class="nx">$opts</span><span class="o">)</span><span class="w"> </span><span class="cp">}}</span>
</span></span><span class="line"><span class="cl">  <span class="cp">{{</span><span class="w"> </span><span class="k">with</span><span class="w"> </span><span class="na">.Err</span><span class="w"> </span><span class="cp">}}</span>
</span></span><span class="line"><span class="cl">    <span class="cp">{{</span><span class="w"> </span><span class="nx">warnf</span><span class="w"> </span><span class="s">&#34;Не удалось получить feed %q: %s&#34;</span><span class="w"> </span><span class="nx">$url</span><span class="w"> </span><span class="na">.</span><span class="w"> </span><span class="cp">}}</span>
</span></span><span class="line"><span class="cl">  <span class="cp">{{</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="k">with</span><span class="w"> </span><span class="na">.Value</span><span class="w"> </span><span class="cp">}}</span>
</span></span><span class="line"><span class="cl">    <span class="cp">{{</span><span class="w"> </span><span class="nx">$data</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="na">.</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="nx">transform</span><span class="na">.Unmarshal</span><span class="w"> </span><span class="cp">}}</span>
</span></span><span class="line"><span class="cl">    <span class="cm">{{/* дальнейшая работа с данными */}}</span>
</span></span><span class="line"><span class="cl">    <span class="cp">{{</span><span class="w"> </span><span class="nx">$data</span><span class="w"> </span><span class="cp">}}</span>
</span></span><span class="line"><span class="cl">  <span class="cp">{{</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="cp">}}</span>
</span></span><span class="line"><span class="cl">    <span class="cp">{{</span><span class="w"> </span><span class="nx">warnf</span><span class="w"> </span><span class="s">&#34;Ресурс %q не найден&#34;</span><span class="w"> </span><span class="nx">$url</span><span class="w"> </span><span class="cp">}}</span>
</span></span><span class="line"><span class="cl">  <span class="cp">{{</span><span class="w"> </span><span class="k">end</span><span class="w"> </span><span class="cp">}}</span>
</span></span><span class="line"><span class="cl"><span class="cp">{{</span><span class="w"> </span><span class="k">end</span><span class="w"> </span><span class="cp">}}</span></span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<p>Практический эффект:</p>
<ul>
<li>можно задавать строгий timeout для нестабильных источников;</li>
<li>сборка перестаёт «висеть» из-за одного внешнего API;</li>
<li>проще разделить критичные и некритичные источники (где-то <code>errorf</code>, где-то <code>warnf</code>).</li>
</ul>
<h2 class="heading" id="изображения-что-важно-понимать-про-avifheifheic-и-webp">
  Изображения: что важно понимать про AVIF/HEIF/HEIC и WebP
  <a class="anchor" href="#%d0%b8%d0%b7%d0%be%d0%b1%d1%80%d0%b0%d0%b6%d0%b5%d0%bd%d0%b8%d1%8f-%d1%87%d1%82%d0%be-%d0%b2%d0%b0%d0%b6%d0%bd%d0%be-%d0%bf%d0%be%d0%bd%d0%b8%d0%bc%d0%b0%d1%82%d1%8c-%d0%bf%d1%80%d0%be-avifheifheic-%d0%b8-webp">#</a>
</h2>
<p>В 0.157.0 добавили <strong>частичную</strong> поддержку AVIF/HEIF/HEIC: на текущем этапе это поддержка метаданных, а не полноценный новый pipeline обработки.</p>
<p>Что это значит на практике:</p>
<ul>
<li>Hugo лучше распознаёт такие файлы;</li>
<li>можно безопаснее работать с метаданными;</li>
<li>но не стоит ожидать полной parity с привычной обработкой JPEG/PNG/WebP прямо «из коробки».</li>
</ul>
<p>Также в релизе скорректированы настройки обработки WebP. Если вы строите агрессивный image pipeline, стоит прогнать визуальные regression-проверки на ключевых страницах.</p>
<h2 class="heading" id="дополнительные-исправления-которые-могут-всплыть-в-проде">
  Дополнительные исправления, которые могут «всплыть» в проде
  <a class="anchor" href="#%d0%b4%d0%be%d0%bf%d0%be%d0%bb%d0%bd%d0%b8%d1%82%d0%b5%d0%bb%d1%8c%d0%bd%d1%8b%d0%b5-%d0%b8%d1%81%d0%bf%d1%80%d0%b0%d0%b2%d0%bb%d0%b5%d0%bd%d0%b8%d1%8f-%d0%ba%d0%be%d1%82%d0%be%d1%80%d1%8b%d0%b5-%d0%bc%d0%be%d0%b3%d1%83%d1%82-%d0%b2%d1%81%d0%bf%d0%bb%d1%8b%d1%82%d1%8c-%d0%b2-%d0%bf%d1%80%d0%be%d0%b4%d0%b5">#</a>
</h2>
<p>В релизе есть не самые заметные, но полезные улучшения:</p>
<ul>
<li>фикс <code>menu pageRef</code> в multidimensional-настройках;</li>
<li>корректировки в логике section pages;</li>
<li>улучшенные сообщения об ошибках модулей (<code>go mod download</code>);</li>
<li>пропуск пустых taxonomy-ключей/значений в конфиге.</li>
</ul>
<p>Каждый пункт по отдельности небольшой, но вместе они снижают количество «странных» инцидентов после релиза.</p>
<h2 class="heading" id="сценарий-который-раньше-ломался-контент-в-нескольких-модулях">
  Сценарий, который раньше ломался: контент в нескольких модулях
  <a class="anchor" href="#%d1%81%d1%86%d0%b5%d0%bd%d0%b0%d1%80%d0%b8%d0%b9-%d0%ba%d0%be%d1%82%d0%be%d1%80%d1%8b%d0%b9-%d1%80%d0%b0%d0%bd%d1%8c%d1%88%d0%b5-%d0%bb%d0%be%d0%bc%d0%b0%d0%bb%d1%81%d1%8f-%d0%ba%d0%be%d0%bd%d1%82%d0%b5%d0%bd%d1%82-%d0%b2-%d0%bd%d0%b5%d1%81%d0%ba%d0%be%d0%bb%d1%8c%d0%ba%d0%b8%d1%85-%d0%bc%d0%be%d0%b4%d1%83%d0%bb%d1%8f%d1%85">#</a>
</h2>
<p>Чтобы понять ценность изменений вокруг GitInfo и section pages, представьте типичную mid-size-конфигурацию: основной репозиторий с темой, плюс два модуля с контентом — <code>docs/</code> и <code>blog/</code>, каждый в своём Git-репо. Их подмонтировали в основной сайт через <code>module.imports.mounts</code>.</p>
<p>До 0.157.0 в этой конфигурации возникали мелкие неприятности: даты в footer&rsquo;е импортированных постов отдавали поведение «default-на-momento-сборки» вместо «коммит-автор-дата»; menu иногда теряла pageRef для импортированных страниц при определённых вариантах языковой настройки; ошибки <code>go mod download</code> приходили без контекста, и приходилось вручную перебирать модули, чтобы найти проблемный.</p>
<p>В 0.157.0 каждый из этих краевых случаев починен. Если вы держите такой setup, после обновления заметна разница: меньше ручных правок шаблонов под «странности» modular-контента, прозрачнее ошибки при сетевых проблемах с одним из модулей.</p>
<h2 class="heading" id="когда-обновляться-можно-отложить">
  Когда обновляться можно отложить
  <a class="anchor" href="#%d0%ba%d0%be%d0%b3%d0%b4%d0%b0-%d0%be%d0%b1%d0%bd%d0%be%d0%b2%d0%bb%d1%8f%d1%82%d1%8c%d1%81%d1%8f-%d0%bc%d0%be%d0%b6%d0%bd%d0%be-%d0%be%d1%82%d0%bb%d0%be%d0%b6%d0%b8%d1%82%d1%8c">#</a>
</h2>
<p>Если у вас одиночный сайт без модулей, без <code>resources.GetRemote</code> в шаблонах, без AVIF/HEIF в pipeline и без активных кастомных меню с <code>pageRef</code> — этот релиз вас почти не коснётся. Обновитесь в плановом окне (вместе с пересборкой Docker-образа, например), но срочности нет.</p>
<p>Срочно обновляться стоит, если: используете <code>resources.GetRemote</code> и хотя бы раз попадали на медленный source; ведёте мультимодульный контент; пишете кастомные шаблоны с <code>.GitInfo</code> для импортированных страниц.</p>
<h2 class="heading" id="чек-лист-обновления-до-hugo-01570-">
  Чек-лист обновления до Hugo 0.157.0 ✅
  <a class="anchor" href="#%d1%87%d0%b5%d0%ba-%d0%bb%d0%b8%d1%81%d1%82-%d0%be%d0%b1%d0%bd%d0%be%d0%b2%d0%bb%d0%b5%d0%bd%d0%b8%d1%8f-%d0%b4%d0%be-hugo-01570-">#</a>
</h2>
<ol>
<li>Обновите бинарь/образ Hugo до <code>0.157.0</code>.</li>
<li>Если используете <code>GitInfo</code>, проверьте <code>enableGitInfo: true</code> в конфигурации.</li>
<li>Убедитесь, что CI делает глубокий клон репозитория (<code>fetch-depth: 0</code> в GitHub Actions или эквивалент).</li>
<li>Для всех <code>resources.GetRemote</code> проставьте осмысленный <code>timeout</code> и единообразный <code>try</code>-обработчик.</li>
<li>Прогоните smoke-тесты меню, section pages и страниц с импортированным модульным контентом.</li>
<li>Проверьте image pipeline (особенно WebP) на визуальные отличия.</li>
<li>Сравните длительность сборки до/после обновления.</li>
</ol>
<h2 class="heading" id="мини-план-миграции-на-30-минут">
  Мини-план миграции на 30 минут
  <a class="anchor" href="#%d0%bc%d0%b8%d0%bd%d0%b8-%d0%bf%d0%bb%d0%b0%d0%bd-%d0%bc%d0%b8%d0%b3%d1%80%d0%b0%d1%86%d0%b8%d0%b8-%d0%bd%d0%b0-30-%d0%bc%d0%b8%d0%bd%d1%83%d1%82">#</a>
</h2>
<p>Если проект уже в хорошем состоянии, переход можно сделать быстро:</p>
<ol>
<li>10 минут: поднять версию и собрать сайт локально без warning/error.</li>
<li>10 минут: проверить шаблоны с <code>.GitInfo</code> и блоки с <code>resources.GetRemote</code>.</li>
<li>10 минут: прогнать CI и открыть несколько критичных страниц руками.</li>
</ol>
<p>Обычно этого достаточно, чтобы перейти на релиз без ночных откатов.</p>
<h2 class="heading" id="итог-">
  Итог 🧠
  <a class="anchor" href="#%d0%b8%d1%82%d0%be%d0%b3-">#</a>
</h2>
<p>Hugo 0.157.0 не про «громкие фичи ради фич», а про зрелость платформы: лучшее поведение в модульных проектах, более предсказуемая работа с внешними запросами и аккуратные улучшения инфраструктурного уровня.</p>
<p>Если у вас контент разбит на модули, а сборка зависит от внешних данных, обновление стоит делать в ближайшем цикле.</p>
<h2 class="heading" id="источники">
  Источники
  <a class="anchor" href="#%d0%b8%d1%81%d1%82%d0%be%d1%87%d0%bd%d0%b8%d0%ba%d0%b8">#</a>
</h2>
<ul>
<li>Официальный релиз: <a href="https://github.com/gohugoio/hugo/releases/tag/v0.157.0">gohugoio/hugo v0.157.0</a></li>
<li>Документация <code>Page.GitInfo</code>: <a href="https://gohugo.io/methods/page/gitinfo/">gohugo.io/methods/page/gitinfo</a></li>
<li>Документация <code>resources.GetRemote</code>: <a href="https://gohugo.io/functions/resources/getremote/">gohugo.io/functions/resources/getremote</a></li>
</ul>
]]></content:encoded><category>hugo</category><category>релизы</category></item><item><title>Hugo 0.156.0: что нового и что проверить после обновления 🚀</title><link>https://kushnaren.co/posts/hugo-0-156-0-obzor-novovvedenij/</link><pubDate>Wed, 18 Feb 2026 21:00:00 +0300</pubDate><guid isPermaLink="true">https://kushnaren.co/posts/hugo-0-156-0-obzor-novovvedenij/</guid><description>Подробный разбор Hugo v0.156.0 по официальным release notes: переход на новые API hugo.Data/hugo.Sites, изменения в link render hooks, переводы site.Home, опция disableSetLocale, практический чек-лист обновления.</description><content:encoded><![CDATA[<h2 class="heading" id="зачем-вообще-читать-про-минорный-релиз">
  Зачем вообще читать про минорный релиз
  <a class="anchor" href="#%d0%b7%d0%b0%d1%87%d0%b5%d0%bc-%d0%b2%d0%be%d0%be%d0%b1%d1%89%d0%b5-%d1%87%d0%b8%d1%82%d0%b0%d1%82%d1%8c-%d0%bf%d1%80%d0%be-%d0%bc%d0%b8%d0%bd%d0%be%d1%80%d0%bd%d1%8b%d0%b9-%d1%80%d0%b5%d0%bb%d0%b8%d0%b7">#</a>
</h2>
<p>18 февраля 2026 вышел <a href="https://github.com/gohugoio/hugo/releases/tag/v0.156.0">Hugo v0.156.0</a>. Если поверхностно прочитать changelog, это очередной минор: пара новых методов, несколько депрекейтов, опция конфига. Звучит как «обновлюсь когда руки дойдут».</p>
<p>Но именно из таких минорных релизов и копится технический долг. Депрекейт API сегодня — это broken-build через год, когда вы решите перейти на крупную версию. Минута, потраченная сейчас, чтобы привести шаблоны в соответствие, экономит вечер разбирательств позже.</p>
<p>В этом посте — что реально изменилось, что заметно в шаблонах, и короткий чек-лист, который проходится за 30 минут.</p>
<h2 class="heading" id="главное-за-один-взгляд">
  Главное за один взгляд
  <a class="anchor" href="#%d0%b3%d0%bb%d0%b0%d0%b2%d0%bd%d0%be%d0%b5-%d0%b7%d0%b0-%d0%be%d0%b4%d0%b8%d0%bd-%d0%b2%d0%b7%d0%b3%d0%bb%d1%8f%d0%b4">#</a>
</h2>
<p>Релиз 0.156.0 содержит шесть значимых изменений:</p>
<ol>
<li>Добавлены новые API: <code>hugo.Data</code> и <code>hugo.Sites</code>.</li>
<li>Устаревшими объявлены <code>site.Data</code> и <code>site.Sites</code> (пока работают для обратной совместимости).</li>
<li>В контекст link render hooks добавлены методы <code>IsBlock</code> и <code>Ordinal</code>.</li>
<li>Добавлен новый метод <code>site.Home.Translations</code>; <code>site.Home.AllTranslations</code> помечен как deprecated.</li>
<li>Появилась опция конфигурации <code>disableSetLocale</code>.</li>
<li>Помечен как deprecated путь <code>_vendor/github.com/gohugoio/locales</code>.</li>
</ol>
<p>Дальше — по каждому пункту, что это значит на практике и что менять.</p>
<h2 class="heading" id="переезд-sitedata--hugodata-">
  Переезд site.Data → hugo.Data 🧱
  <a class="anchor" href="#%d0%bf%d0%b5%d1%80%d0%b5%d0%b5%d0%b7%d0%b4-sitedata--hugodata-">#</a>
</h2>
<p>Самое заметное смысловое изменение — переезд глобальных коллекций данных и сайтов с пространства имён <code>site.*</code> на <code>hugo.*</code>.</p>
<p>Сейчас в шаблонах вы могли писать:</p>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go-html-template" data-lang="go-html-template"><span class="line"><span class="cl"><span class="cp">{{</span><span class="w"> </span><span class="k">range</span><span class="w"> </span><span class="nx">site</span><span class="na">.Data.authors</span><span class="w"> </span><span class="cp">}}</span>
</span></span><span class="line"><span class="cl">  ...
</span></span><span class="line"><span class="cl"><span class="cp">{{</span><span class="w"> </span><span class="k">end</span><span class="w"> </span><span class="cp">}}</span></span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<p>После 0.156 рекомендуется:</p>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go-html-template" data-lang="go-html-template"><span class="line"><span class="cl"><span class="cp">{{</span><span class="w"> </span><span class="k">range</span><span class="w"> </span><span class="nx">hugo</span><span class="na">.Data.authors</span><span class="w"> </span><span class="cp">}}</span>
</span></span><span class="line"><span class="cl">  ...
</span></span><span class="line"><span class="cl"><span class="cp">{{</span><span class="w"> </span><span class="k">end</span><span class="w"> </span><span class="cp">}}</span></span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<p>Версия со старым <code>site.Data</code> пока работает — ради совместимости. Но в release notes явно сказано: новые методы предпочтительнее, старые помечены как deprecated. Когда придёт следующая major-версия (Hugo любит чистить депрекейты), <code>site.Data</code> могут совсем убрать.</p>
<p>Аналогичная история с <code>site.Sites</code> → <code>hugo.Sites</code>. Используется реже, в основном на мультисайтах с подмножеством общих ресурсов.</p>
<p><strong>Что делать:</strong> массовый поиск-замена в шаблонах темы и проекта:</p>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">grep -rn <span class="s1">&#39;site\.Data\|site\.Sites&#39;</span> layouts/ themes/*/layouts/ 2&gt;/dev/null</span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<p>Если хитов нет — вы никак не зависите от этого изменения. Если есть — заменить на <code>hugo.Data</code> и <code>hugo.Sites</code>.</p>
<h2 class="heading" id="render-hooks-isblock-и-ordinal-">
  Render hooks: IsBlock и Ordinal 🔗
  <a class="anchor" href="#render-hooks-isblock-%d0%b8-ordinal-">#</a>
</h2>
<p>Если у вас есть кастомные <a href="https://gohugo.io/render-hooks/links/">link render hooks</a> (файл <code>layouts/_default/_markup/render-link.html</code> или подобный), в их контексте теперь доступны два новых метода:</p>
<ul>
<li><code>IsBlock</code> — true, если ссылка стоит как самостоятельный блок (например, <code>&lt;p&gt;[link](url)&lt;/p&gt;</code> где это единственный элемент абзаца), а не inline внутри текста.</li>
<li><code>Ordinal</code> — порядковый номер ссылки в документе, начиная с 0.</li>
</ul>
<p>Зачем это нужно:</p>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go-html-template" data-lang="go-html-template"><span class="line"><span class="cl"><span class="cm">{{/* render-link.html */}}</span>
</span></span><span class="line"><span class="cl"><span class="cp">{{</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="na">.IsBlock</span><span class="w"> </span><span class="cp">}}</span>
</span></span><span class="line"><span class="cl">  <span class="cm">{{/* Самостоятельная ссылка — рендерим как карточку */}}</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">a</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;link-card&#34;</span> <span class="na">href</span><span class="o">=</span><span class="s">&#34;</span><span class="cp">{{</span><span class="w"> </span><span class="na">.Destination</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="nx">safeURL</span><span class="w"> </span><span class="cp">}}</span><span class="s">&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">span</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;link-card__num&#34;</span><span class="p">&gt;</span>№<span class="cp">{{</span><span class="w"> </span><span class="nx">add</span><span class="w"> </span><span class="na">.Ordinal</span><span class="w"> </span><span class="nx">1</span><span class="w"> </span><span class="cp">}}</span><span class="p">&lt;/</span><span class="nt">span</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">span</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;link-card__text&#34;</span><span class="p">&gt;</span><span class="cp">{{</span><span class="w"> </span><span class="na">.Text</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="nx">safeHTML</span><span class="w"> </span><span class="cp">}}</span><span class="p">&lt;/</span><span class="nt">span</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;/</span><span class="nt">a</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="cp">{{</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="cp">}}</span>
</span></span><span class="line"><span class="cl">  <span class="cm">{{/* Inline-ссылка — обычный &lt;a&gt; */}}</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">a</span> <span class="na">href</span><span class="o">=</span><span class="s">&#34;</span><span class="cp">{{</span><span class="w"> </span><span class="na">.Destination</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="nx">safeURL</span><span class="w"> </span><span class="cp">}}</span><span class="s">&#34;</span><span class="p">&gt;</span><span class="cp">{{</span><span class="w"> </span><span class="na">.Text</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="nx">safeHTML</span><span class="w"> </span><span class="cp">}}</span><span class="p">&lt;/</span><span class="nt">a</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="cp">{{</span><span class="w"> </span><span class="k">end</span><span class="w"> </span><span class="cp">}}</span></span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<p>Это удобно для блогов с активным использованием ссылок: можно по-разному оформлять «отдельные ссылки на источники» и «inline-упоминания».</p>
<p><code>Ordinal</code> помогает строить нумерованные списки источников или footnote-style references без ручной разметки.</p>
<h2 class="heading" id="мультиязычность-sitehometranslations-">
  Мультиязычность: site.Home.Translations 🌐
  <a class="anchor" href="#%d0%bc%d1%83%d0%bb%d1%8c%d1%82%d0%b8%d1%8f%d0%b7%d1%8b%d1%87%d0%bd%d0%be%d1%81%d1%82%d1%8c-sitehometranslations-">#</a>
</h2>
<p>Метод <code>site.Home.AllTranslations</code> помечен как deprecated. Заменяет его более узкий <code>site.Home.Translations</code>.</p>
<p>Разница:</p>
<ul>
<li><code>AllTranslations</code> возвращает <strong>все</strong> языковые версии главной страницы, <strong>включая текущую</strong>.</li>
<li><code>Translations</code> возвращает только <strong>другие</strong> языки, без текущей версии.</li>
</ul>
<p>Старый код:</p>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go-html-template" data-lang="go-html-template"><span class="line"><span class="cl"><span class="cp">{{</span><span class="w"> </span><span class="k">range</span><span class="w"> </span><span class="nx">site</span><span class="na">.Home.AllTranslations</span><span class="w"> </span><span class="cp">}}</span>
</span></span><span class="line"><span class="cl">  <span class="cp">{{</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="k">ne</span><span class="w"> </span><span class="na">.Lang</span><span class="w"> </span><span class="na">$.Lang</span><span class="w"> </span><span class="cp">}}</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">a</span> <span class="na">href</span><span class="o">=</span><span class="s">&#34;</span><span class="cp">{{</span><span class="w"> </span><span class="na">.Permalink</span><span class="w"> </span><span class="cp">}}</span><span class="s">&#34;</span><span class="p">&gt;</span><span class="cp">{{</span><span class="w"> </span><span class="na">.Language.LanguageName</span><span class="w"> </span><span class="cp">}}</span><span class="p">&lt;/</span><span class="nt">a</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="cp">{{</span><span class="w"> </span><span class="k">end</span><span class="w"> </span><span class="cp">}}</span>
</span></span><span class="line"><span class="cl"><span class="cp">{{</span><span class="w"> </span><span class="k">end</span><span class="w"> </span><span class="cp">}}</span></span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<p>После 0.156 ту же логику можно записать прямее:</p>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go-html-template" data-lang="go-html-template"><span class="line"><span class="cl"><span class="cp">{{</span><span class="w"> </span><span class="k">range</span><span class="w"> </span><span class="nx">site</span><span class="na">.Home.Translations</span><span class="w"> </span><span class="cp">}}</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">a</span> <span class="na">href</span><span class="o">=</span><span class="s">&#34;</span><span class="cp">{{</span><span class="w"> </span><span class="na">.Permalink</span><span class="w"> </span><span class="cp">}}</span><span class="s">&#34;</span><span class="p">&gt;</span><span class="cp">{{</span><span class="w"> </span><span class="na">.Language.LanguageName</span><span class="w"> </span><span class="cp">}}</span><span class="p">&lt;/</span><span class="nt">a</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="cp">{{</span><span class="w"> </span><span class="k">end</span><span class="w"> </span><span class="cp">}}</span></span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<p>Меньше кода, понятнее намерение. Если вы вели мультиязычный сайт с языковым переключателем — самое время заменить.</p>
<h2 class="heading" id="опция-disablesetlocale-">
  Опция disableSetLocale ⚙️
  <a class="anchor" href="#%d0%be%d0%bf%d1%86%d0%b8%d1%8f-disablesetlocale-">#</a>
</h2>
<p>В конфиге появилась новая опция:</p>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-toml" data-lang="toml"><span class="line"><span class="cl"><span class="nx">disableSetLocale</span> <span class="p">=</span> <span class="kc">true</span></span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<p>По умолчанию Hugo пытается установить системную локаль операционной системы согласно языку текущего сайта. Это влияет на форматирование дат, чисел, сортировку строк (<code>strings.Sort</code>).</p>
<p>Иногда это поведение нежелательно. Например, в CI-контейнере может не быть нужной локали, и Hugo молча падает на дефолт. Или вы хотите, чтобы поведение было одинаковым на всех машинах сборки независимо от языка контента.</p>
<p><code>disableSetLocale = true</code> отключает эту попытку. Hugo использует значения из конфига и встроенные форматтеры без обращения к OS-уровню <code>setlocale()</code>.</p>
<p>Когда нужно: CI-сборки на минимальных образах (alpine, debian-slim), где локали могут отсутствовать; репозитории с воспроизводимой сборкой; ситуации, когда вы заметили различия в форматах между локальной сборкой и CI.</p>
<h2 class="heading" id="депрекейт-пути-_vendorgithubcomgohugoiolocales">
  Депрекейт пути _vendor/github.com/gohugoio/locales
  <a class="anchor" href="#%d0%b4%d0%b5%d0%bf%d1%80%d0%b5%d0%ba%d0%b5%d0%b9%d1%82-%d0%bf%d1%83%d1%82%d0%b8-_vendorgithubcomgohugoiolocales">#</a>
</h2>
<p>Путь <code>_vendor/github.com/gohugoio/locales</code> помечен как устаревший. Если вы его явно использовали (например, импортировали как submodule в проект), стоит начать миграцию на встроенные локали Hugo — релиз поддерживает их через стандартный механизм.</p>
<p>Большинство пользователей этот путь не трогали, поэтому пункт скорее для разработчиков тем, чем для авторов сайтов.</p>
<h2 class="heading" id="чек-лист-обновления-за-30-минут-">
  Чек-лист обновления за 30 минут ✅
  <a class="anchor" href="#%d1%87%d0%b5%d0%ba-%d0%bb%d0%b8%d1%81%d1%82-%d0%be%d0%b1%d0%bd%d0%be%d0%b2%d0%bb%d0%b5%d0%bd%d0%b8%d1%8f-%d0%b7%d0%b0-30-%d0%bc%d0%b8%d0%bd%d1%83%d1%82-">#</a>
</h2>
<p>Чтобы пройти миграцию без сюрпризов:</p>
<ol>
<li>
<p><strong>Поднять версию Hugo</strong> до 0.161.0 (если ещё на старой) или 0.156.0 как промежуточный шаг. Если работаете в Docker, обновить <code>ARG HUGO_VERSION</code> и пересобрать образ.</p>
</li>
<li>
<p><strong>Поиск устаревших API в шаблонах:</strong></p>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">grep -rn <span class="s1">&#39;site\.Data\|site\.Sites\|AllTranslations&#39;</span> layouts/ themes/*/layouts/</span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<p>Если хиты есть — заменить на <code>hugo.Data</code>, <code>hugo.Sites</code>, <code>Translations</code>.</p>
</li>
<li>
<p><strong>Проверить кастомные render hooks</strong>, если они есть. Можно ли получить пользу от новых <code>IsBlock</code> и <code>Ordinal</code>?</p>
</li>
<li>
<p><strong>Решить про <code>disableSetLocale</code>.</strong> Если CI-сборки иногда дают разные форматы дат в зависимости от хоста, добавить опцию в конфиг.</p>
</li>
<li>
<p><strong>Прогнать сборку:</strong></p>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">hugo --minify --gc</span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<p>Не должно быть warning&rsquo;ов. Если появились — каждый из них чем-то да полезен, не игнорировать.</p>
</li>
<li>
<p><strong>Открыть несколько критичных страниц локально</strong>, проверить, что меню, переводы, render hooks работают.</p>
</li>
<li>
<p><strong>Закоммитить и задеплоить.</strong> На статичном Hugo-сайте откат — это <code>git revert</code> плюс пересборка, минут 5.</p>
</li>
</ol>
<h2 class="heading" id="итог-">
  Итог 🧠
  <a class="anchor" href="#%d0%b8%d1%82%d0%be%d0%b3-">#</a>
</h2>
<p>Hugo 0.156.0 — не «громкий релиз ради хайпа». Это пакет аккуратных архитектурных изменений: переезд на новые API, расширение возможностей для тех, кто пишет render hooks, чистка мультиязычной части.</p>
<p>Главная польза от такого релиза — возможность снять немного технического долга прямо сейчас, пока депрекейты ещё работают. Пропустишь — через год будешь разбираться, почему что-то перестало рендериться.</p>
<p>Если у вас минимальный шаблонный код (стандартная тема без кастомных hook&rsquo;ов и без мультиязычности), переход почти прозрачен. Если у вас активные render hooks или мультиязык — стоит выделить полчаса на ревизию.</p>
<p>И да: каждый минор-релиз стоит читать. Не как обязательное домашнее задание, но как короткую инвестицию в собственный код.</p>
<h2 class="heading" id="источники">
  Источники
  <a class="anchor" href="#%d0%b8%d1%81%d1%82%d0%be%d1%87%d0%bd%d0%b8%d0%ba%d0%b8">#</a>
</h2>
<ul>
<li>Официальный релиз: <a href="https://github.com/gohugoio/hugo/releases/tag/v0.156.0">gohugoio/hugo v0.156.0</a></li>
<li>Документация по новым API: <a href="https://gohugo.io/methods/hugo/data/">hugo.Data</a>, <a href="https://gohugo.io/methods/hugo/sites/">hugo.Sites</a></li>
<li>Документация по переводам: <a href="https://gohugo.io/methods/page/translations/">site.Home.Translations</a></li>
<li>Документация link render hooks: <a href="https://gohugo.io/render-hooks/links/">Render hooks: links</a></li>
</ul>
]]></content:encoded><category>hugo</category><category>релизы</category></item><item><title>Домашняя колбаса: базовый рецепт на 1 кг 🥓</title><link>https://kushnaren.co/posts/domashnyaya-kolbasa-bazovyj-recept-na-1-kg/</link><pubDate>Wed, 11 Feb 2026 12:00:00 +0300</pubDate><guid isPermaLink="true">https://kushnaren.co/posts/domashnyaya-kolbasa-bazovyj-recept-na-1-kg/</guid><description>Рабочая памятка по домашней колбасе на 1 кг: соль, нитрит, специи, ледяная вода, а также технология фарш-набивка-термообработка и типичные ошибки начинающих.</description><content:encoded><![CDATA[<h2 class="heading" id="зачем-вообще-делать-колбасу-дома">
  Зачем вообще делать колбасу дома
  <a class="anchor" href="#%d0%b7%d0%b0%d1%87%d0%b5%d0%bc-%d0%b2%d0%be%d0%be%d0%b1%d1%89%d0%b5-%d0%b4%d0%b5%d0%bb%d0%b0%d1%82%d1%8c-%d0%ba%d0%be%d0%bb%d0%b1%d0%b0%d1%81%d1%83-%d0%b4%d0%be%d0%bc%d0%b0">#</a>
</h2>
<p>Магазинная колбаса — продукт, который терпит много претензий: непрозрачный состав, переизбыток фосфатов, переменное качество от партии к партии, дискомфорт от того, что «там вообще мясо или нет». Домашняя — наоборот: ты сам решаешь, какое мясо, сколько соли, какие специи, как готовить, что положить в оболочку.</p>
<p>Это не «дешевле магазинной» (по факту — нет, особенно с учётом времени). Это «честнее и вкуснее, если потратить время на освоение базовых пропорций». А пропорции — самое важное в колбасе. Если соль/специи/влага в норме, даже простой кусок мяса превращается в нормальный продукт.</p>
<p>Этот пост — рабочая памятка с пропорциями, которые я использую как отправную точку, плюс короткое объяснение, зачем там каждый ингредиент. Без претензий на «единственно верный рецепт».</p>
<h2 class="heading" id="соль-и-добавки-на-1-кг-">
  Соль и добавки на 1 кг 🧂
  <a class="anchor" href="#%d1%81%d0%be%d0%bb%d1%8c-%d0%b8-%d0%b4%d0%be%d0%b1%d0%b0%d0%b2%d0%ba%d0%b8-%d0%bd%d0%b0-1-%d0%ba%d0%b3-">#</a>
</h2>
<p>Базовый набор:</p>
<ul>
<li><strong>Соль:</strong> 18-20 г.</li>
<li><strong>Оптимальный вариант:</strong> 16 г обычной соли + 2-3 г нитритной соли.</li>
<li><strong>Сахар:</strong> 5 г (примерно 1 ч. л.).</li>
<li><strong>Чёрный перец:</strong> 1 ч. л.</li>
<li><strong>Чеснок:</strong> 2 зубчика (около 8-10 г).</li>
<li><strong>Мускатный орех:</strong> щепотка.</li>
<li><strong>Лёд или ледяная вода:</strong> 80-100 мл.</li>
</ul>
<p>Этот набор использую как отправную точку. Дальше корректирую специи под конкретное мясо и личный вкус.</p>
<h2 class="heading" id="зачем-каждое-из-этого">
  Зачем каждое из этого
  <a class="anchor" href="#%d0%b7%d0%b0%d1%87%d0%b5%d0%bc-%d0%ba%d0%b0%d0%b6%d0%b4%d0%be%d0%b5-%d0%b8%d0%b7-%d1%8d%d1%82%d0%be%d0%b3%d0%be">#</a>
</h2>
<p>Чтобы рецепт не казался магической формулой, коротко по каждому пункту:</p>
<p><strong>Соль — 18-20 г на 1 кг.</strong> Это не «по вкусу». Это пороговая концентрация: меньше — фарш плохо «связывается» (соль вытягивает миофибриллярные белки, которые удерживают воду), больше — переедено и опасно. Норма для большинства колбас 1.8-2%.</p>
<p><strong>Нитритная соль — 2-3 г.</strong> Главный вопрос. Нитрит даёт характерный розовый цвет, узнаваемый «колбасный» вкус и — главное — подавляет рост ботулинических бактерий. Без него любая колбаса с длительной выдержкой или копчением рискует превратиться в источник опасных токсинов. Не «химия, которую нужно избегать», а функциональный консервант, который существует не зря. Концентрация 2-3 г нитритной соли (а не чистого нитрита) — безопасный диапазон, давно стандартизированный.</p>
<p><strong>Сахар — 5 г.</strong> Не для сладости. Для микробиоты — она «съедает» сахар и даёт лёгкое подкисление, плюс смягчает солёность.</p>
<p><strong>Чёрный перец, чеснок, мускат.</strong> Базовая «колбасная» ароматическая основа. Каждый компонент можно менять под вкус (паприка, горчица в зёрнах, кориандр, тмин), но эта тройка — спокойная отправная точка.</p>
<p><strong>Ледяная вода — 80-100 мл.</strong> Самое неочевидное для новичков. Вода не «разбавляет», а наоборот — вместе с белками образует эмульсию, которая держит структуру колбасы при нагреве. Если воду не добавить, колбаса получится сухой и зернистой. Если добавить тёплую — белки свернутся раньше времени, эмульсия не сложится. Лёд гарантирует, что фарш во время вымешивания остаётся холодным.</p>
<h2 class="heading" id="технология-процесса">
  Технология процесса
  <a class="anchor" href="#%d1%82%d0%b5%d1%85%d0%bd%d0%be%d0%bb%d0%be%d0%b3%d0%b8%d1%8f-%d0%bf%d1%80%d0%be%d1%86%d0%b5%d1%81%d1%81%d0%b0">#</a>
</h2>
<p>Кратко, без излишних деталей, чтобы держать целое в голове:</p>
<ol>
<li><strong>Подготовка мяса.</strong> Охладить до 1-3°C (не замораживать). Срезать жёсткие плёнки и хрящи, нарезать кусками удобного размера.</li>
<li><strong>Помол.</strong> Через мясорубку с решёткой 4-6 мм. Чем мельче, тем «нежнее» структура; чем крупнее — тем «деревенская» подача.</li>
<li><strong>Внесение соли и нитрита.</strong> На холодный фарш, тщательно перемешать.</li>
<li><strong>Специи и сахар.</strong> Добавить, перемешать снова.</li>
<li><strong>Лёд/ледяная вода.</strong> Добавлять постепенно, продолжая вымешивать. Цель — получить однородную массу, в которой видна вязкость («тянется» при отрыве).</li>
<li><strong>Холодная пауза.</strong> 1-3 часа в холодильнике, чтобы соль распределилась и фарш «созрел».</li>
<li><strong>Набивка.</strong> В оболочку (натуральную или коллагеновую), без воздушных пузырей.</li>
<li><strong>Термообработка.</strong> Зависит от типа: варка при 75-80°C до внутренней температуры 70-72°C, копчение, запекание.</li>
</ol>
<p>Эта последовательность — каркас. Каждый шаг можно тонко донастраивать, но если убрать любой из них, результат заметно проседает.</p>
<h2 class="heading" id="типичные-ошибки-начинающих-">
  Типичные ошибки начинающих 🪤
  <a class="anchor" href="#%d1%82%d0%b8%d0%bf%d0%b8%d1%87%d0%bd%d1%8b%d0%b5-%d0%be%d1%88%d0%b8%d0%b1%d0%ba%d0%b8-%d0%bd%d0%b0%d1%87%d0%b8%d0%bd%d0%b0%d1%8e%d1%89%d0%b8%d1%85-">#</a>
</h2>
<p>Самые частые сбои, которые легко избежать, если знать заранее:</p>
<p><strong>Слишком тёплый фарш.</strong> Если на любом этапе фарш нагрелся выше 12-15°C, эмульсия не сложится. Жир «вытопится» при варке, в продукте появятся жирные карманы. Лёд обязателен.</p>
<p><strong>Переизбыток соли.</strong> «Я люблю солёное» не работает. Превысил 25 г на кг — продукт не съесть, а ребалансировать сложно: соль из готовой колбасы не уберёшь.</p>
<p><strong>Недомес.</strong> Если фарш не дошёл до состояния «вязкий, тянется» — структура развалится. Вымешивание — главное, что делает колбасу колбасой, а не «фарш в кишке».</p>
<p><strong>Воздух в оболочке.</strong> Пузыри = места, где может развиваться нежелательная микрофлора. Прокалывать иголкой при набивке — нормальная практика.</p>
<p><strong>Резкий перегрев при варке.</strong> Внутри колбасы должно быть 70-72°C, не больше. Перегрев = выплавление жира + сухость. Для контроля — кулинарный термометр; «на глаз» в этом деле подводит.</p>
<p><strong>Спешка с дегустацией.</strong> Колбасе нужно «созреть» в холодильнике хотя бы 12-24 часа после варки. Свежевыкипяченная — это не финальный вкус.</p>
<h2 class="heading" id="варианты-по-виду-мяса">
  Варианты по виду мяса
  <a class="anchor" href="#%d0%b2%d0%b0%d1%80%d0%b8%d0%b0%d0%bd%d1%82%d1%8b-%d0%bf%d0%be-%d0%b2%d0%b8%d0%b4%d1%83-%d0%bc%d1%8f%d1%81%d0%b0">#</a>
</h2>
<p>Базовый рецепт работает для свинины и для смесей. Несколько типичных вариаций:</p>
<ul>
<li><strong>Свинина (60% мякоти + 40% жирной части).</strong> Классика, сбалансированный вкус, хороший для новичков.</li>
<li><strong>Свинина + говядина (70/30).</strong> Более «мясной» характер, плотнее структура, чуть жёстче.</li>
<li><strong>Только говядина.</strong> Суше, требует больше воды и аккуратности с эмульсией; вкус интенсивнее.</li>
<li><strong>Птица (грудка + бедро).</strong> Нежнее, ниже жирность; нужно поднять долю воды и тщательнее вымешивать.</li>
</ul>
<p>Соль и нитрит — те же. Воды иногда нужно немного больше для постного мяса.</p>
<h2 class="heading" id="безопасность-">
  Безопасность ⚠️
  <a class="anchor" href="#%d0%b1%d0%b5%d0%b7%d0%be%d0%bf%d0%b0%d1%81%d0%bd%d0%be%d1%81%d1%82%d1%8c-">#</a>
</h2>
<p>Несколько моментов, о которых стоит знать обязательно:</p>
<ul>
<li><strong>Нитритная соль ≠ чистый нитрит.</strong> Это уже разбавленная смесь (обычно 0.5-0.6% NaNO₂ в обычной соли). Использовать строго по дозировке для нитритной соли, не для чистого вещества.</li>
<li><strong>Ботулизм.</strong> Главная причина существования нитрита в колбасном деле. При длительной выдержке без нитрита риск реален; не «древняя страшилка».</li>
<li><strong>Контроль температуры.</strong> Внутренняя температура готового продукта 70-72°C — это не «совет», это безопасность.</li>
<li><strong>Сроки хранения.</strong> Домашняя колбаса без консервантов хранится в холодильнике значительно меньше магазинной. Замораживание — ок, но текстура немного меняется.</li>
</ul>
<p>Если делаете колбасу впервые — стоит прочитать пару проверенных источников по технологии (например, Stanley Marianski «Home Production of Quality Meats and Sausages» или книги по колбасному делу на русском). Это не та область, где «методом тыка» — оптимальный путь обучения.</p>
<h2 class="heading" id="куда-дальше-если-втянулся">
  Куда дальше, если втянулся
  <a class="anchor" href="#%d0%ba%d1%83%d0%b4%d0%b0-%d0%b4%d0%b0%d0%bb%d1%8c%d1%88%d0%b5-%d0%b5%d1%81%d0%bb%d0%b8-%d0%b2%d1%82%d1%8f%d0%bd%d1%83%d0%bb%d1%81%d1%8f">#</a>
</h2>
<p>Если базовый цикл стал привычным, есть много направлений для развития:</p>
<ul>
<li><strong>Сухое созревание</strong> (колбаса как salami). Долгий процесс, требует контроля температуры и влажности.</li>
<li><strong>Копчение</strong> (горячее или холодное). Меняет вкус и продлевает хранение.</li>
<li><strong>Свои смеси специй.</strong> Эксперименты с паприкой, фенхелем, кориандром, перцем чили — ровно по чайной ложке, чтобы не «перегрузить».</li>
<li><strong>Натуральные оболочки.</strong> Свиная черева, говяжьи синюги, бараньи кишки — каждая дает свою текстуру.</li>
</ul>
<p>Но это уже отдельная история. Базовый рецепт хорошо работает сам по себе и закрывает большую часть домашних запросов.</p>
<h2 class="heading" id="итоги">
  Итоги
  <a class="anchor" href="#%d0%b8%d1%82%d0%be%d0%b3%d0%b8">#</a>
</h2>
<p>Колбаса — простой по сути продукт, который очень чувствителен к деталям. Соль и нитрит обеспечивают безопасность и связку, лёд держит эмульсию, специи дают характер. Если эти три блока в порядке, всё остальное — настройка под вкус.</p>
<p>Этот рецепт — мой рабочий минимум. Точные пропорции вы со временем подгоните под себя, но 18-20 г соли, 80-100 мл ледяной воды, обязательная нитритная составляющая и аккуратное вымешивание — фундамент, на котором всё остальное держится. 🍴</p>
]]></content:encoded><category>кухня</category></item><item><title>Самогоноварение как эксперимент: наш опыт с абсентом 🍸</title><link>https://kushnaren.co/posts/samogonovarenie-absent-opyt-i-vyvody/</link><pubDate>Wed, 04 Feb 2026 12:00:00 +0300</pubDate><guid isPermaLink="true">https://kushnaren.co/posts/samogonovarenie-absent-opyt-i-vyvody/</guid><description>Размышления после первого опыта с домашней ректификацией: почему вообще ввязались, что узнали про процесс, чем абсент сложнее обычного дистиллята, и какие выводы из этого сделали. Без рецептов и инструкций.</description><content:encoded><![CDATA[<h2 class="heading" id="почему-вообще-в-это-ввязались">
  Почему вообще в это ввязались
  <a class="anchor" href="#%d0%bf%d0%be%d1%87%d0%b5%d0%bc%d1%83-%d0%b2%d0%be%d0%be%d0%b1%d1%89%d0%b5-%d0%b2-%d1%8d%d1%82%d0%be-%d0%b2%d0%b2%d1%8f%d0%b7%d0%b0%d0%bb%d0%b8%d1%81%d1%8c">#</a>
</h2>
<p>Мы с моим другом Андреем давно обсуждали идею «разобраться, как это работает на самом деле». Самогоноварение показалось подходящим испытанием: техническая часть, химия, дисциплина, плюс шанс сделать что-то необычное своими руками. Не для того, чтобы «гнать в промышленных масштабах», а чтобы пройти процесс целиком и понять, где спрятаны нюансы, о которых снаружи не догадаешься.</p>
<p>Так в нашей жизни появилась ректификационная колонна «Дом Спирт 2» и дерзкая цель — попробовать сделать абсент. Через несколько подходов мы получили результат, который можно назвать «похожим на абсент», и значительно больше — наблюдений о самом процессе.</p>
<h2 class="heading" id="что-такое-ректификационная-колонна-упрощённо">
  Что такое ректификационная колонна (упрощённо)
  <a class="anchor" href="#%d1%87%d1%82%d0%be-%d1%82%d0%b0%d0%ba%d0%be%d0%b5-%d1%80%d0%b5%d0%ba%d1%82%d0%b8%d1%84%d0%b8%d0%ba%d0%b0%d1%86%d0%b8%d0%be%d0%bd%d0%bd%d0%b0%d1%8f-%d0%ba%d0%be%d0%bb%d0%be%d0%bd%d0%bd%d0%b0-%d1%83%d0%bf%d1%80%d0%be%d1%89%d1%91%d0%bd%d0%bd%d0%be">#</a>
</h2>
<p>Колонна — это вертикальная труба, в которой пары спиртосодержащей жидкости поднимаются вверх, проходят через насадку (мелкие металлические или керамические элементы), частично конденсируются и стекают обратно. Это «ректификация» — многоступенчатая дистилляция в одном устройстве.</p>
<p>Эффект: получается высокая степень очистки, спирт-ректификат может быть крепче 90%, без значительной части примесей, которые делают «обычный самогон» неприятным.</p>
<p>«Дом Спирт 2» — российская модель домашней ректификационной колонны. Она не самая мощная и не самая компактная, но достаточно «честная»: достать, освоить базовый цикл, понять, как ведёт себя пар, давление, температура — реально для технически грамотного человека за несколько вечеров.</p>
<h2 class="heading" id="первые-впечатления-техника--это-не-половина-дела-а-почти-всё">
  Первые впечатления: техника — это не половина дела, а почти всё
  <a class="anchor" href="#%d0%bf%d0%b5%d1%80%d0%b2%d1%8b%d0%b5-%d0%b2%d0%bf%d0%b5%d1%87%d0%b0%d1%82%d0%bb%d0%b5%d0%bd%d0%b8%d1%8f-%d1%82%d0%b5%d1%85%d0%bd%d0%b8%d0%ba%d0%b0--%d1%8d%d1%82%d0%be-%d0%bd%d0%b5-%d0%bf%d0%be%d0%bb%d0%be%d0%b2%d0%b8%d0%bd%d0%b0-%d0%b4%d0%b5%d0%bb%d0%b0-%d0%b0-%d0%bf%d0%be%d1%87%d1%82%d0%b8-%d0%b2%d1%81%d1%91">#</a>
</h2>
<p>Оказалось, что в этом хобби важна не только «железка», но и терпение. Ожидания были простыми: собрал, запустил, получил результат. Реальность — другая: время, аккуратность, много мелких нюансов и постоянное чувство, что упускаешь какую-то деталь.</p>
<p>Несколько вещей, которых мы не ожидали:</p>
<ul>
<li><strong>Длительность процесса.</strong> Полный цикл от загрузки до получения готового продукта — это много часов, иногда вся суббота.</li>
<li><strong>Чувствительность к деталям.</strong> Изменение скорости отбора, температуры, охлаждения дефлегматора — каждое влияет на результат сильнее, чем казалось из видеообзоров.</li>
<li><strong>Гигиена.</strong> «Чисто» в обычном смысле и «чисто» для процесса — разные понятия.</li>
<li><strong>Дисциплина протокола.</strong> Если делать «на глаз» — результаты непредсказуемы. Если фиксировать каждый шаг — повторяемость растёт.</li>
</ul>
<h2 class="heading" id="чем-абсент-сложнее-обычного-дистиллята">
  Чем абсент сложнее «обычного дистиллята»
  <a class="anchor" href="#%d1%87%d0%b5%d0%bc-%d0%b0%d0%b1%d1%81%d0%b5%d0%bd%d1%82-%d1%81%d0%bb%d0%be%d0%b6%d0%bd%d0%b5%d0%b5-%d0%be%d0%b1%d1%8b%d1%87%d0%bd%d0%be%d0%b3%d0%be-%d0%b4%d0%b8%d1%81%d1%82%d0%b8%d0%bb%d0%bb%d1%8f%d1%82%d0%b0">#</a>
</h2>
<p>Классический спирт-ректификат — это, грубо, очищенный этанол с водой. Абсент сложнее устроен:</p>
<ol>
<li><strong>Мацерация.</strong> Травы (полынь, анис, фенхель и менее афишированные растения) настаиваются на готовом спирте.</li>
<li><strong>Перегонка с травами.</strong> Полученный настой перегоняется заново — часть ароматических компонентов переходит в дистиллят, часть остаётся в кубе.</li>
<li><strong>Финальное окрашивание.</strong> Дополнительная мацерация на свежих травах даёт характерный зелёный или жёлтый оттенок.</li>
</ol>
<p>Каждый из этих шагов имеет свои переменные: какие травы, в какой пропорции, при какой температуре, как долго. Мелкая ошибка на любом шаге даёт ощутимое отклонение в финальном вкусе. И если «обычный самогон» прощает многое, абсент прощает мало.</p>
<p>Дополнительно — травы дают так называемые «термолабильные» компоненты, которые легко разрушаются при перегреве. Это даёт парадоксальную ситуацию: вы технически умеете гнать спирт, но при попытке сделать абсент получаете либо «горький эликсир», либо «спиртовая вода с лёгким намёком на полынь» — без середины.</p>
<h2 class="heading" id="что-получилось">
  Что получилось
  <a class="anchor" href="#%d1%87%d1%82%d0%be-%d0%bf%d0%be%d0%bb%d1%83%d1%87%d0%b8%d0%bb%d0%be%d1%81%d1%8c">#</a>
</h2>
<ul>
<li>Мы разобрались с базовой логикой процесса и перестали «бояться» оборудования.</li>
<li>Получили результат, который можно оценивать — не идеально, но уже похоже на задуманное.</li>
<li>Поняли, какие этапы требуют больше контроля, чем казалось на старте.</li>
<li>Научились читать поведение колонны: давление, температура, скорость капельного отбора.</li>
<li>Сформировали собственный «лог сессии», который помогает повторять удачные попытки.</li>
</ul>
<h2 class="heading" id="что-не-получилось">
  Что не получилось
  <a class="anchor" href="#%d1%87%d1%82%d0%be-%d0%bd%d0%b5-%d0%bf%d0%be%d0%bb%d1%83%d1%87%d0%b8%d0%bb%d0%be%d1%81%d1%8c">#</a>
</h2>
<ul>
<li><strong>Стабильность.</strong> Один и тот же подход давал разный результат от подхода к подходу.</li>
<li><strong>Предсказуемость вкуса и аромата.</strong> Это тонкая, почти ювелирная работа.</li>
<li><strong>Терпение.</strong> Иногда проще поставить эксперимент на паузу, чем пытаться «додавить» его усталостью.</li>
<li><strong>Точная имитация классического абсента.</strong> До «как в Швейцарии» далеко; пока ближе к «дегустационному образцу собственного производства».</li>
</ul>
<h2 class="heading" id="главный-вывод">
  Главный вывод
  <a class="anchor" href="#%d0%b3%d0%bb%d0%b0%d0%b2%d0%bd%d1%8b%d0%b9-%d0%b2%d1%8b%d0%b2%d0%be%d0%b4">#</a>
</h2>
<p>Самогоноварение — это не «про напиток», а про процесс и дисциплину. Это про внимание к деталям и честность с самим собой: если хочешь качественный результат, придётся уважать все этапы, а не только финал.</p>
<p>Любая часть, которую попытаешься «срезать», даст видимый результат: либо во вкусе, либо в стабильности, либо в безопасности. Это, наверное, и есть главная ценность таких хобби: они напоминают, что качественный результат складывается из мелочей, которые поодиночке кажутся незначительными.</p>
<h2 class="heading" id="безопасность-важное">
  Безопасность (важное)
  <a class="anchor" href="#%d0%b1%d0%b5%d0%b7%d0%be%d0%bf%d0%b0%d1%81%d0%bd%d0%be%d1%81%d1%82%d1%8c-%d0%b2%d0%b0%d0%b6%d0%bd%d0%be%d0%b5">#</a>
</h2>
<p>Несколько вещей, которые нужно проговорить отдельно:</p>
<ul>
<li><strong>Голов и хвостов нельзя пить.</strong> Первые и последние фракции содержат метанол, сивушные масла и другие соединения, потенциально опасные. Их отделяют по проверенной методике.</li>
<li><strong>Высокая концентрация спирта = высокая огнеопасность.</strong> Колонна греется, пары горючи, помещение должно быть вентилируемым.</li>
<li><strong>Лицензирование и закон.</strong> В разных странах правила производства алкоголя для личного потребления отличаются. Ответственность всегда на изготовителе.</li>
<li><strong>Дегустация.</strong> Не «глотнуть и надеяться». Малая проба, оценка по органолептике, никаких больших порций неотлежавшегося продукта.</li>
</ul>
<p>Я не даю инструкций и рецептов в этом посте сознательно. Это пост про опыт и наблюдения, а не учебник.</p>
<h2 class="heading" id="зачем-писать-об-этом">
  Зачем писать об этом
  <a class="anchor" href="#%d0%b7%d0%b0%d1%87%d0%b5%d0%bc-%d0%bf%d0%b8%d1%81%d0%b0%d1%82%d1%8c-%d0%be%d0%b1-%d1%8d%d1%82%d0%be%d0%bc">#</a>
</h2>
<p>Потому что это хороший пример живого эксперимента: мы не профессионалы, а просто люди, которым интересно разобраться. И именно в таких историях — ценность. Не в том, чтобы «повторить», а в том, чтобы увидеть путь, ошибки и выводы.</p>
<p>Любое сложное хобби работает по похожей траектории: первые попытки выглядят неуклюже, потом приходит понимание базовых механик, дальше — наблюдение за деталями, и только потом становится возможным «сознательно делать вкус», а не «случайно получать что-то близкое».</p>
<h2 class="heading" id="что-дальше">
  Что дальше
  <a class="anchor" href="#%d1%87%d1%82%d0%be-%d0%b4%d0%b0%d0%bb%d1%8c%d1%88%d0%b5">#</a>
</h2>
<p>Мы продолжаем экспериментировать. Возможно, через пару месяцев будет вторая часть — с более стабильным результатом и ясными выводами. Пока же — фиксируем этап и идём дальше.</p>
<p>Если резюмировать одной фразой: самое важное, что я понял за эти подходы — терпение в этом хобби стоит больше, чем оборудование. Хорошая колонна не сделает за тебя дисциплину. А плохая дисциплина не оправдается дорогой колонной. 🧪</p>
]]></content:encoded><category>кухня</category></item><item><title>Пишем посты с Codex: от идеи до публикации без лишней рутины ✍️</title><link>https://kushnaren.co/posts/pishem-posty-s-codex-avtomatizaciya-nashe-vse/</link><pubDate>Mon, 02 Feb 2026 12:00:00 +0300</pubDate><guid isPermaLink="true">https://kushnaren.co/posts/pishem-posty-s-codex-avtomatizaciya-nashe-vse/</guid><description>Подробная схема работы с Codex для Hugo-блога: подготовка идеи, сборка черновика, редактура, техническая валидация, публикация и контроль качества.</description><content:encoded><![CDATA[<p>Когда блог ведётся регулярно, главная проблема часто не в том, «о чём писать», а в том, сколько мелкой рутины появляется вокруг каждой публикации: структура, фронтматтер, теги, формат даты, локальная проверка, коммит, пуш.</p>
<p>В какой-то момент я понял простую вещь: если не автоматизировать технические повторяющиеся шаги, то темп публикаций будет определяться не качеством идей, а запасом терпения. Именно здесь Codex даёт максимальную пользу. 🚀</p>
<p>Важно уточнить позицию сразу: Codex не заменяет автора и редактора. Он ускоряет производство черновика, стабилизирует техническую часть и снимает «операционную усталость», чтобы энергия оставалась на смыслы.</p>
<h2 class="heading" id="где-именно-теряется-время-при-выпуске-поста">
  Где именно теряется время при выпуске поста
  <a class="anchor" href="#%d0%b3%d0%b4%d0%b5-%d0%b8%d0%bc%d0%b5%d0%bd%d0%bd%d0%be-%d1%82%d0%b5%d1%80%d1%8f%d0%b5%d1%82%d1%81%d1%8f-%d0%b2%d1%80%d0%b5%d0%bc%d1%8f-%d0%bf%d1%80%d0%b8-%d0%b2%d1%8b%d0%bf%d1%83%d1%81%d0%ba%d0%b5-%d0%bf%d0%be%d1%81%d1%82%d0%b0">#</a>
</h2>
<p>До автоматизации у меня стабильно проседали одни и те же этапы:</p>
<ol>
<li>Переход от идеи к первому цельному черновику.</li>
<li>Ручное оформление фронтматтера без ошибок.</li>
<li>Поддержание одинакового уровня качества для <code>summary</code> и <code>description</code>.</li>
<li>Повторяемые технические действия перед публикацией.</li>
</ol>
<p>Сами шаги простые, но они фрагментируют внимание. После двух-трёх переключений между «текстом» и «технической обвязкой» уже сложнее держать мысль статьи плотной и последовательной.</p>
<h2 class="heading" id="какую-роль-я-отдаю-codex-а-какую-оставляю-себе">
  Какую роль я отдаю Codex, а какую оставляю себе
  <a class="anchor" href="#%d0%ba%d0%b0%d0%ba%d1%83%d1%8e-%d1%80%d0%be%d0%bb%d1%8c-%d1%8f-%d0%be%d1%82%d0%b4%d0%b0%d1%8e-codex-%d0%b0-%d0%ba%d0%b0%d0%ba%d1%83%d1%8e-%d0%be%d1%81%d1%82%d0%b0%d0%b2%d0%bb%d1%8f%d1%8e-%d1%81%d0%b5%d0%b1%d0%b5">#</a>
</h2>
<p>Чтобы автоматизация была полезной, роли должны быть разделены жёстко.</p>
<p><strong>За мной остаётся:</strong></p>
<ul>
<li>тезис и позиция статьи;</li>
<li>финальная логика аргументации;</li>
<li>личный опыт, выводы и тональность.</li>
</ul>
<p><strong>Codex получает:</strong></p>
<ul>
<li>сборку структурированного черновика из тезисов;</li>
<li>технически корректный фронтматтер;</li>
<li>контроль повторяющихся формальностей;</li>
<li>подготовку git-части к публикации.</li>
</ul>
<p>Такая схема позволяет не спорить с инструментом о «вкусе текста», а использовать его там, где важнее точность и скорость.</p>
<h2 class="heading" id="рабочий-конвейер-от-идеи-до-публикации">
  Рабочий конвейер: от идеи до публикации
  <a class="anchor" href="#%d1%80%d0%b0%d0%b1%d0%be%d1%87%d0%b8%d0%b9-%d0%ba%d0%be%d0%bd%d0%b2%d0%b5%d0%b9%d0%b5%d1%80-%d0%be%d1%82-%d0%b8%d0%b4%d0%b5%d0%b8-%d0%b4%d0%be-%d0%bf%d1%83%d0%b1%d0%bb%d0%b8%d0%ba%d0%b0%d1%86%d0%b8%d0%b8">#</a>
</h2>
<p>Ниже процесс, который у меня реально работает в блоге на Hugo.</p>
<h3 class="heading" id="1-формулирую-цель-поста-в-двух-фразах">
  1. Формулирую цель поста в двух фразах
  <a class="anchor" href="#1-%d1%84%d0%be%d1%80%d0%bc%d1%83%d0%bb%d0%b8%d1%80%d1%83%d1%8e-%d1%86%d0%b5%d0%bb%d1%8c-%d0%bf%d0%be%d1%81%d1%82%d0%b0-%d0%b2-%d0%b4%d0%b2%d1%83%d1%85-%d1%84%d1%80%d0%b0%d0%b7%d0%b0%d1%85">#</a>
</h3>
<p>Перед стартом фиксирую:</p>
<ul>
<li>для кого материал;</li>
<li>какое практическое действие читатель сможет сделать после прочтения.</li>
</ul>
<p>Если это не ясно на старте, статья почти всегда расползается.</p>
<h3 class="heading" id="2-даю-codex-каркас-будущего-текста">
  2. Даю Codex каркас будущего текста
  <a class="anchor" href="#2-%d0%b4%d0%b0%d1%8e-codex-%d0%ba%d0%b0%d1%80%d0%ba%d0%b0%d1%81-%d0%b1%d1%83%d0%b4%d1%83%d1%89%d0%b5%d0%b3%d0%be-%d1%82%d0%b5%d0%ba%d1%81%d1%82%d0%b0">#</a>
</h3>
<p>Минимальный вход:</p>
<ul>
<li>рабочий заголовок;</li>
<li>5-8 смысловых пунктов;</li>
<li>2-3 конкретных примера;</li>
<li>желаемая глубина (коротко / подробно / разбор).</li>
</ul>
<p>На этом этапе я не прошу «красивый текст», я прошу структуру, которую удобно усиливать.</p>
<h3 class="heading" id="3-собираю-длинный-черновик-и-сразу-проверяю-логические-провалы">
  3. Собираю длинный черновик и сразу проверяю логические провалы
  <a class="anchor" href="#3-%d1%81%d0%be%d0%b1%d0%b8%d1%80%d0%b0%d1%8e-%d0%b4%d0%bb%d0%b8%d0%bd%d0%bd%d1%8b%d0%b9-%d1%87%d0%b5%d1%80%d0%bd%d0%be%d0%b2%d0%b8%d0%ba-%d0%b8-%d1%81%d1%80%d0%b0%d0%b7%d1%83-%d0%bf%d1%80%d0%be%d0%b2%d0%b5%d1%80%d1%8f%d1%8e-%d0%bb%d0%be%d0%b3%d0%b8%d1%87%d0%b5%d1%81%d0%ba%d0%b8%d0%b5-%d0%bf%d1%80%d0%be%d0%b2%d0%b0%d0%bb%d1%8b">#</a>
</h3>
<p>Обычно я смотрю:</p>
<ul>
<li>нет ли повторов между разделами;</li>
<li>есть ли причинно-следственная связка между блоками;</li>
<li>не превращаются ли выводы в общие фразы.</li>
</ul>
<p>Если провалы есть, лучше исправить их до стилистической шлифовки.</p>
<h3 class="heading" id="4-редактирую-смысл-вручную">
  4. Редактирую смысл вручную
  <a class="anchor" href="#4-%d1%80%d0%b5%d0%b4%d0%b0%d0%ba%d1%82%d0%b8%d1%80%d1%83%d1%8e-%d1%81%d0%bc%d1%8b%d1%81%d0%bb-%d0%b2%d1%80%d1%83%d1%87%d0%bd%d1%83%d1%8e">#</a>
</h3>
<p>Это самый важный шаг. Здесь я:</p>
<ul>
<li>вырезаю «воду»;</li>
<li>добавляю реальные наблюдения;</li>
<li>уточняю формулировки, где можно понять двояко;</li>
<li>усиливаю практическую часть (чек-листы, сценарии, ограничения).</li>
</ul>
<p>Именно здесь текст перестаёт быть «генерированным» и становится авторским.</p>
<h3 class="heading" id="5-передаю-codex-техническое-оформление">
  5. Передаю Codex техническое оформление
  <a class="anchor" href="#5-%d0%bf%d0%b5%d1%80%d0%b5%d0%b4%d0%b0%d1%8e-codex-%d1%82%d0%b5%d1%85%d0%bd%d0%b8%d1%87%d0%b5%d1%81%d0%ba%d0%be%d0%b5-%d0%be%d1%84%d0%be%d1%80%d0%bc%d0%bb%d0%b5%d0%bd%d0%b8%d0%b5">#</a>
</h3>
<p>После смысловой правки Codex приводит материал к правилам блога:</p>
<ul>
<li>корректный фронтматтер;</li>
<li>осмысленные <code>summary</code> и <code>description</code> без дублирования;</li>
<li>релевантные теги;</li>
<li>структура с оглавлением и читабельными секциями;</li>
<li>уместные эмодзи для акцентов.</li>
</ul>
<h3 class="heading" id="6-финальная-техническая-валидация">
  6. Финальная техническая валидация
  <a class="anchor" href="#6-%d1%84%d0%b8%d0%bd%d0%b0%d0%bb%d1%8c%d0%bd%d0%b0%d1%8f-%d1%82%d0%b5%d1%85%d0%bd%d0%b8%d1%87%d0%b5%d1%81%d0%ba%d0%b0%d1%8f-%d0%b2%d0%b0%d0%bb%d0%b8%d0%b4%d0%b0%d1%86%d0%b8%d1%8f">#</a>
</h3>
<p>Перед публикацией использую обязательный минимум:</p>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">hugo list future
</span></span><span class="line"><span class="cl">hugo --minify</span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<p>Если пост попал в <code>future</code>, дата сдвигается назад (МСК, <code>+03:00</code>), затем повторная проверка.</p>
<h3 class="heading" id="7-публикация">
  7. Публикация
  <a class="anchor" href="#7-%d0%bf%d1%83%d0%b1%d0%bb%d0%b8%d0%ba%d0%b0%d1%86%d0%b8%d1%8f">#</a>
</h3>
<p>После проверки Codex помогает зафиксировать изменения:</p>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">git add .
</span></span><span class="line"><span class="cl">git commit -m <span class="s2">&#34;Осмысленный коммит на русском по теме поста&#34;</span>
</span></span><span class="line"><span class="cl">git push</span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<p>На этом этапе уже не нужно держать в голове «не забыть бы пуш» или «как назвать коммит».</p>
<h2 class="heading" id="что-реально-улучшилось-после-внедрения">
  Что реально улучшилось после внедрения
  <a class="anchor" href="#%d1%87%d1%82%d0%be-%d1%80%d0%b5%d0%b0%d0%bb%d1%8c%d0%bd%d0%be-%d1%83%d0%bb%d1%83%d1%87%d1%88%d0%b8%d0%bb%d0%be%d1%81%d1%8c-%d0%bf%d0%be%d1%81%d0%bb%d0%b5-%d0%b2%d0%bd%d0%b5%d0%b4%d1%80%d0%b5%d0%bd%d0%b8%d1%8f">#</a>
</h2>
<p>Я получил не «магическое ускорение», а более важную вещь: предсказуемость процесса.</p>
<p>Практические эффекты:</p>
<ul>
<li>меньше технических ошибок во фронтматтере;</li>
<li>стабильнее качество мета-описаний;</li>
<li>ниже время между идеей и публикацией;</li>
<li>меньше усталости от повторяющихся операций.</li>
</ul>
<p>Главный результат: я пишу чаще и ровнее по качеству, потому что внимание уходит в содержание, а не в микрорутину.</p>
<h2 class="heading" id="типовые-ошибки-при-работе-с-codex-и-как-их-избежать">
  Типовые ошибки при работе с Codex (и как их избежать)
  <a class="anchor" href="#%d1%82%d0%b8%d0%bf%d0%be%d0%b2%d1%8b%d0%b5-%d0%be%d1%88%d0%b8%d0%b1%d0%ba%d0%b8-%d0%bf%d1%80%d0%b8-%d1%80%d0%b0%d0%b1%d0%be%d1%82%d0%b5-%d1%81-codex-%d0%b8-%d0%ba%d0%b0%d0%ba-%d0%b8%d1%85-%d0%b8%d0%b7%d0%b1%d0%b5%d0%b6%d0%b0%d1%82%d1%8c">#</a>
</h2>
<h3 class="heading" id="ошибка-1-просить-сразу-финальный-пост">
  Ошибка 1: просить «сразу финальный пост»
  <a class="anchor" href="#%d0%be%d1%88%d0%b8%d0%b1%d0%ba%d0%b0-1-%d0%bf%d1%80%d0%be%d1%81%d0%b8%d1%82%d1%8c-%d1%81%d1%80%d0%b0%d0%b7%d1%83-%d1%84%d0%b8%d0%bd%d0%b0%d0%bb%d1%8c%d0%bd%d1%8b%d0%b9-%d0%bf%d0%be%d1%81%d1%82">#</a>
</h3>
<p>Так почти всегда получается текст без авторской позиции. Лучше идти через этапы: каркас → черновик → ручная редактура → техническая сборка.</p>
<h3 class="heading" id="ошибка-2-не-задавать-ограничения">
  Ошибка 2: не задавать ограничения
  <a class="anchor" href="#%d0%be%d1%88%d0%b8%d0%b1%d0%ba%d0%b0-2-%d0%bd%d0%b5-%d0%b7%d0%b0%d0%b4%d0%b0%d0%b2%d0%b0%d1%82%d1%8c-%d0%be%d0%b3%d1%80%d0%b0%d0%bd%d0%b8%d1%87%d0%b5%d0%bd%d0%b8%d1%8f">#</a>
</h3>
<p>Если не проговорить глубину, аудиторию и формат, модель заполняет пробелы усреднёнными формулировками. Чем точнее входные параметры, тем полезнее выход.</p>
<h3 class="heading" id="ошибка-3-пропускать-финальный-ручной-проход">
  Ошибка 3: пропускать финальный ручной проход
  <a class="anchor" href="#%d0%be%d1%88%d0%b8%d0%b1%d0%ba%d0%b0-3-%d0%bf%d1%80%d0%be%d0%bf%d1%83%d1%81%d0%ba%d0%b0%d1%82%d1%8c-%d1%84%d0%b8%d0%bd%d0%b0%d0%bb%d1%8c%d0%bd%d1%8b%d0%b9-%d1%80%d1%83%d1%87%d0%bd%d0%be%d0%b9-%d0%bf%d1%80%d0%be%d1%85%d0%be%d0%b4">#</a>
</h3>
<p>Без авторской правки текст может быть «правильным», но без нервов и фактуры. Читатель это считывает мгновенно.</p>
<h2 class="heading" id="мини-шаблон-запроса-который-у-меня-работает">
  Мини-шаблон запроса, который у меня работает
  <a class="anchor" href="#%d0%bc%d0%b8%d0%bd%d0%b8-%d1%88%d0%b0%d0%b1%d0%bb%d0%be%d0%bd-%d0%b7%d0%b0%d0%bf%d1%80%d0%be%d1%81%d0%b0-%d0%ba%d0%be%d1%82%d0%be%d1%80%d1%8b%d0%b9-%d1%83-%d0%bc%d0%b5%d0%bd%d1%8f-%d1%80%d0%b0%d0%b1%d0%be%d1%82%d0%b0%d0%b5%d1%82">#</a>
</h2>
<p>Я обычно даю Codex примерно такую рамку:</p>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">Нужен пост для Hugo-блога на русском.
</span></span><span class="line"><span class="cl">Формат: длинная статья, глубокая проработка, практические выводы.
</span></span><span class="line"><span class="cl">Структура: вступление, 6-8 разделов, финальный чек-лист.
</span></span><span class="line"><span class="cl">Обязательно: осмысленные summary/description, корректный фронтматтер, уместные эмодзи.
</span></span><span class="line"><span class="cl">После текста: проверить техническую часть публикации (hugo list future, hugo --minify, commit, push).</span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<p>Этого достаточно, чтобы стартовый результат был рабочим, а не «общей заготовкой».</p>
<h2 class="heading" id="когда-codex-точно-не-помогает">
  Когда Codex точно не помогает
  <a class="anchor" href="#%d0%ba%d0%be%d0%b3%d0%b4%d0%b0-codex-%d1%82%d0%be%d1%87%d0%bd%d0%be-%d0%bd%d0%b5-%d0%bf%d0%be%d0%bc%d0%be%d0%b3%d0%b0%d0%b5%d1%82">#</a>
</h2>
<p>После пары месяцев работы в этом режиме можно честно перечислить ситуации, где автоматизация скорее мешает:</p>
<p><strong>Когда тема ещё не оформилась.</strong> Если у вас в голове только смутное «хочется написать про X», Codex выдаст структуру вокруг этой смутности — формально стройную, по сути пустую. Лучше потратить полчаса на бумажный набросок, выписать 3-5 ключевых тезисов, и только потом включать инструмент. Код первым приходит туда, где есть запрос; в текстах этот запрос — авторская позиция.</p>
<p><strong>Личные посты.</strong> Эссе про опыт, наблюдение, ошибку — Codex здесь не нужен. Структуру эссе диктует не методическая разбивка на h2-разделы, а внутренняя логика рассказа. Прогон через шаблон «вступление → 6 разделов → чек-лист» убивает живость текста. Технические руководства — да; рефлексия — нет.</p>
<p><strong>Когда ответ нужно проверить руками.</strong> Если вы пишете про инструмент, который сами не запускали (например, обзор библиотеки по чужим текстам), Codex усилит риски: соберёт правдоподобный текст с фактическими ошибками. Точность здесь обеспечивает только личное прохождение сценария, до буквы команд.</p>
<h2 class="heading" id="что-меняется-в-процессе-через-3-6-месяцев">
  Что меняется в процессе через 3-6 месяцев
  <a class="anchor" href="#%d1%87%d1%82%d0%be-%d0%bc%d0%b5%d0%bd%d1%8f%d0%b5%d1%82%d1%81%d1%8f-%d0%b2-%d0%bf%d1%80%d0%be%d1%86%d0%b5%d1%81%d1%81%d0%b5-%d1%87%d0%b5%d1%80%d0%b5%d0%b7-3-6-%d0%bc%d0%b5%d1%81%d1%8f%d1%86%d0%b5%d0%b2">#</a>
</h2>
<p>Любой workflow эволюционирует. Если поначалу Codex заметно ускоряет каждую публикацию, дальше эффект становится тише и переезжает в другую плоскость:</p>
<ul>
<li>Вы начинаете писать чаще, потому что нет «трения старта».</li>
<li>Качество публикаций становится ровным — нет «слабых» постов из-за усталости от рутины.</li>
<li>Появляется привычка фиксировать правила процесса (<code>AGENTS.md</code>, шаблоны, чек-листы) сразу, а не «когда-нибудь».</li>
<li>Перестаёте откладывать посты из-за мелких технических придирок (формат даты, длина summary, теги).</li>
</ul>
<p>Это не «магия ИИ». Это просто разделение труда между «чем я уникально полезен» и «что можно поручить инструменту».</p>
<h2 class="heading" id="практические-выводы">
  Практические выводы
  <a class="anchor" href="#%d0%bf%d1%80%d0%b0%d0%ba%d1%82%d0%b8%d1%87%d0%b5%d1%81%d0%ba%d0%b8%d0%b5-%d0%b2%d1%8b%d0%b2%d0%be%d0%b4%d1%8b">#</a>
</h2>
<p>Если коротко, рабочая модель такая:</p>
<ol>
<li>Смысл и позиция остаются у автора.</li>
<li>Codex берёт структуру и операционную рутину.</li>
<li>Качество растёт там, где есть дисциплина процесса, а не просто «сильный промпт». ✅</li>
</ol>
<p>Автоматизация в блоге полезна не потому, что «пишет быстрее», а потому что защищает внимание автора. А внимание, в долгую, важнее любой единичной публикации.</p>
]]></content:encoded><category>ai-инструменты</category><category>автоматизация</category><category>runbook</category></item><item><title>Здоровье, биохакинг и БАДы: как не потерять голову 💊</title><link>https://kushnaren.co/posts/zdorove-biohaking-bady/</link><pubDate>Mon, 19 Jan 2026 10:17:04 +0300</pubDate><guid isPermaLink="true">https://kushnaren.co/posts/zdorove-biohaking-bady/</guid><description>Без культа, без магии, без обещаний: разбор базовых привычек, роли анализов, принципов выбора БАДов и типичных ловушек, в которые попадает любой, кто впервые погружается в тему биохакинга.</description><content:encoded><![CDATA[<h2 class="heading" id="введение">
  Введение
  <a class="anchor" href="#%d0%b2%d0%b2%d0%b5%d0%b4%d0%b5%d0%bd%d0%b8%d0%b5">#</a>
</h2>
<p>Тема здоровья легко превращается в гонку гаджетов, протоколов и баночек. Зашёл в любой телеграм-канал «про биохак», полистал — и через неделю на полке стоят семь новых БАДов, на руке трекер сна, на диване книга про митохондрии. А базовые вещи — режим сна, ежедневное движение, нормальный завтрак — продолжают проседать.</p>
<p>Я хочу держать тему в более приземлённом поле: сначала базовые привычки, потом аккуратные эксперименты, и только затем — добавки, если есть для этого основания. Этот пост — не медицинская рекомендация и не «топ-10 must-have БАДов». Это попытка нарисовать карту, по которой можно ориентироваться, не теряя голову.</p>
<h2 class="heading" id="база-без-которой-не-работает-ничего-">
  База, без которой не работает ничего 🛏
  <a class="anchor" href="#%d0%b1%d0%b0%d0%b7%d0%b0-%d0%b1%d0%b5%d0%b7-%d0%ba%d0%be%d1%82%d0%be%d1%80%d0%be%d0%b9-%d0%bd%d0%b5-%d1%80%d0%b0%d0%b1%d0%be%d1%82%d0%b0%d0%b5%d1%82-%d0%bd%d0%b8%d1%87%d0%b5%d0%b3%d0%be-">#</a>
</h2>
<p>Самые надёжные улучшения лежат в простых вещах, и они банальны до зевоты:</p>
<ul>
<li><strong>Сон по расписанию.</strong> Одинаковое время отбоя и подъёма (включая выходные), темнота в спальне, ограничение экранов за час до сна. Не «8 часов любой ценой», а ровные 7-8 часов в одни и те же часы.</li>
<li><strong>Движение каждый день.</strong> Прогулки, силовые, растяжка — не важно что именно, важно регулярно. Дневная норма шагов даже без зала уже даёт большой кусок пользы.</li>
<li><strong>Рацион с адекватным белком, клетчаткой и достаточной калорийностью.</strong> Не «суперфуды», не «чистое питание» в религиозном смысле, а понятный рацион без хронического дефицита.</li>
<li><strong>Управление стрессом.</strong> Простые ритуалы (вечерняя прогулка, регулярные паузы), ограничение перегруза, цифровая гигиена. Не «медитация 1 час в день», а «не работать вечером».</li>
</ul>
<p>Если эти пункты не закрыты, «биохакинг» превращается в красивую упаковку поверх системных дыр. Купить адаптоген, чтобы компенсировать хронический недосып — это не про здоровье, это про прокрастинацию здоровья.</p>
<h2 class="heading" id="биохакинг-как-дисциплина-а-не-как-шоу">
  Биохакинг как дисциплина, а не как шоу
  <a class="anchor" href="#%d0%b1%d0%b8%d0%be%d1%85%d0%b0%d0%ba%d0%b8%d0%bd%d0%b3-%d0%ba%d0%b0%d0%ba-%d0%b4%d0%b8%d1%81%d1%86%d0%b8%d0%bf%d0%bb%d0%b8%d0%bd%d0%b0-%d0%b0-%d0%bd%d0%b5-%d0%ba%d0%b0%d0%ba-%d1%88%d0%be%d1%83">#</a>
</h2>
<p>Для меня биохакинг — это не про сверхчеловеческие цели типа «жить до 120 лет», а про наблюдение и микро-настройку под собственные особенности. Три принципа, без которых тема превращается в магазин:</p>
<ol>
<li><strong>Измерять только то, что будет влиять на решения.</strong> Если данные не меняют поведение, это не данные, это шум.</li>
<li><strong>Менять по одному фактору за раз.</strong> Иначе невозможно понять, что именно сработало (и сработало ли). Ввели магний, омегу и витамин D одновременно — улучшение есть, но причина неизвестна.</li>
<li><strong>Держать горизонт не в днях, а в месяцах.</strong> Большинство значимых изменений в самочувствии копится медленно. «Через неделю стало лучше» — обычно эффект новизны, а не реальный сдвиг.</li>
</ol>
<p>Эти три правила сами по себе отсекают 80% эзотерических протоколов из соцсетей. Если автор предлагает «попробуй и сразу почувствуешь разницу» — он не про дисциплину, он про маркетинг.</p>
<h2 class="heading" id="анализы-и-данные-когда-они-действительно-нужны-">
  Анализы и данные: когда они действительно нужны 📊
  <a class="anchor" href="#%d0%b0%d0%bd%d0%b0%d0%bb%d0%b8%d0%b7%d1%8b-%d0%b8-%d0%b4%d0%b0%d0%bd%d0%bd%d1%8b%d0%b5-%d0%ba%d0%be%d0%b3%d0%b4%d0%b0-%d0%be%d0%bd%d0%b8-%d0%b4%d0%b5%d0%b9%d1%81%d1%82%d0%b2%d0%b8%d1%82%d0%b5%d0%bb%d1%8c%d0%bd%d0%be-%d0%bd%d1%83%d0%b6%d0%bd%d1%8b-">#</a>
</h2>
<p>Слепая сдача десятков анализов «потому что в соседнем чате посоветовали» редко помогает. Полезнее идти от вопросов:</p>
<ul>
<li>Что именно я хочу улучшить или понять?</li>
<li>Есть ли симптомы или жалобы?</li>
<li>Что из результатов повлияет на конкретные действия?</li>
</ul>
<p>Если ответов нет — анализы становятся способом успокоиться, а не инструментом управления.</p>
<p>Несколько маркеров, которые часто имеют смысл проверять (без претензии на исчерпывающий список):</p>
<ul>
<li><strong>Витамин D (25-OH).</strong> В умеренных широтах хронический дефицит у большинства, особенно зимой.</li>
<li><strong>Ферритин.</strong> Маркер запасов железа; низкий часто объясняет «беспричинную» усталость.</li>
<li><strong>B12 и фолат.</strong> Особенно важно для тех, кто ограничивает мясо.</li>
<li><strong>Магний.</strong> Анализ малоинформативен (магний в основном внутри клеток), но если есть симптомы (судороги, аритмии) — стоит обсудить с врачом.</li>
<li><strong>ТТГ + Т4 свободный.</strong> Базовая щитовидка, влияет на энергию, вес, настроение.</li>
</ul>
<p>Это не «обязательная панель», это набор «если есть жалобы — есть смысл начать отсюда».</p>
<h2 class="heading" id="бады-инструмент-а-не-спасение">
  БАДы: инструмент, а не спасение
  <a class="anchor" href="#%d0%b1%d0%b0%d0%b4%d1%8b-%d0%b8%d0%bd%d1%81%d1%82%d1%80%d1%83%d0%bc%d0%b5%d0%bd%d1%82-%d0%b0-%d0%bd%d0%b5-%d1%81%d0%bf%d0%b0%d1%81%d0%b5%d0%bd%d0%b8%d0%b5">#</a>
</h2>
<p>Добавки могут быть уместны, когда есть <strong>дефицит</strong>, <strong>особенности питания</strong> или <strong>медицинские показания</strong>. В большинстве случаев они не перекрывают плохой сон, хаотичное питание и хронический стресс.</p>
<p>Принципы, которых я стараюсь придерживаться:</p>
<ul>
<li>Сначала проверка базовых привычек.</li>
<li>Затем чёткая цель и ожидаемый эффект.</li>
<li>И только после этого — минимальная дозировка и наблюдение за эффектом.</li>
</ul>
<p>Если БАД нельзя описать в формате «принимаю X для Y, эффект жду через Z недель» — лучше не принимать. Это правило отсеивает «модные новинки», которые завозят все блогеры разом.</p>
<h2 class="heading" id="как-выбирать-добавки-разумно">
  Как выбирать добавки разумно
  <a class="anchor" href="#%d0%ba%d0%b0%d0%ba-%d0%b2%d1%8b%d0%b1%d0%b8%d1%80%d0%b0%d1%82%d1%8c-%d0%b4%d0%be%d0%b1%d0%b0%d0%b2%d0%ba%d0%b8-%d1%80%d0%b0%d0%b7%d1%83%d0%bc%d0%bd%d0%be">#</a>
</h2>
<p>Простая схема, которая работает:</p>
<ol>
<li><strong>Определить цель.</strong> Сон, энергия, восстановление, дефицит по анализу. Что-то одно, не «всё сразу».</li>
<li><strong>Проверить безопасность и совместимость.</strong> С текущими лекарствами, состояниями, образом жизни. Это отдельная работа, не пропускать.</li>
<li><strong>Начать с одной добавки и фиксировать изменения.</strong> Дневник в три строки в день: сон, энергия, настроение. Этого достаточно.</li>
<li><strong>Отменить, если эффекта нет или он сомнителен.</strong> Через 4-8 недель, не раньше.</li>
</ol>
<p>И да: это не медицинская рекомендация. При сомнениях, симптомах или сложных состояниях — обсуждать с врачом, не с интернетом.</p>
<h2 class="heading" id="типичные-ловушки-">
  Типичные ловушки 🪤
  <a class="anchor" href="#%d1%82%d0%b8%d0%bf%d0%b8%d1%87%d0%bd%d1%8b%d0%b5-%d0%bb%d0%be%d0%b2%d1%83%d1%88%d0%ba%d0%b8-">#</a>
</h2>
<p>Самые частые ошибки, в которые попадаются почти все, кто заходит в тему:</p>
<p><strong>Покупать всё сразу.</strong> Под влиянием статьи или подкаста заказывают 5-7 добавок. В итоге не понимают, что работает, а что нет.</p>
<p><strong>Надеяться на «волшебную таблетку».</strong> Если есть проблема со сном — никакая добавка не починит то, что чинится за неделю гигиены сна.</p>
<p><strong>Забывать про доказательную базу.</strong> Многие популярные добавки имеют слабые или противоречивые исследования. «Все вокруг пьют» — не критерий.</p>
<p><strong>Игнорировать побочки.</strong> Любой БАД может давать эффект, который вы спишете на «обычный день». Дневник помогает поймать.</p>
<p><strong>Доверять ярким инфлюенсерам.</strong> Биохакинг — благодатная почва для красивых историй и плохих советов. Чем громче «у меня всё работает», тем выше вероятность маркетинга или selection bias.</p>
<h2 class="heading" id="минимальный-подход">
  Минимальный подход
  <a class="anchor" href="#%d0%bc%d0%b8%d0%bd%d0%b8%d0%bc%d0%b0%d0%bb%d1%8c%d0%bd%d1%8b%d0%b9-%d0%bf%d0%be%d0%b4%d1%85%d0%be%d0%b4">#</a>
</h2>
<p>Я склоняюсь к минимальному набору: меньше банок, больше дисциплины. Часто достаточно навести порядок в рутине, чтобы необходимость в добавках исчезла или сильно сократилась.</p>
<p>Если совсем коротко: спать в одно время, гулять каждый день, есть не «правильно», а сбалансированно, и не пить больше двух-трёх БАДов одновременно. Этого хватит большинству людей в большинстве периодов жизни.</p>
<h2 class="heading" id="итоги-">
  Итоги 🧠
  <a class="anchor" href="#%d0%b8%d1%82%d0%be%d0%b3%d0%b8-">#</a>
</h2>
<p>Здоровье — это не витрина из биохакинга, а устойчивость, которая складывается из маленьких повторяющихся решений. Добавки могут быть частью этой системы, но только после того, как база отстроена и цели ясны.</p>
<p>Биохакинг как идея полезен ровно до тех пор, пока он остаётся <strong>дисциплиной наблюдения</strong>. Как только он превращается в магазин баночек или гонку метрик — он перестаёт работать на здоровье и начинает работать на чувство «я делаю что-то важное», что сильно дешевле и проще, чем реально менять привычки.</p>
<p>Самый честный «биохакинг» — это лечь спать на час раньше. Бесплатно, без побочек, эффект через неделю.</p>
]]></content:encoded><category>здоровье</category></item><item><title>💻 Продвинутая терминальная разработка</title><link>https://kushnaren.co/posts/2025-04-01-advanced-terminal-development/</link><pubDate>Tue, 01 Apr 2025 10:00:00 +0300</pubDate><guid isPermaLink="true">https://kushnaren.co/posts/2025-04-01-advanced-terminal-development/</guid><description>Полное руководство по оптимизации рабочего окружения: Tmux, zsh, продвинутые скрипты и кастомизация</description><content:encoded><![CDATA[<h2 class="heading" id="-введение-в-продвинутую-терминальную-разработку">
  🖥️ Введение в Продвинутую Терминальную Разработку
  <a class="anchor" href="#-%d0%b2%d0%b2%d0%b5%d0%b4%d0%b5%d0%bd%d0%b8%d0%b5-%d0%b2-%d0%bf%d1%80%d0%be%d0%b4%d0%b2%d0%b8%d0%bd%d1%83%d1%82%d1%83%d1%8e-%d1%82%d0%b5%d1%80%d0%bc%d0%b8%d0%bd%d0%b0%d0%bb%d1%8c%d0%bd%d1%83%d1%8e-%d1%80%d0%b0%d0%b7%d1%80%d0%b0%d0%b1%d0%be%d1%82%d0%ba%d1%83">#</a>
</h2>
<p>Терминал - это не просто интерфейс, это мощный инструмент разработчика.</p>
<h2 class="heading" id="-tmux-мультиплексор-терминала">
  🌟 Tmux: Мультиплексор Терминала
  <a class="anchor" href="#-tmux-%d0%bc%d1%83%d0%bb%d1%8c%d1%82%d0%b8%d0%bf%d0%bb%d0%b5%d0%ba%d1%81%d0%be%d1%80-%d1%82%d0%b5%d1%80%d0%bc%d0%b8%d0%bd%d0%b0%d0%bb%d0%b0">#</a>
</h2>
<h3 class="heading" id="основы-tmux">
  Основы Tmux
  <a class="anchor" href="#%d0%be%d1%81%d0%bd%d0%be%d0%b2%d1%8b-tmux">#</a>
</h3>
<ul>
<li>Создание сессий</li>
<li>Разделение окон</li>
<li>Персистентность</li>
</ul>
<h3 class="heading" id="продвинутая-конфигурация">
  Продвинутая Конфигурация
  <a class="anchor" href="#%d0%bf%d1%80%d0%be%d0%b4%d0%b2%d0%b8%d0%bd%d1%83%d1%82%d0%b0%d1%8f-%d0%ba%d0%be%d0%bd%d1%84%d0%b8%d0%b3%d1%83%d1%80%d0%b0%d1%86%d0%b8%d1%8f">#</a>
</h3>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Пример .tmux.conf</span>
</span></span><span class="line"><span class="cl"><span class="nb">set</span> -g prefix C-a
</span></span><span class="line"><span class="cl">bind-key C-a send-prefix</span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<h2 class="heading" id="-современные-shell-zsh-и-fish">
  🐚 Современные Shell: Zsh и Fish
  <a class="anchor" href="#-%d1%81%d0%be%d0%b2%d1%80%d0%b5%d0%bc%d0%b5%d0%bd%d0%bd%d1%8b%d0%b5-shell-zsh-%d0%b8-fish">#</a>
</h2>
<h3 class="heading" id="zsh">
  Zsh
  <a class="anchor" href="#zsh">#</a>
</h3>
<ul>
<li>Автодополнение</li>
<li>Темы и плагины</li>
<li>Oh My Zsh</li>
</ul>
<h3 class="heading" id="fish-shell">
  Fish Shell
  <a class="anchor" href="#fish-shell">#</a>
</h3>
<ul>
<li>Интуитивный синтаксис</li>
<li>Встроенные подсказки</li>
<li>Автодополнение</li>
</ul>
<h2 class="heading" id="-продвинутые-скрипты">
  🤖 Продвинутые Скрипты
  <a class="anchor" href="#-%d0%bf%d1%80%d0%be%d0%b4%d0%b2%d0%b8%d0%bd%d1%83%d1%82%d1%8b%d0%b5-%d1%81%d0%ba%d1%80%d0%b8%d0%bf%d1%82%d1%8b">#</a>
</h2>
<h3 class="heading" id="bash-scripting">
  Bash Scripting
  <a class="anchor" href="#bash-scripting">#</a>
</h3>
<ul>
<li>Функции</li>
<li>Условные операторы</li>
<li>Обработка ошибок</li>
</ul>
<h3 class="heading" id="python-в-терминале">
  Python в Терминале
  <a class="anchor" href="#python-%d0%b2-%d1%82%d0%b5%d1%80%d0%bc%d0%b8%d0%bd%d0%b0%d0%bb%d0%b5">#</a>
</h3>
<ul>
<li>Click для CLI</li>
<li>Argparse</li>
<li>Asyncio в скриптах</li>
</ul>
<h2 class="heading" id="-кастомизация-рабочего-окружения">
  🎨 Кастомизация Рабочего Окружения
  <a class="anchor" href="#-%d0%ba%d0%b0%d1%81%d1%82%d0%be%d0%bc%d0%b8%d0%b7%d0%b0%d1%86%d0%b8%d1%8f-%d1%80%d0%b0%d0%b1%d0%be%d1%87%d0%b5%d0%b3%d0%be-%d0%be%d0%ba%d1%80%d1%83%d0%b6%d0%b5%d0%bd%d0%b8%d1%8f">#</a>
</h2>
<h3 class="heading" id="dotfiles">
  Dotfiles
  <a class="anchor" href="#dotfiles">#</a>
</h3>
<ul>
<li>Управление конфигурациями</li>
<li>Переносимость настроек</li>
<li>Система контроля версий</li>
</ul>
<h3 class="heading" id="продвинутые-алиасы">
  Продвинутые Алиасы
  <a class="anchor" href="#%d0%bf%d1%80%d0%be%d0%b4%d0%b2%d0%b8%d0%bd%d1%83%d1%82%d1%8b%d0%b5-%d0%b0%d0%bb%d0%b8%d0%b0%d1%81%d1%8b">#</a>
</h3>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Примеры алиасов</span>
</span></span><span class="line"><span class="cl"><span class="nb">alias</span> <span class="nv">gs</span><span class="o">=</span><span class="s1">&#39;git status&#39;</span>
</span></span><span class="line"><span class="cl"><span class="nb">alias</span> <span class="nv">dc</span><span class="o">=</span><span class="s1">&#39;docker-compose&#39;</span></span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<h3 class="heading" id="автоматизация-задач">
  Автоматизация Задач
  <a class="anchor" href="#%d0%b0%d0%b2%d1%82%d0%be%d0%bc%d0%b0%d1%82%d0%b8%d0%b7%d0%b0%d1%86%d0%b8%d1%8f-%d0%b7%d0%b0%d0%b4%d0%b0%d1%87">#</a>
</h3>
<h2 class="heading" id="-инструменты-повышения-продуктивности">
  🛠️ Инструменты Повышения Продуктивности
  <a class="anchor" href="#-%d0%b8%d0%bd%d1%81%d1%82%d1%80%d1%83%d0%bc%d0%b5%d0%bd%d1%82%d1%8b-%d0%bf%d0%be%d0%b2%d1%8b%d1%88%d0%b5%d0%bd%d0%b8%d1%8f-%d0%bf%d1%80%d0%be%d0%b4%d1%83%d0%ba%d1%82%d0%b8%d0%b2%d0%bd%d0%be%d1%81%d1%82%d0%b8">#</a>
</h2>
<ul>
<li>fzf: нечеткий поиск</li>
<li>ripgrep: быстрый поиск</li>
<li>bat: улучшенный cat</li>
<li>fd: современная замена find</li>
</ul>
<h2 class="heading" id="-эстетика-терминала">
  🌈 Эстетика Терминала
  <a class="anchor" href="#-%d1%8d%d1%81%d1%82%d0%b5%d1%82%d0%b8%d0%ba%d0%b0-%d1%82%d0%b5%d1%80%d0%bc%d0%b8%d0%bd%d0%b0%d0%bb%d0%b0">#</a>
</h2>
<ul>
<li>Powerline шрифты</li>
<li>Цветовые схемы</li>
<li>Иконки и prompt</li>
</ul>
<h2 class="heading" id="-заключение">
  🎓 Заключение
  <a class="anchor" href="#-%d0%b7%d0%b0%d0%ba%d0%bb%d1%8e%d1%87%d0%b5%d0%bd%d0%b8%d0%b5">#</a>
</h2>
<p>Терминал - это искусство. Чем больше вы практикуетесь, тем он становится мощнее!</p>
]]></content:encoded><category>Терминал</category><category>Shell</category><category>Продуктивность</category><category>Tmux</category><category>Zsh</category></item><item><title>🚀 Hugo v0.141.0: Улучшения в работе с изображениями и исправления</title><link>https://kushnaren.co/posts/2025-01-19-hugo-v0.141.0/</link><pubDate>Sun, 19 Jan 2025 00:00:00 +0000</pubDate><guid isPermaLink="true">https://kushnaren.co/posts/2025-01-19-hugo-v0.141.0/</guid><description>Обзор обновления Hugo v0.141.0 с улучшениями в обработке изображений, исправлениями ошибок и оптимизацией производительности</description><content:encoded><![CDATA[<h2 class="heading" id="-введение">
  🌟 Введение
  <a class="anchor" href="#-%d0%b2%d0%b2%d0%b5%d0%b4%d0%b5%d0%bd%d0%b8%d0%b5">#</a>
</h2>
<p>Hugo представил версию 0.141.0, которая включает в себя важные улучшения в работе с изображениями, исправления ошибок и общие улучшения производительности. Это обновление делает работу с медиа-контентом более надёжной и эффективной.</p>
<h2 class="heading" id="-улучшения-в-работе-с-изображениями">
  📸 Улучшения в работе с изображениями
  <a class="anchor" href="#-%d1%83%d0%bb%d1%83%d1%87%d1%88%d0%b5%d0%bd%d0%b8%d1%8f-%d0%b2-%d1%80%d0%b0%d0%b1%d0%be%d1%82%d0%b5-%d1%81-%d0%b8%d0%b7%d0%be%d0%b1%d1%80%d0%b0%d0%b6%d0%b5%d0%bd%d0%b8%d1%8f%d0%bc%d0%b8">#</a>
</h2>
<p>В этом релизе были внесены значительные улучшения в обработку изображений:</p>
<ul>
<li>Добавлена поддержка для изображений с прозрачностью в формате JPEG XL</li>
<li>Улучшена обработка EXIF-данных для различных форматов изображений</li>
<li>Оптимизирована работа с цветовыми профилями</li>
</ul>
<h2 class="heading" id="-исправления-ошибок">
  🛠️ Исправления ошибок
  <a class="anchor" href="#-%d0%b8%d1%81%d0%bf%d1%80%d0%b0%d0%b2%d0%bb%d0%b5%d0%bd%d0%b8%d1%8f-%d0%be%d1%88%d0%b8%d0%b1%d0%be%d0%ba">#</a>
</h2>
<p>Релиз включает несколько важных исправлений:</p>
<ul>
<li>Исправлена ошибка в обработке путей к изображениям в Windows</li>
<li>Улучшена обработка ошибок при работе с поврежденными изображениями</li>
<li>Исправлены проблемы с кэшированием при обработке изображений</li>
</ul>
<h2 class="heading" id="-оптимизация-производительности">
  ⚡ Оптимизация производительности
  <a class="anchor" href="#-%d0%be%d0%bf%d1%82%d0%b8%d0%bc%d0%b8%d0%b7%d0%b0%d1%86%d0%b8%d1%8f-%d0%bf%d1%80%d0%be%d0%b8%d0%b7%d0%b2%d0%be%d0%b4%d0%b8%d1%82%d0%b5%d0%bb%d1%8c%d0%bd%d0%be%d1%81%d1%82%d0%b8">#</a>
</h2>
<p>Были внесены улучшения в производительность:</p>
<ul>
<li>Оптимизирована обработка больших наборов изображений</li>
<li>Улучшена эффективность использования памяти при обработке изображений</li>
<li>Ускорена работа с кэшем изображений</li>
</ul>
<h2 class="heading" id="-как-обновиться">
  🔄 Как обновиться
  <a class="anchor" href="#-%d0%ba%d0%b0%d0%ba-%d0%be%d0%b1%d0%bd%d0%be%d0%b2%d0%b8%d1%82%d1%8c%d1%81%d1%8f">#</a>
</h2>
<p>Для обновления Hugo до версии 0.141.0 используйте следующие команды:</p>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Для пользователей Homebrew (macOS)</span>
</span></span><span class="line"><span class="cl">brew upgrade hugo
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Для пользователей Windows (с использованием Chocolatey)</span>
</span></span><span class="line"><span class="cl">choco upgrade hugo
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Для пользователей Linux</span>
</span></span><span class="line"><span class="cl">sudo apt update <span class="o">&amp;&amp;</span> sudo apt upgrade hugo  <span class="c1"># Debian/Ubuntu</span>
</span></span><span class="line"><span class="cl">sudo dnf upgrade hugo                     <span class="c1"># Fedora</span></span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<h2 class="heading" id="-заключение">
  📝 Заключение
  <a class="anchor" href="#-%d0%b7%d0%b0%d0%ba%d0%bb%d1%8e%d1%87%d0%b5%d0%bd%d0%b8%d0%b5">#</a>
</h2>
<p>Hugo v0.141.0 представляет собой важное обновление, особенно для проектов, активно использующих работу с изображениями. Улучшения в обработке изображений и оптимизация производительности делают эту версию рекомендованной к установке для всех пользователей Hugo.</p>
<p>Полный список изменений доступен в <a href="https://github.com/gohugoio/hugo/releases/tag/v0.141.0">официальном релизе</a> на GitHub.</p>
]]></content:encoded><category>Hugo</category><category>Релиз</category><category>Обновление</category><category>Изображения</category></item><item><title>🖥️ Tmux: Мощный терминальный мультиплексор</title><link>https://kushnaren.co/posts/2025-01-01-tmux-terminal-multiplexer/</link><pubDate>Wed, 01 Jan 2025 00:00:00 +0000</pubDate><guid isPermaLink="true">https://kushnaren.co/posts/2025-01-01-tmux-terminal-multiplexer/</guid><description>Подробное руководство по использованию tmux: от базовых команд до продвинутых техник управления сессиями и панелями</description><content:encoded><![CDATA[<h2 class="heading" id="-введение">
  🌟 Введение
  <a class="anchor" href="#-%d0%b2%d0%b2%d0%b5%d0%b4%d0%b5%d0%bd%d0%b8%d0%b5">#</a>
</h2>
<p>Tmux (Terminal Multiplexer) — это мощный инструмент для работы с терминалом, который позволяет создавать несколько виртуальных терминалов внутри одного окна, управлять сессиями и сохранять рабочее окружение даже после отключения. В этой статье мы рассмотрим основные возможности tmux и научимся эффективно использовать его в повседневной работе.</p>
<h2 class="heading" id="-основные-возможности-tmux">
  🚀 Основные возможности tmux
  <a class="anchor" href="#-%d0%be%d1%81%d0%bd%d0%be%d0%b2%d0%bd%d1%8b%d0%b5-%d0%b2%d0%be%d0%b7%d0%bc%d0%be%d0%b6%d0%bd%d0%be%d1%81%d1%82%d0%b8-tmux">#</a>
</h2>
<h3 class="heading" id="ключевые-преимущества">
  Ключевые преимущества
  <a class="anchor" href="#%d0%ba%d0%bb%d1%8e%d1%87%d0%b5%d0%b2%d1%8b%d0%b5-%d0%bf%d1%80%d0%b5%d0%b8%d0%bc%d1%83%d1%89%d0%b5%d1%81%d1%82%d0%b2%d0%b0">#</a>
</h3>
<ul>
<li>📌 Сохранение сессий между подключениями</li>
<li>📌 Разделение окна на панели</li>
<li>📌 Создание нескольких окон в одной сессии</li>
<li>📌 Копирование и вставка текста между панелями</li>
<li>📌 Настраиваемые горячие клавиши</li>
<li>📌 Поддержка скриптов и автоматизации</li>
</ul>
<h2 class="heading" id="-установка-и-настройка">
  🛠️ Установка и настройка
  <a class="anchor" href="#-%d1%83%d1%81%d1%82%d0%b0%d0%bd%d0%be%d0%b2%d0%ba%d0%b0-%d0%b8-%d0%bd%d0%b0%d1%81%d1%82%d1%80%d0%be%d0%b9%d0%ba%d0%b0">#</a>
</h2>
<h3 class="heading" id="установка-tmux">
  Установка tmux
  <a class="anchor" href="#%d1%83%d1%81%d1%82%d0%b0%d0%bd%d0%be%d0%b2%d0%ba%d0%b0-tmux">#</a>
</h3>
<p>На macOS с помощью Homebrew:</p>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">brew install tmux</span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<p>На Ubuntu/Debian:</p>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo apt install tmux</span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<h3 class="heading" id="базовая-конфигурация">
  Базовая конфигурация
  <a class="anchor" href="#%d0%b1%d0%b0%d0%b7%d0%be%d0%b2%d0%b0%d1%8f-%d0%ba%d0%be%d0%bd%d1%84%d0%b8%d0%b3%d1%83%d1%80%d0%b0%d1%86%d0%b8%d1%8f">#</a>
</h3>
<p>Создайте файл <code>~/.tmux.conf</code> с базовыми настройками:</p>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Изменение префикса на Ctrl+a</span>
</span></span><span class="line"><span class="cl"><span class="nb">set</span> -g prefix C-a
</span></span><span class="line"><span class="cl">unbind C-b
</span></span><span class="line"><span class="cl"><span class="nb">bind</span> C-a send-prefix
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Включение поддержки мыши</span>
</span></span><span class="line"><span class="cl"><span class="nb">set</span> -g mouse on
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Начинать нумерацию окон с 1</span>
</span></span><span class="line"><span class="cl"><span class="nb">set</span> -g base-index <span class="m">1</span>
</span></span><span class="line"><span class="cl">setw -g pane-base-index <span class="m">1</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Улучшение цветопередачи</span>
</span></span><span class="line"><span class="cl"><span class="nb">set</span> -g default-terminal <span class="s2">&#34;screen-256color&#34;</span></span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<h2 class="heading" id="-основные-команды">
  📚 Основные команды
  <a class="anchor" href="#-%d0%be%d1%81%d0%bd%d0%be%d0%b2%d0%bd%d1%8b%d0%b5-%d0%ba%d0%be%d0%bc%d0%b0%d0%bd%d0%b4%d1%8b">#</a>
</h2>
<h3 class="heading" id="управление-сессиями">
  Управление сессиями
  <a class="anchor" href="#%d1%83%d0%bf%d1%80%d0%b0%d0%b2%d0%bb%d0%b5%d0%bd%d0%b8%d0%b5-%d1%81%d0%b5%d1%81%d1%81%d0%b8%d1%8f%d0%bc%d0%b8">#</a>
</h3>
<ul>
<li>🔷 Создание новой сессии: <code>tmux new -s имя_сессии</code></li>
<li>🔷 Подключение к существующей сессии: <code>tmux attach -t имя_сессии</code></li>
<li>🔷 Список сессий: <code>tmux ls</code></li>
<li>🔷 Отключение от сессии: <code>Prefix + d</code></li>
<li>🔷 Переименование сессии: <code>Prefix + $</code></li>
</ul>
<h3 class="heading" id="работа-с-окнами">
  Работа с окнами
  <a class="anchor" href="#%d1%80%d0%b0%d0%b1%d0%be%d1%82%d0%b0-%d1%81-%d0%be%d0%ba%d0%bd%d0%b0%d0%bc%d0%b8">#</a>
</h3>
<ul>
<li>🔷 Создание нового окна: <code>Prefix + c</code></li>
<li>🔷 Переключение между окнами: <code>Prefix + номер_окна</code></li>
<li>🔷 Переименование окна: <code>Prefix + ,</code></li>
<li>🔷 Закрытие окна: <code>Prefix + &amp;</code></li>
</ul>
<h3 class="heading" id="управление-панелями">
  Управление панелями
  <a class="anchor" href="#%d1%83%d0%bf%d1%80%d0%b0%d0%b2%d0%bb%d0%b5%d0%bd%d0%b8%d0%b5-%d0%bf%d0%b0%d0%bd%d0%b5%d0%bb%d1%8f%d0%bc%d0%b8">#</a>
</h3>
<ul>
<li>🔷 Разделить горизонтально: <code>Prefix + &quot;</code></li>
<li>🔷 Разделить вертикально: <code>Prefix + %</code></li>
<li>🔷 Переключение между панелями: <code>Prefix + стрелки</code></li>
<li>🔷 Изменение размера панели: <code>Prefix + Alt + стрелки</code></li>
<li>🔷 Закрытие панели: <code>Prefix + x</code></li>
</ul>
<h2 class="heading" id="-продвинутые-техники">
  🎯 Продвинутые техники
  <a class="anchor" href="#-%d0%bf%d1%80%d0%be%d0%b4%d0%b2%d0%b8%d0%bd%d1%83%d1%82%d1%8b%d0%b5-%d1%82%d0%b5%d1%85%d0%bd%d0%b8%d0%ba%d0%b8">#</a>
</h2>
<h3 class="heading" id="копирование-и-вставка">
  Копирование и вставка
  <a class="anchor" href="#%d0%ba%d0%be%d0%bf%d0%b8%d1%80%d0%be%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5-%d0%b8-%d0%b2%d1%81%d1%82%d0%b0%d0%b2%d0%ba%d0%b0">#</a>
</h3>
<ol>
<li>Вход в режим копирования: <code>Prefix + [</code></li>
<li>Перемещение курсора к началу текста</li>
<li>Начало выделения: <code>Space</code></li>
<li>Выделение текста</li>
<li>Копирование в буфер: <code>Enter</code></li>
<li>Вставка: <code>Prefix + ]</code></li>
</ol>
<h3 class="heading" id="синхронизация-панелей">
  Синхронизация панелей
  <a class="anchor" href="#%d1%81%d0%b8%d0%bd%d1%85%d1%80%d0%be%d0%bd%d0%b8%d0%b7%d0%b0%d1%86%d0%b8%d1%8f-%d0%bf%d0%b0%d0%bd%d0%b5%d0%bb%d0%b5%d0%b9">#</a>
</h3>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Включение синхронного ввода во все панели</span>
</span></span><span class="line"><span class="cl">:setw synchronize-panes on
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Выключение синхронного ввода</span>
</span></span><span class="line"><span class="cl">:setw synchronize-panes off</span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<h3 class="heading" id="сохранение-и-восстановление-сессий">
  Сохранение и восстановление сессий
  <a class="anchor" href="#%d1%81%d0%be%d1%85%d1%80%d0%b0%d0%bd%d0%b5%d0%bd%d0%b8%d0%b5-%d0%b8-%d0%b2%d0%be%d1%81%d1%81%d1%82%d0%b0%d0%bd%d0%be%d0%b2%d0%bb%d0%b5%d0%bd%d0%b8%d0%b5-%d1%81%d0%b5%d1%81%d1%81%d0%b8%d0%b9">#</a>
</h3>
<p>Используйте плагин <code>tmux-resurrect</code> для сохранения состояния сессий:</p>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Установка через tpm (Tmux Plugin Manager)</span>
</span></span><span class="line"><span class="cl"><span class="nb">set</span> -g @plugin <span class="s1">&#39;tmux-plugins/tmux-resurrect&#39;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Сохранение сессии: Prefix + Ctrl-s</span>
</span></span><span class="line"><span class="cl"><span class="c1"># Восстановление сессии: Prefix + Ctrl-r</span></span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<h2 class="heading" id="-полезные-советы">
  💡 Полезные советы
  <a class="anchor" href="#-%d0%bf%d0%be%d0%bb%d0%b5%d0%b7%d0%bd%d1%8b%d0%b5-%d1%81%d0%be%d0%b2%d0%b5%d1%82%d1%8b">#</a>
</h2>
<h3 class="heading" id="эффективная-работа">
  Эффективная работа
  <a class="anchor" href="#%d1%8d%d1%84%d1%84%d0%b5%d0%ba%d1%82%d0%b8%d0%b2%d0%bd%d0%b0%d1%8f-%d1%80%d0%b0%d0%b1%d0%be%d1%82%d0%b0">#</a>
</h3>
<ol>
<li>Используйте осмысленные имена для сессий и окон</li>
<li>Создавайте отдельные сессии для разных проектов</li>
<li>Используйте скрипты для автоматического создания рабочего окружения</li>
<li>Настройте статусную строку для отображения важной информации</li>
</ol>
<h3 class="heading" id="пример-скрипта-для-создания-рабочего-окружения">
  Пример скрипта для создания рабочего окружения
  <a class="anchor" href="#%d0%bf%d1%80%d0%b8%d0%bc%d0%b5%d1%80-%d1%81%d0%ba%d1%80%d0%b8%d0%bf%d1%82%d0%b0-%d0%b4%d0%bb%d1%8f-%d1%81%d0%be%d0%b7%d0%b4%d0%b0%d0%bd%d0%b8%d1%8f-%d1%80%d0%b0%d0%b1%d0%be%d1%87%d0%b5%d0%b3%d0%be-%d0%be%d0%ba%d1%80%d1%83%d0%b6%d0%b5%d0%bd%d0%b8%d1%8f">#</a>
</h3>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="cp">#!/bin/bash
</span></span></span><span class="line"><span class="cl"><span class="c1"># Создание новой сессии</span>
</span></span><span class="line"><span class="cl">tmux new-session -d -s dev
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Разделение окна</span>
</span></span><span class="line"><span class="cl">tmux split-window -h
</span></span><span class="line"><span class="cl">tmux split-window -v
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Запуск команд в панелях</span>
</span></span><span class="line"><span class="cl">tmux send-keys -t <span class="m">0</span> <span class="s1">&#39;vim&#39;</span> C-m
</span></span><span class="line"><span class="cl">tmux send-keys -t <span class="m">1</span> <span class="s1">&#39;git status&#39;</span> C-m
</span></span><span class="line"><span class="cl">tmux send-keys -t <span class="m">2</span> <span class="s1">&#39;htop&#39;</span> C-m
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Подключение к сессии</span>
</span></span><span class="line"><span class="cl">tmux attach-session -d -t dev</span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<h2 class="heading" id="-заключение">
  📝 Заключение
  <a class="anchor" href="#-%d0%b7%d0%b0%d0%ba%d0%bb%d1%8e%d1%87%d0%b5%d0%bd%d0%b8%d0%b5">#</a>
</h2>
<p>Tmux — это мощный инструмент, который значительно повышает эффективность работы в терминале. Начните с базовых команд и постепенно добавляйте новые возможности в свой рабочий процесс. С практикой вы сможете создавать сложные рабочие окружения и эффективно управлять множеством терминальных сессий.</p>
<p>Рекомендуется:</p>
<ol>
<li>Создать собственный конфигурационный файл</li>
<li>Изучить и настроить горячие клавиши под свои нужды</li>
<li>Использовать плагины для расширения функциональности</li>
<li>Регулярно практиковаться в использовании новых команд</li>
</ol>
]]></content:encoded><category>Tmux</category><category>Terminal</category><category>Productivity</category><category>Linux</category><category>Macos</category></item><item><title>🛡️ Hugo v0.140.2: Обновление безопасности и улучшения</title><link>https://kushnaren.co/posts/2025-01-01-hugo-v0.140.2/</link><pubDate>Wed, 01 Jan 2025 00:00:00 +0000</pubDate><guid isPermaLink="true">https://kushnaren.co/posts/2025-01-01-hugo-v0.140.2/</guid><description>Обзор обновления Hugo v0.140.2 с важным исправлением безопасности в html.Parse и другими улучшениями</description><content:encoded><![CDATA[<h2 class="heading" id="-введение">
  🌟 Введение
  <a class="anchor" href="#-%d0%b2%d0%b2%d0%b5%d0%b4%d0%b5%d0%bd%d0%b8%d0%b5">#</a>
</h2>
<p>Hugo выпустил версию 0.140.2, в которой основное внимание уделено важному исправлению безопасности. Обновление затрагивает функцию <code>html.Parse</code> из пакета <code>golang.org/x/net</code>, которая используется в двух ключевых компонентах Hugo: при извлечении оглавления из вывода Asciidoctor и при сборе HTML-классов во время включенной статистики сборки.</p>
<h2 class="heading" id="-исправление-безопасности">
  🔒 Исправление безопасности
  <a class="anchor" href="#-%d0%b8%d1%81%d0%bf%d1%80%d0%b0%d0%b2%d0%bb%d0%b5%d0%bd%d0%b8%d0%b5-%d0%b1%d0%b5%d0%b7%d0%be%d0%bf%d0%b0%d1%81%d0%bd%d0%be%d1%81%d1%82%d0%b8">#</a>
</h2>
<p>Хотя вероятность эксплуатации уязвимости в контексте Hugo оценивается как невысокая, это обновление:</p>
<ul>
<li>Устраняет потенциальные риски безопасности</li>
<li>Обеспечивает более чистый отчет безопасности</li>
<li>Поддерживает высокие стандарты безопасности проекта</li>
</ul>
<h2 class="heading" id="-технические-улучшения">
  🔧 Технические улучшения
  <a class="anchor" href="#-%d1%82%d0%b5%d1%85%d0%bd%d0%b8%d1%87%d0%b5%d1%81%d0%ba%d0%b8%d0%b5-%d1%83%d0%bb%d1%83%d1%87%d1%88%d0%b5%d0%bd%d0%b8%d1%8f">#</a>
</h2>
<h3 class="heading" id="обновления-зависимостей">
  Обновления зависимостей
  <a class="anchor" href="#%d0%be%d0%b1%d0%bd%d0%be%d0%b2%d0%bb%d0%b5%d0%bd%d0%b8%d1%8f-%d0%b7%d0%b0%d0%b2%d0%b8%d1%81%d0%b8%d0%bc%d0%be%d1%81%d1%82%d0%b5%d0%b9">#</a>
</h3>
<ul>
<li>✨ Пакет <code>golang.org/x/net</code> обновлен с версии 0.32.0 до 0.33.0</li>
<li>✨ Улучшена стабильность и безопасность системы</li>
</ul>
<h3 class="heading" id="исправления-ошибок">
  Исправления ошибок
  <a class="anchor" href="#%d0%b8%d1%81%d0%bf%d1%80%d0%b0%d0%b2%d0%bb%d0%b5%d0%bd%d0%b8%d1%8f-%d0%be%d1%88%d0%b8%d0%b1%d0%be%d0%ba">#</a>
</h3>
<ul>
<li>🐛 Устранена проблема с конфигурацией языковых настроек</li>
<li>🐛 Исправлена ошибка многократной публикации одного ресурса</li>
<li>🐛 Добавлена проверка определения формата вывода</li>
</ul>
<h3 class="heading" id="улучшения-функциональности">
  Улучшения функциональности
  <a class="anchor" href="#%d1%83%d0%bb%d1%83%d1%87%d1%88%d0%b5%d0%bd%d0%b8%d1%8f-%d1%84%d1%83%d0%bd%d0%ba%d1%86%d0%b8%d0%be%d0%bd%d0%b0%d0%bb%d1%8c%d0%bd%d0%be%d1%81%d1%82%d0%b8">#</a>
</h3>
<ul>
<li>📝 Добавлена документация по использованию <code>hugo gen chromastyles</code> с CSS</li>
<li>🎨 В подсветку синтаксиса добавлена опция <code>wrapperClass</code></li>
<li>🔍 Улучшена обработка ошибок и информативность сообщений</li>
</ul>
<h2 class="heading" id="-рекомендации-по-обновлению">
  📚 Рекомендации по обновлению
  <a class="anchor" href="#-%d1%80%d0%b5%d0%ba%d0%be%d0%bc%d0%b5%d0%bd%d0%b4%d0%b0%d1%86%d0%b8%d0%b8-%d0%bf%d0%be-%d0%be%d0%b1%d0%bd%d0%be%d0%b2%d0%bb%d0%b5%d0%bd%d0%b8%d1%8e">#</a>
</h2>
<p>Рекомендуется обновить Hugo до версии 0.140.2 по следующим причинам:</p>
<ol>
<li>Повышение уровня безопасности системы</li>
<li>Улучшенная обработка ошибок</li>
<li>Новые возможности подсветки синтаксиса</li>
<li>Исправления в работе с ресурсами</li>
</ol>
<h2 class="heading" id="-заключение">
  🔍 Заключение
  <a class="anchor" href="#-%d0%b7%d0%b0%d0%ba%d0%bb%d1%8e%d1%87%d0%b5%d0%bd%d0%b8%d0%b5">#</a>
</h2>
<p>Hugo v0.140.2 представляет собой важное обновление безопасности, которое также включает ряд полезных улучшений и исправлений. Хотя риск эксплуатации уязвимости в существующих установках Hugo минимален, обновление рекомендуется для поддержания высокого уровня безопасности и стабильности вашего сайта.</p>
]]></content:encoded><category>Hugo</category><category>Релиз</category><category>Безопасность</category><category>Обновление</category></item><item><title>🎄 Hugo v0.140.1: Последний релиз 2024 года</title><link>https://kushnaren.co/posts/2024-12-23-hugo-v0.140.1/</link><pubDate>Mon, 23 Dec 2024 00:00:00 +0000</pubDate><guid isPermaLink="true">https://kushnaren.co/posts/2024-12-23-hugo-v0.140.1/</guid><description>Обзор финального релиза Hugo v0.140.1 в 2024 году с улучшениями в работе с S3, JavaScript и системой меню</description><content:encoded><![CDATA[<h2 class="heading" id="-введение">
  🌟 Введение
  <a class="anchor" href="#-%d0%b2%d0%b2%d0%b5%d0%b4%d0%b5%d0%bd%d0%b8%d0%b5">#</a>
</h2>
<p>23 декабря 2024 года команда Hugo выпустила версию 0.140.1, которая, вероятно, станет последним обновлением в уходящем году. Этот релиз фокусируется на улучшении стабильности и исправлении ошибок в различных компонентах системы.</p>
<h2 class="heading" id="-основные-улучшения">
  🔧 Основные улучшения
  <a class="anchor" href="#-%d0%be%d1%81%d0%bd%d0%be%d0%b2%d0%bd%d1%8b%d0%b5-%d1%83%d0%bb%d1%83%d1%87%d1%88%d0%b5%d0%bd%d0%b8%d1%8f">#</a>
</h2>
<h3 class="heading" id="улучшенная-поддержка-облачных-хранилищ">
  Улучшенная поддержка облачных хранилищ
  <a class="anchor" href="#%d1%83%d0%bb%d1%83%d1%87%d1%88%d0%b5%d0%bd%d0%bd%d0%b0%d1%8f-%d0%bf%d0%be%d0%b4%d0%b4%d0%b5%d1%80%d0%b6%d0%ba%d0%b0-%d0%be%d0%b1%d0%bb%d0%b0%d1%87%d0%bd%d1%8b%d1%85-%d1%85%d1%80%d0%b0%d0%bd%d0%b8%d0%bb%d0%b8%d1%89">#</a>
</h3>
<ul>
<li>✨ Обновлена интеграция с gocloud</li>
<li>✨ Улучшена документация для S3-совместимых конечных точек</li>
<li>✨ Расширена поддержка различных S3-совместимых сервисов хранения</li>
</ul>
<h3 class="heading" id="javascript-и-сборка">
  JavaScript и сборка
  <a class="anchor" href="#javascript-%d0%b8-%d1%81%d0%b1%d0%be%d1%80%d0%ba%d0%b0">#</a>
</h3>
<ul>
<li>🔍 Оптимизирована работа js/esbuild</li>
<li>🔍 Исключены лишние попытки разрешения пакетов в <code>/assets</code></li>
<li>🔍 Повышена стабильность процесса сборки</li>
</ul>
<h3 class="heading" id="работа-с-ресурсами">
  Работа с ресурсами
  <a class="anchor" href="#%d1%80%d0%b0%d0%b1%d0%be%d1%82%d0%b0-%d1%81-%d1%80%d0%b5%d1%81%d1%83%d1%80%d1%81%d0%b0%d0%bc%d0%b8">#</a>
</h3>
<ul>
<li>📦 Исправлены функции для временных ресурсов:
<ul>
<li>Объединение</li>
<li>Дополнение</li>
<li>Симметричная разность</li>
<li>Пересечение</li>
</ul>
</li>
</ul>
<h3 class="heading" id="улучшения-в-развертывании">
  Улучшения в развертывании
  <a class="anchor" href="#%d1%83%d0%bb%d1%83%d1%87%d1%88%d0%b5%d0%bd%d0%b8%d1%8f-%d0%b2-%d1%80%d0%b0%d0%b7%d0%b2%d0%b5%d1%80%d1%82%d1%8b%d0%b2%d0%b0%d0%bd%d0%b8%d0%b8">#</a>
</h3>
<ul>
<li>🚀 Добавлены расширенные deb-архивы</li>
<li>🚀 Улучшена поддержка деплоя</li>
<li>🚀 Расширены возможности для развертывания</li>
</ul>
<h2 class="heading" id="-технические-улучшения">
  🛠 Технические улучшения
  <a class="anchor" href="#-%d1%82%d0%b5%d1%85%d0%bd%d0%b8%d1%87%d0%b5%d1%81%d0%ba%d0%b8%d0%b5-%d1%83%d0%bb%d1%83%d1%87%d1%88%d0%b5%d0%bd%d0%b8%d1%8f">#</a>
</h2>
<h3 class="heading" id="система-логирования">
  Система логирования
  <a class="anchor" href="#%d1%81%d0%b8%d1%81%d1%82%d0%b5%d0%bc%d0%b0-%d0%bb%d0%be%d0%b3%d0%b8%d1%80%d0%be%d0%b2%d0%b0%d0%bd%d0%b8%d1%8f">#</a>
</h3>
<ul>
<li>📝 Изменен вывод <code>PrintTimerIfDelayed</code></li>
<li>📝 Логи теперь направляются в stderr</li>
<li>📝 Улучшена общая обработка логов</li>
</ul>
<h3 class="heading" id="обновления-зависимостей">
  Обновления зависимостей
  <a class="anchor" href="#%d0%be%d0%b1%d0%bd%d0%be%d0%b2%d0%bb%d0%b5%d0%bd%d0%b8%d1%8f-%d0%b7%d0%b0%d0%b2%d0%b8%d1%81%d0%b8%d0%bc%d0%be%d1%81%d1%82%d0%b5%d0%b9">#</a>
</h3>
<ul>
<li>📚 Обновлена библиотека <code>github.com/spf13/cast</code></li>
<li>📚 Версия обновлена с 1.7.0 до 1.7.1</li>
<li>📚 Включены последние исправления и улучшения</li>
</ul>
<h3 class="heading" id="система-меню">
  Система меню
  <a class="anchor" href="#%d1%81%d0%b8%d1%81%d1%82%d0%b5%d0%bc%d0%b0-%d0%bc%d0%b5%d0%bd%d1%8e">#</a>
</h3>
<ul>
<li>🔄 Исправлена обработка резервных значений</li>
<li>🔄 Улучшена работа с полями <code>Name</code> и <code>Title</code></li>
<li>🔄 Добавлена корректная обработка отсутствующих значений</li>
</ul>
<h2 class="heading" id="-изменения-в-инструментах-разработки">
  🔨 Изменения в инструментах разработки
  <a class="anchor" href="#-%d0%b8%d0%b7%d0%bc%d0%b5%d0%bd%d0%b5%d0%bd%d0%b8%d1%8f-%d0%b2-%d0%b8%d0%bd%d1%81%d1%82%d1%80%d1%83%d0%bc%d0%b5%d0%bd%d1%82%d0%b0%d1%85-%d1%80%d0%b0%d0%b7%d1%80%d0%b0%d0%b1%d0%be%d1%82%d0%ba%d0%b8">#</a>
</h2>
<p>Важное изменение коснулось инструмента <code>hugoreleaser</code>:</p>
<ul>
<li>🔄 Переход с TOML на YAML для конфигурации релизов</li>
<li>🔄 Упрощение процесса настройки</li>
<li>🔄 Улучшение читаемости конфигурационных файлов</li>
</ul>
<h2 class="heading" id="-заключение">
  📝 Заключение
  <a class="anchor" href="#-%d0%b7%d0%b0%d0%ba%d0%bb%d1%8e%d1%87%d0%b5%d0%bd%d0%b8%d0%b5">#</a>
</h2>
<p>Hugo v0.140.1 завершает 2024 год набором важных улучшений, направленных на повышение стабильности и удобства использования фреймворка. Особое внимание было уделено работе с облачными хранилищами, системе сборки JavaScript и улучшению процесса развертывания.</p>
<p>Рекомендуется обновиться до этой версии, особенно если вы используете S3-совместимые хранилища или активно работаете с JavaScript в своих проектах. Новые deb-архивы с поддержкой деплоя также могут быть полезны для оптимизации процесса развертывания.</p>
]]></content:encoded><category>Hugo</category><category>Релиз</category><category>Javascript</category><category>S3</category><category>Deployment</category></item><item><title>🔌 Работа с API в Gitea</title><link>https://kushnaren.co/posts/2024-12-21-working-with-gitea-api/</link><pubDate>Sat, 21 Dec 2024 10:00:00 +0300</pubDate><guid isPermaLink="true">https://kushnaren.co/posts/2024-12-21-working-with-gitea-api/</guid><description>Подробное руководство по использованию API Gitea для автоматизации и интеграции</description><content:encoded><![CDATA[<h2 class="heading" id="-введение-в-gitea-api">
  🌐 Введение в Gitea API
  <a class="anchor" href="#-%d0%b2%d0%b2%d0%b5%d0%b4%d0%b5%d0%bd%d0%b8%d0%b5-%d0%b2-gitea-api">#</a>
</h2>
<p>Gitea предоставляет мощный API, который позволяет автоматизировать различные задачи и интегрировать Gitea с другими системами. Это делает Gitea гибким инструментом для DevOps и разработки.</p>
<h3 class="heading" id="почему-использовать-api-gitea">
  Почему использовать API Gitea?
  <a class="anchor" href="#%d0%bf%d0%be%d1%87%d0%b5%d0%bc%d1%83-%d0%b8%d1%81%d0%bf%d0%be%d0%bb%d1%8c%d0%b7%d0%be%d0%b2%d0%b0%d1%82%d1%8c-api-gitea">#</a>
</h3>
<ul>
<li><strong>Автоматизация</strong>: Позволяет автоматизировать рутинные задачи.</li>
<li><strong>Интеграция</strong>: Легко интегрируется с другими инструментами и сервисами.</li>
<li><strong>Гибкость</strong>: Позволяет создавать кастомные решения.</li>
</ul>
<h2 class="heading" id="-основы-работы-с-api">
  🔧 Основы работы с API
  <a class="anchor" href="#-%d0%be%d1%81%d0%bd%d0%be%d0%b2%d1%8b-%d1%80%d0%b0%d0%b1%d0%be%d1%82%d1%8b-%d1%81-api">#</a>
</h2>
<h3 class="heading" id="аутентификация">
  Аутентификация
  <a class="anchor" href="#%d0%b0%d1%83%d1%82%d0%b5%d0%bd%d1%82%d0%b8%d1%84%d0%b8%d0%ba%d0%b0%d1%86%d0%b8%d1%8f">#</a>
</h3>
<p>Для работы с API Gitea требуется аутентификация с использованием токена доступа. Создайте токен в настройках вашего профиля Gitea.</p>
<h3 class="heading" id="пример-использования-api">
  Пример использования API
  <a class="anchor" href="#%d0%bf%d1%80%d0%b8%d0%bc%d0%b5%d1%80-%d0%b8%d1%81%d0%bf%d0%be%d0%bb%d1%8c%d0%b7%d0%be%d0%b2%d0%b0%d0%bd%d0%b8%d1%8f-api">#</a>
</h3>
<h4 class="heading" id="получение-списка-репозиториев">
  Получение списка репозиториев
  <a class="anchor" href="#%d0%bf%d0%be%d0%bb%d1%83%d1%87%d0%b5%d0%bd%d0%b8%d0%b5-%d1%81%d0%bf%d0%b8%d1%81%d0%ba%d0%b0-%d1%80%d0%b5%d0%bf%d0%be%d0%b7%d0%b8%d1%82%d0%be%d1%80%d0%b8%d0%b5%d0%b2">#</a>
</h4>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">curl -H <span class="s2">&#34;Authorization: token YOUR_TOKEN&#34;</span> <span class="se">\
</span></span></span><span class="line"><span class="cl">    https://gitea.example.com/api/v1/user/repos</span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<h4 class="heading" id="создание-нового-репозитория">
  Создание нового репозитория
  <a class="anchor" href="#%d1%81%d0%be%d0%b7%d0%b4%d0%b0%d0%bd%d0%b8%d0%b5-%d0%bd%d0%be%d0%b2%d0%be%d0%b3%d0%be-%d1%80%d0%b5%d0%bf%d0%be%d0%b7%d0%b8%d1%82%d0%be%d1%80%d0%b8%d1%8f">#</a>
</h4>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">curl -X POST -H <span class="s2">&#34;Authorization: token YOUR_TOKEN&#34;</span> <span class="se">\
</span></span></span><span class="line"><span class="cl">    -H <span class="s2">&#34;Content-Type: application/json&#34;</span> <span class="se">\
</span></span></span><span class="line"><span class="cl">    -d <span class="s1">&#39;{&#34;name&#34;: &#34;new-repo&#34;}&#39;</span> <span class="se">\
</span></span></span><span class="line"><span class="cl">    https://gitea.example.com/api/v1/user/repos</span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<h2 class="heading" id="-автоматизация-с-использованием-api">
  🛠️ Автоматизация с использованием API
  <a class="anchor" href="#-%d0%b0%d0%b2%d1%82%d0%be%d0%bc%d0%b0%d1%82%d0%b8%d0%b7%d0%b0%d1%86%d0%b8%d1%8f-%d1%81-%d0%b8%d1%81%d0%bf%d0%be%d0%bb%d1%8c%d0%b7%d0%be%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5%d0%bc-api">#</a>
</h2>
<h3 class="heading" id="создание-скрипта-для-автоматизации">
  Создание скрипта для автоматизации
  <a class="anchor" href="#%d1%81%d0%be%d0%b7%d0%b4%d0%b0%d0%bd%d0%b8%d0%b5-%d1%81%d0%ba%d1%80%d0%b8%d0%bf%d1%82%d0%b0-%d0%b4%d0%bb%d1%8f-%d0%b0%d0%b2%d1%82%d0%be%d0%bc%d0%b0%d1%82%d0%b8%d0%b7%d0%b0%d1%86%d0%b8%d0%b8">#</a>
</h3>
<p>Пример скрипта на Python для автоматизации создания репозитория:</p>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">requests</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Настройки</span>
</span></span><span class="line"><span class="cl"><span class="n">api_url</span><span class="p">:</span> <span class="s2">&#34;https://gitea.example.com/api/v1/user/repos&#34;</span>
</span></span><span class="line"><span class="cl"><span class="n">token</span><span class="p">:</span> <span class="s2">&#34;YOUR_TOKEN&#34;</span>
</span></span><span class="line"><span class="cl"><span class="n">headers</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;Authorization&#34;</span><span class="p">:</span> <span class="sa">f</span><span class="s2">&#34;token </span><span class="si">{</span><span class="n">token</span><span class="si">}</span><span class="s2">&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;Content-Type&#34;</span><span class="p">:</span> <span class="s2">&#34;application/json&#34;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="n">data</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;name&#34;</span><span class="p">:</span> <span class="s2">&#34;automated-repo&#34;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Создание репозитория</span>
</span></span><span class="line"><span class="cl"><span class="n">response</span><span class="p">:</span> <span class="n">requests</span><span class="o">.</span><span class="n">post</span><span class="p">(</span><span class="n">api_url</span><span class="p">,</span> <span class="n">headers</span><span class="o">=</span><span class="n">headers</span><span class="p">,</span> <span class="n">json</span><span class="o">=</span><span class="n">data</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">if</span> <span class="n">response</span><span class="o">.</span><span class="n">status_code</span> <span class="o">==</span> <span class="mi">201</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    <span class="nb">print</span><span class="p">(</span><span class="s2">&#34;Репозиторий успешно создан!&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="k">else</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    <span class="nb">print</span><span class="p">(</span><span class="s2">&#34;Ошибка при создании репозитория:&#34;</span><span class="p">,</span> <span class="n">response</span><span class="o">.</span><span class="n">json</span><span class="p">())</span></span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<h2 class="heading" id="-заключение">
  📚 Заключение
  <a class="anchor" href="#-%d0%b7%d0%b0%d0%ba%d0%bb%d1%8e%d1%87%d0%b5%d0%bd%d0%b8%d0%b5">#</a>
</h2>
<p>Использование API Gitea позволяет автоматизировать и интегрировать процессы, делая вашу работу более эффективной и гибкой. Это мощный инструмент для создания кастомных решений и улучшения рабочих процессов.</p>
]]></content:encoded><category>Gitea</category><category>API</category><category>Автоматизация</category></item><item><title>🚀 Hugo v0.140.0: Новые возможности для JavaScript и исправления ошибок</title><link>https://kushnaren.co/posts/2024-12-17-hugo-v0.140.0/</link><pubDate>Tue, 17 Dec 2024 00:00:00 +0000</pubDate><guid isPermaLink="true">https://kushnaren.co/posts/2024-12-17-hugo-v0.140.0/</guid><description>Обзор нового релиза Hugo v0.140.0 с функцией js.Batch для управления JavaScript-файлами и множеством улучшений</description><content:encoded><![CDATA[<h2 class="heading" id="-введение">
  🌟 Введение
  <a class="anchor" href="#-%d0%b2%d0%b2%d0%b5%d0%b4%d0%b5%d0%bd%d0%b8%d0%b5">#</a>
</h2>
<p>Hugo продолжает развиваться и совершенствоваться. В новой версии v0.140.0 разработчики представили важное нововведение для работы с JavaScript, а также внесли множество улучшений и исправлений. Давайте подробно рассмотрим, что нового появилось в этом релизе.</p>
<h2 class="heading" id="-главное-нововведение-jsbatch">
  🔥 Главное нововведение: js.Batch
  <a class="anchor" href="#-%d0%b3%d0%bb%d0%b0%d0%b2%d0%bd%d0%be%d0%b5-%d0%bd%d0%be%d0%b2%d0%be%d0%b2%d0%b2%d0%b5%d0%b4%d0%b5%d0%bd%d0%b8%d0%b5-jsbatch">#</a>
</h2>
<p>Ключевым обновлением в Hugo v0.140.0 стала функция <code>js.Batch</code>. Это мощный инструмент для организации JavaScript-кода, который предоставляет следующие возможности:</p>
<ul>
<li>Создание групп JavaScript-файлов для разных разделов сайта</li>
<li>Глобальное разделение кода между группами</li>
<li>Гибкая настройка хуков и порядка выполнения</li>
<li>Эффективное управление зависимостями</li>
</ul>
<p>Эта функция особенно полезна при разработке сложных сайтов, где требуется четкая организация JavaScript-кода и оптимизация его загрузки.</p>
<h2 class="heading" id="-исправления-ошибок">
  🛠 Исправления ошибок
  <a class="anchor" href="#-%d0%b8%d1%81%d0%bf%d1%80%d0%b0%d0%b2%d0%bb%d0%b5%d0%bd%d0%b8%d1%8f-%d0%be%d1%88%d0%b8%d0%b1%d0%be%d0%ba">#</a>
</h2>
<p>В этом релизе было исправлено несколько важных ошибок:</p>
<h3 class="heading" id="стабильность-и-производительность">
  Стабильность и производительность
  <a class="anchor" href="#%d1%81%d1%82%d0%b0%d0%b1%d0%b8%d0%bb%d1%8c%d0%bd%d0%be%d1%81%d1%82%d1%8c-%d0%b8-%d0%bf%d1%80%d0%be%d0%b8%d0%b7%d0%b2%d0%be%d0%b4%d0%b8%d1%82%d0%b5%d0%bb%d1%8c%d0%bd%d0%be%d1%81%d1%82%d1%8c">#</a>
</h3>
<ul>
<li>✅ Устранена паника при перестроении сервера при использовании базовых шаблонов с <code>template.Defer</code></li>
<li>✅ Улучшена работа <code>js.Batch</code> в конфигурациях с несколькими сайтами</li>
<li>✅ Исправлены проблемы с перестроением при переименовании ресурсов</li>
</ul>
<h3 class="heading" id="форматирование-и-парсинг">
  Форматирование и парсинг
  <a class="anchor" href="#%d1%84%d0%be%d1%80%d0%bc%d0%b0%d1%82%d0%b8%d1%80%d0%be%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5-%d0%b8-%d0%bf%d0%b0%d1%80%d1%81%d0%b8%d0%bd%d0%b3">#</a>
</h3>
<ul>
<li>✅ Корректная работа разделителя аннотаций в Org Mode</li>
<li>✅ Исправлен атрибут <code>title</code> в шорткоде <code>details</code></li>
<li>✅ Улучшен парсинг текста в хуке рендеринга цитат</li>
</ul>
<h3 class="heading" id="работа-с-ресурсами">
  Работа с ресурсами
  <a class="anchor" href="#%d1%80%d0%b0%d0%b1%d0%be%d1%82%d0%b0-%d1%81-%d1%80%d0%b5%d1%81%d1%83%d1%80%d1%81%d0%b0%d0%bc%d0%b8">#</a>
</h3>
<ul>
<li>✅ Правильная обработка импортов Sass для файлов формата <code>index.{scss,sass}</code></li>
</ul>
<h2 class="heading" id="-улучшения-и-новые-возможности">
  💡 Улучшения и новые возможности
  <a class="anchor" href="#-%d1%83%d0%bb%d1%83%d1%87%d1%88%d0%b5%d0%bd%d0%b8%d1%8f-%d0%b8-%d0%bd%d0%be%d0%b2%d1%8b%d0%b5-%d0%b2%d0%be%d0%b7%d0%bc%d0%be%d0%b6%d0%bd%d0%be%d1%81%d1%82%d0%b8">#</a>
</h2>
<h3 class="heading" id="обновления-esbuild">
  Обновления esbuild
  <a class="anchor" href="#%d0%be%d0%b1%d0%bd%d0%be%d0%b2%d0%bb%d0%b5%d0%bd%d0%b8%d1%8f-esbuild">#</a>
</h3>
<ul>
<li>🆕 Добавлена поддержка цели <code>es2024</code></li>
<li>🆕 Возможность запуска после выполнения скриптов</li>
<li>🆕 Оптимизированное построение групп в порядке идентификаторов</li>
</ul>
<h3 class="heading" id="улучшения-шорткодов-и-функций">
  Улучшения шорткодов и функций
  <a class="anchor" href="#%d1%83%d0%bb%d1%83%d1%87%d1%88%d0%b5%d0%bd%d0%b8%d1%8f-%d1%88%d0%be%d1%80%d1%82%d0%ba%d0%be%d0%b4%d0%be%d0%b2-%d0%b8-%d1%84%d1%83%d0%bd%d0%ba%d1%86%d0%b8%d0%b9">#</a>
</h3>
<ul>
<li>📦 Обновлены шорткоды <code>youtube</code> и <code>details</code></li>
<li>📦 В функцию <code>querify</code> добавлена поддержка аргумента типа <code>map</code></li>
<li>📦 Добавлен новый шорткод <code>details</code> в <code>tpl/tplimpl</code></li>
</ul>
<h3 class="heading" id="оптимизация-jsbatch">
  Оптимизация js.Batch
  <a class="anchor" href="#%d0%be%d0%bf%d1%82%d0%b8%d0%bc%d0%b8%d0%b7%d0%b0%d1%86%d0%b8%d1%8f-jsbatch">#</a>
</h3>
<ul>
<li>🔧 Предотвращение создания пустого среза <code>Instances</code></li>
<li>🔧 Улучшенная интеграция с многосайтовыми конфигурациями</li>
</ul>
<h2 class="heading" id="-заключение">
  📝 Заключение
  <a class="anchor" href="#-%d0%b7%d0%b0%d0%ba%d0%bb%d1%8e%d1%87%d0%b5%d0%bd%d0%b8%d0%b5">#</a>
</h2>
<p>Hugo v0.140.0 представляет собой важное обновление, которое значительно улучшает работу с JavaScript и исправляет множество ошибок. Новая функция <code>js.Batch</code> открывает дополнительные возможности для организации и оптимизации JavaScript-кода на сайтах, построенных с помощью Hugo.</p>
<p>Рекомендуется обновиться до новой версии, особенно если вы активно используете JavaScript в своих проектах или сталкивались с какими-либо из исправленных ошибок.</p>
<p>Для получения более подробной информации и загрузки новой версии посетите <a href="https://github.com/gohugoio/hugo/releases/tag/v0.140.0">официальную страницу релиза</a> на GitHub.</p>
<h2 class="heading" id="-версия-01440">
  🚀 Версия 0.144.0
  <a class="anchor" href="#-%d0%b2%d0%b5%d1%80%d1%81%d0%b8%d1%8f-01440">#</a>
</h2>
<p>Это крупное обновление Hugo, выпущенное незадолго до 19 февраля 2025 года, принесло ряд важных изменений и улучшений:</p>
<h3 class="heading" id="-новые-возможности">
  🎯 Новые возможности
  <a class="anchor" href="#-%d0%bd%d0%be%d0%b2%d1%8b%d0%b5-%d0%b2%d0%be%d0%b7%d0%bc%d0%be%d0%b6%d0%bd%d0%be%d1%81%d1%82%d0%b8">#</a>
</h3>
<ul>
<li>Добавлены новые токены для постоянных ссылок: <code>:contentbasename</code> и <code>:slugorcontentbasename</code> (заменяют устаревшие <code>:filename</code> и <code>:slugorfilename</code>)</li>
<li>Введена настройка <code>parser.autoDefinitionTermID</code> для автоматического добавления атрибутов <code>id</code> к элементам <code>dt</code> в списках определений</li>
<li>Добавлена поддержка меню в виде карт (maps) в адаптерах контента</li>
<li>Реализована опция <code>drop</code> для js.esbuild</li>
<li>Добавлена поддержка <code>GOAUTH</code> в конфигурации модулей</li>
</ul>
<h3 class="heading" id="-исправления-ошибок-1">
  🐛 Исправления ошибок
  <a class="anchor" href="#-%d0%b8%d1%81%d0%bf%d1%80%d0%b0%d0%b2%d0%bb%d0%b5%d0%bd%d0%b8%d1%8f-%d0%be%d1%88%d0%b8%d0%b1%d0%be%d0%ba-1">#</a>
</h3>
<ul>
<li>Исправлена паника при обработке пустых заголовков Markdown</li>
<li>Устранена проблема с позиционированием для проходных хуков</li>
<li>Исправлена ошибка, когда <code>server.redirects.fromRe</code> игнорировался, если не был установлен <code>server.redirects.from</code></li>
<li>Улучшено сообщение об ошибке для самозакрывающихся шорткодов без <code>.Inner</code></li>
</ul>
<h3 class="heading" id="-улучшения">
  ⚡ Улучшения
  <a class="anchor" href="#-%d1%83%d0%bb%d1%83%d1%87%d1%88%d0%b5%d0%bd%d0%b8%d1%8f">#</a>
</h3>
<ul>
<li>Обновлен Go до версии 1.24</li>
<li>Улучшена обработка автоматически генерируемых ID заголовков</li>
<li>Добавлена поддержка autoID для терминов определений</li>
<li>Включено расширение KaTeX mhchem</li>
<li>Добавлены новые опции сервера</li>
</ul>
<h3 class="heading" id="-устаревания">
  ⚠️ Устаревания
  <a class="anchor" href="#-%d1%83%d1%81%d1%82%d0%b0%d1%80%d0%b5%d0%b2%d0%b0%d0%bd%d0%b8%d1%8f">#</a>
</h3>
<ul>
<li>Объявлены устаревшими <code>kind</code>, <code>lang</code> и <code>path</code> во фронтматтере</li>
</ul>
<h2 class="heading" id="-версия-01441">
  🔧 Версия 0.144.1
  <a class="anchor" href="#-%d0%b2%d0%b5%d1%80%d1%81%d0%b8%d1%8f-01441">#</a>
</h2>
<p>Это небольшое обновление, выпущенное вскоре после 0.144.0, фокусируется на исправлении критической ошибки:</p>
<h3 class="heading" id="-исправление-ошибки">
  🐛 Исправление ошибки
  <a class="anchor" href="#-%d0%b8%d1%81%d0%bf%d1%80%d0%b0%d0%b2%d0%bb%d0%b5%d0%bd%d0%b8%d0%b5-%d0%be%d1%88%d0%b8%d0%b1%d0%ba%d0%b8">#</a>
</h3>
<ul>
<li>Устранена паника при обработке пустых заголовков Markdown</li>
</ul>
<p>Это обновление обеспечивает стабильность работы Hugo при обработке контента с пустыми заголовками, что особенно важно для больших проектов с разнообразным контентом.</p>
]]></content:encoded><category>Hugo</category><category>Релиз</category><category>Javascript</category><category>Web</category></item><item><title>🖥️ WezTerm: Современный GPU-ускоренный Терминал</title><link>https://kushnaren.co/posts/2024-12-05-terminal-wezterm-obzor/</link><pubDate>Thu, 05 Dec 2024 10:46:16 +0300</pubDate><guid isPermaLink="true">https://kushnaren.co/posts/2024-12-05-terminal-wezterm-obzor/</guid><description>Подробный обзор WezTerm - мощного терминального эмулятора с GPU-ускорением, мультиплексированием и конфигурацией на Lua</description><content:encoded><![CDATA[<h2 class="heading" id="-введение">
  🚀 Введение
  <a class="anchor" href="#-%d0%b2%d0%b2%d0%b5%d0%b4%d0%b5%d0%bd%d0%b8%d0%b5">#</a>
</h2>
<p>WezTerm - это мощный, современный терминальный эмулятор с открытым исходным кодом, написанный на Rust. Благодаря использованию GPU-ускорения и оптимизированному коду, он обеспечивает молниеносную производительность и плавную работу даже с большими объемами данных.</p>
<h2 class="heading" id="-ключевые-особенности">
  ✨ Ключевые особенности
  <a class="anchor" href="#-%d0%ba%d0%bb%d1%8e%d1%87%d0%b5%d0%b2%d1%8b%d0%b5-%d0%be%d1%81%d0%be%d0%b1%d0%b5%d0%bd%d0%bd%d0%be%d1%81%d1%82%d0%b8">#</a>
</h2>
<h3 class="heading" id="-мультиплексирование-и-вкладки">
  📑 Мультиплексирование и вкладки
  <a class="anchor" href="#-%d0%bc%d1%83%d0%bb%d1%8c%d1%82%d0%b8%d0%bf%d0%bb%d0%b5%d0%ba%d1%81%d0%b8%d1%80%d0%be%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5-%d0%b8-%d0%b2%d0%ba%d0%bb%d0%b0%d0%b4%d0%ba%d0%b8">#</a>
</h3>
<ul>
<li>Встроенная поддержка вкладок и разделения окон</li>
<li>Мультиплексирование без необходимости использования tmux</li>
<li>Удобное переключение между сессиями с помощью горячих клавиш</li>
<li>Сохранение и восстановление рабочих сессий</li>
</ul>
<h3 class="heading" id="-поддержка-gpu">
  🚄 Поддержка GPU
  <a class="anchor" href="#-%d0%bf%d0%be%d0%b4%d0%b4%d0%b5%d1%80%d0%b6%d0%ba%d0%b0-gpu">#</a>
</h3>
<ul>
<li>Аппаратное ускорение рендеринга текста</li>
<li>Плавная прокрутка и анимации без задержек</li>
<li>Эффективная работа с большими объемами текста</li>
<li>Поддержка OpenGL и DirectX</li>
</ul>
<h3 class="heading" id="-кастомизация">
  🎨 Кастомизация
  <a class="anchor" href="#-%d0%ba%d0%b0%d1%81%d1%82%d0%be%d0%bc%d0%b8%d0%b7%d0%b0%d1%86%d0%b8%d1%8f">#</a>
</h3>
<ul>
<li>Гибкая конфигурация на Lua</li>
<li>Поддержка пользовательских цветовых схем</li>
<li>Настраиваемые горячие клавиши и команды</li>
<li>Расширенные возможности стилизации</li>
</ul>
<h3 class="heading" id="-кроссплатформенность">
  🌍 Кроссплатформенность
  <a class="anchor" href="#-%d0%ba%d1%80%d0%be%d1%81%d1%81%d0%bf%d0%bb%d0%b0%d1%82%d1%84%d0%be%d1%80%d0%bc%d0%b5%d0%bd%d0%bd%d0%be%d1%81%d1%82%d1%8c">#</a>
</h3>
<ul>
<li>Нативная поддержка macOS, Linux и Windows</li>
<li>Единообразный опыт на всех платформах</li>
<li>Поддержка различных shell’ов</li>
<li>Интеграция с системными возможностями</li>
</ul>
<h2 class="heading" id="-установка">
  🛠️ Установка
  <a class="anchor" href="#-%d1%83%d1%81%d1%82%d0%b0%d0%bd%d0%be%d0%b2%d0%ba%d0%b0">#</a>
</h2>
<h3 class="heading" id="macos">
  macOS
  <a class="anchor" href="#macos">#</a>
</h3>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">brew install --cask wezterm</span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<h3 class="heading" id="linux">
  Linux
  <a class="anchor" href="#linux">#</a>
</h3>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">curl -LO https://github.com/wez/wezterm/releases/download/nightly/wezterm-nightly.Ubuntu20.04.deb
</span></span><span class="line"><span class="cl">sudo apt install ./wezterm-nightly.Ubuntu20.04.deb</span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<h3 class="heading" id="windows">
  Windows
  <a class="anchor" href="#windows">#</a>
</h3>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-powershell" data-lang="powershell"><span class="line"><span class="cl"><span class="n">winget</span> <span class="n">install</span> <span class="n">wez</span><span class="p">.</span><span class="n">wezterm</span></span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<h2 class="heading" id="-базовая-настройка">
  ⚙️ Базовая настройка
  <a class="anchor" href="#-%d0%b1%d0%b0%d0%b7%d0%be%d0%b2%d0%b0%d1%8f-%d0%bd%d0%b0%d1%81%d1%82%d1%80%d0%be%d0%b9%d0%ba%d0%b0">#</a>
</h2>
<ol>
<li>Создайте файл конфигурации:</li>
</ol>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">mkdir -p ~/.config/wezterm
</span></span><span class="line"><span class="cl">touch ~/.config/wezterm/wezterm.lua</span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<ol>
<li>Добавьте базовую конфигурацию:</li>
</ol>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-lua" data-lang="lua"><span class="line"><span class="cl"><span class="kd">local</span> <span class="n">wezterm</span> <span class="o">=</span> <span class="n">require</span> <span class="s1">&#39;wezterm&#39;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">return</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="c1">-- Шрифт и размер</span>
</span></span><span class="line"><span class="cl">  <span class="n">font</span> <span class="o">=</span> <span class="n">wezterm.font</span><span class="p">(</span><span class="s2">&#34;JetBrains Mono&#34;</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">  <span class="n">font_size</span> <span class="o">=</span> <span class="mf">14.0</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  
</span></span><span class="line"><span class="cl">  <span class="c1">-- Цветовая схема</span>
</span></span><span class="line"><span class="cl">  <span class="n">color_scheme</span> <span class="o">=</span> <span class="s2">&#34;Catppuccin Mocha&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  
</span></span><span class="line"><span class="cl">  <span class="c1">-- Настройки интерфейса</span>
</span></span><span class="line"><span class="cl">  <span class="n">enable_tab_bar</span> <span class="o">=</span> <span class="kc">true</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="n">use_fancy_tab_bar</span> <span class="o">=</span> <span class="kc">false</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="n">window_padding</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">left</span> <span class="o">=</span> <span class="mi">2</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">right</span> <span class="o">=</span> <span class="mi">2</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">top</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">bottom</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl">  
</span></span><span class="line"><span class="cl">  <span class="c1">-- Производительность</span>
</span></span><span class="line"><span class="cl">  <span class="n">animation_fps</span> <span class="o">=</span> <span class="mi">60</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="n">enable_wayland</span> <span class="o">=</span> <span class="kc">true</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="n">webgpu_preferred_adapter</span> <span class="o">=</span> <span class="n">wezterm.gpu_adapters</span><span class="p">.</span><span class="n">discrete</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<h2 class="heading" id="-горячие-клавиши">
  ⌨️ Горячие клавиши
  <a class="anchor" href="#-%d0%b3%d0%be%d1%80%d1%8f%d1%87%d0%b8%d0%b5-%d0%ba%d0%bb%d0%b0%d0%b2%d0%b8%d1%88%d0%b8">#</a>
</h2>
<h3 class="heading" id="буфер-обмена">
  Буфер обмена
  <a class="anchor" href="#%d0%b1%d1%83%d1%84%d0%b5%d1%80-%d0%be%d0%b1%d0%bc%d0%b5%d0%bd%d0%b0">#</a>
</h3>
<table>
	<thead>
			<tr>
					<th>Комбинация</th>
					<th>Действие</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td>⌘C / ⌃⇧C</td>
					<td>Копировать в буфер обмена</td>
			</tr>
			<tr>
					<td>⌘V / ⌃⇧V</td>
					<td>Вставить из буфера обмена</td>
			</tr>
			<tr>
					<td>⌃⇧X</td>
					<td>Активировать режим копирования</td>
			</tr>
	</tbody>
</table>
<h3 class="heading" id="управление-окнами">
  Управление окнами
  <a class="anchor" href="#%d1%83%d0%bf%d1%80%d0%b0%d0%b2%d0%bb%d0%b5%d0%bd%d0%b8%d0%b5-%d0%be%d0%ba%d0%bd%d0%b0%d0%bc%d0%b8">#</a>
</h3>
<table>
	<thead>
			<tr>
					<th>Комбинация</th>
					<th>Действие</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td>⌘N / ⌃⇧N</td>
					<td>Открыть новое окно</td>
			</tr>
			<tr>
					<td>⌘M</td>
					<td>Скрыть окно</td>
			</tr>
			<tr>
					<td>⌥↵</td>
					<td>Переключить полноэкранный режим</td>
			</tr>
			<tr>
					<td>⌘H</td>
					<td>Скрыть приложение (только macOS)</td>
			</tr>
	</tbody>
</table>
<h3 class="heading" id="управление-вкладками">
  Управление вкладками
  <a class="anchor" href="#%d1%83%d0%bf%d1%80%d0%b0%d0%b2%d0%bb%d0%b5%d0%bd%d0%b8%d0%b5-%d0%b2%d0%ba%d0%bb%d0%b0%d0%b4%d0%ba%d0%b0%d0%bc%d0%b8">#</a>
</h3>
<table>
	<thead>
			<tr>
					<th>Комбинация</th>
					<th>Действие</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td>⌘T / ⌃⇧T</td>
					<td>Открыть новую вкладку в текущем домене</td>
			</tr>
			<tr>
					<td>⌘⇧T</td>
					<td>Открыть новую вкладку в домене по умолчанию</td>
			</tr>
			<tr>
					<td>⌘W / ⌃⇧W</td>
					<td>Закрыть текущую вкладку</td>
			</tr>
			<tr>
					<td>⌘[число] / ⌃⇧[число]</td>
					<td>Переключиться на вкладку по номеру</td>
			</tr>
			<tr>
					<td>⌘⇧[ / ⌃⇧Tab</td>
					<td>Предыдущая вкладка</td>
			</tr>
			<tr>
					<td>⌘⇧] / ⌃Tab</td>
					<td>Следующая вкладка</td>
			</tr>
			<tr>
					<td>⌃PageUp</td>
					<td>Предыдущая вкладка</td>
			</tr>
			<tr>
					<td>⌃PageDown</td>
					<td>Следующая вкладка</td>
			</tr>
			<tr>
					<td>⌃⇧PageUp</td>
					<td>Переместить вкладку влево</td>
			</tr>
			<tr>
					<td>⌃⇧PageDown</td>
					<td>Переместить вкладку вправо</td>
			</tr>
	</tbody>
</table>
<h3 class="heading" id="разделение-панелей">
  Разделение панелей
  <a class="anchor" href="#%d1%80%d0%b0%d0%b7%d0%b4%d0%b5%d0%bb%d0%b5%d0%bd%d0%b8%d0%b5-%d0%bf%d0%b0%d0%bd%d0%b5%d0%bb%d0%b5%d0%b9">#</a>
</h3>
<table>
	<thead>
			<tr>
					<th>Комбинация</th>
					<th>Действие</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td>⌃⇧⌥&quot;</td>
					<td>Разделить панель вертикально</td>
			</tr>
			<tr>
					<td>⌃⇧⌥%</td>
					<td>Разделить панель горизонтально</td>
			</tr>
			<tr>
					<td>⌃⇧←→↑↓</td>
					<td>Активировать соседнюю панель</td>
			</tr>
			<tr>
					<td>⌃⇧Z</td>
					<td>Переключить увеличение панели</td>
			</tr>
	</tbody>
</table>
<h3 class="heading" id="размер-панелей">
  Размер панелей
  <a class="anchor" href="#%d1%80%d0%b0%d0%b7%d0%bc%d0%b5%d1%80-%d0%bf%d0%b0%d0%bd%d0%b5%d0%bb%d0%b5%d0%b9">#</a>
</h3>
<table>
	<thead>
			<tr>
					<th>Комбинация</th>
					<th>Действие</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td>⌃⇧⌥←</td>
					<td>Уменьшить размер панели влево</td>
			</tr>
			<tr>
					<td>⌃⇧⌥→</td>
					<td>Увеличить размер панели вправо</td>
			</tr>
			<tr>
					<td>⌃⇧⌥↑</td>
					<td>Уменьшить размер панели вверх</td>
			</tr>
			<tr>
					<td>⌃⇧⌥↓</td>
					<td>Увеличить размер панели вниз</td>
			</tr>
	</tbody>
</table>
<h3 class="heading" id="шрифт-и-отображение">
  Шрифт и отображение
  <a class="anchor" href="#%d1%88%d1%80%d0%b8%d1%84%d1%82-%d0%b8-%d0%be%d1%82%d0%be%d0%b1%d1%80%d0%b0%d0%b6%d0%b5%d0%bd%d0%b8%d0%b5">#</a>
</h3>
<table>
	<thead>
			<tr>
					<th>Комбинация</th>
					<th>Действие</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td>⌘-</td>
					<td>Уменьшить размер шрифта</td>
			</tr>
			<tr>
					<td>⌘=</td>
					<td>Увеличить размер шрифта</td>
			</tr>
			<tr>
					<td>⌘0</td>
					<td>Сбросить размер шрифта</td>
			</tr>
	</tbody>
</table>
<h3 class="heading" id="навигация-и-поиск">
  Навигация и поиск
  <a class="anchor" href="#%d0%bd%d0%b0%d0%b2%d0%b8%d0%b3%d0%b0%d1%86%d0%b8%d1%8f-%d0%b8-%d0%bf%d0%be%d0%b8%d1%81%d0%ba">#</a>
</h3>
<table>
	<thead>
			<tr>
					<th>Комбинация</th>
					<th>Действие</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td>⌘F / ⌃⇧F</td>
					<td>Поиск (с учетом регистра)</td>
			</tr>
			<tr>
					<td>⇧PageUp</td>
					<td>Пролистать на страницу вверх</td>
			</tr>
			<tr>
					<td>⇧PageDown</td>
					<td>Пролистать на страницу вниз</td>
			</tr>
			<tr>
					<td>⌘K / ⌃⇧K</td>
					<td>Очистить историю прокрутки</td>
			</tr>
	</tbody>
</table>
<h3 class="heading" id="дополнительные-функции">
  Дополнительные функции
  <a class="anchor" href="#%d0%b4%d0%be%d0%bf%d0%be%d0%bb%d0%bd%d0%b8%d1%82%d0%b5%d0%bb%d1%8c%d0%bd%d1%8b%d0%b5-%d1%84%d1%83%d0%bd%d0%ba%d1%86%d0%b8%d0%b8">#</a>
</h3>
<table>
	<thead>
			<tr>
					<th>Комбинация</th>
					<th>Действие</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td>⌘R / ⌃⇧R</td>
					<td>Перезагрузить конфигурацию</td>
			</tr>
			<tr>
					<td>⌃⇧L</td>
					<td>Показать отладочный оверлей</td>
			</tr>
			<tr>
					<td>⌃⇧P</td>
					<td>Активировать палитру команд</td>
			</tr>
			<tr>
					<td>⌃⇧U</td>
					<td>Открыть выбор символов</td>
			</tr>
			<tr>
					<td>⌃⇧Space</td>
					<td>Быстрый выбор</td>
			</tr>
	</tbody>
</table>
<blockquote>
<p>💡 <strong>Примечание</strong>: Все горячие клавиши можно настроить в конфигурационном файле. На macOS доступны комбинации с ⌘, на других системах используйте ⌃⇧.</p>
</blockquote>
<h2 class="heading" id="-преимущества">
  🏆 Преимущества
  <a class="anchor" href="#-%d0%bf%d1%80%d0%b5%d0%b8%d0%bc%d1%83%d1%89%d0%b5%d1%81%d1%82%d0%b2%d0%b0">#</a>
</h2>
<h3 class="heading" id="1-производительность">
  1. Производительность
  <a class="anchor" href="#1-%d0%bf%d1%80%d0%be%d0%b8%d0%b7%d0%b2%d0%be%d0%b4%d0%b8%d1%82%d0%b5%d0%bb%d1%8c%d0%bd%d0%be%d1%81%d1%82%d1%8c">#</a>
</h3>
<ul>
<li>🚀 GPU-ускорение для плавной работы</li>
<li>⚡ Минимальная задержка ввода</li>
<li>📊 Эффективное использование ресурсов</li>
<li>🔄 Оптимизированный рендеринг</li>
</ul>
<h3 class="heading" id="2-функциональность">
  2. Функциональность
  <a class="anchor" href="#2-%d1%84%d1%83%d0%bd%d0%ba%d1%86%d0%b8%d0%be%d0%bd%d0%b0%d0%bb%d1%8c%d0%bd%d0%be%d1%81%d1%82%d1%8c">#</a>
</h3>
<ul>
<li>📑 Встроенное мультиплексирование</li>
<li>🖼️ Поддержка изображений в терминале</li>
<li>🔤 Лигатуры и эмодзи</li>
<li>🔍 Встроенный поиск</li>
</ul>
<h3 class="heading" id="3-настраиваемость">
  3. Настраиваемость
  <a class="anchor" href="#3-%d0%bd%d0%b0%d1%81%d1%82%d1%80%d0%b0%d0%b8%d0%b2%d0%b0%d0%b5%d0%bc%d0%be%d1%81%d1%82%d1%8c">#</a>
</h3>
<ul>
<li>⚙️ Мощный конфигурационный язык</li>
<li>🎨 Широкие возможности кастомизации</li>
<li>🔌 Поддержка плагинов</li>
<li>🎯 Гибкие правила</li>
</ul>
<h3 class="heading" id="4-стабильность">
  4. Стабильность
  <a class="anchor" href="#4-%d1%81%d1%82%d0%b0%d0%b1%d0%b8%d0%bb%d1%8c%d0%bd%d0%be%d1%81%d1%82%d1%8c">#</a>
</h3>
<ul>
<li>🛡️ Написан на безопасном Rust</li>
<li>📈 Активная разработка</li>
<li>👥 Большое сообщество</li>
<li>🔒 Регулярные обновления</li>
</ul>
<h2 class="heading" id="-заключение">
  📝 Заключение
  <a class="anchor" href="#-%d0%b7%d0%b0%d0%ba%d0%bb%d1%8e%d1%87%d0%b5%d0%bd%d0%b8%d0%b5">#</a>
</h2>
<p>WezTerm представляет собой современное решение для разработчиков, системных администраторов и power-users, которым важна производительность, гибкость и удобство работы в терминале. Благодаря GPU-ускорению, мощной системе конфигурации на Lua и активному развитию, WezTerm становится все более популярным выбором среди профессионалов.</p>
<p>Попробуйте WezTerm, если вы ищете:</p>
<ul>
<li>🚀 Максимальную производительность</li>
<li>🎨 Гибкую настройку</li>
<li>📑 Встроенное мультиплексирование</li>
<li>🌍 Кроссплатформенность</li>
<li>🛡️ Надежность и стабильность</li>
</ul>
]]></content:encoded><category>Терминал</category><category>Инструменты Разработчика</category><category>Производительность</category><category>Macos</category><category>Linux</category><category>Windows</category><category>Rust</category><category>GPU</category><category>Shell</category></item><item><title>🌊 Windsurf IDE: Революционная Среда Разработки с AI-Ассистентом</title><link>https://kushnaren.co/posts/2024-12-05-windsurf-ide-review/</link><pubDate>Thu, 05 Dec 2024 00:00:00 +0000</pubDate><guid isPermaLink="true">https://kushnaren.co/posts/2024-12-05-windsurf-ide-review/</guid><description>Обзор Windsurf IDE - новой среды разработки с встроенным AI-ассистентом Cascade, особенности, преимущества и опыт использования</description><content:encoded><![CDATA[<h2 class="heading" id="-введение">
  🎯 Введение
  <a class="anchor" href="#-%d0%b2%d0%b2%d0%b5%d0%b4%d0%b5%d0%bd%d0%b8%d0%b5">#</a>
</h2>
<p>В мире разработки программного обеспечения появился новый игрок - Windsurf IDE. Это не просто еще одна среда разработки, а революционный инструмент, который интегрирует в себя мощного AI-ассистента Cascade. В этой статье мы рассмотрим основные особенности Windsurf и то, как он может изменить процесс разработки.</p>
<h2 class="heading" id="-что-такое-windsurf-ide">
  🤖 Что такое Windsurf IDE
  <a class="anchor" href="#-%d1%87%d1%82%d0%be-%d1%82%d0%b0%d0%ba%d0%be%d0%b5-windsurf-ide">#</a>
</h2>
<p>Windsurf - это первая в мире агентная среда разработки (IDE), созданная с фокусом на взаимодействие с искусственным интеллектом. Главная особенность Windsurf - это встроенный AI-ассистент Cascade, разработанный командой Codeium, который работает на основе революционной парадигмы AI Flow.</p>
<h2 class="heading" id="-ключевые-особенности">
  💡 Ключевые особенности
  <a class="anchor" href="#-%d0%ba%d0%bb%d1%8e%d1%87%d0%b5%d0%b2%d1%8b%d0%b5-%d0%be%d1%81%d0%be%d0%b1%d0%b5%d0%bd%d0%bd%d0%be%d1%81%d1%82%d0%b8">#</a>
</h2>
<h3 class="heading" id="ai-ассистент-cascade">
  AI-ассистент Cascade
  <a class="anchor" href="#ai-%d0%b0%d1%81%d1%81%d0%b8%d1%81%d1%82%d0%b5%d0%bd%d1%82-cascade">#</a>
</h3>
<ul>
<li>Понимает контекст проекта и может работать как с существующим кодом, так и создавать новые проекты</li>
<li>Способен самостоятельно анализировать кодовую базу</li>
<li>Предлагает решения на основе лучших практик программирования</li>
<li>Работает в режиме парного программирования</li>
</ul>
<h3 class="heading" id="интеграция-с-проектом">
  Интеграция с проектом
  <a class="anchor" href="#%d0%b8%d0%bd%d1%82%d0%b5%d0%b3%d1%80%d0%b0%d1%86%d0%b8%d1%8f-%d1%81-%d0%bf%d1%80%d0%be%d0%b5%d0%ba%d1%82%d0%be%d0%bc">#</a>
</h3>
<ul>
<li>Глубокое понимание структуры проекта</li>
<li>Автоматический анализ зависимостей</li>
<li>Умное автодополнение кода</li>
<li>Рефакторинг с учетом всего контекста</li>
</ul>
<h3 class="heading" id="пользовательский-опыт">
  Пользовательский опыт
  <a class="anchor" href="#%d0%bf%d0%be%d0%bb%d1%8c%d0%b7%d0%be%d0%b2%d0%b0%d1%82%d0%b5%d0%bb%d1%8c%d1%81%d0%ba%d0%b8%d0%b9-%d0%be%d0%bf%d1%8b%d1%82">#</a>
</h3>
<ul>
<li>Современный и интуитивный интерфейс</li>
<li>Быстрый отклик системы</li>
<li>Удобная навигация по проекту</li>
<li>Встроенные инструменты для работы с git</li>
</ul>
<h2 class="heading" id="-как-работает-ai-flow">
  🔧 Как работает AI Flow
  <a class="anchor" href="#-%d0%ba%d0%b0%d0%ba-%d1%80%d0%b0%d0%b1%d0%be%d1%82%d0%b0%d0%b5%d1%82-ai-flow">#</a>
</h2>
<p>AI Flow - это новая парадигма взаимодействия с искусственным интеллектом в процессе разработки. Она позволяет:</p>
<ul>
<li>Вести естественный диалог с AI-ассистентом</li>
<li>Получать контекстно-зависимые предложения</li>
<li>Автоматизировать рутинные задачи</li>
<li>Получать объяснения предлагаемых решений</li>
</ul>
<h2 class="heading" id="-преимущества-использования">
  💪 Преимущества использования
  <a class="anchor" href="#-%d0%bf%d1%80%d0%b5%d0%b8%d0%bc%d1%83%d1%89%d0%b5%d1%81%d1%82%d0%b2%d0%b0-%d0%b8%d1%81%d0%bf%d0%be%d0%bb%d1%8c%d0%b7%d0%be%d0%b2%d0%b0%d0%bd%d0%b8%d1%8f">#</a>
</h2>
<h3 class="heading" id="для-разработчиков">
  Для разработчиков
  <a class="anchor" href="#%d0%b4%d0%bb%d1%8f-%d1%80%d0%b0%d0%b7%d1%80%d0%b0%d0%b1%d0%be%d1%82%d1%87%d0%b8%d0%ba%d0%be%d0%b2">#</a>
</h3>
<ul>
<li>Ускорение процесса разработки</li>
<li>Уменьшение количества ошибок</li>
<li>Автоматизация рутинных задач</li>
<li>Обучение лучшим практикам</li>
</ul>
<h3 class="heading" id="для-команд">
  Для команд
  <a class="anchor" href="#%d0%b4%d0%bb%d1%8f-%d0%ba%d0%be%d0%bc%d0%b0%d0%bd%d0%b4">#</a>
</h3>
<ul>
<li>Улучшение качества кода</li>
<li>Единый стиль кодирования</li>
<li>Быстрая адаптация новых членов команды</li>
<li>Эффективное решение сложных задач</li>
</ul>
<h2 class="heading" id="-примеры-использования">
  🎓 Примеры использования
  <a class="anchor" href="#-%d0%bf%d1%80%d0%b8%d0%bc%d0%b5%d1%80%d1%8b-%d0%b8%d1%81%d0%bf%d0%be%d0%bb%d1%8c%d0%b7%d0%be%d0%b2%d0%b0%d0%bd%d0%b8%d1%8f">#</a>
</h2>
<h3 class="heading" id="создание-нового-проекта">
  Создание нового проекта
  <a class="anchor" href="#%d1%81%d0%be%d0%b7%d0%b4%d0%b0%d0%bd%d0%b8%d0%b5-%d0%bd%d0%be%d0%b2%d0%be%d0%b3%d0%be-%d0%bf%d1%80%d0%be%d0%b5%d0%ba%d1%82%d0%b0">#</a>
</h3>
<p>Windsurf может помочь с:</p>
<ul>
<li>Генерацией базовой структуры проекта</li>
<li>Настройкой зависимостей</li>
<li>Созданием конфигурационных файлов</li>
<li>Написанием базовой документации</li>
</ul>
<h3 class="heading" id="рефакторинг-существующего-кода">
  Рефакторинг существующего кода
  <a class="anchor" href="#%d1%80%d0%b5%d1%84%d0%b0%d0%ba%d1%82%d0%be%d1%80%d0%b8%d0%bd%d0%b3-%d1%81%d1%83%d1%89%d0%b5%d1%81%d1%82%d0%b2%d1%83%d1%8e%d1%89%d0%b5%d0%b3%d0%be-%d0%ba%d0%be%d0%b4%d0%b0">#</a>
</h3>
<p>AI-ассистент способен:</p>
<ul>
<li>Анализировать качество кода</li>
<li>Предлагать улучшения</li>
<li>Находить потенциальные проблемы</li>
<li>Оптимизировать производительность</li>
</ul>
<h2 class="heading" id="-будущее-развития">
  📈 Будущее развития
  <a class="anchor" href="#-%d0%b1%d1%83%d0%b4%d1%83%d1%89%d0%b5%d0%b5-%d1%80%d0%b0%d0%b7%d0%b2%d0%b8%d1%82%d0%b8%d1%8f">#</a>
</h2>
<p>Windsurf IDE находится в активной разработке, и команда постоянно работает над:</p>
<ul>
<li>Улучшением возможностей AI-ассистента</li>
<li>Добавлением новых функций</li>
<li>Оптимизацией производительности</li>
<li>Расширением поддержки языков и фреймворков</li>
</ul>
<h2 class="heading" id="-заключение">
  🎯 Заключение
  <a class="anchor" href="#-%d0%b7%d0%b0%d0%ba%d0%bb%d1%8e%d1%87%d0%b5%d0%bd%d0%b8%d0%b5">#</a>
</h2>
<p>Windsurf IDE представляет собой значительный шаг вперед в развитии инструментов разработки. Интеграция AI-ассистента Cascade и использование парадигмы AI Flow создают уникальный опыт разработки, который может существенно повысить продуктивность программистов и качество создаваемого кода.</p>
<p>Если вы ищете современную среду разработки, которая не только предоставляет стандартный набор инструментов, но и активно помогает в процессе написания кода, Windsurf определенно заслуживает вашего внимания.</p>
]]></content:encoded><category>Разработка</category><category>Ide</category><category>Ai</category><category>Инструменты</category></item><item><title>✍️ Типографика Markdown: Полное Руководство</title><link>https://kushnaren.co/posts/2024-11-11-typography-markdown/</link><pubDate>Mon, 11 Nov 2024 10:00:00 +0300</pubDate><guid isPermaLink="true">https://kushnaren.co/posts/2024-11-11-typography-markdown/</guid><description>Comprehensive гайд по форматированию текста с помощью Markdown</description><content:encoded><![CDATA[<h1 class="heading" id="полное-руководство-по-типографике-в-markdown">
  Полное руководство по типографике в Markdown
  <a class="anchor" href="#%d0%bf%d0%be%d0%bb%d0%bd%d0%be%d0%b5-%d1%80%d1%83%d0%ba%d0%be%d0%b2%d0%be%d0%b4%d1%81%d1%82%d0%b2%d0%be-%d0%bf%d0%be-%d1%82%d0%b8%d0%bf%d0%be%d0%b3%d1%80%d0%b0%d1%84%d0%b8%d0%ba%d0%b5-%d0%b2-markdown">#</a>
</h1>
<h2 class="heading" id="-введение-в-markdown-typography">
  🔤 Введение в Markdown Typography
  <a class="anchor" href="#-%d0%b2%d0%b2%d0%b5%d0%b4%d0%b5%d0%bd%d0%b8%d0%b5-%d0%b2-markdown-typography">#</a>
</h2>
<p>Markdown - это легкий язык разметки, который позволяет форматировать текст с минимальными усилиями. Этот гайд покажет все возможности типографики.</p>
<h2 class="heading" id="-основы-форматирования-текста">
  📝 Основы форматирования текста
  <a class="anchor" href="#-%d0%be%d1%81%d0%bd%d0%be%d0%b2%d1%8b-%d1%84%d0%be%d1%80%d0%bc%d0%b0%d1%82%d0%b8%d1%80%d0%be%d0%b2%d0%b0%d0%bd%d0%b8%d1%8f-%d1%82%d0%b5%d0%ba%d1%81%d1%82%d0%b0">#</a>
</h2>
<h3 class="heading" id="синтаксис-заголовков">
  Синтаксис Заголовков
  <a class="anchor" href="#%d1%81%d0%b8%d0%bd%d1%82%d0%b0%d0%ba%d1%81%d0%b8%d1%81-%d0%b7%d0%b0%d0%b3%d0%be%d0%bb%d0%be%d0%b2%d0%ba%d0%be%d0%b2">#</a>
</h3>
<p>Markdown поддерживает 6 уровней заголовков:</p>
<h4 class="heading" id="пример-синтаксиса">
  Пример Синтаксиса
  <a class="anchor" href="#%d0%bf%d1%80%d0%b8%d0%bc%d0%b5%d1%80-%d1%81%d0%b8%d0%bd%d1%82%d0%b0%d0%ba%d1%81%d0%b8%d1%81%d0%b0">#</a>
</h4>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="cl"><span class="gu">## Заголовок второго уровня
</span></span></span><span class="line"><span class="cl"><span class="gu">### Заголовок третьего уровня
</span></span></span><span class="line"><span class="cl"><span class="gu">#### Заголовок четвертого уровня
</span></span></span><span class="line"><span class="cl"><span class="gu">##### Заголовок пятого уровня
</span></span></span><span class="line"><span class="cl">###### Заголовок шестого уровня</span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<h4 class="heading" id="визуальное-представление-заголовков">
  Визуальное Представление Заголовков
  <a class="anchor" href="#%d0%b2%d0%b8%d0%b7%d1%83%d0%b0%d0%bb%d1%8c%d0%bd%d0%be%d0%b5-%d0%bf%d1%80%d0%b5%d0%b4%d1%81%d1%82%d0%b0%d0%b2%d0%bb%d0%b5%d0%bd%d0%b8%d0%b5-%d0%b7%d0%b0%d0%b3%d0%be%d0%bb%d0%be%d0%b2%d0%ba%d0%be%d0%b2">#</a>
</h4>
<h2 class="heading" id="заголовок-второго-уровня">
  Заголовок второго уровня
  <a class="anchor" href="#%d0%b7%d0%b0%d0%b3%d0%be%d0%bb%d0%be%d0%b2%d0%be%d0%ba-%d0%b2%d1%82%d0%be%d1%80%d0%be%d0%b3%d0%be-%d1%83%d1%80%d0%be%d0%b2%d0%bd%d1%8f">#</a>
</h2>
<h3 class="heading" id="заголовок-третьего-уровня">
  Заголовок третьего уровня
  <a class="anchor" href="#%d0%b7%d0%b0%d0%b3%d0%be%d0%bb%d0%be%d0%b2%d0%be%d0%ba-%d1%82%d1%80%d0%b5%d1%82%d1%8c%d0%b5%d0%b3%d0%be-%d1%83%d1%80%d0%be%d0%b2%d0%bd%d1%8f">#</a>
</h3>
<h4 class="heading" id="заголовок-четвертого-уровня">
  Заголовок четвертого уровня
  <a class="anchor" href="#%d0%b7%d0%b0%d0%b3%d0%be%d0%bb%d0%be%d0%b2%d0%be%d0%ba-%d1%87%d0%b5%d1%82%d0%b2%d0%b5%d1%80%d1%82%d0%be%d0%b3%d0%be-%d1%83%d1%80%d0%be%d0%b2%d0%bd%d1%8f">#</a>
</h4>
<h5 class="heading" id="заголовок-пятого-уровня">
  Заголовок пятого уровня
  <a class="anchor" href="#%d0%b7%d0%b0%d0%b3%d0%be%d0%bb%d0%be%d0%b2%d0%be%d0%ba-%d0%bf%d1%8f%d1%82%d0%be%d0%b3%d0%be-%d1%83%d1%80%d0%be%d0%b2%d0%bd%d1%8f">#</a>
</h5>
<h6 class="heading" id="заголовок-шестого-уровня">
  Заголовок шестого уровня
  <a class="anchor" href="#%d0%b7%d0%b0%d0%b3%d0%be%d0%bb%d0%be%d0%b2%d0%be%d0%ba-%d1%88%d0%b5%d1%81%d1%82%d0%be%d0%b3%d0%be-%d1%83%d1%80%d0%be%d0%b2%d0%bd%d1%8f">#</a>
</h6>
<h3 class="heading" id="стили-текста">
  Стили Текста
  <a class="anchor" href="#%d1%81%d1%82%d0%b8%d0%bb%d0%b8-%d1%82%d0%b5%d0%ba%d1%81%d1%82%d0%b0">#</a>
</h3>
<table>
	<thead>
			<tr>
					<th>Тип</th>
					<th>Синтаксис</th>
					<th>Пример</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td><strong>Жирный</strong></td>
					<td><code>**текст**</code></td>
					<td><strong>Жирный текст</strong></td>
			</tr>
			<tr>
					<td><em>Курсив</em></td>
					<td><code>*текст*</code></td>
					<td><em>Курсивный текст</em></td>
			</tr>
			<tr>
					<td><em><strong>Жирный курсив</strong></em></td>
					<td><code>***текст***</code></td>
					<td><em><strong>Жирный курсив</strong></em></td>
			</tr>
			<tr>
					<td><del>Зачеркнутый</del></td>
					<td><code>~~текст~~</code></td>
					<td><del>Зачеркнутый текст</del></td>
			</tr>
	</tbody>
</table>
<h4 class="heading" id="демонстрация-стилей-текста">
  Демонстрация Стилей Текста
  <a class="anchor" href="#%d0%b4%d0%b5%d0%bc%d0%be%d0%bd%d1%81%d1%82%d1%80%d0%b0%d1%86%d0%b8%d1%8f-%d1%81%d1%82%d0%b8%d0%bb%d0%b5%d0%b9-%d1%82%d0%b5%d0%ba%d1%81%d1%82%d0%b0">#</a>
</h4>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="cl">**Жирный текст**
</span></span><span class="line"><span class="cl"><span class="ge">*Курсивный текст*</span>
</span></span><span class="line"><span class="cl"><span class="ge">**</span>*Жирный курсив***
</span></span><span class="line"><span class="cl">~~Зачеркнутый текст~~</span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<h4 class="heading" id="результат-применения-стилей">
  Результат Применения Стилей
  <a class="anchor" href="#%d1%80%d0%b5%d0%b7%d1%83%d0%bb%d1%8c%d1%82%d0%b0%d1%82-%d0%bf%d1%80%d0%b8%d0%bc%d0%b5%d0%bd%d0%b5%d0%bd%d0%b8%d1%8f-%d1%81%d1%82%d0%b8%d0%bb%d0%b5%d0%b9">#</a>
</h4>
<p><strong>Жирный текст</strong>
<em>Курсивный текст</em>
<em><strong>Жирный курсив</strong></em>
<del>Зачеркнутый текст</del></p>
<h2 class="heading" id="-типы-списков">
  📋 Типы Списков
  <a class="anchor" href="#-%d1%82%d0%b8%d0%bf%d1%8b-%d1%81%d0%bf%d0%b8%d1%81%d0%ba%d0%be%d0%b2">#</a>
</h2>
<h3 class="heading" id="нумерованные-списки">
  Нумерованные Списки
  <a class="anchor" href="#%d0%bd%d1%83%d0%bc%d0%b5%d1%80%d0%be%d0%b2%d0%b0%d0%bd%d0%bd%d1%8b%d0%b5-%d1%81%d0%bf%d0%b8%d1%81%d0%ba%d0%b8">#</a>
</h3>
<h4 class="heading" id="пример-нумерованного-списка">
  Пример Нумерованного Списка
  <a class="anchor" href="#%d0%bf%d1%80%d0%b8%d0%bc%d0%b5%d1%80-%d0%bd%d1%83%d0%bc%d0%b5%d1%80%d0%be%d0%b2%d0%b0%d0%bd%d0%bd%d0%be%d0%b3%d0%be-%d1%81%d0%bf%d0%b8%d1%81%d0%ba%d0%b0">#</a>
</h4>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="cl"><span class="k">1.</span> Первый элемент
</span></span><span class="line"><span class="cl"><span class="k">2.</span> Второй элемент
</span></span><span class="line"><span class="cl">3. Третий элемент</span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<h4 class="heading" id="визуализация-нумерованного-списка">
  Визуализация Нумерованного Списка
  <a class="anchor" href="#%d0%b2%d0%b8%d0%b7%d1%83%d0%b0%d0%bb%d0%b8%d0%b7%d0%b0%d1%86%d0%b8%d1%8f-%d0%bd%d1%83%d0%bc%d0%b5%d1%80%d0%be%d0%b2%d0%b0%d0%bd%d0%bd%d0%be%d0%b3%d0%be-%d1%81%d0%bf%d0%b8%d1%81%d0%ba%d0%b0">#</a>
</h4>
<ol>
<li>Первый элемент</li>
<li>Второй элемент</li>
<li>Третий элемент</li>
</ol>
<h3 class="heading" id="ненумерованные-списки">
  Ненумерованные Списки
  <a class="anchor" href="#%d0%bd%d0%b5%d0%bd%d1%83%d0%bc%d0%b5%d1%80%d0%be%d0%b2%d0%b0%d0%bd%d0%bd%d1%8b%d0%b5-%d1%81%d0%bf%d0%b8%d1%81%d0%ba%d0%b8">#</a>
</h3>
<h4 class="heading" id="пример-ненумерованного-списка">
  Пример Ненумерованного Списка
  <a class="anchor" href="#%d0%bf%d1%80%d0%b8%d0%bc%d0%b5%d1%80-%d0%bd%d0%b5%d0%bd%d1%83%d0%bc%d0%b5%d1%80%d0%be%d0%b2%d0%b0%d0%bd%d0%bd%d0%be%d0%b3%d0%be-%d1%81%d0%bf%d0%b8%d1%81%d0%ba%d0%b0">#</a>
</h4>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="cl"><span class="k">-</span> Первый элемент
</span></span><span class="line"><span class="cl"><span class="k">-</span> Второй элемент
</span></span><span class="line"><span class="cl">  <span class="k">-</span> Подэлемент
</span></span><span class="line"><span class="cl">- Третий элемент</span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<h4 class="heading" id="визуализация-ненумерованного-списка">
  Визуализация Ненумерованного Списка
  <a class="anchor" href="#%d0%b2%d0%b8%d0%b7%d1%83%d0%b0%d0%bb%d0%b8%d0%b7%d0%b0%d1%86%d0%b8%d1%8f-%d0%bd%d0%b5%d0%bd%d1%83%d0%bc%d0%b5%d1%80%d0%be%d0%b2%d0%b0%d0%bd%d0%bd%d0%be%d0%b3%d0%be-%d1%81%d0%bf%d0%b8%d1%81%d0%ba%d0%b0">#</a>
</h4>
<ul>
<li>Первый элемент</li>
<li>Второй элемент
<ul>
<li>Подэлемент</li>
</ul>
</li>
<li>Третий элемент</li>
</ul>
<h2 class="heading" id="-дополнительные-элементы-разметки">
  🖋️ Дополнительные Элементы Разметки
  <a class="anchor" href="#-%d0%b4%d0%be%d0%bf%d0%be%d0%bb%d0%bd%d0%b8%d1%82%d0%b5%d0%bb%d1%8c%d0%bd%d1%8b%d0%b5-%d1%8d%d0%bb%d0%b5%d0%bc%d0%b5%d0%bd%d1%82%d1%8b-%d1%80%d0%b0%d0%b7%d0%bc%d0%b5%d1%82%d0%ba%d0%b8">#</a>
</h2>
<h3 class="heading" id="цитаты">
  Цитаты
  <a class="anchor" href="#%d1%86%d0%b8%d1%82%d0%b0%d1%82%d1%8b">#</a>
</h3>
<h4 class="heading" id="пример-цитаты">
  Пример Цитаты
  <a class="anchor" href="#%d0%bf%d1%80%d0%b8%d0%bc%d0%b5%d1%80-%d1%86%d0%b8%d1%82%d0%b0%d1%82%d1%8b">#</a>
</h4>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="cl"><span class="k">&gt; </span><span class="ge">Это основная цитата
</span></span></span><span class="line"><span class="cl">&gt; 
</span></span><span class="line"><span class="cl">&gt; С несколькими строками</span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<h4 class="heading" id="визуализация-цитаты">
  Визуализация Цитаты
  <a class="anchor" href="#%d0%b2%d0%b8%d0%b7%d1%83%d0%b0%d0%bb%d0%b8%d0%b7%d0%b0%d1%86%d0%b8%d1%8f-%d1%86%d0%b8%d1%82%d0%b0%d1%82%d1%8b">#</a>
</h4>
<blockquote>
<p>Это основная цитата</p>
<p>С несколькими строками</p>
</blockquote>
<h3 class="heading" id="код">
  Код
  <a class="anchor" href="#%d0%ba%d0%be%d0%b4">#</a>
</h3>
<h4 class="heading" id="встроенный-код">
  Встроенный Код
  <a class="anchor" href="#%d0%b2%d1%81%d1%82%d1%80%d0%be%d0%b5%d0%bd%d0%bd%d1%8b%d0%b9-%d0%ba%d0%be%d0%b4">#</a>
</h4>
<h5 class="heading" id="синтаксис-встроенного-кода">
  Синтаксис Встроенного Кода
  <a class="anchor" href="#%d1%81%d0%b8%d0%bd%d1%82%d0%b0%d0%ba%d1%81%d0%b8%d1%81-%d0%b2%d1%81%d1%82%d1%80%d0%be%d0%b5%d0%bd%d0%bd%d0%be%d0%b3%d0%be-%d0%ba%d0%be%d0%b4%d0%b0">#</a>
</h5>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="cl"><span class="sb">`Встроенный код в тексте`</span></span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<h5 class="heading" id="результат-встроенного-кода">
  Результат Встроенного Кода
  <a class="anchor" href="#%d1%80%d0%b5%d0%b7%d1%83%d0%bb%d1%8c%d1%82%d0%b0%d1%82-%d0%b2%d1%81%d1%82%d1%80%d0%be%d0%b5%d0%bd%d0%bd%d0%be%d0%b3%d0%be-%d0%ba%d0%be%d0%b4%d0%b0">#</a>
</h5>
<p><code>Встроенный код в тексте</code></p>
<h4 class="heading" id="блоки-кода">
  Блоки Кода
  <a class="anchor" href="#%d0%b1%d0%bb%d0%be%d0%ba%d0%b8-%d0%ba%d0%be%d0%b4%d0%b0">#</a>
</h4>
<h5 class="heading" id="пример-блока-кода">
  Пример Блока Кода
  <a class="anchor" href="#%d0%bf%d1%80%d0%b8%d0%bc%d0%b5%d1%80-%d0%b1%d0%bb%d0%be%d0%ba%d0%b0-%d0%ba%d0%be%d0%b4%d0%b0">#</a>
</h5>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="cl">```python
</span></span><span class="line"><span class="cl">def hello_world():
</span></span><span class="line"><span class="cl">    print(&#34;Привет, мир!&#34;)</span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<div class="code-block">
  <pre tabindex="0"><code>
##### Визуализация Блока Кода

```python
def hello_world():
    print(&#34;Привет, мир!&#34;)</code></pre>
  <button class="copy-code-button">copy</button>
</div>
<h3 class="heading" id="сноски">
  Сноски
  <a class="anchor" href="#%d1%81%d0%bd%d0%be%d1%81%d0%ba%d0%b8">#</a>
</h3>
<h4 class="heading" id="синтаксис-сносок">
  Синтаксис Сносок
  <a class="anchor" href="#%d1%81%d0%b8%d0%bd%d1%82%d0%b0%d0%ba%d1%81%d0%b8%d1%81-%d1%81%d0%bd%d0%be%d1%81%d0%be%d0%ba">#</a>
</h4>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="cl">Текст с первой сноской[^1]. 
</span></span><span class="line"><span class="cl">Текст со второй сноской[^2].
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">[^1]: Первая сноска
</span></span><span class="line"><span class="cl">[^2]: Вторая сноска</span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<h4 class="heading" id="результат-сносок">
  Результат Сносок
  <a class="anchor" href="#%d1%80%d0%b5%d0%b7%d1%83%d0%bb%d1%8c%d1%82%d0%b0%d1%82-%d1%81%d0%bd%d0%be%d1%81%d0%be%d0%ba">#</a>
</h4>
<p>Текст с первой сноской<a href="#fn:1">1</a>.
Текст со второй сноской<a href="#fn:2">2</a>.</p>
<h3 class="heading" id="горизонтальная-линия">
  Горизонтальная Линия
  <a class="anchor" href="#%d0%b3%d0%be%d1%80%d0%b8%d0%b7%d0%be%d0%bd%d1%82%d0%b0%d0%bb%d1%8c%d0%bd%d0%b0%d1%8f-%d0%bb%d0%b8%d0%bd%d0%b8%d1%8f">#</a>
</h3>
<h4 class="heading" id="синтаксис-линии">
  Синтаксис Линии
  <a class="anchor" href="#%d1%81%d0%b8%d0%bd%d1%82%d0%b0%d0%ba%d1%81%d0%b8%d1%81-%d0%bb%d0%b8%d0%bd%d0%b8%d0%b8">#</a>
</h4>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="cl">---</span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<h2 class="heading" id="-ссылки-и-изображения">
  🔗 Ссылки и Изображения
  <a class="anchor" href="#-%d1%81%d1%81%d1%8b%d0%bb%d0%ba%d0%b8-%d0%b8-%d0%b8%d0%b7%d0%be%d0%b1%d1%80%d0%b0%d0%b6%d0%b5%d0%bd%d0%b8%d1%8f">#</a>
</h2>
<h3 class="heading" id="гиперссылки">
  Гиперссылки
  <a class="anchor" href="#%d0%b3%d0%b8%d0%bf%d0%b5%d1%80%d1%81%d1%81%d1%8b%d0%bb%d0%ba%d0%b8">#</a>
</h3>
<h4 class="heading" id="примеры-ссылок">
  Примеры Ссылок
  <a class="anchor" href="#%d0%bf%d1%80%d0%b8%d0%bc%d0%b5%d1%80%d1%8b-%d1%81%d1%81%d1%8b%d0%bb%d0%be%d0%ba">#</a>
</h4>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="cl">[<span class="nt">Ссылка на сайт</span>](<span class="na">https://example.com</span>)
</span></span><span class="line"><span class="cl">[<span class="nt">Ссылка с title</span>](<span class="na">https://example.com &#34;Описание сайта&#34;</span>)</span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<h4 class="heading" id="визуализация-ссылок">
  Визуализация Ссылок
  <a class="anchor" href="#%d0%b2%d0%b8%d0%b7%d1%83%d0%b0%d0%bb%d0%b8%d0%b7%d0%b0%d1%86%d0%b8%d1%8f-%d1%81%d1%81%d1%8b%d0%bb%d0%be%d0%ba">#</a>
</h4>
<p><a href="https://example.com">Ссылка на сайт</a>
<a href="https://example.com" title="Описание сайта">Ссылка с title</a></p>
<h3 class="heading" id="изображения">
  Изображения
  <a class="anchor" href="#%d0%b8%d0%b7%d0%be%d0%b1%d1%80%d0%b0%d0%b6%d0%b5%d0%bd%d0%b8%d1%8f">#</a>
</h3>
<h4 class="heading" id="синтаксис-изображений">
  Синтаксис Изображений
  <a class="anchor" href="#%d1%81%d0%b8%d0%bd%d1%82%d0%b0%d0%ba%d1%81%d0%b8%d1%81-%d0%b8%d0%b7%d0%be%d0%b1%d1%80%d0%b0%d0%b6%d0%b5%d0%bd%d0%b8%d0%b9">#</a>
</h4>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="cl">![<span class="nt">Логотип Markdown</span>](<span class="na">https://upload.wikimedia.org/wikipedia/commons/4/48/Markdown-mark.svg</span>)
</span></span><span class="line"><span class="cl">![<span class="nt">GitHub логотип</span>](<span class="na">https://github.githubassets.com/images/modules/logos_page/GitHub-Mark.png</span>)</span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<h4 class="heading" id="галерея-изображений">
  Галерея Изображений
  <a class="anchor" href="#%d0%b3%d0%b0%d0%bb%d0%b5%d1%80%d0%b5%d1%8f-%d0%b8%d0%b7%d0%be%d0%b1%d1%80%d0%b0%d0%b6%d0%b5%d0%bd%d0%b8%d0%b9">#</a>
</h4>
<p>










<figure class="">
  
  
    <div class="img-container">
      <img loading="lazy" alt="Логотип Markdown" src="https://upload.wikimedia.org/wikipedia/commons/4/48/Markdown-mark.svg">
    </div>
  

  
</figure>












<figure class="">
  
  
    <div class="img-container">
      <img loading="lazy" alt="GitHub логотип" src="https://github.githubassets.com/images/modules/logos_page/GitHub-Mark.png">
    </div>
  

  
</figure>












<figure class="">
  
  
    <div class="img-container">
      <img loading="lazy" alt="Технологический фон" src="https://images.unsplash.com/photo-1498050108023-c5249f4df085">
    </div>
  

  
</figure>
</p>
<h2 class="heading" id="-расширенный-синтаксис">
  🌟 Расширенный синтаксис
  <a class="anchor" href="#-%d1%80%d0%b0%d1%81%d1%88%d0%b8%d1%80%d0%b5%d0%bd%d0%bd%d1%8b%d0%b9-%d1%81%d0%b8%d0%bd%d1%82%d0%b0%d0%ba%d1%81%d0%b8%d1%81">#</a>
</h2>
<h3 class="heading" id="таблицы">
  Таблицы
  <a class="anchor" href="#%d1%82%d0%b0%d0%b1%d0%bb%d0%b8%d1%86%d1%8b">#</a>
</h3>
<h4 class="heading" id="пример-таблицы">
  Пример Таблицы
  <a class="anchor" href="#%d0%bf%d1%80%d0%b8%d0%bc%d0%b5%d1%80-%d1%82%d0%b0%d0%b1%d0%bb%d0%b8%d1%86%d1%8b">#</a>
</h4>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="cl">| Колонка 1 | Колонка 2 | Колонка 3 |
</span></span><span class="line"><span class="cl">|-----------|-----------|-----------|
</span></span><span class="line"><span class="cl">| Строка 1  | Данные    | Инфо      |
</span></span><span class="line"><span class="cl">| Строка 2  | Значение  | Данные    |</span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<h4 class="heading" id="визуализация-таблицы">
  Визуализация Таблицы
  <a class="anchor" href="#%d0%b2%d0%b8%d0%b7%d1%83%d0%b0%d0%bb%d0%b8%d0%b7%d0%b0%d1%86%d0%b8%d1%8f-%d1%82%d0%b0%d0%b1%d0%bb%d0%b8%d1%86%d1%8b">#</a>
</h4>
<table>
	<thead>
			<tr>
					<th>Колонка 1</th>
					<th>Колонка 2</th>
					<th>Колонка 3</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td>Строка 1</td>
					<td>Данные</td>
					<td>Инфо</td>
			</tr>
			<tr>
					<td>Строка 2</td>
					<td>Значение</td>
					<td>Данные</td>
			</tr>
	</tbody>
</table>
<h3 class="heading" id="задачи">
  Задачи
  <a class="anchor" href="#%d0%b7%d0%b0%d0%b4%d0%b0%d1%87%d0%b8">#</a>
</h3>
<h4 class="heading" id="пример-задач">
  Пример Задач
  <a class="anchor" href="#%d0%bf%d1%80%d0%b8%d0%bc%d0%b5%d1%80-%d0%b7%d0%b0%d0%b4%d0%b0%d1%87">#</a>
</h4>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="cl"><span class="k">- [x]</span> Выполненная задача
</span></span><span class="line"><span class="cl"><span class="k">- [ ]</span> Невыполненная задача
</span></span><span class="line"><span class="cl">- [x] Еще одна выполненная</span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<h4 class="heading" id="визуализация-задач">
  Визуализация Задач
  <a class="anchor" href="#%d0%b2%d0%b8%d0%b7%d1%83%d0%b0%d0%bb%d0%b8%d0%b7%d0%b0%d1%86%d0%b8%d1%8f-%d0%b7%d0%b0%d0%b4%d0%b0%d1%87">#</a>
</h4>
<ul>
<li>Выполненная задача</li>
<li>Невыполненная задача</li>
<li>Еще одна выполненная</li>
</ul>
<h2 class="heading" id="-советы-и-best-practices">
  💡 Советы и best practices
  <a class="anchor" href="#-%d1%81%d0%be%d0%b2%d0%b5%d1%82%d1%8b-%d0%b8-best-practices">#</a>
</h2>
<ol>
<li>Используйте консистентный стиль</li>
<li>Не перегружайте текст</li>
<li>Помните о читаемости</li>
<li>Экспериментируйте</li>
</ol>
<h2 class="heading" id="-полезные-ресурсы">
  📚 Полезные ресурсы
  <a class="anchor" href="#-%d0%bf%d0%be%d0%bb%d0%b5%d0%b7%d0%bd%d1%8b%d0%b5-%d1%80%d0%b5%d1%81%d1%83%d1%80%d1%81%d1%8b">#</a>
</h2>
<ul>
<li><a href="https://daringfireball.net/projects/markdown/">Официальное руководство Markdown</a></li>
<li><a href="https://guides.github.com/features/mastering-markdown/">GitHub Markdown Guide</a></li>
</ul>
<h2 class="heading" id="-заключение">
  🤔 Заключение
  <a class="anchor" href="#-%d0%b7%d0%b0%d0%ba%d0%bb%d1%8e%d1%87%d0%b5%d0%bd%d0%b8%d0%b5">#</a>
</h2>
<p>Markdown - мощный и простой инструмент для форматирования текста. Практикуйтесь и открывайте для себя новые возможности!</p>
<p>123412341234123412341234</p>
<p>CCJo+al+vu,amWsnecbr1,i,ApCstos,leCumSmbSnl,yH2T,MCLolumn3</p>
<hr>
<ol>
<li>Первая сноска <a href="#fnref:1">↩︎</a></li>
<li>Вторая сноска <a href="#fnref:2">↩︎</a></li>
</ol>
]]></content:encoded><category>Markdown</category><category>Typography</category><category>Guide</category></item><item><title>☕ Tea: Консольный Клиент для Gitea</title><link>https://kushnaren.co/posts/2024-10-02-tea-gitea-cli/</link><pubDate>Wed, 02 Oct 2024 10:00:00 +0300</pubDate><guid isPermaLink="true">https://kushnaren.co/posts/2024-10-02-tea-gitea-cli/</guid><description>Полное руководство по использованию Tea - официального консольного клиента для Gitea</description><content:encoded><![CDATA[<h2 class="heading" id="-введение-в-tea">
  🍵 Введение в Tea
  <a class="anchor" href="#-%d0%b2%d0%b2%d0%b5%d0%b4%d0%b5%d0%bd%d0%b8%d0%b5-%d0%b2-tea">#</a>
</h2>
<p>Tea - это мощный инструмент для разработчиков, который позволяет управлять репозиториями, issue и pull request прямо из терминала. Он особенно полезен для DevOps-инженеров и разработчиков, которые предпочитают работать с командной строкой. Используя Tea, вы можете автоматизировать многие рутинные задачи и интегрировать его в свои рабочие процессы.</p>
<h3 class="heading" id="зачем-использовать-tea">
  Зачем использовать Tea?
  <a class="anchor" href="#%d0%b7%d0%b0%d1%87%d0%b5%d0%bc-%d0%b8%d1%81%d0%bf%d0%be%d0%bb%d1%8c%d0%b7%d0%be%d0%b2%d0%b0%d1%82%d1%8c-tea">#</a>
</h3>
<ul>
<li><strong>Ускорение рабочих процессов</strong>: Tea позволяет быстро выполнять команды, не переключаясь между интерфейсами.</li>
<li><strong>Автоматизация задач</strong>: Используйте скрипты для автоматизации рутинных операций.</li>
<li><strong>Интеграция с CI/CD</strong>: Легко интегрируйте Tea в ваши процессы непрерывной интеграции и доставки.</li>
</ul>
<h3 class="heading" id="установка">
  Установка
  <a class="anchor" href="#%d1%83%d1%81%d1%82%d0%b0%d0%bd%d0%be%d0%b2%d0%ba%d0%b0">#</a>
</h3>
<h4 class="heading" id="macos">
  macOS
  <a class="anchor" href="#macos">#</a>
</h4>
<p>Для установки Tea на macOS используйте Homebrew:</p>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">brew install tea</span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<p>После установки проверьте, что Tea установлен корректно, выполнив:</p>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">tea --version</span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<h4 class="heading" id="linux">
  Linux
  <a class="anchor" href="#linux">#</a>
</h4>
<p>Для установки на Linux выполните следующие шаги:</p>
<ol>
<li>Загрузите бинарный файл:</li>
</ol>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">wget https://dl.gitea.com/tea/latest/tea-amd64</span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<ol>
<li>Сделайте файл исполняемым:</li>
</ol>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">chmod +x tea-amd64</span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<ol>
<li>Переместите файл в директорию, доступную в PATH:</li>
</ol>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo mv tea-amd64 /usr/local/bin/tea</span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<ol>
<li>Проверьте установку:</li>
</ol>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">tea --version</span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<h2 class="heading" id="-аутентификация">
  🔐 Аутентификация
  <a class="anchor" href="#-%d0%b0%d1%83%d1%82%d0%b5%d0%bd%d1%82%d0%b8%d1%84%d0%b8%d0%ba%d0%b0%d1%86%d0%b8%d1%8f">#</a>
</h2>
<h3 class="heading" id="создание-токена-в-gitea">
  Создание токена в Gitea
  <a class="anchor" href="#%d1%81%d0%be%d0%b7%d0%b4%d0%b0%d0%bd%d0%b8%d0%b5-%d1%82%d0%be%d0%ba%d0%b5%d0%bd%d0%b0-%d0%b2-gitea">#</a>
</h3>
<ol>
<li>Перейдите в настройки профиля на вашем Gitea-сервере.</li>
<li>Выберите “Настройки приложений” и создайте новый токен доступа.</li>
<li>Сохраните токен в безопасном месте.</li>
</ol>
<h3 class="heading" id="настройка-tea">
  Настройка Tea
  <a class="anchor" href="#%d0%bd%d0%b0%d1%81%d1%82%d1%80%d0%be%d0%b9%d0%ba%d0%b0-tea">#</a>
</h3>
<p>Для настройки Tea выполните команду:</p>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">tea login add</span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<p>Следуйте интерактивным инструкциям для ввода вашего токена и настройки соединения.</p>
<h2 class="heading" id="-работа-с-репозиториями">
  🗂️ Работа с Репозиториями
  <a class="anchor" href="#-%d1%80%d0%b0%d0%b1%d0%be%d1%82%d0%b0-%d1%81-%d1%80%d0%b5%d0%bf%d0%be%d0%b7%d0%b8%d1%82%d0%be%d1%80%d0%b8%d1%8f%d0%bc%d0%b8">#</a>
</h2>
<h3 class="heading" id="список-репозиториев">
  Список репозиториев
  <a class="anchor" href="#%d1%81%d0%bf%d0%b8%d1%81%d0%be%d0%ba-%d1%80%d0%b5%d0%bf%d0%be%d0%b7%d0%b8%d1%82%d0%be%d1%80%d0%b8%d0%b5%d0%b2">#</a>
</h3>
<p>Чтобы получить список всех ваших репозиториев, используйте:</p>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">tea repos</span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<p>Вы можете фильтровать и сортировать список по различным критериям.</p>
<h3 class="heading" id="клонирование-репозитория">
  Клонирование репозитория
  <a class="anchor" href="#%d0%ba%d0%bb%d0%be%d0%bd%d0%b8%d1%80%d0%be%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5-%d1%80%d0%b5%d0%bf%d0%be%d0%b7%d0%b8%d1%82%d0%be%d1%80%d0%b8%d1%8f">#</a>
</h3>
<p>Клонируйте репозиторий с помощью команды:</p>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">tea clone username/repository</span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<p>Эта команда создаст локальную копию указанного репозитория.</p>
<h3 class="heading" id="создание-нового-репозитория">
  Создание нового репозитория
  <a class="anchor" href="#%d1%81%d0%be%d0%b7%d0%b4%d0%b0%d0%bd%d0%b8%d0%b5-%d0%bd%d0%be%d0%b2%d0%be%d0%b3%d0%be-%d1%80%d0%b5%d0%bf%d0%be%d0%b7%d0%b8%d1%82%d0%be%d1%80%d0%b8%d1%8f">#</a>
</h3>
<p>Создайте новый репозиторий с помощью:</p>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">tea create repo --name my-new-project</span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<p>Вы можете указать дополнительные параметры, такие как приватность репозитория.</p>
<h2 class="heading" id="-управление-issue">
  🐞 Управление Issue
  <a class="anchor" href="#-%d1%83%d0%bf%d1%80%d0%b0%d0%b2%d0%bb%d0%b5%d0%bd%d0%b8%d0%b5-issue">#</a>
</h2>
<h3 class="heading" id="список-issue">
  Список Issue
  <a class="anchor" href="#%d1%81%d0%bf%d0%b8%d1%81%d0%be%d0%ba-issue">#</a>
</h3>
<p>Получите список всех issue, связанных с вашим аккаунтом:</p>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">tea issues</span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<p>Используйте фильтры для отображения только открытых или закрытых issue.</p>
<h3 class="heading" id="создание-issue">
  Создание Issue
  <a class="anchor" href="#%d1%81%d0%be%d0%b7%d0%b4%d0%b0%d0%bd%d0%b8%d0%b5-issue">#</a>
</h3>
<p>Создайте новое issue с подробным описанием:</p>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">tea create issue <span class="se">\
</span></span></span><span class="line"><span class="cl">    --title <span class="s2">&#34;Новая задача&#34;</span> <span class="se">\
</span></span></span><span class="line"><span class="cl">    --description <span class="s2">&#34;Подробное описание&#34;</span> <span class="se">\
</span></span></span><span class="line"><span class="cl">    --repo username/repository</span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<h3 class="heading" id="закрытие-issue">
  Закрытие Issue
  <a class="anchor" href="#%d0%b7%d0%b0%d0%ba%d1%80%d1%8b%d1%82%d0%b8%d0%b5-issue">#</a>
</h3>
<p>Закройте issue по его номеру:</p>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">tea close issue <span class="m">42</span></span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<h2 class="heading" id="-работа-с-pull-request">
  🔀 Работа с Pull Request
  <a class="anchor" href="#-%d1%80%d0%b0%d0%b1%d0%be%d1%82%d0%b0-%d1%81-pull-request">#</a>
</h2>
<h3 class="heading" id="список-pull-request">
  Список Pull Request
  <a class="anchor" href="#%d1%81%d0%bf%d0%b8%d1%81%d0%be%d0%ba-pull-request">#</a>
</h3>
<p>Получите список всех pull request:</p>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">tea pulls</span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<h3 class="heading" id="создание-pull-request">
  Создание Pull Request
  <a class="anchor" href="#%d1%81%d0%be%d0%b7%d0%b4%d0%b0%d0%bd%d0%b8%d0%b5-pull-request">#</a>
</h3>
<p>Создайте новый pull request для слияния изменений:</p>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">tea create pr <span class="se">\
</span></span></span><span class="line"><span class="cl">    --base main <span class="se">\
</span></span></span><span class="line"><span class="cl">    --head feature-branch <span class="se">\
</span></span></span><span class="line"><span class="cl">    --title <span class="s2">&#34;Новый функционал&#34;</span> <span class="se">\
</span></span></span><span class="line"><span class="cl">    --description <span class="s2">&#34;Детали изменений&#34;</span></span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<h3 class="heading" id="слияние-pull-request">
  Слияние Pull Request
  <a class="anchor" href="#%d1%81%d0%bb%d0%b8%d1%8f%d0%bd%d0%b8%d0%b5-pull-request">#</a>
</h3>
<p>Слейте pull request, указав его номер:</p>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">tea merge pr <span class="m">10</span></span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<h2 class="heading" id="-дополнительные-команды">
  🌐 Дополнительные Команды
  <a class="anchor" href="#-%d0%b4%d0%be%d0%bf%d0%be%d0%bb%d0%bd%d0%b8%d1%82%d0%b5%d0%bb%d1%8c%d0%bd%d1%8b%d0%b5-%d0%ba%d0%be%d0%bc%d0%b0%d0%bd%d0%b4%d1%8b">#</a>
</h2>
<h3 class="heading" id="просмотр-веток">
  Просмотр веток
  <a class="anchor" href="#%d0%bf%d1%80%d0%be%d1%81%d0%bc%d0%be%d1%82%d1%80-%d0%b2%d0%b5%d1%82%d0%be%d0%ba">#</a>
</h3>
<p>Просмотрите все ветки в репозитории:</p>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">tea branches</span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<h3 class="heading" id="просмотр-релизов">
  Просмотр релизов
  <a class="anchor" href="#%d0%bf%d1%80%d0%be%d1%81%d0%bc%d0%be%d1%82%d1%80-%d1%80%d0%b5%d0%bb%d0%b8%d0%b7%d0%be%d0%b2">#</a>
</h3>
<p>Получите информацию о всех релизах:</p>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">tea releases</span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<h2 class="heading" id="-полезные-советы">
  🛠️ Полезные Советы
  <a class="anchor" href="#-%d0%bf%d0%be%d0%bb%d0%b5%d0%b7%d0%bd%d1%8b%d0%b5-%d1%81%d0%be%d0%b2%d0%b5%d1%82%d1%8b">#</a>
</h2>
<ul>
<li>Используйте флаг <code>-r</code> для указания репозитория при выполнении команд.</li>
<li>Настройте автодополнение команд в вашем shell для ускорения работы.</li>
<li>Регулярно обновляйте Tea, чтобы использовать последние функции и исправления.</li>
</ul>
<h2 class="heading" id="-заключение">
  📚 Заключение
  <a class="anchor" href="#-%d0%b7%d0%b0%d0%ba%d0%bb%d1%8e%d1%87%d0%b5%d0%bd%d0%b8%d0%b5">#</a>
</h2>
<p>Tea значительно упрощает работу с Gitea, предоставляя мощный инструмент для управления репозиториями прямо из терминала. Он помогает автоматизировать рабочие процессы и интегрируется с различными инструментами DevOps, делая вашу работу более эффективной.</p>
]]></content:encoded><category>Gitea</category><category>CLI</category><category>DevOps</category></item><item><title>📝 Obsidian: Ваш персональный менеджер знаний</title><link>https://kushnaren.co/posts/2024-07-14-obsidian-guide/</link><pubDate>Sun, 14 Jul 2024 10:00:00 +0300</pubDate><guid isPermaLink="true">https://kushnaren.co/posts/2024-07-14-obsidian-guide/</guid><description>Подробное руководство по Obsidian - мощному инструменту для управления знаниями и заметками</description><content:encoded><![CDATA[<h2 class="heading" id="что-такое-obsidian">
  Что такое Obsidian?
  <a class="anchor" href="#%d1%87%d1%82%d0%be-%d1%82%d0%b0%d0%ba%d0%be%d0%b5-obsidian">#</a>
</h2>
<p>Obsidian - это powerful markdown-редактор и менеджер знаний нового поколения, который позволяет создавать связанную базу знаний на основе локальных markdown-файлов.</p>
<h3 class="heading" id="ключевые-преимущества">
  Ключевые преимущества
  <a class="anchor" href="#%d0%ba%d0%bb%d1%8e%d1%87%d0%b5%d0%b2%d1%8b%d0%b5-%d0%bf%d1%80%d0%b5%d0%b8%d0%bc%d1%83%d1%89%d0%b5%d1%81%d1%82%d0%b2%d0%b0">#</a>
</h3>
<ol>
<li><strong>Локальное хранение</strong>: Все ваши заметки хранятся локально на устройстве</li>
<li><strong>Markdown-совместимость</strong>: Полная поддержка markdown</li>
<li><strong>Связывание заметок</strong>: Возможность создавать wiki-links между документами</li>
<li><strong>Расширяемость</strong>: Большое количество плагинов</li>
<li><strong>Приватность</strong>: Никаких облачных синхронизаций по умолчанию</li>
</ol>
<h2 class="heading" id="установка">
  Установка
  <a class="anchor" href="#%d1%83%d1%81%d1%82%d0%b0%d0%bd%d0%be%d0%b2%d0%ba%d0%b0">#</a>
</h2>
<h3 class="heading" id="macos">
  macOS
  <a class="anchor" href="#macos">#</a>
</h3>
<ol>
<li>Скачать с официального сайта <a href="https://obsidian.md">obsidian.md</a></li>
<li>Перетащить в папку Applications</li>
<li>Первый запуск - создание хранилища (Vault)</li>
</ol>
<h3 class="heading" id="windowslinux">
  Windows/Linux
  <a class="anchor" href="#windowslinux">#</a>
</h3>
<ol>
<li>Скачать дистрибутив с официального сайта</li>
<li>Установить через стандартный установщик</li>
<li>Запустить и создать первое хранилище</li>
</ol>
<h2 class="heading" id="базовая-настройка">
  Базовая настройка
  <a class="anchor" href="#%d0%b1%d0%b0%d0%b7%d0%be%d0%b2%d0%b0%d1%8f-%d0%bd%d0%b0%d1%81%d1%82%d1%80%d0%be%d0%b9%d0%ba%d0%b0">#</a>
</h2>
<h3 class="heading" id="создание-хранилища">
  Создание хранилища
  <a class="anchor" href="#%d1%81%d0%be%d0%b7%d0%b4%d0%b0%d0%bd%d0%b8%d0%b5-%d1%85%d1%80%d0%b0%d0%bd%d0%b8%d0%bb%d0%b8%d1%89%d0%b0">#</a>
</h3>
<ol>
<li>Нажать “New vault”</li>
<li>Выбрать директорию</li>
<li>Дать название хранилищу</li>
</ol>
<h3 class="heading" id="основные-настройки">
  Основные настройки
  <a class="anchor" href="#%d0%be%d1%81%d0%bd%d0%be%d0%b2%d0%bd%d1%8b%d0%b5-%d0%bd%d0%b0%d1%81%d1%82%d1%80%d0%be%d0%b9%d0%ba%d0%b8">#</a>
</h3>
<ul>
<li><strong>Темы</strong>: Настройка внешнего вида</li>
<li><strong>Плагины</strong>: Включение/отключение функционала</li>
<li><strong>Горячие клавиши</strong>: Кастомизация</li>
</ul>
<h2 class="heading" id="продвинутые-техники">
  Продвинутые техники
  <a class="anchor" href="#%d0%bf%d1%80%d0%be%d0%b4%d0%b2%d0%b8%d0%bd%d1%83%d1%82%d1%8b%d0%b5-%d1%82%d0%b5%d1%85%d0%bd%d0%b8%d0%ba%d0%b8">#</a>
</h2>
<h3 class="heading" id="связывание-заметок">
  Связывание заметок
  <a class="anchor" href="#%d1%81%d0%b2%d1%8f%d0%b7%d1%8b%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5-%d0%b7%d0%b0%d0%bc%d0%b5%d1%82%d0%be%d0%ba">#</a>
</h3>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="cl">[[Название другой заметки]]  # Внутренняя ссылка</span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<h3 class="heading" id="теги">
  Теги
  <a class="anchor" href="#%d1%82%d0%b5%d0%b3%d0%b8">#</a>
</h3>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="cl"><span class="ni">#productivity</span> <span class="ni">#programming</span></span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<h3 class="heading" id="daily-notes">
  Daily Notes
  <a class="anchor" href="#daily-notes">#</a>
</h3>
<h4 class="heading" id="что-такое-daily-notes">
  Что такое Daily Notes?
  <a class="anchor" href="#%d1%87%d1%82%d0%be-%d1%82%d0%b0%d0%ba%d0%be%d0%b5-daily-notes">#</a>
</h4>
<p>Daily Notes - это автоматически создаваемые ежедневные заметки, которые служат персональным дневником, трекером задач и инструментом рефлексии.</p>
<h4 class="heading" id="настройка-daily-notes">
  Настройка Daily Notes
  <a class="anchor" href="#%d0%bd%d0%b0%d1%81%d1%82%d1%80%d0%be%d0%b9%d0%ba%d0%b0-daily-notes">#</a>
</h4>
<h5 class="heading" id="1-базовая-конфигурация">
  1. Базовая конфигурация
  <a class="anchor" href="#1-%d0%b1%d0%b0%d0%b7%d0%be%d0%b2%d0%b0%d1%8f-%d0%ba%d0%be%d0%bd%d1%84%d0%b8%d0%b3%d1%83%d1%80%d0%b0%d1%86%d0%b8%d1%8f">#</a>
</h5>
<p>В настройках Obsidian:</p>
<ul>
<li>Включить “Daily Notes” в Core Plugins</li>
<li>Выбрать папку для хранения</li>
<li>Настроить формат имени файла</li>
</ul>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="cl">Формат: YYYY-MM-DD.md
</span></span><span class="line"><span class="cl">Пример: 2024-01-13.md</span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<h5 class="heading" id="2-шаблонизация">
  2. Шаблонизация
  <a class="anchor" href="#2-%d1%88%d0%b0%d0%b1%d0%bb%d0%be%d0%bd%d0%b8%d0%b7%d0%b0%d1%86%d0%b8%d1%8f">#</a>
</h5>
<p>Создайте шаблон для ежедневных заметок:</p>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="cl"><span class="gh"># {{date:YYYY-MM-DD}} - День {{date:dddd}}
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="gu">## Утренние намерения
</span></span></span><span class="line"><span class="cl"><span class="k">- [ ]</span> Основная цель дня
</span></span><span class="line"><span class="cl"><span class="k">- [ ]</span> Приоритетные задачи
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="gu">## Задачи
</span></span></span><span class="line"><span class="cl"><span class="gu">### Критично
</span></span></span><span class="line"><span class="cl"><span class="k">-</span> [ ] 
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="gu">### Важно
</span></span></span><span class="line"><span class="cl"><span class="k">-</span> [ ] 
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="gu">### Второстепенно
</span></span></span><span class="line"><span class="cl"><span class="k">-</span> [ ] 
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="gu">## Трекинг
</span></span></span><span class="line"><span class="cl"><span class="k">-</span> Сон: 
</span></span><span class="line"><span class="cl"><span class="k">-</span> Вода: 
</span></span><span class="line"><span class="cl"><span class="k">-</span> Физическая активность: 
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="gu">## Рефлексия
</span></span></span><span class="line"><span class="cl"><span class="gu">### Что прошло хорошо
</span></span></span><span class="line"><span class="cl">- 
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="gu">### Что можно улучшить
</span></span></span><span class="line"><span class="cl">- 
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="gu">## Заметки
</span></span></span><span class="line"><span class="cl">- 
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">## Связанные заметки</span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<h5 class="heading" id="3-плагины-для-расширения-функционала">
  3. Плагины для расширения функционала
  <a class="anchor" href="#3-%d0%bf%d0%bb%d0%b0%d0%b3%d0%b8%d0%bd%d1%8b-%d0%b4%d0%bb%d1%8f-%d1%80%d0%b0%d1%81%d1%88%d0%b8%d1%80%d0%b5%d0%bd%d0%b8%d1%8f-%d1%84%d1%83%d0%bd%d0%ba%d1%86%d0%b8%d0%be%d0%bd%d0%b0%d0%bb%d0%b0">#</a>
</h5>
<ol>
<li>
<p><strong>Templater</strong></p>
<ul>
<li>Динамическая генерация шаблонов</li>
<li>Поддержка скриптов JavaScript</li>
<li>Автоматическое заполнение метаданных</li>
</ul>
</li>
<li>
<p><strong>Calendar</strong></p>
<ul>
<li>Визуальный календарь</li>
<li>Быстрый переход между Daily Notes</li>
<li>Индикация заполненных дней</li>
</ul>
</li>
</ol>
<h5 class="heading" id="4-автоматизация-с-templater">
  4. Автоматизация с Templater
  <a class="anchor" href="#4-%d0%b0%d0%b2%d1%82%d0%be%d0%bc%d0%b0%d1%82%d0%b8%d0%b7%d0%b0%d1%86%d0%b8%d1%8f-%d1%81-templater">#</a>
</h5>
<p>Пример скрипта для автоматизации:</p>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="c1">// Получение списка незавершенных задач из предыдущего дня
</span></span></span><span class="line"><span class="cl"><span class="kr">async</span> <span class="kd">function</span> <span class="nx">getPreviousDayTasks</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kr">const</span> <span class="nx">previousDate</span> <span class="o">=</span> <span class="nx">moment</span><span class="p">().</span><span class="nx">subtract</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="s1">&#39;days&#39;</span><span class="p">).</span><span class="nx">format</span><span class="p">(</span><span class="s1">&#39;YYYY-MM-DD&#39;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="kr">const</span> <span class="nx">previousFile</span> <span class="o">=</span> <span class="kr">await</span> <span class="nx">app</span><span class="p">.</span><span class="nx">vault</span><span class="p">.</span><span class="nx">getMarkdownFiles</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">        <span class="p">.</span><span class="nx">find</span><span class="p">(</span><span class="nx">file</span> <span class="p">=&gt;</span> <span class="nx">file</span><span class="p">.</span><span class="nx">name</span> <span class="o">===</span> <span class="sb">`</span><span class="si">${</span><span class="nx">previousDate</span><span class="si">}</span><span class="sb">.md`</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="nx">previousFile</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="kr">const</span> <span class="nx">content</span> <span class="o">=</span> <span class="kr">await</span> <span class="nx">app</span><span class="p">.</span><span class="nx">vault</span><span class="p">.</span><span class="nx">read</span><span class="p">(</span><span class="nx">previousFile</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="c1">// Логика извлечения незавершенных задач
</span></span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<h5 class="heading" id="5-стратегии-использования">
  5. Стратегии использования
  <a class="anchor" href="#5-%d1%81%d1%82%d1%80%d0%b0%d1%82%d0%b5%d0%b3%d0%b8%d0%b8-%d0%b8%d1%81%d0%bf%d0%be%d0%bb%d1%8c%d0%b7%d0%be%d0%b2%d0%b0%d0%bd%d0%b8%d1%8f">#</a>
</h5>
<ul>
<li><strong>Утренний ritual</strong>: Заполнение намерений</li>
<li><strong>Вечерний review</strong>: Рефлексия и анализ дня</li>
<li><strong>Еженедельный и ежемесячный обзор</strong></li>
</ul>
<h5 class="heading" id="6-продвинутые-техники">
  6. Продвинутые техники
  <a class="anchor" href="#6-%d0%bf%d1%80%d0%be%d0%b4%d0%b2%d0%b8%d0%bd%d1%83%d1%82%d1%8b%d0%b5-%d1%82%d0%b5%d1%85%d0%bd%d0%b8%d0%ba%d0%b8">#</a>
</h5>
<ul>
<li>Создание персональной системы треков</li>
<li>Интеграция с проектным планированием</li>
<li>Анализ продуктивности через Dataview</li>
</ul>
<h5 class="heading" id="7-приватность-и-безопасность">
  7. Приватность и безопасность
  <a class="anchor" href="#7-%d0%bf%d1%80%d0%b8%d0%b2%d0%b0%d1%82%d0%bd%d0%be%d1%81%d1%82%d1%8c-%d0%b8-%d0%b1%d0%b5%d0%b7%d0%be%d0%bf%d0%b0%d1%81%d0%bd%d0%be%d1%81%d1%82%d1%8c">#</a>
</h5>
<ul>
<li>Использование <code>.gitignore</code> для исключения Daily Notes</li>
<li>Настройка шифрования для личных заметок</li>
<li>Регулярное резервное копирование</li>
</ul>
<h4 class="heading" id="best-practices">
  Best Practices
  <a class="anchor" href="#best-practices">#</a>
</h4>
<ol>
<li>Будьте последовательны</li>
<li>Не перегружайте заметки</li>
<li>Экспериментируйте с форматом</li>
<li>Используйте теги для категоризации</li>
<li>Связывайте заметки с проектами</li>
</ol>
<h4 class="heading" id="примеры-использования">
  Примеры использования
  <a class="anchor" href="#%d0%bf%d1%80%d0%b8%d0%bc%d0%b5%d1%80%d1%8b-%d0%b8%d1%81%d0%bf%d0%be%d0%bb%d1%8c%d0%b7%d0%be%d0%b2%d0%b0%d0%bd%d0%b8%d1%8f">#</a>
</h4>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="cl"><span class="gh">#daily/productive 
</span></span></span><span class="line"><span class="cl"><span class="gh">#daily/learning
</span></span></span><span class="line"><span class="cl"><span class="ni">#daily/health</span></span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<h4 class="heading" id="интеграции">
  Интеграции
  <a class="anchor" href="#%d0%b8%d0%bd%d1%82%d0%b5%d0%b3%d1%80%d0%b0%d1%86%d0%b8%d0%b8">#</a>
</h4>
<ul>
<li><strong>Todoist</strong>: Синхронизация задач</li>
<li><strong>Notion</strong>: Импорт/экспорт данных</li>
<li><strong>Apple Health</strong>: Трекинг активности</li>
</ul>
<h4 class="heading" id="ограничения-и-советы">
  Ограничения и советы
  <a class="anchor" href="#%d0%be%d0%b3%d1%80%d0%b0%d0%bd%d0%b8%d1%87%d0%b5%d0%bd%d0%b8%d1%8f-%d0%b8-%d1%81%d0%be%d0%b2%d0%b5%d1%82%d1%8b">#</a>
</h4>
<ul>
<li>Не привязывайтесь слишком сильно к шаблону</li>
<li>Адаптируйте под свои нужды</li>
<li>Экспериментируйте</li>
</ul>
<h2 class="heading" id="синхронизация">
  Синхронизация
  <a class="anchor" href="#%d1%81%d0%b8%d0%bd%d1%85%d1%80%d0%be%d0%bd%d0%b8%d0%b7%d0%b0%d1%86%d0%b8%d1%8f">#</a>
</h2>
<ol>
<li><strong>Obsidian Sync</strong>: Платная официальная синхронизация</li>
<li><strong>Git</strong>: Бесплатная синхронизация через Git-репозиторий</li>
<li><strong>Dropbox/iCloud</strong>: Альтернативные варианты</li>
</ol>
<h2 class="heading" id="полезные-плагины">
  Полезные плагины
  <a class="anchor" href="#%d0%bf%d0%be%d0%bb%d0%b5%d0%b7%d0%bd%d1%8b%d0%b5-%d0%bf%d0%bb%d0%b0%d0%b3%d0%b8%d0%bd%d1%8b">#</a>
</h2>
<ul>
<li>Dataview: Создание динамических представлений заметок</li>
<li>Templater: Продвинутые шаблоны</li>
<li>Advanced Tables: Улучшенная работа с таблицами</li>
<li>Kanban: Доски в стиле Trello</li>
</ul>
<h2 class="heading" id="безопасность">
  Безопасность
  <a class="anchor" href="#%d0%b1%d0%b5%d0%b7%d0%be%d0%bf%d0%b0%d1%81%d0%bd%d0%be%d1%81%d1%82%d1%8c">#</a>
</h2>
<ul>
<li>Шифрование хранилища</li>
<li>Использование приватных репозиториев</li>
<li>Регулярное резервное копирование</li>
</ul>
<h2 class="heading" id="заключение">
  Заключение
  <a class="anchor" href="#%d0%b7%d0%b0%d0%ba%d0%bb%d1%8e%d1%87%d0%b5%d0%bd%d0%b8%d0%b5">#</a>
</h2>
<p>Obsidian - мощный инструмент для тех, кто серьезно относится к управлению знаниями. Локальность, расширяемость и удобство делают его отличным выбором для разработчиков, исследователей и профессионалов.</p>
<h3 class="heading" id="полезные-ресурсы">
  Полезные ресурсы
  <a class="anchor" href="#%d0%bf%d0%be%d0%bb%d0%b5%d0%b7%d0%bd%d1%8b%d0%b5-%d1%80%d0%b5%d1%81%d1%83%d1%80%d1%81%d1%8b">#</a>
</h3>
<ul>
<li><a href="https://help.obsidian.md">Официальная документация</a></li>
<li><a href="https://forum.obsidian.md">Форум сообщества</a></li>
<li><a href="https://www.reddit.com/r/ObsidianMD/">Reddit-сообщество</a></li>
</ul>
<p><strong>Совет</strong>: Начните с малого, постепенно изучайте возможности и создавайте свою систему знаний!</p>
]]></content:encoded><category>Productivity</category><category>Notes</category><category>Knowledge Management</category></item><item><title>📚📖 Markdown: Продвинутые техники для Power Users</title><link>https://kushnaren.co/posts/2024-06-04-markdown-poweruser-techniques/</link><pubDate>Tue, 04 Jun 2024 10:00:00 +0300</pubDate><guid isPermaLink="true">https://kushnaren.co/posts/2024-06-04-markdown-poweruser-techniques/</guid><description>Секретные приемы и расширенные возможности Markdown для опытных пользователей</description><content:encoded><![CDATA[<p>










<figure class="">
  
  
    <div class="img-container">
      <img loading="lazy" alt="Futuristic Digital Workspace" src="/img/posts/markdown-poweruser-techniques/futuristic-digital-workspace-markdown-techniques.webp">
    </div>
  

  
</figure>
</p>
<h2 class="heading" id="-введение-в-power-user-markdown">
  🚀 Введение в Power User Markdown
  <a class="anchor" href="#-%d0%b2%d0%b2%d0%b5%d0%b4%d0%b5%d0%bd%d0%b8%d0%b5-%d0%b2-power-user-markdown">#</a>
</h2>
<p>Если вы уже знакомы с базовым Markdown, эта статья откроет вам новые горизонты использования этого мощного инструмента разметки.</p>
<h2 class="heading" id="-расширенные-синтаксические-трюки">
  🔧 Расширенные синтаксические трюки
  <a class="anchor" href="#-%d1%80%d0%b0%d1%81%d1%88%d0%b8%d1%80%d0%b5%d0%bd%d0%bd%d1%8b%d0%b5-%d1%81%d0%b8%d0%bd%d1%82%d0%b0%d0%ba%d1%81%d0%b8%d1%87%d0%b5%d1%81%d0%ba%d0%b8%d0%b5-%d1%82%d1%80%d1%8e%d0%ba%d0%b8">#</a>
</h2>
<h3 class="heading" id="кастомные-id-для-заголовков">
  Кастомные ID для заголовков
  <a class="anchor" href="#%d0%ba%d0%b0%d1%81%d1%82%d0%be%d0%bc%d0%bd%d1%8b%d0%b5-id-%d0%b4%d0%bb%d1%8f-%d0%b7%d0%b0%d0%b3%d0%be%d0%bb%d0%be%d0%b2%d0%ba%d0%be%d0%b2">#</a>
</h3>
<h4 class="heading" id="markdown">
  Markdown
  <a class="anchor" href="#markdown">#</a>
</h4>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="cl"><span class="gu">### Мой заголовок {#custom-anchor}
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">[<span class="nt">Ссылка на кастомный заголовок</span>](<span class="na">#custom-anchor</span>)</span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<h4 class="heading" id="результат">
  Результат
  <a class="anchor" href="#%d1%80%d0%b5%d0%b7%d1%83%d0%bb%d1%8c%d1%82%d0%b0%d1%82">#</a>
</h4>
<h3 class="heading" id="мой-заголовок">
  Мой заголовок
  <a class="anchor" href="#%d0%bc%d0%be%d0%b9-%d0%b7%d0%b0%d0%b3%d0%be%d0%bb%d0%be%d0%b2%d0%be%d0%ba">#</a>
</h3>
<p><a href="#custom-anchor">Ссылка на кастомный заголовок</a></p>
<h4 class="heading" id="применение">
  Применение
  <a class="anchor" href="#%d0%bf%d1%80%d0%b8%d0%bc%d0%b5%d0%bd%d0%b5%d0%bd%d0%b8%d0%b5">#</a>
</h4>
<ul>
<li>Создание уникальных якорей</li>
<li>Возможность прямой навигации</li>
<li>Улучшение структуры документа</li>
</ul>
<h3 class="heading" id="аббревиатуры">
  Аббревиатуры
  <a class="anchor" href="#%d0%b0%d0%b1%d0%b1%d1%80%d0%b5%d0%b2%d0%b8%d0%b0%d1%82%d1%83%d1%80%d1%8b">#</a>
</h3>
<p>Markdown</p>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="cl">*[HTML]: Hyper Text Markup Language
</span></span><span class="line"><span class="cl">*[W3C]: World Wide Web Consortium
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">HTML - язык разметки, стандартизированный W3C.</span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<p>Результат</p>
<p>*[HTML]: Hyper Text Markup Language
*[W3C]: World Wide Web Consortium</p>
<p>HTML - язык разметки, стандартизированный W3C.</p>
<p>Преимущества</p>
<ul>
<li>Встроенные расшифровки терминов</li>
<li>Всплывающие подсказки</li>
<li>Улучшение читаемости технических текстов</li>
</ul>
<h2 class="heading" id="-продвинутое-форматирование">
  💡 Продвинутое форматирование
  <a class="anchor" href="#-%d0%bf%d1%80%d0%be%d0%b4%d0%b2%d0%b8%d0%bd%d1%83%d1%82%d0%be%d0%b5-%d1%84%d0%be%d1%80%d0%bc%d0%b0%d1%82%d0%b8%d1%80%d0%be%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5">#</a>
</h2>
<h3 class="heading" id="математические-формулы">
  Математические формулы
  <a class="anchor" href="#%d0%bc%d0%b0%d1%82%d0%b5%d0%bc%d0%b0%d1%82%d0%b8%d1%87%d0%b5%d1%81%d0%ba%d0%b8%d0%b5-%d1%84%d0%be%d1%80%d0%bc%d1%83%d0%bb%d1%8b">#</a>
</h3>
<p>Markdown</p>
<div class="code-block">
  <pre tabindex="0"><code class="language-math" data-lang="math">\int_{a}^{b} f(x) dx = F(b) - F(a)</code></pre>
  <button class="copy-code-button">copy</button>
</div>
<p>Результат</p>
<div class="code-block">
  <pre tabindex="0"><code class="language-math" data-lang="math">\int_{a}^{b} f(x) dx = F(b) - F(a)</code></pre>
  <button class="copy-code-button">copy</button>
</div>
<p>Применение</p>
<ul>
<li>Научные публикации</li>
<li>Технические документы</li>
<li>Академические записки</li>
</ul>
<h3 class="heading" id="диаграммы-и-блок-схемы">
  Диаграммы и блок-схемы
  <a class="anchor" href="#%d0%b4%d0%b8%d0%b0%d0%b3%d1%80%d0%b0%d0%bc%d0%bc%d1%8b-%d0%b8-%d0%b1%d0%bb%d0%be%d0%ba-%d1%81%d1%85%d0%b5%d0%bc%d1%8b">#</a>
</h3>
<p>В современных системах документации существует множество способов визуализации алгоритмов и процессов:</p>
<ul>
<li>PlantUML</li>
<li>Graphviz</li>
<li>Mermaid</li>
<li>Draw.io</li>
<li>Excalidraw</li>
</ul>
<p>Каждый из этих инструментов имеет свои преимущества:</p>
<ol>
<li><strong>PlantUML</strong>: Текстовое описание диаграмм</li>
<li><strong>Graphviz</strong>: Генерация графов</li>
<li><strong>Mermaid</strong>: Встраиваемые диаграммы в Markdown</li>
<li><strong>Draw.io</strong>: Визуальный редактор</li>
<li><strong>Excalidraw</strong>: Рукописные схемы</li>
</ol>
<h4 class="heading" id="возможности">
  Возможности
  <a class="anchor" href="#%d0%b2%d0%be%d0%b7%d0%bc%d0%be%d0%b6%d0%bd%d0%be%d1%81%d1%82%d0%b8">#</a>
</h4>
<ul>
<li>Визуализация алгоритмов</li>
<li>Построение схем процессов</li>
<li>Наглядное представление логики</li>
</ul>
<h2 class="heading" id="-расширенное-форматирование">
  🎨 Расширенное форматирование
  <a class="anchor" href="#-%d1%80%d0%b0%d1%81%d1%88%d0%b8%d1%80%d0%b5%d0%bd%d0%bd%d0%be%d0%b5-%d1%84%d0%be%d1%80%d0%bc%d0%b0%d1%82%d0%b8%d1%80%d0%be%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5">#</a>
</h2>
<h3 class="heading" id="сноски-с-метками">
  Сноски с метками
  <a class="anchor" href="#%d1%81%d0%bd%d0%be%d1%81%d0%ba%d0%b8-%d1%81-%d0%bc%d0%b5%d1%82%d0%ba%d0%b0%d0%bc%d0%b8">#</a>
</h3>
<p>Markdown</p>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="cl">Текст с расширенной сноской[^detailed].
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">[^detailed]: 
</span></span><span class="line"><span class="cl">    Подробная сноска может содержать:
</span></span><span class="line"><span class="cl">    <span class="k">-</span> Многострочный текст
</span></span><span class="line"><span class="cl">    <span class="k">-</span> Список
</span></span><span class="line"><span class="cl">    <span class="k">-</span> Даже код
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    ``<span class="sb">`python
</span></span></span><span class="line"><span class="cl"><span class="sb">    def example():
</span></span></span><span class="line"><span class="cl"><span class="sb">        return &#34;Мощь сносок!&#34;
</span></span></span><span class="line"><span class="cl"><span class="sb">    `</span>``</span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<p>Результат</p>
<p>Текст с расширенной сноской<a href="#fn:1">1</a>.</p>
<ul>
<li>
<p>Многострочный текст</p>
</li>
<li>
<p>Список</p>
</li>
<li>
<p>Даже код</p>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">example</span><span class="p">():</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="s2">&#34;Мощь сносок!&#34;</span></span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
</li>
</ul>
<h4 class="heading" id="преимущества">
  Преимущества
  <a class="anchor" href="#%d0%bf%d1%80%d0%b5%d0%b8%d0%bc%d1%83%d1%89%d0%b5%d1%81%d1%82%d0%b2%d0%b0">#</a>
</h4>
<ul>
<li>Многострочные сноски</li>
<li>Возможность добавления кода</li>
<li>Улучшенная информативность</li>
</ul>
<h3 class="heading" id="задачи-с-приоритетами">
  Задачи с приоритетами
  <a class="anchor" href="#%d0%b7%d0%b0%d0%b4%d0%b0%d1%87%d0%b8-%d1%81-%d0%bf%d1%80%d0%b8%d0%be%d1%80%d0%b8%d1%82%d0%b5%d1%82%d0%b0%d0%bc%d0%b8">#</a>
</h3>
<p>Markdown</p>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="cl"><span class="k">- [x]</span> Высокий приоритет ⚡
</span></span><span class="line"><span class="cl"><span class="k">- [ ]</span> Средний приоритет 🔶
</span></span><span class="line"><span class="cl">- [ ] Низкий приоритет 🕰️</span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<p>Результат</p>
<ul>
<li>Высокий приоритет ⚡</li>
<li>Средний приоритет 🔶</li>
<li>Низкий приоритет 🕰️</li>
</ul>
<h2 class="heading" id="-продвинутые-техники">
  🔬 Продвинутые техники
  <a class="anchor" href="#-%d0%bf%d1%80%d0%be%d0%b4%d0%b2%d0%b8%d0%bd%d1%83%d1%82%d1%8b%d0%b5-%d1%82%d0%b5%d1%85%d0%bd%d0%b8%d0%ba%d0%b8">#</a>
</h2>
<h3 class="heading" id="условный-рендеринг">
  Условный рендеринг
  <a class="anchor" href="#%d1%83%d1%81%d0%bb%d0%be%d0%b2%d0%bd%d1%8b%d0%b9-%d1%80%d0%b5%d0%bd%d0%b4%d0%b5%d1%80%d0%b8%d0%bd%d0%b3">#</a>
</h3>
<p>Markdown</p>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="cl">{% if user.is_admin %}
</span></span><span class="line"><span class="cl"><span class="gu">## Административная панель
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">-</span> Управление пользователями
</span></span><span class="line"><span class="cl"><span class="k">-</span> Настройки системы
</span></span><span class="line"><span class="cl">{% endif %}</span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<p>Применение</p>
<ul>
<li>Динамические документы</li>
<li>Контекстные руководства</li>
<li>Персонализированный контент</li>
</ul>
<h3 class="heading" id="переменные-и-шаблоны">
  Переменные и шаблоны
  <a class="anchor" href="#%d0%bf%d0%b5%d1%80%d0%b5%d0%bc%d0%b5%d0%bd%d0%bd%d1%8b%d0%b5-%d0%b8-%d1%88%d0%b0%d0%b1%d0%bb%d0%be%d0%bd%d1%8b">#</a>
</h3>
<p>Markdown</p>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="cl">{%raw%}
</span></span><span class="line"><span class="cl">{{ variable_name }}
</span></span><span class="line"><span class="cl">{{ for item in list }}
</span></span><span class="line"><span class="cl">    <span class="k">-</span> {{ item }}
</span></span><span class="line"><span class="cl">{{ endfor }}
</span></span><span class="line"><span class="cl">{%endraw%}</span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<h4 class="heading" id="сценарии-использования">
  Сценарии использования
  <a class="anchor" href="#%d1%81%d1%86%d0%b5%d0%bd%d0%b0%d1%80%d0%b8%d0%b8-%d0%b8%d1%81%d0%bf%d0%be%d0%bb%d1%8c%d0%b7%d0%be%d0%b2%d0%b0%d0%bd%d0%b8%d1%8f">#</a>
</h4>
<ul>
<li>Генерация документации</li>
<li>Автоматизация контента</li>
<li>Шаблонизация записей</li>
</ul>
<h2 class="heading" id="-полезные-расширения">
  🛠️ Полезные расширения
  <a class="anchor" href="#-%d0%bf%d0%be%d0%bb%d0%b5%d0%b7%d0%bd%d1%8b%d0%b5-%d1%80%d0%b0%d1%81%d1%88%d0%b8%d1%80%d0%b5%d0%bd%d0%b8%d1%8f">#</a>
</h2>
<ol>
<li><strong>Pandoc</strong>: Конвертация между форматами</li>
<li><strong>Markdeep</strong>: Расширенная визуализация</li>
<li><strong>Obsidian</strong>: Продвинутая работа с Markdown</li>
<li><strong>VS Code</strong>: Плагины для Markdown</li>
</ol>
<h2 class="heading" id="-советы-power-user">
  💪 Советы Power User
  <a class="anchor" href="#-%d1%81%d0%be%d0%b2%d0%b5%d1%82%d1%8b-power-user">#</a>
</h2>
<ol>
<li>Используйте линтеры для Markdown</li>
<li>Автоматизируйте форматирование</li>
<li>Создавайте собственные шаблоны</li>
<li>Экспериментируйте с расширениями</li>
</ol>
<h2 class="heading" id="-заключение">
  🤔 Заключение
  <a class="anchor" href="#-%d0%b7%d0%b0%d0%ba%d0%bb%d1%8e%d1%87%d0%b5%d0%bd%d0%b8%d0%b5">#</a>
</h2>
<p>Markdown - это не просто разметка, это мощный инструмент для создания и структурирования контента. Постоянно изучайте новые техники!</p>
<h3 class="heading" id="-дополнительные-ресурсы">
  📚 Дополнительные ресурсы
  <a class="anchor" href="#-%d0%b4%d0%be%d0%bf%d0%be%d0%bb%d0%bd%d0%b8%d1%82%d0%b5%d0%bb%d1%8c%d0%bd%d1%8b%d0%b5-%d1%80%d0%b5%d1%81%d1%83%d1%80%d1%81%d1%8b">#</a>
</h3>
<ul>
<li><a href="https://spec.commonmark.org/">CommonMark Spec</a></li>
<li><a href="https://github.github.com/gfm/">GitHub Flavored Markdown</a></li>
<li><a href="https://www.markdownguide.org/">Markdown Guide</a></li>
</ul>
<hr>
<ol>
<li>Подробная сноска может содержать: <a href="#fnref:1">↩︎</a></li>
</ol>
]]></content:encoded><category>Markdown</category><category>Productivity</category><category>Advanced</category></item><item><title>🐳 Как настроить Docker Registry в Gitea 🚢</title><link>https://kushnaren.co/posts/2024-04-25-gitea-docker-registry/</link><pubDate>Thu, 25 Apr 2024 10:00:00 +0300</pubDate><guid isPermaLink="true">https://kushnaren.co/posts/2024-04-25-gitea-docker-registry/</guid><description>Подробное руководство по включению и настройке Docker Registry в Gitea, установленной как бинарник в Linux 🔧</description><content:encoded><![CDATA[<h2 class="heading" id="введение-">
  Введение 🌟
  <a class="anchor" href="#%d0%b2%d0%b2%d0%b5%d0%b4%d0%b5%d0%bd%d0%b8%d0%b5-">#</a>
</h2>
<p>Если вы установили <a href="https://gitea.io/">Gitea</a> как бинарник в Linux и хотите настроить собственный Docker Registry, этот гайд для вас! 🐳 Мы рассмотрим все шаги от настройки до практического использования.</p>
<h2 class="heading" id="предварительные-требования-">
  Предварительные требования 📋
  <a class="anchor" href="#%d0%bf%d1%80%d0%b5%d0%b4%d0%b2%d0%b0%d1%80%d0%b8%d1%82%d0%b5%d0%bb%d1%8c%d0%bd%d1%8b%d0%b5-%d1%82%d1%80%d0%b5%d0%b1%d0%be%d0%b2%d0%b0%d0%bd%d0%b8%d1%8f-">#</a>
</h2>
<ul>
<li>Установленная Gitea в виде бинарника ✅</li>
<li>Установленный Docker 🐳</li>
<li>Доступ к серверу с правами администратора 🔑</li>
<li>Базовые навыки работы в Linux 🖥️</li>
</ul>
<h2 class="heading" id="шаг-1-проверка-текущей-конфигурации-gitea-">
  Шаг 1: Проверка текущей конфигурации Gitea 🕵️
  <a class="anchor" href="#%d1%88%d0%b0%d0%b3-1-%d0%bf%d1%80%d0%be%d0%b2%d0%b5%d1%80%d0%ba%d0%b0-%d1%82%d0%b5%d0%ba%d1%83%d1%89%d0%b5%d0%b9-%d0%ba%d0%be%d0%bd%d1%84%d0%b8%d0%b3%d1%83%d1%80%d0%b0%d1%86%d0%b8%d0%b8-gitea-">#</a>
</h2>
<p>Найдите конфигурационный файл Gitea. Обычно он расположен по пути:</p>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">/etc/gitea/app.ini</span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<p>Откройте его:</p>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">nano /etc/gitea/app.ini</span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<h2 class="heading" id="шаг-2-включение-docker-registry-">
  Шаг 2: Включение Docker Registry 🚢
  <a class="anchor" href="#%d1%88%d0%b0%d0%b3-2-%d0%b2%d0%ba%d0%bb%d1%8e%d1%87%d0%b5%d0%bd%d0%b8%d0%b5-docker-registry-">#</a>
</h2>
<p>Добавьте в <code>app.ini</code> следующие настройки:</p>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ini" data-lang="ini"><span class="line"><span class="cl"><span class="k">[docker]</span>
</span></span><span class="line"><span class="cl"><span class="na">ENABLED</span> <span class="o">=</span> <span class="s">true</span>
</span></span><span class="line"><span class="cl"><span class="na">REGISTRY_HOST</span> <span class="o">=</span> <span class="s">registry.kushnaren.co</span></span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<h2 class="heading" id="шаг-3-настройка-прав-доступа-">
  Шаг 3: Настройка прав доступа 🔐
  <a class="anchor" href="#%d1%88%d0%b0%d0%b3-3-%d0%bd%d0%b0%d1%81%d1%82%d1%80%d0%be%d0%b9%d0%ba%d0%b0-%d0%bf%d1%80%d0%b0%d0%b2-%d0%b4%d0%be%d1%81%d1%82%d1%83%d0%bf%d0%b0-">#</a>
</h2>
<p>Убедитесь, что пользователь Gitea имеет необходимые права:</p>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Проверьте текущего пользователя Gitea</span>
</span></span><span class="line"><span class="cl">grep User /etc/systemd/system/gitea.service
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># При необходимости измените права</span>
</span></span><span class="line"><span class="cl">chown -R git:git /path/to/docker/registry</span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<h2 class="heading" id="шаг-4-конфигурация-docker-registry-">
  Шаг 4: Конфигурация Docker Registry 🔧
  <a class="anchor" href="#%d1%88%d0%b0%d0%b3-4-%d0%ba%d0%be%d0%bd%d1%84%d0%b8%d0%b3%d1%83%d1%80%d0%b0%d1%86%d0%b8%d1%8f-docker-registry-">#</a>
</h2>
<p>Создайте директорию для хранения образов:</p>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">mkdir -p /var/lib/gitea/docker-registry
</span></span><span class="line"><span class="cl">chown -R git:git /var/lib/gitea/docker-registry</span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<h2 class="heading" id="шаг-5-перезапуск-gitea-">
  Шаг 5: Перезапуск Gitea 🔄
  <a class="anchor" href="#%d1%88%d0%b0%d0%b3-5-%d0%bf%d0%b5%d1%80%d0%b5%d0%b7%d0%b0%d0%bf%d1%83%d1%81%d0%ba-gitea-">#</a>
</h2>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">systemctl restart gitea</span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<h2 class="heading" id="проверка-работоспособности-">
  Проверка работоспособности 🕹️
  <a class="anchor" href="#%d0%bf%d1%80%d0%be%d0%b2%d0%b5%d1%80%d0%ba%d0%b0-%d1%80%d0%b0%d0%b1%d0%be%d1%82%d0%be%d1%81%d0%bf%d0%be%d1%81%d0%be%d0%b1%d0%bd%d0%be%d1%81%d1%82%d0%b8-">#</a>
</h2>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Проверьте статус Gitea</span>
</span></span><span class="line"><span class="cl">systemctl status gitea
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Проверьте порты</span>
</span></span><span class="line"><span class="cl">netstat -tulpn <span class="p">|</span> grep gitea</span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<h2 class="heading" id="аутентификация-и-использование-">
  Аутентификация и использование 🔑
  <a class="anchor" href="#%d0%b0%d1%83%d1%82%d0%b5%d0%bd%d1%82%d0%b8%d1%84%d0%b8%d0%ba%d0%b0%d1%86%d0%b8%d1%8f-%d0%b8-%d0%b8%d1%81%d0%bf%d0%be%d0%bb%d1%8c%d0%b7%d0%be%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5-">#</a>
</h2>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Логин в локальный Docker Registry</span>
</span></span><span class="line"><span class="cl">docker login registry.kushnaren.co
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Создание и пуш образа</span>
</span></span><span class="line"><span class="cl">docker build -t registry.kushnaren.co/username/repo/image:tag .
</span></span><span class="line"><span class="cl">docker push registry.kushnaren.co/username/repo/image:tag</span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<h2 class="heading" id="безопасность-">
  Безопасность 🚨
  <a class="anchor" href="#%d0%b1%d0%b5%d0%b7%d0%be%d0%bf%d0%b0%d1%81%d0%bd%d0%be%d1%81%d1%82%d1%8c-">#</a>
</h2>
<p>🔒 Дополнительные рекомендации:</p>
<ul>
<li>Используйте HTTPS 🔐</li>
<li>Настройте fail2ban</li>
<li>Регулярно обновляйте Gitea</li>
<li>Используйте строгие правила паролей 🛡️</li>
</ul>
<h2 class="heading" id="troubleshooting-">
  Troubleshooting 🔍
  <a class="anchor" href="#troubleshooting-">#</a>
</h2>
<h3 class="heading" id="частые-проблемы-">
  Частые проблемы 🛠️
  <a class="anchor" href="#%d1%87%d0%b0%d1%81%d1%82%d1%8b%d0%b5-%d0%bf%d1%80%d0%be%d0%b1%d0%bb%d0%b5%d0%bc%d1%8b-">#</a>
</h3>
<ol>
<li>
<p><strong>Ошибки доступа</strong> 🚫</p>
<ul>
<li>Проверьте права пользователя</li>
<li>Убедитесь в корректности путей</li>
</ul>
</li>
<li>
<p><strong>Проблемы с портами</strong> 🌐</p>
<ul>
<li>Проверьте firewall</li>
<li>Убедитесь, что порты не заняты</li>
</ul>
</li>
</ol>
<h2 class="heading" id="заключение-">
  Заключение 🏁
  <a class="anchor" href="#%d0%b7%d0%b0%d0%ba%d0%bb%d1%8e%d1%87%d0%b5%d0%bd%d0%b8%d0%b5-">#</a>
</h2>
<p>Docker Registry в Gitea - отличный способ иметь приватное хранилище образов прямо на вашем сервере. Следуя этой инструкции, вы легко настроите registry для вашей инфраструктуры. 🐳🚢</p>
<h2 class="heading" id="полезные-ссылки-">
  Полезные ссылки 🔗
  <a class="anchor" href="#%d0%bf%d0%be%d0%bb%d0%b5%d0%b7%d0%bd%d1%8b%d0%b5-%d1%81%d1%81%d1%8b%d0%bb%d0%ba%d0%b8-">#</a>
</h2>
<ul>
<li><a href="https://docs.gitea.io/">Официальная документация Gitea</a> 📖</li>
<li><a href="https://docs.docker.com/registry/">Docker Registry Documentation</a> 🐳</li>
</ul>
<hr>
]]></content:encoded><category>Gitea</category><category>Docker</category><category>Registry</category><category>Linux</category><category>DevOps</category></item><item><title>📚 Git: Полное Руководство от Новичка до Профессионала</title><link>https://kushnaren.co/posts/2024-02-05-git-basics-and-core-functions/</link><pubDate>Mon, 05 Feb 2024 10:00:00 +0300</pubDate><guid isPermaLink="true">https://kushnaren.co/posts/2024-02-05-git-basics-and-core-functions/</guid><description>Comprehensive guide to Git - от основ до продвинутых техник управления версиями</description><content:encoded><![CDATA[<h2 class="heading" id="-введение-в-систему-контроля-версий">
  🌐 Введение в Систему Контроля Версий
  <a class="anchor" href="#-%d0%b2%d0%b2%d0%b5%d0%b4%d0%b5%d0%bd%d0%b8%d0%b5-%d0%b2-%d1%81%d0%b8%d1%81%d1%82%d0%b5%d0%bc%d1%83-%d0%ba%d0%be%d0%bd%d1%82%d1%80%d0%be%d0%bb%d1%8f-%d0%b2%d0%b5%d1%80%d1%81%d0%b8%d0%b9">#</a>
</h2>
<h3 class="heading" id="что-такое-git">
  Что такое Git?
  <a class="anchor" href="#%d1%87%d1%82%d0%be-%d1%82%d0%b0%d0%ba%d0%be%d0%b5-git">#</a>
</h3>
<p>Git - распределенная система контроля версий (DVCS), созданная Линусом Торвальдсом в 2005 году. Ключевые особенности:</p>
<ul>
<li><strong>Распределенность</strong>: Каждый разработчик имеет полную копию репозитория</li>
<li><strong>Целостность</strong>: Невозможно изменить файл без ведома системы</li>
<li><strong>Производительность</strong>: Молниеносные операции</li>
<li><strong>Ветвление</strong>: Легкое создание и слияние веток</li>
</ul>
<h3 class="heading" id="преимущества-распределенной-системы-контроля-версий">
  Преимущества Распределенной Системы Контроля Версий
  <a class="anchor" href="#%d0%bf%d1%80%d0%b5%d0%b8%d0%bc%d1%83%d1%89%d0%b5%d1%81%d1%82%d0%b2%d0%b0-%d1%80%d0%b0%d1%81%d0%bf%d1%80%d0%b5%d0%b4%d0%b5%d0%bb%d0%b5%d0%bd%d0%bd%d0%be%d0%b9-%d1%81%d0%b8%d1%81%d1%82%d0%b5%d0%bc%d1%8b-%d0%ba%d0%be%d0%bd%d1%82%d1%80%d0%be%d0%bb%d1%8f-%d0%b2%d0%b5%d1%80%d1%81%d0%b8%d0%b9">#</a>
</h3>
<p>Распределенная природа Git предоставляет ряд существенных преимуществ:</p>
<ol>
<li>
<p><strong>Полная локальная история</strong>: Каждый разработчик имеет полную копию истории проекта, что обеспечивает:</p>
<ul>
<li>Независимость от центрального сервера</li>
<li>Возможность работы оффлайн</li>
<li>Быстрые операции без необходимости постоянного подключения к удаленному репозиторию</li>
</ul>
</li>
<li>
<p><strong>Отказоустойчивость</strong>:</p>
<ul>
<li>Каждая копия репозитория является полным бэкапом</li>
<li>Потеря одного репозитория не приводит к потере всей истории проекта</li>
</ul>
</li>
<li>
<p><strong>Гибкость рабочего процесса</strong>:</p>
<ul>
<li>Легкое создание веток и экспериментирование</li>
<li>Простое совместное развитие проекта</li>
<li>Возможность работы с различными моделями разработки</li>
</ul>
</li>
</ol>
<h3 class="heading" id="почему-git">
  Почему Git?
  <a class="anchor" href="#%d0%bf%d0%be%d1%87%d0%b5%d0%bc%d1%83-git">#</a>
</h3>
<ol>
<li><strong>Совместная разработка</strong></li>
<li><strong>Отслеживание изменений</strong></li>
<li><strong>Возможность отката</strong></li>
<li><strong>Параллельная работа</strong></li>
</ol>
<h2 class="heading" id="-установка-и-настройка">
  🔧 Установка и Настройка
  <a class="anchor" href="#-%d1%83%d1%81%d1%82%d0%b0%d0%bd%d0%be%d0%b2%d0%ba%d0%b0-%d0%b8-%d0%bd%d0%b0%d1%81%d1%82%d1%80%d0%be%d0%b9%d0%ba%d0%b0">#</a>
</h2>
<h3 class="heading" id="установка-на-разных-платформах">
  Установка на разных платформах
  <a class="anchor" href="#%d1%83%d1%81%d1%82%d0%b0%d0%bd%d0%be%d0%b2%d0%ba%d0%b0-%d0%bd%d0%b0-%d1%80%d0%b0%d0%b7%d0%bd%d1%8b%d1%85-%d0%bf%d0%bb%d0%b0%d1%82%d1%84%d0%be%d1%80%d0%bc%d0%b0%d1%85">#</a>
</h3>
<h4 class="heading" id="macos">
  macOS
  <a class="anchor" href="#macos">#</a>
</h4>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Предпочтительный метод через Homebrew для простоты обновлений</span>
</span></span><span class="line"><span class="cl">brew install git
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Альтернативный способ через официальный установщик</span>
</span></span><span class="line"><span class="cl">https://git-scm.com/download/mac</span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<h4 class="heading" id="linux-ubuntudebian">
  Linux (Ubuntu/Debian)
  <a class="anchor" href="#linux-ubuntudebian">#</a>
</h4>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo apt update
</span></span><span class="line"><span class="cl">sudo apt install git</span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<h4 class="heading" id="windows">
  Windows
  <a class="anchor" href="#windows">#</a>
</h4>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Рекомендуется использовать Git Bash для унифицированного интерфейса</span>
</span></span><span class="line"><span class="cl"><span class="c1"># Скачать с официального сайта: https://git-scm.com/download/win</span></span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<h3 class="heading" id="первичная-конфигурация">
  Первичная Конфигурация
  <a class="anchor" href="#%d0%bf%d0%b5%d1%80%d0%b2%d0%b8%d1%87%d0%bd%d0%b0%d1%8f-%d0%ba%d0%be%d0%bd%d1%84%d0%b8%d0%b3%d1%83%d1%80%d0%b0%d1%86%d0%b8%d1%8f">#</a>
</h3>
<h4 class="heading" id="настройка-идентификационных-данных">
  Настройка идентификационных данных
  <a class="anchor" href="#%d0%bd%d0%b0%d1%81%d1%82%d1%80%d0%be%d0%b9%d0%ba%d0%b0-%d0%b8%d0%b4%d0%b5%d0%bd%d1%82%d0%b8%d1%84%d0%b8%d0%ba%d0%b0%d1%86%d0%b8%d0%be%d0%bd%d0%bd%d1%8b%d1%85-%d0%b4%d0%b0%d0%bd%d0%bd%d1%8b%d1%85">#</a>
</h4>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Установка имени пользователя</span>
</span></span><span class="line"><span class="cl">git config --global user.name <span class="s2">&#34;Ваше Имя&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Установка электронной почты</span>
</span></span><span class="line"><span class="cl">git config --global user.email <span class="s2">&#34;your.email@example.com&#34;</span></span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<h4 class="heading" id="настройка-редактора-по-умолчанию">
  Настройка редактора по умолчанию
  <a class="anchor" href="#%d0%bd%d0%b0%d1%81%d1%82%d1%80%d0%be%d0%b9%d0%ba%d0%b0-%d1%80%d0%b5%d0%b4%d0%b0%d0%ba%d1%82%d0%be%d1%80%d0%b0-%d0%bf%d0%be-%d1%83%d0%bc%d0%be%d0%bb%d1%87%d0%b0%d0%bd%d0%b8%d1%8e">#</a>
</h4>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Для Vim</span>
</span></span><span class="line"><span class="cl">git config --global core.editor <span class="s2">&#34;vim&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Для Nano</span>
</span></span><span class="line"><span class="cl">git config --global core.editor <span class="s2">&#34;nano&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Для VS Code</span>
</span></span><span class="line"><span class="cl">git config --global core.editor <span class="s2">&#34;code --wait&#34;</span></span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<h4 class="heading" id="проверка-конфигурации">
  Проверка конфигурации
  <a class="anchor" href="#%d0%bf%d1%80%d0%be%d0%b2%d0%b5%d1%80%d0%ba%d0%b0-%d0%ba%d0%be%d0%bd%d1%84%d0%b8%d0%b3%d1%83%d1%80%d0%b0%d1%86%d0%b8%d0%b8">#</a>
</h4>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Просмотр текущей конфигурации</span>
</span></span><span class="line"><span class="cl">git config --list</span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<h2 class="heading" id="-основы-работы-с-репозиторием">
  🏗️ Основы Работы с Репозиторием
  <a class="anchor" href="#-%d0%be%d1%81%d0%bd%d0%be%d0%b2%d1%8b-%d1%80%d0%b0%d0%b1%d0%be%d1%82%d1%8b-%d1%81-%d1%80%d0%b5%d0%bf%d0%be%d0%b7%d0%b8%d1%82%d0%be%d1%80%d0%b8%d0%b5%d0%bc">#</a>
</h2>
<h3 class="heading" id="создание-репозитория">
  Создание Репозитория
  <a class="anchor" href="#%d1%81%d0%be%d0%b7%d0%b4%d0%b0%d0%bd%d0%b8%d0%b5-%d1%80%d0%b5%d0%bf%d0%be%d0%b7%d0%b8%d1%82%d0%be%d1%80%d0%b8%d1%8f">#</a>
</h3>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Создание нового репозитория</span>
</span></span><span class="line"><span class="cl">mkdir my_project
</span></span><span class="line"><span class="cl"><span class="nb">cd</span> my_project
</span></span><span class="line"><span class="cl">git init
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Клонирование существующего</span>
</span></span><span class="line"><span class="cl">git clone https://github.com/username/repository.git
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Клонирование с указанием ветки</span>
</span></span><span class="line"><span class="cl">git clone -b develop https://github.com/username/repository.git</span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<h3 class="heading" id="состояния-файлов">
  Состояния Файлов
  <a class="anchor" href="#%d1%81%d0%be%d1%81%d1%82%d0%be%d1%8f%d0%bd%d0%b8%d1%8f-%d1%84%d0%b0%d0%b9%d0%bb%d0%be%d0%b2">#</a>
</h3>
<ol>
<li><strong>Untracked</strong>: Новый файл</li>
<li><strong>Unmodified</strong>: Файл не изменен</li>
<li><strong>Modified</strong>: Файл изменен</li>
<li><strong>Staged</strong>: Файл подготовлен к коммиту</li>
</ol>
<h3 class="heading" id="базовые-операции">
  Базовые Операции
  <a class="anchor" href="#%d0%b1%d0%b0%d0%b7%d0%be%d0%b2%d1%8b%d0%b5-%d0%be%d0%bf%d0%b5%d1%80%d0%b0%d1%86%d0%b8%d0%b8">#</a>
</h3>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Проверка статуса</span>
</span></span><span class="line"><span class="cl">git status
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Добавление файлов</span>
</span></span><span class="line"><span class="cl">git add file.txt       <span class="c1"># Один файл</span>
</span></span><span class="line"><span class="cl">git add .              <span class="c1"># Все файлы</span>
</span></span><span class="line"><span class="cl">git add *.txt          <span class="c1"># Все txt-файлы</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Коммит</span>
</span></span><span class="line"><span class="cl">git commit -m <span class="s2">&#34;Описание изменений&#34;</span>
</span></span><span class="line"><span class="cl">git commit -am <span class="s2">&#34;Коммит с добавлением&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># История коммитов</span>
</span></span><span class="line"><span class="cl">git log
</span></span><span class="line"><span class="cl">git log --oneline      <span class="c1"># Краткий вид</span>
</span></span><span class="line"><span class="cl">git log -p             <span class="c1"># С изменениями</span></span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<h2 class="heading" id="-основы-работы-с-репозиторием-1">
  🗂️ Основы Работы с Репозиторием
  <a class="anchor" href="#-%d0%be%d1%81%d0%bd%d0%be%d0%b2%d1%8b-%d1%80%d0%b0%d0%b1%d0%be%d1%82%d1%8b-%d1%81-%d1%80%d0%b5%d0%bf%d0%be%d0%b7%d0%b8%d1%82%d0%be%d1%80%d0%b8%d0%b5%d0%bc-1">#</a>
</h2>
<h3 class="heading" id="использование-gitignore">
  Использование .gitignore
  <a class="anchor" href="#%d0%b8%d1%81%d0%bf%d0%be%d0%bb%d1%8c%d0%b7%d0%be%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5-gitignore">#</a>
</h3>
<p>Файл <code>.gitignore</code> позволяет исключить определенные файлы и директории из системы контроля версий:</p>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Игнорирование временных файлов</span>
</span></span><span class="line"><span class="cl">*.tmp
</span></span><span class="line"><span class="cl">*.log
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Игнорирование директорий</span>
</span></span><span class="line"><span class="cl">node_modules/
</span></span><span class="line"><span class="cl">build/
</span></span><span class="line"><span class="cl">dist/
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Исключение конфиденциальных файлов</span>
</span></span><span class="line"><span class="cl">.env
</span></span><span class="line"><span class="cl">*.secret
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Исключение файлов IDE</span>
</span></span><span class="line"><span class="cl">.vscode/
</span></span><span class="line"><span class="cl">.idea/</span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<h3 class="heading" id="сравнение-изменений-с-помощью-git-diff">
  Сравнение изменений с помощью git diff
  <a class="anchor" href="#%d1%81%d1%80%d0%b0%d0%b2%d0%bd%d0%b5%d0%bd%d0%b8%d0%b5-%d0%b8%d0%b7%d0%bc%d0%b5%d0%bd%d0%b5%d0%bd%d0%b8%d0%b9-%d1%81-%d0%bf%d0%be%d0%bc%d0%be%d1%89%d1%8c%d1%8e-git-diff">#</a>
</h3>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Показать изменения в незакоммиченных файлах</span>
</span></span><span class="line"><span class="cl">git diff
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Сравнить staged изменения</span>
</span></span><span class="line"><span class="cl">git diff --staged
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Сравнение между ветками</span>
</span></span><span class="line"><span class="cl">git diff main feature-branch</span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<h2 class="heading" id="-работа-с-ветками">
  🌿 Работа с Ветками
  <a class="anchor" href="#-%d1%80%d0%b0%d0%b1%d0%be%d1%82%d0%b0-%d1%81-%d0%b2%d0%b5%d1%82%d0%ba%d0%b0%d0%bc%d0%b8">#</a>
</h2>
<h3 class="heading" id="основы-ветвления">
  Основы Ветвления
  <a class="anchor" href="#%d0%be%d1%81%d0%bd%d0%be%d0%b2%d1%8b-%d0%b2%d0%b5%d1%82%d0%b2%d0%bb%d0%b5%d0%bd%d0%b8%d1%8f">#</a>
</h3>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Создание ветки</span>
</span></span><span class="line"><span class="cl">git branch feature/login
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Переключение между ветками</span>
</span></span><span class="line"><span class="cl">git checkout feature/login
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Создание и переключение</span>
</span></span><span class="line"><span class="cl">git checkout -b feature/registration
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Список веток</span>
</span></span><span class="line"><span class="cl">git branch
</span></span><span class="line"><span class="cl">git branch -a           <span class="c1"># Включая удаленные</span></span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<h3 class="heading" id="продвинутое-ветвление">
  Продвинутое Ветвление
  <a class="anchor" href="#%d0%bf%d1%80%d0%be%d0%b4%d0%b2%d0%b8%d0%bd%d1%83%d1%82%d0%be%d0%b5-%d0%b2%d0%b5%d1%82%d0%b2%d0%bb%d0%b5%d0%bd%d0%b8%d0%b5">#</a>
</h3>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Переименование ветки</span>
</span></span><span class="line"><span class="cl">git branch -m old_name new_name
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Удаление ветки</span>
</span></span><span class="line"><span class="cl">git branch -d feature/login
</span></span><span class="line"><span class="cl">git branch -D feature/login  <span class="c1"># Принудительно</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Слияние веток</span>
</span></span><span class="line"><span class="cl">git merge feature/login
</span></span><span class="line"><span class="cl">git merge --no-ff feature/login  <span class="c1"># Без fast-forward</span></span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<h3 class="heading" id="стратегии-ветвления">
  Стратегии Ветвления
  <a class="anchor" href="#%d1%81%d1%82%d1%80%d0%b0%d1%82%d0%b5%d0%b3%d0%b8%d0%b8-%d0%b2%d0%b5%d1%82%d0%b2%d0%bb%d0%b5%d0%bd%d0%b8%d1%8f">#</a>
</h3>
<h4 class="heading" id="git-flow">
  Git Flow
  <a class="anchor" href="#git-flow">#</a>
</h4>
<p>Популярная модель ветвления для крупных проектов:</p>
<ul>
<li><code>main</code>: Стабильная версия</li>
<li><code>develop</code>: Ветка разработки</li>
<li><code>feature/*</code>: Ветки новых функций</li>
<li><code>release/*</code>: Подготовка релизов</li>
<li><code>hotfix/*</code>: Критические исправления</li>
</ul>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Создание новой ветки</span>
</span></span><span class="line"><span class="cl">git checkout -b feature/new-authentication
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Переключение между ветками</span>
</span></span><span class="line"><span class="cl">git checkout main
</span></span><span class="line"><span class="cl">git checkout feature/new-authentication
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Слияние веток</span>
</span></span><span class="line"><span class="cl">git checkout main
</span></span><span class="line"><span class="cl">git merge feature/new-authentication</span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<h3 class="heading" id="разрешение-конфликтов-при-слиянии">
  Разрешение Конфликтов при Слиянии
  <a class="anchor" href="#%d1%80%d0%b0%d0%b7%d1%80%d0%b5%d1%88%d0%b5%d0%bd%d0%b8%d0%b5-%d0%ba%d0%be%d0%bd%d1%84%d0%bb%d0%b8%d0%ba%d1%82%d0%be%d0%b2-%d0%bf%d1%80%d0%b8-%d1%81%d0%bb%d0%b8%d1%8f%d0%bd%d0%b8%d0%b8">#</a>
</h3>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># При возникновении конфликтов</span>
</span></span><span class="line"><span class="cl">git merge feature-branch
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Открытие конфликтных файлов</span>
</span></span><span class="line"><span class="cl"><span class="c1"># Ручное редактирование конфликтующих участков</span>
</span></span><span class="line"><span class="cl"><span class="c1"># Удаление маркеров конфликтов (&lt;&lt;&lt;&lt;&lt;&lt;&lt;, =======, &gt;&gt;&gt;&gt;&gt;&gt;&gt;)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># После разрешения конфликтов</span>
</span></span><span class="line"><span class="cl">git add .
</span></span><span class="line"><span class="cl">git commit</span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<h3 class="heading" id="практические-рекомендации-по-работе-с-ветками">
  Практические Рекомендации по Работе с Ветками
  <a class="anchor" href="#%d0%bf%d1%80%d0%b0%d0%ba%d1%82%d0%b8%d1%87%d0%b5%d1%81%d0%ba%d0%b8%d0%b5-%d1%80%d0%b5%d0%ba%d0%be%d0%bc%d0%b5%d0%bd%d0%b4%d0%b0%d1%86%d0%b8%d0%b8-%d0%bf%d0%be-%d1%80%d0%b0%d0%b1%d0%be%d1%82%d0%b5-%d1%81-%d0%b2%d0%b5%d1%82%d0%ba%d0%b0%d0%bc%d0%b8">#</a>
</h3>
<ol>
<li>Создавайте отдельную ветку для каждой логически завершенной задачи</li>
<li>Используйте осмысленные названия веток</li>
<li>Регулярно синхронизируйте свою ветку с основной веткой</li>
<li>Удаляйте ветки после их слияния</li>
</ol>
<h2 class="heading" id="-работа-с-удалёнными-репозиториями">
  🌍 Работа с Удалёнными Репозиториями
  <a class="anchor" href="#-%d1%80%d0%b0%d0%b1%d0%be%d1%82%d0%b0-%d1%81-%d1%83%d0%b4%d0%b0%d0%bb%d1%91%d0%bd%d0%bd%d1%8b%d0%bc%d0%b8-%d1%80%d0%b5%d0%bf%d0%be%d0%b7%d0%b8%d1%82%d0%be%d1%80%d0%b8%d1%8f%d0%bc%d0%b8">#</a>
</h2>
<h3 class="heading" id="основы-работы-с-удаленными-репозиториями">
  Основы Работы с Удаленными Репозиториями
  <a class="anchor" href="#%d0%be%d1%81%d0%bd%d0%be%d0%b2%d1%8b-%d1%80%d0%b0%d0%b1%d0%be%d1%82%d1%8b-%d1%81-%d1%83%d0%b4%d0%b0%d0%bb%d0%b5%d0%bd%d0%bd%d1%8b%d0%bc%d0%b8-%d1%80%d0%b5%d0%bf%d0%be%d0%b7%d0%b8%d1%82%d0%be%d1%80%d0%b8%d1%8f%d0%bc%d0%b8">#</a>
</h3>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Добавление удаленного репозитория</span>
</span></span><span class="line"><span class="cl">git remote add origin https://github.com/username/repository.git
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Список удаленных репозиториев</span>
</span></span><span class="line"><span class="cl">git remote -v
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Загрузка изменений без слияния</span>
</span></span><span class="line"><span class="cl">git fetch origin
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Загрузка и слияние изменений</span>
</span></span><span class="line"><span class="cl">git pull origin main</span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<h3 class="heading" id="различия-между-git-fetch-и-git-pull">
  Различия между git fetch и git pull
  <a class="anchor" href="#%d1%80%d0%b0%d0%b7%d0%bb%d0%b8%d1%87%d0%b8%d1%8f-%d0%bc%d0%b5%d0%b6%d0%b4%d1%83-git-fetch-%d0%b8-git-pull">#</a>
</h3>
<ul>
<li><code>git fetch</code>: Загружает изменения из удаленного репозитория БЕЗ автоматического слияния</li>
<li><code>git pull</code>: Загружает и СРАЗУ СЛИВАЕТ изменения с текущей веткой</li>
</ul>
<h3 class="heading" id="работа-с-несколькими-удаленными-репозиториями">
  Работа с Несколькими Удаленными Репозиториями
  <a class="anchor" href="#%d1%80%d0%b0%d0%b1%d0%be%d1%82%d0%b0-%d1%81-%d0%bd%d0%b5%d1%81%d0%ba%d0%be%d0%bb%d1%8c%d0%ba%d0%b8%d0%bc%d0%b8-%d1%83%d0%b4%d0%b0%d0%bb%d0%b5%d0%bd%d0%bd%d1%8b%d0%bc%d0%b8-%d1%80%d0%b5%d0%bf%d0%be%d0%b7%d0%b8%d1%82%d0%be%d1%80%d0%b8%d1%8f%d0%bc%d0%b8">#</a>
</h3>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Добавление нескольких удаленных источников</span>
</span></span><span class="line"><span class="cl">git remote add upstream https://github.com/original/repository.git
</span></span><span class="line"><span class="cl">git remote add fork https://github.com/myusername/repository.git</span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<h2 class="heading" id="-дополнительные-возможности-git">
  🧩 Дополнительные Возможности Git
  <a class="anchor" href="#-%d0%b4%d0%be%d0%bf%d0%be%d0%bb%d0%bd%d0%b8%d1%82%d0%b5%d0%bb%d1%8c%d0%bd%d1%8b%d0%b5-%d0%b2%d0%be%d0%b7%d0%bc%d0%be%d0%b6%d0%bd%d0%be%d1%81%d1%82%d0%b8-git">#</a>
</h2>
<h3 class="heading" id="работа-с-подмодулями">
  Работа с Подмодулями
  <a class="anchor" href="#%d1%80%d0%b0%d0%b1%d0%be%d1%82%d0%b0-%d1%81-%d0%bf%d0%be%d0%b4%d0%bc%d0%be%d0%b4%d1%83%d0%bb%d1%8f%d0%bc%d0%b8">#</a>
</h3>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Добавление подмодуля</span>
</span></span><span class="line"><span class="cl">git submodule add https://github.com/example/library.git libs/library
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Инициализация подмодулей</span>
</span></span><span class="line"><span class="cl">git submodule init
</span></span><span class="line"><span class="cl">git submodule update
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Клонирование репозитория с подмодулями</span>
</span></span><span class="line"><span class="cl">git clone --recursive https://github.com/example/project.git</span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<h3 class="heading" id="использование-тегов">
  Использование Тегов
  <a class="anchor" href="#%d0%b8%d1%81%d0%bf%d0%be%d0%bb%d1%8c%d0%b7%d0%be%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5-%d1%82%d0%b5%d0%b3%d0%be%d0%b2">#</a>
</h3>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Создание легковесного тега</span>
</span></span><span class="line"><span class="cl">git tag v1.0.0
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Создание аннотированного тега</span>
</span></span><span class="line"><span class="cl">git tag -a v1.1.0 -m <span class="s2">&#34;Релиз версии 1.1.0&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Просмотр тегов</span>
</span></span><span class="line"><span class="cl">git tag
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Отправка тегов на удаленный репозиторий</span>
</span></span><span class="line"><span class="cl">git push origin v1.0.0
</span></span><span class="line"><span class="cl">git push origin --tags</span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<h2 class="heading" id="-обновление-терминологии">
  🔄 Обновление Терминологии
  <a class="anchor" href="#-%d0%be%d0%b1%d0%bd%d0%be%d0%b2%d0%bb%d0%b5%d0%bd%d0%b8%d0%b5-%d1%82%d0%b5%d1%80%d0%bc%d0%b8%d0%bd%d0%be%d0%bb%d0%be%d0%b3%d0%b8%d0%b8">#</a>
</h2>
<h3 class="heading" id="переименование-основной-ветки">
  Переименование Основной Ветки
  <a class="anchor" href="#%d0%bf%d0%b5%d1%80%d0%b5%d0%b8%d0%bc%d0%b5%d0%bd%d0%be%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5-%d0%be%d1%81%d0%bd%d0%be%d0%b2%d0%bd%d0%be%d0%b9-%d0%b2%d0%b5%d1%82%d0%ba%d0%b8">#</a>
</h3>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># В локальном репозитории</span>
</span></span><span class="line"><span class="cl">git branch -m master main
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># На удаленном репозитории (GitHub)</span>
</span></span><span class="line"><span class="cl"><span class="c1"># 1. Изменить настройки репозитория в веб-интерфейсе</span>
</span></span><span class="line"><span class="cl"><span class="c1"># 2. Обновить локальный репозиторий</span>
</span></span><span class="line"><span class="cl">git branch -m master main
</span></span><span class="line"><span class="cl">git fetch origin
</span></span><span class="line"><span class="cl">git branch -u origin/main main</span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<h2 class="heading" id="-лучшие-практики">
  💡 Лучшие Практики
  <a class="anchor" href="#-%d0%bb%d1%83%d1%87%d1%88%d0%b8%d0%b5-%d0%bf%d1%80%d0%b0%d0%ba%d1%82%d0%b8%d0%ba%d0%b8">#</a>
</h2>
<h3 class="heading" id="рекомендации-по-коммитам">
  Рекомендации по Коммитам
  <a class="anchor" href="#%d1%80%d0%b5%d0%ba%d0%be%d0%bc%d0%b5%d0%bd%d0%b4%d0%b0%d1%86%d0%b8%d0%b8-%d0%bf%d0%be-%d0%ba%d0%be%d0%bc%d0%bc%d0%b8%d1%82%d0%b0%d0%bc">#</a>
</h3>
<ol>
<li>
<p><strong>Частота коммитов</strong>:</p>
<ul>
<li>Коммитьте после завершения логически законченных изменений</li>
<li>Один коммит = одна задача</li>
</ul>
</li>
<li>
<p><strong>Сообщения коммитов</strong>:</p>
<div class="code-block">
  <pre tabindex="0"><code class="language-git" data-lang="git"># Шаблон сообщения коммита
&lt;тип&gt;: &lt;краткое описание&gt;

&lt;развернутое описание (необязательно)&gt;

Примеры:
feat: добавить аутентификацию пользователей
fix: исправить утечку памяти в модуле кэширования
docs: обновить README с инструкциями по установке</code></pre>
  <button class="copy-code-button">copy</button>
</div>
</li>
</ol>
<h3 class="heading" id="рекомендуемые-ресурсы">
  Рекомендуемые Ресурсы
  <a class="anchor" href="#%d1%80%d0%b5%d0%ba%d0%be%d0%bc%d0%b5%d0%bd%d0%b4%d1%83%d0%b5%d0%bc%d1%8b%d0%b5-%d1%80%d0%b5%d1%81%d1%83%d1%80%d1%81%d1%8b">#</a>
</h3>
<ul>
<li><a href="https://git-scm.com/doc">Официальная документация Git</a></li>
<li><a href="https://lab.github.com/">GitHub Learning Lab</a></li>
<li><a href="https://www.atlassian.com/git/tutorials">Atlassian Git Tutorial</a></li>
</ul>
<h2 class="heading" id="-дополнительные-ресурсы">
  📚 Дополнительные Ресурсы
  <a class="anchor" href="#-%d0%b4%d0%be%d0%bf%d0%be%d0%bb%d0%bd%d0%b8%d1%82%d0%b5%d0%bb%d1%8c%d0%bd%d1%8b%d0%b5-%d1%80%d0%b5%d1%81%d1%83%d1%80%d1%81%d1%8b">#</a>
</h2>
<ul>
<li><a href="https://git-scm.com/book/ru/v2">Pro Git Book</a></li>
<li><a href="https://lab.github.com/">GitHub Learning Lab</a></li>
<li><a href="https://www.atlassian.com/git/tutorials">Atlassian Git Tutorials</a></li>
</ul>
<h2 class="heading" id="-заключение">
  🎓 Заключение
  <a class="anchor" href="#-%d0%b7%d0%b0%d0%ba%d0%bb%d1%8e%d1%87%d0%b5%d0%bd%d0%b8%d0%b5">#</a>
</h2>
<p>Git - это не просто инструмент, это философия совместной разработки. Чем больше вы практикуетесь, тем легче становится работать.</p>
<p><strong>Практика - ключ к совершенству!</strong></p>
]]></content:encoded><category>Git</category><category>Версионный Контроль</category><category>DevOps</category><category>Разработка</category></item><item><title>🔍 VSCode IDE: Полный обзор возможностей</title><link>https://kushnaren.co/posts/2024-01-09-vscode-ide-obzor/</link><pubDate>Tue, 09 Jan 2024 00:00:00 +0000</pubDate><guid isPermaLink="true">https://kushnaren.co/posts/2024-01-09-vscode-ide-obzor/</guid><description>Подробный обзор Visual Studio Code: основные возможности, расширения, настройка и лучшие практики использования</description><content:encoded><![CDATA[<h2 class="heading" id="-введение">
  📝 Введение
  <a class="anchor" href="#-%d0%b2%d0%b2%d0%b5%d0%b4%d0%b5%d0%bd%d0%b8%d0%b5">#</a>
</h2>
<p>Visual Studio Code (VSCode) - это современный, легковесный, но при этом мощный редактор кода от Microsoft. В этой статье мы рассмотрим основные возможности, которые делают его одним из самых популярных IDE среди разработчиков.</p>
<h3 class="heading" id="история-и-развитие">
  История и развитие
  <a class="anchor" href="#%d0%b8%d1%81%d1%82%d0%be%d1%80%d0%b8%d1%8f-%d0%b8-%d1%80%d0%b0%d0%b7%d0%b2%d0%b8%d1%82%d0%b8%d0%b5">#</a>
</h3>
<p>Visual Studio Code был впервые представлен Microsoft в 2015 году. Проект быстро завоевал популярность благодаря:</p>
<ul>
<li>Открытому исходному коду</li>
<li>Кроссплатформенности (Windows, macOS, Linux)</li>
<li>Регулярным обновлениям</li>
<li>Активному сообществу разработчиков</li>
<li>Высокой производительности</li>
</ul>
<p>За годы развития VSCode превратился из простого редактора кода в полноценную среду разработки, сохранив при этом свою легковесность и скорость работы.</p>
<h2 class="heading" id="-основные-возможности">
  🚀 Основные возможности
  <a class="anchor" href="#-%d0%be%d1%81%d0%bd%d0%be%d0%b2%d0%bd%d1%8b%d0%b5-%d0%b2%d0%be%d0%b7%d0%bc%d0%be%d0%b6%d0%bd%d0%be%d1%81%d1%82%d0%b8">#</a>
</h2>
<h3 class="heading" id="интеллектуальное-автодополнение">
  Интеллектуальное автодополнение
  <a class="anchor" href="#%d0%b8%d0%bd%d1%82%d0%b5%d0%bb%d0%bb%d0%b5%d0%ba%d1%82%d1%83%d0%b0%d0%bb%d1%8c%d0%bd%d0%be%d0%b5-%d0%b0%d0%b2%d1%82%d0%be%d0%b4%d0%be%d0%bf%d0%be%d0%bb%d0%bd%d0%b5%d0%bd%d0%b8%d0%b5">#</a>
</h3>
<p>VSCode предлагает умное автодополнение кода (IntelliSense) для множества языков программирования. Это включает:</p>
<ul>
<li>Подсказки по синтаксису с контекстной информацией</li>
<li>Автодополнение функций и переменных с документацией</li>
<li>Информацию о параметрах методов и их типах</li>
<li>Быстрый доступ к документации и определениям</li>
<li>Рефакторинг кода и быстрые исправления</li>
<li>Анализ типов и проверку ошибок на лету</li>
<li>Поддержку пользовательских определений</li>
</ul>
<h3 class="heading" id="встроенный-терминал">
  Встроенный терминал
  <a class="anchor" href="#%d0%b2%d1%81%d1%82%d1%80%d0%be%d0%b5%d0%bd%d0%bd%d1%8b%d0%b9-%d1%82%d0%b5%d1%80%d0%bc%d0%b8%d0%bd%d0%b0%d0%bb">#</a>
</h3>
<p>Встроенный терминал предоставляет множество возможностей:</p>
<ul>
<li>Выполнение команд без переключения окон</li>
<li>Работа с несколькими терминалами одновременно</li>
<li>Интеграция с различными оболочками:
<ul>
<li>bash</li>
<li>PowerShell</li>
<li>cmd</li>
<li>zsh</li>
<li>fish</li>
</ul>
</li>
<li>Настройка внешнего вида и поведения:
<ul>
<li>Выбор шрифта и размера текста</li>
<li>Настройка цветовой схемы</li>
<li>Конфигурация курсора</li>
<li>Горячие клавиши</li>
</ul>
</li>
<li>Поддержка разделения терминала</li>
<li>История команд и автодополнение</li>
<li>Интеграция с системным буфером обмена</li>
</ul>
<h3 class="heading" id="отладка-кода">
  Отладка кода
  <a class="anchor" href="#%d0%be%d1%82%d0%bb%d0%b0%d0%b4%d0%ba%d0%b0-%d0%ba%d0%be%d0%b4%d0%b0">#</a>
</h3>
<p>Мощные возможности отладки включают:</p>
<ul>
<li>Точки останова:
<ul>
<li>Обычные точки останова</li>
<li>Условные точки останова</li>
<li>Логические точки останова</li>
<li>Точки останова с подсчетом попаданий</li>
</ul>
</li>
<li>Пошаговое выполнение:
<ul>
<li>Шаг с заходом</li>
<li>Шаг с обходом</li>
<li>Шаг с выходом</li>
<li>Продолжение выполнения</li>
</ul>
</li>
<li>Просмотр переменных:
<ul>
<li>Локальные переменные</li>
<li>Глобальные переменные</li>
<li>Выражения наблюдения</li>
<li>Стек вызовов</li>
</ul>
</li>
<li>Консоль отладки:
<ul>
<li>Выполнение произвольного кода</li>
<li>Просмотр значений выражений</li>
<li>Логирование отладочной информации</li>
</ul>
</li>
<li>Расширенные возможности:
<ul>
<li>Отладка нескольких процессов</li>
<li>Удаленная отладка</li>
<li>Отладка в контейнерах</li>
<li>Интеграция с отладчиками языков</li>
</ul>
</li>
</ul>
<h3 class="heading" id="поиск-и-навигация">
  Поиск и навигация
  <a class="anchor" href="#%d0%bf%d0%be%d0%b8%d1%81%d0%ba-%d0%b8-%d0%bd%d0%b0%d0%b2%d0%b8%d0%b3%d0%b0%d1%86%d0%b8%d1%8f">#</a>
</h3>
<p>VSCode предоставляет мощные инструменты для работы с кодом:</p>
<ul>
<li>Глобальный поиск по проекту:
<ul>
<li>Поиск по регулярным выражениям</li>
<li>Поиск с учетом регистра</li>
<li>Поиск целых слов</li>
<li>Замена с предпросмотром</li>
</ul>
</li>
<li>Навигация по коду:
<ul>
<li>Переход к определению</li>
<li>Поиск всех ссылок</li>
<li>Просмотр иерархии вызовов</li>
<li>Просмотр структуры файла</li>
</ul>
</li>
<li>Быстрый переход:
<ul>
<li>Между файлами</li>
<li>К определенной строке</li>
<li>К символу в файле</li>
<li>К символу в проекте</li>
</ul>
</li>
</ul>
<h2 class="heading" id="-расширения">
  🔧 Расширения
  <a class="anchor" href="#-%d1%80%d0%b0%d1%81%d1%88%d0%b8%d1%80%d0%b5%d0%bd%d0%b8%d1%8f">#</a>
</h2>
<h3 class="heading" id="экосистема-расширений">
  Экосистема расширений
  <a class="anchor" href="#%d1%8d%d0%ba%d0%be%d1%81%d0%b8%d1%81%d1%82%d0%b5%d0%bc%d0%b0-%d1%80%d0%b0%d1%81%d1%88%d0%b8%d1%80%d0%b5%d0%bd%d0%b8%d0%b9">#</a>
</h3>
<p>VSCode обладает богатой экосистемой расширений:</p>
<ul>
<li>Более 30,000 доступных расширений</li>
<li>Простой процесс установки и обновления</li>
<li>Возможность создания собственных расширений</li>
<li>Рейтинг и отзывы пользователей</li>
<li>Категоризация и поиск</li>
</ul>
<h3 class="heading" id="популярные-расширения">
  Популярные расширения
  <a class="anchor" href="#%d0%bf%d0%be%d0%bf%d1%83%d0%bb%d1%8f%d1%80%d0%bd%d1%8b%d0%b5-%d1%80%d0%b0%d1%81%d1%88%d0%b8%d1%80%d0%b5%d0%bd%d0%b8%d1%8f">#</a>
</h3>
<ol>
<li>
<p><strong>GitLens</strong></p>
<ul>
<li>Улучшенная интеграция с Git:
<ul>
<li>История изменений файла</li>
<li>Авторство каждой строки</li>
<li>Сравнение версий</li>
</ul>
</li>
<li>Визуализация веток:
<ul>
<li>Графическое представление</li>
<li>Интерактивная история</li>
<li>Поиск по коммитам</li>
</ul>
</li>
<li>Дополнительные функции:
<ul>
<li>Встроенный просмотр изменений</li>
<li>Интеграция с GitHub/GitLab</li>
<li>Расширенные настройки</li>
</ul>
</li>
</ul>
</li>
<li>
<p><strong>Prettier</strong></p>
<ul>
<li>Автоматическое форматирование кода:
<ul>
<li>Настраиваемые правила</li>
<li>Поддержка множества языков</li>
<li>Интеграция с ESLint</li>
</ul>
</li>
<li>Возможности конфигурации:
<ul>
<li>Отступы и переносы строк</li>
<li>Максимальная длина строки</li>
<li>Кавычки и точки с запятой</li>
</ul>
</li>
<li>Интеграция с редактором:
<ul>
<li>Форматирование при сохранении</li>
<li>Форматирование выделенного кода</li>
<li>Горячие клавиши</li>
</ul>
</li>
</ul>
</li>
<li>
<p><strong>ESLint</strong></p>
<ul>
<li>Проверка качества кода:
<ul>
<li>Поиск потенциальных ошибок</li>
<li>Проверка стиля кода</li>
<li>Соблюдение лучших практик</li>
</ul>
</li>
<li>Настройка правил:
<ul>
<li>Использование готовых конфигураций</li>
<li>Создание собственных правил</li>
<li>Отключение правил</li>
</ul>
</li>
<li>Автоматическое исправление:
<ul>
<li>Исправление при сохранении</li>
<li>Пакетное исправление файлов</li>
<li>Предпросмотр изменений</li>
</ul>
</li>
</ul>
</li>
<li>
<p><strong>Live Share</strong></p>
<ul>
<li>Совместная разработка в реальном времени:
<ul>
<li>Совместное редактирование</li>
<li>Общий терминал</li>
<li>Общая отладка</li>
</ul>
</li>
<li>Функции для команд:
<ul>
<li>Аудио-чат</li>
<li>Следование за участником</li>
<li>Права доступа</li>
</ul>
</li>
<li>Безопасность:
<ul>
<li>Шифрование данных</li>
<li>Аутентификация</li>
<li>Контроль доступа</li>
</ul>
</li>
</ul>
</li>
</ol>
<h2 class="heading" id="-настройка-и-оптимизация">
  ⚙️ Настройка и оптимизация
  <a class="anchor" href="#-%d0%bd%d0%b0%d1%81%d1%82%d1%80%d0%be%d0%b9%d0%ba%d0%b0-%d0%b8-%d0%be%d0%bf%d1%82%d0%b8%d0%bc%d0%b8%d0%b7%d0%b0%d1%86%d0%b8%d1%8f">#</a>
</h2>
<h3 class="heading" id="пользовательские-настройки">
  Пользовательские настройки
  <a class="anchor" href="#%d0%bf%d0%be%d0%bb%d1%8c%d0%b7%d0%be%d0%b2%d0%b0%d1%82%d0%b5%d0%bb%d1%8c%d1%81%d0%ba%d0%b8%d0%b5-%d0%bd%d0%b0%d1%81%d1%82%d1%80%d0%be%d0%b9%d0%ba%d0%b8">#</a>
</h3>
<p>VSCode предлагает гибкие возможности настройки:</p>
<ul>
<li>Настройка интерфейса:
<ul>
<li>Темы оформления</li>
<li>Иконки файлов</li>
<li>Размер и тип шрифта</li>
<li>Расположение панелей</li>
</ul>
</li>
<li>Поведение редактора:
<ul>
<li>Автосохранение</li>
<li>Форматирование</li>
<li>Автодополнение</li>
<li>Проверка орфографии</li>
</ul>
</li>
<li>Горячие клавиши:
<ul>
<li>Настройка существующих</li>
<li>Создание новых</li>
<li>Импорт/экспорт</li>
</ul>
</li>
<li>Настройка языков:
<ul>
<li>Специфичные настройки</li>
<li>Форматтеры</li>
<li>Линтеры</li>
<li>Отладчики</li>
</ul>
</li>
</ul>
<h3 class="heading" id="синхронизация-настроек">
  Синхронизация настроек
  <a class="anchor" href="#%d1%81%d0%b8%d0%bd%d1%85%d1%80%d0%be%d0%bd%d0%b8%d0%b7%d0%b0%d1%86%d0%b8%d1%8f-%d0%bd%d0%b0%d1%81%d1%82%d1%80%d0%be%d0%b5%d0%ba">#</a>
</h3>
<p>Встроенная система синхронизации позволяет:</p>
<ul>
<li>Синхронизировать между устройствами:
<ul>
<li>Настройки редактора</li>
<li>Установленные расширения</li>
<li>Пользовательские сниппеты</li>
<li>Горячие клавиши</li>
</ul>
</li>
<li>Управлять синхронизацией:
<ul>
<li>Выбор элементов для синхронизации</li>
<li>Разрешение конфликтов</li>
<li>История изменений</li>
</ul>
</li>
<li>Безопасность:
<ul>
<li>Шифрование данных</li>
<li>Привязка к аккаунту</li>
<li>Управление устройствами</li>
</ul>
</li>
</ul>
<h2 class="heading" id="-продвинутые-функции">
  🎯 Продвинутые функции
  <a class="anchor" href="#-%d0%bf%d1%80%d0%be%d0%b4%d0%b2%d0%b8%d0%bd%d1%83%d1%82%d1%8b%d0%b5-%d1%84%d1%83%d0%bd%d0%ba%d1%86%d0%b8%d0%b8">#</a>
</h2>
<h3 class="heading" id="встроенный-git">
  Встроенный Git
  <a class="anchor" href="#%d0%b2%d1%81%d1%82%d1%80%d0%be%d0%b5%d0%bd%d0%bd%d1%8b%d0%b9-git">#</a>
</h3>
<p>VSCode предоставляет мощную интеграцию с Git:</p>
<ul>
<li>Визуализация изменений:
<ul>
<li>Подсветка измененных строк</li>
<li>Сравнение версий</li>
<li>История изменений</li>
</ul>
</li>
<li>Управление ветками:
<ul>
<li>Создание и удаление</li>
<li>Переключение</li>
<li>Слияние</li>
</ul>
</li>
<li>Работа с коммитами:
<ul>
<li>Создание коммитов</li>
<li>Просмотр истории</li>
<li>Отмена изменений</li>
</ul>
</li>
<li>Интеграция с удаленными репозиториями:
<ul>
<li>Push/Pull операции</li>
<li>Работа с PR/MR</li>
<li>Просмотр удаленных веток</li>
</ul>
</li>
</ul>
<h3 class="heading" id="remote-development">
  Remote Development
  <a class="anchor" href="#remote-development">#</a>
</h3>
<p>Возможности удаленной разработки включают:</p>
<ul>
<li>Работа с контейнерами:
<ul>
<li>Docker интеграция</li>
<li>Devcontainer конфигурация</li>
<li>Отладка в контейнерах</li>
</ul>
</li>
<li>SSH подключения:
<ul>
<li>Безопасное подключение</li>
<li>Сохранение хостов</li>
<li>Проброс портов</li>
</ul>
</li>
<li>WSL интеграция:
<ul>
<li>Прозрачная работа</li>
<li>Доступ к файловой системе</li>
<li>Терминал WSL</li>
</ul>
</li>
</ul>
<h3 class="heading" id="workspace-trust">
  Workspace Trust
  <a class="anchor" href="#workspace-trust">#</a>
</h3>
<p>Система безопасности рабочего пространства:</p>
<ul>
<li>Изолированное выполнение кода</li>
<li>Контроль доступа расширений</li>
<li>Предупреждения о потенциальных рисках</li>
<li>Настройка уровней доверия</li>
</ul>
<h2 class="heading" id="-советы-по-производительности">
  💡 Советы по производительности
  <a class="anchor" href="#-%d1%81%d0%be%d0%b2%d0%b5%d1%82%d1%8b-%d0%bf%d0%be-%d0%bf%d1%80%d0%be%d0%b8%d0%b7%d0%b2%d0%be%d0%b4%d0%b8%d1%82%d0%b5%d0%bb%d1%8c%d0%bd%d0%be%d1%81%d1%82%d0%b8">#</a>
</h2>
<h3 class="heading" id="-комбинации-клавиш">
  🎮 Комбинации клавиш
  <a class="anchor" href="#-%d0%ba%d0%be%d0%bc%d0%b1%d0%b8%d0%bd%d0%b0%d1%86%d0%b8%d0%b8-%d0%ba%d0%bb%d0%b0%d0%b2%d0%b8%d1%88">#</a>
</h3>
<p>Эффективное использование горячих клавиш значительно ускоряет работу в VSCode. Вот основные комбинации по категориям:</p>
<h4 class="heading" id="-навигация-и-поиск">
  🔍 Навигация и поиск
  <a class="anchor" href="#-%d0%bd%d0%b0%d0%b2%d0%b8%d0%b3%d0%b0%d1%86%d0%b8%d1%8f-%d0%b8-%d0%bf%d0%be%d0%b8%d1%81%d0%ba">#</a>
</h4>
<ul>
<li>
<p>Файлы и поиск:</p>
<ul>
<li><code>Ctrl+P</code> - быстрый поиск файлов</li>
<li><code>Ctrl+Shift+P</code> - командная палитра</li>
<li><code>Ctrl+Tab</code> - переключение между файлами</li>
<li><code>Ctrl+G</code> - переход к строке</li>
<li><code>Ctrl+T</code> - поиск символа в проекте</li>
<li><code>Ctrl+Shift+O</code> - поиск символа в текущем файле</li>
<li><code>Ctrl+Shift+F</code> - поиск по всем файлам</li>
</ul>
</li>
<li>
<p>Панели и интерфейс:</p>
<ul>
<li><code>Ctrl+B</code> - скрыть/показать боковую панель</li>
<li><code>Ctrl+J</code> - скрыть/показать панель терминала</li>
<li><code>Ctrl+Shift+E</code> - открыть проводник</li>
<li><code>Ctrl+Shift+G</code> - открыть панель Git</li>
<li><code>Ctrl+Shift+D</code> - открыть панель отладки</li>
<li><code>Ctrl+Shift+X</code> - открыть панель расширений</li>
<li><code>Alt+Z</code> - перенос длинных строк</li>
<li><code>F11</code> - полноэкранный режим</li>
<li><code>Ctrl+K Z</code> - режим Zen Mode</li>
</ul>
</li>
</ul>
<h4 class="heading" id="-базовые-операции-редактирования">
  ⌨️ Базовые операции редактирования
  <a class="anchor" href="#-%d0%b1%d0%b0%d0%b7%d0%be%d0%b2%d1%8b%d0%b5-%d0%be%d0%bf%d0%b5%d1%80%d0%b0%d1%86%d0%b8%d0%b8-%d1%80%d0%b5%d0%b4%d0%b0%d0%ba%d1%82%d0%b8%d1%80%d0%be%d0%b2%d0%b0%d0%bd%d0%b8%d1%8f">#</a>
</h4>
<ul>
<li>Базовое редактирование:
<ul>
<li><code>Alt+↑/↓</code> - перемещение строк вверх/вниз</li>
<li><code>Shift+Alt+↑/↓</code> - копирование строк вверх/вниз</li>
<li><code>Ctrl+Shift+K</code> - удаление строки</li>
<li><code>Ctrl+Enter</code> - вставить строку снизу</li>
<li><code>Ctrl+Shift+Enter</code> - вставить строку сверху</li>
<li><code>Ctrl+Shift+\</code> - перейти к парной скобке</li>
<li><code>Ctrl+]</code> - увеличить отступ</li>
<li><code>Ctrl+[</code> - уменьшить отступ</li>
</ul>
</li>
</ul>
<h4 class="heading" id="-мультикурсор-и-выделение">
  👥 Мультикурсор и выделение
  <a class="anchor" href="#-%d0%bc%d1%83%d0%bb%d1%8c%d1%82%d0%b8%d0%ba%d1%83%d1%80%d1%81%d0%be%d1%80-%d0%b8-%d0%b2%d1%8b%d0%b4%d0%b5%d0%bb%d0%b5%d0%bd%d0%b8%d0%b5">#</a>
</h4>
<ul>
<li>Многокурсорное редактирование:
<ul>
<li><code>Alt+Click</code> - добавить курсор</li>
<li><code>Ctrl+Alt+↑/↓</code> - добавить курсор сверху/снизу</li>
<li><code>Ctrl+D</code> - выделить следующее вхождение</li>
<li><code>Ctrl+Shift+L</code> - выделить все вхождения</li>
<li><code>Ctrl+F2</code> - выделить все вхождения текущего слова</li>
</ul>
</li>
</ul>
<h4 class="heading" id="-манипуляции-с-текстом">
  📝 Манипуляции с текстом
  <a class="anchor" href="#-%d0%bc%d0%b0%d0%bd%d0%b8%d0%bf%d1%83%d0%bb%d1%8f%d1%86%d0%b8%d0%b8-%d1%81-%d1%82%d0%b5%d0%ba%d1%81%d1%82%d0%be%d0%bc">#</a>
</h4>
<ul>
<li>Работа с текстом:
<ul>
<li><code>Ctrl+/</code> - закомментировать/раскомментировать</li>
<li><code>Alt+Shift+A</code> - блочный комментарий</li>
<li><code>Ctrl+H</code> - замена</li>
<li><code>Ctrl+Shift+V</code> - вставить с сохранением форматирования</li>
<li><code>Ctrl+Space</code> - вызвать автодополнение</li>
<li><code>Ctrl+K Ctrl+X</code> - удалить лишние пробелы</li>
</ul>
</li>
</ul>
<h4 class="heading" id="-рефакторинг-и-навигация-по-коду">
  🔄 Рефакторинг и навигация по коду
  <a class="anchor" href="#-%d1%80%d0%b5%d1%84%d0%b0%d0%ba%d1%82%d0%be%d1%80%d0%b8%d0%bd%d0%b3-%d0%b8-%d0%bd%d0%b0%d0%b2%d0%b8%d0%b3%d0%b0%d1%86%d0%b8%d1%8f-%d0%bf%d0%be-%d0%ba%d0%be%d0%b4%d1%83">#</a>
</h4>
<ul>
<li>Рефакторинг:
<ul>
<li><code>F2</code> - переименовать символ</li>
<li><code>Ctrl+.</code> - быстрые исправления</li>
<li><code>Shift+Alt+F</code> - форматировать документ</li>
<li><code>Ctrl+K Ctrl+F</code> - форматировать выделенный код</li>
<li><code>F12</code> - перейти к определению</li>
<li><code>Alt+F12</code> - показать определение</li>
<li><code>Shift+F12</code> - показать все ссылки</li>
</ul>
</li>
</ul>
<h4 class="heading" id="-отладка-и-тестирование">
  🐞 Отладка и тестирование
  <a class="anchor" href="#-%d0%be%d1%82%d0%bb%d0%b0%d0%b4%d0%ba%d0%b0-%d0%b8-%d1%82%d0%b5%d1%81%d1%82%d0%b8%d1%80%d0%be%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5">#</a>
</h4>
<ul>
<li>Отладка:
<ul>
<li><code>F5</code> - начать/продолжить отладку</li>
<li><code>F9</code> - поставить/убрать точку останова</li>
<li><code>F10</code> - шаг с обходом</li>
<li><code>F11</code> - шаг с заходом</li>
<li><code>Shift+F11</code> - шаг с выходом</li>
<li><code>Ctrl+Shift+F5</code> - перезапустить отладку</li>
<li><code>Shift+F5</code> - остановить отладку</li>
</ul>
</li>
</ul>
<h4 class="heading" id="-управление-git">
  📦 Управление Git
  <a class="anchor" href="#-%d1%83%d0%bf%d1%80%d0%b0%d0%b2%d0%bb%d0%b5%d0%bd%d0%b8%d0%b5-git">#</a>
</h4>
<ul>
<li>Основные операции:
<ul>
<li><code>Ctrl+Shift+G G</code> - открыть панель Git</li>
<li><code>Ctrl+Enter</code> - зафиксировать изменения (в панели Git)</li>
<li><code>Ctrl+Shift+P</code> затем <code>&gt;git</code> - доступ ко всем командам Git</li>
<li><code>Alt+←/→</code> - навигация по истории изменений файла</li>
</ul>
</li>
</ul>
<h4 class="heading" id="-работа-с-терминалом">
  💻 Работа с терминалом
  <a class="anchor" href="#-%d1%80%d0%b0%d0%b1%d0%be%d1%82%d0%b0-%d1%81-%d1%82%d0%b5%d1%80%d0%bc%d0%b8%d0%bd%d0%b0%d0%bb%d0%be%d0%bc">#</a>
</h4>
<ul>
<li>Управление терминалом:
<ul>
<li>`Ctrl+`` - открыть/закрыть терминал</li>
<li>`Ctrl+Shift+`` - создать новый терминал</li>
<li><code>Ctrl+Alt+←/→</code> - переключение между терминалами</li>
<li><code>Ctrl+Shift+C</code> - копировать выделенное</li>
<li><code>Ctrl+Shift+V</code> - вставить в терминал</li>
</ul>
</li>
</ul>
<h4 class="heading" id="-персонализация-редактора">
  ⚙️ Персонализация редактора
  <a class="anchor" href="#-%d0%bf%d0%b5%d1%80%d1%81%d0%be%d0%bd%d0%b0%d0%bb%d0%b8%d0%b7%d0%b0%d1%86%d0%b8%d1%8f-%d1%80%d0%b5%d0%b4%d0%b0%d0%ba%d1%82%d0%be%d1%80%d0%b0">#</a>
</h4>
<ul>
<li>Настройка редактора:
<ul>
<li><code>Ctrl+,</code> - открыть настройки</li>
<li><code>Ctrl+K Ctrl+S</code> - открыть горячие клавиши</li>
<li><code>Ctrl+K Ctrl+T</code> - изменить тему оформления</li>
</ul>
</li>
</ul>
<h4 class="heading" id="-рекомендации-по-использованию">
  💡 Рекомендации по использованию
  <a class="anchor" href="#-%d1%80%d0%b5%d0%ba%d0%be%d0%bc%d0%b5%d0%bd%d0%b4%d0%b0%d1%86%d0%b8%d0%b8-%d0%bf%d0%be-%d0%b8%d1%81%d0%bf%d0%be%d0%bb%d1%8c%d0%b7%d0%be%d0%b2%d0%b0%d0%bd%d0%b8%d1%8e">#</a>
</h4>
<ul>
<li>Создайте свои собственные сочетания клавиш для часто используемых операций</li>
<li>Используйте командную палитру (<code>Ctrl+Shift+P</code>) для поиска команд, которые вы не помните</li>
<li>Постепенно добавляйте новые горячие клавиши в свой рабочий процесс</li>
<li>Распечатайте или сохраните шпаргалку с самыми важными комбинациями</li>
</ul>
<h3 class="heading" id="сниппеты">
  Сниппеты
  <a class="anchor" href="#%d1%81%d0%bd%d0%b8%d0%bf%d0%bf%d0%b5%d1%82%d1%8b">#</a>
</h3>
<p>Работа со сниппетами кода:</p>
<ul>
<li>Создание сниппетов:
<ul>
<li>Определение триггеров</li>
<li>Использование плейсхолдеров</li>
<li>Табуляция между полями</li>
</ul>
</li>
<li>Использование:
<ul>
<li>Автодополнение</li>
<li>Вставка через командную палитру</li>
<li>Импорт готовых сниппетов</li>
</ul>
</li>
<li>Организация:
<ul>
<li>По языкам</li>
<li>По проектам</li>
<li>Глобальные сниппеты</li>
</ul>
</li>
</ul>
<h3 class="heading" id="профили">
  Профили
  <a class="anchor" href="#%d0%bf%d1%80%d0%be%d1%84%d0%b8%d0%bb%d0%b8">#</a>
</h3>
<p>Работа с профилями VSCode:</p>
<ul>
<li>Создание профилей для разных задач</li>
<li>Переключение между профилями</li>
<li>Экспорт и импорт профилей</li>
<li>Синхронизация профилей</li>
</ul>
<h2 class="heading" id="-заключение">
  📚 Заключение
  <a class="anchor" href="#-%d0%b7%d0%b0%d0%ba%d0%bb%d1%8e%d1%87%d0%b5%d0%bd%d0%b8%d0%b5">#</a>
</h2>
<p>Visual Studio Code предоставляет отличный баланс между простотой использования и мощными функциями разработки. Благодаря:</p>
<ul>
<li>Обширной экосистеме расширений</li>
<li>Активному сообществу</li>
<li>Регулярным обновлениям</li>
<li>Открытому исходному коду</li>
</ul>
<p>VSCode продолжает развиваться и адаптироваться под нужды современной разработки. Это делает его надежным выбором для:</p>
<ul>
<li>Веб-разработчиков</li>
<li>Системных программистов</li>
<li>Data Scientists</li>
<li>DevOps инженеров</li>
<li>И многих других специалистов</li>
</ul>
<h3 class="heading" id="будущее-развития">
  Будущее развития
  <a class="anchor" href="#%d0%b1%d1%83%d0%b4%d1%83%d1%89%d0%b5%d0%b5-%d1%80%d0%b0%d0%b7%d0%b2%d0%b8%d1%82%d0%b8%d1%8f">#</a>
</h3>
<p>Microsoft активно развивает VSCode, добавляя новые возможности:</p>
<ul>
<li>Улучшенная поддержка AI и ML</li>
<li>Расширенные возможности удаленной работы</li>
<li>Оптимизация производительности</li>
<li>Новые инструменты для совместной разработки</li>
</ul>
<p>Это делает VSCode не просто редактором кода, а полноценной платформой для разработки программного обеспечения.</p>
]]></content:encoded><category>Инструменты Разработчика</category><category>Продуктивность</category><category>Ide</category></item><item><title>🤖 Настройка чат бота в проекте разработки</title><link>https://kushnaren.co/posts/2024-01-07-chatbot-setup-in-development/</link><pubDate>Sun, 07 Jan 2024 00:00:00 +0000</pubDate><guid isPermaLink="true">https://kushnaren.co/posts/2024-01-07-chatbot-setup-in-development/</guid><description>Руководство по настройке и интеграции чат-бота в процесс разработки</description><content:encoded><![CDATA[<h2 class="heading" id="-введение">
  💡 Введение
  <a class="anchor" href="#-%d0%b2%d0%b2%d0%b5%d0%b4%d0%b5%d0%bd%d0%b8%d0%b5">#</a>
</h2>
<p>В современной разработке программного обеспечения чат-боты становятся незаменимыми помощниками, способными значительно ускорить и упростить процесс разработки. В этой статье мы рассмотрим процесс настройки чат-бота для проекта разработки.</p>
<h2 class="heading" id="-преимущества-использования-чат-бота">
  🎯 Преимущества использования чат-бота
  <a class="anchor" href="#-%d0%bf%d1%80%d0%b5%d0%b8%d0%bc%d1%83%d1%89%d0%b5%d1%81%d1%82%d0%b2%d0%b0-%d0%b8%d1%81%d0%bf%d0%be%d0%bb%d1%8c%d0%b7%d0%be%d0%b2%d0%b0%d0%bd%d0%b8%d1%8f-%d1%87%d0%b0%d1%82-%d0%b1%d0%be%d1%82%d0%b0">#</a>
</h2>
<ul>
<li><strong>Автоматизация рутинных задач</strong>: генерация кода, документации, тестов</li>
<li><strong>Быстрые ответы на вопросы</strong>: поиск по документации и кодовой базе</li>
<li><strong>Помощь в отладке</strong>: анализ ошибок и предложение решений</li>
<li><strong>Улучшение процессов</strong>: рекомендации по оптимизации кода и архитектуры</li>
</ul>
<h2 class="heading" id="-пошаговое-руководство-по-настройке">
  🛠️ Пошаговое руководство по настройке
  <a class="anchor" href="#-%d0%bf%d0%be%d1%88%d0%b0%d0%b3%d0%be%d0%b2%d0%be%d0%b5-%d1%80%d1%83%d0%ba%d0%be%d0%b2%d0%be%d0%b4%d1%81%d1%82%d0%b2%d0%be-%d0%bf%d0%be-%d0%bd%d0%b0%d1%81%d1%82%d1%80%d0%be%d0%b9%d0%ba%d0%b5">#</a>
</h2>
<h3 class="heading" id="-подготовительный-этап">
  📋 Подготовительный этап
  <a class="anchor" href="#-%d0%bf%d0%be%d0%b4%d0%b3%d0%be%d1%82%d0%be%d0%b2%d0%b8%d1%82%d0%b5%d0%bb%d1%8c%d0%bd%d1%8b%d0%b9-%d1%8d%d1%82%d0%b0%d0%bf">#</a>
</h3>
<ul>
<li>Выбор задач для автоматизации</li>
<li>Определение необходимых интеграций</li>
<li>Оценка требований к безопасности</li>
</ul>
<h3 class="heading" id="-выбор-оптимальной-платформы">
  🔍 Выбор оптимальной платформы
  <a class="anchor" href="#-%d0%b2%d1%8b%d0%b1%d0%be%d1%80-%d0%be%d0%bf%d1%82%d0%b8%d0%bc%d0%b0%d0%bb%d1%8c%d0%bd%d0%be%d0%b9-%d0%bf%d0%bb%d0%b0%d1%82%d1%84%d0%be%d1%80%d0%bc%d1%8b">#</a>
</h3>
<ul>
<li>Анализ доступных решений</li>
<li>Оценка возможностей API</li>
<li>Проверка совместимости с инструментами разработки</li>
</ul>
<h3 class="heading" id="-процесс-интеграции">
  🔄 Процесс интеграции
  <a class="anchor" href="#-%d0%bf%d1%80%d0%be%d1%86%d0%b5%d1%81%d1%81-%d0%b8%d0%bd%d1%82%d0%b5%d0%b3%d1%80%d0%b0%d1%86%d0%b8%d0%b8">#</a>
</h3>
<ul>
<li>Настройка окружения</li>
<li>Подключение к системе контроля версий</li>
<li>Настройка прав доступа</li>
</ul>
<h3 class="heading" id="-документирование-системы">
  📚 Документирование системы
  <a class="anchor" href="#-%d0%b4%d0%be%d0%ba%d1%83%d0%bc%d0%b5%d0%bd%d1%82%d0%b8%d1%80%d0%be%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5-%d1%81%d0%b8%d1%81%d1%82%d0%b5%d0%bc%d1%8b">#</a>
</h3>
<ul>
<li>Документирование команд и возможностей</li>
<li>Описание процесса взаимодействия</li>
<li>Примеры использования</li>
</ul>
<h2 class="heading" id="-ключевые-аспекты-настройки">
  ⚙️ Ключевые аспекты настройки
  <a class="anchor" href="#-%d0%ba%d0%bb%d1%8e%d1%87%d0%b5%d0%b2%d1%8b%d0%b5-%d0%b0%d1%81%d0%bf%d0%b5%d0%ba%d1%82%d1%8b-%d0%bd%d0%b0%d1%81%d1%82%d1%80%d0%be%d0%b9%d0%ba%d0%b8">#</a>
</h2>
<h3 class="heading" id="-настройка-безопасности-системы">
  🔒 Настройка безопасности системы
  <a class="anchor" href="#-%d0%bd%d0%b0%d1%81%d1%82%d1%80%d0%be%d0%b9%d0%ba%d0%b0-%d0%b1%d0%b5%d0%b7%d0%be%d0%bf%d0%b0%d1%81%d0%bd%d0%be%d1%81%d1%82%d0%b8-%d1%81%d0%b8%d1%81%d1%82%d0%b5%d0%bc%d1%8b">#</a>
</h3>
<ul>
<li>Контроль доступа к конфиденциальной информации</li>
<li>Аутентификация и авторизация</li>
<li>Логирование действий</li>
</ul>
<h3 class="heading" id="-конфигурация-рабочего-контекста">
  🎨 Конфигурация рабочего контекста
  <a class="anchor" href="#-%d0%ba%d0%be%d0%bd%d1%84%d0%b8%d0%b3%d1%83%d1%80%d0%b0%d1%86%d0%b8%d1%8f-%d1%80%d0%b0%d0%b1%d0%be%d1%87%d0%b5%d0%b3%d0%be-%d0%ba%d0%be%d0%bd%d1%82%d0%b5%d0%ba%d1%81%d1%82%d0%b0">#</a>
</h3>
<ul>
<li>Определение области знаний</li>
<li>Настройка специфичных для проекта команд</li>
<li>Создание пользовательских сценариев</li>
</ul>
<h3 class="heading" id="-система-мониторинга-и-улучшений">
  📊 Система мониторинга и улучшений
  <a class="anchor" href="#-%d1%81%d0%b8%d1%81%d1%82%d0%b5%d0%bc%d0%b0-%d0%bc%d0%be%d0%bd%d0%b8%d1%82%d0%be%d1%80%d0%b8%d0%bd%d0%b3%d0%b0-%d0%b8-%d1%83%d0%bb%d1%83%d1%87%d1%88%d0%b5%d0%bd%d0%b8%d0%b9">#</a>
</h3>
<ul>
<li>Отслеживание использования</li>
<li>Сбор обратной связи</li>
<li>Регулярное обновление возможностей</li>
</ul>
<h2 class="heading" id="-организация-файла-инструкций">
  📋 Организация файла инструкций
  <a class="anchor" href="#-%d0%be%d1%80%d0%b3%d0%b0%d0%bd%d0%b8%d0%b7%d0%b0%d1%86%d0%b8%d1%8f-%d1%84%d0%b0%d0%b9%d0%bb%d0%b0-%d0%b8%d0%bd%d1%81%d1%82%d1%80%d1%83%d0%ba%d1%86%d0%b8%d0%b9">#</a>
</h2>
<h3 class="heading" id="-базовая-структура-документации">
  📝 Базовая структура документации
  <a class="anchor" href="#-%d0%b1%d0%b0%d0%b7%d0%be%d0%b2%d0%b0%d1%8f-%d1%81%d1%82%d1%80%d1%83%d0%ba%d1%82%d1%83%d1%80%d0%b0-%d0%b4%d0%be%d0%ba%d1%83%d0%bc%d0%b5%d0%bd%d1%82%d0%b0%d1%86%d0%b8%d0%b8">#</a>
</h3>
<div class="code-block">
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="cl"><span class="gh"># Инструкции для AI Chat Bots
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="gu">## Цель
</span></span></span><span class="line"><span class="cl"><span class="k">-</span> Описание основной цели использования бота
</span></span><span class="line"><span class="cl"><span class="k">-</span> Ключевые задачи и ограничения
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="gu">## Ключевые моменты
</span></span></span><span class="line"><span class="cl"><span class="k">-</span> Используемый фреймворк и его версия
</span></span><span class="line"><span class="cl"><span class="k">-</span> Формат конфигурации
</span></span><span class="line"><span class="cl"><span class="k">-</span> Основной язык проекта
</span></span><span class="line"><span class="cl"><span class="k">-</span> Структура контента
</span></span><span class="line"><span class="cl">- Расположение файлов</span></span></code></pre></div>
  <button class="copy-code-button">copy</button>
</div>
<h3 class="heading" id="-рекомендации-по-ведению-документации">
  🔧 Рекомендации по ведению документации
  <a class="anchor" href="#-%d1%80%d0%b5%d0%ba%d0%be%d0%bc%d0%b5%d0%bd%d0%b4%d0%b0%d1%86%d0%b8%d0%b8-%d0%bf%d0%be-%d0%b2%d0%b5%d0%b4%d0%b5%d0%bd%d0%b8%d1%8e-%d0%b4%d0%be%d0%ba%d1%83%d0%bc%d0%b5%d0%bd%d1%82%d0%b0%d1%86%d0%b8%d0%b8">#</a>
</h3>
<ul>
<li>Храните файл инструкций в корне проекта</li>
<li>Регулярно обновляйте при изменении требований</li>
<li>Используйте понятную структуру и форматирование</li>
<li>Добавляйте примеры для сложных случаев</li>
<li>Версионируйте файл вместе с кодом проекта</li>
</ul>
<h2 class="heading" id="-заключение">
  📝 Заключение
  <a class="anchor" href="#-%d0%b7%d0%b0%d0%ba%d0%bb%d1%8e%d1%87%d0%b5%d0%bd%d0%b8%d0%b5">#</a>
</h2>
<p>Правильно настроенный чат-бот может стать мощным инструментом, повышающим эффективность разработки. Важно уделить внимание начальной настройке и постоянно совершенствовать его возможности на основе потребностей команды.</p>
<h2 class="heading" id="-полезные-ресурсы">
  🔗 Полезные ресурсы
  <a class="anchor" href="#-%d0%bf%d0%be%d0%bb%d0%b5%d0%b7%d0%bd%d1%8b%d0%b5-%d1%80%d0%b5%d1%81%d1%83%d1%80%d1%81%d1%8b">#</a>
</h2>
<ul>
<li><a href="https://platform.openai.com/docs">Официальная документация OpenAI</a></li>
<li><a href="https://docs.github.com/en/copilot">GitHub Copilot Documentation</a></li>
<li><a href="https://huggingface.co/docs">Hugging Face Documentation</a></li>
</ul>
]]></content:encoded><category>Автоматизация</category><category>Инструменты Разработчика</category><category>Продуктивность</category><category>Интеграция</category></item></channel></rss>