SkillCheck validator, Cursor exports, and per-agent installers (#27)
Three more learnings from alirezarezvani/claude-skills, applied: 1. SkillCheck validator (scripts/skillcheck.mjs) — validates every SKILL.md against the authoring standard (frontmatter, name/folder match, trigger + produces clauses, required headings) plus tier referential integrity. Errors fail CI; --strict fails on warnings too. New skillcheck.yml workflow and a SkillCheck status badge in the README. Current: 0 errors / 14 advisory warnings across 172 skills. 2. Cursor export platform — build-exports.mjs now generates exports/cursor/<bundle>/<skill>/<skill>.mdc rule files. The PLATFORMS registry now supports per-skill filenames (file as a function). 3. Per-agent installers — scripts/install.sh unifies install for claude/hermes/codex/openclaw/cursor (--link, --target, --dry-run, --list). Curl-able one-liners codex-install.sh, openclaw-install.sh, and cursor-install.sh clone the library and install in a single command. README documents the one-line installs and Cursor exports; CHANGELOG and the authoring standard updated. Claude-Session: https://claude.ai/code/session_016JWn5jRD5tcEFKrubjQ6Px Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
Executable
+114
@@ -0,0 +1,114 @@
|
||||
#!/usr/bin/env bash
|
||||
# Unified skill installer for SKILL.md-native agents (and Cursor rules).
|
||||
#
|
||||
# Native agents (Claude Code, Hermes, OpenAI Codex, OpenClaw) read the same
|
||||
# SKILL.md standard — installing is just placing the skill folders where the
|
||||
# agent discovers them. Cursor uses .mdc rule files (from exports/cursor/).
|
||||
#
|
||||
# Usage:
|
||||
# ./scripts/install.sh --agent claude
|
||||
# ./scripts/install.sh --agent codex --link
|
||||
# ./scripts/install.sh --agent cursor --target ./.cursor/rules
|
||||
# ./scripts/install.sh --list
|
||||
#
|
||||
# Flags:
|
||||
# --agent <name> claude | hermes | codex | openclaw | cursor
|
||||
# --target <path> override the default install directory
|
||||
# --link symlink instead of copy (native agents only; updates follow git pull)
|
||||
# --dry-run print actions without writing
|
||||
# --list list supported agents and their default targets
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
REPO_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||
SKILLS_DIR="$REPO_DIR/skills"
|
||||
|
||||
AGENT=""; TARGET=""; LINK=0; DRYRUN=0
|
||||
|
||||
default_target() {
|
||||
case "$1" in
|
||||
claude) echo "$HOME/.claude/skills" ;;
|
||||
hermes) echo "$HOME/.hermes/skills" ;;
|
||||
codex) echo "$HOME/.codex/skills" ;;
|
||||
openclaw) echo "$HOME/.openclaw/skills" ;;
|
||||
cursor) echo "$PWD/.cursor/rules" ;;
|
||||
*) return 1 ;;
|
||||
esac
|
||||
}
|
||||
|
||||
list_agents() {
|
||||
echo "Supported agents and default targets:"
|
||||
for a in claude hermes codex openclaw cursor; do
|
||||
printf " %-9s %s\n" "$a" "$(default_target "$a")"
|
||||
done
|
||||
echo
|
||||
echo "Native SKILL.md agents: claude, hermes, codex, openclaw (install skill folders)."
|
||||
echo "Cursor installs generated .mdc rules from exports/cursor/."
|
||||
echo "Targets are sensible defaults — override with --target if your setup differs."
|
||||
}
|
||||
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
--agent) AGENT="${2:-}"; shift 2 ;;
|
||||
--target) TARGET="${2:-}"; shift 2 ;;
|
||||
--link) LINK=1; shift ;;
|
||||
--dry-run) DRYRUN=1; shift ;;
|
||||
--list) list_agents; exit 0 ;;
|
||||
-h|--help) sed -n '2,20p' "$0" | sed 's/^# \{0,1\}//'; exit 0 ;;
|
||||
*) echo "Unknown argument: $1" >&2; exit 2 ;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ -z "$AGENT" ]; then echo "Error: --agent is required (see --list)." >&2; exit 2; fi
|
||||
if ! default_target "$AGENT" >/dev/null 2>&1; then
|
||||
echo "Error: unknown agent '$AGENT'. Run --list." >&2; exit 2
|
||||
fi
|
||||
[ -n "$TARGET" ] || TARGET="$(default_target "$AGENT")"
|
||||
|
||||
if [ ! -d "$SKILLS_DIR" ]; then
|
||||
echo "Error: cannot find skills/ at $SKILLS_DIR (run from a clone of the repo)." >&2; exit 1
|
||||
fi
|
||||
|
||||
place() { # place <src> <dest>
|
||||
local src="$1" dest="$2"
|
||||
if [ "$DRYRUN" = 1 ]; then echo " would install $(basename "$src") -> $dest"; return; fi
|
||||
rm -rf "$dest"
|
||||
if [ "$LINK" = 1 ]; then ln -s "$src" "$dest"; else cp -R "$src" "$dest"; fi
|
||||
}
|
||||
|
||||
count=0
|
||||
if [ "$DRYRUN" = 1 ]; then echo "[dry-run] Installing skills for '$AGENT' into $TARGET";
|
||||
else echo "Installing skills for '$AGENT' into $TARGET"; mkdir -p "$TARGET"; fi
|
||||
|
||||
if [ "$AGENT" = "cursor" ]; then
|
||||
# Install generated .mdc rules (flattened) into .cursor/rules/.
|
||||
CURSOR_DIR="$REPO_DIR/exports/cursor"
|
||||
if [ ! -d "$CURSOR_DIR" ]; then
|
||||
echo "Error: $CURSOR_DIR missing. Run: node scripts/build-exports.mjs" >&2; exit 1
|
||||
fi
|
||||
while IFS= read -r mdc; do
|
||||
base="$(basename "$mdc")"
|
||||
if [ "$DRYRUN" = 1 ]; then echo " would install $base -> $TARGET/$base";
|
||||
else cp "$mdc" "$TARGET/$base"; fi
|
||||
count=$((count + 1))
|
||||
done < <(find "$CURSOR_DIR" -name '*.mdc' | sort)
|
||||
else
|
||||
# Native SKILL.md agents: place each skill folder.
|
||||
for skill in "$SKILLS_DIR"/*/; do
|
||||
[ -f "$skill/SKILL.md" ] || continue
|
||||
name="$(basename "$skill")"
|
||||
place "${skill%/}" "$TARGET/$name"
|
||||
count=$((count + 1))
|
||||
done
|
||||
fi
|
||||
|
||||
echo
|
||||
if [ "$DRYRUN" = 1 ]; then
|
||||
echo "[dry-run] Would install $count item(s) for '$AGENT'."
|
||||
else
|
||||
echo "Installed $count item(s) for '$AGENT'."
|
||||
case "$AGENT" in
|
||||
cursor) echo "Cursor will pick up the rules in $TARGET on its next session." ;;
|
||||
*) echo "Restart $AGENT — it auto-discovers SKILL.md skills in $TARGET by their description." ;;
|
||||
esac
|
||||
fi
|
||||
Reference in New Issue
Block a user