yasyf/open-pr

Ouvrir une pull request qui semble avoir été écrite par les mainteneurs du dépôt — choisissez d'abord une profondeur : une voie express pour « ouvrir juste la PR » ou « juste livrer » oriente, écrit et expédie sans les passes de recherche, tandis que la voie complète s'oriente avec `ccx vcs lane` et `ccx vcs guidelines`, apprend le style maison à partir d'un échantillon filtré de PR récentes humaines fusionnées via une carte de style par dépôt mise en cache, calibre le registre par rapport à un profil vocal wlm local, exécute une passe de politesse et de conformité aux normes avec traitement issue-first sur les dépôts que l'utilisateur ne possède pas, écrit le titre, le corps et les messages de commit selon les conventions du dépôt, expédie via `ccx vcs ship`, et confie la surveillance des CI et commentaires de bots à un agent observateur de PR en arrière-plan. À utiliser lors de l'ouverture, de la soumission ou de la contribution d'une pull request, de la rédaction d'un titre ou d'un corps de PR, de la contribution d'un changement à un dépôt open-source, ou de l'expédition d'une branche sous forme de PR.

Qu'est-ce que open-pr ?

Cette compétence pour agents d'IA (comme Claude Code, Cursor, Codex) automatise la création de pull requests (PR) de haute qualité en imitant le style et les conventions d'un dépôt cible. Elle résout le problème de recherche qui précède la rédaction d'une PR : un relecteur juge en un coup d'œil si l'auteur connaît le dépôt, via la grammaire du titre, la structure du corps et les sujets des commits. La compétence propose deux modes : Express, qui saute la recherche approfondie pour les changements simples, et Full, qui réalise une étude complète du style maison via une carte de style mise en cache. Elle s'intègre avec `ccx vcs` pour gérer les lanes de développement (jj, git, gt), et supporte les dépôts que l'utilisateur ne possède pas avec des passes de politesse, de conformité et issue-first. La compétence écrit le titre et le corps dans des fichiers, pas en arguments shell, pour éviter les problèmes de syntaxe, puis les expédie avec `ccx vcs ship`. Enfin, elle lance un agent observateur de PR (`pr-watcher`) en arrière-plan pour surveiller les CI, les commentaires de bots et l'état de fusion, jusqu'à un verdict final.

Compatible avec✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/yasyf/cc-skills/tree/HEAD/plugins/open-pr/skills/open-pr

Installed? Explore more Recherche et analyse de données skills: affaan-m/uspto-database, affaan-m/scholar-evaluation, affaan-m/literature-review · View all 6 →

Demander à votre IA préférée

Ouvre une nouvelle conversation avec cette compétence d'agent déjà préchargée.

Documentation

Ouvrir une PR

Ouvrir une PR correctement est un problème de recherche avant d'être un problème git. Un relecteur décide dans le premier écran si l'auteur connaît le dépôt — la grammaire du titre, la forme du corps, les sujets des commits le signalent — donc le travail est : apprendre ce que les mainteneurs de ce dépôt écrivent, puis écrire cela.

Choisissez d'abord la profondeur

Express est pour « ouvrir juste la PR », « juste livrer », « faire entrer ça » — et pour tout changement assez petit pour que la recherche coûte plus que la relecture qu'elle économiserait. Orienter, écrire, expédier, confier la surveillance. Ignorer l'explorateur de style et sa carte, le calibrage vocal et la passerelle de prose. Ne demandez pas si l'express est souhaité : la formulation l'a déjà dit, et le confirmer est le délai que l'utilisateur voulait éviter.

ccx vcs lane --json
ccx vcs diff
ccx vcs ship --no-watch --pr-title-file "$TITLE" --pr-body-file "$BODY"

Le corps dit toujours ce qui a changé et pourquoi, dans le modèle du dépôt s'il en a un, et le titre correspond encore à la grammaire des dernières PR fusionnées — une lecture gh pr list --state merged --limit 5 --json title, pas une exploration. Express abandonne la recherche, jamais le corps : une PR sans corps est la seule chose qu'aucune lane n'expédie.

Complet est le reste de ce fichier, et il mérite son coût sur un dépôt que vous ne possédez pas, sur un changement dont un mainteneur doit être convaincu, ou la première fois que vous ouvrez une PR quelque part. Sur un dépôt étranger, les passes de conformité et de politesse ne sont pas optionnelles même en express — un invité qui les saute gaspille l'aller-retour du mainteneur, pas le sien.

S'orienter

Le chemin compte ici : trois commandes dont la sortie nommée est référencée par tout ce qui suit.

ccx vcs lane --json          # lane, branche, tronc, dirty, github.mine, PRs downstack et lesquelles manquent de corps
gh repo view --json isPrivate,owner,viewerPermission,pullRequestTemplates,nameWithOwner,defaultBranchRef
ccx vcs guidelines           # CONTRIBUTING, modèle PR, code de conduite, config issue — affiche le chemin de la carte

Puis ccx vcs diff pour le changement lui-même.

ccx vcs lane rapporte la lane — elle ne la choisit pas, et vous non plus. ccx vcs ship sélectionne jj, git ou gt au moment de l'expédition, et un dépôt que l'utilisateur ne contrôle pas tombe silencieusement de la lane gt, donc n'écrivez rien qui suppose une lane avant que ship n'en rapporte une. github.mine est le verdict de propriété ; le test derrière et tout ce qui dépend de mine : false vit dans reference/oss.md. Lisez la carte que ccx vcs guidelines a écrite, puis séparez les exigences strictes des préférences — reference/guidelines.md contient les indices, et les alternatives gh api pour un dépôt qui ne publie rien.

Apprendre le style maison

Le style maison vit dans une carte sur disque, explorée une fois par dépôt et mise en cache :

bash "${CLAUDE_PLUGIN_ROOT}/scripts/pr-cache.sh" status <owner/name>   # fresh | stale:<raison> | missing
bash "${CLAUDE_PLUGIN_ROOT}/scripts/pr-cache.sh" path <owner/name>     # affiche le répertoire cache

fresh n'a besoin d'aucune exploration — lisez la carte et passez à la suite. stale ou missing → déclenchez l'explorateur, une fois par dépôt par exécution :

Agent(subagent_type : "open-pr:pr-style-scout",
      prompt : "repo : <owner/name>\ncache : <dir>\nviewer : <gh login>")

L'explorateur échantillonne les PR fusionnées récentes, filtre les bots, les PR écrites par IA et — sur un dépôt étranger — celles du visionneur lui-même, et écrit la carte dans le répertoire cache. Il renvoie un chemin, un résumé court et une confiance — lisez la carte qu'il a écrite, pas sa narration.

La carte porte sa taille d'échantillon et une confiance par axe, car les filtres qui gardent l'échantillon humain le réduisent aussi. La grammaire du titre et la structure du corps sont des conventions — elles tiennent à toute taille d'échantillon. Le ton de réponse à la relecture et le registre de prose reposent sur moins de signaux : à confidence : low ils sont une tendance, pas une règle, et le modèle PR et les directives pèsent plus lourd. Une convention lue sur trois échantillons les décrit tous les trois. La disposition du cache, le schéma de la carte et la fraîcheur vivent dans reference/style-cache.md.

Calibrer la voix

Quand l'utilisateur a un profil wlm local, empruntez les parties de sa voix qui survivent au changement de format :

wlm profile list
wlm -p <profile> stylecard show    # -p vient avant la sous-commande et n'est pas optionnel

La carte wlm a été construite pour une prose de blog longue : la liste Jamais et le choix des mots se transfèrent entièrement, le ton à moitié, la longueur et les ouvertures pas du tout. Le tableau de transfert complet et le repli sans profil sont dans reference/voice.md. Là où la carte du dépôt et la carte vocale divergent, le dépôt gagne — vous êtes un invité dans son format.

Dépôts que vous ne contrôlez pas

github.mine : false change le registre et ajoute deux passes avant d'écrire (reference/oss.md) :

  • Le registre de politesse — direct sur le changement, déférent sur la décision : les chiffres portent les affirmations, le mainteneur garde les décisions qui sont les siennes.
  • Conformité aux normes — parcourez ccx vcs diff par rapport à la carte de directives et à la liste de contrôle : périmètre, style, tests, documentation, hygiène des commits, taille du diff par rapport à la norme des PR fusionnées du dépôt. Chaque manquement est une correction, ou une phrase dans le corps reconnaissant l'écart.
  • Issue-first — quand la carte de directives marque une issue comme une exigence stricte, cherchez avant d'ouvrir : gh issue list --repo <slug> --search "<keywords>" --state all. Pas de correspondance → rédigez l'issue, puis présentez le brouillon à l'utilisateur avec AskUserQuestion — ouvrir tel quel / éditer d'abord / lier une issue existante / ignorer l'exigence délibérément — et agissez selon son choix. Ouvrir une issue publie sous le nom de l'utilisateur sur le projet de quelqu'un d'autre ; la rédiger ne le fait pas.

Écrire

Le titre, le corps et les sujets de commit suivent la carte de style à la confiance déclarée ; le modèle PR, s'il existe, est le squelette du corps. Un nombre partout où un adjectif qualifierait autrement le changement : un relecteur vérifie « 40 ms de moins au démarrage à froid » et ignore « beaucoup plus rapide ».

Écrivez le corps et le titre dans des fichiers, jamais dans des arguments shell — un corps avec des backticks, $, ou une barrière de code ne survit pas intact à une ligne de commande, et un titre y est refusé pour moins (voir Expédier) :

BODY=$(mktemp)
TITLE=$(mktemp)

Le corps est de la prose, donc il passe la barrière de prose avant d'être expédié : slop-cop check "$BODY" --lang=markdown, en triant les drapeaux plutôt qu'en les acceptant tous.

Les messages de commit reçoivent le même traitement : la carte enregistre la grammaire des sujets de ce dépôt, sa longueur, et quels trailers les commits fusionnés de ce dépôt portent — correspondance avec ces trailers et aucun autre. Sur un dépôt dont l'historique n'a pas de Co-Authored-By : Claude ou Generated with Claude Code, un trailer annonçant l'outillage est la seule ligne qui fait passer une PR soignée pour automatisée, et les mainteneurs filtrent dessus ; sur un dépôt dont l'historique les porte, les garder est la convention.

Une pile par session

Un travail connexe d'une session va dans une pile chaînée, jamais des branches sœurs indépendantes du tronc — même si les diffs sont prouvablement disjoints. « Les fichiers ne se chevauchent pas » n'est pas une raison pour diviser : des sœurs effacent l'ordre de relecture qu'une chaîne énonce, et perdent la mécanique de milieu de pile — un restack porte un amendement à travers chaque branche au-dessus, alors que les sœurs rebasent seules chacune. Chaînez dans l'ordre des dépendances, ce qui consomme au-dessus de ce qu'il consomme ; une lane encore en vol va à la pointe, pour que les branches finies en dessous ne soient jamais rebasées sous son agitation. Mécanique dans reference/stack.md.

Une PR est une unité de travail de la taille d'une fonctionnalité. Les suivis, corrections et réponses aux relectures sont des commits sur la PR ouverte, jamais un enfant empilé. Expédiez-les avec ccx vcs ship, en ajoutant --amend pour les fondre dans son commit ou --tip-only quand seule la pointe d'une pile a changé. Empilez seulement quand un parent doit atterrir avant que d'autres travaux puissent continuer, ou quand la relecture a besoin de la division. Poussez à des points de contrôle cohérents, jamais par édition, car chaque poussée remplace la construction en cours et relance les CI et les bots de relecture. Poussez quand même dans l'heure, car l'origine est la sauvegarde.

Expédier

La combinaison de drapeaux est importante :

ccx vcs ship --no-watch --pr-title-file "$TITLE" --pr-body-file "$BODY"

Écrivez le titre dans un fichier d'une ligne à côté du fichier corps et passez --pr-title-file, jamais un --pr-title en ligne. Le bac à sable Bash d'un agent isolé dans un worktree refuse tout argument qui associe un guillemet au mot git ou à un nom de shell, comme GitHub's ... git, et un titre dans un fichier n'atteint jamais la ligne de commande. Ship prend le sujet du commit de ce titre et le corps du commit du corps de la PR, donc -m n'est nécessaire que pour un sujet qui diffère du titre.

--no-watch car la surveillance intégrée de ship bloque jusqu'à ce que CI conclue — juste au moment où vous attendez, mauvais quand la surveillance va être confiée. Ship possède la création-et-mise-à-jour de PR dans chaque lane : un gh pr create fait à la main à côté produit une PR que la lane gt ne peut pas réconcilier avec sa propre pile.

Sur une PR déjà ouverte, ship prévient et garde le titre et le corps qu'elle a, donc un amendement ne porte aucun drapeau, et une PR dont le texte doit changer prend --replace-pr-text.

Sur la lane gt, une soumission peut créer plusieurs PR, et chaque PR dans la soumission qui n'a pas encore de corps en reçoit un. --pr-title-file et --pr-body-file se répètent et sont cadrés par branche (--pr-body-file <branche>=<chemin> ; une valeur nue s'applique à la pointe) ; ccx vcs lane --json vous dit quelles PR downstack sont sans corps.

Un refus est une information, pas une nouvelle tentative : nothing to commit signifie qu'une expédition précédente a déjà atterri cela ; ship rejoue un needs_restack de gt lui-même. Quand ship refuse toujours parce qu'une branche est en dehors de son parent ou que le tronc a bougé, exécutez ccx vcs stack submit (ou passez le refus textuellement au propriétaire de la pile quand une autre lane la possède), puis relancez ship.

Ship rapporte la branche, le numéro et l'URL de la PR, et le sha de tête. La transmission a besoin des quatre.

Confier la surveillance

Résolvez ${CLAUDE_PLUGIN_ROOT} en son chemin absolu dans l'appelant au moment de la création et remplissez poll : avec la commande prête à exécuter. La variable est substituée dans le texte de cette compétence ; le sous-agent ne la reçoit pas. Passez la phrase après poll : textuellement pour que l'observateur puisse armer le script même si le harnais omet sa définition d'agent.

Agent(subagent_type : "open-pr:pr-watcher", run_in_background : true,
      name : "pr-watch-<num>",
      prompt : "pr : <num>\nurl : <url>\nrepo : <owner/name>\nhead : <sha>\n"
              "branch : <branche>\nlane : <gt|jj|git>\ncache : <dir>\nownership : <mine|foreign>\n"
              "poll : bash \"<chemin absolu plugin>/scripts/pr-poll.sh\" <owner/name> <num> <cache>/pr/<num>.json\n"
              "Exécutez PR_POLL_WINDOW=40 <poll : commande> seul comme Bash de premier plan avec timeout : 60000, relancez-le immédiatement sur DONE window-elapsed, et continuez d'appeler jusqu'à un verdict final : n'armez jamais un Monitor et ne mettez jamais l'appel en arrière-plan, car aucun ne réveille un sous-agent, ne l'enveloppez jamais dans une boucle, et ne substituez jamais une boucle gh pr checks/bk faite main, qui ne peut pas voir un atterrissage de file. Sur DONE ready-to-merge, SendMessage main avant toute autre chose.")

Après la création, vérifiez que le script de scrutation a écrit son fichier d'état :

bash "${CLAUDE_PLUGIN_ROOT}/scripts/pr-watch-armed.sh" "<cache>/pr/<num>.json"

Sur sortie 1, SendMessage à l'observateur la même ligne poll : et exécutez la vérification une deuxième fois. Si elle échoue à nouveau, signalez à l'utilisateur que la surveillance n'est pas armée. Une création d'agent seule ne prouve pas que le script tourne.

Un observateur par PR — un deuxième sur la même PR pousserait le premier. Chaque rapport sauf evicted termine la surveillance ; SendMessage par nom la reprend pour le prochain tour. Un message evicted : <raison> <détail> arrive en cours d'exécution et l'observateur continue de surveiller pour que l'appelant le remette en file par étiquette ou dans l'UI de Graphite. Poussez toute correction avant de remettre en file ; l'appelant décide quand remettre en file.

Après un rapport ready-to-merge : open-pr.on-ready

Un rapport ready-to-merge signifie que la PR est verte, fusionnable et approuvée : chaque vérification passée, chaque suite de vérifications GitHub Actions sur la tête s'est terminée, mergeable est vrai, l'état de la file a été lu proprement (jamais QUEUE unknown), et la PR n'est ni en file ni évincée sur sa tête actuelle. Aucun dernier avis du relecteur n'est CHANGES_REQUESTED, et REST mergeable_state n'est pas blocked (l'état pour une approbation requise manquante). Un rapport ready-to-merge downstack #<n> est une PR empilée attendant la PR downstack # (y compris quand la vérification de fusionnabilité de Graphite est la seule vérification inachevée sur une pile Graphite héritée). La PR elle-même est prête, mais elle n'atterrit qu'avec sa downstack : nommez # dans la question et mettez la pile en file, jamais cette PR seule.

Lisez le CLAUDE.md de l'utilisateur pour une de ces lignes exactes :

  • open-pr.on-ready : offer-open (le défaut quand aucune ligne n'est définie) : dans ce même tour, demandez à l'utilisateur via AskUserQuestion s'il veut ouvrir la page de la PR. Exécutez gh pr view <num> --web seulement sur un oui.
  • open-pr.on-ready : offer-merge : dans ce même tour, demandez « fusionner # maintenant ? » via AskUserQuestion. Ajoutez l'étiquette de file du dépôt seulement sur un oui.

N'étiquetez ni n'ouvrez jamais sur le seul rapport. Sous la compétence long-running, transmettez le rapport au bureau d'atterrissage ; il possède la décision quel que soit le réglage.

Après avoir ajouté l'étiquette de file à une PR dont l'observateur a déjà signalé ready-to-merge, reprenez cet observateur par nom pour qu'il surveille la file à travers les vérifications vertes jusqu'à un atterrissage ou un échec :

SendMessage(to : "pr-watch-<num>", message : "Étiquette de file <étiquette> ajoutée. Reprenez la surveillance de la file sur le même fichier d'état.")

Son rapport arrive comme une notification en cours de tâche — continuez de travailler jusqu'à ce qu'il arrive. Quand il rapporte un jugement…

… [tronqué pour la traduction]

Individual skills in this repo

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

yasyf/design-doc

Run an assumptions-first architecture design and ship it as an interactive design doc. Ground truths land in a register with stable IDs, every design fork goes through a question round with a recorded escape hatch, an adversarial review attacks the middle draft, and every estimate is gated on a named spike. The deliverable is a registers.json-driven single-file HTML doc that opens on a hand-written executive summary, cites every entry by a human-readable handle, carries declared interactive components, and answers questions in the page when an AI config is deployed beside it, plus a generated PDF, written as a humble proposal that explains and asks for feedback. Use when asked to "write a design doc", "architecture proposal", "help me design <system>", "redesign <system>", "assumptions-first design", or to turn a systems discussion into a reviewable design document.

yasyf/long-running

Runs a multi-lane drive so no coordinator becomes its bottleneck. The session the owner types in is the communicator; a sibling Orca session bound as lane root is the coordinator; a standing meta lane takes every skill, tooling and process change and turns each ruling into a skill update; every question has a verb of the drive tool lr; landing, grading, lane liveness, incident spawn, release tracking and owner updates run as processes that reach the coordinator only with a decision to make. Use when orchestrating multi-lane work, driving a CI or infra bring-up, running a migration or audit across many units, supervising background agents or PR landings, tracking more than ten open PRs, landing PRs through a merge queue from many lanes, or on any task that will plainly exceed one context window.

yasyf/orca

Launch and supervise Orca workers through the canonical Sprite prepare-and-attach entrypoint, with an explicit local route for Opus roots and the rare Fable assignment for the most sensitive work, and reclaim what a settled Dispatch left behind. Use for worker dispatch, native Run messaging, remote diagnosis, ending a done lane, or source return.

Skills associés