Мержим, пушим, билдим, фиксим ....
Тут недавно был отличный пост про то, как вынести
~/.claudeв git-репозиторий. Я делаю так же — но у git-подхода есть слепое пятно: он версионирует то, что Claude умеет, а не то, что он узнал про твои проекты. Вот как я закрыл это для команды.
Тот самый пост — про то, как превратить ~/.claude в git-репозиторий: скиллы, агенты, слэш-команды, MCP-конфиг, хуки под симлинками через make install, синк между машинами, не теряется при блокировке аккаунта. Подход правильный, сам так делаю.
Но за 2 года на нескольких проектах я упёрся в то, что git-конфиг не решает.
Git версионирует статику — то, что Claude умеет: твои скиллы, агентов, команды, правила. Это здорово и переносимо.
Чего там нет — это динамики: того, что Claude узнал про конкретный проект за прошлые сессии. Например:
migrate, а через свою обёртку над artisan;Это не скилл и не правило — это накопленный контекст по проекту. В Claude Code он копится через auto-memory, но живёт в отдельной базе, а не в ~/.claude/*.md. Поэтому в git он не попадает. А значит:
Git-pull этого по своей природе не лечит: он пофайловый и point-in-time. А память по проекту нужна живой, общей и искомой по смыслу, а не «закоммить — запушь — подтяни».
Вынес слой памяти на сервер. ruflo-hub — небольшая Docker-обёртка: берёт MCP-сервер памяти, оборачивает stdio в HTTP, и Claude Code у всех в команде ходит в одно общее хранилище памяти. Один человек разобрался в особенности проекта — и у остальных Claude это уже знает.
Сразу честно, иначе про этот проект нельзя. В основе — ruflo (форк claude-flow), и у него репутация. Я сам проверял: большая часть из «300+ MCP-инструментов» — нерабочие заглушки. swarm_init оставляет agentCount: 0, neural_train возвращает Math.random(), «агенты» — это markdown-файлы. Как swarm-оркестратор это в основном театр (об этом же — обсуждение на r/ClaudeAI).
Реально работает ровно одна часть — слой памяти: настоящая ONNX-модель (MiniLM) + HNSW-индекс, SQLite-персист и auto-memory-хук. ruflo-hub — тонкая обёртка, которая отдаёт по сети только этот слой и мостит его в Claude Code. Никакого swarm/neural и сотен заглушек в контексте — мы их просто не грузим. То есть это ровно тот рабочий ~1% от ruflo, без остального.
Поднять сервер:
docker compose up -d
curl http://localhost:3000/health
Память хранится в SQLite (memory.db, WAL-режим). PostgreSQL в комплекте опционален — он не основное хранилище, а нужен только под ruflo ruvector import/export.
Подключение проекта — самоконфигурирующийся скрипт с того же сервера:
curl http://<сервер>:3000/setup | bash
Да, это curl | bash со своего сервера — скрипт отдаётся в открытом виде, гляньте перед запуском. Он кладёт хелперы в .claude/helpers/ (auto-memory-хук + statusline) и правит .claude/settings.json (хуки SessionStart → import / Stop → sync). Дальше Claude Code пишет и читает память на сервере сам: memory_store на находки, memory_search — по смыслу (не grep: найдёт «паттерн JWT-авторизации» по запросу «token-based login flow»). В statusline видно число векторов и статус MCP.
@claude-flow/memory. Зарепортили апстриму (#2432), и в ruflo 3.14.2 это уже исправлено; у себя держим ещё RSS-watchdog как страховку.ruflo@latest и пересобирается еженедельно, так что :latest со временем уедет вперёд. Аудит и фиксы ниже я делал на 3.14.2. Хотите воспроизводимость — берите конкретный тег (:1.3.0 или :<sha>), а не :latest, и проверяйте docker exec … ruflo --version.ruflo (3.1.0-alpha.55 – 3.5.2) был #1375: вредоносный preinstall-скрипт и скрытая инъекция в описаниях инструментов. Раз хаб ставит пакет и раздаёт описания клиентам — перепроверил версию, которую шиплю (3.14.2): preinstall-хуков нет, все 305 описаний чистые. В этой версии вылечено — но фиксируйте версию и проверяйте сами.memory.db в WAL-режиме, бэкапим том целиком (memory.db + -wal + -shm); копия одного memory.db даёт database disk image is malformed.Когда я кидал это в один Laravel-чат, первым прилетело не «как», а «а как с безопасностью общей памяти» и «чем это лучше папки docs + claude.md». Отвечу честно.
«А если кто-то накидает в общую память инъекций? Джун насыплет своих инструкций? А если они нужны только в одном проекте, а в другом нет?»
Память разводится по namespace — Claude сам заводит их по проектам, плюс можно явно сказать «сохрани/прочитай в такой-то namespace». Если у проектов разные trust-зоны и утечки между ними недопустимы — это не «одна общая помойка»: поднимаешь отдельный ruflo-hub под бизнес-скоуп (один сервер = один периметр доверия), личное — на своём.
А вот честное ограничение: per-user ACL и автофильтра инъекций из коробки пока нет. Сейчас это организационно — общая память это общая граница доверия: подключаешь тех, кому доверяешь, ревью памяти на тимлиде. Технического «джун не может писать сюда» я ещё не сделал — и не буду делать вид, что сделал. Если у тебя в команде это критично — пока только разводка по отдельным серверам.
«Чем лучше папки docs/ и claude.md?»
Они никуда не деваются, и память их не заменяет. Разница в двух вещах. Первое — часть рабочих вещей в гит класть нельзя или не нужно, а память не в гите. Второе — память живая и сразу доступна агенту через хуки + поиск по смыслу. Часто в ней лежат как раз ссылки на эти доки: Claude, просматривая память, сам быстро находит «а, про это есть док вот тут» — даже если конкретный разработчик не знает, что кто-то положил эту доку сто лет назад. То есть docs/claude.md — статика для людей, а память — индекс по опыту для агента, который на эту статику ссылается.
Зеркалю мысль из того поста — не ради инфраструктуры:
Нужно — когда команда и много проектов, и хочется, чтобы то, что Claude понял на одном проекте или у одного человека, доходило до всех без пересказа.
~/.claude в git и общая память — про разные половины одной задачи: статика (что Claude умеет) едет в git, динамика (что он узнал про твои проекты) — в общий сетевой слой памяти. У меня работает связка из обоих.
jazz-max/ruflo-hub (образ на Docker Hub — jazzmax/ruflo-hub; да, ник на GitHub и в Docker Hub исторически разный)Backend, Frontend, Weekend
В последнее время я активно использую Claude Code в своей разработке. По мере роста числа агентов я столкнулся с неожиданной проблемой — стало сложно синхронизировать их правила между разными системами.

Кроме того, появилось вполне рациональное опасение: в случае блокировки аккаунта можно потерять все наработки — команды, скилы и правила агентов, которые я собирал и оттачивал на протяжении нескольких месяцев. Это подтолкнуло меня к созданию удобной системы хранения конфигурации. Здесь важно зафиксировать простую мысль: директория ~/.claude/ — это такой же код. А код должен храниться в Git.
Так появился claude-config-template — репозиторий-шаблон, в котором живут скилы, агенты, команды, хуки и MCP-конфигурации. При этом сама папка ~/.claude/ собирается из него с помощью симлинков.
Если кратко, этот подход решает сразу три ключевые проблемы:
Дальше расскажу, как устроен шаблон и почему именно симлинки, а не копирование, оказались оптимальным решением.
Если вы хотя бы раз заглядывали в ~/.claude/, структура этого шаблона вас не удивит.
skills/ пользовательские скилы (SKILL.md + ресурсы)
agents/ субагенты (отдельные .md с frontmatter)
commands/ слеш-команды
mcp/ примеры конфигов MCP-серверов
hooks/ PreToolUse / PostToolUse и прочие хуки
docs/ конвенции, гайды, changelog
scripts/ утилиты: линтер, генератор новых скилов
linting/ pre-push-хук и набор проверок
И это сделано намеренно: чем меньше различий между репозиторием и реальной рабочей директорией, тем проще всё переносится и поддерживается.
Например, вы просто кладёте SKILL.md в skills/my-skill/ — и уже через минуту он доступен в Claude Code так, будто всегда там и находился.
Сам репозиторий по умолчанию пустой: никаких готовых скилов или агентов. Есть только agents/example.md — в качестве минимальной заглушки.
По сути, claude-config-template — это ваш персональный конфиг. Вы форкаете его и наполняете под свои задачи.
Самое интересное в этом шаблоне — не структура, а способ подключения.
Механика максимально простая:
make installСкрипт создаёт симлинки в ~/.claude/, указывающие на файлы из репозитория.
make install # создаёт ссылки в ~/.claude/
make uninstall # удаляет только наши ссылки, родные скилы не трогает
Важно: все ваши текущие файлы в ~/.claude/ остаются нетронутыми. make install ничего не копирует и не перезаписывает — он только создаёт ссылки.
Под капотом install.sh проходит по категориям (skills, agents, commands, hooks) и линкует каждый элемент отдельно.
ln -s "$REPO/skills/my-skill" "$CLAUDE_HOME/skills/my-skill"
ln -s "$REPO/agents/example.md" "$CLAUDE_HOME/agents/example.md"
Это принципиальный момент. Если бы мы линковали директории целиком (например, skills/), то затёрли бы встроенные скилы, которые Anthropic добавляет автоматически. Поэлементная линковка позволяет избежать этого: системные и пользовательские файлы спокойно сосуществуют в одной директории.
Что это даёт на практике:
SKILL.md в репозитории — Claude Code видит новую версию при следующем запуске. Не нужно копировать, переустанавливать, перезапускать что-то ещё.git blame по агенту, откатиться на старую версию, открыть PR на скил от коллеги.install.sh --uninstall удаляет ровно те ссылки, которые создал, и проверяет, что они до сих пор указывают на репозиторий. Чужие файлы в ~/.claude/ не трогает.Разумеется, у такого подхода есть и ограничения.
Если вы переместите репозиторий, симлинки «сломаются» — нужно будет снова запустить make install. Кроме того, если поверх симлинка вручную положить реальный файл, скрипт не станет его перезаписывать — он просто пропустит его.
Это осознанный компромисс: лучше ничего не трогать и избежать потери данных, чем случайно затереть чужую работу.
Пример вывода make install:
[skills]
+ /home/me/.claude/skills/my-skill -> /home/me/code/claude-config/skills/my-skill
= /home/me/.claude/skills/hello-test (already linked)
! /home/me/.claude/skills/manual-skill exists and is not a symlink. Skipping.
Когда скилы превращаются в обычный Git-репозиторий, перенос на новую машину становится тривиальной задачей:
git clone <repo>
cd <repo>
make install
И всё. Уже через несколько секунд в ~/.claude/ появляются симлинки на ваши скилы, агенты и команды.
Если что-то пошло не так, есть команда make doctor. Скрипт scripts/doctor.sh проверяет:
На выходе — понятный отчёт: что работает, а что нужно доустановить или поправить.
Скилы и агенты — это всего лишь Markdown с frontmatter. Казалось бы, что тут можно сломать.
На практике — очень многое. Достаточно:
И Claude Code просто молча проигнорирует часть файла — без ошибок и предупреждений.
Именно поэтому в шаблоне заложен довольно строгий (и местами параноидальный) набор проверок.
Они запускаются локально (через pre-push хук в linting/pre-push-check.sh) и в CI:
SKILL.md и agents/*.mdcommands/task_*.md по контрактуlinting/.markdownlint.yml).yamllint.yml).claude/settings*.jsonКаждая проверка оформлена как отдельный скрипт в linting/check_scripts/: check_shellcheck_all.sh, check_codespell_all.sh и так далее.
pre-push хук просто запускает их последовательно, а CI использует те же самые скрипты в виде отдельных джоб.
В результате — один источник правды для локальной разработки и для GitHub Actions.
Я не считаю этот шаблон серебряной пулей или обязательным стандартом. Это просто инструмент, который хорошо решает конкретный класс задач — но не все подряд.
Он действительно начинает приносить пользу, если:
В этих сценариях Git + симлинки дают предсказуемость: конфигурация всегда под рукой, изменения отслеживаются, а окружение легко восстановить.
С другой стороны, этот подход может быть избыточным.
Если у вас:
— то обычный файл в ~/.claude/skills/ решит задачу быстрее и проще.
Не стоит поднимать инфраструктуру ради инфраструктуры. Если всё помещается в один SKILL.md, Git-репозиторий и набор линтеров, скорее всего, только усложнят жизнь, а не упростят её.
В итоге получился не просто шаблон, а удобный способ навести порядок в своей работе с Claude Code: хранить конфигурацию как код, контролировать изменения и не зависеть от конкретной машины или аккаунта.
Если вам откликнулась эта идея — поддержите проект ⭐️ на GitHub. Это действительно помогает другим разработчикам находить его и экономить время.
Важно: этот шаблон задумывался не как готовое решение «из коробки», а как отправная точка. Форкните репозиторий, адаптируйте под себя и соберите свой собственный конфиг — такой, который идеально ложится в ваш процесс.
Если захотите поучаствовать в развитии — буду рад: багрепорты, идеи для новых проверок и pull request’ы с улучшениями только приветствуются. Процесс описан в CONTRIBUTING.md.
{message}