Now liveThe Skillselion MCP - thousands of ranked skills, loaded into your agent mid-task. No install.Get it →
ai-strategy-llc avatar

Skill Sync

  • 1 installs
  • Updated May 29, 2026
  • ai-strategy-llc/agentskills

skill-sync is a Claude Code skill that provisions each AI CLI's per-repo skill and agent directories with only the artifacts a repo's toolchain actually needs.

About

skill-sync provisions a repo's per-CLI agent and skill directories (.claude/, .opencode/, .kilo/, .codex/, .gemini/, .pi/, .crush/) with only the artifacts a repo needs. It detects the repo's toolchains, fetches the matching subset from an org-configured GitHub source repo, renders each agent through a per-CLI renderer, and writes a manifest for idempotent re-runs. Developers use it when setting up a new repo, after adding or removing a language, or after adding a new CLI to their global install.

  • Provisions per-CLI skill and agent directories from an org source repo
  • Detects repo toolchains (Cargo.toml, package.json, pyproject.toml, go.mod, etc.) and installs only the matching subset
  • apply / --dry-run / --status / --prune modes with an idempotent .sync-manifest.json

Skill Sync by the numbers

  • 1 all-time installs (skills.sh)
  • Ranked #644 of 782 Skill Development skills by installs in the Skillselion catalog
  • Data as of Jul 7, 2026 (Skillselion catalog sync)
At a glance

skill-sync capabilities & compatibility

Capabilities
skill development
Works with
github
From the docs

What skill-sync says it does

`skill-sync` installs only the repo-scope artifacts (skills + agents) a given repo actually needs, fetched from an organization's source GitHub repo
SKILL.md
Modes: apply, --dry-run, --status, --prune. Accepts --for <cli>[,<cli>...] to override the CLI set.
SKILL.md
npx skills add https://github.com/ai-strategy-llc/agentskills --skill skill-sync

Add your badge

Show developers this skill is listed on Skillselion. Paste this into your README.

Listed on Skillselion
Installs1
Last updatedMay 29, 2026
Repositoryai-strategy-llc/agentskills

What it does

Install only the repo-scope skills and agents a repo needs into each AI CLI directory the developer has set up.

When should I use this skill?

when setting up a new repo, after adding or removing a language, or after adding a new CLI to your global install

What you get

Each installed CLI gets only the repo-relevant skills and agents in its own directory, recorded for idempotent re-runs.

  • Per-CLI skill and agent directories
  • A .sync-manifest.json for idempotent re-runs

By the numbers

  • Supports 8 AI CLIs (.claude, .opencode, .kilo, .codex, .gemini, agy, .pi, .crush)
  • 4 run modes: apply, --dry-run, --status, --prune

Files

SKILL.mdMarkdownGitHub ↗

Skill Sync

skill-sync installs only the repo-scope artifacts (skills + agents) a given repo actually needs, fetched from an organization's source GitHub repo, and writes them into the correct directory for each AI CLI the user has installed AgentSkills for. It replaces "install everything globally and hope the harness picks the right one" with "install the relevant subset per repo so the harness has a clean pick — for each CLI in play."

Source repo layout

The source GitHub repo splits skills and agents into global-scope and repo-scope subtrees. Agents live under a single agents/base/ canonical tree and are rendered to per-CLI formats at install time by the scripts in agents/renderers/:

skills/
  global-scope/      # user-level — installed into ~/.claude/skills/ via install.sh, not skill-sync
    deep-review/SKILL.md
    branch-review/SKILL.md
    bdd-audit/SKILL.md
    coverage-audit/SKILL.md
    repo-health/SKILL.md
    merge-sprint/SKILL.md
    skill-sync/SKILL.md
    skill-interview/SKILL.md
  repo-scope/        # per-repo — installed by skill-sync when the toolchain matches
    preflight/SKILL.md
    cargo-preflight/SKILL.md
    rust-testing/SKILL.md
    deploy-app/SKILL.md
    native-app-deploy/SKILL.md, web-app-deploy/SKILL.md, container-app-deploy/SKILL.md
    …
agents/
  base/              # canonical, CLI-agnostic source
    global-scope/
      deep-review/{agent.md, metadata.yaml, references/, evals/}
      branch-review/{agent.md, metadata.yaml}
      bdd-audit/{agent.md, metadata.yaml}
      coverage-investigator/{agent.md, metadata.yaml}
      ato-artifact-collector/{agent.md, metadata.yaml, references/, evals/, config.yaml}
    repo-scope/      # empty today; reserved for future repo-scoped agents
  renderers/         # one script per CLI (claude.sh, opencode.sh, kilo.sh, gemini.sh, agy.sh, codex.sh)
    + codex-agents-md.sh for the Codex AGENTS.md inventory

Agent rendering. skill-sync never copies agents/base/<scope>/<name>/agent.md verbatim. Instead, for each CLI in play, it pipes the base agent through agents/renderers/<cli>.sh to produce the CLI's native format (Markdown+YAML for Claude/OpenCode/Kilo/Gemini/Antigravity; TOML for Codex). Antigravity (agy) reuses the Gemini renderer's helpers because the two CLIs share a core agent engine.

`skill-sync` only ever fetches from `skills/repo-scope/` and `agents/base/repo-scope/`. The global-scope/ subtrees are the responsibility of a separate one-time install (install.sh) — they are always available regardless of which repo the user is working in, so installing them per-repo would just duplicate them. Globally, install.sh writes skills to at most two physical locations regardless of how many CLIs are selected: ~/.claude/skills/ (Claude only) and ~/.agents/skills/ (shared by OpenCode + Kilo + Gemini + Antigravity + Codex, all of which auto-discover that path). Codex specifically also scans ~/.codex/skills/, so writing there in addition would surface every skill twice — install.sh deliberately avoids that. Within ~/.<cli>/agents/, each selected CLI gets its own rendered agents.

A thin-stub skill in skills/repo-scope/<name>/SKILL.md may delegate to an agent in agents/base/repo-scope/<name>/. When a skill advertises an agent delegate, both are installed together; they are versioned as a pair and recorded as a pair in the manifest.

Install target layout — per CLI

In the target repo, installs go under a per-CLI directory. The installer manifest at ~/.agent-skills/installer-manifest.json lists which CLIs the user has installed globally; skill-sync targets that same set unless overridden with --for.

CLIPer-repo targetAgent file extension
Claude Code<repo>/.claude/.md
OpenCode<repo>/.opencode/.md
Kilo Code<repo>/.kilo/.md
Codex<repo>/.codex/.toml
Gemini CLI<repo>/.gemini/.md
Antigravity CLI (agy)<repo>/.gemini/antigravity-cli/ (extrapolated; verify on a real per-repo install).md
Pi (pi.dev)<repo>/.pi/ and <repo>/.agents/skills/ (skills only — no agents)
Crush<repo>/.crush/skills/ and <repo>/.agents/skills/ (skills only — agents live in crush.json)

For each selected CLI the install shape is:

<repo>/.<cli>/
  skills/<name>/SKILL.md                        # Claude only — other CLIs don't consume SKILL.md today
  agents/<name>.<ext>                           # flat form for agents without bundled references
  agents/<name>/<name>.<ext>                    # directory form for agents that bundle references/evals/config.yaml
  agents/<name>/{references/, evals/, config.yaml}   # bundled alongside the rendered agent file

Codex additionally gets <repo>/.codex/AGENTS.md — an inventory of installed agents rendered via agents/renderers/codex-agents-md.sh.

Why skills are Claude-only per-repo for now. Per-repo skill placement is still Claude-only here even though OpenCode, Kilo, Gemini, Antigravity, and Codex all support SKILL.md natively at the global tier — install.sh (global) handles them via the cross-scan compatibility paths (~/.agents/skills/ for OpenCode/Kilo/Gemini/Antigravity, dedicated dirs for Claude/Codex). Per-repo skill scanning paths differ by CLI (e.g., <repo>/.opencode/skills/ vs <repo>/.kilo/skills/ vs <repo>/.gemini/skills/ vs <repo>/.antigravity/skills/) and there is no equivalent shared .agents/skills/ convention at the per-repo tier in every CLI. Until that lands consistently, repo-scope skills go to .claude/skills/ only and other CLIs read repo-scope content via Claude's directory if they cross-scan it; otherwise per-CLI repo-scope skill placement should be added when there is a real need.

When to run

  • Setting up a brand-new clone of an existing repo.
  • After adding or removing a language/toolchain from the repo.
  • After the org publishes a new skill-source ref and you want to update.
  • After adding a new CLI to your global install (re-run with the new CLI in --for or refresh the installer manifest).
  • To audit drift: skill-sync --status reports what is installed vs. what would be installed.

For a greenfield project with no code yet, use the sibling skill skill-interview — it gathers the language/framework/architecture answers by Q&A and then calls this skill.

Configuration

Config lives at ~/.claude/skill-sync.config.yaml (user-global). A per-repo override at <repo>/.skill-sync.yaml wins for its fields. If neither exists, skill-sync refuses to run — there is no built-in default source, because the source is org-specific.

version: 2
source:
  repo: your-org/ClaudeSkills           # GitHub owner/repo
  ref: main                             # branch, tag, or commit SHA (prefer a pinned tag)
target_clis: []                         # optional. Empty = read from ~/.agent-skills/installer-manifest.json
                                        # else comma-list of: claude, opencode, kilo, codex, gemini, agy, pi, cursor, crush
allowlist: []                           # empty = every skill/agent in source is available
                                        # non-empty = only these directory names may be installed
deny: []                                # always exclude these (takes precedence over allowlist)
auth:
  method: gh                            # gh | ssh
                                        # gh  → use `gh` CLI (ambient auth, no tokens stored)
                                        # ssh → use `git` over SSH (keys must already be configured)

Workflow

Step 1 — Load config, resolve CLI set, verify auth

1. Read ~/.claude/skill-sync.config.yaml. Merge <repo>/.skill-sync.yaml if present (per-field override, no deep merge). 2. Resolve the CLI set:

  • If the user passed --for <list> on invocation, use that.
  • Else if config has target_clis: non-empty, use that.
  • Else read ~/.agent-skills/installer-manifest.json and use the clis array from the most recent install.sh run.
  • Else ask the user via AskUserQuestion (multi-select): "Which CLIs should I configure this repo for? claude / opencode / kilo / codex / gemini / agy / pi / cursor / crush".

3. If auth.method: gh, check gh auth status succeeds; if ssh, check ssh -T git@github.com 2>&1 | grep -q 'successfully authenticated'. If auth is missing, stop with an actionable message — do not prompt to store tokens.

Step 2 — Detect the repo's toolchains and workflow signals

Walk the repo root and immediate subtrees for marker files. Record every toolchain detected.

Toolchain markers:

MarkerToolchain → Skills to install
Cargo.tomlRust → cargo-preflight, rust-testing
*.xcodeproj, *.xcworkspace, Package.swift, Podfile, *.m + *.hSwift / Objective-C → xcode-preflight, swift-testing
tsconfig.json, or package.json + TypeScript depTypeScript → node-preflight, node-testing
package.json without TypeScriptJavaScript → node-preflight, node-testing
pyproject.toml, setup.py, requirements.txt, PipfilePython → python-preflight, python-testing
pom.xml, build.gradle, build.gradle.ktsJava / Kotlin → jvm-preflight, jvm-testing
go.modGo → go-preflight
Gemfile, *.gemspec, RakefileRuby → ruby-preflight
*.csproj, *.sln, Directory.Build.propsC# / .NET → dotnet-preflight
CMakeLists.txt, Makefile, configure.ac, meson.buildC / C++ → cmake-preflight
composer.jsonPHP → php-preflight
DESCRIPTION + .R files, *.sas, Makefile.PL / cpanfile, standalone .sql / .sqlfluffR / SAS / Perl / SQL → data-script-preflight

Workflow signals (always install when detected):

Only artifacts under the source repo's repo-scope trees are candidates. Global-scope artifacts live in each CLI's global directory already.

SignalSkills / agents to install
Any recognized VCS/CI marker (git repo)skills: preflight
Tauri (tauri.conf.json or src-tauri/) or *.xcodeproj or .xcworkspace on macOSskills: deploy-app (dispatcher), native-app-deploy
Dockerfile or docker-compose.ymlskills: deploy-app, container-app-deploy
package.json with "express" / "fastify" / "next" dep, or pyproject.toml with "flask" / "fastapi" / "django"skills: deploy-app, web-app-deploy

Skill↔agent pairing rule. When a repo-scope stub skill advertises an agent delegate, both are installed together and recorded as a pair in the manifest. Never install the stub without the agent — the stub's only purpose is to trigger the agent. There are no repo-scope pairs today; all current agent pairs live under agents/base/global-scope/ and are handled by install.sh, not skill-sync.

Apply allowlist and deny filters last.

Step 3 — Compute the diff

Read <repo>/.claude/.sync-manifest.json if it exists (the legacy single-CLI location; used as the authoritative source regardless of which CLIs are now in play — the manifest records what was previously installed per CLI).

Compute three sets per CLI:

  • To add — selected by detection, not present in the manifest's entry for this CLI.
  • To update — present in the manifest, manifest records a different source ref than current config.
  • To prune — present in the manifest's entry for this CLI, NOT selected by detection.

Any directory present on disk under <repo>/.<cli>/ but not listed in the manifest is user-authored or left over from another tool; never touch it.

Step 4 — Apply (or dry-run)

In --dry-run mode, print the three sets for each CLI and stop.

Otherwise, fetch a shallow clone of the source repo to a cache:

CACHE=~/.cache/claude-skill-sync/<source-repo-slug>@<ref>
if [ ! -d "$CACHE" ]; then
    gh repo clone <source-repo> "$CACHE" -- --depth 1 --branch <ref> --quiet
fi

Then, for each selected CLI, for each skill/agent in add ∪ update:

# Determine per-CLI target root
case "$cli" in
    claude)   root="<repo>/.claude" ;;
    opencode) root="<repo>/.opencode" ;;
    kilo)     root="<repo>/.kilo" ;;
    codex)    root="<repo>/.codex" ;;
    gemini)   root="<repo>/.gemini" ;;
    agy)      root="<repo>/.gemini/antigravity-cli" ;;   # Antigravity nests under .gemini/
    cursor)   root="<repo>/.cursor" ;;
    pi)       root="<repo>/.pi"  ;;     # Pi has no subagents — skills only (handled below)
    crush)    root="<repo>/.crush" ;;   # Crush has no subagents — skills only (handled below)
esac

# Pi and Crush both have no subagents. Install repo-scope skills into a shared
# per-repo location each harness auto-discovers, then continue to the next CLI
# without rendering any agents.
if [ "$cli" = "pi" ]; then
    pi_skills_dir="<repo>/.agents/skills"
    mkdir -p "$pi_skills_dir"
    rsync -a --delete "$CACHE/skills/repo-scope/<name>/" "$pi_skills_dir/<name>/"
    continue
fi
if [ "$cli" = "crush" ]; then
    crush_skills_dir="<repo>/.crush/skills"
    mkdir -p "$crush_skills_dir"
    rsync -a --delete "$CACHE/skills/repo-scope/<name>/" "$crush_skills_dir/<name>/"
    continue
fi

mkdir -p "$root/agents"

# Skills: Claude only (for now)
if [ "$cli" = "claude" ]; then
    mkdir -p "$root/skills"
    rsync -a --delete "$CACHE/skills/repo-scope/<name>/" "$root/skills/<name>/"
fi

# Agents: render through the per-CLI script
renderer="$CACHE/agents/renderers/$cli.sh"
base="$CACHE/agents/base/repo-scope/<name>"
ext=$(case "$cli" in codex) echo toml ;; *) echo md ;; esac)

if [ -d "$base/references" ] || [ -d "$base/evals" ] || [ -f "$base/config.yaml" ]; then
    # Directory form: render inside the bundled directory
    mkdir -p "$root/agents/<name>"
    "$renderer" "$base" > "$root/agents/<name>/<name>.$ext"
    [ -d "$base/references" ] && cp -R "$base/references" "$root/agents/<name>/"
    [ -d "$base/evals" ]      && cp -R "$base/evals"      "$root/agents/<name>/"
    [ -f "$base/config.yaml" ] && cp "$base/config.yaml" "$root/agents/<name>/"
else
    # Flat form
    "$renderer" "$base" > "$root/agents/<name>.$ext"
fi

Codex additionally gets an AGENTS.md inventory covering every agent that was installed for it:

if [ "$cli" = "codex" ]; then
    "$CACHE/agents/renderers/codex-agents-md.sh" <every-installed-base-path> > "$root/AGENTS.md"
fi

For each entry in prune (per CLI):

# Skill (Claude only)
rm -rf "$root/skills/<name>"

# Agent (flat)
rm -f "$root/agents/<name>.$ext"

# Agent (directory)
rm -rf "$root/agents/<name>"

Only prune paths that are in the manifest entry for this CLI.

Step 5 — Write the manifest

<repo>/.claude/.sync-manifest.json (kept at .claude/ for historical reasons; covers all CLIs):

{
  "version": 2,
  "source": {
    "repo": "your-org/ClaudeSkills",
    "ref": "v1.4.0",
    "resolved_sha": "abc123def456..."
  },
  "generated_at": "2026-04-24T14:00:00Z",
  "commit_policy": "committed",
  "clis": ["claude", "opencode"],
  "installed": {
    "claude": {
      "skills": {
        "cargo-preflight": {"reason": "Cargo.toml detected"},
        "rust-testing":    {"reason": "Cargo.toml detected"}
      },
      "agents": {}
    },
    "opencode": {
      "agents": {}
    }
  }
}

Step 6 — Commit policy for per-CLI directories

Teams split on whether synced skills/agents should be committed (a team lead runs skill-sync once and the result rides with the repo) or gitignored (each developer runs skill-sync locally). Ask once per repo, record the answer in the manifest, and update .gitignore to match.

Skip the prompt when already decided:

  • Manifest has commit_policy: "committed" | "ignored" → honor it.
  • .gitignore already contains a line matching any of the per-CLI directories → treat as "ignored", record in manifest.
  • --dry-run → skip this step entirely.

Otherwise, ask via AskUserQuestion with two options:

  • Committed — Team lead runs skill-sync once, commits .claude/, .opencode/, .kilo/, .codex/, .gemini/ (which also covers .gemini/antigravity-cli/ for agy) (as applicable) + manifest.
  • Ignored — Each developer runs skill-sync themselves; those directories + the manifest stay gitignored.

Apply `committed`:

  • Remove any matching ignore lines (and any preceding # Added by skill-sync comment), one at a time, without reordering.
  • Record commit_policy: "committed" in the manifest.
  • Remind the user to git add the per-CLI directories and the manifest.

Apply `ignored`:

  • Append this block to .gitignore only if none of its paths already appear as standalone lines:
  # Added by skill-sync — per-developer AI CLI skills/agents
  .claude/skills/
  .claude/agents/
  .claude/.sync-manifest.json
  .opencode/
  .kilo/
  .codex/
  .gemini/                  # also covers .gemini/antigravity-cli/ for agy
  • Record commit_policy: "ignored" in the manifest.

Invariants: Never edit unrelated sections of .gitignore. Never touch .claude/settings.json or similar tool-managed files.

Modes

InvocationBehaviour
skill-syncFull apply: detect, compute diff per CLI, render, install, prune, write manifest.
skill-sync --for <cli>[,<cli>...]Override the CLI set for this run only. Does not change the installer manifest.
skill-sync --dry-runDetect and print the diff for each CLI; do not touch the filesystem.
skill-sync --statusRead the manifest, compare to current detection; print any drift. Exit non-zero if drift.
skill-sync --pruneOnly prune. Do not add or update.
skill-sync --force-updateTreat all manifest entries as "to update" regardless of ref.

Safety rules

1. Never delete a skill or agent that isn't in the manifest. Those are user-authored or from another tool. 2. Never write auth tokens to the manifestgh and ssh handle auth; skill-sync only records source repo/ref/SHA. 3. Refuse to run without valid auth. Don't prompt for token creation; tell them what's missing and stop. 4. Abort on allowlist violations. If detection selects a skill/agent not in the allowlist (and allowlist is non-empty), warn, skip, continue. 5. Never install a stub skill without its paired agent (or vice versa). 6. Respect the CLI scope. Never write into a CLI directory the user didn't select. 7. Every change is reversible via `--prune` and via manifest inspection. Back up the manifest before running with --force-update. 8. Ask for the commit policy at most once.

Example — polyglot repo with two CLIs

~/.agent-skills/installer-manifest.json shows the user installed for Claude + OpenCode. Detection finds Cargo.toml + package.json (no TS) + Dockerfile. Selected install set:

skills (Claude only — repo-scope):
  preflight, cargo-preflight, rust-testing, node-preflight, node-testing,
  deploy-app, container-app-deploy

agents (both CLIs — rendered per CLI):
  (none currently — no repo-scope agents in the base tree today)

Layout after apply:

<repo>/
├── .claude/
│   ├── skills/{preflight, cargo-preflight, rust-testing, ...}/SKILL.md
│   └── .sync-manifest.json
└── .opencode/
    └── agents/          # empty today; will populate when repo-scope agents land

Global-scope artifacts (deep-review, branch-review, bdd-audit, coverage-audit + coverage-investigator, repo-health, merge-sprint, skill-sync, skill-interview, ato-*, auth-*) are not in this list — they live in each CLI's global directory already, installed by install.sh.

Related skills

FAQ

Which CLIs does skill-sync target?

Claude Code, OpenCode, Kilo Code, Codex, Gemini CLI, Antigravity (agy), Pi, and Crush; it targets the set listed in the installer manifest unless overridden with --for.

What modes does skill-sync support?

apply, --dry-run, --status, and --prune, plus --for <cli> to override the CLI set.

Skill Developmentagentsautomation

This week in AI coding

Five minutes, every Monday - the tools, releases and tactics for developers.

unsubscribe anytime.