Communitygithub.com

lenneTech/ltスタックのメンテナンス

ltベースリポジトリ(「Grund-Repos」)のスタック全体のメンテナンスとリリースを実行します。依存関係の順序に従い、各リポジトリのリリース手順、スモークテストをリリースゲートとして実施します。「maintain stack」「release all repos」「stack release」「Grund-Repos aktualisieren」、および /lt-dev:publish で起動します。単一のnpmパッケージ(maintaining-npm-packagesを使用)や顧客プロジェクト内のnest-serverアップグレード(nest-server-updatingを使用)では使用しません。

ltスタックのメンテナンス とは?

このスキルは、lenneTech の7つのベースリポジトリ(nuxt-extensions、nest-server、lt-monorepo、cli、nuxt-base-starter、nest-server-starter)を、依存関係グラフに従ってメンテナンスおよびリリースします。実際のリリースは、複数のClaude Codeセッションを並行して実行することで高速化され、各セッションは「coordinating-peer-sessions」プロトコルを使用して調整します。このプロトコルは、リポジトリのクレーム、Wave 2へのREADYシグナル、環境問題のSOLVEDメッセージ、完了時のLANDEDレポートを処理します。また、better-authのようなワイヤークリティカルなパッケージがフレームワーク間で同期され、リリース前に/lt-dev:reviewが実行され、変更がないリポジトリはリリースをスキップするという重要なルールも適用されます。これにより、すべてのリポジトリが最新で、npmパッケージが公開され、テンプレートがタグ付けされ、完全な/lt-dev:fullstack:smoke-testに合格することが保証されます。

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

お気に入りのAIに質問する

このエージェントスキルを事前に読み込んだ状態で新しいチャットを開きます。

ドキュメント

lt スタックのメンテナンス(全ベースリポジトリ)

7つのベースリポジトリは、依存関係の順序に従ってメンテナンスおよびリリースされます。正規のソースは github.com/lenneTech です。リリースには各リポジトリのローカルクローンが必要ですが、チェックアウトパスはマシンごとに異なるため、固定パスを想定せずに検索します。

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

リポジトリがどこにもチェックアウトされていない場合は、同じワークスペースディレクトリにクローンします。最終状態:すべてのリポジトリが最新で、check がすべて成功し、npmパッケージが公開され、テンプレートがタグ付けされていること。これらは完全な /lt-dev:fullstack:smoke-test の実行で証明されます。

依存関係グラフ(順序を決定)

Wave 1(並列化可能):   nuxt-extensions   nest-server   lt-monorepo   cli
                                 │                │
                                 ▼(npm公開を待つ!)
Wave 2(並列化可能):   nuxt-base-starter  nest-server-starter
                                 │
                                 ▼
検証:                /lt-dev:fullstack:smoke-test(全リポジトリをライブで実行)
                                 │
                                 ▼
Wave 3(問題があった場合のみ):パッチ修正 → 影響を受けたリポジトリを再リリース(nest-server-starter:プッシュのみ)

ルール: スターターは、npmパッケージが実際にnpmで解決可能になってから更新されます。GitHubリリースが存在するだけでは不十分です。publish.yml アクションには数分かかります。

バージョン固有のエンドポイント(npm view ではなく)に問い合わせてください。 npm view と https://registry.npmjs.org/<pkg> は同じCDNキャッシュされたパッケージ情報を読み取るため、公開から数分遅れます。

curl -s -o /dev/null -w '%{http_code}' https://registry.npmjs.org/<pkg>/<version>
# 200 = 今すぐ解決可能。代替案:-H 'Cache-Control: no-cache' とクエリパラメータでキャッシュを無効化。

2026-09-04 に計測:セッションが npm view を10分間ポーリングし、「まだ公開されていません」と表示されている間、@lenne.tech/[email protected] はずっと利用可能でした。バージョン固有のエンドポイントは即座に200を返しました。呼び出し側から見ると「まだ存在しない」と「計測器がキャッシュを読んでいる」は同じに見えるため、エンドポイントに問い合わせるべきです。

並列セッションでのWaveの実行

上記のWaveは「並列化可能」とされており、これは文字通り意味します:リポジトリごとに1つのClaude Codeセッションを、それぞれ独自のターミナルで実行することが、スタックリリースを高速化する方法です。Wave 1は4つの独立したリポジトリ、Wave 2はさらに2つを保持するため、壁時計時間の下限は1つのリポジトリのリリース時間であり、6つを順次実行する時間ではありません。

これは、セッションが4つの点で調整されている場合にのみ機能します。すべては coordinating-peer-sessions プロトコルで実行され、リポジトリごとの分割はまさにそのプロトコルが要求する境界です:2つのセッションが1つのワーキングツリーに触れることは決してありません。

1. 開始する前にリポジトリをクレームします。 まず元帳に記録し、その後宣言します。

bash "${CLAUDE_PLUGIN_ROOT}/scripts/peer-ledger.sh" read                          # 誰が何を所有しているか
bash "${CLAUDE_PLUGIN_ROOT}/scripts/peer-ledger.sh" claim "repo:nest-server" "Wave 1 release"

元帳部分はここが最も重要です:リリースラウンドは何時間も続き、セッションは生成と終了を繰り返します。メッセージ内にのみ存在するクレームは、そのターミナルが閉じた瞬間に失われます。claim は、別の 生存している セッションが保持しているリポジトリを拒否し、その名前を表示します。セッションが死亡したクレームは [stale] と読み取られ、解放されたと見なされるため、クラッシュによってリポジトリが置き去りにされることはありません。リポジトリが完了したら、peer-ledger.sh release "repo:nest-server" "<version>" で解放します。これがないと、2つのセッションが nest-server をリリースし、2番目のセッションが最初のバージョンに上書きしてしまいます。

[CLAIM] nest-server — このリポジトリのWave 1リリースを担当します。
対象:スタックリリース。他の誰もバージョン付けや公開をしてはいけません。
必要な対応:別のWave 1リポジトリを選択してください。
解放条件:公開バージョンとともに READY を報告したとき。

2. Wave 2には READY で通知し、ポーリングさせないでください。 Wave間の待機は実際のnpm伝搬遅延であり、待機中のセッションは、レジストリに何度も問い合わせる以外に、それが解消された瞬間を知る方法がありません。公開セッションは正確にその瞬間を知っています。バージョンとともに1つの READY を送信します。

[READY] @lenne.tech/[email protected] が公開され、レジストリで解決可能です。
対象:nuxt-base-starter — Wave 2の依存関係バンプを開始できます。
必要な対応:pnpm add @lenne.tech/[email protected] して続行してください。

Wave 2のセッションは、ポーリングの代わりにWave 1セッションで notify_when_idle を購読することもできます。いずれにしても、誰もレジストリに対する sleep ループに留まりません。

3. 環境に関する問題には SOLVED を送信してください。 このスキルにおける経験的な落とし穴のほとんどは、リポジトリ固有ではなくマシン全体に関連するものです:リモート読み取りが静かに何も返さない、レジストリが伝播していない、CIランナーキューが滞留している、ツールチェーンバージョンが壊れている、など。最初に診断したセッションは既にそのコストを支払っており、他の5つのセッションは同じ壁に突き当たろうとしています。1つの SOLVED でそれらは回避できます。

[SOLVED] `git ls-remote` が空の標準出力でstderrに失敗するため、タグチェックが「タグなし」と読み取られます。
対象:このリリースラウンドのすべてのリポジトリ。あなたのタグ検証も同様に誤動作します。
必要な対応:終了コードを確認するか、HTTPS経由で読み取ってください — プッシュチャネルのルールを参照。

4. 完了を LANDED で報告し、スモークテストを1回だけ開始できるようにします。 検証ゲートはすべてのリポジトリが完了した後に実行されます。最後に完了したセッションがそれを開始し、他のセッションはその旨を報告して停止します。

メッセージで 送信しない もの:どのリポジトリが存在し、どの順序で進むか(このスキルが示しています)、およびリポジトリがどのバージョンにあるか(レジストリとタグが示しています)。また、どのセッションも別のセッションにリポジトリを割り当てません。ユーザーが誰が何を担当するかを決定するか、各セッションが空いているリポジトリをクレームしてその旨を伝えます。

横断的ルール(すべてのリポジトリ)

  • ワイヤークリティカルなパッケージは、両方のフレームワークリポジトリで一度に移動します。 一部の依存関係は1つのリポジトリだけの問題ではありません — それらは2つの端点を持つ1つのプロトコルであり、nest-server と nuxt-extensions がそれぞれ1つの端点を所有しています。better-auth はその教訓を与えたケースです。両方のフレームワークが同じ方法でインポートするパッケージはすべて同様に扱います。

    両方ともそれを peer として宣言し、2つのマニフェストでバイト単位で同一の範囲で、狭い範囲(>=<既知の最低正常バージョン> <<次のマイナー>)とし、^ は使用しません。better-auth はMINORリリースで壊れるため、キャレットを使用すると1リリース後に同じ分割を招きます。現在の範囲はここからではなくマニフェストから読み取ってください — それは移動し、このスキルに書き込まれたバージョンは古くなるバージョンです。

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

    バンプするということは:nest-server と nuxt-extensions の両方で範囲を上げ、nest-server-starter と nuxt-base-starter の両方で新しいバージョンを固定し、4つすべてをリリースすることを意味します。決して半分だけ、たとえ「フロントエンドのブロックを解除するためだけ」であっても実行してはいけません。下限のみを上げることもバンプです — それはどのパッチが既知の正常バージョンかを示すものであり、2つのリポジトリ間で下限が一致しないことは、バージョン分割と同じ欠陥であり、1リリース早く発生します。

    下限は好みの問題ではありません:それは兄弟ピアも満たさなければなりません。 better-auth のようなパッケージには、コンパニオン(@better-auth/passkey、@better-auth/core)が同梱されており、それらは順にそのバージョンをピア要求します。コンパニオンが要求するバージョン未満の下限は、実際にはインストールできない組み合わせを許容します — >=1.7.0 は、better-auth 1.7.0 と passkey 1.7.1 の組み合わせを許可しましたが、passkey 自体はそれを拒否します(^1.7.1)。範囲は一般的には間違っていませんでした。ただ1つの無効なクロスコンビネーションを許可しただけであり、それはまさにどちらのリポジトリでもどのインストールでも決して発生しない種類のものです。下限は直感ではなく、コンパニオンのマニフェストから導出します。

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

    nuxt-extensions はこれを test/peer-dependency-ranges.test.ts で機械的に検証します(下限とコンパニオンの要件、およびすべての範囲を実際にテストされた devDependency と比較)。ピア範囲にコンパニオンがいる場合は、どこでもコピーする価値があります。

    分割のコスト(計測値):nest-server は better-auth 1.6.26 をハード依存関係として固定していた一方、nuxt-extensions はピアとして宣言していたため、アプリは 1.7.1 に移行し、API は追随できませんでした。1.7 は twoFactor.enable に method を運ぶ判別された結果を提供しますが、1.6.26 はそれを決して送信しません — すべてのフルスタックプロジェクトで全ての2FAアクティベーションが失敗し、一般的なクライアントエラーが発生し、サーバーログには異常はありませんでした。両方のリポジトリの check は常に成功していました:それぞれは内部的に一貫しており、組み立てられたワークスペースだけが両方の半分を持っていました。

    現在は3つのガードがそれをキャッチしますが、それらのどれもこのルールを置き換えるものではありません — これらは間違いをキャッチし、ルールはそれを防ぎます。

    • マニフェストがマージされるとき(lt CLI hoist-workspace-pnpm-config.ts、1.45.0以降)。hoist は最後書き込み優先であり、これはルート対サブには正しいが、兄弟間では罠となります。報告された問題:同じ実行で2つのサブプロジェクトが1つのキーを異なる値に設定した場合;増分ケース(add-api の後に add-app を実行し、以前の実行が既にhoistしてそのソースを空にしていた場合);およびリポジトリが package.json#pnpm と自身の pnpm-workspace.yaml で矛盾する場合。allowBuilds は報告されるだけでなく deny-wins でマージ されます — 警告は、1つのプロジェクトが明示的に拒否したインストールスクリプトを停止しません。overrides は報告のみのままです。なぜなら、バージョンに対して安全な方向がないためです。

    • 組み立てられたワークスペース内(lt-monorepo/scripts/check-workspace-consistency.mjs、3.10.0以降)。APIとアプリがワイヤークリティカルなパッケージを異なる方法で解決した場合、2つのフレームワークが異なるピア範囲を約束した場合、またはメンバーがパッケージをインストールしているがどこにも固定していない場合に失敗します — autoInstallPeers はデフォルトでtrueであるため、固定されていないピアは今日は一致しても、次のインストールで自由にドリフトできます。

    • 動作面(nuxt-base-starter/.github/workflows/test.yml、ジョブ e2e-auth、2.22.3以降成功)。MongoDB と nest-server-starter を起動し、実際のAPIに対して認証スイートを実行します。バージョンの差分ではなく、壊れたコントラクトを確認する唯一のレイヤーです — 他のレイヤーは宣言を比較しますが、宣言は分割中も常に成功していました。

      最初の実行で見つかった、見落としがちな2つのこと:テンプレートの依存関係は個別にインストールする必要があります(独自のロックファイルがあり、チェックチェーンは cross-env で始まります — これは自身の devDependency の1つです)。また、空のデータベースはすべての訪問者を /auth/setup にルーティングするため、スイートを実行する前に、最初の管理者を POST /system-setup/init で作成する必要があります。

    スモークテストはエンドツーエンドのゲートです:実際のフルスタックプロジェクトを構築するため、ワイヤ分割がバージョンの差分ではなくフローの失敗として現れる唯一の場所です。

  • メンテナンス後、バージョンバンプ前のそのリポジトリのリリース差分に対して /lt-dev:review が実行されるまで、何も公開されません(/lt-dev:review --base=<最後のリリースタグ>。未コミットファイルと追跡対象外ファイルを含む)。タグは origin/main から取得します:git describe --tags --abbrev=0 origin/main。リリースタグはすべてのベースリポジトリの main ブランチにあり、nest-server のタグは develop には決して含まれないマージコミットであるため、HEAD からのルックアップはリリースより古いタグを返します(2026-10-27 に nest-server develop で計測:11.33.1 の代わりに 12.0.0、14ファイルの代わりに851ファイルのレビュー)。チェーンのすべてのリポジトリは、自身の差分でそれを通過します。レビューで修正できなかった問題は、そのリポジトリのリリースとそれに続くすべてのリポジトリを停止します。Kai によって2026-10-21に決定されたため、自動化されたリリースチェーンが誰もレビューしていないコードを公開することは決してありません。

  • 変更なし → リリースなし。 リリースをスキップする唯一のケースは、リポジトリで本当に何も変更されていない場合です(ワーキングツリーがクリーンで、最後にリリースされたバージョン以降コミットがない)。変更を一切含まないバージョンを作成してはいけません。依存関係のバンプ、コード、スクリプト、ロックファイル、ツーリングの固定など、リポジトリの実際の変更はすべて新しいバージョンを正当化します。変更が「リリースに値する」かどうかを推測してはいけません。変更されていないリポジトリは「既に最新 — リリースなし」と報告され、スキップされます。唯一の例外は nest-server-starter です:そのバージョンは nest-server のバージョンとのみ連動するため、自身の変更はリリースなしでコミットおよびプッシュされ、次のリリースで出荷されます(recipes.md、nest-server-starter)。 参照するのは 公開されたアーティファクト です:npmパッケージの場合、tarballに到達できないコミット(package.json の files セット外 — 例:.claude/agent-memory/**、CI設定)は、それ自体ではリリースをトリガーしません。不明な場合は npm pack --dry-run で確認してください。そのようなコミットは、単に次の実際のリリースに便乗します。テンプレートの場合、アーティファクトはリポジトリ自体であるため、すべてのコミットがカウントされます。

  • プッシュチャネル: スクリプトに問い合わせてください。スクリプトが機能的に決定します。

    bash "${CLAUDE_PLUGIN_ROOT}/scripts/check-push-channel.sh" [<repo-root>]   # リポジトリ内では省略。決して "$(pwd)" を渡さないでください。
    # -> ssh<TAB>github.com<TAB>認証済み:Hi kaihaase! …
    # -> https<TAB>github.com<TAB>SSH認証なし(…)
    

    https の場合、HTTPS経由でプッシュ: git -c credential.helper='!gh auth git-credential' push https://github.com/lenneTech/<repo>.git <branch>。 gh release create はどちらの場合も影響を受けません。

    権限の問題のように見えるプッシュ障害が発生した場合にチェックを実行してください。 2026-09-08 に nest-server-starter で計測:git push origin main が Please make sure you have the correct access rights and the repository exists で失敗した一方、SSH経由の nest-server へのプッシュは同じ時間帯に成功しました。アカウント、コラボレーターステータス、リモートURLに問題はありませんでした。github.com へのSSHがそのパスでのみダウンしており、チェックは https<TAB>github.com<TAB>no response fr を示していました。

Individual skills in this repo

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

関連スキル