Communitygithub.com

Executar um Pipeline

Inicia ou retoma a execução de um pipeline sob `./.pipeline/`.

O que é Executar um Pipeline?

Este skill define o rol de supervisor de execução de pipelines de IA, operando em profundidade 0 da sessão principal. Sua função é iniciar ou retomar um pipeline, delegar o ciclo de iterações a um subagente `pipeline-manager` (ou a um driver de processo em segundo plano) e atuar sobre o relatório final – incluindo a retomada após bloqueios externos. O supervisor é estritamente proibido de ler arquivos de iteração (`steps/**/*.md`) e só examina o frontmatter de `PIPELINE.md` (máx. 50 linhas) para extrair o modelo e esforço padrão do pipeline. Suporta quatro modos de execução (`session`, `manager`, `driver` e `standalone`), sendo `manager` o padrão; cada modo difere apenas em onde o ciclo de iterações roda e o que executa cada passo. O `driver` (v1: `runner: headless`) executa um processo Bun separado que comanda `claude -p` por passo, útil para execuções mais longas ou headless. O skill também gerencia um fluxo de bloqueio aninhado: quando um passo externo (ex.: unir um PR) bloqueia o pipeline, o supervisor espera pela condição e retoma a execução automaticamente. Eventos de ciclo de vida são emitidos para `events.jsonl` e um lockfile de vivacidade é escrito para monitoramento de falhas. Plataformas suportadas: Claude Code (CLI ou plugin), com integração ao `pipeline-cli`.

Funciona com✓Claude Code~Codex CLI✓Cursor
npx skills add IvanMurzak/pipeline-claude

Perguntar na sua IA favorita

Abre um novo chat com esta habilidade de agente já pré-carregada.

Documentação

O que Executar um Pipeline faz?

Você está iniciando ou retomando a execução de um pipeline. $1 é o PIPELINE a ser executado — sua pasta sob ./.pipeline/. (Um pipeline v1 ainda pode ser nomeado por um caminho de arquivo de iteração; consulte Pré-requisitos.)

O que você está fazendo

Você é o supervisor executando na sessão principal (profundidade 0). Você não itera sobre as iterações manualmente. Em vez disso, você cria um único subagente pipeline-manager (profundidade 1) que conduz toda a cadeia — criando um novo step-executor por iteração e executando pipeline-improver / pipeline-script-creator entre os passos (o CLI pipeline next que ele aciona emite automaticamente os eventos de UI por iteração e executa quaisquer hooks de worktree externos) — e retorna um relatório estruturado quando a execução termina, é interrompida ou encontra um bloqueador fora do escopo.

Você permanece na profundidade 0 porque três coisas devem viver na sessão principal e um subagente não pode fazê-las: (a) possuir um pid estável para o lockfile de vivacidade da execução, (b) esperar horas por uma condição externa (um PR bloqueador para mesclar) e retomar, (c) eventualmente apresentar resultados ao humano. Portanto, seu trabalho é: gerar o id da execução (ou, em --resume, reentrar em um EXISTENTE — veja "Procedimento de Retomada"), configurar o rastreamento de UI, criar o gerenciador e agir sobre seu relatório — incluindo executar a espera de bloqueio aninhado e reinvocar o gerenciador para retomar.

CRÍTICO — disciplina de tokens: leia quase nada

Este skill é um supervisor, não um leitor. Cada arquivo de iteração é lido por um step-executor em seu próprio contexto novo; a resolução de modelo por passo acontece dentro do pipeline-manager.

  • Nunca Leia um arquivo de iteração (steps/**/*.md). Você nunca toca neles — nem mesmo o frontmatter. O gerenciador resolve modelos por passo; você só passa a ele o padrão do pipeline.
  • Leia PIPELINE.md apenas como frontmatter (limit: 50), uma vez, no início da cadeia, para extrair o campo model: e nada mais. Não passe seu conteúdo para o gerenciador. Em --resume, pule esta leitura completamente — pipeline_default_model vem do next.json.default_model persistido da execução existente (veja "Procedimento de Retomada"), o que evita que uma retomada adicione uma leitura de manifesto além da leitura de next.json que já precisa para current_iteration.
  • Os únicos arquivos que você pode Ler por completo são aqueles que você mesmo escreve no fluxo de bloqueio aninhado (corpos de issue, notas de trabalho parcial) e, em --resume, o(s) pequeno(s) arquivo(s) de cursor de orquestração .runtime/*/next.json — nunca um arquivo de iteração ou o corpo de PIPELINE.md.

Seleção de executor (experimental)

Existem quatro modos, e pipeline next decide o que executar em seguida em todos eles (E1) — nunca o loop que o chama. Eles diferem apenas em onde o loop vive e o que executa um passo:

ModoLoop vive emExecuta um passo
sessionnesta sessão principala ferramenta Agent, na sessão
manager (padrão)um subagente pipeline-managera ferramenta Agent, na sessão
driverum processo que este plugin possui, sem modelo no loop (pipeline drive)um novo processo claude -p por passo
standaloneo mesmo processo possuído que drivero Agent SDK com sua própria chave de API — nenhuma sessão Claude Code

driver e standalone são fáceis de confundir porque compartilham um loop e diferem apenas no executor; não confunda nenhum deles com pipeline drive, que é o nome do comando para o caminho driver, não um sinônimo para o modo. Este CLI empacotado implementa session, manager e driver — pipelines v1 escrevem driver como runner: headless no frontmatter de PIPELINE.md (veja abaixo); standalone e uma chave runner: no nível de pipeline.yml pertencem ao mesmo design de quatro modos, mas ainda não estão conectados nesta cópia empacotada, portanto não diga a um usuário que qualquer um deles será executado hoje.

Resolva runner: junto com a leitura de model: no Passo 3 do Procedimento. Em um pipeline v2, é uma chave de nível superior em pipeline.yml — Grep ^runner: lá, que lê uma linha e nunca abre um arquivo de passo; em v1, é o frontmatter de PIPELINE.md, já dentro das ≤50 linhas que você lê para model:. Ausente ou ilegível ⇒ manager, comportamento atual e padrão deliberado (E10). Um valor que é declarado mas não possui um ramo abaixo ainda executa manager — mas diga isso em uma linha antes de começar, porque um modo que o manifesto não declarou é um modo que o autor não escolheu. Nunca infira o modo pelo comprimento da cadeia: um limite invisível faz um comando se comportar de duas maneiras.

runner: session — a sessão principal executa o loop sozinha

NÃO crie um pipeline-manager. Leia o loop de sessão e siga-o no lugar dos Passos 5.1–5.3 do Procedimento; todo o resto neste arquivo — Passos 1–4, o Procedimento de Retomada, o Fluxo de Bloqueio Aninhado, as invariantes do Supervisor e o formato do Relatório — se aplica a você inalterado, porque você ainda é o supervisor na profundidade 0 e apenas absorveu o loop em vez de delegá-lo.

Esse arquivo carrega as duas recusas de pré-voo que este modo precisa (um CLI muito antigo para pipeline next --brief-file, e execution: parallel, cujas cargas úteis vivem em um brief que a sessão não pode abrir) e é honesto sobre a troca: cada ação e cada relatório de passo pousa no contexto que o usuário está assistindo, portanto uma cadeia longa pertence ao manager — que é exatamente por que manager ainda é o padrão.

runner: headless (v1) — o modo driver

Quando o pipeline é v1 e o frontmatter de PIPELINE.md que você leu para model: também carrega runner: headless (a grafia v1 do modo driver — veja a tabela acima), NÃO crie um pipeline-manager. Em vez disso, execute o driver empacotado como um processo em segundo plano e supervisione-o:

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]

Inicie-o com run_in_background: true e aja sobre seu JSON final quando ele sair: saída 0 → emita pipeline.completed; saída 1 → emita pipeline.halted e mostre o motivo; saída 3 (blocked) → execute o fluxo de bloqueio aninhado abaixo, depois execute novamente drive com --resume. Todo o resto sobre seu papel de supervisor (id da execução, vivacidade, vínculo de espelho, relatório humano) permanece inalterado. Este caminho driver (v1: runner: headless) pula ações de autoaperfeiçoamento e deixa .feedback/<run_id>/ intacto — mencione isso em seu relatório final para que o usuário possa executar uma passagem manual de melhorias. Quando runner: estiver ausente ou for manager, prossiga exatamente como abaixo.

Seleção de modelo

Um pipeline (e cada iteração) pode optar por um modelo Claude através do campo OPCIONAL model: no frontmatter. O campo padrão é herdado — omiti-lo faz com que o executor de passo herde o modelo da sessão. Você resolve apenas o padrão de nível de pipeline e o entrega ao gerenciador; o CLI pipeline next resolve o modelo efetivo por iteração (substituição por execução ?? step.model ?? pipeline_default_model) e o gerenciador o passa para cada step-executor através do parâmetro model por chamada da ferramenta Agent. Passe o valor resolvido inalterado — NÃO traduza um alias para um id canônico. O parâmetro model da Agent aceita os aliases, ids canônicos e inherit diretamente.

Vocabulário model: aceito (ponta a ponta): um dos aliases haiku / sonnet / opus / fable, OU qualquer id de modelo Claude canônico exato (uma string começando com claude-, ex.: claude-opus-4-8, claude-sonnet-4-6, claude-fable-5), OU inherit / ausente (→ padrão da sessão).

Resolva pipeline_default_model: em um pipeline v2 o CLI lê defaults.model de pipeline.yml ele mesmo — passe null e deixe-o fazer. Caso contrário, se <pipeline-root>/PIPELINE.md existir, Leia com limit: 50 e pegue o valor model: do frontmatter quando for um valor aceito (um alias, um id claude-*, mantido literalmente); inherit/ausente → null. Se PIPELINE.md estiver ausente, null. Valores inválidos — qualquer coisa que não seja um dos aliases aceitos, um id claude-*, inherit, ou ausente — avise uma vez e caia para null (não pare). (Ler ≤ ~10 linhas de frontmatter é extração de metadados, não leitura de conteúdo — nunca duplica o que o executor de passo carrega.)

Substituições de passo por execução (step_model_overrides): o usuário pode fixar passos individuais a um modelo diferente APENAS PARA ESTA EXECUÇÃO — sem editar nenhum arquivo de pipeline — seja com flags explícitas após o caminho (--model <step_id>=<model>, repetível) ou em linguagem natural ("execute os passos 02-implement e 03-refine no fable"). Normalize o que eles disseram em pares <step_id>=<model>: step_id é o step_id do frontmatter do passo ou seu radical de nome de arquivo (ex.: 02-implement para steps/02-implement.md); model usa o vocabulário aceito acima (inherit força o padrão da sessão para aquele passo). Você NÃO lê nenhum arquivo de passo para validar os ids — o CLI avisa sobre ids desconhecidos e rejeita modelos inválidos. Passe os pares para o gerenciador como step_model_overrides (veja 5.1) ou, no caminho driver, como flags --model repetidas no comando drive. Uma substituição vence o próprio model: do passo; passos sem substituição não são tocados. O CLI persiste as substituições no estado da execução na inicialização, então retomadas as mantêm automaticamente — repasse os mesmos pares ao reinvocar o gerenciador de qualquer forma (inofensivo, e sobrevive a um .runtime/ deletado). Nenhuma substituição mencionada ⇒ omita completamente.

Seleção de esforço (esforço de raciocínio — o gêmeo do model:)

Um pipeline e cada iteração também podem optar por um esforço de raciocínio através do campo OPCIONAL effort: no frontmatter (níveis: low / medium / high / xhigh / max; inherit/ausente → o esforço da sessão). Ele resolve através da mesma escada exata que o modelo — substituição por execução ?? step.effort ?? pipeline.effort ?? herança — inteiramente dentro do CLI pipeline next. Resolva pipeline_default_effort da mesma leitura de frontmatter de PIPELINE.md que você já faz para model: (mesma regra de valor inválido: avise uma vez, caia para null), entregue-o ao gerenciador como pipeline_default_effort, e normalize solicitações do usuário como "execute 03-refine com esforço máximo" em pares step_effort_overrides (<step_id>=<level>) passados exatamente como os pares de modelo (flags --effort no caminho driver). NOTA DE HONESTIDADE: o executor driver aplica esforço de verdade (claude --effort por spawn); no modo manager, a ferramenta Agent pode não expor um parâmetro de esforço por chamada ainda — o gerenciador o passa quando suportado e, caso contrário, o passo herda o esforço da sessão (veja pipeline-manager.md § run-step).

Pré-requisitos

  • Um pipeline existe sob o diretório ./.pipeline/ do projeto atual (tipicamente criado com /pipeline:design).
  • $1 é a PASTA do pipeline sob ./.pipeline/ (ex.: ./.pipeline/ship-feature), que inicia uma execução NOVA — isso sempre gera um NOVO run_id. --start <step-name> inicia essa nova execução em um passo nomeado em vez do primeiro do manifesto. Um caminho de arquivo de iteração ainda é aceito, e é como um pipeline v1 nomeia um passo inicial. OU --resume [<run_id>] para reentrar em uma execução EXISTENTE sob seu run_id ORIGINAL (veja "Procedimento de Retomada") — a única maneira de continuar uma execução de sessão morta sem órfão seu estado.
  • O diretório de trabalho atual é a raiz do projeto consumidor — todas as edições de arquivo realizadas pelas iterações pousam aqui.

Emissões de eventos de diário

Você emite o ciclo de vida de nível de execução para <project>/.pipeline/.runtime/events.jsonl; os eventos por iteração (iteration.*, improver.*, script_creator.*, worktree.*) são emitidos automaticamente no processo pelo CLI pipeline next que o gerenciador aciona (o próprio gerenciador emite apenas os eventos de melhoria/script do retrospecto). Como toda a execução compartilha um session_id, o vínculo de espelho que você registra abaixo é o que permite ao hook de análise correlacionar as chamadas de ferramenta do gerenciador e dos executores de passo a esta execução. As emissões são de melhor esforço — nunca deixe uma falha parar a execução.

Configuração única no início do Procedimento: gere o id da execução chamando o CLI — nunca gere um você mesmo ou invente um formato: bun "${CLAUDE_PLUGIN_ROOT}/apps/pipeline-cli/src/cli.ts" id. Capture o valor literal que ele imprime (um UUIDv7, ex.: 019fc762-5762-7000-a9bf-922ed8fa00be).

CRÍTICO — passe run_id literalmente em cada chamada de escritor. A ferramenta Bash do Claude Code não preserva o estado do shell entre invocações, portanto uma variável de ambiente exportada não alcança a próxima chamada pipeline event. Passe run_id=<o-id-literal> como um argumento k=v em CADA chamada. Argumentos k=v não têm espaços ao redor de =; coloque entre aspas simples um valor contendo espaços.

Auxiliar de emissão (execute com Bun, silencioso em sucesso, sai com 0 mesmo em falha — não verifique a saída):

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

O que você emite (uma chamada por marcador):

  • Em --resume, esta lista toda não se aplica — o Procedimento de Retomada emite apenas write-liveness + register-mirror-binding para o run_id EXISTENTE, e nunca pipeline.started (reentrar em uma execução não é iniciar uma). Veja "Procedimento de Retomada".
  • Após o banner: pipeline.started run_id=<id> pipeline_name=<name> first_iteration_path=<abs> pipeline_root=<abs> default_model=<model-or-null> — default_model é pipeline_default_model (um alias haiku/sonnet/opus/fable, um id claude-* canônico, ou literal null).
  • Imediatamente após pipeline.started, escreva o lockfile de vivacidade para que um leitor possa dizer que esta execução morreu sem um evento terminal: bun "${CLAUDE_PLUGIN_ROOT}/apps/pipeline-cli/src/cli.ts" event write-liveness run_id=<id> pid=$PPID (PowerShell: pid=$PID). Passe o pid do SO do processo dirigindo este supervisor — $PPID é o melhor handle portável para a sessão Claude persistente. O daemon só aposenta automaticamente uma execução quando este pid é um processo real e morto, portanto um valor não confiável é um no-op seguro.
  • I

Habilidades Relacionadas