Synchronisation amont EGM
Apporter les modifications de marcus-darden/egm dans ce port sans perdre les renommages, les adaptations Cursor ni les fichiers propres au port. Lisez d'abord le AGENTS.md à la racine du dépôt : c'est le livre de règles qu'applique cette compétence. Cette compétence se trouve dans .cursor/skills/, elle est donc locale au projet ; install.sh ne l'installe jamais.
Invoquer avec /egm-sync-upstream [--dry-run] [upstream-ref]. upstream-ref prend par défaut la branche main upstream. Avec --dry-run, effectuez les étapes 1 à 4 et imprimez le plan ; ne modifiez rien.
Règles strictes
- Ne jamais pousser sur
main. Tout le travail se fait sursync/upstream-<sha_court>; Juan fusionne la PR. - Ne jamais écraser un fichier propre au port (liste dans
AGENTS.md). Si upstream a modifié quelque chose que ces fichiers reflètent (par exemple la section d'installation du README upstream), décrivez-le dans le rapport plutôt. - Ne pas deviner. Les nouvelles compétences ou agents upstream, les fichiers upstream supprimés, les fichiers upstream renommés et les conflits de fusion sont signalés à Juan avec les chemins exacts, sans être résolus en inventant un nom ou en choisissant un camp.
- Conserver l'attribution.
LICENSEconserve les deux lignes de copyright ;UPSTREAM_COMMITn'est déplacé que lorsque la branche contient effectivement les modifications upstream.
Aides
<dossier-comp> est le dossier contenant ce fichier.
python3 <dossier-comp>/scripts/port_names.py chemin <chemin-upstream>...mappe les chemins upstream vers les chemins du port et indique quand un chemin est propre au port, non porté, ou nouveau.python3 <dossier-comp>/scripts/port_names.py fusionner <clone> <ancien> <nouveau> <chemin-upstream> [--write]effectue une fusion à trois points d'une modification d'un fichier upstream dans son fichier du port (la base et la leur sont d'abord réécrites avec les noms du port, la nôtre est le fichier du port), afin que les adaptations Cursor sur les lignes non touchées survivent. Code de sortie 0 : propre, 1 : marqueurs de conflit laissés, 3 : rien à faire (propre au port, non porté, ou nouveau).python3 <dossier-comp>/scripts/port_names.py reécrire <fichier>/vérifier <fichier>...réécrit les noms dans le texte, ou liste les anciens noms avec slash restants.bash <dossier-comp>/scripts/check_port.shexécute toutes les vérifications du port (étape 7).
Workflow
Progression sync EGM :
- [ ] Étape 1 : arbre de travail propre, sur une branche main à jour
- [ ] Étape 2 : upstream cloné dans un répertoire temporaire ; ancien = UPSTREAM_COMMIT, nouveau = HEAD upstream
- [ ] Étape 3 : entrées du CHANGELOG depuis l'ancien lues ; fichiers modifiés listés avec leur statut
- [ ] Étape 4 : chaque fichier modifié mappé et classifié (fusion / signalement / ignoré)
- [ ] Étape 5 : branche sync/upstream-<sha_court> créée ; fusions appliquées ; adaptations revérifiées
- [ ] Étape 6 : UPSTREAM_COMMIT mis à jour
- [ ] Étape 7 : check_port.sh réussi
- [ ] Étape 8 : SYNC-REPORT.md rédigé
- [ ] Étape 9 : branche poussée ; PR ouverte avec gh ; Juan informé
Étape 1 : Départ propre
git status --porcelain doit être vide et la branche courante main, à jour avec origin/main (git fetch origin && git status -sb). Sinon, arrêtez-vous et dites à Juan ce qui est sale. Ne stash pas son travail.
Étape 2 : Récupérer upstream
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})"
Si ancien == nouveau, signalez "upstream n'a pas de nouveau commit depuis " et arrêtez-vous (pas de branche, pas de PR). Si ancien n'est pas un ancêtre de nouveau (git -C "$tmp/upstream" merge-base --is-ancestor $ancien $nouveau), upstream a réécrit l'historique : arrêtez-vous et signalez-le.
Étape 3 : Lire ce qui a changé
git -C "$tmp/upstream" log --oneline $ancien..$nouveaugit -C "$tmp/upstream" diff --name-status -M $ancien $nouveau- Les nouvelles entrées du
CHANGELOG.md(tags après celui contenantancien). Le CHANGELOG explique pourquoi ; citez les lignes pertinentes dans le rapport.
Étape 4 : Mapper et classifier chaque fichier
Exécutez port_names.py chemin sur chaque chemin upstream modifié, puis placez chacun dans un seau :
| Statut upstream et mapping | Seau |
|---|---|
| M, mappe vers un fichier de port existant | fusion |
A, mappe dans un dossier de compétence connu (par exemple une nouvelle ressource dans skills/goldfish/) | fusion (crée le fichier) |
| A, nouvelle compétence, agent ou walkthrough (note "NOUVEAU") | signaler : Juan choisit le nom egm- et s'il faut le porter |
| D (supprimé upstream) | signaler : ne pas supprimer le fichier du port |
| R (renommé upstream) | signaler : montrer les ancien et nouveau chemins ainsi que le chemin du port |
| note propre au port ou non porté | ignorer (décrire la modification si elle importe, p. ex. texte d'installation du README) |
LICENSE | fusion, puis confirmer que les deux lignes de copyright restent |
Avec --dry-run, imprimez ce tableau et la liste des commits, puis arrêtez-vous.
Étape 5 : Appliquer sur une branche
git switch -c "sync/upstream-${new:0:7}"
python3 <dossier-comp>/scripts/port_names.py fusionner "$tmp/upstream" $old $new <chemin-upstream> --write
Exécutez la fusion une fois par fichier fusion. En cas de code de sortie 1, laissez les marqueurs de conflit hors du commit : restaurez le fichier (git checkout -- <chemin-port>), et enregistrez le bloc de conflit dans le rapport pour Juan. Après la fusion, relisez chaque fichier touché pour les adaptations Cursor listées dans AGENTS.md (texte de spawn Task-tool, readonly: true dans les agents, AGENTS.md à côté de CLAUDE.md, les reviewers ignorant AGENTS.md et .cursor/rules/, /review pas /code-review, la ligne Cursor dans runtimes.md). Si upstream a ajouté un nouvel endroit qui en nécessite une (par exemple une nouvelle recherche CLAUDE.md, une nouvelle ligne tools: dans un agent, une nouvelle instruction de spawn propre à Claude), appliquez la même adaptation et listez-la sous "adapté". Commitez par groupes logiques avec des messages qui citent les commits upstream.
Étape 6 : Déplacer le pointeur
Écrivez nouveau dans UPSTREAM_COMMIT uniquement si chaque fichier fusion a été fusionné proprement ou si son conflit est enregistré. Commitez-le en dernier.
Étape 7 : Vérifier
bash <dossier-comp>/scripts/check_port.sh. Il vérifie le nom égal au dossier, évalue le JSON, check_gate.py (BLOQUÉ puis OK), les anciens noms avec slash restants, et une installation test dans un répertoire temporaire (qui ne doit pas contenir cette compétence). Corrigez les échecs causés par la fusion ; tout le reste va dans le rapport.
Étape 8 : SYNC-REPORT.md
Écrivez SYNC-REPORT.md à la racine du dépôt sur la branche, et utilisez le même texte que le corps de la PR :
# Synchronisation upstream : <ancien7>..<nouveau7>
Commits upstream : <liste>
CHANGELOG : <lignes citées>
## Appliqué
- <chemin-port> <- <chemin-upstream> : <une ligne>
## Adapté pour Cursor
- <chemin-port> : <quelle adaptation et pourquoi>
## Ignoré
- <chemin-upstream> : <propre au port | non porté>, <ce qui a changé, si cela importe>
## Signalé pour Juan
- <nouvelle compétence/agent, suppression, renommage, conflit> : <chemins, le bloc, la question>
## Vérifications
<résumé de check_port.sh>
## Questions ouvertes
- <...>
Étape 9 : Pousser et ouvrir la 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
Dites à Juan l'URL de la PR, les comptes (appliqué, adapté, ignoré, signalé) et les éléments signalés. Ne fusionnez pas la PR. Supprimez le clone temporaire.