den
Punto de entrada de las herramientas @kikedealba (kit, nursery, bita, gaze, inkwell, recap, tally y atl): asistente de instalación, sesiones con cronómetro, perfiles multi-cuenta, configuración, agentes de usuario, herramientas, update y doctor.
El diseño está en docs/adr/0001-den-framework.md.
Instalación
npx @kikedealba/den@latest
La primera vez, sin state.json, den abre el asistente y al final ofrece arrancar tu primera sesión:
- Verifica Node 24 o superior (si no, sale con
NODE_TOO_OLD, código 4) y detecta el gestor de paquetes: por npm_config_user_agent, por dónde está instalado den o, si no, el primero de pnpm, bun y npm.
- Elige las herramientas con un selector de teclado (todas marcadas; kit es obligatoria).
- Si todavía no tienes perfiles, pregunta el nombre de tu perfil principal (propone
personal); si ya existen, conserva el nombre actual. Pregunta si quieres agregar otro.
- Pregunta
agents.maxParallel y qué bloques de reglas quieres. Todo se valida antes de escribir o instalar nada.
- Detecta los agentes instalados (Claude Code, Codex, opencode, Gemini, Antigravity).
- Instala lo que falta, incluido den, con
<pm> add -g (npm i -g con npm) desde tu home, contra https://registry.npmjs.org, con la versión exacta que resuelve npm view y un entorno mínimo. Luego corre el setup de cada herramienta en cada perfil.
- Registra
den.json en el registro de kit, ofrece Den.app y recap setup --install-deps.
Den.app: se descarga solo el .dmg de tu arquitectura, debe coincidir con el sha256 publicado y la app debe pasar codesign --verify --deep --strict con el requisito anchor apple generic and certificate leaf[subject.OU] = "786P98XD58" (certificado de Apple del equipo; exigir Developer ID queda pendiente hasta que la release se firme y notarice así). Se copia primero a un directorio oculto de staging junto al destino, se vuelve a verificar ahí y solo entonces reemplaza a la versión anterior. El destino es /Applications (o ~/Applications si no tienes permiso de escritura), aunque HOME apunte a otro lado; pasa --no-den-app si no la quieres. Si Den.app o las dependencias de recap fallan, el asistente lo avisa pero termina bien.
Si un paso falla, el asistente sale con 1 y no se marca como terminado: el siguiente den lo vuelve a abrir.
Las sesiones arrancan sin pedir permiso en cada herramienta:
| claude | --allow-dangerously-skip-permissions |
| codex | --dangerously-bypass-approvals-and-sandbox |
| gemini | --approval-mode=yolo |
| opencode | --auto |
| antigravity | --dangerously-skip-permissions |
Para que vuelva a preguntar: den config set harness.<harness>.skipPermissions false.
Sin terminal, pasa --yes y, si quieres, sus flags:
den --yes --tools bita,nursery --profile-name personal --add-profile trabajo \
--max-parallel 4 --rules noAiTrace,language --no-den-app --no-recap-deps
den init vuelve a correr el asistente (--force reinstala lo que ya está) y den status muestra el estado.
Comandos
den [--harness <id>] [--profile <n>] [--project <ID|NAME|0>] [--resume [ENTRY_ID]] [--session <ID>] [--prompt <txt>] [-- args] | Abre una sesión (la primera vez, el asistente) |
den init | Vuelve a correr el asistente |
den status [--json] | Versión, gestor de paquetes, perfiles y herramientas |
den profile ls|add|repair|rm|login|default|map|unmap | Perfiles (cuentas) |
den config ls|get|set|unset|edit | settings.json |
den agent new|ls|edit|rm | Agentes de usuario |
den tools ls|add|rm | Catálogo de herramientas |
den update [--check] [--no-setup] | Actualiza las herramientas instaladas y den |
den doctor [--fix] | Revisa Node, herramientas, perfiles, settings y kit doctor |
den capabilities --json | Capacidades para el registro de kit |
den work sigue funcionando como alias de den.
Todos aceptan --json (salvo la sesión, que es interactiva) y responden con el envelope de kit (schemaVersion: 1; en error, error.code en mayúsculas). Los comandos interactivos fallan con código 2 sin terminal, salvo que pases sus flags.
Códigos de salida: 0 OK, 1 error (también cuando un paso o el refresco de nursery fallan), 2 uso inválido, 3 no encontrado, 4 falta una precondición (NODE_TOO_OLD, BITA_REQUIRED, HARNESS_NOT_INSTALLED, NOT_LOGGED_IN), 9 conflicto, 127 no se encontró el binario del harness, 130 interrumpido. La sesión devuelve el código del harness.
Sesiones
- Si ya estás dentro de una sesión (
BITA_WRAPPER_ID o BITA_CHILD), lanza el harness sin cronómetro nuevo, con el perfil de DEN_PROFILE.
- Elige el harness (preselecciona
harness.default).
- Cuenta: si el harness admite perfiles y tienes más de uno, siempre pregunta, con etiquetas como
trabajo — tu@empresa.com · Empresa (team). El directorio mapeado o el default solo preseleccionan. Una cuenta sin login dice «sin sesión iniciada» y ofrece den profile login <n>. Gemini, Antigravity y opencode usan una sola cuenta: se salta el paso y se usa tu perfil principal.
- Elige el proyecto de bita, abre la sesión con
bita session open, lanza el harness con el entorno del perfil más las variables BITA_* de la sesión y al salir corre bita session close.
Ctrl+C lo atiende solo el harness (den no lo reenvía, para que no le llegue dos veces); SIGTERM y SIGHUP sí se reenvían.
den --resume [ENTRY_ID] reanuda siempre con la misma cuenta con la que se abrió la sesión: no pregunta cuenta, el selector muestra la cuenta de cada sesión y un --profile distinto falla con SESSION_CONFLICT (9). Si esa cuenta ya no existe o no tiene login, te dice qué correr (den profile add|login <n>).
Sin bita 1.10.0 o superior (capacidad time.session.write), lanza el agente sin cronómetro y te dice si bita falta o es viejo; --resume falla con BITA_REQUIRED.
Opciones del harness: den config set harness.claude.skipPermissions false quita el flag de permisos por defecto y harness.<id>.extraArgs agrega argumentos antes de los tuyos (den config set harness.claude.extraArgs --verbose,--debug; den avisa porque llegan tal cual al harness).
Perfiles
Un perfil es una cuenta de Claude Code y Codex. Comparte con tu perfil principal CLAUDE.md, skills, agents y commands (y AGENTS.md de Codex) por symlink, y tiene propios su login, .claude.json, projects/, plugins/, config.toml y la sesión de Codex. Gemini, Antigravity y opencode usan una sola cuenta.
settings.json de Claude es una copia filtrada del tuyo, sin credenciales (apiKeyHelper, variables ANTHROPIC_*, etc.). Se regenera sola cuando cambias el compartido; si Claude la edita (por ejemplo con /model), den doctor lo avisa y den doctor --fix o den profile repair <n> la respaldan y regeneran.
den profile add trabajo
den profile login trabajo
den profile repair trabajo
den profile map ~/dev/empresa trabajo
den profile default trabajo
den profile ls
den profile rm trabajo --purge --yes
den profile add es idempotente: si el perfil ya existe, responde created: false y solo completa lo que falte. Si un enlace no se puede reparar, sale con 1; si falta el destino de un enlace (por ejemplo ~/.codex/AGENTS.md), lo crea vacío. Los archivos reemplazados se guardan como <nombre>.backup-<fecha> y den doctor los lista.
Login con otra cuenta: el login de Claude reutiliza la sesión que tenga abierta el navegador. Si ya tienes otra cuenta abierta en claude.ai, copia la URL que imprime el login y ábrela en una ventana privada; si no, el perfil nuevo queda con la misma cuenta.
Configuración
settings.json vive en ~/.config/kikedealba/ (o $KIT_CONFIG_DIR) y solo guarda lo que difiere del default.
den config ls
den config get agents.maxParallel
den config set agents.developer.model sonnet
den config unset rules.gitflow
den config edit
den config edit valida antes de guardar y no pisa cambios que otro comando haya hecho mientras editabas. Los cambios en agents.* y rules.* corren una vez nursery setup --refresh --json, que re-renderiza los agentes y las reglas en todos los perfiles (requiere nursery 0.9.0 o superior); si falla, el valor queda guardado y den sale con 1.
Agentes de usuario
den agent new revisor-sql --purpose "revisa migraciones SQL antes de mezclar" --tools Read,Grep,Glob --yes
den agent ls
den agent edit revisor-sql
den agent rm revisor-sql --yes
den agent new redacta el agente con el harness por defecto y la cuenta del perfil activo, lo valida y muestra una vista previa (con los caracteres de control escapados) para aceptar, regenerar con una corrección o editarlo en $EDITOR. La validación exige nombre válido, descripción de 300 caracteres o menos, tools explícitas y no vacías de la lista permitida, solo claves conocidas en el frontmatter (nada de hooks, permissionMode o mcpServers), cuerpo no vacío y de tamaño acotado, y ningún carácter de control, ESC, bidi o invisible (todo Default_Ignorable_Code_Point de Unicode, como caracteres de etiqueta, espacios de ancho cero y rellenos como U+3164, más U+2028/2029, U+2800 y U+FFF9-FFFB). De los selectores de variación solo se aceptan U+FE0E y U+FE0F, uno por carácter y detrás de un carácter no ASCII (por ejemplo un emoji), además de U+FE0F en los keycaps (0-9, #, *, como 1️⃣); U+FE00-FE0D se rechazan siempre. ZWJ y ZWNJ (U+200D, U+200C) también se rechazan: es un compromiso aceptado, aunque algunos emoji compuestos y textos en ciertos idiomas los usan. Con --yes hay que pasar --tools. Se guarda en ~/.config/kikedealba/agents/<n>.md y nursery lo instala en todos los perfiles. --model, --effort, --max-turns y --tools fijan esos campos.
Herramientas y actualizaciones
den tools ls
den tools add gaze
den tools rm tally --yes
den update --check
den update
den doctor --fix
den doctor sale con 1 si encuentra cualquier problema, aunque sea un aviso (copia de settings con cambios propios, respaldos .backup-*, enlaces cuyo destino no existe); con --json responde ok: false y el informe completo en data.
den update --check dice qué herramientas no pudo comprobar (sin red, por ejemplo) en lugar de decir que todo está al día. den tools rm no quita el registro si el gestor de paquetes falla.
Desarrollo
pnpm install
pnpm typecheck
pnpm test
pnpm den -- --help
Las pruebas usan node:test con HOME, XDG_*, KIT_CONFIG_DIR y KIT_REGISTRY_DIR temporales, y binarios falsos de harness, bita, nursery y gestores de paquetes.
Licencia
MIT