← Back to Skills

migrate-to-plugins

active

Moves someone from the old symlinked skill install (skills linked into ~/.claude/skills or a project's .claude/skills) to plugins from the skill marketplaces, checking before and after that no place loses a skill. Use when a colleague says 'migrate my skills to plugins', 'passa ai plugin', 'switch to the new skills install', 'I still have the old symlinks', or after velais-skills moved to plugins. Do not use to install one plugin (plain `claude plugin install`) or to write a new skill (skill-creator).

Owner: velais Category: workflow-automation Version: 1.0.0 Tokens: ~10k
pluginsmigrationskillssetup
81

Quality Score Breakdown

Structure (15%) 18/18
Show checks (11)
  • ✓ SKILL.md exists with exact casing 3/3
  • ✓ Valid YAML frontmatter 3/3
  • ✓ No unexpected frontmatter keys 1/1
  • ✓ Name field valid (kebab-case) 2/2
  • ✓ Name matches folder name 1/1
  • ✓ Description field present 2/2
  • ✓ No angle brackets in frontmatter 1/1
  • ✓ Folder name is kebab-case 1/1
  • ✓ No README.md inside skill folder 1/1
  • ✓ Test directory with test-cases.yml exists 2/2
  • ✓ Status 'active' is valid 1/1
Description (20%) 15/22
Show checks (7)
  • ✗ No action verbs found — description should say what the skill DOES 0/4
  • ✓ Contains trigger indicators: use when, says 5/5
  • ✓ Description is specific and actionable 4/4
  • ✗ Skill handles files but description doesn't mention file types 0/3
  • ✓ Description length: 506/1024 chars 2/2
  • ✓ Has negative triggers (scope boundaries) 2/2
  • ✓ Owner/author specified in metadata 2/2
Instructions (25%) 23/28
Show checks (8)
  • ✓ Skill body has content 3/3
  • ✓ Has step/section structure 4/4
  • ✗ Add examples — code blocks, user scenarios, or expected outputs 0/5
  • ✓ Includes error handling 4/4
  • ✓ Uses progressive disclosure (references/scripts) 4/4
  • ✓ Actionable language: 3/10 verb patterns found 3/3
  • ✓ Word count: 723/5000 2/2
  • ✓ All referenced paths exist 3/3
Test Coverage (25%) 19/29
Show checks (10)
  • ✓ test-cases.yml exists and parses 3/3
  • ✓ 4 should-trigger tests ✓ 4/4
  • ✓ 3 should-not-trigger tests ✓ 3/3
  • ✓ 4 functional tests ✓ 5/5
  • ✗ 0 negative tests (need ≥1) 0/3
  • ✗ 0 edge case tests (need ≥1) 0/3
  • ✗ Add performance_baseline section comparing with/without skill 0/2
  • ✗ Some functional tests have fewer than 2 expected_behavior items 0/2
  • ✓ All trigger phrases are diverse 2/2
  • ✓ All assertions are specific 2/2
Security (15%) 15/15
Show checks (5)
  • ✓ No secrets detected 5/5
  • ✓ No injection vectors in frontmatter 3/3
  • ✓ Name is not reserved 3/3
  • ✓ No suspicious code patterns 2/2
  • ✓ External URLs: 0 2/2

Test Coverage

4
Should Trigger
3
Should Not Trigger
4
Functional
0
Negative
0
Edge Cases
No
LLM Evals

Migrate to plugins

Skills used to be installed by linking folders from a clone of velais-skills (or another skill repo) into ~/.claude/skills, and sometimes into a project’s .claude/skills. Now each skill repo is a plugin marketplace: a skill comes from a plugin, installed for everyone (--scope user) or for one project, only for you (--scope local). This skill moves a person over without losing anything.

The work is done by one script, scripts/migrate.py in this skill’s folder (standard library only; the python3 that comes with macOS is enough). Never edit links by hand.

What it changes, and what it never touches

  • A link in ~/.claude/skills to a skill in a marketplace → that skill’s plugin, user scope.
  • A link in a project’s .claude/skills → that plugin, local scope in that project (only this person; nothing committed). If the same plugin goes in for everyone, no project install is needed.
  • A dead link named like a skill some plugin has (for example a project link that pointed at an old global link) → that plugin, the same way. When two marketplaces have a skill by that name and the link doesn’t say which, it’s left in place with a note: ask which one.
  • A plugin already installed but switched off is switched on, since its skills weren’t reaching anyone.
  • Other dead links are removed. Links to folders outside any skill repo are left alone.
  • Real skill folders (a project’s own skills, personal ones) are never touched. The skill repos are never touched.
  • Removed links go to ~/.claude/skills-migration-backup-<time>/ with a manifest, so rollback puts everything back.

A plugin brings its whole package: someone who linked one BC skill gets all of bc. Say so when it happens.

Steps

Tell the person what each step does before running it, in plain words.

  1. Access. The repos are private. Check that git can reach them: gh auth status, then gh auth setup-git if needed. A failed marketplace add usually means this.
  2. Before. Record what every place can use now: python3 <skill folder>/scripts/migrate.py snapshot --out ~/skills-before.json It scans the home folder for projects with a .claude folder (--roots narrows it).
  3. Plan. python3 <skill folder>/scripts/migrate.py plan. Show the person the list: per place, which skill becomes which plugin, everywhere or only in that project. Read the notes aloud, especially links committed in a project’s git. Ask before going on.
  4. Apply. python3 <skill folder>/scripts/migrate.py apply. It adds the marketplaces from GitHub, installs the plugins and moves the old links to the backup folder it prints. Keep that path.
  5. After. python3 <skill folder>/scripts/migrate.py verify --before ~/skills-before.json. It must say OK: all N places still have every skill they had. If it lists places that lost skills, stop, show the list, and either install the missing plugin (cd <project> && claude plugin install <plugin>@<marketplace> --scope local) or run rollback --backup <folder>.
  6. Updates. In Claude Code, /plugin → Marketplaces → each marketplace → Enable auto-update. Without it, new versions only come with /plugin marketplace update <name>.
  7. Restart any open Claude Code session: skills load at start.

After the migration

  • See what’s installed: claude plugin list (scope user = everywhere, local/project = that project).
  • A plugin for one more project: run inside its folder claude plugin install <plugin>@<marketplace> --scope local.
  • For the whole team in a project: --scope project writes .claude/settings.json; commit it.
  • Authors who edit a skill repo can point its marketplace at their clone (claude plugin marketplace remove <name>, then claude plugin marketplace add <path to clone>) and use /reload-plugins after an edit.

When it goes wrong

  • claude plugin ... failed: show the line it printed. Unknown marketplace → step 1. Already installed → harmless; run plan again.
  • verify lists a project that no longer exists: it’s skipped automatically. Anything else listed is a real loss: check it in that project with claude plugin list.
  • apply stopped with an error: it prints the backup folder with what it did so far; rollback --backup <folder> undoes exactly that. If the message got lost, the folders are ~/.claude/skills-migration-backup-*.
  • To undo everything: python3 <skill folder>/scripts/migrate.py rollback --backup <backup folder>.

Tests: python3 -m unittest discover -s <skill folder>/tests runs the whole flow on a fake home with a fake claude.