Módulo 5: Plugins — Crear y Distribuir

4. Dynamic Loading y Versioning — Carga, Semver, y Registries

4. Dynamic Loading y Versioning — Carga, Semver, y Registries

Descripción

Tu plugin funciona localmente. Lo instalaste con claude plugins add ./path, verificaste que los agentes cargan, y testeaste que las skills se precargan. Pero queda la pregunta que hace este esfuerzo valioso a largo plazo: ¿cómo lo distribuyes a tu equipo? ¿Cómo manejas versiones cuando actualizas un agent file? ¿Qué pasa si un compañero instala la versión 2.0 pero su proyecto necesita la 1.x?

En esta cápsula aprendes lo que convierte un plugin local en un paquete profesional: cómo Claude Code descubre y carga plugins al inicio de sesión, cómo funciona el versionado semver aplicado a plugins, cómo publicar en un npm registry (local con verdaccio o remoto con npm/GitHub Packages), y cómo manejar actualizaciones sin romper flujos existentes.

Al terminar, entenderás el ciclo completo: crear → versionar → publicar → instalar → actualizar → pinear versión. Tu plugin deja de ser "un directorio en tu máquina" y se convierte en "un paquete que cualquier desarrollador puede instalar con un comando."


⚠️ FEATURE EXPERIMENTAL

El sistema de dynamic loading de plugins y la integración con npm registries reflejan la funcionalidad disponible a marzo 2026. Los mecanismos de carga y los comandos de gestión pueden cambiar. Los principios de versionado semver y distribución via registries son estándares de la industria y se mantienen.

Última verificación: Marzo 2026


Dynamic Loading: Cómo Claude Code Carga Plugins

El proceso de carga al inicio de sesión

Cuando inicias una sesión de Claude Code, esto ocurre internamente:

claude (inicio de sesión)
    │
    ├── 1. Lee configuración de plugins
    │      ├── Plugins globales (usuario)
    │      └── Plugins de proyecto (.claude/plugins)
    │
    ├── 2. Para cada plugin instalado:
    │      ├── Localiza el paquete (node_modules o path local)
    │      ├── Lee package.json
    │      ├── Verifica claudeCodePlugin: true
    │      └── Si falta o es false → ignora el paquete
    │
    ├── 3. Carga componentes:
    │      ├── agents/*.md → registra como subagents disponibles
    │      ├── skills/*.md → registra como skills precargables
    │      ├── hooks → registra en el sistema de eventos
    │      └── MCP servers → inicia procesos
    │
    └── 4. Sesión lista con plugins activos

Scopes de plugins

Los plugins pueden instalarse en dos scopes:

GLOBAL (usuario)                     PROYECTO
─────────────────                    ────────

Disponible en todos los proyectos    Solo en este proyecto
Instalado una vez                    Instalado por proyecto
Ideal para herramientas personales   Ideal para plugins de equipo

claude plugins add --global @pkg     claude plugins add @pkg
~/.config/claude-code/plugins/       .claude/plugins/

Regla práctica:

  • Plugins personales (tu reviewer favorito) → global
  • Plugins de equipo (convenciones del proyecto) → proyecto
  • Si el mismo plugin está en global Y proyecto → proyecto gana

Resolución de conflictos de nombres

¿Qué pasa si dos plugins tienen un agente llamado reviewer?

@team/quality-plugin       →  agents/reviewer.md
@team/security-plugin      →  agents/reviewer.md

Claude Code resuelve con prefijos del plugin:

Agentes disponibles:
  quality-plugin/reviewer     ← del plugin de quality
  security-plugin/reviewer    ← del plugin de security

Para evitar confusión, usa nombres únicos en tus agent files: quality-reviewer en lugar de reviewer.


Versionado Semver para Plugins

Por qué versionar importa

Sin versionado:

Lunes:    Publicas plugin con reviewer v1
Martes:   Cambias el formato del reporte del reviewer
Miércoles: Tu colega instala → su CI pipeline se rompe porque
           espera el formato viejo

Con versionado:

Lunes:    Publicas @team/quality@1.0.0
Martes:   Publicas @team/quality@1.1.0 (nuevo formato de reporte)
Miércoles: Tu colega tiene @team/quality@1.0.0 pineado → nada se rompe
           Cuando esté listo, actualiza a 1.1.0

Semver aplicado a plugins

MAJOR.MINOR.PATCH
  │     │     │
  │     │     └── Bug fix en un agent file
  │     │         (corregir typo en system prompt, ajustar maxTurns)
  │     │
  │     └── Nueva funcionalidad compatible
  │         (nuevo agent file, nueva skill, nuevo hook)
  │
  └── Breaking change
      (agent renombrado, skill eliminada, formato de output cambiado)

Ejemplos concretos de cada tipo de cambio

Patch (1.0.0 → 1.0.1):

 agents/reviewer.md:
 ---
 name: reviewer
-maxTurns: 15
+maxTurns: 20
 ---

Corrección menor. Nadie que use el plugin notará un problema.

Minor (1.0.0 → 1.1.0):

ADDED: agents/test-writer.md
ADDED: skills/python-standards.md

Funcionalidad nueva. Los agent files existentes no cambiaron. Compatible hacia atrás.

Major (1.0.0 → 2.0.0):

 agents/reviewer.md:
 ---
-name: reviewer
+name: quality-reviewer
 ---

-## Output Format
-### Review Report
-**Issues:** [list]
+## Output Format
+### Quality Analysis
+**Findings:** [structured object]

Breaking change: el nombre del agente cambió (scripts que lo invocan por nombre se rompen) y el formato de output cambió (parsers que esperan el formato viejo fallan).


Versión Pinning

Qué es versión pinning

Versión pinning es fijar la versión exacta (o rango) de un plugin que tu proyecto usa. Sin pinning, cada npm update podría traer una versión nueva con cambios inesperados.

Estrategias de pinning

{
  "dependencies": {
    "@team/quality": "1.2.3",     // Exacta: solo 1.2.3
    "@team/quality": "^1.2.3",    // Compatible: >=1.2.3 <2.0.0
    "@team/quality": "~1.2.3",    // Patch only: >=1.2.3 <1.3.0
    "@team/quality": "*"          // Cualquiera (peligroso)
  }
}

Cuándo usar cada estrategia

PRODUCCIÓN / CI:
├── Versión exacta: "1.2.3"
├── Razón: reproducibilidad garantizada
└── Update: manual, controlado, con review

DESARROLLO:
├── Compatible: "^1.2.3"
├── Razón: recibir patches y nuevas features
└── Update: automático en minor/patch

EXPERIMENTACIÓN:
├── Latest: "*" o sin pinning
├── Razón: siempre la versión más reciente
└── Riesgo: breaking changes sin aviso

Recomendación: Para equipos, usa ^ (compatible) en desarrollo y versión exacta en CI/CD.


Publicar en un Registry

Opción 1: npm Registry (Público)

Para plugins open-source o empresas con npm org:

cd ~/plugins-workshop/my-quality-plugin

# Login en npm (primera vez)
npm login

# Publicar
npm publish --access public

Si usas scoped package (@org/name), necesitas --access public para que sea público, o pertenecer a la org para publicar como privado.

Opción 2: Verdaccio (Registry Local)

Para equipos que no quieren publicar en npm público. Verdaccio es un registry npm que corre en tu red local o servidor interno.

Instalar verdaccio:

npm install -g verdaccio
verdaccio

Esto levanta un registry local en http://localhost:4873.

Configurar npm para usar verdaccio:

npm set registry http://localhost:4873

Publicar al registry local:

cd ~/plugins-workshop/my-quality-plugin
npm publish --registry http://localhost:4873

Instalar desde verdaccio:

claude plugins add @your-org/code-quality-plugin --registry http://localhost:4873

O si Claude Code usa npm internamente:

npm install @your-org/code-quality-plugin --registry http://localhost:4873

Opción 3: GitHub Packages

Para equipos que usan GitHub:

Configurar package.json:

{
  "name": "@your-github-org/code-quality-plugin",
  "version": "1.0.0",
  "publishConfig": {
    "registry": "https://npm.pkg.github.com"
  }
}

Autenticar:

echo "//npm.pkg.github.com/:_authToken=YOUR_GITHUB_TOKEN" >> ~/.npmrc

Publicar:

npm publish

Comparación de registries

Aspectonpm públicoVerdaccio (local)GitHub Packages
CostoGratis (público)Gratis (self-hosted)Gratis (con GitHub)
AccesoCualquieraRed local/VPNMiembros del org
SetupCuenta npmInstalar + correrToken de GitHub
CI/CDFácilRequiere red internaIntegrado con GH Actions
Ideal paraOpen sourceEquipos internosEquipos en GitHub

Flujo Completo: Crear → Publicar → Instalar → Actualizar

El ciclo de vida profesional

1. DESARROLLO
   ├── Crear plugin (cápsula 03)
   ├── Testear localmente
   └── Iterar hasta estable

2. PUBLICACIÓN INICIAL
   ├── Establecer versión 1.0.0
   ├── npm publish (o verdaccio/GitHub)
   └── Notificar al equipo

3. INSTALACIÓN
   ├── claude plugins add @team/quality@^1.0.0
   └── Verificar con claude plugins list

4. ACTUALIZACIÓN (patch/minor)
   ├── Editar agent files
   ├── Bump versión: npm version patch (o minor)
   ├── npm publish
   └── Usuarios con ^1.0.0 reciben update automáticamente

5. BREAKING CHANGE (major)
   ├── Editar con cambios incompatibles
   ├── Documentar qué cambió y por qué
   ├── Bump versión: npm version major
   ├── npm publish
   └── Usuarios deben actualizar manualmente a ^2.0.0

Comandos de versión bump

# Patch: 1.0.0 → 1.0.1
npm version patch

# Minor: 1.0.0 → 1.1.0
npm version minor

# Major: 1.0.0 → 2.0.0
npm version major

Estos comandos actualizan version en package.json y crean un git commit + tag automáticamente.


Manejar Actualizaciones y Migraciones

Update sin breaking changes

# El usuario ejecuta:
npm update @team/code-quality-plugin

# O si Claude Code gestiona plugins:
claude plugins update @team/code-quality-plugin

Con ^1.0.0, esto actualiza a la última 1.x.x disponible.

Migración con breaking changes

Cuando publicas una versión major, proporciona una guía de migración:

# Migración de v1 a v2

## Cambios breaking

### Agent "reviewer" renombrado a "quality-reviewer"
- **Antes:** `reviewer`
- **Después:** `quality-reviewer`
- **Acción:** Actualizar cualquier referencia a `reviewer` en tus prompts

### Formato de output cambiado
- **Antes:** Secciones "Critical", "Warning", "Info"
- **Después:** Secciones "Findings" con campo severity
- **Acción:** Si parseas el output del reviewer, actualizar el parser

## Cómo actualizar

```bash
claude plugins remove @team/code-quality-plugin
claude plugins add @team/code-quality-plugin@^2.0.0

Mantener v1

Si necesitas más tiempo:

claude plugins add @team/code-quality-plugin@~1.5.0

### Estrategia de deprecation

v1.5.0 → Agrega warnings: "reviewer will be renamed to quality-reviewer in v2" v2.0.0 → Aplica el cambio v2.1.0 → Agrega alias temporal: reviewer → quality-reviewer con warning v3.0.0 → Elimina alias, solo quality-reviewer


Gradual. Nadie se rompe de golpe.

---

## Comparación: Versión Pinning vs Latest

### Side-by-side

VERSION PINNING ("^1.2.3") LATEST ("*" o sin pin) ────────────────────────── ──────────────────────

Predecible Impredecible Actualizaciones controladas Updates automáticos CI reproducible CI puede fallar por update sorpresa Requiere maintenance manual Zero maintenance Seguro para producción Riesgoso para producción Puede perder security patches Siempre tiene security patches


### Escenarios reales

**Escenario: CI pipeline que corre daily**

Con pinning: @team/quality@1.2.3 → misma versión cada día → resultados consistentes

Sin pinning: Lunes: v1.2.3 → pipeline OK Martes: v1.3.0 sale → nuevo agent con nuevo output → parser falla → pipeline roto


**Escenario: Desarrollador individual explorando**

Con pinning: Instalas v1.2.3 → funciona → 3 meses después, pierdes v1.5.0 con mejoras

Sin pinning: Siempre la última → pierdes estabilidad pero ganas mejoras inmediatas


**Recomendación:**
- Proyectos de equipo: `^major.minor.patch` (compatible range)
- CI/CD: versión exacta `major.minor.patch`
- Desarrollo personal: `*` o `^` amplio

---

## Alternativa Manual: Git Tags como Versionado

Si no tienes acceso a un npm registry:

```bash
# En el repo del plugin
git tag v1.0.0
git push origin v1.0.0

# Para instalar una versión específica
git clone --branch v1.0.0 https://github.com/team/quality-plugin.git
claude plugins add ./quality-plugin

O con git submodules:

# En el proyecto que consume el plugin
git submodule add -b v1.0.0 https://github.com/team/quality-plugin.git .plugins/quality
claude plugins add .plugins/quality

Pierdes la conveniencia de npm update, pero ganas versionado formal con git tags.


Ejercicios

Ejercicio 1: Determinar el tipo de versión bump (Fácil)

Para cada cambio, indica si es patch, minor, o major y explica por qué:

  1. Corriges un typo en el system prompt del reviewer
  2. Agregas un nuevo agent file security-scanner.md
  3. Renombras implementer.md a code-implementer.md (cambia el name field)
  4. Aumentas maxTurns del implementer de 25 a 30
  5. Cambias el formato de output del reviewer de lista plana a JSON estructurado
  6. Agregas una nueva skill python-patterns.md
Ver solución
  1. Patch (1.0.0 → 1.0.1) — Typo fix, no afecta funcionalidad
  2. Minor (1.0.0 → 1.1.0) — Nuevo componente, compatible hacia atrás
  3. Major (1.0.0 → 2.0.0) — Nombre del agente cambia, scripts que lo invocan se rompen
  4. Patch (1.0.0 → 1.0.1) — Ajuste interno, no afecta al consumidor
  5. Major (1.0.0 → 2.0.0) — Formato de output cambia, parsers existentes se rompen
  6. Minor (1.0.0 → 1.1.0) — Nuevo componente, nada existente cambia

Ejercicio 2: Escribir un .npmignore (Fácil)

Escribe un .npmignore para un plugin que excluya archivos de desarrollo pero incluya todos los componentes del plugin. El directorio del plugin contiene:

agents/ skills/ hooks/ tests/ docs/ .github/
package.json README.md CHANGELOG.md
.eslintrc.json .prettierrc .env.example
Ver solución
# .npmignore

# Testing
tests/

# Documentation (README.md is included by default)
docs/

# CI/CD
.github/

# Development config
.eslintrc.json
.prettierrc
.env.example

# Editor
.vscode/
.idea/
*.swp

Nota: README.md, package.json, y los archivos en files siempre se incluyen. Este .npmignore excluye solo lo que no es parte del plugin distribuible.

Ejercicio 3: Configurar verdaccio y publicar (Medio)

Instala verdaccio, publícalo localmente, e instala tu plugin desde el registry local. Documenta cada paso con el comando ejecutado y su output esperado.

Ver solución
# 1. Instalar verdaccio
npm install -g verdaccio

# 2. Arrancar verdaccio
verdaccio
# Output esperado:
# http address - http://localhost:4873/

# 3. Crear usuario en verdaccio (en otra terminal)
npm adduser --registry http://localhost:4873
# Username: tu-usuario
# Password: tu-password
# Email: tu@email.com

# 4. Publicar el plugin
cd ~/plugins-workshop/my-quality-plugin
npm publish --registry http://localhost:4873
# Output esperado:
# + @your-org/code-quality-plugin@1.0.0

# 5. Verificar publicación
npm view @your-org/code-quality-plugin --registry http://localhost:4873
# Output: información del paquete

# 6. Instalar desde verdaccio en otro proyecto
cd ~/another-project
claude plugins add @your-org/code-quality-plugin --registry http://localhost:4873
# O: npm install @your-org/code-quality-plugin --registry http://localhost:4873

# 7. Verificar instalación
claude plugins list
# Output: @your-org/code-quality-plugin@1.0.0

Ejercicio 4: Simular un breaking change y migración (Medio)

Toma tu plugin de quality en v1.0.0. Haz tres cambios breaking: renombra un agente, cambia una skill, y modifica un hook. Escribe: el nuevo package.json con v2.0.0, los archivos modificados, y una guía de migración completa.

Ver solución

Cambios breaking:

  1. agents/reviewer.md → agents/quality-reviewer.md (name: quality-reviewer)
  2. skills/api-conventions.md → skills/api-standards.md (name: api-standards)
  3. Hook matcher cambia de "Write" a "Write|Edit"

package.json v2.0.0:

{
  "name": "@your-org/code-quality-plugin",
  "version": "2.0.0",
  "description": "Code quality agents with reviewer and implementer (v2)",
  "claudeCodePlugin": true,
  "files": ["agents", "skills"],
  "keywords": ["claude-code", "plugin", "code-quality"]
}

Guía de migración (MIGRATION.md):

# Migrating from v1 to v2

## Breaking Changes

### 1. Agent renamed: reviewer → quality-reviewer
**v1:** `reviewer`
**v2:** `quality-reviewer`
**Action:** Update any prompts or scripts that reference "reviewer" by name

### 2. Skill renamed: api-conventions → api-standards
**v1:** `api-conventions`
**v2:** `api-standards`
**Action:** If your CLAUDE.md references this skill, update the name

### 3. Hook scope expanded
**v1:** Hook triggers on Write only
**v2:** Hook triggers on Write and Edit
**Action:** Review hook behavior — it now also runs on edits, not just new files

## Upgrade Steps

1. Remove v1: `claude plugins remove @your-org/code-quality-plugin`
2. Install v2: `claude plugins add @your-org/code-quality-plugin@^2.0.0`
3. Update references in your prompts/scripts
4. Test with a simple review command

## Staying on v1

If you need more time:
`claude plugins add @your-org/code-quality-plugin@~1.5.0`

Ejercicio 5: Diseñar estrategia de versionado para un equipo (Difícil)

Tu equipo tiene 5 desarrolladores, 3 proyectos, y 2 plugins internos. Diseña una estrategia de versionado que cubra:

  • Quién puede publicar nuevas versiones
  • Cómo se comunican los breaking changes
  • Qué pinning usa cada proyecto (dev vs CI)
  • Cómo se manejan hotfixes urgentes
Ver solución
# Plugin Versioning Strategy

## Who Can Publish

- **Minor/Patch:** Any team member with review from 1 peer
- **Major:** Requires review from tech lead + 1 week notice
- **Hotfix:** Any team member can publish patch directly (post-review)

## Communication

- **Patch:** CHANGELOG update + Slack notification
- **Minor:** CHANGELOG + Slack + email to plugin consumers
- **Major:** CHANGELOG + MIGRATION.md + team meeting + 2-week deprecation period

## Pinning Strategy

### Development (local)
```json
"@team/quality": "^1.0.0"

Receive patches and minors automatically.

Staging

"@team/quality": "~1.2.0"

Receive patches only. Minor updates require explicit bump.

CI/CD and Production

"@team/quality": "1.2.3"

Exact pin. Zero surprises. Update requires PR.

Hotfix Process

  1. Fix the issue on main branch
  2. npm version patch (1.2.3 → 1.2.4)
  3. npm publish
  4. Notify in Slack: "Hotfix @team/quality@1.2.4 — [issue]"
  5. CI projects: open PR to bump exact version
  6. Dev projects: automatic via ^/~ range

Release Cadence

  • Patches: as needed (bug fixes)
  • Minors: bi-weekly (new features)
  • Majors: quarterly at most (breaking changes)

</details>

---

## Troubleshooting

### Problema 1: "npm publish falla con 'You must be logged in'"

**Síntoma:** `npm ERR! need auth`

**Solución:**

```bash
# Para npm público
npm login

# Para verdaccio
npm adduser --registry http://localhost:4873

# Para GitHub Packages
echo "//npm.pkg.github.com/:_authToken=$GITHUB_TOKEN" >> ~/.npmrc

Problema 2: "Plugin instalado pero versión no coincide"

Síntoma: claude plugins list muestra una versión diferente a la esperada.

Solución:

# Verificar qué versión está instalada
claude plugins list

# Forzar versión específica
claude plugins remove @team/quality
claude plugins add @team/quality@1.2.3

Problema 3: "Verdaccio no arranca o no es accesible"

Síntoma: npm publish --registry http://localhost:4873 falla con connection refused.

Solución:

# Verificar que verdaccio está corriendo
ps aux | grep verdaccio

# Reiniciar
verdaccio --listen 4873

# Verificar acceso
curl http://localhost:4873

Problema 4: "Breaking change no detectado — el usuario no sabía que era major"

Síntoma: Publicaste un cambio breaking como minor y rompiste flujos de otros.

Solución preventiva:

Antes de cada publicación, revisa este checklist:

¿Algún agent file cambió de nombre?           → MAJOR
¿Algún agent file fue eliminado?               → MAJOR
¿El formato de output de algún agente cambió?  → MAJOR
¿Alguna skill fue renombrada o eliminada?       → MAJOR
¿Solo se agregaron archivos nuevos?             → MINOR
¿Solo se corrigieron bugs sin cambiar API?      → PATCH

Problema 5: "Dos proyectos necesitan versiones diferentes del mismo plugin"

Síntoma: Proyecto A necesita v1.x, Proyecto B necesita v2.x.

Solución:

Cada proyecto tiene su propio pinning en .claude/plugins o en su configuración:

Proyecto A: @team/quality@^1.5.0
Proyecto B: @team/quality@^2.0.0

npm resuelve las versiones por proyecto. No hay conflicto mientras cada proyecto tenga su propio node_modules o configuración de plugins.


Resumen

  • Dynamic loading ocurre al inicio de sesión — Claude Code descubre plugins, verifica claudeCodePlugin: true, y registra agents, skills, y hooks
  • Plugins se pueden scoping a global (usuario) o proyecto — proyecto tiene precedencia
  • Semver es obligatorio: patch para fixes, minor para features compatibles, major para breaking changes
  • Versión pinning protege de sorpresas: exacto para CI, ^ para desarrollo, ~ para staging
  • Tres opciones de registry: npm público (open source), verdaccio (local/privado), GitHub Packages (equipos en GitHub)
  • El flujo completo es: crear → testear local → publicar → instalar via registry → bump versión → update
  • Breaking changes requieren: major bump, guía de migración, y período de deprecation
  • npm version patch|minor|major automatiza el bump y crea git tags
  • La alternativa sin registry son git tags + submodules — funcional pero sin la conveniencia de npm

Recursos Adicionales

  1. Semantic Versioning (semver.org) — Estándar de versionado completo
  2. npm Versioning — Semver aplicado a paquetes npm
  3. npm publish — Referencia del comando de publicación
  4. Verdaccio — Registry npm local/privado
  5. GitHub Packages — npm registry de GitHub
  6. npm versión — Automatización de versión bumps
  7. Claude Code CLI Reference — Comandos de plugins
  8. npm .npmignore — Control de archivos publicados

Siguiente cápsula: En la cápsula 05 construyes el proyecto completo: un plugin de code quality con reviewer + implementer + api-conventions skill, empaquetado, testeado localmente, y publicado en un registry local. Es el cierre del módulo — todo lo aprendido en las cápsulas 02-04 integrado en un producto funcional y distribuible.