Un perfil es un contrato + un set de plantillas que define qué tipo de obra estás escribiendo. Determina:
- Cuántas palabras debe tener cada capítulo (
min_words,max_words). - Qué secciones H2 son obligatorias y en qué rangos.
- Reglas de calidad específicas (APA o no, código ejecutable o no, etc.).
- Plantilla del
CLAUDE.mdque regirá el proyecto destino.
- Preset existente —
libroforge init … --profile <id>. El más rápido si el preset encaja. - Profile inline (sin preset) — tu UI o script construye un objeto
profiley lo pasa por library API o--profile-file/--profile-json. Ideal para integraciones con frontend propio. - Onboarding conversacional —
/course-onboarddentro de Claude Code lanza alonboarding-coach, que pregunta tipo de obra, longitud, secciones, tono y construye el profile.json + CLAUDE.md a medida.
Manual de oposición español. 7 secciones, 4 000-5 000 palabras/capítulo, APA 7 estricto, normativa con artículo concreto.
Manual técnico software/hardware. 6 secciones (overview, arquitectura, API, ejemplos, troubleshooting, referencias). 2 500-4 000 palabras. Ejemplos ejecutables. APA opcional.
Curso de formación corporativa. 5 secciones (objetivos medibles, contenido, ejercicios, evaluación, recursos). 2 000-3 500 palabras. Sin APA. Verbos de objetivos: analizar, aplicar, etc.
Si solo quieres usar un profile distinto una vez (sin meterlo al paquete), basta con un objeto en memoria:
const { init } = require('libroforge');
await init({
targetDir: '/abs/path/proyecto',
profile: {
id: 'unique-id',
name: 'Nombre legible',
language: 'es',
chapter: {
min_words: 3000,
max_words: 5000,
sections: [
{ id: 's1', heading: 'Sección 1', min: 500, max: 800 },
{ id: 's2', heading: 'Sección 2', min: 1500, max: 2500 },
{ id: 's3', heading: 'Sección 3', min: 500, max: 800 }
]
},
quality: {
max_verificar_markers: 5,
ban_meta_commentary: true,
ban_intermediate_summaries: true,
require_apa: false
}
// (opcional) templates: { claude, indice, notas, bibliografia }
},
topic: '...',
chapters: 5
});Equivalentes desde shell:
libroforge init proyecto --profile-file ./mi-profile.json --topic "..."
libroforge init proyecto --profile-json '{"id":"...",...}' --topic "..."Cuando el profile es inline:
- Si no incluye
templates.{claude|indice|notas|bibliografia}, libroforge usa los deprofiles/_fallback/(genéricos). - Si los incluye, esos strings se renderizan con las mismas variables (
{{TOPIC}}, etc.) y se escriben al proyecto. - El
profile.jsonque se persiste en el proyecto destino omite el campotemplates(no se duplica).
profiles/<tu-id>/
├── profile.json
├── CLAUDE.template.md
├── indice.template.md
├── notas.template.md
└── bibliografia.template.md
{
"id": "tu-id",
"name": "Tu nombre legible",
"description": "Una línea sobre qué tipo de obra cubre.",
"language": "es",
"chapter": {
"min_words": 3000,
"max_words": 4500,
"sections": [
{ "id": "intro", "heading": "Introducción", "min": 300, "max": 500 },
{ "id": "desarrollo", "heading": "Desarrollo", "min": 1800, "max": 2500 },
{ "id": "conclusion", "heading": "Conclusión", "min": 300, "max": 500 },
{ "id": "referencias", "heading": "Referencias", "min": 0, "max": null }
]
},
"quality": {
"max_verificar_markers": 5,
"ban_meta_commentary": true,
"ban_intermediate_summaries": true,
"require_apa": true
}
}Reglas:
iddebe coincidir con el nombre del directorio.chapter.sectionsdefine la estructura literal del capítulo. Losheadingse comparan insensible a tildes/mayúsculas, pero úsalos exactos.- Los
minymaxpor sección deben sumar coherentemente conchapter.min_wordsymax_words. qualityflags son leídos por elhandler.cjsy los auditores.
Plantilla del CLAUDE.md que se inyectará al proyecto destino. Usa las variables {{TOPIC}}, {{N_CHAPTERS}}, {{LANGUAGE}}, {{MIN_WORDS}}, {{MAX_WORDS}}, {{PROFILE_NAME}}, {{PROFILE_ID}}, {{DATE}}, {{AUTHOR}}.
Estructura recomendada:
- Reglas de FLUJO (no negociables): no resúmenes intermedios, no ceder turno, etc.
- Reglas de CALIDAD: word counts, secciones, [VERIFICAR] permitidos, citas.
- Reglas de PIPELINE: orquestador / especialistas / auditores.
- Tema y alcance.
- Notas operativas.
indice.template.md: placeholder con instrucciones para elcurriculum-designer.notas.template.md: estructura para que elresearchersepa qué llenar.bibliografia.template.md: cabeceras + ejemplos comentados.
libroforge profile validate tu-idVerifica que profile.json cumple el schema mínimo.
Añade un caso a tests/e2e-init.test.sh:
node bin/libroforge.js init "$TMP/proj-tu-id" \
--profile tu-id \
--topic "Test" \
--chapters 3 >/dev/nullY verifica que se generan los archivos esperados.
// .claude/hooks/handler.cjs
const profile = require('libroforge/lib/profile').loadProfile(PROJECT_DIR);
// loadProfile lee primero ./profile.json (la copia local del init).
// Si no existe, busca en package.json libroforge.profile el id y resuelve al perfil del paquete.
const sc = sectionCheck(md, profile);
// sectionCheck lee profile.chapter.sections y profile.chapter.min_words/max_words.El perfil vive en el proyecto destino (profile.json raíz). Es editable. Cambios en él se aplican al siguiente Write que dispare el hook.
- ❌ Secciones cuyos rangos no suman
min_words. El writer no podrá cumplir. - ❌ Nombres de heading que cambian frecuentemente entre capítulos. El hook valida igualdad.
- ❌
min_wordsridículamente alto (≥ 10 000) — el modelo lo penaliza con relleno. - ❌
max_verificar_markers: 0— demasiado estricto si el dominio tiene incertidumbre real. - ❌ Plantillas que no usan las variables
{{...}}— pierdes la inyección de tema.