mcpField
U
update-project-skills

update-project-skills

github.com/toy-craneAgent workflows337 installsUpdated 1w ago
Repository

About update-project-skills

A project skill for updating installed skills, reconciling Toycrane skills, and syncing their companion agents in a repository. It is intended for maintainers managing project-local skill installations across Claude Code and Codex.

Key features

  1. 01Update locked skills in place
  2. 02Reconcile the published Toycrane skill set
  3. 03Sync companion agents for Claude Code and Codex
  4. 04Check ownership and collisions
  5. 05Verify project files and changes

Use cases

  1. 01Refresh third-party and Toycrane skills
  2. 02Install newly published eligible skills
  3. 03Retire removed Toycrane skills
  4. 04Keep managed companion agents synchronized

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/toy-crane/skills --skill update-project-skills

After installing, type/update-project-skillsin Claude Code to confirm it loaded.

Bundled files

References and scripts installed along with SKILL.md.

agents/
openai.yaml
evals/
evals.json
scripts/
sync_companion_agents.py
tests/
test_sync_companion_agents.py

Details

From the project README

Update Project Skills

Bring every skill installed in the target project to its latest published version through the current skills.sh CLI, then reconcile the Toycrane set from https://github.com/toy-crane/skills and materialize the custom agents carried by its installed skills for both Claude Code and Codex.

Treat .agents/skills as the canonical project skill copy. The CLI exposes the same skill files to Claude Code through relative links under .claude/skills. skills-lock.json records every skill the CLI installed and its source. Treat entries whose source is toy-crane/skills as Toycrane-managed and every other entry as third-party. Skills and agents without a lock entry are project-local; preserve them unless the user explicitly approves adopting a name.

Run the CLI

Every command below runs the current published CLI as <runner> skills@latest. Take <runner> from the target project's package manager: bunx for bun, pnpm dlx for pnpm, npx -y otherwise. npm aborts npx with EBADDEVENGINES before the CLI starts when package.json pins another package manager through devEngines.

Update every installed skill

  1. Resolve the target Git repository from the requested path or current directory. Read its instructions and inspect its status before changing it.

  2. Inspect the installed and upstream inventories:

    <runner> skills@latest list --json
    <runner> skills@latest add toy-crane/skills --list
    

    Read the project's skills-lock.json. The upstream list is the current published Toycrane set; ignore the source repository's own development-only dependencies under .agents/skills.

  3. Update every locked skill in place, from every source, in one project-scoped call:

    <runner> skills@latest update -p -y
    

    The CLI refreshes each lock entry that records a skillPath, one clone per source, and reinstalls it for the current client plus the universal .agents copy; existing .claude/skills links keep resolving because they are relative. Carry three parts of its output into the final report: the per-skill results, the entries it cannot update in place because they were installed before skillPath tracking (with the reinstall hint it prints), and the skills it reports as deleted upstream. Leave those last two groups as reported; whether to reinstall or remove them is the user's call.

Reconcile the Toycrane set

Classify the published Toycrane list against the lock:

  • Install each newly published universal skill whose name is absent locally.
  • Install a newly published skill from the expo group only when a package.json depends on expo or react-native. Stack detection gates new installation only; an already managed stack-specific skill keeps being updated even if the stack is no longer detected.
  • Treat a published Toycrane name that exists locally without a matching lock entry as a collision. Show the path and ask before adopting it.
  • Retire each locked Toycrane skill that is no longer published.

Install the new skills in one explicit call so stack exclusions and unapproved collisions stay excluded, then remove retired names from the whole project:

<runner> skills@latest add toy-crane/skills \
  --skill <new-skill-name> [<new-skill-name> ...] \
  --agent codex claude-code \
  -y
<runner> skills@latest remove <retired-skill-name> [<retired-skill-name> ...] -y

Keep retirement unscoped. An agent-scoped removal can leave the canonical .agents copy and lock entry behind.

Reconcile companion agents

Run the synchronizer from the freshly updated project copy of this skill:

python3 .agents/skills/update-project-skills/scripts/sync_companion_agents.py \
  --project <project-root> \
  [--retired-skill <retired-skill-name> ...]

Append one --retired-skill for every Toycrane-managed skill removed in the preceding reconciliation. This lets a project-level agent manifest retire those skill declarations after skills-lock.json no longer contains them.

The script scans only installed skills proven Toycrane-managed by skills-lock.json. A skill declares companions in companion-agents/manifest.json; the script copies its native definitions to .claude/agents/<name>.md and .codex/agents/<name>.toml, records ownership in .agents/toycrane-agents-lock.json, and reconciles both shared_skills and shared_agents when the project already has .agent-sync/manifest.json.

The ownership lock authorizes later refresh and retirement of those exact agent names. Other agent files and manifest entries remain project-owned. If the script reports an unowned collision, show every colliding path and ask for approval for that name. After approval, adopt only the approved names:

python3 .agents/skills/update-project-skills/scripts/sync_companion_agents.py \
  --project <project-root> \
  --adopt <approved-agent-name>

Repeat --adopt for multiple separately approved names. Never infer approval from identical contents or an existing manifest declaration. Collision checks use the name declared inside every native agent definition, not only its filename. Adoption removes alternate-path native definitions of the approved identity before writing its canonical Claude Code and Codex pair.

Verify the result

  • Rerun <runner> skills@latest list --json.

  • Confirm each current Toycrane skill exists in .agents/skills and in skills-lock.json with source toy-crane/skills, and that .claude/skills/<name> is a relative link to ../../.agents/skills/<name>.

  • Confirm retired Toycrane skills are absent from the lock and both skill paths, third-party lock entries still name their original sources, and project-local skills remain unchanged.

  • Run the companion check:

    python3 .agents/skills/update-project-skills/scripts/sync_companion_agents.py \
      --project <project-root> \
      --check
    
  • When .agent-sync/manifest.json exists, run the repository's agent sync check after the companion check. Confirm it lists every current managed Toycrane skill in shared_skills and every companion in shared_agents.

  • Inspect the complete Git diff. Report, per skill, whether it changed and how much (git diff --stat is enough), followed by the entries the update skipped and the upstream deletions it warned about. Then follow the repository's commit policy.

  • If the current Claude Code or Codex session does not expose a newly installed custom agent, finish the update and report that a new session is needed before testing agent routing.

Boundaries

  • Keep every change project-local; never use --global or -g.
  • Third-party skills change only through the in-place update. Installing a new third-party skill or removing one that disappeared upstream waits for the user's request naming it.
  • Commit skills-lock.json, .agents/toycrane-agents-lock.json when present, updated skills, and managed agent files together so ownership stays durable.
  • Do not remove or overwrite an artifact whose lock does not prove Toycrane ownership without explicit approval for that name.
  • Do not push unless the user asks.

Comments

Markdown supported