diff options
Diffstat (limited to 'scripts/install-lang.sh')
| -rwxr-xr-x | scripts/install-lang.sh | 41 |
1 files changed, 35 insertions, 6 deletions
diff --git a/scripts/install-lang.sh b/scripts/install-lang.sh index 6e8d806..3aaa76e 100755 --- a/scripts/install-lang.sh +++ b/scripts/install-lang.sh @@ -104,12 +104,16 @@ fi echo "Installing '$LANG' ruleset into $PROJECT" -# 1. Generic rules from claude-rules/ (shared across all languages) -if [ -d "$REPO_ROOT/claude-rules" ]; then - mkdir -p "$PROJECT/.claude/rules" - cp "$REPO_ROOT/claude-rules"/*.md "$PROJECT/.claude/rules/" 2>/dev/null || true - count=$(ls -1 "$REPO_ROOT/claude-rules"/*.md 2>/dev/null | wc -l) - echo " [ok] .claude/rules/ — $count generic rule(s) from claude-rules/" +# 1. Generic rules are NOT copied here. They install once at ~/.claude/rules/ +# via `make install` and load in every session on the machine. Copying them per +# project loaded them twice, and project rules outrank user-level ones — so a +# stale project copy quietly overrode the fresh global rule. The bundle owns its +# own language rules only; sync-language-bundle.sh sweeps copies left by earlier +# installs. A machine that wants the generic rules runs `make install`. +mkdir -p "$PROJECT/.claude/rules" +if [ ! -d "$HOME/.claude/rules" ]; then + echo " [!!] ~/.claude/rules/ is missing — run 'make install' so the generic" + echo " rules are available; this bundle installs language rules only." fi # 2. .claude/ — language-specific rules, hooks, settings (authoritative, always overwrite) @@ -195,5 +199,30 @@ if [ -f "$SRC/gitignore-add.txt" ]; then fi fi +# --- Bundle completeness check --- +# Every component copy above is guarded by a plain existence test, so a bundle +# missing one installs silently and reports success. That is how the python and +# typescript bundles shipped for nearly two months with no pre-commit hook, and +# therefore no credential scan, on every project that installed them: nothing +# ever said the component was absent. +# +# This can't be fixed by never missing a component — someone adding the seventh +# bundle will miss one too. It's fixed by the install saying so. Warn, never +# block: a partial bundle is still worth installing, and turning this into a +# failure would just teach people to skip the installer. +missing="" +[ -f "$SRC/githooks/pre-commit" ] || missing="${missing} - githooks/pre-commit (secret scan on commit)"$'\n' +[ -f "$SRC/claude/settings.json" ] || missing="${missing} - claude/settings.json (permissions + PostToolUse hook wiring)"$'\n' +ls "$SRC"/claude/hooks/*.sh >/dev/null 2>&1 || missing="${missing} - claude/hooks/*.sh (validate-on-edit hook)"$'\n' +[ -f "$SRC/CLAUDE.md" ] || missing="${missing} - CLAUDE.md (seed project instructions)"$'\n' + +if [ -n "$missing" ]; then + echo "" + echo "WARNING: the '$LANG' bundle is incomplete. Not installed, because the bundle doesn't ship them:" >&2 + printf '%s' "$missing" >&2 + echo "The install above succeeded; these components are simply absent upstream." >&2 + echo "Add them under languages/$LANG/ in rulesets, then re-run this install." >&2 +fi + echo "" echo "Install complete." |
