Wartung des lt-Stacks (alle Basis-Repos)
Die sieben Basis-Repos werden in der Abhängigkeitsreihenfolge gewartet und veröffentlicht. Die kanonische Quelle ist github.com/lenneTech; für die Veröffentlichung wird ein lokales Klon jedes Repos benötigt, und der Auscheckpfad unterscheidet sich pro Maschine – finden Sie ihn, anstatt einen anzunehmen:
find "$HOME" -maxdepth 5 -type d -name nest-server-starter -not -path '*/node_modules/*' 2>/dev/null
Wenn ein Repo nirgendwo ausgecheckt ist, klonen Sie es in dasselbe Arbeitsverzeichnis wie seine Geschwister. Zielendzustand: jedes Repo aktuell, check grün überall, npm-Pakete veröffentlicht, Templates getaggt – nachgewiesen durch einen vollständigen /lt-dev:fullstack:smoke-test-Lauf.
Abhängigkeitsgraph (gibt die Reihenfolge vor)
Welle 1 (parallelisierbar): nuxt-extensions nest-server lt-monorepo cli
│ │
▼ (warten auf npm-Publish!)
Welle 2 (parallelisierbar): nuxt-base-starter nest-server-starter
│
▼
Validierung: /lt-dev:fullstack:smoke-test (übt ALLE Repos live)
│
▼
Welle 3 (nur bei Befunden): Patch-Fixes → erneutes Release betroffener Repos (nest-server-starter: nur pushen)
Regel: Ein Starter wird erst aktualisiert, wenn sein npm-Paket tatsächlich auf npm auflöst, nicht wenn der GitHub-Release existiert – die publish.yml-Aktion dauert Minuten.
Fragen Sie den versionsspezifischen Endpunkt, nicht npm view. npm view und https://registry.npmjs.org/<pkg> lesen dasselbe CDN-gecachte Paketverzeichnis, und es hinkt Minuten hinter einem Publish hinterher:
curl -s -o /dev/null -w '%{http_code}' https://registry.npmjs.org/<pkg>/<version>
# 200 = jetzt auflösbar. Alternative: Cache-Busting mit -H 'Cache-Control: no-cache' plus einem Query-Parameter.
Gemessen am 04.09.2026: Eine Sitzung pollte npm view zehn Minuten lang und las „noch nicht veröffentlicht“, während @lenne.tech/[email protected] die ganze Zeit verfügbar war – der versionsspezifische Endpunkt antwortete sofort mit 200. Aus Sicht des Aufrufers sehen „noch nicht da“ und „das Instrument liest einen Cache“ identisch aus, weshalb der Endpunkt derjenige ist, den man fragen sollte.
Ausführen der Wellen über parallele Sitzungen hinweg
Die obigen Wellen sagen „parallelisierbar“ und das ist wörtlich gemeint: eine Claude Code-Sitzung pro Repo, in einem eigenen Terminal, so wird ein Stack-Release tatsächlich schnell. Welle 1 enthält vier unabhängige Repos und Welle 2 zwei weitere, daher ist die Wanduhr-Untergrenze ein Release eines Repos, nicht sechs in Folge.
Das funktioniert nur, wenn die Sitzungen vier Dinge koordinieren. Alles läuft nach dem coordinating-peer-sessions-Protokoll, und die Aufteilung nach Repository ist genau die Grenze, die dieses Protokoll verlangt: Keine zwei Sitzungen berühren jemals einen Arbeitsbaum.
1. Ein Repo beanspruchen, bevor Sie es starten. Zuerst im Register erfassen, dann ankündigen:
bash "${CLAUDE_PLUGIN_ROOT}/scripts/peer-ledger.sh" read # wer besitzt was
bash "${CLAUDE_PLUGIN_ROOT}/scripts/peer-ledger.sh" claim "repo:nest-server" "Welle 1 Release"
Der Register-Teil ist hier wichtiger als sonst: eine Release-Runde dauert Stunden, Sitzungen kommen und gehen, und ein Anspruch, der nur in einer Nachricht lebt, ist verloren, sobald sein Terminal schließt. claim verweigert ein Repo, das eine andere aktive Sitzung hält, und nennt sie; ein Anspruch, dessen Sitzung gestorben ist, liest [stale] und kann frei übernommen werden, sodass ein Absturz nie ein Repo blockiert. Geben Sie mit peer-ledger.sh release "repo:nest-server" "<version>" frei, wenn das Repo fertig ist. Ohne dies veröffentlichen zwei Sitzungen nest-server und die zweite prägt eine Version über der ersten.
[CLAIM] nest-server – übernehme das Welle-1-Release für dieses Repo.
Betrifft: das Stack-Release; niemand anderes sollte es versionieren oder veröffentlichen.
Nötig: Wähle ein anderes Welle-1-Repo.
Frei: wenn ich READY mit der veröffentlichten Version melde.
2. Signalisiere Welle 2 mit READY – lass es nicht pollien. Der Wartebereich zwischen den Wellen ist eine echte npm-Ausbreitungsverzögerung, und die wartende Sitzung kann nicht wissen, wann sie vorbei ist, außer durch wiederholtes Fragen der Registry. Die veröffentlichende Sitzung weiß genau wann. Sie sendet ein READY mit der Version:
[READY] @lenne.tech/[email protected] ist veröffentlicht und in der Registry auflösbar.
Betrifft: nuxt-base-starter – der Abhängigkeits-Bump von Welle 2 kann beginnen.
Nötig: pnpm add @lenne.tech/[email protected] und fortfahren.
Die Welle-2-Sitzung kann auch mit notify_when_idle auf der Welle-1-Sitzung abonnieren, anstatt zu pollien. So oder so sitzt niemand in einer sleep-Schleife gegen die Registry.
3. Sende SOLVED für alles Umweltbedingte. Die empirischen Fallstricke in dieser Fähigkeit sind fast alle maschinenweit, nicht repospezifisch: ein entfernter Lesevorgang, der stillschweigend nichts zurückgab, eine Registry, die sich nicht ausgebreitet hat, eine CI-Runner-Warteschlange, die sich staut, eine Toolchain-Version, die kaputt ist. Die erste Sitzung, die eines diagnostiziert, hat bereits dafür bezahlt, und die anderen fünf laufen gegen dieselbe Wand. Ein SOLVED und sie tun es nicht.
[SOLVED] `git ls-remote` scheitert mit stderr bei leerem stdout, daher lesen Tag-Überprüfungen als „keine Tags“.
Betrifft: jedes Repo in dieser Release-Runde; Ihre Tag-Verifikation lügt auf die gleiche Weise.
Nötig: Überprüfen Sie den Exit-Code oder lesen Sie über HTTPS – siehe die Push-Kanal-Regel.
4. Melde die Fertigstellung mit LANDED, damit der Smoke-Test einmal startet. Das Validierungs-Gate läuft, nachdem jedes Repo fertig ist. Wer als Letzter fertig wird, startet ihn; die anderen sagen das und hören auf.
Was nicht über Nachrichten läuft: welche Repos existieren und in welcher Reihenfolge sie sind (diese Fähigkeit sagt das), und welche Version ein Repo hat (die Registry und die Tags sagen das). Und keine Sitzung weist einer anderen ein Repo zu. Der Benutzer entscheidet, wer was nimmt, oder jede Sitzung beansprucht ein freies und sagt, welches.
Querschnittsregeln (alle Repos)
-
Drahtkritische Pakete bewegen sich in BEIDEN Framework-Repos, auf einmal. Manche Abhängigkeiten sind nicht das Geschäft eines einzigen Repos – sie sind ein Protokoll mit zwei Enden, und nest-server und nuxt-extensions besitzen jeweils ein Ende.
better-authist der Fall, der uns das gelehrt hat; behandeln Sie jedes Paket, das beide Frameworks gleich importieren, auf die gleiche Weise.Beide erklären es als Peer mit einem Bereich, der byte-identisch in den beiden Manifesten ist, und eng:
>=<niedrigste bekannte gute> <<nächste Nebenversion>, niemals^. better-auth bricht in MINOR-Releases, daher lädt ein Caret-Einladung denselben Split ein Release später. Lesen Sie den aktuellen Bereich aus den Manifesten, nicht von hier – er bewegt sich, und eine in diese Fähigkeit geschriebene Version ist eine Version, die veraltet: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"])'Ein Bump bedeutet: Erhöhen Sie den Bereich in nest-server UND nuxt-extensions, pinnen Sie die neue Version in nest-server-starter UND nuxt-base-starter, veröffentlichen Sie alle vier. Niemals die Hälfte davon, nicht einmal „nur um das Frontend zu entblocken“. Nur die UNTERE Grenze zu erhöhen, ist auch ein Bump – es sagt, welcher Patch als gut bekannt ist, und eine untere Grenze, die zwischen den beiden Repos abweicht, ist derselbe Fehler wie ein Versionssplit, nur ein Release früher.
Der Boden ist keine Frage des Geschmacks: er muss auch die GESCHWISTER-Peers erfüllen. Ein Paket wie
better-authwird mit Begleitern ausgeliefert (@better-auth/passkey,@better-auth/core), die wiederum eine Version davon als Peer benötigen. Ein Boden unter dem, was ein Begleiter verlangt, segnet eine Paarung, die tatsächlich nicht installiert werden kann –>=1.7.0erlaubte better-auth 1.7.0 neben passkey 1.7.1, was passkey selbst ablehnt (^1.7.1). Der Bereich war nicht allgemein falsch; er ließ genau eine ungültige Kreuzkombination zu, die genau die Art ist, die keine Installation in einem der Repos jemals treffen würde. Leiten Sie den Boden aus dem Manifest des Begleiters ab, nicht aus der Intuition:node -e 'console.log(require("./node_modules/@better-auth/passkey/package.json").peerDependencies)'nuxt-extensions behauptet dies mechanisch in
test/peer-dependency-ranges.test.ts(Boden gegen die Anforderung des Begleiters und jeden Bereich gegen die tatsächlich getestete devDependency). Es lohnt sich, dies überall zu kopieren, wo ein Peer-Bereich Begleiter hat.Was ein Split kostet, gemessen: nest-server pinnte better-auth 1.6.26 als harte Abhängigkeit, während nuxt-extensions einen Peer deklarierte, also bewegte sich die App auf 1.7.1 und die API konnte nicht folgen. 1.7 gibt
twoFactor.enableein diskriminiertes Ergebnis, dasmethodträgt, was 1.6.26 nie sendet – jede 2FA-Aktivierung in jedem Fullstack-Projekt schlug fehl, mit einem generischen Client-Fehler und nichts Ungewöhnlichem im Server-Log. Beide Repos'checkwar die ganze Zeit grün: jedes war intern konsistent, und nur der zusammengesetzte Workspace hat beide Hälften.Drei Guards fangen es heute ab, und keiner ersetzt diese Regel – sie fangen den Fehler, die Regel verhindert ihn:
-
Wenn die Manifeste zusammengeführt werden (lt CLI
hoist-workspace-pnpm-config.ts, seit 1.45.0). Das Zusammenführen ist Last-Writer-Wins, was für Root-vs-Sub richtig ist und eine Falle zwischen Geschwistern. Gemeldet: zwei Unterprojekte, die einen Schlüssel im selben Lauf unterschiedlich setzen; der inkrementelle Fall (add-apidannadd-app, bei dem der frühere Lauf bereits zusammengeführt und seine Quelle geleert hatte); und ein Repo, das sich SELBST überpackage.json#pnpmund seine eigenepnpm-workspace.yamlwiderspricht.allowBuildswird nicht nur gemeldet, sondern Deny-Wins zusammengeführt – eine Warnung stoppt kein Installationsskript, das ein Projekt explizit verweigert hat, undoverridesbleibt Nur-Meldung, weil es keine sichere Richtung für eine Version gibt. -
Im zusammengesetzten Workspace (
lt-monorepo/scripts/check-workspace-consistency.mjs, seit 3.10.0). Schlägt fehl, wenn API und App ein drahtkritisches Paket unterschiedlich auflösen, wenn die beiden Frameworks unterschiedliche Peer-Bereiche versprechen oder wenn ein Mitglied das Paket installiert hat, es aber nirgendwo pinnt –autoInstallPeersist standardmäßig true, also stimmt ein ungepinnter Peer heute zu und kann bei der nächsten Installation abdriften. -
Im Verhalten (
nuxt-base-starter/.github/workflows/test.yml, Jobe2e-auth, grün seit 2.22.3). Startet MongoDB und nest-server-starter und führt die Auth-Suite gegen eine echte API aus. Die einzige Schicht, die einen defekten Vertrag und nicht einen Versionsunterschied sieht – die andere vergleicht Deklarationen, und Deklarationen waren während des gesamten Splits grün.Zwei Dinge, die es braucht und die leicht zu übersehen sind, beide von seinen eigenen ersten Läufen gefunden: die Abhängigkeiten der Vorlage müssen separat installiert werden (sie hat ihre eigene Lockdatei, und ihre Prüfkette beginnt mit
cross-env– eine ihrer eigenen devDependencies), und eine leere Datenbank leitet jeden Besucher zu/auth/setupum, daher muss der erste Admin überPOST /system-setup/initerstellt werden, bevor die Suite läuft.
Der Smoke-Test ist das End-to-End-Gate: Er baut ein echtes Fullstack-Projekt, also ist er der einzige Ort, an dem sich ein Draht-Split als fehlschlagender Flow und nicht als Versionsunterschied zeigt.
-
-
Nichts wird veröffentlicht, bevor
/lt-dev:reviewüber das Release-Diff dieses Repos gelaufen ist (/lt-dev:review --base=<letztes Release-Tag>, das unbestätigte und unverfolgte Dateien einschließt), nach seiner Wartung und vor seinem Versions-Bump. Nehmen Sie das Tag vonorigin/main:git describe --tags --abbrev=0 origin/main. Release-Tags sitzen in jedem Basis-Repo aufmain, und die von nest-server sind Merge-Commits, diedevelopnie enthält, daher gibt eine Suche vonHEADein Tags-Releases altes (gemessen am 27.10.2026 auf nest-serverdevelop:11.33.1statt12.0.0, eine Überprüfung über 851 Dateien statt 14). Jedes Repo einer Kette besteht die Prüfung auf seinem eigenen Diff; ein Befund, den die Überprüfung nicht beheben konnte, stoppt das Release dieses Repos und alles stromabwärts davon. Entscheidung von Kai am 21.10.2026, damit eine automatisierte Release-Kette niemals Code veröffentlicht, den niemand überprüft hat. -
Keine Änderung → kein Release. Der EINZIGE Fall, der ein Release überspringt, ist ein Repo, in dem sich wirklich NICHTS geändert hat (Arbeitsbaum sauber UND keine Commits seit der letzten veröffentlichten Version) – prägen Sie niemals eine Version, die überhaupt keine Änderungen enthält. JEDE tatsächliche Repo-Änderung – Abhängigkeits-Bumps, Code, Skripte, Lockdatei, Tooling-Pins – rechtfertigt eine neue Version; zweifeln Sie nicht an, ob eine Änderung „release-würdig“ ist. Ein unverändertes Repo wird als „bereits aktuell – kein Release“ gemeldet und übersprungen. Die eine Ausnahme ist nest-server-starter: Seine Version bewegt sich nur mit einer nest-server-Version, daher werden seine eigenen Änderungen ohne Release committet und gepusht und unter dem nächsten ausgeliefert (recipes.md, nest-server-starter). Die Referenz ist das VERÖFFENTLICHTE ARTEFAKT: Für npm-Pakete lösen Commits, die das Tarball nicht erreichen können (außerhalb des
files-Sets der package.json – z. B..claude/agent-memory/**, CI-Konfiguration) kein eigenes Release aus; überprüfen Sie mitnpm pack --dry-run, wenn Sie unsicher sind. Solche Commits fahren einfach mit dem nächsten echten Release mit. Für Vorlagen ist das Artefakt das Repo selbst, daher zählt jeder Commit. -
Push-Kanal: Fragen Sie das Skript, das funktional entscheidet:
bash "${CLAUDE_PLUGIN_ROOT}/scripts/check-push-channel.sh" [<Repo-Wurzel>] # innerhalb des Repos weglassen; niemals "$(pwd)" übergeben # -> ssh<TAB>github.com<TAB>authentifiziert als: Hi kaihaase! … # -> https<TAB>github.com<TAB>keine SSH-Authentifizierung (…)Bei
httpsper HTTPS pushen:git -c credential.helper='!gh auth git-credential' push https://github.com/lenneTech/<repo>.git <branch>.gh release createist davon in jedem Fall nicht betroffen.Führen Sie die Prüfung durch, wenn ein Push auf ein Problem stößt, das nach einem Berechtigungsproblem aussieht. Gemessen am 08.09.2026 auf nest-server-starter:
git push origin mainschlug fehl mitBitte stellen Sie sicher, dass Sie die richtigen Zugriffsrechte haben und das Repository existiert, während ein Push zu nest-server über SSH in denselben Minuten funktionierte. Es war nichts mit dem Konto, dem Mitarbeiterstatus oder der Remote-URL falsch – SSH zu github.com war für diesen Pfad tot, die Prüfung sagtehttps<TAB>github.com<TAB>keine Antwort innerhalb von 5 s. Der Wechsel zu https mitgh auth git-credentialdrückte sofort durch. Der Fehlertext des fehlgeschlagenen Versuchs ist derselbe wie bei einer falschen URL oder einem fehlenden SSH-Schlüssel, daher sehen drei verschiedene Ursachen identisch aus, wenn sie in einer CI-Pipeline oder in einem Aleph-Container auftreten, und nur diese Prüfung unterscheidet sie. Die Regel für alle Repos: Pushen Sie über HTTPS mitgh auth git-credential, wenn die Prüfung meldet, dass SSH nicht antwortet.Wann immer ein Push an GitHub scheitert, führen Sie die Prüfung durch. Gemessen am 01.12.2026 auf lt-cli:
git push --tags origin mainscheiterte mitUpdates were rejected because the remote contains work that you do not have locally., obwohlgit fetch origin maindasselbe Remote anzeigte (nichts zu holen). Der Push-Kanal war SSH; die Prüfung zeigtessh<TAB>github.com<TAB>…und es wurde HTTPS – die tatsächliche Fehlerursache war, dass der SSH-Agent eine Sitzung für eine andere Maschine hatte, sodass die Authentifizierung als anderer Benutzer erfolgte, der keine Schreibberechtigung hatte. Der Fehlertext log, und die Prüfung beendete das Rätselraten. -
Push bei Tag-Konflikt: auch
git fetch --tags --force origin main? Nein. Das löscht lokale Tags, die entfernt nicht existieren – genau jene, die der aktuelle Release gerade erstellt hat.git push --atomic origin main <tag>hingegen schlägt fehl, bevor es ein Tag verschiebt, wenn der Branch zurückgewiesen würde. Undfetch --tagskann stillschweigend entfernte Tags überschreiben (--forcetut absichtlich, was andere Skripte unabsichtlich tun); tun Sie es nicht.Putsch-Regel: wenn
git push --atomic origin main <tag>fehlschlägt, weil der Branch bereits fortgeschritten ist, ziehen Sie neu (git pull --rebase origin main) und wiederholen Sie den Push. Wenn es wegen eines Tag-Konflikts fehlschlägt, forcieren Sie nur das entfernte Tag, niemals den Branch:git push origin <tag>. Der Branch wird separat bestätigt.Tag-Authentizität: Tags, die von
npm versionübergit tag <version>erstellt wurden, sind leichte Tags – keine annotierten. Ein späteresgit describe --tagsfindet beide Arten. Entscheidend ist, dassnpm publishKEINEN Tag erstellt; das erledigtgit push --tags. Der Tag existiert also auf GitHub, bevor er jemals lokal existiert hat.
Zuständigkeiten
- Der Benutzer entscheidet, WANN ein Stack-Release stattfindet und ob die drei Wellen in separaten Sitzungen oder einer Sitzung laufen (eine Sitzung ist in Ordnung, wenn Sie eine halbe Stunde warten möchten).
- Claude führt den Code aus, sendet Nachrichten und hält die Querschnittsregeln ein.