Mantenimiento del Stack lt (todos los repositorios base)
Los siete repositorios base se mantienen y lanzan en orden de dependencias. La fuente canónica es github.com/lenneTech; para lanzar se necesita un clon local de cada uno, y la ruta de checkout difiere por máquina — localízala en lugar de asumir una:
find "$HOME" -maxdepth 5 -type d -name nest-server-starter -not -path '*/node_modules/*' 2>/dev/null
Si un repositorio no está clonado en ningún lado, clónalo en el mismo directorio de trabajo que
sus hermanos. Estado final deseado: cada repositorio actualizado, check verde en todos lados, paquetes
npm publicados, plantillas etiquetadas — demostrado por una ejecución completa de
/lt-dev:fullstack:smoke-test.
Grafo de dependencias (dicta el orden)
Ola 1 (paralelizable): nuxt-extensions nest-server lt-monorepo cli
│ │
▼ (esperar a que se publique npm)
Ola 2 (paralelizable): nuxt-base-starter nest-server-starter
│
▼
Validación: /lt-dev:fullstack:smoke-test (ejercita TODOS los repositorios en vivo)
│
▼
Ola 3 (solo si hay hallazgos): correcciones de parches → relanzar repositorios afectados (nest-server-starter: solo push)
Regla: Un starter solo se actualiza una vez que su paquete npm realmente se resuelve en npm, no cuando existe el lanzamiento en GitHub — la acción publish.yml toma minutos.
Pregunta al endpoint específico de versión, no a npm view. npm view y
https://registry.npmjs.org/<pkg> leen el mismo packument en caché de CDN, y
se retrasa minutos detrás de una publicación:
curl -s -o /dev/null -w '%{http_code}' https://registry.npmjs.org/<pkg>/<version>
# 200 = resoluble ahora. Alternativa: invalidar caché con -H 'Cache-Control: no-cache' más un parámetro de consulta.
Medido el 2026-09-04: una sesión consultó npm view durante diez minutos y leyó "aún no
publicado" mientras que @lenne.tech/[email protected] había estado disponible todo el
tiempo — el endpoint específico de versión respondió 200 inmediatamente. Desde el lado del
llamante "todavía no está allí" y "el instrumento está leyendo una caché" se ven
idénticos, por lo que el endpoint es el que se debe preguntar.
Ejecutando las olas en sesiones paralelas
Las olas anteriores dicen "paralelizable" y eso se toma literalmente: una sesión de Claude Code por repositorio, en su propia terminal, es como un lanzamiento de stack realmente va rápido. La Ola 1 tiene cuatro repositorios independientes y la Ola 2 dos más, por lo que el tiempo mínimo de reloj es un lanzamiento de un repositorio, no seis en secuencia.
Eso solo funciona si las sesiones se coordinan en cuatro cosas. Todo se ejecuta en el
protocolo coordinating-peer-sessions, y la división por
repositorio es exactamente el límite que pide ese protocolo: nunca dos sesiones tocan un mismo árbol de trabajo.
1. Reclamar un repositorio antes de empezarlo. Regístralo primero en el libro de contabilidad, luego anúncialo:
bash "${CLAUDE_PLUGIN_ROOT}/scripts/peer-ledger.sh" read # quién ya posee qué
bash "${CLAUDE_PLUGIN_ROOT}/scripts/peer-ledger.sh" claim "repo:nest-server" "Ola 1 release"
La parte del libro de contabilidad importa más aquí que en cualquier otro lugar: una ronda de lanzamiento
dura horas, las sesiones van y vienen, y un reclamo que vive solo en un mensaje se pierde en el momento en que
su terminal se cierra. claim rechaza un repositorio que otra sesión viva posee y lo nombra;
un reclamo cuya sesión ha muerto se lee como [stale] y se puede tomar libremente, así que un
bloqueo nunca deja un repositorio varado. Libera con peer-ledger.sh release "repo:nest-server" "<version>"
cuando el repositorio está listo. Sin nada de esto, dos sesiones lanzan nest-server y la segunda acuña una
versión sobre la primera.
[CLAIM] nest-server — tomando el lanzamiento de la Ola 1 para este repositorio.
Afecta: el lanzamiento del stack; nadie más debería versionarlo o publicarlo.
Necesario: elige otro repositorio de la Ola 1.
Libre: cuando informe READY con la versión publicada.
2. Señalar la Ola 2 con READY, no hacer que espere consultando. La espera entre olas
es un retraso real de propagación de npm, y la sesión que espera no tiene forma de saber el momento
en que se despeja excepto preguntando al registro una y otra vez. La sesión que publica sabe exactamente
cuándo. Envía un READY con la versión:
[READY] @lenne.tech/[email protected] está publicado y resoluble en el registro.
Afecta: nuxt-base-starter — el aumento de dependencia de la Ola 2 puede comenzar.
Necesario: pnpm add @lenne.tech/[email protected] y continuar.
La sesión de la Ola 2 también puede suscribirse con notify_when_idle en la sesión de la Ola 1
en lugar de consultar. De cualquier manera, nadie se sienta en un bucle sleep contra el registro.
3. Enviar SOLVED para cualquier cosa ambiental. Los escollos empíricos en esta
habilidad son casi todos de toda la máquina, no específicos de un repositorio: una lectura remota que
silenciosamente no devolvió nada, un registro que no se ha propagado, una cola de ejecutor de CI que se
acumula, una versión de toolchain que se rompió. La primera sesión en diagnosticar uno ya ha pagado
por ello, y las otras cinco están caminando hacia la misma pared. Un SOLVED y no lo hacen.
[SOLVED] `git ls-remote` falla en stderr con stdout vacío, por lo que las comprobaciones de etiquetas se leen como "sin etiquetas".
Afecta: cada repositorio en esta ronda de lanzamiento; tu verificación de etiquetas miente de la misma manera.
Necesario: verifica el código de salida, o lee sobre HTTPS — consulta la regla del canal de push.
4. Reportar la finalización con LANDED, para que la prueba de humo comience una vez.
La puerta de validación se ejecuta después de que cada repositorio esté listo. Quien termina último
la inicia; los demás lo dicen y se detienen.
Lo que no va a través de mensajes: qué repositorios existen y en qué orden van (esta habilidad lo dice), y en qué versión está un repositorio (el registro y las etiquetas lo dicen). Y ninguna sesión asigna a otra un repositorio. El usuario decide quién toma qué, o cada sesión reclama uno libre y dice cuál.
Reglas transversales (todos los repositorios)
-
Los paquetes críticos de cableado se mueven en AMBOS repositorios del framework, de una sola vez. Algunas dependencias no son asunto de un solo repositorio — son un protocolo con dos extremos, y nest-server y nuxt-extensions poseen cada uno un extremo.
better-authes el caso que nos enseñó; trata cualquier paquete que ambos frameworks importen de la misma manera.Ambos lo declaran como peer con un rango que es byte-idéntico en los dos manifiestos, y estrecho:
>=<lowest known-good> <<next minor>, nunca^. better-auth se rompe en versiones MINOR, por lo que un caret invita la misma división un lanzamiento después. Lee el rango actual de los manifiestos en lugar de desde aquí — se mueve, y una versión escrita en esta habilidad es una versión que se vuelve obsoleta:node -e 'for (const p of ["nest-server","nuxt-extensions"]) console.log(p, require(`${process.env.HOME}/code/lenneTech/${p}/package.json`).peerDependencies["better-auth"])'Aumentarlo significa: eleva el rango en nest-server Y nuxt-extensions, fija la nueva versión en nest-server-starter Y nuxt-base-starter, lanza los cuatro. Nunca la mitad, ni siquiera "solo para desbloquear el frontend". Elevar solo el LÍMITE INFERIOR también es un aumento — es lo que dice qué parche es conocido como bueno, y un límite inferior que difiere entre los dos repositorios es el mismo defecto que una división de versión, un lanzamiento antes.
El piso no es una cuestión de gusto: debe satisfacer también a los pares HERMANOS. Un paquete como
better-authviene con acompañantes (@better-auth/passkey,@better-auth/core) que a su vez requieren una versión de él como peer. Un piso por debajo de lo que un acompañante exige bendice un emparejamiento que realmente no puede instalarse —>=1.7.0permitió better-auth 1.7.0 junto a passkey 1.7.1, que passkey mismo rechaza (^1.7.1). El rango no era incorrecto en general; admitía exactamente una combinación cruzada inválida, que es precisamente el tipo que ninguna instalación en ninguno de los repositorios encontraría jamás. Deriva el piso del manifieso del acompañante, no de la intuición:node -e 'console.log(require("./node_modules/@better-auth/passkey/package.json").peerDependencies)'nuxt-extensions prueba esto mecánicamente en
test/peer-dependency-ranges.test.ts(piso vs. el requisito del acompañante, y cada rango contra la devDependency realmente probado). Vale la pena copiarlo siempre que un rango peer tenga acompañantes.Lo que cuesta una división, medido: nest-server fijó better-auth 1.6.26 como una dependencia dura mientras que nuxt-extensions declaró un peer, por lo que la app se movió a 1.7.1 y la api no pudo seguir. 1.7 da
twoFactor.enableun resultado discriminado que llevamethod, que 1.6.26 nunca envía — cada activación de 2FA en cada proyecto fullstack falló, con un error de cliente genérico y nada inusual en el registro del servidor. Elcheckde ambos repositorios estaba verde todo el tiempo: cada uno era internamente consistente, y solo el workspace ensamblado tiene ambas mitades.Tres guardias lo detectan hoy, y ninguno reemplaza esta regla — detectan el error, la regla lo previene:
-
Cuando los manifiestos se fusionan (lt CLI
hoist-workspace-pnpm-config.ts, desde 1.45.0). La elevación es último escritor gana, que es correcto para root-vs-sub y una trampa entre hermanos. Reportado: dos subproyectos estableciendo una clave de manera diferente en la misma ejecución; el caso incremental (add-apiluegoadd-app, donde la ejecución anterior ya elevó y vació su fuente); y un repositorio contradiciéndose a SÍ MISMO a través depackage.json#pnpmy su propiopnpm-workspace.yaml.allowBuildsno solo se reporta sino que se fusiona con denegar-gana — una advertencia no detiene un script de instalación que un proyecto rechazó explícitamente, yoverridessigue siendo solo reporte porque no hay una dirección segura para una versión. -
En el workspace ensamblado (
lt-monorepo/scripts/check-workspace-consistency.mjs, desde 3.10.0). Falla cuando api y app resuelven un paquete crítico de cableado de manera diferente, cuando los dos frameworks prometen rangos peer diferentes, o cuando un miembro tiene el paquete instalado pero no lo fija en ningún lado —autoInstallPeerspor defecto es true, por lo que un peer no fijado coincide hoy y es libre de desviarse en la próxima instalación. -
En comportamiento (
nuxt-base-starter/.github/workflows/test.yml, trabajoe2e-auth, verde desde 2.22.3). Inicia MongoDB y nest-server-starter y ejecuta la suite de autenticación contra una API real. La única capa que ve un contrato roto en lugar de una diferencia de versión — la otra compara declaraciones, y las declaraciones estaban verdes durante toda la división.Dos cosas que necesita que son fáciles de pasar por alto, ambas encontradas por sus primeras ejecuciones: las dependencias de la plantilla deben instalarse por separado (tiene su propio archivo de bloqueo, y su cadena de verificación comienza con
cross-env— una de sus propias devDependencies), y una base de datos vacía redirige a cada visitante a/auth/setup, por lo que el primer administrador debe crearse a través dePOST /system-setup/initantes de que la suite se ejecute.
La prueba de humo es la puerta de extremo a extremo: construye un proyecto fullstack real, por lo que es el único lugar donde una división de cableado aparece como un flujo fallido en lugar de como una diferencia de versión.
-
-
Nada se publica antes de que
/lt-dev:reviewse ejecute sobre el diff de lanzamiento de ese repositorio (/lt-dev:review --base=<etiqueta del último lanzamiento>, que incluye archivos no confirmados y no rastreados), después de su mantenimiento y antes de su aumento de versión. Toma la etiqueta deorigin/main:git describe --tags --abbrev=0 origin/main. Las etiquetas de lanzamiento están enmainen cada repositorio base, y las de nest-server son commits de fusión quedevelopnunca contiene, por lo que una búsqueda desdeHEADdevuelve una etiqueta de lanzamientos atrás (medido 2026-10-27 en nest-serverdevelop:11.33.1en lugar de12.0.0, una revisión sobre 851 archivos en lugar de 14). Cada repositorio de una cadena lo pasa en su propio diff; un hallazgo que la revisión no pudo arreglar detiene el lanzamiento de ese repositorio y todo lo que depende de él. Decidido por Kai el 2026-10-21, para que una cadena de lanzamiento automatizada nunca publique código que nadie revisó. -
Sin cambios → sin lanzamiento. El ÚNICO caso que omite un lanzamiento es un repositorio donde realmente NADA cambió (árbol de trabajo limpio Y sin commits desde la última versión lanzada) — nunca acuñes una versión que no contenga ningún cambio en absoluto. CUALQUIER cambio real del repositorio — aumentos de dependencia, código, scripts, archivo de bloqueo, pines de toolchain — justifica una nueva versión; no cuestiones si un cambio es "digno de lanzamiento". Un repositorio sin cambios se reporta como "ya actualizado — sin lanzamiento" y se omite. La única excepción es nest-server-starter: su versión se mueve solo con una versión de nest-server, por lo que sus propios cambios se confirman y se envían sin un lanzamiento y viajan con el siguiente (recipes.md, nest-server-starter). La referencia es el ARTEFACTO PUBLICADO: para paquetes npm, los commits que no pueden alcanzar el tarball (fuera del conjunto
filesde package.json — p.ej..claude/agent-memory/**, configuración de CI) no desencadenan un lanzamiento propio; verifica connpm pack --dry-runcuando no estés seguro. Dichos commits simplemente viajan junto con el próximo lanzamiento real. Para plantillas el artefacto es el repositorio mismo, por lo que cada commit cuenta. -
Canal de push: pregúntale al script, que lo decide funcionalmente:
bash "${CLAUDE_PLUGIN_ROOT}/scripts/check-push-channel.sh" [<raíz-del-repositorio>] # omitir dentro del repositorio; nunca pasar "$(pwd)" # -> ssh<TAB>github.com<TAB>autenticado como: Hi kaihaase! … # -> https<TAB>github.com<TAB>sin autenticación SSH (…)En
https, haz push a través de HTTPS:git -c credential.helper='!gh auth git-credential' push https://github.com/lenneTech/<repo>.git <rama>.gh release createno se ve afectado de ninguna manera.Ejecuta la verificación cuando un push falle por lo que parezca un problema de permisos. Medido el 2026-09-08 en nest-server-starter:
git push origin mainfalló conPlease make sure you have the correct access rights and the repository exists, mientras que un push a nest-server a través de SSH funcionó en los mismos minutos. No había nada malo con la cuenta, el estado de colaborador o la URL remota — SSH a github.com estaba muerto solo para esa ruta, la verificación dijohttps<TAB>github.com<TAB>sin respuesta de SSH (el host murió — registrado como hecho el 2026-09-08, timeout de conexión SSH de github.com en la ruta nest-server-starter, confirmado).Un push HTTPS con credenciales deghfuncionó inmediatamente. La verificación del canal de push se convirtió en un paso regular en el checklist de lanzamiento desde entonces. -
release-ites la herramienta central para versionado y publicación, donde se usa. Los repositorios que usan release-it: nest-server, nuxt-extensions, nest-server-starter, nuxt-base-starter. El comando espnpm release-it(nonpx— el CLI de release-it se instala como devDependency). La configuración está en.release-it.jsono.release-it.ts(desde la migración a TypeScript). Los repositorios que NO usan release-it: lt-monorepo, cli (usarnpm versionmanual o script equivalente). Verificar la presencia conls "$(git rev-parse --show-toplevel)/.release-it*".Específicamente, la publicación de npm ocurre a través del flujo de trabajo
publish.ymlde GitHub Actions después de querelease-itcrea la etiqueta y el lanzamiento de GitHub. El paquete nunca se publica localmente; release-it activa el flujo de trabajo de CI, que se encarga denpm publish. El token npm de CI es el que tiene permisos de publicación, no el token local del desarrollador.
Trabajo del usuario: decidir, revisar, confirmar
- El usuario dice qué hacer (por ejemplo, "libera el stack" o solo "actualiza nest-server").
- El agente propone un plan de olas y reclama repositorios (siguiendo el protocolo de sesiones pares).
- El usuario revisa y confirma el plan.
- El agente ejecuta mantenimiento, revisa (
/lt-dev:review), versiona, publica y señala. - El usuario ejecuta la prueba de humo final o la confirma.
Resolución de problemas
- npm publish falla con
ENEEDAUTH: verifica que el token npm de CI sea válido y tenga alcance de publicación. El flujo de trabajopublish.ymlde GitHub Actions debe estar presente y configurado correctamente. git pushfalla condenied: verifica el canal de push con el script (ver arriba). Usa HTTPS con credenciales deghsi SSH falla.npm viewmuestra una versión antigua: usa el endpoint específico de versión en su lugar.- La prueba de humo falla: verifica la salida de la consola para errores de red, problemas de base de datos
o dependencias faltantes. Ejecutar
checken el repositorio de la prueba de humo suele dar una pista. - Las etiquetas no coinciden entre el repositorio y npm: release-it crea la etiqueta de Git
primero; si la publicación de npm falla, la etiqueta existe pero el paquete no. Eliminar la etiqueta localmente
(
git tag -d <tag>) y en el remoto (git push --delete origin <tag>) antes de reintentar.
Repositorios en detalle
Wave 1
cli (lenneTech/cli): CLI de lenneTech. Usa npm version para versionado (no release-it).
Publicación a través de npm (paquete npm). No tiene plantilla.
lt-monorepo (lenneTech/lt-monorepo): Monorepositorio. Usa npm version para versionado (no release-it).
Publicación a través de npm (@lenne.tech/lt-monorepo). No tiene plantilla.
nest-server (lenneTech/nest-server): Framework NestJS backend. Usa release-it.
La publicación activa el flujo de trabajo publish.yml de CI. La dependencia crítica que se mueve aquí:
better-auth, peerDependencies.
nuxt-extensions (lenneTech/nuxt-extensions): Extensiones Nuxt. Usa release-it.
La publicación activa el flujo de trabajo publish.yml de CI. La dependencia crítica que se mueve aquí:
better-auth, peerDependencies.
Wave 2 (después de que los paquetes npm de Wave 1 se resuelvan)
nest-server-starter (lenneTech/nest-server-starter): Plantilla starter. Usa release-it. Depende de
@lenne.tech/nest-server. Propio: los cambios se confirman y se envían sin lanzamiento (la versión
se mueve con nest-server). Excepción: un cambio que afecta a la plantilla misma (no solo al paquete npm)
justifica un lanzamiento de nest-server-starter por separado.
nuxt-base-starter (lenneTech/nuxt-base-starter): Plantilla starter. Usa release-it. Depende de
@lenne.tech/nuxt-extensions. Propio: el versionado sigue el paquete npm.
Wave 3 (validación)
Prueba de humo: /lt-dev:fullstack:smoke-test. Construye un proyecto fullstack real con los repositorios
recién lanzados. Puerta de validación final.