aboutsummaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2026-04-26 19:48:31 -0500
committerCraig Jennings <c@cjennings.net>2026-04-26 19:48:31 -0500
commit5dc03427571d88d407389e67d1c1c1936e8f61ce (patch)
treedf577f6a17fd0d02c5f4d6707e0d37490d1c74b7 /scripts
parent2eff127c1dbf2bc09175f929d581f1dde12cb2e3 (diff)
downloadrulesets-5dc03427571d88d407389e67d1c1c1936e8f61ce.tar.gz
rulesets-5dc03427571d88d407389e67d1c1c1936e8f61ce.zip
chore(build): wildcard SKILLS, claude-rules bridge symlink, link lint
The refactor scan flagged three install/lint problems. I fixed all three. - The Makefile SKILLS list was hand-maintained and had drifted: `respond-to-cj-comments` exists on disk but wasn't installed by `make install`. I replaced the list with `$(patsubst %/SKILL.md,%,$(wildcard */SKILL.md))` so every directory containing a SKILL.md is picked up automatically. - Cross-references in installed skills point at `../claude-rules/foo.md`. The install layout puts rules at `~/.claude/rules/`, not `~/.claude/skills/claude-rules/`, so those links resolved in the source repo and silently broke at install. I added a bridge symlink to the install target. `~/.claude/skills/claude-rules` now points at the source `claude-rules/` directory, so the same relative path works in both layouts. - I extended `scripts/lint.sh` with a `check_md_links` function that validates `claude-rules/` cross-references in `claude-rules/*.md` and `*/SKILL.md`. Scoped narrowly on purpose: skill bodies cite illustrative file names (ADR templates, arc42 sections) that aren't real source files and would generate noise. Verified locally: `make install` is idempotent, the bridge resolves the previously-broken link, and `bash scripts/lint.sh` is clean.
Diffstat (limited to 'scripts')
-rwxr-xr-xscripts/lint.sh35
1 files changed, 35 insertions, 0 deletions
diff --git a/scripts/lint.sh b/scripts/lint.sh
index 2956aff..ae30aa5 100755
--- a/scripts/lint.sh
+++ b/scripts/lint.sh
@@ -5,6 +5,9 @@
# - Every rule file has an 'Applies to:' header
# - Every language CLAUDE.md has a top-level heading
# - Every hook script has a shebang and is executable
+# - Every cross-reference to claude-rules/ from a SKILL.md or
+# claude-rules/*.md resolves to a real file (catches the install-layout
+# drift that the bridge symlink fixes)
set -u
@@ -45,6 +48,32 @@ check_hook() {
fi
}
+check_md_links() {
+ # Validate cross-references to claude-rules/ — the install-layout problem
+ # solved by the bridge symlink in `make install`. Doesn't validate
+ # example file names that skills cite illustratively (e.g. ADR templates,
+ # arc42 section files), which are intentionally not real source files.
+ local f="$1"
+ [ -f "$f" ] || return 0
+ local dir
+ dir="$(dirname "$f")"
+ while IFS= read -r link; do
+ local url="${link##*\(}"
+ url="${url%\)}"
+ case "$url" in
+ *claude-rules/*) ;;
+ *) continue ;;
+ esac
+ url="${url%%#*}"
+ url="${url%%\?*}"
+ local resolved
+ resolved="$(cd "$dir" 2>/dev/null && readlink -m "$url" 2>/dev/null)"
+ if [ -z "$resolved" ] || [ ! -e "$resolved" ]; then
+ warn "$f — broken claude-rules link: $url"
+ fi
+ done < <(grep -oE '\[[^]]*\]\([^)]+\)' "$f" 2>/dev/null || true)
+}
+
echo "Linting rulesets in $REPO_ROOT"
# Generic rules
@@ -82,6 +111,12 @@ for s in scripts/*.sh; do
check_hook "$s"
done
+# Markdown link validation across rules and skills
+for f in claude-rules/*.md */SKILL.md; do
+ [ -f "$f" ] || continue
+ check_md_links "$f"
+done
+
echo "---"
if [ "$errors" -eq 0 ]; then
echo "All checks passed."