fix(claude): settings.json копируется вместо симлинка через stow
- Зачем:
- stow tree-folding создавал симлинк ~/.claude → dotfiles/claude/.claude/,
из-за чего Claude Code модифицировал settings.json прямо в репозитории,
а рантайм-данные (sessions, credentials) попадали в каталог dotfiles.
- Что:
- claude убран из stow-пакетов, установка через ручную секцию в install.sh.
- settings.json копируется в ~/.claude/ (оригинал защищён chmod 444).
- добавлена автомиграция: симлинк → директория с переносом рантайм-данных.
- грязный settings.json в репо автоматически сбрасывается через git checkout.
- добавлен .stow-local-ignore для защиты от случайного stow claude.
- check.sh дополнен проверками: ~/.claude — директория, settings.json — копия.
- Проверка:
- bash install.sh (на машине с симлинком — мигрирует, иначе — идемпотентно).
- bash agents/.agents/skills/dotfiles-check/check.sh.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
769ef95096
commit
e00611015a
3 files changed
+79
-10
No files matched your search
@@ -28,6 +28,8 @@ echo "════════════════════════
|
||||
for pkg_dir in "$DOTFILES_DIR"/*/; do
|
||||
pkg=$(basename "$pkg_dir")
|
||||
[[ "$pkg" == .* ]] && continue
|
||||
# claude управляется вручную (копирование settings.json), не через stow
|
||||
[[ "$pkg" == "claude" ]] && continue
|
||||
|
||||
# Точки входа — элементы первого уровня внутри пакета
|
||||
entries=()
|
||||
@@ -99,7 +101,25 @@ if [ -f "$install_script" ]; then
|
||||
echo ""
|
||||
echo "Доп. проверки (install.sh):"
|
||||
|
||||
# chmod 444 на settings.json
|
||||
# Claude Code: ~/.claude должна быть директорией, не симлинком
|
||||
if [ -L "$HOME/.claude" ]; then
|
||||
err "~/.claude — симлинк (должна быть директория). Запустите install.sh"
|
||||
elif [ -d "$HOME/.claude" ]; then
|
||||
pass "~/.claude — директория (не симлинк)"
|
||||
else
|
||||
err "~/.claude — не найден"
|
||||
fi
|
||||
|
||||
# Claude Code: settings.json должен быть копией, не симлинком
|
||||
if [ -L "$HOME/.claude/settings.json" ]; then
|
||||
err "~/.claude/settings.json — симлинк (должна быть копия)"
|
||||
elif [ -f "$HOME/.claude/settings.json" ]; then
|
||||
pass "~/.claude/settings.json — файл (копия)"
|
||||
else
|
||||
err "~/.claude/settings.json — не найден"
|
||||
fi
|
||||
|
||||
# chmod 444 на settings.json в репозитории
|
||||
if [ -f "$DOTFILES_DIR/claude/.claude/settings.json" ]; then
|
||||
perms=$(stat -c %a "$DOTFILES_DIR/claude/.claude/settings.json" 2>/dev/null || true)
|
||||
if [ "$perms" = "444" ]; then
|
||||
@@ -116,6 +136,13 @@ if [ -f "$install_script" ]; then
|
||||
skip "~/.claude/settings.local.json — не найден (создайте через install.sh)"
|
||||
fi
|
||||
|
||||
# skills симлинк
|
||||
if [ -L "$HOME/.claude/skills" ]; then
|
||||
pass "~/.claude/skills — симлинк"
|
||||
else
|
||||
skip "~/.claude/skills — не найден"
|
||||
fi
|
||||
|
||||
# bashrc
|
||||
if grep -q 'bash_custom' "$HOME/.bashrc" 2>/dev/null; then
|
||||
pass "~/.bashrc содержит подключение bash_custom"
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
# Claude Code управляется вручную через install.sh (копирование, не симлинк).
|
||||
# Этот файл не даёт stow случайно создать симлинк ~/.claude.
|
||||
\.claude
|
||||
+48
-9
@@ -20,7 +20,7 @@ if ! command -v stow &>/dev/null; then
|
||||
fi
|
||||
|
||||
# --- Stow пакеты ---
|
||||
PACKAGES=(bash tmux vim zed vscode agents opencode codex claude gemini)
|
||||
PACKAGES=(bash tmux vim zed vscode agents opencode codex gemini)
|
||||
|
||||
info "Применяю stow пакеты..."
|
||||
cd "$DOTFILES_DIR"
|
||||
@@ -32,7 +32,53 @@ for pkg in "${PACKAGES[@]}"; do
|
||||
fi
|
||||
done
|
||||
|
||||
# --- Claude: settings.local.json ---
|
||||
# --- Claude Code: установка без stow ---
|
||||
# settings.json КОПИРУЕТСЯ (не линкуется), чтобы Claude Code не модифицировал
|
||||
# файл в репозитории. Локальные настройки — в settings.local.json.
|
||||
|
||||
# Миграция: если ~/.claude — stow-симлинк, раскрываем в реальную директорию
|
||||
if [ -L "$HOME/.claude" ]; then
|
||||
info "Миграция: ~/.claude — симлинк, преобразую в директорию..."
|
||||
CLAUDE_STOW_DIR=$(readlink -f "$HOME/.claude")
|
||||
rm "$HOME/.claude"
|
||||
mkdir -p "$HOME/.claude"
|
||||
# Переносим рантайм-данные из stow-директории
|
||||
for item in "$CLAUDE_STOW_DIR"/* "$CLAUDE_STOW_DIR"/.[!.]*; do
|
||||
[ -e "$item" ] || continue
|
||||
base=$(basename "$item")
|
||||
# Пропускаем git-tracked файлы — они останутся в репозитории
|
||||
case "$base" in .gitignore|settings.json|skills) continue ;; esac
|
||||
mv "$item" "$HOME/.claude/" 2>/dev/null || true
|
||||
done
|
||||
info "Рантайм-данные перенесены в ~/.claude/"
|
||||
fi
|
||||
|
||||
mkdir -p "$HOME/.claude"
|
||||
|
||||
# Skills (симлинк)
|
||||
SKILLS_SRC="$DOTFILES_DIR/agents/.agents/skills"
|
||||
if [ -d "$SKILLS_SRC" ]; then
|
||||
ln -sfn "$SKILLS_SRC" "$HOME/.claude/skills"
|
||||
fi
|
||||
|
||||
# settings.json — копия из репозитория (не симлинк!)
|
||||
CLAUDE_SETTINGS_SRC="$DOTFILES_DIR/claude/.claude/settings.json"
|
||||
CLAUDE_SETTINGS_DST="$HOME/.claude/settings.json"
|
||||
if [ -f "$CLAUDE_SETTINGS_SRC" ]; then
|
||||
# Если settings.json в репо был изменён (например, Claude Code писал через симлинк) — сбрасываем
|
||||
if cd "$DOTFILES_DIR" && ! git diff --quiet claude/.claude/settings.json 2>/dev/null; then
|
||||
warn "claude/.claude/settings.json имеет локальные изменения — сбрасываю"
|
||||
git checkout claude/.claude/settings.json
|
||||
fi
|
||||
# Защищаем оригинал в репозитории
|
||||
chmod 444 "$CLAUDE_SETTINGS_SRC"
|
||||
# Копируем в ~/.claude/ (перезаписывает при повторном запуске)
|
||||
cp -f "$CLAUDE_SETTINGS_SRC" "$CLAUDE_SETTINGS_DST"
|
||||
chmod 644 "$CLAUDE_SETTINGS_DST"
|
||||
info "settings.json скопирован (оригинал защищён chmod 444)"
|
||||
fi
|
||||
|
||||
# settings.local.json — локальные переопределения (не в git)
|
||||
CLAUDE_LOCAL="$HOME/.claude/settings.local.json"
|
||||
if [ ! -f "$CLAUDE_LOCAL" ]; then
|
||||
info "Создаю $CLAUDE_LOCAL (локальные настройки Claude)..."
|
||||
@@ -46,13 +92,6 @@ else
|
||||
warn "$CLAUDE_LOCAL уже существует, пропускаю"
|
||||
fi
|
||||
|
||||
# --- Claude: защита settings.json от перезаписи ---
|
||||
CLAUDE_SETTINGS="$DOTFILES_DIR/claude/.claude/settings.json"
|
||||
if [ -f "$CLAUDE_SETTINGS" ]; then
|
||||
chmod 444 "$CLAUDE_SETTINGS"
|
||||
info "settings.json защищён от записи (chmod 444)"
|
||||
fi
|
||||
|
||||
# --- Bash: подключение в .bashrc ---
|
||||
BASHRC="$HOME/.bashrc"
|
||||
BASHRC_LINE='[ -f ~/.bash_custom ] && source ~/.bash_custom'
|
||||
|
||||
Reference in new issue
Block a user