EGM 上流同期
marcus-darden/egm の変更を、このポートのリネーム、Cursor 適応、ポート独自ファイルを失わずに取り込みます。リポジトリルートの AGENTS.md を最初に読んでください。このスキルが適用するルールブックです。このスキルは .cursor/skills/ に置かれプロジェクトローカルです。install.sh ではインストールされません。
/egm-sync-upstream [--dry-run] [upstream-ref] として呼び出します。upstream-ref のデフォルトは上流の main です。--dry-run の場合、ステップ 1~4 を実行して計画を表示し、何も変更しません。
厳格ルール
mainにプッシュしないこと。 すべての作業はsync/upstream-<shortsha>ブランチで行い、Juan が PR をマージします。- ポート独自ファイルを上書きしないこと(一覧は
AGENTS.mdにあります)。上流がそれらのファイルがミラーしているものを変更した場合(例: 上流 README のインストールセクション)、レポートに説明を記載します。 - 推測しないこと。 新しい上流スキルやエージェント、削除された上流ファイル、名前が変更された上流ファイル、マージコンフリクトは、正確なパスとともに Juan にフラグを立てます。名前を発明したり片方を選択したりして解決しません。
- 帰属を維持すること。
LICENSEは両方の著作権表示を保持します。UPSTREAM_COMMITはブランチが実際に上流の変更を含んでいる場合のみ更新します。
ヘルパー
<skill-dir> はこのファイルがあるフォルダです。
python3 <skill-dir>/scripts/port_names.py path <upstream-path>...: 上流パスをポートパスにマッピングし、パスがポート独自、未移植、新規のいずれかを表示します。python3 <skill-dir>/scripts/port_names.py merge <clone> <old> <new> <upstream-path> [--write]: 1 つの上流ファイル変更をポートファイルに 3-way マージします(ベースと theirs は最初にポート名に書き換えられ、ours はポートファイルです)。これにより、変更されていない行の Cursor 適応が維持されます。終了コード 0: 正常、1: コンフリクトマーカーが残存、3: 何もする必要がない(ポート独自、未移植、または新規)。python3 <skill-dir>/scripts/port_names.py rewrite <file>/check <file>...: テキスト内の名前を書き換えるか、残存する古いスラッシュ名を一覧表示します。bash <skill-dir>/scripts/check_port.sh: すべてのポートチェックを実行します(ステップ 7)。
ワークフロー
EGM 同期の進捗:
- [ ] ステップ 1: ワーキングツリーがクリーンで、最新の main ブランチ上
- [ ] ステップ 2: 上流を一時ディレクトリにクローン、old = UPSTREAM_COMMIT、new = 上流 HEAD
- [ ] ステップ 3: old 以降の CHANGELOG エントリを読み、変更されたファイルをステータス付きで一覧表示
- [ ] ステップ 4: 変更された各ファイルをマッピングし分類(マージ / フラグ / スキップ)
- [ ] ステップ 5: ブランチ sync/upstream-<shortsha> を作成、マージを適用、適応を再チェック
- [ ] ステップ 6: UPSTREAM_COMMIT を更新
- [ ] ステップ 7: check_port.sh が成功
- [ ] ステップ 8: SYNC-REPORT.md を作成
- [ ] ステップ 9: ブランチをプッシュ、gh で PR を作成、Juan に通知
ステップ 1: クリーンな開始
git status --porcelain が空で、カレントブランチが main であり、origin/main と同期していること(git fetch origin && git status -sb)。そうでない場合は停止し、何がダーティかを Juan に伝えます。彼の作業を stash しないでください。
ステップ 2: 上流を取得
tmp="$(mktemp -d)"
git clone --quiet https://github.com/marcus-darden/egm.git "$tmp/upstream"
old="$(cat UPSTREAM_COMMIT)"; new="$(git -C "$tmp/upstream" rev-parse ${REF:-HEAD})"
old == new の場合、「上流に 以降の新しいコミットはありません」と報告して停止します(ブランチも PR も作成しません)。old が new の祖先でない場合(git -C "$tmp/upstream" merge-base --is-ancestor $old $new)、上流が履歴を書き換えています。停止してフラグを立てます。
ステップ 3: 変更内容を読む
git -C "$tmp/upstream" log --oneline $old..$newgit -C "$tmp/upstream" diff --name-status -M $old $new- 新しい
CHANGELOG.mdエントリ(oldを含むタグより後のタグ)。CHANGELOG は なぜ を説明します。関連する行をレポートに引用します。
ステップ 4: 各ファイルをマッピングし分類
変更された各上流パスに対して port_names.py path を実行し、各ファイルを以下のバケットに分類します。
| 上流ステータスとマッピング | バケット |
|---|---|
| M、既存のポートファイルにマップ | マージ |
A、既知のスキルフォルダにマップ(例: skills/goldfish/ の新しいアセット) | マージ(ファイルを作成) |
| A、新しいスキル、エージェント、またはウォークスルー(「新規」注記) | フラグ: Juan が egm- 名前と移植するかどうかを判断 |
| D(上流で削除) | フラグ: ポートファイルを削除しない |
| R(上流で名前変更) | フラグ: 新旧パスとポートパスを表示 |
| ポート独自または未移植の注記 | スキップ(重要な変更がある場合、例: README インストールテキストなどは説明) |
LICENSE | マージ、その後両方の著作権表示が残っていることを確認 |
--dry-run の場合、このテーブルとコミットリストを表示して停止します。
ステップ 5: ブランチに適用
git switch -c "sync/upstream-${new:0:7}"
python3 <skill-dir>/scripts/port_names.py merge "$tmp/upstream" $old $new <upstream-path> --write
マージ ファイルごとにマージを 1 回実行します。終了コード 1 の場合、コンフリクトマーカーをコミットから除外します。ファイルを復元し(git checkout -- <port-path>)、コンフリクトハンクを Juan 向けのレポートに記録します。マージ後、AGENTS.md にリストされている Cursor 適応(タスクツール起動文、エージェント内の readonly: true、CLAUDE.md と並ぶ AGENTS.md、レビュワーが AGENTS.md と .cursor/rules/ を無視すること、/review ではなく /code-review、runtimes.md の Cursor 行)について、タッチした各ファイルを再読み取りします。上流が新しい場所を追加した場合(例: 新しい CLAUDE.md 参照、エージェントの新しい tools: 行、新しい Claude 専用起動指示)、同じ適応を適用し「適応済み」にリストします。論理グループごとにコミットし、メッセージには上流コミットを引用します。
ステップ 6: ポインタを移動
すべての マージ ファイルが正常にマージされたか、そのコンフリクトが記録されている場合のみ、new を UPSTREAM_COMMIT に書き込みます。最後にコミットします。
ステップ 7: チェック
bash <skill-dir>/scripts/check_port.sh を実行します。名前とフォルダの一致、JSON の評価、check_gate.py(BLOCKED の後に GO)、残存する古いスラッシュ名、一時ディレクトリへのテストインストール(このスキルを含まないこと)をチェックします。マージが原因の失敗は修正し、その他はレポートに記載します。
ステップ 8: SYNC-REPORT.md
ブランチ上のリポジトリルートに SYNC-REPORT.md を作成し、PR の本文と同じテキストを使用します。
# 上流同期: <old7>..<new7>
上流コミット: <リスト>
CHANGELOG: <引用行>
## 適用済み
- <ポートパス> <- <上流パス>: <1行>
## Cursor 向けに適応
- <ポートパス>: <どの適応と理由>
## スキップ
- <上流パス>: <ポート独自 | 未移植>, <変更内容(重要な場合)>
## Juan にフラグ
- <新しいスキル/エージェント、削除、名前変更、コンフリクト>: <パス、ハンク、質問>
## チェック
<check_port.sh のサマリー>
## 未解決の質問
- <...>
ステップ 9: プッシュして PR を開く
git push -u origin "sync/upstream-${new:0:7}"
gh pr create --base main --head "sync/upstream-${new:0:7}" --title "Sync upstream marcus-darden/egm ${old:0:7}..${new:0:7}" --body-file SYNC-REPORT.md
Juan に PR の URL、件数(適用済み、適応済み、スキップ、フラグ)、およびフラグされた項目を伝えます。PR はマージしません。一時クローンを削除します。