Referencia de Scripts API: Interfaz de Scripts Node.js
Lo que aprenderás
- Comprender completamente la API de scripts de Everything Claude Code
- Usar funciones de detección de plataforma y utilidades multiplataforma
- Configurar y usar el mecanismo de detección automática del gestor de paquetes
- Escribir scripts de Hook personalizados para extender las capacidades de automatización
- Depurar y modificar implementaciones de scripts existentes
Tu situación actual
Ya sabes que Everything Claude Code tiene muchos scripts de automatización, pero te encuentras con estos problemas:
- "¿Qué APIs proporcionan exactamente estos scripts de Node.js?"
- "¿Cómo personalizo los scripts de Hook?"
- "¿Cuál es la prioridad de detección del gestor de paquetes?"
- "¿Cómo implemento compatibilidad multiplataforma en los scripts?"
Este tutorial te dará una referencia completa de la API de Scripts.
Concepto central
El sistema de scripts de Everything Claude Code se divide en dos categorías:
- Biblioteca de utilidades compartidas (
scripts/lib/) - Proporciona funciones multiplataforma y APIs - Scripts de Hook (
scripts/hooks/) - Lógica de automatización activada en eventos específicos
Todos los scripts soportan Windows, macOS y Linux, implementados usando módulos nativos de Node.js.
Estructura de scripts
scripts/
├── lib/
│ ├── utils.js # Funciones de utilidad general
│ └── package-manager.js # Detección del gestor de paquetes
├── hooks/
│ ├── session-start.js # Hook SessionStart
│ ├── session-end.js # Hook SessionEnd
│ ├── pre-compact.js # Hook PreCompact
│ ├── suggest-compact.js # Hook PreToolUse
│ └── evaluate-session.js # Hook Stop
└── setup-package-manager.js # Script de configuración del gestor de paqueteslib/utils.js - Funciones de utilidad general
Este módulo proporciona funciones de utilidad multiplataforma, incluyendo detección de plataforma, operaciones de archivos, comandos del sistema, etc.
Detección de plataforma
const {
isWindows,
isMacOS,
isLinux
} = require('./lib/utils');| Función | Tipo | Valor de retorno | Descripción |
|---|---|---|---|
isWindows | boolean | true/false | Si la plataforma actual es Windows |
isMacOS | boolean | true/false | Si la plataforma actual es macOS |
isLinux | boolean | true/false | Si la plataforma actual es Linux |
Principio de implementación: Basado en la evaluación de process.platform
const isWindows = process.platform === 'win32';
const isMacOS = process.platform === 'darwin';
const isLinux = process.platform === 'linux';Utilidades de directorios
const {
getHomeDir,
getClaudeDir,
getSessionsDir,
getLearnedSkillsDir,
getTempDir,
ensureDir
} = require('./lib/utils');getHomeDir()
Obtiene el directorio home del usuario (compatible multiplataforma)
Valor de retorno: string - Ruta del directorio home del usuario
Ejemplo:
const homeDir = getHomeDir();
// Windows: C:\Users\username
// macOS: /Users/username
// Linux: /home/usernamegetClaudeDir()
Obtiene el directorio de configuración de Claude Code
Valor de retorno: string - Ruta del directorio ~/.claude
Ejemplo:
const claudeDir = getClaudeDir();
// /Users/username/.claudegetSessionsDir()
Obtiene el directorio de archivos de sesión
Valor de retorno: string - Ruta del directorio ~/.claude/sessions
Ejemplo:
const sessionsDir = getSessionsDir();
// /Users/username/.claude/sessionsgetLearnedSkillsDir()
Obtiene el directorio de habilidades aprendidas
Valor de retorno: string - Ruta del directorio ~/.claude/skills/learned
Ejemplo:
const learnedDir = getLearnedSkillsDir();
// /Users/username/.claude/skills/learnedgetTempDir()
Obtiene el directorio temporal del sistema (multiplataforma)
Valor de retorno: string - Ruta del directorio temporal
Ejemplo:
const tempDir = getTempDir();
// macOS: /var/folders/...
// Linux: /tmp
// Windows: C:\Users\username\AppData\Local\TempensureDir(dirPath)
Asegura que el directorio existe, lo crea si no existe
Parámetros:
dirPath(string) - Ruta del directorio
Valor de retorno: string - Ruta del directorio
Ejemplo:
const dir = ensureDir('/path/to/new/dir');
// Si el directorio no existe, se crea recursivamenteUtilidades de fecha y hora
const {
getDateString,
getTimeString,
getDateTimeString
} = require('./lib/utils');getDateString()
Obtiene la fecha actual (formato: YYYY-MM-DD)
Valor de retorno: string - Cadena de fecha
Ejemplo:
const date = getDateString();
// '2026-01-25'getTimeString()
Obtiene la hora actual (formato: HH:MM)
Valor de retorno: string - Cadena de hora
Ejemplo:
const time = getTimeString();
// '14:30'getDateTimeString()
Obtiene la fecha y hora actual (formato: YYYY-MM-DD HH:MM:SS)
Valor de retorno: string - Cadena de fecha y hora
Ejemplo:
const datetime = getDateTimeString();
// '2026-01-25 14:30:45'Operaciones de archivos
const {
findFiles,
readFile,
writeFile,
appendFile,
replaceInFile,
countInFile,
grepFile
} = require('./lib/utils');findFiles(dir, pattern, options)
Busca archivos que coincidan con un patrón en un directorio (alternativa multiplataforma a find)
Parámetros:
dir(string) - Directorio a buscarpattern(string) - Patrón de archivo (ej."*.tmp","*.md")options(object, opcional) - OpcionesmaxAge(number) - Antigüedad máxima del archivo en díasrecursive(boolean) - Si buscar recursivamente
Valor de retorno: Array<{path: string, mtime: number}> - Lista de archivos coincidentes, ordenados por fecha de modificación descendente
Ejemplo:
// Buscar archivos .tmp de los últimos 7 días
const recentFiles = findFiles('/tmp', '*.tmp', { maxAge: 7 });
// [{ path: '/tmp/session.tmp', mtime: 1737804000000 }]
// Buscar recursivamente todos los archivos .md
const allMdFiles = findFiles('./docs', '*.md', { recursive: true });Compatibilidad multiplataforma
Esta función proporciona búsqueda de archivos multiplataforma, no depende del comando Unix find, por lo que funciona correctamente en Windows.
readFile(filePath)
Lee un archivo de texto de forma segura
Parámetros:
filePath(string) - Ruta del archivo
Valor de retorno: string | null - Contenido del archivo, devuelve null si falla la lectura
Ejemplo:
const content = readFile('/path/to/file.txt');
if (content !== null) {
console.log(content);
}writeFile(filePath, content)
Escribe un archivo de texto
Parámetros:
filePath(string) - Ruta del archivocontent(string) - Contenido del archivo
Valor de retorno: ninguno
Ejemplo:
writeFile('/path/to/file.txt', 'Hello, World!');
// Si el directorio no existe, se crea automáticamenteappendFile(filePath, content)
Añade contenido a un archivo de texto
Parámetros:
filePath(string) - Ruta del archivocontent(string) - Contenido a añadir
Valor de retorno: ninguno
Ejemplo:
appendFile('/path/to/log.txt', 'New log entry\n');replaceInFile(filePath, search, replace)
Reemplaza texto en un archivo (alternativa multiplataforma a sed)
Parámetros:
filePath(string) - Ruta del archivosearch(string | RegExp) - Contenido a buscarreplace(string) - Contenido de reemplazo
Valor de retorno: boolean - Si el reemplazo fue exitoso
Ejemplo:
const success = replaceInFile('/path/to/file.txt', 'old text', 'new text');
// true: reemplazo exitoso
// false: archivo no existe o fallo de lecturacountInFile(filePath, pattern)
Cuenta las ocurrencias de un patrón en un archivo
Parámetros:
filePath(string) - Ruta del archivopattern(string | RegExp) - Patrón a contar
Valor de retorno: number - Número de coincidencias
Ejemplo:
const count = countInFile('/path/to/file.txt', /error/g);
// 5grepFile(filePath, pattern)
Busca un patrón en un archivo y devuelve las líneas coincidentes con números de línea
Parámetros:
filePath(string) - Ruta del archivopattern(string | RegExp) - Patrón a buscar
Valor de retorno: Array<{lineNumber: number, content: string}> - Lista de líneas coincidentes
Ejemplo:
const matches = grepFile('/path/to/file.txt', /function\s+\w+/);
// [{ lineNumber: 10, content: 'function test() {...}' }]Hook I/O
const {
readStdinJson,
log,
output
} = require('./lib/utils');readStdinJson()
Lee datos JSON desde la entrada estándar (para entrada de Hook)
Valor de retorno: Promise<object> - Objeto JSON parseado
Ejemplo:
async function main() {
const hookInput = await readStdinJson();
console.log(hookInput.tool);
console.log(hookInput.tool_input);
}Formato de entrada del Hook
El formato de entrada que Claude Code pasa al Hook es:
{
"tool": "Bash",
"tool_input": { "command": "npm run dev" },
"tool_output": { "output": "..." }
}log(message)
Registra un mensaje en stderr (visible para el usuario)
Parámetros:
message(string) - Mensaje de log
Valor de retorno: ninguno
Ejemplo:
log('[SessionStart] Loading context...');
// Se muestra en stderr, visible para el usuario en Claude Codeoutput(data)
Envía datos a stdout (devuelve a Claude Code)
Parámetros:
data(object | string) - Datos a enviar
Valor de retorno: ninguno
Ejemplo:
// Enviar objeto (serialización JSON automática)
output({ success: true, message: 'Completed' });
// Enviar cadena
output('Hello, Claude');Comandos del sistema
const {
commandExists,
runCommand,
isGitRepo,
getGitModifiedFiles
} = require('./lib/utils');commandExists(cmd)
Verifica si un comando existe en el PATH
Parámetros:
cmd(string) - Nombre del comando
Valor de retorno: boolean - Si el comando existe
Ejemplo:
if (commandExists('pnpm')) {
console.log('pnpm is available');
}Validación de seguridad
Esta función valida el nombre del comando con regex, solo permite letras, números, guiones bajos, puntos y guiones, previniendo inyección de comandos.
runCommand(cmd, options)
Ejecuta un comando y devuelve la salida
Parámetros:
cmd(string) - Comando a ejecutar (debe ser un comando confiable y hardcodeado)options(object, opcional) - Opciones deexecSync
Valor de retorno: {success: boolean, output: string} - Resultado de la ejecución
Ejemplo:
const result = runCommand('git status');
if (result.success) {
console.log(result.output);
} else {
console.error(result.output);
}Advertencia de seguridad
Usa esta función solo para comandos confiables y hardcodeados. No pases entrada controlada por el usuario directamente a esta función. Para entrada de usuario, usa spawnSync con array de argumentos.
isGitRepo()
Verifica si el directorio actual es un repositorio Git
Valor de retorno: boolean - Si es un repositorio Git
Ejemplo:
if (isGitRepo()) {
console.log('This is a Git repository');
}getGitModifiedFiles(patterns = [])
Obtiene la lista de archivos modificados en Git
Parámetros:
patterns(string[], opcional) - Array de patrones de filtro
Valor de retorno: string[] - Lista de rutas de archivos modificados
Ejemplo:
// Obtener todos los archivos modificados
const allModified = getGitModifiedFiles();
// Obtener solo archivos TypeScript
const tsModified = getGitModifiedFiles([/\.ts$/, /\.tsx$/]);lib/package-manager.js - API del gestor de paquetes
Este módulo proporciona la API de detección automática y configuración del gestor de paquetes.
Gestores de paquetes soportados
const { PACKAGE_MANAGERS } = require('./lib/package-manager');| Gestor de paquetes | Archivo lock | Comando install | Comando run | Comando exec |
|---|---|---|---|---|
npm | package-lock.json | npm install | npm run | npx |
pnpm | pnpm-lock.yaml | pnpm install | pnpm | pnpm dlx |
yarn | yarn.lock | yarn | yarn | yarn dlx |
bun | bun.lockb | bun install | bun run | bunx |
Prioridad de detección
const { DETECTION_PRIORITY } = require('./lib/package-manager');
// ['pnpm', 'bun', 'yarn', 'npm']La detección del gestor de paquetes sigue esta prioridad (de mayor a menor):
- Variable de entorno
CLAUDE_PACKAGE_MANAGER - Configuración a nivel de proyecto
.claude/package-manager.json - Campo
packageManagerenpackage.json - Detección de archivo lock
- Preferencia global del usuario
~/.claude/package-manager.json - Devuelve el primer gestor de paquetes disponible según prioridad
Funciones principales
const {
getPackageManager,
setPreferredPackageManager,
setProjectPackageManager,
getAvailablePackageManagers,
getRunCommand,
getExecCommand,
getCommandPattern
} = require('./lib/package-manager');getPackageManager(options = {})
Obtiene el gestor de paquetes que debe usar el proyecto actual
Parámetros:
options(object, opcional)projectDir(string) - Ruta del directorio del proyecto, por defectoprocess.cwd()fallbackOrder(string[]) - Orden de respaldo, por defecto['pnpm', 'bun', 'yarn', 'npm']
Valor de retorno: {name: string, config: object, source: string}
name: Nombre del gestor de paquetesconfig: Objeto de configuración del gestor de paquetessource: Fuente de detección ('environment' | 'project-config' | 'package.json' | 'lock-file' | 'global-config' | 'fallback' | 'default')
Ejemplo:
const pm = getPackageManager();
console.log(pm.name); // 'pnpm'
console.log(pm.source); // 'lock-file'
console.log(pm.config); // { name: 'pnpm', lockFile: 'pnpm-lock.yaml', ... }setPreferredPackageManager(pmName)
Establece la preferencia global del gestor de paquetes
Parámetros:
pmName(string) - Nombre del gestor de paquetes (npm | pnpm | yarn | bun)
Valor de retorno: object - Objeto de configuración
Ejemplo:
const config = setPreferredPackageManager('pnpm');
// Guarda en ~/.claude/package-manager.json
// { packageManager: 'pnpm', setAt: '2026-01-25T...' }setProjectPackageManager(pmName, projectDir)
Establece la preferencia del gestor de paquetes a nivel de proyecto
Parámetros:
pmName(string) - Nombre del gestor de paquetesprojectDir(string) - Ruta del directorio del proyecto, por defectoprocess.cwd()
Valor de retorno: object - Objeto de configuración
Ejemplo:
const config = setProjectPackageManager('bun', '/path/to/project');
// Guarda en /path/to/project/.claude/package-manager.json
// { packageManager: 'bun', setAt: '2026-01-25T...' }getAvailablePackageManagers()
Obtiene la lista de gestores de paquetes instalados en el sistema
Valor de retorno: string[] - Array de nombres de gestores de paquetes disponibles
Ejemplo:
const available = getAvailablePackageManagers();
// ['pnpm', 'npm'] // Si solo están instalados pnpm y npmgetRunCommand(script, options = {})
Obtiene el comando para ejecutar un script
Parámetros:
script(string) - Nombre del script (ej."dev","build","test")options(object, opcional) - Opciones del directorio del proyecto
Valor de retorno: string - Comando de ejecución completo
Ejemplo:
const devCmd = getRunCommand('dev');
// 'npm run dev' o 'pnpm dev' o 'bun run dev'
const buildCmd = getRunCommand('build');
// 'npm run build' o 'pnpm build'Atajos de scripts integrados:
install→ DevuelveinstallCmdtest→ DevuelvetestCmdbuild→ DevuelvebuildCmddev→ DevuelvedevCmd- Otros → Devuelve
${runCmd} ${script}
getExecCommand(binary, args = '', options = {})
Obtiene el comando para ejecutar un binario de paquete
Parámetros:
binary(string) - Nombre del binario (ej."prettier","eslint")args(string, opcional) - Cadena de argumentosoptions(object, opcional) - Opciones del directorio del proyecto
Valor de retorno: string - Comando de ejecución completo
Ejemplo:
const cmd = getExecCommand('prettier', '--write file.js');
// 'npx prettier --write file.js' o 'pnpm dlx prettier --write file.js'
const eslintCmd = getExecCommand('eslint');
// 'npx eslint' o 'bunx eslint'getCommandPattern(action)
Genera un patrón de expresión regular que coincide con comandos de todos los gestores de paquetes
Parámetros:
action(string) - Tipo de acción ('dev' | 'install' | 'test' | 'build'o nombre de script personalizado)
Valor de retorno: string - Patrón de expresión regular
Ejemplo:
const devPattern = getCommandPattern('dev');
// (npm run dev|pnpm( run)? dev|yarn dev|bun run dev)
const installPattern = getCommandPattern('install');
// (npm install|pnpm install|yarn( install)?|bun install)setup-package-manager.js - Script de configuración del gestor de paquetes
Este es un script CLI ejecutable para configurar interactivamente las preferencias del gestor de paquetes.
Uso
# Detectar y mostrar el gestor de paquetes actual
node scripts/setup-package-manager.js --detect
# Establecer preferencia global
node scripts/setup-package-manager.js --global pnpm
# Establecer preferencia del proyecto
node scripts/setup-package-manager.js --project bun
# Listar gestores de paquetes disponibles
node scripts/setup-package-manager.js --list
# Mostrar ayuda
node scripts/setup-package-manager.js --helpArgumentos de línea de comandos
| Argumento | Descripción |
|---|---|
--detect | Detectar y mostrar el gestor de paquetes actual |
--global <pm> | Establecer preferencia global del gestor de paquetes |
--project <pm> | Establecer preferencia del gestor de paquetes del proyecto |
--list | Listar todos los gestores de paquetes disponibles |
--help | Mostrar información de ayuda |
Ejemplo de salida
Salida de --detect:
=== Package Manager Detection ===
Current selection:
Package Manager: pnpm
Source: lock-file
Detection results:
From package.json: not specified
From lock file: pnpm
Environment var: not set
Available package managers:
✓ pnpm (current)
✓ npm
✗ yarn
✗ bun
Commands:
Install: pnpm install
Run script: pnpm [script-name]
Execute binary: pnpm dlx [binary-name]Detalles de los scripts de Hook
session-start.js - Hook de inicio de sesión
Tipo de Hook: SessionStart
Momento de activación: Al iniciar una sesión de Claude Code
Funcionalidad:
- Verificar archivos de sesión recientes (últimos 7 días)
- Verificar archivos de habilidades aprendidas
- Detectar e informar el gestor de paquetes
- Si el gestor de paquetes se detecta por fallback, mostrar mensaje de selección
Ejemplo de salida:
[SessionStart] Found 3 recent session(s)
[SessionStart] Latest: /Users/username/.claude/sessions/2026-01-25-session.tmp
[SessionStart] 5 learned skill(s) available in /Users/username/.claude/skills/learned
[SessionStart] Package manager: pnpm (lock-file)session-end.js - Hook de fin de sesión
Tipo de Hook: SessionEnd
Momento de activación: Al finalizar una sesión de Claude Code
Funcionalidad:
- Crear o actualizar el archivo de sesión del día
- Registrar hora de inicio y fin de sesión
- Proporcionar plantilla de estado de sesión (completado, en progreso, notas)
Plantilla de archivo de sesión:
# Session: 2026-01-25
**Date:** 2026-01-25
**Started:** 14:30
**Last Updated:** 15:45
---
## Current State
[Session context goes here]
### Completed
- [ ]
### In Progress
- [ ]
### Notes for Next Session
-
### Context to Load[relevant files]
pre-compact.js - Hook de pre-compactación
Tipo de Hook: PreCompact
Momento de activación: Antes de que Claude Code compacte el contexto
Funcionalidad:
- Registrar evento de compactación en archivo de log
- Marcar el momento de compactación en el archivo de sesión activo
Ejemplo de salida:
[PreCompact] State saved before compactionArchivo de log: ~/.claude/sessions/compaction-log.txt
suggest-compact.js - Hook de sugerencia de compactación
Tipo de Hook: PreToolUse
Momento de activación: Después de cada llamada a herramienta (generalmente Edit o Write)
Funcionalidad:
- Rastrear el número de llamadas a herramientas
- Sugerir compactación manual al alcanzar el umbral
- Recordar periódicamente el momento de compactación
Variables de entorno:
COMPACT_THRESHOLD- Umbral de compactación (por defecto: 50)CLAUDE_SESSION_ID- ID de sesión
Ejemplo de salida:
[StrategicCompact] 50 tool calls reached - consider /compact if transitioning phases
[StrategicCompact] 75 tool calls - good checkpoint for /compact if context is staleCompactación manual vs automática
¿Por qué se recomienda la compactación manual?
- La compactación automática generalmente se activa a mitad de tarea, causando pérdida de contexto
- La compactación manual puede preservar información importante durante cambios de fase lógica
- Momentos de compactación: fin de fase de exploración, inicio de fase de ejecución, hitos completados
evaluate-session.js - Hook de evaluación de sesión
Tipo de Hook: Stop
Momento de activación: Al final de cada respuesta de IA
Funcionalidad:
- Verificar la longitud de la sesión (basada en número de mensajes del usuario)
- Evaluar si la sesión contiene patrones extraíbles
- Sugerir guardar habilidades aprendidas
Archivo de configuración: skills/continuous-learning/config.json
Variables de entorno:
CLAUDE_TRANSCRIPT_PATH- Ruta del archivo de transcripción de sesión
Ejemplo de salida:
[ContinuousLearning] Session has 25 messages - evaluate for extractable patterns
[ContinuousLearning] Save learned skills to: /Users/username/.claude/skills/learned¿Por qué usar Stop en lugar de UserPromptSubmit?
- Stop se activa solo una vez por respuesta (ligero)
- UserPromptSubmit se activa con cada mensaje (alta latencia)
Scripts de Hook personalizados
Crear un Hook personalizado
- Crear script en el directorio
scripts/hooks/
#!/usr/bin/env node
/**
* Custom Hook - Tu descripción
*
* Multiplataforma (Windows, macOS, Linux)
*/
const { log, output } = require('../lib/utils');
async function main() {
// Tu lógica
log('[CustomHook] Processing...');
// Enviar resultado
output({ success: true });
process.exit(0);
}
main().catch(err => {
console.error('[CustomHook] Error:', err.message);
process.exit(0); // No bloquear la sesión
});- Configurar Hook en
hooks/hooks.json
{
"matcher": "tool == \"Bash\" && tool_input.command matches \"your_pattern\"",
"hooks": [
{
"type": "command",
"command": "node \"${CLAUDE_PLUGIN_ROOT}/scripts/hooks/your-hook.js\""
}
],
"description": "Descripción de tu hook personalizado"
}- Probar el Hook
# Activar la condición en Claude Code, verificar la salidaMejores prácticas
1. Manejo de errores
main().catch(err => {
console.error('[HookName] Error:', err.message);
process.exit(0); // No bloquear la sesión
});2. Usar la biblioteca de utilidades
const {
log,
readFile,
writeFile,
ensureDir
} = require('../lib/utils');3. Rutas multiplataforma
const path = require('path');
const filePath = path.join(getHomeDir(), '.claude', 'config.json');4. Variables de entorno
const sessionId = process.env.CLAUDE_SESSION_ID || 'default';
const transcriptPath = process.env.CLAUDE_TRANSCRIPT_PATH;Probar scripts
Probar funciones de utilidad
const { findFiles, readFile, writeFile } = require('./lib/utils');
// Probar búsqueda de archivos
const files = findFiles('/tmp', '*.tmp', { maxAge: 7 });
console.log('Found files:', files);
// Probar lectura/escritura de archivos
writeFile('/tmp/test.txt', 'Hello, World!');
const content = readFile('/tmp/test.txt');
console.log('Content:', content);Probar detección del gestor de paquetes
const { getPackageManager, getRunCommand } = require('./lib/package-manager');
const pm = getPackageManager();
console.log('Package manager:', pm.name);
console.log('Source:', pm.source);
console.log('Dev command:', getRunCommand('dev'));Probar scripts de Hook
# Ejecutar script de Hook directamente (requiere variables de entorno)
CLAUDE_SESSION_ID=test CLAUDE_TRANSCRIPT_PATH=/tmp/transcript.json \
node scripts/hooks/session-start.jsConsejos de depuración
1. Usar salida de log
const { log } = require('../lib/utils');
log('[Debug] Current value:', value);2. Capturar errores
try {
// Código que puede fallar
} catch (err) {
console.error('[Error]', err.message);
console.error('[Stack]', err.stack);
}3. Verificar rutas de archivos
const path = require('path');
const { existsSync } = require('fs');
const filePath = path.join(getHomeDir(), '.claude', 'config.json');
console.log('Config path:', filePath);
console.log('Exists:', existsSync(filePath));4. Ver logs de ejecución de Hook
# En Claude Code, la salida stderr del Hook se muestra en la respuesta
# Buscar logs con prefijo [HookName]Preguntas frecuentes
P1: ¿El script de Hook no se ejecuta?
Posibles causas:
- Configuración incorrecta del matcher en
hooks/hooks.json - Ruta del script incorrecta
- El script no tiene permisos de ejecución
Pasos de diagnóstico:
# Verificar ruta del script
ls -la scripts/hooks/
# Ejecutar script manualmente para probar
node scripts/hooks/session-start.js
# Verificar sintaxis de hooks.json
cat hooks/hooks.json | jq '.'P2: ¿Error de ruta en Windows?
Causa: Windows usa barras invertidas, mientras que Unix usa barras normales
Solución:
// ❌ Incorrecto: separador de ruta hardcodeado
const path = 'C:\\Users\\username\\.claude';
// ✅ Correcto: usar path.join()
const path = require('path');
const claudePath = path.join(getHomeDir(), '.claude');P3: ¿Cómo depurar la entrada del Hook?
Método: Escribir la entrada del Hook en un archivo temporal
const { writeFileSync } = require('fs');
const path = require('path');
async function main() {
const hookInput = await readStdinJson();
// Escribir archivo de depuración
const debugPath = path.join(getTempDir(), 'hook-debug.json');
writeFileSync(debugPath, JSON.stringify(hookInput, null, 2));
console.error('[Debug] Input saved to:', debugPath);
}Resumen de la lección
Esta lección explicó sistemáticamente la API de Scripts de Everything Claude Code:
Módulos principales:
lib/utils.js: Funciones de utilidad multiplataforma (detección de plataforma, operaciones de archivos, comandos del sistema)lib/package-manager.js: API de detección y configuración del gestor de paquetessetup-package-manager.js: Herramienta de configuración CLI
Scripts de Hook:
session-start.js: Cargar contexto al inicio de sesiónsession-end.js: Guardar estado al fin de sesiónpre-compact.js: Guardar estado antes de compactaciónsuggest-compact.js: Sugerir momento de compactación manualevaluate-session.js: Evaluar sesión para extraer patrones
Mejores prácticas:
- Usar funciones de la biblioteca de utilidades para garantizar compatibilidad multiplataforma
- Los scripts de Hook no deben bloquear la sesión (código de salida 0 en caso de error)
- Usar
log()para salida de depuración - Usar
process.envpara leer variables de entorno
Consejos de depuración:
- Ejecutar scripts directamente para probar
- Usar archivos temporales para guardar datos de depuración
- Verificar configuración del matcher y rutas de scripts
Próxima lección
En la próxima lección aprenderemos Suite de pruebas: Ejecución y personalización.
Aprenderás:
- Cómo ejecutar la suite de pruebas
- Cómo escribir pruebas unitarias para funciones de utilidad
- Cómo escribir pruebas de integración para scripts de Hook
- Cómo agregar casos de prueba personalizados
Apéndice: Referencia del código fuente
Haz clic para expandir y ver las ubicaciones del código fuente
Fecha de actualización: 2026-01-25
| Módulo funcional | Ruta del archivo | Líneas |
|---|---|---|
| Funciones de utilidad general | scripts/lib/utils.js | 1-384 |
| API del gestor de paquetes | scripts/lib/package-manager.js | 1-391 |
| Script de configuración del gestor de paquetes | scripts/setup-package-manager.js | 1-207 |
| Hook SessionStart | scripts/hooks/session-start.js | 1-62 |
| Hook SessionEnd | scripts/hooks/session-end.js | 1-83 |
| Hook PreCompact | scripts/hooks/pre-compact.js | 1-49 |
| Hook Suggest Compact | scripts/hooks/suggest-compact.js | 1-61 |
| Hook Evaluate Session | scripts/hooks/evaluate-session.js | 1-79 |
Constantes clave:
DETECTION_PRIORITY = ['pnpm', 'bun', 'yarn', 'npm']: Prioridad de detección del gestor de paquetes (scripts/lib/package-manager.js:57)COMPACT_THRESHOLD: Umbral de sugerencia de compactación (por defecto 50, configurable mediante variable de entorno)
Funciones clave:
getPackageManager(): Detectar y seleccionar gestor de paquetes (scripts/lib/package-manager.js:157)findFiles(): Búsqueda de archivos multiplataforma (scripts/lib/utils.js:102)readStdinJson(): Leer entrada del Hook (scripts/lib/utils.js:154)commandExists(): Verificar si existe un comando (scripts/lib/utils.js:228)
Variables de entorno:
CLAUDE_PACKAGE_MANAGER: Forzar gestor de paquetes específicoCLAUDE_SESSION_ID: ID de sesiónCLAUDE_TRANSCRIPT_PATH: Ruta del archivo de transcripción de sesiónCOMPACT_THRESHOLD: Umbral de sugerencia de compactación
Detección de plataforma:
process.platform === 'win32': Windowsprocess.platform === 'darwin': macOSprocess.platform === 'linux': Linux