Skip to main content
Un mod es un plugin de Claude Code con un archivo de entrada, llamado el módulo de hooks: un archivo JavaScript o TypeScript cuyas funciones Claude Code llama cuando ocurren eventos. Hay dos formas de hacer uno:
  • Pida a Claude que lo escriba: describa lo que desea en una sesión de Claude Code
  • Escríbalo usted mismo: siga el tutorial para aprender cómo funciona el código de un mod. No necesita Node.js, un empaquetador o un paso de compilación, porque Claude Code carga archivos .js y .ts directamente.
Si aún no ha decidido si un mod es la herramienta adecuada, lea primero la comparación en la descripción general.
Los mods requieren Claude Code v2.1.287 o posterior. En su shell, ejecute claude --version para verificar. Para ver si los mods pueden cargarse para usted, consulte Verificar si los mods pueden cargarse.

Pida a Claude un mod

Describa el mod que desea en una sesión interactiva de Claude Code, y Claude lo escribe. Claude trabaja a partir de una skill integrada llamada plugin-authoring, que le dice dónde escribir el mod, qué eventos y métodos tiene su versión, y cómo se carga el mod. Claude puede cargar la skill cuando le pide un mod, o puede cargarla usted mismo ejecutando /plugin-authoring en el símbolo del sistema de Claude Code. El mod se ejecuta una vez que lo aprueba, excepto en sesiones donde un mod que Claude escribe no puede cargarse.
1

Describa el mod

Pida el mod con sus propias palabras, por ejemplo make a mod that shows the current git branch above the prompt. Claude escribe el mod en un directorio propio en la carpeta de mods de la sesión, que es ~/.claude/dev-mods/ seguido del ID de la sesión. La ruta completa de un mod se ve como ~/.claude/dev-mods/3f2a9c1e-5b7d-4e8a-9c21-6d0f4b8a7e13/git-branch/.
En los modos de permiso default y acceptEdits, Claude Code pregunta antes de que Claude cree cada uno de los archivos del mod, porque ~/.claude es una ruta protegida. Apruebe cada archivo cuando aparezca.
2

Apruebe el mod

Cuando Claude guarda el primer archivo, Claude Code pregunta si desea habilitar la recarga en caliente para la sesión. La recarga en caliente ejecuta los mods que Claude escribe en esta sesión y recoge cada cambio posterior.Elija una de estas respuestas:
  • Habilitar para esta sesión: los mods en la carpeta de mods de la sesión se cargan cuando termina el turno, y se recargan al final de cada turno que los cambia. Su respuesta dura para la sesión, incluso después de reanudarla.
  • Ahora no: nada se carga por ahora. Los archivos permanecen donde Claude los escribió, y los mods se cargan la próxima vez que esa sesión comienza. Para evitar que un mod se cargue nunca, elimine su directorio.
3

Verifique que el mod se cargó

Ejecute /plugin en el símbolo del sistema de Claude Code y presione Tab hasta que se seleccione la pestaña Installed. Enumera el mod, y puede desactivarlo allí.
4

Pruebe el mod

Use lo que pidió. Para el ejemplo de símbolo del sistema, el nombre de la rama actual aparece encima del cuadro de símbolo del sistema. Si el mod no hace lo que deseaba, dígale a Claude qué cambiar. El mod se recarga al final de cada turno que cambia sus archivos, por lo que puede probar el cambio tan pronto como Claude termine.

Use el mod en otras sesiones

Un mod que Claude escribió se carga solo en la sesión que lo creó, y Claude Code elimina la carpeta de mods de esa sesión una vez que es más antigua que cleanupPeriodDays. Para mantener el mod, copie su directorio fuera de la carpeta de mods a un lugar de su elección, como ~/mods/git-branch. Luego elija cómo cargarlo:
  • En una sesión que inicia: en su shell, ejecute claude --plugin-dir ~/mods/git-branch
  • Para otras personas: agréguelo a un marketplace para que puedan instalarlo

Sesiones donde un mod que Claude escribe no puede cargarse

Un mod que Claude escribe se carga solo después de que lo aprueba, en un espacio de trabajo de confianza donde se permite que los mods se ejecuten. En estas sesiones no se carga:
  • Nadie está allí para aprobar: la sesión no puede mostrarle un símbolo del sistema, como en una ejecución claude -p o modo dontAsk
  • El espacio de trabajo no es de confianza: no ha aceptado el símbolo del sistema de confianza para el directorio
  • Los mods están detenidos: comenzó con --safe-mode o --bare, estableció disableAllHooks, o la configuración administrada de su organización lo bloquea

Escriba un mod usted mismo

En este tutorial construye un mod llamado first-mod que cuenta las llamadas de herramientas que Claude hace, muestra el recuento junto al spinner mientras Claude trabaja, y agrega un comando /tally que lo imprime. Luego lee las declaraciones de tipo que Claude Code escribe junto a su mod y ejecuta claude plugin validate. Juntos muestran los eventos y métodos que su versión ofrece y qué Claude Code lee de su código. Esta grabación muestra el mod terminado. El spinner cuenta llamadas de herramientas, /tally imprime el recuento, y una edición del código toma efecto mientras la sesión se ejecuta:
Escribe tres archivos:
1

Cree el directorio del plugin

Cree los dos directorios que contienen los archivos:
2

Escriba el manifiesto

Un mod es un plugin, y un mod necesita un manifiesto. El manifiesto de este mod no tiene campos especiales. Guarde esto como first-mod/.claude-plugin/plugin.json:
first-mod/.claude-plugin/plugin.json
3

Dígale a Claude Code dónde está su código

Cuando Claude Code carga un plugin, lee el hooks/hooks.json del plugin. La clave modules en ese archivo da la ruta a su código, y tenerla es lo que hace que el plugin sea un mod. Enumere una ruta, relativa a hooks.json. Aquí apunta a register.js, que escribe en el siguiente paso.Guarde esto como first-mod/hooks/hooks.json:
first-mod/hooks/hooks.json
4

Escriba el código

Este archivo es el código del mod, llamado el módulo de hooks. Cuando el mod se carga, Claude Code llama a la función register que el archivo exporta y le pasa una función llamada on. Cada llamada a on registra un controlador de eventos, llamado un hook, para el evento que nombra.Guarde esto como first-mod/hooks/register.js:
first-mod/hooks/register.js
El archivo mantiene un recuento en calls y registra cuatro hooks:
  • session.start se ejecuta cuando la sesión comienza, antes de su primer símbolo del sistema, y nuevamente cada vez que el mod se recarga. Agrega el comando /tally a Claude Code.
  • tool.call se ejecuta cada vez que Claude está a punto de usar una herramienta. Suma uno a calls y pide a Claude Code que dibuje la interfaz nuevamente.
  • command.run se ejecuta cuando escribe /tally. Devuelve el texto a imprimir.
  • ui.render se ejecuta cada vez que Claude Code dibuja el spinner. Agrega el recuento después de la palabra del spinner.
Cómo funciona el mod de ejemplo explica los tres argumentos que cada hook toma y qué devuelve cada uno.
5

Cargue el mod

Inicie Claude Code con la bandera --plugin-dir, que carga un directorio de plugin para una sesión sin instalarlo:
6

Pruebe el mod

Pida a Claude que haga algo que requiera algunas llamadas de herramientas, como list the files here and read the README. Mientras Claude trabaja, la palabra del spinner va seguida de un recuento que sube, como en Thinking · tool calls: 2…. Cuando Claude termina, escriba /tally y presione Enter. La transcripción muestra first-mod: Claude has made 2 tool calls since this mod loaded, con su propio recuento. Claude Code pone el nombre del plugin delante del texto del comando.Para verificar el comando sin una sesión interactiva, ejecútelo en modo no interactivo:
Si /tally no está en la lista de comandos, el módulo no se cargó. Consulte Descubra por qué un mod no hace nada.
7

Cambie el código mientras la sesión se ejecuta

Deje la sesión abierta. En register.js, cambie ' · tool calls: ' a ' · tools used: ' en el hook ui.render y guarde. La línea resaltada es la que cambia:
first-mod/hooks/register.js
Una línea en la transcripción dice que first-mod se recargó y enumera sus hooks, y el siguiente spinner usa el nuevo texto, como en Thinking · tools used: 1….

Cómo funciona el mod de ejemplo

Cada función que pasa a on es un hook, que es un controlador de eventos. Claude Code pasa a cada hook los mismos tres argumentos:
  • La API de mods, llamada $: cada método que un mod puede llamar para llegar fuera de sí mismo, en espacios de nombres como $.ui y $.command
  • El evento, llamado e: la entrada del evento como datos simples, como el nombre y los argumentos de una llamada de herramienta
  • El siguiente controlador, llamado next: una función que pasa el evento a los otros mods y luego al comportamiento propio de Claude Code, y devuelve el resultado
Los hooks en first-mod manejan sus eventos de las tres formas en que un hook puede:
  • Observar: el hook session.start registra el comando, y el hook tool.call cuenta la llamada y pide un redibujado. Ambos devuelven next(e), por lo que la sesión comienza y la herramienta se ejecuta como de costumbre.
  • Responder: el hook command.run devuelve su propio resultado y nunca llama a next. El segundo argumento a on, { command: 'tally' }, es un filtro, llamado un matcher, por lo que el hook se ejecuta solo para /tally.
  • Reescribir: el hook ui.render llama a next con una copia de e cuyo suffix contiene el recuento, por lo que Claude Code dibuja su spinner habitual con su texto después de la palabra
Claude Code observa un directorio cargado con --plugin-dir y recarga en caliente el módulo de hooks cuando un archivo en él cambia. Cada recarga ejecuta register nuevamente, por lo que calls vuelve a 0 y /tally comienza a contar nuevamente. Para mantener un valor entre recargas, consulte Mantener estado.

Continúe trabajando en un mod

Una vez que un mod se carga, puede hacer que Claude lo cambie, verificar su código contra las definiciones de tipo para su versión, enumerar los eventos y llamadas que Claude Code encuentra en él, y probarlo.

Cambie un mod con Claude

Para cambiar un mod que ya tiene, inicie la sesión con --plugin-dir apuntando al directorio del mod, para que lo que Claude escribe se cargue en la misma sesión:
Luego pida el cambio, por ejemplo add a /tally-reset command to this mod that sets the tally back to zero. Claude edita el módulo de hooks, ejecuta claude plugin validate, y corrige lo que reporta. Un directorio que carga con --plugin-dir es una ruta protegida, por lo que en los modos default y acceptEdits se le pide que apruebe cada edición de Claude al mod. La tabla de rutas protegidas da el resultado para los otros modos de permiso. Los archivos que Claude guarda durante su turno se recargan cuando termina el turno, por lo que puede probar /tally-reset tan pronto como Claude termine.

Obtenga definiciones de tipo para su versión

Cada vez que Claude Code carga o recarga un mod desde un directorio que pasa a --plugin-dir, o un mod que Claude escribió para usted, escribe archivos de declaración de TypeScript, terminando en .d.ts, en .claude-plugin/types/ dentro del directorio del mod. Describen los eventos exactos, métodos de la API de mods, y elementos en la versión de Claude Code que está ejecutando, por lo que su editor puede autocompletar y verificar el tipo de sus hooks. Para examinar las declaraciones en línea, lea mods/types/claude-code.d.ts en el repositorio de Claude Code, cuya primera línea nombra la versión que la escribió. El directorio contiene estos archivos: Si su mod no tiene su propio tsconfig.json, Claude Code agrega uno en la raíz del mod que extiende el generado, por lo que su editor y tsc -p ./first-mod verifican el tipo del mod sin más configuración. Los eventos y métodos pueden cambiar entre versiones, por lo que confíe en estos archivos sobre cualquier página, incluso esta, cuando no estén de acuerdo. claude-code/index.d.ts es la referencia más completa para su compilación, con un comentario y un ejemplo para cada método de la API de mods. Para buscar algo, busque en el archivo su nombre, como 'tool.call'.

Verifique qué Claude Code lee de su mod

Para ver su mod de la forma en que Claude Code lo ve, sin ejecutar su código o iniciar una sesión, use claude plugin validate. Verifica el manifiesto y ejecuta el mismo análisis estático en la fuente del módulo de hooks que Claude Code ejecuta cuando carga un mod. En su shell, ejecútelo en el directorio del mod:
Para first-mod, la salida incluye estas líneas.
La línea hooks: enumera los eventos que su módulo engancha, cada uno con su filtro entre llaves. La línea calls: enumera cada método de la API de mods que llama. Un módulo que lee o establece variables de entorno también obtiene líneas env reads: y env writes:, y uno que usa $.state obtiene state reads: y state writes:. Si un evento que pretendía enganchar falta en la primera línea, Claude Code tampoco llamará a ese hook. La causa habitual es un nombre de evento mal escrito, que el comando reporta como un error como "tool.calls" is not an event. Siga estas reglas para que el análisis estático pueda encontrar cada hook y llamada:
  • Deletree cada llamada de la API de mods en su totalidad: $, el espacio de nombres, luego el método, como en $.store.get('notes'). Puede pasar $ a una función declarada en el nivel superior del mismo archivo, y para una función suya llamada loadNotes, la línea calls: entonces lee $.store.get (via loadNotes). Pasar $ a un método, una función definida dentro del hook, o una función que importa de otro de sus archivos falla la validación. Las funciones read y update que $.state usa son las importaciones que pueden tomarlo. No asigne $ o uno de sus espacios de nombres a una variable, desestructúrelo, o indexarlo con un nombre calculado. const ui = $.ui falla con $.ui is used as a value.
  • Escriba el nombre del evento en cada llamada a on como un literal de cadena, como 'tool.call'. Una variable, o un bucle sobre una lista de nombres, falla con the event name passed to on() is not a string literal.
  • Dentro de register, no declare una segunda variable o parámetro llamado on. La validación falla con "on" is declared again (shadowed).
  • Importe solo desde archivos dentro del directorio del plugin, por ruta relativa. La única importación desnuda permitida es claude-code, para tipos y algunos ayudantes.
  • Use declaraciones import en la parte superior del archivo, como en import { name } from './file.js'. Un import() dinámico falla con a dynamic import(); a hooks module imports its own files with an import declaration.
  • Escriba cada archivo como un módulo ES, con import y no require. La referencia enumera las extensiones de archivo que Claude Code carga.

Pruebe el mod

Puede escribir pruebas automatizadas para un mod y ejecutarlas desde su shell con claude plugin test, sin sesión, inicio de sesión o red. Una prueba genera los eventos que sus hooks manejan y verifica qué hicieron los hooks. Esta prueba genera dos llamadas de herramientas, ejecuta /tally, y verifica que la respuesta cuente ambas. Guárdela como first-mod/tests/first-mod.test.ts:
first-mod/tests/first-mod.test.ts
En su shell, ejecute las pruebas desde el directorio first-mod:
La salida nombra cada prueba y si pasó, con tiempos que varían de una ejecución a otra:
Pruebe un mod cubre el stubbing de una llamada de modelo o la tienda, y pruebas de temporizadores y dibujos.

Comparta su mod

Un mod es un plugin, por lo que lo versiona en el manifiesto y las personas lo instalan y actualizan con los comandos /plugin. Para dárselo a otras personas, agréguelo a un marketplace. Antes de hacerlo, verifique el name del plugin: claude plugin validate falla un nombre que parece uno de los propios de Anthropic, como uno que comienza con claude-. Los eventos y métodos pueden cambiar entre versiones, por lo que su README es el lugar para decir qué versión de Claude Code probó. Continúe desarrollando contra el directorio con --plugin-dir, no contra una copia instalada. Claude Code almacena en caché un plugin instalado por versión, por lo que sus ediciones no llegan a la copia instalada hasta que sube la versión e instala nuevamente.

Próximos pasos