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
Resolve the target Git repository from the requested path or current directory. Read its instructions and inspect its status before changing it.
Inspect the installed and upstream inventories:
<runner> skills@latest list --json <runner> skills@latest add toy-crane/skills --listRead 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.Update every locked skill in place, from every source, in one project-scoped call:
<runner> skills@latest update -p -yThe CLI refreshes each lock entry that records a
skillPath, one clone per source, and reinstalls it for the current client plus the universal.agentscopy; existing.claude/skillslinks 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 beforeskillPathtracking (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
expogroup only when apackage.jsondepends onexpoorreact-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/skillsand inskills-lock.jsonwith sourcetoy-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> \ --checkWhen
.agent-sync/manifest.jsonexists, run the repository's agent sync check after the companion check. Confirm it lists every current managed Toycrane skill inshared_skillsand every companion inshared_agents.Inspect the complete Git diff. Report, per skill, whether it changed and how much (
git diff --statis 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
--globalor-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.jsonwhen 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.