claude-harness/install.sh

82 lines
3.8 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env bash
# claude-harness: установка глобальной части (CLAUDE.md, хуки, конфиг caveman, слияние settings.json).
# Идемпотентно. Запуск: bash install.sh | проверка окружения: bash install.sh --check
set -euo pipefail
HERE="$(cd "$(dirname "$0")" && pwd)"
CC="${CLAUDE_CONFIG_DIR:-$HOME/.claude}"
check() {
local ok=0
echo "== Проверка окружения"
for bin in claude git python3 node npm tea openspec codegraph; do
if command -v "$bin" >/dev/null 2>&1; then echo " ok $bin ($(command -v "$bin"))"; else echo " MISS $bin"; ok=1; fi
done
if [ -f "$CC/plugins/installed_plugins.json" ]; then
for p in superpowers caveman; do
if grep -q "\"$p@" "$CC/plugins/installed_plugins.json"; then echo " ok plugin $p"; else echo " MISS plugin $p (/plugin install ...)"; fi
done
for p in beads template-bridge; do
grep -q "\"$p@" "$CC/plugins/installed_plugins.json" && echo " WARN plugin $p установлен — конфликтует с обвязкой, удалить" || true
done
else
echo " WARN не найден $CC/plugins/installed_plugins.json"
fi
if [ -f "$CC/settings.json" ] && grep -q 'codegraph prompt-hook' "$CC/settings.json"; then
echo " WARN codegraph prompt-hook в settings.json — рекомендуется отключить на время пилота"
fi
return $ok
}
if [ "${1:-}" = "--check" ]; then check; exit $?; fi
mkdir -p "$CC/hooks" "$HOME/.config/caveman"
stamp=$(date +%Y%m%d-%H%M%S)
# 1. Глобальный CLAUDE.md
if [ -f "$CC/CLAUDE.md" ] && ! cmp -s "$HERE/global/CLAUDE.md" "$CC/CLAUDE.md"; then
cp "$CC/CLAUDE.md" "$CC/CLAUDE.md.bak.$stamp"; echo "backup: CLAUDE.md.bak.$stamp"
fi
cp "$HERE/global/CLAUDE.md" "$CC/CLAUDE.md"
# 2. Хуки
cp "$HERE/hooks/guard-main.sh" "$HERE/hooks/require-plan.sh" "$HERE/hooks/harness-check.sh" "$CC/hooks/"
# 2a. Скрипты бутстрапа проекта — агент запускает их из сессии
mkdir -p "$CC/harness"
cp -R "$HERE/adopt-project.sh" "$HERE/new-project.sh" "$HERE/project-template" "$CC/harness/"
chmod +x "$CC/harness/"*.sh
chmod +x "$CC/hooks/"*.sh
# 3. caveman off by default
cp "$HERE/caveman/config.json" "$HOME/.config/caveman/config.json"
# 4. settings.json: слить блок hooks, вычистить хвосты beads/template-bridge
SETTINGS="$CC/settings.json"
[ -f "$SETTINGS" ] || echo '{}' > "$SETTINGS"
cp "$SETTINGS" "$SETTINGS.bak.$stamp"
python3 - "$SETTINGS" "$HERE/hooks/settings.hooks.json" <<'PY'
import json, sys
sp, hp = sys.argv[1], sys.argv[2]
s = json.load(open(sp)); h = json.load(open(hp))
hooks = s.setdefault("hooks", {})
pre = hooks.setdefault("PreToolUse", [])
def ours(entry):
return any(("guard-main.sh" in x.get("command","") or "require-plan.sh" in x.get("command","")) for x in entry.get("hooks",[]))
pre[:] = [e for e in pre if not ours(e)]
pre.extend(h["hooks"]["PreToolUse"])
ss = hooks.setdefault("SessionStart", [])
ss[:] = [e for e in ss if not any("harness-check.sh" in x.get("command","") for x in e.get("hooks",[]))]
ss.extend(h["hooks"]["SessionStart"])
for ev in ("SessionStart","PreCompact"):
if ev in hooks:
for e in hooks[ev]:
e["hooks"] = [x for x in e.get("hooks",[]) if "bd prime" not in x.get("command","") and "WORKFLOW REMINDER" not in x.get("command","")]
hooks[ev] = [e for e in hooks[ev] if e.get("hooks")]
if not hooks[ev]: del hooks[ev]
json.dump(s, open(sp,"w"), ensure_ascii=False, indent=2)
print("settings.json: hooks merged")
PY
echo "done: $CC/CLAUDE.md, $CC/hooks/{guard-main,require-plan,harness-check}.sh, $CC/harness/, ~/.config/caveman/config.json"
echo "Плагины Claude Code ставятся вручную: /plugin install superpowers@claude-plugins-official"
check || true