aboutsummaryrefslogtreecommitdiff
path: root/scripts/install-lang.sh
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/install-lang.sh')
-rwxr-xr-xscripts/install-lang.sh41
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."