monorepo-setup-worktrees について
Editframe モノレポで並行開発するためのワークツリー管理スキルです。統合 CLI で範囲別の Docker 環境やブランチを管理し、ガード機能により main ワークツリーを main に保ちます。
主な機能
- 01elements、web、render の範囲で環境作成
- 02ワークツリーのライフサイクルと健全性確認
- 03Docker コンテナの停止、再開、削除
- 04main の同期とマージ済みブランチの整理
- 05レンダリングのスモークテスト実行
活用シーン
- 01複数の機能ブランチに分離環境を用意
- 02必要に応じてワークツリーの範囲を拡張
- 03マージ後に main の変更を作業ブランチへ反映
- 04マージ前にレンダリングパイプラインの変更を検証
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ editframe/ skills --skill monorepo-setup-worktreesインストール後、Claude Code で/monorepo-setup-worktreesを入力して読み込まれたか確認します。
詳細
モノレポのワークツリーシステム
並行する開発ストリームをスコープ単位で分離するワークツリーです。各ワークツリーには、分離された Docker サービス、データベース、ドメインが割り当てられます。
スコープ
| スコープ | サービス | コンテナ | 作成時間 |
|---|---|---|---|
elements | Elements ランナー + dev-projects のみ | 2 | 約28秒 |
web | Elements + telecine コア(web、hasura、valkey、maintenance) | 8 | 約1分30秒 |
render | Elements + telecine コア + レンダリングパイプライン(ワーカー、スケジューラー) | 約22 | 約2分30秒 |
アップグレードパス:elements → web → render。ダウングレードはサポートされていません。
ワークツリーの管理
すべてのワークツリー操作には、統合 CLI scripts/worktree <command> を使用します。
worktree create <branch> [scope] # Create new worktree (default: web)
worktree list # List all worktrees
worktree status [branch] # Health check
worktree pause <branch> # Stop containers
worktree resume <branch> # Start containers
worktree remove <branch> [--force] # Full cleanup
worktree upgrade <branch> <scope> # Escalate scope (elements→web→render)
worktree merge <branch> # Merge branch into main (feature → main)
worktree pull # Fetch upstream, update local main, sync main → all worktrees
worktree prune [--dry-run] # Remove worktrees whose branches are fully merged into main
worktree smoke <branch> # One-shot render verification
worktree logs [branch] [options] # View logs
worktree doctor [branch] [--skills] # Diagnose issues
worktree editor-deps [branch] # Install host-side node_modules for editor tooling
worktree deps [--workspace=...] # Show dependency graph
アーキテクチャ
リポジトリのレイアウト
~/Editframe/
monorepo -> worktrees/main/monorepo (symlink for convenience)
worktrees/
main/
.worktree-scope # scope for main (e.g. "render")
monorepo/ # primary monorepo checkout [main]
telecine -> ../telecine # symlink
elements -> ../elements # symlink
telecine/ # primary telecine clone [main]
elements/ # primary elements clone [main]
<branch>/
.worktree-scope # scope for this branch
monorepo/ # monorepo worktree [branch]
telecine/ # telecine git worktree [branch]
elements/ # elements git worktree [branch]
メインワークツリー(worktrees/main/)は、常に main ブランチにある必要があります。 メインワークツリーのディレクトリでは、git checkout、git switch、その他のブランチ切り替えコマンドを実行しないでください。すべての機能開発は、worktree create で作成した専用のブランチワークツリーで行います。LLM エージェントは、通常の単一チェックアウトのリポジトリのようにメインワークツリーを扱って git checkout <branch> を直接実行したり、事前のチェックアウトが必要なマージ方法を使ったりして、このルールに違反する可能性が最も高くなります。
scripts/worktree.ts は、次の2つの厳格なガードによってこのルールを適用しています。削除したり緩和したりしないでください。
cmdCreateは、新しいワークツリーを作成する前にメインワークツリーがmainにあることを確認し、新しいブランチは常にmainを起点に作成します。cmdMergeは、各リポジトリがすでにmainにあることを確認してから、チェックアウトせずにマージします。メインワークツリーでgit checkoutを呼び出すことはありません。
~/Editframe/monorepo は利便性のためのシンボリックリンクであり、すべてのワークツリーコマンドの起点です。
エージェントとしてブランチワークツリーで作業する
エージェントの作業ディレクトリは起動時に固定されます。通常は worktrees/main/monorepo です。永続的な cd はありません。 ブランチワークツリーを作成または特定した後は、すべてのファイル編集、git コマンド、スクリプト呼び出しで、エージェントの現在の作業ディレクトリからの相対パスではなく、ブランチワークツリーを起点とする絶対パスを使用する必要があります。
ブランチが my-feature の場合、ワークツリーのルートは ~/Editframe/worktrees/my-feature/monorepo/ です。具体的なルールは次のとおりです。
- ファイルの読み取り/編集:
~/Editframe/worktrees/my-feature/monorepo/配下の絶対パスを使用します - Git 操作:
git -C ~/Editframe/worktrees/my-feature/monorepo <command>を使うか、ツール呼び出しのworkdirパラメーターを使用します - Elements スクリプト:
~/Editframe/worktrees/my-feature/elements/scripts/<script> - Telecine スクリプト:
~/Editframe/worktrees/my-feature/telecine/scripts/<script> - 禁止事項:ブランチ作業では相対パスや
worktrees/main/配下のパスを使用しないでください
既存ブランチのルートを調べるには、git worktree list | grep my-feature を実行します。
スクリプト内の EDITFRAME_DIR は常に $(dirname $(dirname $(dirname $(git rev-parse --show-toplevel)))) です。monorepo のチェックアウトパスから3階層上を指します。
共有インフラストラクチャ
editframe-postgres— 共有 PostgreSQL は1つで、各ワークツリーに独自のデータベース(telecine-<branch>)が割り当てられますeditframe-traefik— 共有リバースプロキシで、Hostヘッダー(<branch>.localhost)に基づいてルーティングしますtelecine-runner/elements-runner— 共有 Docker イメージ(ワークツリーごとには再ビルドされません)
データベーステンプレート
telecine-template は telecine-main(304件のマイグレーションとシードデータを含み、クローンに約0.6秒)から複製されます。メインで telecine/scripts/start がマイグレーションを実行すると、テンプレートは自動更新されます。
ポートオフセット
ワークツリーのサービスでは、cksum に基づくポートオフセット(200スロット、間隔は100)を使用するため、Postico などのホストツールから接続できます。メインワークツリーでは標準ポートを使用します。
設定スクリプト
telecine/scripts/worktree-config—WORKTREE_ID、WORKTREE_DATABASE、WORKTREE_DOMAIN、WORKTREE_DOCKER_PROJECT_NAME、ポート変数をエクスポートしますelements/scripts/worktree-config— elements 用の同じ形式の設定です- monorepo ワークツリーのルートにある
.worktree-scopeファイルが、現在のスコープを記録します
Docker Compose プロファイル
- プロファイルなし = コアサービス(常に起動):runner、web、valkey、graphql-engine、data-connector-agent、maintenance
renderプロファイル:すべてのワーカーサービス、scheduler-go、jit-transcodingdevプロファイル:tracing、otel-viewer、mailhog、playwrighttelecine/scripts/startは.worktree-scopeを読み込み、COMPOSE_PROFILESを設定します
サービスの起動順序
runner を起動し、アプリケーションコードを実行する他のサービス(web、dev-projects、ワーカー)を起動する前に npm install を完了する必要があります。作成スクリプトとアップグレードスクリプトがこれを処理します:up -d runner → npm install → up -d(残りのサービス)。
main を worktree に同期する
PR が main にマージされた後(頻繁に発生します)、main の worktree から worktree pull を実行します:
worktree pull
次の 3 つの処理が順番に行われます:
- monorepo、telecine、elements の upstream リモートからフェッチします
- telecine と elements のローカル main に
origin/mainをマージします(競合がなければ早送りマージします) - ローカル main を、アクティブなすべての worktree ブランチにマージします
package.json、package-lock.json、VERSION.ts の競合は、main のバージョンを採用して自動的に解決されます。それ以外の競合は報告され、スキップされます。該当する worktree には手を加えず、手動で解決できる状態にします。
3 つのリポジトリすべてでブランチが main に完全にマージされた worktree をクリーンアップするには:
worktree prune # remove all fully-merged worktrees
worktree prune --dry-run # preview what would be removed
prune は削除を始める前に 3 つすべてのリポジトリを確認します。ブランチが monorepo、telecine、elements のすべてで同時に main の祖先である場合にのみ、worktree はプルーニングされます。
Worktree のライフサイクル
create (elements, 28s) → upgrade (web, 63s) → upgrade (render)
↓ ↓
pause/resume pause/resume
↓
remove
開発サーバーの URL
elements の dev-projects Vite サーバーでは root: elements/dev-projects/ を使用します。ファイルはルートパスで配信され、/dev-projects/ の下ではありません。
video.html→http://<branch>.localhost:4321/video.htmlcanvas-demo.html→http://<branch>.localhost:4321/canvas-demo.html
URL パスに dev-projects/ を含めないでください。
worktree 内の dev-projects
elements/dev-projects/ は gitignore 対象です。worktree には、完全な asset/src ツリーではなく、コミット済みのスタブだけが存在します。
worktree create は、main の dev-projects を参照するように、worktree の elements/.env に DEV_PROJECTS_HOST を設定します。docker-compose.yaml の dev-projects サービスはこのパスを /packages/dev-projects にマウントするため、worktree の開発サーバーでは常に main の完全なファイルツリーを利用できます。
スモークテスト
worktree smoke <branch> は、1 回限りのレンダリング検証です。永続的なスコープではありません。レンダリングパイプラインの変更をマージする前のゲートとして使用してください。
webまたはrenderスコープが必要です(elementsではエラーになります)- スコープが
webの場合:render プロファイルのサービスを一時的に起動し、終了時にサービスを停止するクリーンアップトラップを登録します - スコープが
renderの場合:すでに起動しているサービスに対して実行し、ライフサイクル管理は行いません - runner コンテナ内で
EF_HOST=http://web:3000と worktree のEF_TOKENを使用してtelecine/scripts/smoke-test.tsを実行します - レンダリング結果を目視確認するためのダッシュボード URL(
http://<branch>.localhost:3000)を表示します - render サービスを起動した場合は、サービスを停止する前に Enter キーを押すよう促します
レンダリング開発のワークフロー:web スコープを維持し、ユニットテストを直接実行します。レンダリングスタック全体を終日稼働させるのではなく、マージゲートとして worktree smoke を使用します。
scheduler-go は docker-compose で管理されない、事前ビルド済みの Go イメージです。worktree smoke は初回実行時に自動でビルドします。scripts/build-runner-images でもビルドされます。
エディターツール
Docker コンテナでは node_modules に名前付きボリュームを使用しており、ホストのファイルシステムからは見えません。TypeScript の型と JSX の組み込み要素を解決するには、ホスト側のエディター(VS Code、Cursor など)にも独自の node_modules が必要です。
worktree create は npm install --ignore-scripts を使って、ホスト側の依存関係を自動的にインストールします。ホスト側の型定義が不足している既存の worktree では、worktree editor-deps <branch> を実行してください。worktree doctor はホスト側の型定義の不足を検出して報告します。
トラブルシューティング
- ポートの競合:2 つのブランチが同じオフセットにハッシュされました。cksum と 200 個のスロットを使用するため可能性は非常に低いですが、発生することがあります。片方のワークツリーを削除して、再作成してください。
- 孤立したコンテナ:
worktree doctorは孤立したプロジェクト(対応する Git ワークツリーがないコンテナ)を検出し、削除に使用する正確なdocker rm -fコマンドを表示します。 - 作成の一部失敗:
worktree createが途中で失敗した場合、ワークツリーのディレクトリは作成されていますが、不完全な状態です。再試行する前に、worktree remove --force <branch>を実行してください。 - 古いテンプレート:現在のメイン DB の状態を反映するには、
scripts/update-template-dbを実行してください。