Sync Skills Manager Manage synchronization between repository skills and local/system skill directories. Scripts (canonical manager) Sync between repository-canonical categories and runtime installs ( + other agents). | Command | Description | |---------|-------------| | | Preview system-only skills | | | Sync - repo (add new skills) | | | Sync repo - and refresh agent links | | | Rebuild other agent dirs as symlinks to | | | Remove duplicate entries from | | | Show sync status | (recommended) Incremental 3-way sync across: - (including ) - (canonical) - repository skills tree Key behavior: -…

\\\n | sort -u\n}\n\n# List category directories (dirs ending with \"-skills\" that directly contain skill dirs)\nlist_repo_category_dirs() {\n local cat_dir\n while IFS= read -r -d '' cat_dir; do\n case \"$cat_dir\" in\n */.git/*|*/node_modules/*|*/__pycache__/*)\n continue\n ;;\n esac\n if [ \"$(basename \"$cat_dir\")\" = \"system-skills\" ]; then\n continue\n fi\n\n local has_skill=0\n local maybe_skill\n for maybe_skill in \"$cat_dir\"/*/; do\n [ -d \"$maybe_skill\" ] || continue\n if [ -f \"$maybe_skill/SKILL.md\" ]; then\n has_skill=1\n break\n fi\n done\n\n if [ \"$has_skill\" -eq 1 ]; then\n echo \"$cat_dir\"\n fi\n done \u003c \u003c(find \"$REPO_SKILLS_DIR\" -type d -name \"*-skills\" -print0) | sort -u\n}\n\nresolve_category_dir() {\n local category=\"$1\"\n local root_candidate=\"$REPO_SKILLS_DIR/$category\"\n local fallback=\"\"\n local cat_dir\n\n # Repo-root is canonical when present.\n if [ -d \"$root_candidate\" ]; then\n echo \"$root_candidate\"\n return 0\n fi\n\n while IFS= read -r cat_dir; do\n [ \"$(basename \"$cat_dir\")\" = \"$category\" ] || continue\n case \"$cat_dir\" in\n \"$REPO_SKILLS_DIR/system-skills/\"*)\n [ -n \"$fallback\" ] || fallback=\"$cat_dir\"\n ;;\n *)\n echo \"$cat_dir\"\n return 0\n ;;\n esac\n done \u003c \u003c(list_repo_category_dirs)\n\n if [ -n \"$fallback\" ]; then\n echo \"$fallback\"\n return 0\n fi\n\n echo \"$root_candidate\"\n}\n\n# Find which category directory contains a skill\nfind_skill_category() {\n local skill_name=\"$1\"\n local cat_dir\n while IFS= read -r cat_dir; do\n if [ -d \"$cat_dir/$skill_name\" ]; then\n echo \"$cat_dir\"\n return 0\n fi\n done \u003c \u003c(list_repo_category_dirs)\n return 1\n}\n\n# Get all categories (subdirectories)\nget_categories() {\n list_repo_category_dirs | xargs -I {} basename {} | sort -u\n}\n\n# Auto-determine category for a skill\nauto_categorize() {\n local skill_name=\"$1\"\n local name_lower=$(echo \"$skill_name\" | tr '[:upper:]' '[:lower:]')\n\n # AI & ML\n if [[ \"$name_lower\" == ai-* || \"$name_lower\" == *llm* || \"$name_lower\" == *openai* || \\\n \"$name_lower\" == *context7* || \"$name_lower\" == *doc*lookup* || \"$name_lower\" == *firecrawl* || \\\n \"$name_lower\" == *mcp-builder* || \"$name_lower\" == *retrieval* || \"$name_lower\" == *eval-harness* ]]; then\n echo \"ai-skills\"\n # DevOps & Infrastructure\n elif [[ \"$name_lower\" == *kubectl* || \"$name_lower\" == *eksctl* || \"$name_lower\" == *argocd* || \\\n \"$name_lower\" == *k8s* || \"$name_lower\" == *docker* || \"$name_lower\" == *aws* || \\\n \"$name_lower\" == *gitlab* || \"$name_lower\" == *github* || \"$name_lower\" == gh-* || \\\n \"$name_lower\" == *kargo* || \"$name_lower\" == *deploy* || \"$name_lower\" == *release* || \\\n \"$name_lower\" == *terraform* || \"$name_lower\" == *sync-ci* || \"$name_lower\" == *ci-fix* || \\\n \"$name_lower\" == *cloudflare* || \"$name_lower\" == *vercel* || \"$name_lower\" == *ecc* ]]; then\n echo \"devops-skills\"\n # Engineering & Code Quality\n elif [[ \"$name_lower\" == *pattern* || \"$name_lower\" == *testing* || \"$name_lower\" == *security* || \\\n \"$name_lower\" == *tdd* || \"$name_lower\" == *verification* || \"$name_lower\" == *playwright* || \\\n \"$name_lower\" == *web-performance* || \"$name_lower\" == *web-accessibility* || \"$name_lower\" == *web-design* || \\\n \"$name_lower\" == *ui-ux* || \"$name_lower\" == *remotion* || \"$name_lower\" == *postgres* || \\\n \"$name_lower\" == *supabase* || \"$name_lower\" == *clickhouse* || \"$name_lower\" == *mdbase* || \\\n \"$name_lower\" == *coding-standards* ]]; then\n echo \"engineering-skills\"\n # Marketing & SEO\n elif [[ \"$name_lower\" == baoyu-* || \"$name_lower\" == *seo* || \"$name_lower\" == *marketing* || \"$name_lower\" == *audit* || \\\n \"$name_lower\" == *content* || \"$name_lower\" == *brand* || \"$name_lower\" == *community* ]]; then\n echo \"marketing-skills\"\n # Product Management\n elif [[ \"$name_lower\" == *product* || \"$name_lower\" == *roadmap* || \"$name_lower\" == *prd* || \\\n \"$name_lower\" == *metric* || \"$name_lower\" == *priorit* || \"$name_lower\" == *vision* || \\\n \"$name_lower\" == *linear* || \"$name_lower\" == *retention* || \"$name_lower\" == *scoping* || \\\n \"$name_lower\" == *positioning* || \"$name_lower\" == *research* || \"$name_lower\" == *marketplace* ]]; then\n echo \"product-skills\"\n # Leadership & Team\n elif [[ \"$name_lower\" == *leadership* || \"$name_lower\" == *culture* || \"$name_lower\" == *hiring* || \\\n \"$name_lower\" == *onboarding* || \"$name_lower\" == *1-1* || \"$name_lower\" == *1:1* || \\\n \"$name_lower\" == *coaching* || \"$name_lower\" == *delegate* || \"$name_lower\" == *decision* || \\\n \"$name_lower\" == *ritual* || \"$name_lower\" == *post-mortem* || \"$name_lower\" == *okrs* ]]; then\n echo \"leadership-skills\"\n # Career\n elif [[ \"$name_lower\" == *career* || \"$name_lower\" == *job* || \"$name_lower\" == *interview* || \\\n \"$name_lower\" == *promotion* || \"$name_lower\" == *offer* || \"$name_lower\" == *mentor* || \\\n \"$name_lower\" == *continuous-learning* ]]; then\n echo \"career-skills\"\n # Communication\n elif [[ \"$name_lower\" == *presentation* || \"$name_lower\" == *communicat* || \"$name_lower\" == *writing* || \\\n \"$name_lower\" == *fundrais* || \"$name_lower\" == *humanizer* || \"$name_lower\" == *docs-update* || \\\n \"$name_lower\" == *changelog* ]]; then\n echo \"communication-skills\"\n # Sales & GTM\n elif [[ \"$name_lower\" == *sales* || \"$name_lower\" == *founder* || \"$name_lower\" == *enterprise* || \\\n \"$name_lower\" == *partnership* || \"$name_lower\" == *bd* ]]; then\n echo \"sales-skills\"\n # Obsidian & Notes\n elif [[ \"$name_lower\" == *obsidian* || \"$name_lower\" == *canvas* || \"$name_lower\" == *notebook* || \\\n \"$name_lower\" == *note* || \"$name_lower\" == *task* || \"$name_lower\" == *scheduler* || \\\n \"$name_lower\" == *excalidraw* ]]; then\n echo \"obsidian-skills\"\n # Default to tools\n else\n echo \"tools-skills\"\n fi\n}\n\ndedupe_gemini_overlaps() {\n local removed=0\n\n if [ ! -d \"$GEMINI_SKILLS_DIR\" ]; then\n echo \"$removed\"\n return\n fi\n\n while IFS= read -r -d '' gemini_dir; do\n local skill_name\n skill_name=\"$(basename \"$gemini_dir\")\"\n\n # Keep canonical symlinks; remove copied/foreign overlaps from Gemini.\n if [ -L \"$gemini_dir\" ]; then\n local link_target abs_target expected_target\n link_target=\"$(readlink \"$gemini_dir\" || true)\"\n abs_target=\"$(cd \"$(dirname \"$gemini_dir\")\" && cd \"$(dirname \"$link_target\")\" 2>/dev/null && pwd)/$(basename \"$link_target\")\"\n expected_target=\"$SYSTEM_SKILLS_DIR/$skill_name\"\n if [ \"$abs_target\" = \"$expected_target\" ]; then\n continue\n fi\n fi\n\n if [ -d \"$SYSTEM_SKILLS_DIR/$skill_name\" ] || [ -L \"$SYSTEM_SKILLS_DIR/$skill_name\" ]; then\n rm -rf \"$gemini_dir\"\n removed=$((removed + 1))\n fi\n done \u003c \u003c(find \"$GEMINI_SKILLS_DIR\" -mindepth 1 -maxdepth 1 \\( -type d -o -type l \\) -print0)\n\n echo \"$removed\"\n}\n\nget_canonical_skill_names() {\n find \"$SYSTEM_SKILLS_DIR\" -mindepth 1 -maxdepth 1 \\( -type d -o -type l \\) \\\n -exec sh -c 'p=\"$1\"; [ -f \"$p/SKILL.md\" ] && basename \"$p\"' _ {} \\; 2>/dev/null | sort -u\n}\n\nis_reserved_entry() {\n local target_dir=\"$1\"\n local entry_name=\"$2\"\n\n case \"$target_dir\" in\n \"$HOME/.codex/skills\")\n [ \"$entry_name\" = \".system\" ]\n return\n ;;\n \"$HOME/.factory/skills\")\n [ \"$entry_name\" = \"template\" ]\n return\n ;;\n esac\n\n return 1\n}\n\nrelink_target_dir() {\n local target_dir=\"$1\"\n mkdir -p \"$target_dir\"\n\n while IFS= read -r -d '' entry; do\n local name\n name=\"$(basename \"$entry\")\"\n\n # Keep dotfiles/directories as agent internals.\n if [[ \"$name\" == .* ]]; then\n continue\n fi\n\n if is_reserved_entry \"$target_dir\" \"$name\"; then\n continue\n fi\n\n rm -rf \"$entry\"\n done \u003c \u003c(find \"$target_dir\" -mindepth 1 -maxdepth 1 -print0)\n\n local linked=0\n while IFS= read -r skill_name; do\n [ -n \"$skill_name\" ] || continue\n if is_reserved_entry \"$target_dir\" \"$skill_name\"; then\n continue\n fi\n ln -s \"$SYSTEM_SKILLS_DIR/$skill_name\" \"$target_dir/$skill_name\"\n linked=$((linked + 1))\n done \u003c \u003c(get_canonical_skill_names)\n\n log_info \"Linked $linked skill(s) -> $target_dir\"\n}\n\ncmd_link_all() {\n log_info \"Rebuilding agent links from canonical source: $SYSTEM_SKILLS_DIR\"\n\n local list=\"$AGENT_TARGET_DIRS\"\n IFS=',' read -r -a targets \u003c\u003c\u003c \"$list\"\n\n local target\n for target in \"${targets[@]}\"; do\n # trim leading/trailing whitespace\n target=\"$(echo \"$target\" | sed -E 's/^[[:space:]]+//; s/[[:space:]]+$//')\"\n [ -n \"$target\" ] || continue\n relink_target_dir \"$target\"\n done\n}\n\ncmd_diff() {\n log_info \"Previewing sync changes...\"\n echo \"\"\n\n local system_skills=($(ls -d \"$SYSTEM_SKILLS_DIR\"/*/ 2>/dev/null | xargs -I {} basename {}))\n local system_count=${#system_skills[@]}\n\n local repo_skills=($(get_repo_skill_names))\n local repo_count=${#repo_skills[@]}\n\n echo \"System skills: $system_count\"\n echo \"Repo skills: $repo_count\"\n echo \"\"\n\n # Build a map of repo skills for fast lookup (using grep instead of associative array)\n echo \"=== New skills in system (not in repo) ===\"\n echo \"----------------------------------------\"\n\n local new_count=0\n for skill_dir in \"$SYSTEM_SKILLS_DIR\"/*/; do\n local skill_name=$(basename \"$skill_dir\")\n\n if [ \"$skill_name\" == \"sync-skills-manager\" ]; then\n continue\n fi\n\n # Check if skill exists in repo (any category)\n local found_in_repo=\"\"\n local cat_dir\n while IFS= read -r cat_dir; do\n if [ -d \"$cat_dir/$skill_name\" ]; then\n found_in_repo=\"1\"\n break\n fi\n done \u003c \u003c(list_repo_category_dirs)\n\n if [ -z \"$found_in_repo\" ]; then\n local category=$(auto_categorize \"$skill_name\")\n log_diff \" + $skill_name → $category/\"\n new_count=$((new_count + 1))\n fi\n done\n\n if [ $new_count -eq 0 ]; then\n echo \" (no new skills)\"\n else\n echo \"\"\n echo \"Total: $new_count new skill(s)\"\n fi\n\n echo \"\"\n echo \"=== Skills in repo but NOT in system ===\"\n echo \"----------------------------------------\"\n\n local missing_count=0\n for skill_name in \"${repo_skills[@]}\"; do\n if [ ! -d \"$SYSTEM_SKILLS_DIR/$skill_name\" ]; then\n log_warn \" - $skill_name\"\n missing_count=$((missing_count + 1))\n fi\n done\n\n if [ $missing_count -eq 0 ]; then\n echo \" (all repo skills exist in system)\"\n else\n echo \"\"\n echo \"Total: $missing_count skill(s) missing in system\"\n fi\n}\n\ncmd_auto() {\n log_info \"Auto-categorizing and syncing new skills...\"\n\n local system_skills=($(ls -d \"$SYSTEM_SKILLS_DIR\"/*/ 2>/dev/null | xargs -I {} basename {}))\n local synced=0\n local skipped=0\n\n for skill_name in \"${system_skills[@]}\"; do\n if [ \"$skill_name\" == \"sync-skills-manager\" ]; then\n continue\n fi\n\n # Check if skill already exists in repo (any category)\n local found_in_repo=\"\"\n local cat_dir\n while IFS= read -r cat_dir; do\n if [ -d \"$cat_dir/$skill_name\" ]; then\n found_in_repo=\"1\"\n break\n fi\n done \u003c \u003c(list_repo_category_dirs)\n\n if [ -n \"$found_in_repo\" ]; then\n continue\n fi\n\n local category=$(auto_categorize \"$skill_name\")\n local target_dir\n target_dir=\"$(resolve_category_dir \"$category\")\"\n\n if [ ! -d \"$target_dir\" ]; then\n log_warn \"Category $category doesn't exist, using tools-skills\"\n category=\"tools-skills\"\n target_dir=\"$(resolve_category_dir \"$category\")\"\n fi\n\n log_info \"Adding: $skill_name → $category/\"\n mkdir -p \"$target_dir\"\n\n # Copy with error handling for broken symlinks\n if cp -rL \"$SYSTEM_SKILLS_DIR/$skill_name\" \"$target_dir/\" 2>/dev/null; then\n synced=$((synced + 1))\n else\n # Try rsync without broken symlinks\n if rsync -av --exclude='data' --exclude='scripts' \\\n \"$SYSTEM_SKILLS_DIR/$skill_name/\" \"$target_dir/$skill_name/\" 2>/dev/null; then\n log_warn \" Copied with some exclusions (broken symlinks skipped)\"\n synced=$((synced + 1))\n else\n log_error \" Failed to copy $skill_name\"\n skipped=$((skipped + 1))\n fi\n fi\n done\n\n echo \"\"\n if [ $synced -gt 0 ]; then\n log_info \"Synced $synced new skill(s) to repository\"\n log_info \"Run 'git add -A && git commit' to save changes\"\n fi\n if [ $skipped -gt 0 ]; then\n log_warn \"Skipped $skipped skill(s) due to errors\"\n fi\n if [ $synced -eq 0 ] && [ $skipped -eq 0 ]; then\n log_info \"No new skills to sync (all skills already exist in repo)\"\n fi\n}\n\ncmd_pull() {\n cmd_auto\n}\n\ncmd_push() {\n log_info \"Syncing repository skills to: $SYSTEM_SKILLS_DIR\"\n\n mkdir -p \"$SYSTEM_SKILLS_DIR\"\n\n local synced=0\n local updated=0\n local tmp_file\n tmp_file=\"$(mktemp)\"\n\n # Choose newest SKILL.md copy per skill name when duplicates exist in repo.\n while IFS= read -r -d '' skill_md; do\n local skill_dir\n local skill_name\n local mtime\n skill_dir=\"$(dirname \"$skill_md\")\"\n skill_name=\"$(basename \"$skill_dir\")\"\n if [ \"$skill_name\" == \"sync-skills-manager\" ]; then\n continue\n fi\n mtime=\"$(stat -f '%m' \"$skill_md\")\"\n printf '%s\\t%s\\t%s\\n' \"$skill_name\" \"$mtime\" \"$skill_dir\" >> \"$tmp_file\"\n done \u003c \u003c(find \"$REPO_SKILLS_DIR\" -type f -name \"SKILL.md\" -print0)\n\n if [ -s \"$tmp_file\" ]; then\n while IFS=

Sync Skills Manager Manage synchronization between repository skills and local/system skill directories. Scripts (canonical manager) Sync between repository-canonical categories and runtime installs ( + other agents). | Command | Description | |---------|-------------| | | Preview system-only skills | | | Sync - repo (add new skills) | | | Sync repo - and refresh agent links | | | Rebuild other agent dirs as symlinks to | | | Remove duplicate entries from | | | Show sync status | (recommended) Incremental 3-way sync across: - (including ) - (canonical) - repository skills tree Key behavior: -…

\\t' read -r skill_name skill_dir; do\n if [ -d \"$SYSTEM_SKILLS_DIR/$skill_name\" ] || [ -L \"$SYSTEM_SKILLS_DIR/$skill_name\" ]; then\n updated=$((updated + 1))\n else\n synced=$((synced + 1))\n fi\n # Canonical should own real directories; avoid writing through symlink targets.\n if [ -L \"$SYSTEM_SKILLS_DIR/$skill_name\" ]; then\n rm -f \"$SYSTEM_SKILLS_DIR/$skill_name\"\n fi\n mkdir -p \"$SYSTEM_SKILLS_DIR/$skill_name\"\n rsync -a --delete \"$skill_dir/\" \"$SYSTEM_SKILLS_DIR/$skill_name/\"\n done \u003c \u003c(sort -k1,1 -k2,2nr \"$tmp_file\" | awk -F '\\t' '!seen[$1]++ {print $1 \"\\t\" $3}')\n fi\n\n rm -f \"$tmp_file\"\n\n log_info \"Repo push complete (new: $synced, updated: $updated)\"\n cmd_link_all\n local removed\n removed=\"$(dedupe_gemini_overlaps)\"\n if [ \"$removed\" -gt 0 ]; then\n log_info \"Gemini dedupe complete (removed overlaps: $removed)\"\n else\n log_info \"Gemini dedupe: no overlapping entries found\"\n fi\n}\n\ncmd_dedupe() {\n local removed\n removed=\"$(dedupe_gemini_overlaps)\"\n if [ \"$removed\" -gt 0 ]; then\n log_info \"Gemini dedupe complete (removed overlaps: $removed)\"\n else\n log_info \"Gemini dedupe: no overlapping entries found\"\n fi\n}\n\ncmd_status() {\n echo \"Sync Status\"\n echo \"==============================================\"\n echo \"\"\n\n local system_count=$(ls -d \"$SYSTEM_SKILLS_DIR\"/*/ 2>/dev/null | wc -l | tr -d ' ')\n local repo_count=$(get_repo_skill_names | wc -l | tr -d ' ')\n\n echo \"System skills: $system_count\"\n echo \"Repo skills: $repo_count\"\n echo \"\"\n\n # Count by category\n echo \"Repo by category:\"\n local cat_dir\n while IFS= read -r cat_dir; do\n local cat_name=\"${cat_dir#$REPO_SKILLS_DIR/}\"\n local count\n count=\"$(find \"$cat_dir\" -mindepth 1 -maxdepth 1 -type d -exec sh -c '[ -f \"$1/SKILL.md\" ] && echo \"$1\"' _ {} \\; | wc -l | tr -d ' ')\"\n echo \" $cat_name: $count skills\"\n done \u003c \u003c(list_repo_category_dirs)\n echo \"\"\n\n local missing=0\n echo \"Skills in repo but NOT in system:\"\n for skill_name in $(get_repo_skill_names); do\n if [ ! -d \"$SYSTEM_SKILLS_DIR/$skill_name\" ]; then\n echo \" [ ] $skill_name\"\n missing=$((missing + 1))\n fi\n done\n\n if [ $missing -eq 0 ]; then\n echo \" (all skills synced)\"\n fi\n}\n\n# Main\ncase \"${1:-help}\" in\n diff)\n cmd_diff\n ;;\n pull|auto)\n cmd_auto\n ;;\n push)\n cmd_push\n ;;\n link-all)\n cmd_link_all\n ;;\n dedupe)\n cmd_dedupe\n ;;\n status)\n cmd_status\n ;;\n help|--help|-h)\n show_help\n ;;\n *)\n log_error \"Unknown command: $1\"\n show_help\n exit 1\n ;;\nesac\n","content_type":"application/x-sh; charset=utf-8","language":"bash","size":18503,"content_sha256":"de6e528ffa16d444351d4068a5ff7700ccfdf0ca8d8efaea09d603f349a7fed5"}],"content_json":{"type":"doc","content":[{"type":"heading","attrs":{"level":1},"content":[{"text":"Sync Skills Manager","type":"text"}]},{"type":"paragraph","content":[{"text":"Manage synchronization between repository skills and local/system skill directories.","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Scripts","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"sync-skills.sh","type":"text","marks":[{"type":"code_inline"}]},{"text":" (canonical manager)","type":"text"}]},{"type":"paragraph","content":[{"text":"Sync between repository-canonical categories and runtime installs (","type":"text"},{"text":"~/.claude/skills","type":"text","marks":[{"type":"code_inline"}]},{"text":" + other agents).","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Command","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Description","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"./sync-skills.sh diff","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Preview system-only skills","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"./sync-skills.sh pull","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Sync ","type":"text"},{"text":"~/.claude/skills","type":"text","marks":[{"type":"code_inline"}]},{"text":" -> repo (add new skills)","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"./sync-skills.sh push","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Sync repo -> ","type":"text"},{"text":"~/.claude/skills","type":"text","marks":[{"type":"code_inline"}]},{"text":" and refresh agent links","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"./sync-skills.sh link-all","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Rebuild other agent dirs as symlinks to ","type":"text"},{"text":"~/.claude/skills","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"./sync-skills.sh dedupe","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Remove duplicate entries from ","type":"text"},{"text":"~/.gemini/skills","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"./sync-skills.sh status","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Show sync status","type":"text"}]}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"sync-skills-3way.sh","type":"text","marks":[{"type":"code_inline"}]},{"text":" (recommended)","type":"text"}]},{"type":"paragraph","content":[{"text":"Incremental 3-way sync across:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"~/.codex/skills","type":"text","marks":[{"type":"code_inline"}]},{"text":" (including ","type":"text"},{"text":".system","type":"text","marks":[{"type":"code_inline"}]},{"text":")","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"~/.claude/skills","type":"text","marks":[{"type":"code_inline"}]},{"text":" (canonical)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"repository skills tree","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"Key behavior:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Incremental only (","type":"text"},{"text":"rsync --update","type":"text","marks":[{"type":"code_inline"}]},{"text":"), never deletes files.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"New skills missing in repo are added to ","type":"text"},{"text":"tools-skills/","type":"text","marks":[{"type":"code_inline"}]},{"text":" by default (or legacy ","type":"text"},{"text":"system-skills/tools-skills/","type":"text","marks":[{"type":"code_inline"}]},{"text":" if present).","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"For duplicate skill names in repo, the newest ","type":"text"},{"text":"SKILL.md","type":"text","marks":[{"type":"code_inline"}]},{"text":" copy is treated as canonical for repo -> local sync.","type":"text"}]}]}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Command","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Description","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"./sync-skills-3way.sh sync","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Run 3-way incremental sync (default)","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"./sync-skills-3way.sh status","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Show counts and name-level diffs","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"./sync-skills-3way.sh help","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Show usage","type":"text"}]}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"scripts/skills_profiles.py","type":"text","marks":[{"type":"code_inline"}]},{"text":" (profiles manager)","type":"text"}]},{"type":"paragraph","content":[{"text":"Manage ","type":"text"},{"text":"which","type":"text","marks":[{"type":"em"}]},{"text":" skills are enabled per agent by creating/removing symlinks that point to the canonical registry (","type":"text"},{"text":"~/.claude/skills","type":"text","marks":[{"type":"code_inline"}]},{"text":").","type":"text"}]},{"type":"paragraph","content":[{"text":"This solves two common issues:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"New skills created/edited in one tool (e.g. Codex) not showing up in others (e.g. Cursor).","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Too many skills loaded everywhere (context bloat) while still keeping one global registry.","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"Config","type":"text","marks":[{"type":"strong"}]}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Default config file: ","type":"text"},{"text":"system-skills/sync-skills-manager/skills-profiles.json","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"paragraph","content":[{"text":"Safety model","type":"text","marks":[{"type":"strong"}]}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"apply","type":"text","marks":[{"type":"code_inline"}]},{"text":" and ","type":"text"},{"text":"normalize","type":"text","marks":[{"type":"code_inline"}]},{"text":" default to ","type":"text"},{"text":"dry-run","type":"text","marks":[{"type":"strong"}]},{"text":". Use ","type":"text"},{"text":"--apply","type":"text","marks":[{"type":"code_inline"}]},{"text":" to change files.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Only “managed skills” are modified: a directory in the registry that contains ","type":"text"},{"text":"SKILL.md","type":"text","marks":[{"type":"code_inline"}]},{"text":".","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Non-skill folders (no ","type":"text"},{"text":"SKILL.md","type":"text","marks":[{"type":"code_inline"}]},{"text":", e.g. ","type":"text"},{"text":"dist/","type":"text","marks":[{"type":"code_inline"}]},{"text":") are treated as ","type":"text"},{"text":"unmanaged","type":"text","marks":[{"type":"strong"}]},{"text":" and never touched.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"normalize","type":"text","marks":[{"type":"code_inline"}]},{"text":" always moves existing entries into a backup folder before replacing them with symlinks.","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"Commands","type":"text","marks":[{"type":"strong"}]}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# Show registry + per-agent status\npython3 system-skills/sync-skills-manager/scripts/skills_profiles.py status\n\n# Preview what would change (desired vs current)\npython3 system-skills/sync-skills-manager/scripts/skills_profiles.py diff\n\n# 1) Sync Codex/registry/repo (incremental, no delete)\npython3 system-skills/sync-skills-manager/scripts/skills_profiles.py sync\n\n# 2) Normalize drift (copies/non-canonical links -> canonical symlinks, with backups)\npython3 system-skills/sync-skills-manager/scripts/skills_profiles.py normalize --dry-run\npython3 system-skills/sync-skills-manager/scripts/skills_profiles.py normalize --apply\n\n# 3) Apply enable/disable sets (remove extra canonical links, add missing links)\npython3 system-skills/sync-skills-manager/scripts/skills_profiles.py apply --dry-run\npython3 system-skills/sync-skills-manager/scripts/skills_profiles.py apply --apply\n\n# One-shot daily workflow (sync -> normalize -> apply)\npython3 system-skills/sync-skills-manager/scripts/skills_profiles.py refresh --apply\n\n# Manage by star ratings (1-7)\n# Keep only 7-star skills (other agents). claude-code registry itself is skipped.\npython3 system-skills/sync-skills-manager/scripts/skills_profiles.py stars --mode only --stars 7 --dry-run\npython3 system-skills/sync-skills-manager/scripts/skills_profiles.py stars --mode only --stars 7 --apply\n\n# Batch install by stars (e.g. add 6-star and 5-star)\npython3 system-skills/sync-skills-manager/scripts/skills_profiles.py stars --mode install --stars 6,5 --apply\n\n# Batch uninstall by stars\npython3 system-skills/sync-skills-manager/scripts/skills_profiles.py stars --mode uninstall --stars 5 --apply","type":"text"}]},{"type":"paragraph","content":[{"text":"Backups","type":"text","marks":[{"type":"strong"}]}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Default backup root: ","type":"text"},{"text":"~/.claude/skills-backups/\u003ctimestamp>/\u003cagent>/\u003cskill>/...","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"paragraph","content":[{"text":"Tests","type":"text","marks":[{"type":"strong"}]}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"python3 -m unittest -q","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"scripts/agent_skills_audit.py","type":"text","marks":[{"type":"code_inline"}]},{"text":" (agent installation + diff auditor)","type":"text"}]},{"type":"paragraph","content":[{"text":"Check which supported agents are installed locally, list recognized skills, and diff skill sets between agents.","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# Scan all supported agents\npython3 system-skills/sync-skills-manager/scripts/agent_skills_audit.py scan\n\n# Only installed agents, with skills preview\npython3 system-skills/sync-skills-manager/scripts/agent_skills_audit.py scan --installed-only --with-skills\n\n# List full skills for selected agents\npython3 system-skills/sync-skills-manager/scripts/agent_skills_audit.py skills --installed-only --agent codex,cursor\n\n# Diff codex vs cursor\npython3 system-skills/sync-skills-manager/scripts/agent_skills_audit.py diff --left codex --right cursor\n\n# Diff one baseline against multiple agents\npython3 system-skills/sync-skills-manager/scripts/agent_skills_audit.py diff --left codex --right cursor,amp,claude-code\n\n# Sync check: compare installed agents against canonical claude-code\npython3 system-skills/sync-skills-manager/scripts/agent_skills_audit.py sync-check --canonical-agent claude-code --installed-only\n\n# Sync check for selected agents\npython3 system-skills/sync-skills-manager/scripts/agent_skills_audit.py sync-check --canonical-agent claude-code --agent codex,cursor,amp","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"scripts/reclassify_system_skills.py","type":"text","marks":[{"type":"code_inline"}]},{"text":" (category rebalancer)","type":"text"}]},{"type":"paragraph","content":[{"text":"Rebalance ","type":"text"},{"text":"system-skills","type":"text","marks":[{"type":"code_inline"}]},{"text":" category distribution (defaults to reclassifying ","type":"text"},{"text":"tools-skills","type":"text","marks":[{"type":"code_inline"}]},{"text":" into domain categories).","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# Preview reclassification plan\npython3 system-skills/sync-skills-manager/scripts/reclassify_system_skills.py --from-category tools-skills\n\n# Apply reclassification\npython3 system-skills/sync-skills-manager/scripts/reclassify_system_skills.py --from-category tools-skills --apply","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"scripts/flatten_system_skills_layout.py","type":"text","marks":[{"type":"code_inline"}]},{"text":" (layout simplifier)","type":"text"}]},{"type":"paragraph","content":[{"text":"Flatten legacy ","type":"text"},{"text":"system-skills/\u003ccategory>/\u003cskill>","type":"text","marks":[{"type":"code_inline"}]},{"text":" into repo-root ","type":"text"},{"text":"\u003ccategory>/\u003cskill>","type":"text","marks":[{"type":"code_inline"}]},{"text":" while preserving ","type":"text"},{"text":"system-skills/sync-skills-manager/","type":"text","marks":[{"type":"code_inline"}]},{"text":".","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# Preview flatten/migration actions\npython3 system-skills/sync-skills-manager/scripts/flatten_system_skills_layout.py\n\n# Apply migration actions\npython3 system-skills/sync-skills-manager/scripts/flatten_system_skills_layout.py --apply","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Usage","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Daily 3-way sync","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"./sync-skills-3way.sh sync","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Quick status check","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"./sync-skills-3way.sh status","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Configuration","type":"text"}]},{"type":"paragraph","content":[{"text":"sync-skills.sh","type":"text","marks":[{"type":"code_inline"}]},{"text":" uses ","type":"text"},{"text":"sync-config.json","type":"text","marks":[{"type":"code_inline"}]},{"text":":","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"json"},"content":[{"text":"{\n \"system_skills_path\": \"~/.claude/skills\",\n \"repo_skills_path\": \"./\",\n \"exclude_patterns\": [\"sync-skills-manager\"],\n \"sync_mode\": \"incremental\",\n \"default_command\": \"diff\"\n}","type":"text"}]},{"type":"hr","attrs":{"markup":"---"}}]},"metadata":{"date":"2026-06-05","name":"sync-skills-manager","author":"@skillopedia","source":{"stars":3,"repo_name":"skills","origin_url":"https://github.com/oldwinter/skills/blob/HEAD/meta-skills/sync-skills-manager/SKILL.md","repo_owner":"oldwinter","body_sha256":"e190056d9ce99c108d18db0e12e65ea6f9f0206d16c8b4574085dc07d535421c","cluster_key":"8b95083af14f75af458107262ad9755d12ed89324f092ca36402d264a2f308c8","clean_bundle":{"format":"clean-skill-bundle-v1","source":"oldwinter/skills/meta-skills/sync-skills-manager/SKILL.md","attachments":[{"id":"ee98291d-53f9-5cbd-a14d-a032cfff9456","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/ee98291d-53f9-5cbd-a14d-a032cfff9456/attachment.md","path":"AGENTS.md","size":1025,"sha256":"43b79c437d6261bf2659dc5549f433d4cb9b8562ac4a6d07b02da491a7ef1a86","contentType":"text/markdown; charset=utf-8"},{"id":"c35a2db0-a694-59a6-9e08-7808accc1c4b","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/c35a2db0-a694-59a6-9e08-7808accc1c4b/attachment.py","path":"scripts/agent_skills_audit.py","size":19938,"sha256":"ef8132a7125cc29d7108f319495a479cd0241bd3900d77dd1951df9dbe6658e9","contentType":"text/x-python; charset=utf-8"},{"id":"d350dc84-2833-5a56-92e1-078810821d1d","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/d350dc84-2833-5a56-92e1-078810821d1d/attachment.py","path":"scripts/flatten_system_skills_layout.py","size":7928,"sha256":"ab4b0b55d47384b5dc20de659aa9e312c6b48f45152b7b0534c8cc9dacb4cf6d","contentType":"text/x-python; charset=utf-8"},{"id":"ccd430fd-8ee8-545f-ac94-499ea73a92fe","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/ccd430fd-8ee8-545f-ac94-499ea73a92fe/attachment.py","path":"scripts/reclassify_system_skills.py","size":8541,"sha256":"8cf83d2386358322f594f3240b437bc068ab29e6d86bb7497e9b49d6d298196a","contentType":"text/x-python; charset=utf-8"},{"id":"8e5a4995-0aa6-555c-93e3-90095d5532b0","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/8e5a4995-0aa6-555c-93e3-90095d5532b0/attachment.py","path":"scripts/skills_profiles.py","size":35366,"sha256":"6901c90becd8499eaa6553ac29a68ca049f0c2735d2393e71a7b95eca062cf09","contentType":"text/x-python; charset=utf-8"},{"id":"f11f31d0-caab-5f49-b5e7-e0ebf83a33ff","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/f11f31d0-caab-5f49-b5e7-e0ebf83a33ff/attachment.py","path":"scripts/test_agent_skills_audit.py","size":4409,"sha256":"38e26ee692a9ce2ea99a41d9ae29a639f87d3ceedcc31e98a90bde961f11663c","contentType":"text/x-python; charset=utf-8"},{"id":"643cd15f-350e-53a2-83f1-aa0c411c760e","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/643cd15f-350e-53a2-83f1-aa0c411c760e/attachment.py","path":"scripts/test_flatten_system_skills_layout.py","size":3324,"sha256":"cb2eb50255c58d357e464ea8b43cabff37a4f5c6f984da5568c3a831146d81c1","contentType":"text/x-python; charset=utf-8"},{"id":"34234d74-438f-5078-9e8f-ad761c2ce105","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/34234d74-438f-5078-9e8f-ad761c2ce105/attachment.py","path":"scripts/test_reclassify_system_skills.py","size":1492,"sha256":"8739cecc053a7890af281e6849d6538fa6dfd31912a2934bafcc972a8f978306","contentType":"text/x-python; charset=utf-8"},{"id":"0f4fdfaa-d3d7-5527-a1fd-1ca385a1b751","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/0f4fdfaa-d3d7-5527-a1fd-1ca385a1b751/attachment.py","path":"scripts/test_skills_profiles.py","size":8093,"sha256":"519d54bc39867cb9b883d09dc6ada1806b5d07a1248a0908d2ebcca8931d9234","contentType":"text/x-python; charset=utf-8"},{"id":"7e0b4aaa-b82d-5ef9-a772-94e3233bfd8c","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/7e0b4aaa-b82d-5ef9-a772-94e3233bfd8c/attachment.json","path":"skills-profiles.json","size":2890,"sha256":"6699b02a14761dc402b69d6b5fa86dad64594c13ed6f349746f5fdcc754badae","contentType":"application/json; charset=utf-8"},{"id":"cf54741e-ea66-50da-8af1-93ab6be6a6d7","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/cf54741e-ea66-50da-8af1-93ab6be6a6d7/attachment.json","path":"sync-config.json","size":181,"sha256":"7a41aec76a6d0c94eeccbc71d91d46d8d77da6e7ef2054b3359d23a323c42b16","contentType":"application/json; charset=utf-8"},{"id":"5483e888-fd70-53f6-8a81-8b68bf2f9026","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/5483e888-fd70-53f6-8a81-8b68bf2f9026/attachment.sh","path":"sync-skills-3way.sh","size":9543,"sha256":"f16478178991dd58b82245191db5bc452e7b4a9d90575774a6a096b5ed895e82","contentType":"application/x-sh; charset=utf-8"},{"id":"27db8cf5-a489-5947-81fe-b697d074bbbb","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/27db8cf5-a489-5947-81fe-b697d074bbbb/attachment.sh","path":"sync-skills.sh","size":18503,"sha256":"de6e528ffa16d444351d4068a5ff7700ccfdf0ca8d8efaea09d603f349a7fed5","contentType":"application/x-sh; charset=utf-8"}],"bundle_sha256":"0d2086660b0c4c88ff9dc190cc9fc9acff97404a89dcecd7ac6b90982a662f88","attachment_count":13,"text_attachments":13,"attachment_storage":"skillopedia-attachments-v1","binary_attachments":0,"excluded_attachments":[]},"cluster_size":1,"skill_md_path":"meta-skills/sync-skills-manager/SKILL.md","import_metadata":{"date":"2026-06-05","author":"@skillopedia","version":"v1","category":"productivity-workflow","category_label":"Productivity"},"exact_dupes_collapsed_into_this":0},"version":"v1","category":"productivity-workflow","import_tag":"clean-skills-v1","description":"Manage synchronization workflows between repository skills and local system skill directories."}},"renderedAt":1782980919596}

Sync Skills Manager Manage synchronization between repository skills and local/system skill directories. Scripts (canonical manager) Sync between repository-canonical categories and runtime installs ( + other agents). | Command | Description | |---------|-------------| | | Preview system-only skills | | | Sync - repo (add new skills) | | | Sync repo - and refresh agent links | | | Rebuild other agent dirs as symlinks to | | | Remove duplicate entries from | | | Show sync status | (recommended) Incremental 3-way sync across: - (including ) - (canonical) - repository skills tree Key behavior: -…