diff --git a/README.md b/README.md index ccad9a4b..3e78a5af 100644 --- a/README.md +++ b/README.md @@ -113,7 +113,26 @@ Visit [impeccable.style](https://impeccable.style#casestudies) to see before/aft Visit [impeccable.style](https://impeccable.style), download the ZIP for your tool, and extract to your project. -### Option 2: Copy from Repository +### Option 2: Git Submodule (For version control) + +Keep skills updated by adding this repository as a submodule: + +```bash +# 1. Add impeccable as a submodule +git submodule add https://github.com/pbakaus/impeccable .impeccable + +# 2. Link your preferred provider's skill folders (e.g. cursor, claude, gemini) +./.impeccable/bin/link.sh cursor + +# 3. Commit the changes +# (This creates symlinks inside .cursor/skills/*, without replacing your whole .cursor folder) +git add .gitmodules .impeccable .cursor +git commit -m "Add Impeccable skills" +``` + +To update the skills later, simply run `git submodule update --remote`. If new skills are added upstream, run the link script again to create symlinks for the new folders. + +### Option 3: Copy from Repository **Cursor:** ```bash @@ -162,6 +181,17 @@ cp -r dist/gemini/.gemini your-project/ cp -r dist/codex/.codex/* ~/.codex/ ``` +### Option 3: Git Submodule (Advanced) + +If you'd like to keep Impeccable updated as a git submodule in your project: + +```bash +git submodule add https://github.com/pbakaus/impeccable .impeccable +./.impeccable/bin/link.sh +``` + +Replace `` with your tool (e.g., `cursor`, `claude`, `gemini`, `opencode`, `pi`). This will create symlinks only for the skill subfolders inside your existing provider config (for example, `.claude/skills/*`), instead of replacing the whole provider directory. + ## Usage Once installed, use commands in your AI harness: diff --git a/bin/link.sh b/bin/link.sh new file mode 100755 index 00000000..b2007bad --- /dev/null +++ b/bin/link.sh @@ -0,0 +1,65 @@ +#!/bin/bash + +# link.sh: Symlink impeccable skills into the parent project directory +# Usage: ./bin/link.sh + +set -e + +PROVIDER=$1 +REPO_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +SUBMODULE_NAME="$(basename "$REPO_DIR")" +PARENT_DIR="$(cd "$REPO_DIR/.." && pwd)" + +if [ -z "$PROVIDER" ]; then + echo "Usage: $0 " + echo "Example: $0 cursor" + echo "Available providers:" + find "$REPO_DIR" -maxdepth 1 -type d -name ".*" ! -name ".git" ! -name ".github" ! -name ".*-plugin" -exec basename {} \; | sed 's/^\.//' | sort + exit 1 +fi + +PROVIDER_DIR=".$PROVIDER" +SOURCE_SKILLS_DIR="$REPO_DIR/$PROVIDER_DIR/skills" +TARGET_PROVIDER_DIR="$PARENT_DIR/$PROVIDER_DIR" +TARGET_SKILLS_DIR="$TARGET_PROVIDER_DIR/skills" + +if [ ! -d "$REPO_DIR/$PROVIDER_DIR" ]; then + echo "Error: Provider directory '$PROVIDER_DIR' not found in $REPO_DIR" + exit 1 +fi + +if [ ! -d "$SOURCE_SKILLS_DIR" ]; then + echo "Error: Skills directory '$SOURCE_SKILLS_DIR' not found" + exit 1 +fi + +echo "Linking skill folders from $PROVIDER_DIR into parent directory..." + +mkdir -p "$TARGET_SKILLS_DIR" + +LINKED=0 +SKIPPED=0 + +for skill_dir in "$SOURCE_SKILLS_DIR"/*; do + [ -d "$skill_dir" ] || continue + + skill_name="$(basename "$skill_dir")" + target_path="$TARGET_SKILLS_DIR/$skill_name" + relative_source="$SUBMODULE_NAME/$PROVIDER_DIR/skills/$skill_name" + + if [ -e "$target_path" ] || [ -L "$target_path" ]; then + echo "Warning: '$target_path' already exists. Skipping $skill_name." + SKIPPED=$((SKIPPED + 1)) + continue + fi + + ( + cd "$PARENT_DIR" + ln -s "$relative_source" "$PROVIDER_DIR/skills/$skill_name" + ) + + echo "Linked: $target_path -> $relative_source" + LINKED=$((LINKED + 1)) +done + +echo "Done! Linked $LINKED skill folder(s), skipped $SKIPPED existing folder(s)."