Communitygithub.com

Exécuter un Pipeline

Lance ou reprend l'exécution d'un pipeline depuis son dossier sous `./.pipeline/`.

Qu'est-ce que Exécuter un Pipeline ?

Ce skill transforme l'agent superviseur Claude Code en orchestrateur de pipeline sans lecture superflue. Il n'ouvre jamais les fichiers d'itération (`steps/**/*.md`) ; seul un sous-agent `pipeline-manager` (ou un processus externe en mode `driver`) les pilote. Le superviseur reste au niveau 0 (session principale) pour gérer le verrou de vivacité, attendre des blocs externes (ex. fusion d'une PR bloquante) et présenter les résultats à l'humain. Quatre modes d'exécution sont disponibles : `session` (boucle dans la session principale), `manager` (défaut, via un sous-agent), `driver` (processus externe sans modèle dans la boucle) et `standalone` (via SDK sans session Claude Code). L'utilisateur peut spécifier un modèle par pipeline ou par étape (alias `haiku`/`sonnet`/`opus`/`fable` ou ID canonique `claude-*`), un effort de raisonnement (`low`/`medium`/`high`/`xhigh`/`max`), et les surcharges par exécution sont persistées automatiquement. Le skill émet des événements de cycle de vie vers `events.jsonl`, gère la reprise (`--resume`) avec un état d'exécution préservé, et inclut un flux de blocage imbriqué pour attendre puis relancer automatiquement le pipeline.

Compatible avec✓Claude Code~Codex CLI✓Cursor
npx skills add IvanMurzak/pipeline-claude

Demander à votre IA préférée

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

Documentation

Que fait Exécuter un Pipeline ?

Vous démarrez ou reprenez l'exécution d'un pipeline. $1 est le PIPELINE à exécuter — son dossier sous ./.pipeline/. (Un pipeline v1 peut encore être nommé par un chemin de fichier d'itération ; voir Prérequis.)

Ce que vous faites

Vous êtes le superviseur qui s'exécute dans la session principale (profondeur 0). Vous ne bouclez pas vous-même sur les itérations. Au lieu de cela, vous générez un unique sous-agent pipeline-manager (profondeur 1) qui conduit toute la chaîne — générant un nouveau step-executor par itération et exécutant pipeline-improver / pipeline-script-creator entre les étapes (le CLI pipeline next qu'il pilote émet automatiquement les événements UI par itération et exécute lui-même les hooks externes worktree) — et retourne un rapport structuré lorsque l'exécution se termine, s'arrête ou rencontre un blocage hors de son périmètre.

Vous restez à la profondeur 0 car trois choses doivent vivre dans la session principale et un sous-agent ne peut pas les faire : (a) posséder un pid stable pour le fichier de verrou de vivacité de l'exécution, (b) attendre des heures une condition externe (une PR bloquante à fusionner) et reprendre, (c) finalement présenter les résultats à l'humain. Votre travail est donc : créer l'ID d'exécution (ou, sur --resume, ré-entrer dans un ID EXISTANT — voir "Procédure de reprise"), configurer le suivi UI, générer le manager, et agir sur son rapport — y compris exécuter l'attente du blocage imbriqué et ré-invoquer le manager pour reprendre.

CRITIQUE — discipline de jetons : ne lisez presque rien

Ce skill est un superviseur, pas un lecteur. Chaque fichier d'itération est lu par un step-executor dans son propre contexte frais ; la résolution du modèle par étape a lieu à l'intérieur du pipeline-manager.

  • Ne Lisez jamais un fichier d'itération (steps/**/*.md). Vous ne les touchez jamais — pas même leur frontmatter. Le manager résout les modèles par étape ; vous ne lui passez que le modèle par défaut du pipeline.
  • Lisez PIPELINE.md uniquement comme frontmatter (limit: 50), une fois, au début de la chaîne, pour extraire le champ model: comme pipeline_default_model et rien d'autre. Ne passez pas son contenu au manager. Sur --resume, sautez entièrement cette lecture — pipeline_default_model provient du next.json.default_model persistant de l'exécution existante (voir "Procédure de reprise"), ce qui empêche une reprise d'ajouter une lecture de manifeste en plus de la lecture next.json déjà nécessaire pour current_iteration.
  • Les seuls fichiers que vous pouvez Lire en entier sont ceux que vous écrivez vous-même dans le flux de blocage imbriqué (corps d'issues, notes de travail partielles) et, sur --resume, le(s) petit(s) fichier(s) de curseur d'orchestration .runtime/*/next.json — jamais un fichier d'itération ou le corps de PIPELINE.md.

Sélection du mode d'exécution (expérimental)

Quatre modes existent, et pipeline next décide de ce qui s'exécute ensuite dans chacun d'eux (E1) — jamais la boucle qui l'appelle. Ils diffèrent uniquement par où se trouve la boucle et ce qui exécute une étape :

ModeBoucle vit dansExécute une étape
sessioncette session principalel'outil Agent, dans la session
manager (défaut)un sous-agent pipeline-managerl'outil Agent, dans la session
driverun processus possédé par ce plugin, aucun modèle dans la boucle (pipeline drive)un nouveau processus claude -p par étape
standalonele même processus possédé que driverle SDK Agent avec votre propre clé API — aucune session Claude Code du tout

driver et standalone sont faciles à confondre car ils partagent une boucle et diffèrent seulement par l'exécuteur ; ne confondez aucun des deux avec pipeline drive, qui est le nom de la commande pour le chemin driver, pas un synonyme du mode. Ce CLI fourni implémente session, manager et driver — les pipelines v1 écrivent driver comme runner: headless dans le frontmatter de PIPELINE.md (voir ci-dessous) ; standalone et une clé runner: au niveau de pipeline.yml appartiennent au même design à quatre modes mais ne sont pas encore câblés dans cette copie fournie, donc ne dites pas à un utilisateur que l'un ou l'autre s'exécutera aujourd'hui.

Résolvez runner: en même temps que la lecture de model: à l'étape 3 de la Procédure. Dans un pipeline v2, c'est une clé de premier niveau dans pipeline.yml — Grep ^runner: là, ce qui lit une ligne et n'ouvre jamais un fichier d'étape ; dans v1, c'est le frontmatter de PIPELINE.md, déjà dans les ≤50 lignes que vous lisez pour model:. Absent ou illisible ⇒ manager, comportement actuel et défaut délibéré (E10). Une valeur qui est déclarée mais n'a pas de branche ci-dessous exécute encore manager — mais dites-le en une ligne avant de commencer, car un mode que le manifeste n'a pas déclaré est un mode que l'auteur n'a pas choisi. Ne déduisez jamais le mode de la longueur de la chaîne : un seuil invisible fait qu'une commande se comporte de deux manières.

runner: session — la session principale exécute elle-même la boucle

Ne générez PAS de pipeline-manager. Lisez la boucle de session et suivez-la à la place des étapes 5.1–5.3 de la Procédure. Tout le reste de ce fichier — étapes 1–4, la Procédure de reprise, le Flux de blocage imbriqué, les invariants du superviseur et le format du rapport — s'applique à vous sans changement, car vous êtes toujours le superviseur à la profondeur 0 et avez seulement absorbé la boucle au lieu de la déléguer.

Ce fichier porte les deux refus de pré-vol dont ce mode a besoin (un CLI trop vieux pour pipeline next --brief-file, et execution: parallel, dont les charges utiles vivent dans un brief que la session ne peut pas ouvrir) et est honnête sur le compromis : chaque action et chaque rapport d'étape atterrit dans le contexte que l'utilisateur regarde, donc une longue chaîne appartient à manager — ce qui est précisément pourquoi manager reste le défaut.

runner: headless (v1) — le mode driver

Lorsque le pipeline est v1 et que le frontmatter PIPELINE.md que vous lisez pour model: porte aussi runner: headless (l'orthographe v1 du mode driver — voir le tableau ci-dessus), ne générez PAS de pipeline-manager. Au lieu de cela, exécutez le pilote fourni comme processus d'arrière-plan et supervisez-le :

bun "${CLAUDE_PLUGIN_ROOT}/apps/pipeline-cli/src/cli.ts" drive \
  --root "<pipeline_root>" --run-id "<run_id>" [--start "<step-name>"] \
  --default-model "<pipeline_default_model-or-null>" \
  [--default-effort "<level-or-null>"] \
  [--model "<step_id>=<model>" ...] [--effort "<step_id>=<level>" ...] --json [--resume]

Lancez-le avec run_in_background: true et agissez sur son JSON final lorsqu'il se termine : code de sortie 0 → émettre pipeline.completed ; code de sortie 1 → émettre pipeline.halted et remonter la raison ; code de sortie 3 (blocked) → exécuter le flux de blocage imbriqué ci-dessous, puis relancer drive avec --resume. Tout le reste de votre rôle de superviseur (ID d'exécution, vivacité, liaison miroir, rapport humain) est inchangé. Ce chemin driver (v1 : runner: headless) saute les actions d'auto-amélioration et laisse .feedback/<run_id>/ intact — mentionnez-le dans votre rapport final pour que l'utilisateur puisse lancer un passage manuel d'amélioration. Lorsque runner: est absent ou manager, procédez exactement comme ci-dessous.

Sélection du modèle

Un pipeline (et chaque itération) peut choisir un modèle Claude via le champ OPTIONNEL model: du frontmatter. Le champ par défaut est hérité — omettez-le et le step-executor hérite du modèle de session. Vous ne résolvez que le défaut au niveau du pipeline et le transmettez au manager ; le CLI pipeline next résout le modèle effectif par itération (surcharge par exécution ?? step.model ?? pipeline_default_model) et le manager le passe à chaque step-executor via le paramètre model par appel de l'outil Agent. Passez la valeur résolue sans changement — ne traduisez PAS un alias en un ID canonique. Le paramètre model de l'Agent accepte directement les alias, les ID canoniques et inherit.

Vocabulaire model: accepté (de bout en bout) : l'un des alias haiku / sonnet / opus / fable, OU tout ID de modèle Claude canonique exact (une chaîne commençant par claude-, par exemple claude-opus-4-8, claude-sonnet-4-6, claude-fable-5), OU inherit / absent (→ défaut de session).

Résolvez pipeline_default_model : dans un pipeline v2, le CLI lit defaults.model depuis pipeline.yml lui-même — passez null et laissez-le faire. Sinon, si <pipeline-root>/PIPELINE.md existe, Lisez-le avec limit: 50 et prenez la valeur model: du frontmatter lorsqu'il s'agit d'une valeur acceptée (un alias, un claude-* ID, conservé textuellement) ; inherit/absent → null. Si PIPELINE.md est absent, null. Valeurs invalides — tout ce qui n'est pas l'un des alias acceptés, un claude-* ID, inherit, ou absent — avertissez une fois et retombez à null (ne vous arrêtez pas). (Lire ≤ ~10 lignes de frontmatter est une extraction de métadonnées, pas une lecture de contenu — cela ne duplique jamais ce que le step-executor charge.)

Surcharges d'étape par exécution (step_model_overrides) : l'utilisateur peut épingler des étapes individuelles à un modèle différent POUR CETTE EXÉCUTION UNIQUEMENT — sans modifier aucun fichier de pipeline — soit avec des drapeaux explicites après le chemin (--model <step_id>=<model>, répétable), soit en langage naturel ("exécute les étapes 02-implement et 03-refine sur fable"). Normalisez ce qu'ils ont dit en paires <step_id>=<model> : step_id est le step_id du frontmatter de l'étape ou son nom de fichier (par exemple 02-implement pour steps/02-implement.md) ; model utilise le vocabulaire accepté ci-dessus (inherit force le défaut de session pour cette étape). Vous ne lisez AUCUN fichier d'étape pour valider les ID — le CLI avertit sur les ID inconnus et rejette les modèles invalides. Passez les paires au manager comme step_model_overrides (voir 5.1) ou, sur le chemin driver, comme des drapeaux --model répétés sur la commande drive. Une surcharge bat le propre model: du frontmatter de l'étape ; les étapes sans surcharge ne sont pas touchées. Le CLI persiste les surcharges dans l'état de l'exécution à l'initialisation, donc les reprises les conservent automatiquement — repassez les mêmes paires lors de la ré-invocation du manager de toute façon (inoffensif, et cela survit à un .runtime/ supprimé). Pas de surcharges mentionnées ⇒ omettez entièrement.

Sélection de l'effort (effort de raisonnement — le jumeau de model:)

Un pipeline et chaque itération peuvent aussi choisir un effort de raisonnement via le champ OPTIONNEL effort: du frontmatter (niveaux : low / medium / high / xhigh / max ; inherit/absent → l'effort de la session). Il se résout par la même échelle exacte que le modèle — surcharge par exécution ?? effort d'étape effort: ?? effort pipeline effort: ?? héritage — entièrement à l'intérieur du CLI pipeline next. Résolvez pipeline_default_effort depuis la même lecture du frontmatter PIPELINE.md que vous faites déjà pour model: (même règle de valeur invalide : avertissez une fois, retombez à null), transmettez-le au manager comme pipeline_default_effort, et normalisez les demandes utilisateur comme "exécute 03-refine avec effort max" en paires step_effort_overrides (<step_id>=<level>) passées exactement comme les paires de modèle (drapeaux --effort sur le chemin driver). NOTE D'HONNÊTETÉ : l'exécuteur driver applique l'effort pour de vrai (claude --effort par génération) ; en mode manager, l'outil Agent peut ne pas encore exposer un paramètre d'effort par appel — le manager le passe lorsqu'il est pris en charge et sinon l'étape hérite de l'effort de session (voir pipeline-manager.md § run-step).

Prérequis

  • Un pipeline existe sous le ./.pipeline/ du projet courant (généralement créé avec /pipeline:design).
  • $1 est le DOSSIER du pipeline sous ./.pipeline/ (par exemple ./.pipeline/ship-feature), qui démarre une exécution FRAÎCHE — cela crée toujours un NOUVEL run_id. --start <step-name> démarre cette exécution fraîche à une étape nommée au lieu de la première du manifeste. Un chemin de fichier d'itération est toujours accepté, et c'est ainsi qu'un pipeline v1 nomme une étape de départ. OU --resume [<run_id>] pour ré-entrer dans une exécution EXISTANTE sous son run_id ORIGINAL (voir "Procédure de reprise") — le seul moyen de continuer l'exécution d'une session morte sans orpheliner son état.
  • Le répertoire de travail courant est la racine du projet consommateur — toutes les modifications de fichiers effectuées par les itérations atterrissent ici.

Émissions d'événements de journal

Vous émettez le cycle de vie au niveau de l'exécution vers <projet>/.pipeline/.runtime/events.jsonl ; les événements par itération (iteration.*, improver.*, script_creator.*, worktree.*) sont automatiquement émis en processus par le CLI pipeline next que le manager pilote (le manager lui-même n'émet que les événements d'amélioration/script du rétrospectif). Comme toute l'exécution partage un même session_id, la liaison miroir que vous enregistrez ci-dessous est ce qui permet au hook d'analyse de corréler les appels d'outils du manager et des step-executor à cette exécution. Les émissions sont au mieux — ne laissez jamais un échec arrêter l'exécution.

Configuration unique au début de la Procédure : créez l'ID d'exécution en appelant le CLI — ne générez jamais un vous-même ou n'inventez pas de format : bun "${CLAUDE_PLUGIN_ROOT}/apps/pipeline-cli/src/cli.ts" id. Capturez la valeur littérale qu'il imprime (un UUIDv7, par exemple 019fc762-5762-7000-a9bf-922ed8fa00be).

CRITIQUE — passez run_id littéralement à chaque appel d'écrivain. L'outil Bash de Claude Code ne préserve pas l'état du shell entre les invocations, donc une variable d'environnement exportée n'atteint pas le prochain appel pipeline event. Passez run_id=<l'id-littéral> comme argument k=v sur CHAQUE appel. Les arguments k=v n'ont pas d'espaces autour de = ; mettez entre quotes simples une valeur contenant des espaces.

Aide à l'émission (exécutée avec Bun, silencieuse en cas de succès, sortie 0 même en cas d'échec — ne vérifiez pas la sortie) :

bun "${CLAUDE_PLUGIN_ROOT}/apps/pipeline-cli/src/cli.ts" event <event-type> run_id=<literal-id> [k=v ...]

Ce que vous émettez (un appel par puce) :

  • Sur --resume, cette liste entière ne s'applique pas — la Procédure de reprise n'émet que write-liveness + register-mirror-binding pour le run_id EXISTANT, et jamais pipeline.started (ré-entrer dans une exécution n'en démarre pas une nouvelle). Voir "Procédure de reprise".
  • Après la bannière : pipeline.started run_id=<id> pipeline_name=<nom> first_iteration_path=<chemin_abs> pipeline_root=<chemin_abs> default_model=<modèle-ou-null> — default_model est pipeline_default_model (un alias haiku/sonnet/opus/fable, un ID claude-* canonique, ou le littéral null).
  • Immédiatement après pipeline.started, écrivez le fichier de verrou de vivacité pour qu'un lecteur puisse dire que cette exécution est morte sans événement terminal : bun "${CLAUDE_PLUGIN_ROOT}/apps/pipeline-cli/src/cli.ts" event write-liveness run_id=<id> pid=$PPID (PowerShell : pid=$PID). Passez le pid OS du processus conduisant ce superviseur — $PPID est la meilleure poignée portable pour la session Claude persistante. Le démon ne retire automatiquement une exécution que lorsque ce pid est un processus réel et mort, donc une valeur non fiable est un no-op sûr.
  • Im...

Skills associés