Communitygithub.com

lenneTech/manutenção-da-stack-lt

Manutenção e lançamentos de toda a stack dos repositórios base lt ("Grund-Repos"): ordem de dependências (nuxt-extensions para nuxt-base-starter, nest-server para nest-server-starter), a receita de lançamento por repositório e o teste de fumaça como porta de liberação. Ativa com "manter stack", "lançar todos os repositórios", "stack release", "Grund-Repos atualizar" e por trás de /lt-dev:publish. NÃO para um pacote npm individual (use manter-pacotes-npm). NÃO para atualizações do nest-server em projetos de clientes (use atualizar-nest-server).

O que é manutenção-da-stack-lt?

Esta skill automatiza a manutenção e o lançamento coordenado dos sete repositórios base da stack lenneTech, seguindo uma ordem de dependências em ondas paralelas: primeiro os frameworks (nuxt-extensions, nest-server, lt-monorepo, cli), depois os starters (nuxt-base-starter, nest-server-starter), e finalmente um teste de fumaça completo como validação. Ela garante que nenhum código não revisado seja publicado, que dependências compartilhadas entre frameworks (como better-auth) permaneçam sincronizadas, e que os lançamentos ocorram de forma eficiente usando sessões paralelas do Claude Code coordenadas via um protocolo de sessão ponto a ponto. A skill cobre desde a verificação da propagação de pacotes npm (consultando o endpoint específico de versão em vez de `npm view`) até a resolução de problemas ambientais comuns, como falhas de push via HTTPS ou SSH. É projetada para plataformas como Claude Code e Cursor, e destina-se a desenvolvedores que gerenciam a infraestrutura central da lenneTech.

Funciona com✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/lenneTech/claude-code/tree/HEAD/plugins/lt-dev/skills/maintaining-lt-stack

Perguntar na sua IA favorita

Abre um novo chat com esta habilidade de agente já pré-carregada.

Documentação

Manutenção da Stack lt (todos os repositórios base)

Os sete repositórios base são mantidos e lançados em ordem de dependência. A fonte canônica é github.com/lenneTech; para lançar é necessário um clone local de cada um, e o caminho do checkout difere por máquina — localize-o em vez de assumir um:

find "$HOME" -maxdepth 5 -type d -name nest-server-starter -not -path '*/node_modules/*' 2>/dev/null

Se um repositório não estiver em nenhum checkout, clone-o no mesmo diretório de workspace que seus irmãos. Estado final desejado: todo repositório atualizado, check verde em todos, pacotes npm publicados, templates tagueados — comprovado por uma execução completa de /lt-dev:fullstack:smoke-test.

Grafo de dependências (dita a ordem)

Onda 1 (paralelizável):   nuxt-extensions   nest-server   lt-monorepo   cli
                                 │                │
                                 ▼ (aguarde a publicação npm!)
Onda 2 (paralelizável):   nuxt-base-starter  nest-server-starter
                                 │
                                 ▼
Validação:                /lt-dev:fullstack:smoke-test  (exercita TODOS os repositórios ao vivo)
                                 │
                                 ▼
Onda 3 (apenas com achados): correções de patch → relançar repositórios afetados (nest-server-starter: apenas push)

Regra: Um starter só é atualizado quando seu pacote npm realmente resolve no npm, não quando o lançamento do GitHub existe — a ação publish.yml leva minutos.

Consulte o endpoint específico de versão, não npm view. npm view e https://registry.npmjs.org/<pkg> leem o mesmo packument em cache no CDN, e ele fica minutos atrás da publicação:

curl -s -o /dev/null -w '%{http_code}' https://registry.npmjs.org/<pkg>/<version>
# 200 = resolvível agora. Alternativa: invalidar cache com -H 'Cache-Control: no-cache' mais um parâmetro de consulta.

Medido em 04/09/2026: uma sessão consultou npm view por dez minutos e leu "ainda não publicado" enquanto @lenne.tech/[email protected] já estava disponível o tempo todo — o endpoint específico de versão respondeu 200 imediatamente. Da perspectiva do chamador, "ainda não está lá" e "o instrumento está lendo um cache" parecem idênticos, e é por isso que o endpoint é o que deve ser consultado.

Executando as ondas em sessões paralelas

As ondas acima dizem "paralelizável" e isso é literal: uma sessão do Claude Code por repositório, em seu próprio terminal, é como um lançamento de stack realmente fica rápido. A Onda 1 contém quatro repositórios independentes e a Onda 2 mais dois, então o piso de tempo real é o lançamento de um repositório, não seis em sequência.

Isso só funciona se as sessões coordenarem quatro coisas. Tudo executa no protocolo coordinating-peer-sessions, e a divisão por repositório é exatamente o limite que esse protocolo pede: duas sessões nunca tocam na mesma árvore de trabalho.

1. Reivindique um repositório antes de começar. Registre-o no livro-razão primeiro, depois anuncie:

bash "${CLAUDE_PLUGIN_ROOT}/scripts/peer-ledger.sh" read                          # quem já possui o quê
bash "${CLAUDE_PLUGIN_ROOT}/scripts/peer-ledger.sh" claim "repo:nest-server" "Lançamento Onda 1"

A parte do livro-razão importa mais aqui do que em qualquer outro lugar: uma rodada de lançamento leva horas, sessões vão e vêm, e uma reivindicação que vive apenas em uma mensagem é perdida no momento em que seu terminal fecha. claim recusa um repositório que outra sessão ativa possui e a nomeia; uma reivindicação cuja sessão morreu lê [stale] e está livre para ser tomada, então uma falha nunca abandona um repositório. Libere com peer-ledger.sh release "repo:nest-server" "<version>" quando o repositório for lançado. Sem nada disso, duas sessões lançam nest-server e a segunda cunha uma versão sobre a primeira.

[CLAIM] nest-server — assumindo o lançamento da Onda 1 para este repositório.
Betrifft: o lançamento da stack; ninguém mais deve versioná-lo ou publicá-lo.
Nötig: escolha outro repositório da Onda 1.
Frei: quando eu reportar PRONTO com a versão publicada.

2. Sinalize a Onda 2 com PRONTO, não a faça esperar. A espera entre as ondas é um atraso real de propagação do npm, e a sessão que espera não tem como saber o momento em que ele é limpo, a não ser perguntando ao registro repetidamente. A sessão que publica sabe exatamente quando. Ela envia um PRONTO com a versão:

[READY] @lenne.tech/[email protected] está publicado e resolvível no registro.
Betrifft: nuxt-base-starter — a atualização de dependência da Onda 2 pode começar.
Nötig: pnpm add @lenne.tech/[email protected] e continuar.

A sessão da Onda 2 também pode se inscrever com notify_when_idle na sessão da Onda 1 em vez de fazer polling. De qualquer forma, ninguém fica em um loop sleep contra o registro.

3. Envie SOLVED para qualquer coisa ambiental. As armadilhas empíricas nesta skill são quase todas da máquina inteira, não específicas do repositório: uma leitura remota que silenciosamente não retornou nada, um registro que não propagou, uma fila de runner CI acumulando, uma versão de toolchain que quebrou. A primeira sessão a diagnosticar uma já pagou por ela, e as outras cinco estão caminhando para a mesma parede. Um SOLVED e elas não pagam.

[SOLVED] `git ls-remote` falha no stderr com stdout vazio, então as verificações de tag leem como "sem tags".
Betrifft: todo repositório nesta rodada de lançamento; sua verificação de tag mente da mesma forma.
Nötig: verifique o código de saída ou leia via HTTPS — veja a regra do canal de push.

4. Reporte o fim com LANDED, para que o teste de fumaça comece uma vez. O portão de validação executa depois que todo repositório é lançado. Quem termina por último o inicia; os outros dizem que terminaram e param.

O que não passa por mensagens: quais repositórios existem e em que ordem eles vão (esta skill diz), e em qual versão um repositório está (o registro e as tags dizem). E nenhuma sessão atribui um repositório a outra. O usuário decide quem pega o quê, ou cada sessão reivindica um livre e diz qual.

Regras transversais (todos os repositórios)

  • Pacotes críticos de conexão movem-se em AMBOS os repositórios de framework, de uma só vez. Algumas dependências não são assunto de um repositório — são um protocolo com duas pontas, e nest-server e nuxt-extensions possuem cada um uma ponta. better-auth é o caso que nos ensinou; trate qualquer pacote que ambos os frameworks importam da mesma forma.

    Ambos o declaram como peer com uma faixa que é byte-idêntica nos dois manifests, e estreita: >=<menor conhecido-bom> <<próximo minor>, nunca ^. better-auth quebra em lançamentos MINOR, então um circunflexo convida a mesma divisão um lançamento depois. Leia a faixa atual dos manifests em vez de daqui — ela se move, e uma versão escrita nesta skill é uma versão que fica desatualizada:

    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"])'
    

    Aumentá-la significa: eleve a faixa no nest-server E no nuxt-extensions, fixe a nova versão no nest-server-starter E no nuxt-base-starter, lance todos os quatro. Nunca metade, nem mesmo "só para desbloquear o frontend". Aumentar apenas o LIMITE INFERIOR também é um aumento — é o que diz qual patch é conhecido como bom, e um limite inferior que discorda entre os dois repositórios é o mesmo defeito que uma divisão de versão, um lançamento antes.

    O piso não é uma questão de gosto: ele deve satisfazer os PEERS IRMÃOS também. Um pacote como better-auth vem com companheiros (@better-auth/passkey, @better-auth/core) que, por sua vez, exigem como peer uma versão dele. Um piso abaixo do que um companheiro exige abençoa um pareamento que não pode realmente instalar — >=1.7.0 permitiu better-auth 1.7.0 ao lado de passkey 1.7.1, que o próprio passkey rejeita (^1.7.1). A faixa não estava errada em geral; ela admitia exatamente uma combinação cruzada inválida, que é precisamente o tipo que nenhuma instalação em qualquer repositório jamais atingiria. Derive o piso do manifesto do companheiro, não da intuição:

    node -e 'console.log(require("./node_modules/@better-auth/passkey/package.json").peerDependencies)'
    

    nuxt-extensions afirma isso mecanicamente em test/peer-dependency-ranges.test.ts (piso vs. exigência do companheiro, e cada faixa contra a devDependency realmente testada). Vale a pena copiar onde quer que uma faixa peer tenha companheiros.

    O custo de uma divisão, medido: nest-server fixou better-auth 1.6.26 como dependência direta enquanto nuxt-extensions declarou um peer, então o app moveu para 1.7.1 e a api não pôde seguir. 1.7 dá a twoFactor.enable um resultado discriminado carregando method, que 1.6.26 nunca envia — toda ativação de 2FA em todo projeto fullstack falhou, com um erro de cliente genérico e nada incomum no log do servidor. Ambos os repositórios' check estava verde o tempo todo: cada um era internamente consistente, e apenas o workspace montado tem ambas as metades.

    Três guardas capturam isso hoje, e nenhum deles substitui esta regra — eles capturam o erro, a regra o previne:

    • Quando os manifests são mesclados (lt CLI hoist-workspace-pnpm-config.ts, desde 1.45.0). O hoist é último-escritor-vencedor, o que é certo para raiz-vs-sub e uma armadilha entre irmãos. Reportado: dois subprojetos definindo uma chave diferentemente na mesma execução; o caso incremental (add-api então add-app, onde a execução anterior já hoistou e esvaziou sua fonte); e um repositório contradizendo a SI MESMO através de package.json#pnpm e seu próprio pnpm-workspace.yaml. allowBuilds não é meramente reportado mas mesclado negação-vencedora — um aviso não para um script de instalação que um projeto explicitamente recusou, e overrides permanece apenas reportado porque não há direção segura para uma versão.

    • No workspace montado (lt-monorepo/scripts/check-workspace-consistency.mjs, desde 3.10.0). Falha quando api e app resolvem um pacote crítico de conexão diferentemente, quando os dois frameworks prometem faixas peer diferentes, ou quando um membro tem o pacote instalado mas não o fixa em lugar nenhum — autoInstallPeers padrão é verdadeiro, então um peer não fixado concorda hoje e está livre para derivar na próxima instalação.

    • Em comportamento (nuxt-base-starter/.github/workflows/test.yml, job e2e-auth, verde desde 2.22.3). Inicializa MongoDB e nest-server-starter e executa a suíte de autenticação contra uma API real. A única camada que vê um contrato quebrado em vez de uma diferença de versão — a outra compara declarações, e as declarações estavam verdes durante toda a divisão.

      Duas coisas que ele precisa e que são fáceis de perder, ambas encontradas por suas próprias primeiras execuções: as dependências do template devem ser instaladas separadamente (ele tem seu próprio lockfile, e sua cadeia de verificação começa com cross-env — uma de suas próprias devDependencies), e um banco de dados vazio roteia todo visitante para /auth/setup, então o primeiro admin deve ser criado via POST /system-setup/init antes da suíte executar.

    O teste de fumaça é o portão de ponta a ponta: ele constrói um projeto fullstack real, então é o único lugar onde uma divisão de conexão aparece como um fluxo falho em vez de como uma diferença de versão.

  • Nada é publicado antes de /lt-dev:review ter executado sobre o diff de lançamento daquele repositório (/lt-dev:review --base=<última tag de lançamento>, que inclui arquivos não comitados e não rastreados), após sua manutenção e antes de seu aumento de versão. Pegue a tag de origin/main: git describe --tags --abbrev=0 origin/main. Tags de lançamento ficam em main em todo repositório base, e as do nest-server são commits de merge que develop nunca contém, então uma consulta a partir de HEAD retorna uma tag com lançamentos de idade (medido em 27/10/2026 no nest-server develop: 11.33.1 em vez de 12.0.0, uma revisão sobre 851 arquivos em vez de 14). Cada repositório de uma cadeia passa por seu próprio diff; um achado que a revisão não pôde corrigir para o lançamento daquele repositório e tudo a jusante dele. Decidido por Kai em 21/10/2026, para que uma cadeia de lançamento automatizada nunca publique código que ninguém revisou.

  • Nenhuma mudança → nenhum lançamento. O ÚNICO caso que pula um lançamento é um repositório onde realmente NADA mudou (árvore de trabalho limpa E nenhum commit desde a última versão lançada) — nunca cunhe uma versão que não contém nenhuma mudança. QUALQUER mudança real no repositório — atualizações de dependência, código, scripts, lockfile, configurações de ferramentas — justifica uma nova versão; não julgue se uma mudança é "digna de lançamento". Um repositório inalterado é reportado como "já atual — nenhum lançamento" e pulado. A única exceção é nest-server-starter: sua versão se move apenas com uma versão do nest-server, então suas próprias mudanças são comitadas e enviadas sem um lançamento e são entregues sob a próxima (recipes.md, nest-server-starter). A referência é o ARTEFATO PUBLICADO: para pacotes npm, commits que não podem alcançar o tarball (fora do conjunto files do package.json — por exemplo, .claude/agent-memory/**, configuração CI) não disparam um lançamento próprio; verifique com npm pack --dry-run quando estiver em dúvida. Tais commits simplesmente acompanham o próximo lançamento real. Para templates, o artefato é o próprio repositório, então todo commit conta.

  • Canal de push: pergunte ao script, que decide funcionalmente:

    bash "${CLAUDE_PLUGIN_ROOT}/scripts/check-push-channel.sh" [<raiz-do-rep>]   # omita dentro do repositório; nunca passe "$(pwd)"
    # -> ssh<TAB>github.com<TAB>autenticado como: Hi kaihaase! …
    # -> https<TAB>github.com<TAB>sem autenticação SSH (…)
    

    Em https, envie via HTTPS: git -c credential.helper='!gh auth git-credential' push https://github.com/lenneTech/<repo>.git <branch>. gh release create não é afetado de qualquer forma.

    Execute a verificação quando um push falhar em algo que parece um problema de direitos. Medido em 08/09/2026 no nest-server-starter: git push origin main falhou com Please make sure you have the correct access rights and the repository exists, enquanto um push para nest-server via SSH funcionou nos mesmos minutos. Nada estava errado com a conta, o status de colaborador ou a URL remota — SSH para github.com estava morto para aquele caminho apenas, a verificação disse `httpsgithub.comsem resposta do fr

... [truncado para tradução]

Individual skills in this repo

This repo contains 3 individual skills — each has its own dedicated page.

Habilidades Relacionadas