#!/bin/bash # KB Lint — health checks with exit codes # Usage: ./scripts/lint.sh set -euo pipefail KB_DIR="$(cd "$(dirname "$0")/.." && pwd)" cd "$KB_DIR" if ! command -v rg &>/dev/null; then echo "❌ ripgrep (rg) is required." >&2 exit 1 fi broken=0 stale=0 orphan=0 echo "🔍 KB Lint" echo "===========" echo "" # ── P0: Broken wikilinks ────────────────────────────────── echo "--- P0: Broken Wikilinks ---" while IFS= read -r match; do file="${match%%:*}" raw_link="${match#*:}" # Strip [[ and ]] link="${raw_link#\[\[}" link="${link%\]\]}" # Strip alias: [[page|display]] → page link="${link%%|*}" # Strip anchor: [[page#heading]] → page link="${link%%#*}" link="$(echo "$link" | xargs)" # trim whitespace [ -z "$link" ] && continue # Look for matching .md file (case-insensitive) found=$(find wiki/ -iname "${link}.md" -print -quit 2>/dev/null) if [ -z "$found" ]; then echo "❌ $file: [[$link]] → not found" broken=1 fi done < <(rg -noH '\[\[([^]]+)\]\]' wiki/ 2>/dev/null) if [ "$broken" -eq 0 ]; then echo "✅ No broken links" fi echo "" # ── P1: Stale investing pages (>60 days) ───────────────── echo "--- P1: Stale Investing Pages (>60 days) ---" if [ -d wiki/investing ]; then while IFS= read -r f; do [ -z "$f" ] && continue modified=$(date -r "$f" +%Y-%m-%d 2>/dev/null || stat -f %Sm -t %Y-%m-%d "$f" 2>/dev/null || echo "?") echo "⚠️ $f — last modified $modified" stale=1 done < <(find wiki/investing -name "*.md" -mtime +60 2>/dev/null) fi if [ "$stale" -eq 0 ]; then echo "✅ All investing pages up to date" fi echo "" # ── P2: Orphan pages ────────────────────────────────────── echo "--- P2: Possible Orphans ---" while IFS= read -r page; do [ -z "$page" ] && continue slug=$(basename "$page" .md) refs=$(rg -l "\[\[${slug}(\]\]|\||#)" wiki/ 2>/dev/null | grep -cv "$page" || true) if [ "$refs" -eq 0 ]; then echo "🔸 $page — no incoming links" orphan=1 fi done < <(find wiki -name "*.md" 2>/dev/null) if [ "$orphan" -eq 0 ]; then echo "✅ No orphan pages" fi echo "" # ── Result ───────────────────────────────────────────────── issues=$((broken + stale + orphan)) if [ "$issues" -gt 0 ]; then echo "❌ Lint found issues: $broken broken links, $stale stale pages, $orphan orphans" exit 1 else echo "✅ Lint clean — no issues found" exit 0 fi