Abrir PR
Abra um pull request para a branch atual na plataforma de PR detectada (Azure DevOps ou GitHub). O título e a descrição são elaborados para corresponder às convenções de PRs passados do próprio usuário em vez de um estilo fixo da casa, e então exibidos para confirmação. O PR nunca é criado sem aprovação explícita — abrir um PR é uma ação voltada para o mundo externo.
Esta skill é independente de backend: os mecanismos específicos da plataforma (criar PR, verificar duplicidade, adicionar label, link de backport) residem em documentos de referência de adaptadores de backend em resources/backends/, e os mecanismos de link de ticket residem em documentos de referência de adaptadores de rastreadores em resources/trackers/. O corpo da skill detecta a plataforma e o rastreador, carrega os adaptadores correspondentes e segue suas receitas — não possui análise de campos específica de az/gh e nem análise de id/URL específica de rastreador. Ela aproveita as proteções de segurança de um fluxo de criação de PR, mas é deliberadamente mais restrita: abre um PR para a branch como ela está — publicando-a no remoto primeiro, se ainda não estiver lá, pois o PR precisa dela. Não faz merge da branch base, não exclui branches e não faz triagem de comentários de revisão (isso é função de resolve-pr-comments).
Etapa 0 — Detectar plataforma + rastreador, carregar adaptadores, anunciar
Antes de qualquer coisa, resolva qual backend e rastreador esta execução irá utilizar:
- Plataforma de PR — a partir de
git remote get-url origin:dev.azure.comou*.visualstudio.com→ Azure DevOps (resources/backends/azure-devops.md).github.com→ GitHub (resources/backends/github.md).- Ambíguo ou outro host → informe a limitação e pergunte ao usuário qual plataforma utilizar, em vez de adivinhar.
- Rastreador de issues (precedência — o primeiro match vence):
- Configuração explícita vence: se
.claude/pr-lifecycle.json(opcional, gitignorado) define o tipo de rastreador, use-o (e obtenha a URL base do Jira a partir dele). - senão inferir o tipo a partir de uma referência de ticket existente:
[A-Z][A-Z0-9]+-\d+→ Jira (em qualquer plataforma); uma referência de issue numérica simples → GitHub Issues — mas apenas em um remoto GitHub (no Azure DevOps#<n>é um link de item de trabalho, não uma issue do GitHub, portanto um número simples não implica GitHub Issues lá). - senão padrão por plataforma: um remoto GitHub → GitHub Issues (zero-configuração); um remoto Azure DevOps → Jira.
- Nenhum ticket → não produza linha de rastreador (como hoje).
- Jira →
resources/trackers/jira.md; GitHub Issues →resources/trackers/github-issues.md.
- Configuração explícita vence: se
- Anuncie a plataforma e o rastreador detectados para que um palpite errado silencioso seja impossível.
Carregue os adaptadores de backend e rastreador correspondentes e execute as partes específicas da plataforma/rastreador das etapas abaixo por meio deles. A única costura de backend neste corpo é reconhecer a string remota para selecionar o adaptador — nenhum acesso a campos além disso. (Os caminhos dos adaptadores são relativos à raiz do plugin — plugins/pr-lifecycle/resources/backends/ e resources/trackers/ — não ao diretório da skill.)
Etapa 1 — Detectar a branch de destino
- Leia a branch padrão do próprio repositório; nunca presuma uma.
git symbolic-ref --short refs/remotes/origin/HEADproduzorigin/<branch>— remova o prefixo. Essa referência é escrita porgit clone, portanto um remoto construído porgit init+git fetchpode não tê-la; então pergunte diretamente ao remoto comgit ls-remote --symref origin HEAD, que é somente leitura e não altera estado local. - Apenas quando nenhuma das duas resolve, recorra a qual de
main/mastero remoto realmente tem — e se ambas existirem, pergunte. Um repositório no meio de uma renomeação mantém a antiga como uma branch obsoleta, portanto escolher silenciosamente basearia o PR no destino errado, o que também invalida a contagem de commits à frente da Etapa 2 e o histórico que a Etapa 3 usa para aprender a convenção do usuário. - Se a branch atual for direcionada a uma linha de release (por exemplo,
release/2.5), trate-a como um backport (veja o formato de backport abaixo). - Se o destino correto for genuinamente ambíguo, pergunte em vez de adivinhar.
Etapa 2 — Pré-condições (pare e informe se alguma falhar)
Execute estas antes de redigir qualquer coisa, pois cada uma é um bloqueio comum na primeira execução:
- Tem commits para o PR. A branch deve estar à frente do destino:
git fetch, em seguidagit rev-list --count origin/<destino>..HEADdeve ser maior que 0. - No remoto — publique se necessário. Criar o PR precisa da branch de origem no remoto. Uma branch ainda não enviada não é uma parada: após confirmação, open-pr a publica (
git push -u origin <branch>) como parte da criação na Etapa 4. (Executando de forma não interativa, não faz push e não cria — veja Etapa 4.) - Sem duplicidade. Verifique se existe um PR aberto existente para esta origem e destino através da receita de verificação de duplicidade do adaptador de backend. Se existir, pare e aponte o usuário para ele — não abra um segundo PR e não modifique o existente aqui.
Etapa 3 — Aprender a convenção do usuário e redigir
Identifique o usuário a partir de git config user.email (preferido) e user.name, e leia seus PRs recentes mesclados neste repositório: git log <destino> --author="<email ou nome>" (tente ambas as formas; trate como "sem histórico" apenas quando ambas não retornarem nada). A partir dos últimos vários, infira capitalização do título e layout da descrição (seccionado vs uma lista plana de marcadores) por maioria — o mais novo por data de commit desempata, um único PR anterior é usado diretamente. Anuncie o resultado (aprendido de K dos seus PRs anteriores ou nenhum histórico correspondente -> usando padrão), para que um palpite errado silencioso seja impossível.
O aprendizado cobre como este repositório e este usuário escrevem as coisas, não apenas tipografia: capitalização do título, layout da descrição (seccionado vs uma lista plana de marcadores) e a forma do prefixo de ticket no título — entre colchetes ([acme-123] …), simples (acme-123 …), um tipo Conventional Commits (fix(escopo): …) ou nenhum prefixo. Leia a forma do mesmo histórico; se os PRs observados não carregam prefixo de ticket, não adicione um. Os padrões abaixo são o que usar quando não há histórico para aprender, nunca um formato a impor a um repositório que visivelmente faz outra coisa.
O aprendizado nunca deve remover ou reordenar o conteúdo obrigatório abaixo — o link do ticket, o resumo e os marcadores; o diagrama no item 4 é opcional, e o rodapé de procedência no item 5 está desativado por padrão, mas quando o rodapé de procedência é opt-in, o aprendizado deve mantê-lo por último e nunca removê-lo. Não enviese o aprendizado para este repositório se ele for de um único autor — a convenção que importa é a do usuário, em qualquer repositório onde a skill for executada.
Formato padrão (o fallback; a convenção aprendida do usuário substitui a apresentação)
Título: derive o id do ticket e sua capitalização a partir do adaptador de rastreador:
- Rastreador Jira:
[acme-xxxxx] <resumo conciso de uma linha>— a chave em minúsculas entre colchetes (o adaptador também fornece a forma maiúscula para a URL). - Rastreador GitHub Issues:
#<n> <resumo conciso de uma linha>— a referência#<n>no lugar da forma entre colchetes. - Nenhum ticket encontrado: omita a linha do ticket e intitule da forma que este repositório intitula PRs sem ticket.
ad-hoc <resumo>é o fallback apenas quando o histórico na Etapa 3 não lhe deu nada para copiar — é um marcador de uma equipe, não uma convenção a introduzir em um repositório que nunca a usou. Um<resumo>simples é o padrão mais seguro. - Dois ou mais ids de ticket diferentes significa perguntar qual, em vez de assumir silenciosamente o primeiro.
Descrição (PR padrão):
- Link do ticket — construído pelo adaptador de rastreador: para Jira,
https://<jira_base_url>/browse/<KEY>(chave maiúscula); para GitHub Issues,#<n>(o GitHub vincula automaticamente uma issue do mesmo repositório). Esta é a primeira linha para que a plataforma o vincule automaticamente; omita a linha inteira apenas quando não houver ticket. - Resumo — uma ou duas frases.
- Descrição — uma lista de marcadores, um marcador por alteração discreta como ação mais breve porquê/impacto. Omita identificadores de arquivo / classe / método / caminho — descreva a intenção, não cole o diff.
- Um diagrama ASCII curto, envolto em um bloco de código com delimitadores (opcional) — inclua um apenas quando uma imagem permitir que o revisor compreenda a alteração mais rápido do que a prosa; caso contrário, deixe de fora. Quando incluir: um diagrama de estrutura monoespaçada real (caixas / setas, ou uma pequena árvore / tabela — nunca prosa disfarçada de diagrama), mantido em alto nível, envolto em delimitadores de três crases, desenhado com glifos ASCII simples (
+ - | > v), não Mermaid; divida qualquer diagrama amplo ou complexo em menores, em vez de forçar um bloco ilegível. Orientações completas de desenho, a justificativa dos delimitadores/codificação e uma forma ilustrativa:resources/diagram-guidance.md. - Marcadores de procedência AI (opt-in — desativados por padrão) — o rodapé (um divisor
---, depois🤖 _Elaborado com Claude Code._) e o labelai-assistedaplicado na Etapa 4 são adicionados apenas quando a solicitação invocadora pede explicitamente para marcar / rotular / sinalizar o PR como assistido por AI (ou passa um opt-in explícito). Ausente essa frase — incluindo toda chamada de pipeline automatizadaresolve-issue, que não carrega tal frase — não adicione nenhum dos dois. Anuncie a decisão na mesma linha que o resultado da plataforma / rastreador / aprendizado (procedência: desligada (diga "marcar como assistido por AI" para adicionar), ouprocedência: ligada (rodapé + label de melhor esforço)) para que um marcador descartado silenciosamente seja impossível. Quando opt-in, o rodapé é o último elemento em todos os caminhos — anexe-o após o corpo da convenção aprendida e nunca permita que o aprendizado o remova ou reordene — e ele é renderizado de forma idêntica no Azure DevOps e GitHub, o marcador portátil; o label é o selo nativo da plataforma ao lado dele (melhor esforço — veja Etapa 4). Se uma equipe algum dia precisar de divulgação obrigatória de AI para auditoria, reintroduza-a então como um sinalizador de configuração — deliberadamente não construído agora.
Backport (destino é release/*):
- Título (rastreador Jira):
[acme-xxxxx] [release] <resumo>; (rastreador GitHub Issues):#<n> [release] <resumo>. - Descrição é o link do ticket, então
cherry pick de <link-do-PR>onde o adaptador de backend fornece a sintaxe do link-do-PR (Azure DevOps!<numero_pr>, GitHub#<numero_pr>— ambos renderizam como um link para aquele PR), então — apenas quando a procedência é opt-in (Etapa 3, item 5) — o rodapé de procedência AI (---+🤖 _Elaborado com Claude Code._). Sem bloco de resumo, marcadores ou diagrama — a revisão real aconteceu no PR original. - Pergunte ao usuário (ou aceite como entrada) o número do PR de origem do qual foi feito cherry-pick e reutilize o resumo de uma linha daquele PR para
<resumo>. Um backport aprende apenas a capitalização do título, não o layout da descrição.
Em todos os caminhos (incluindo o backport): o título e a descrição estão em inglês. Não adicione um trailer Co-Authored-By do git por conta própria — é uma preocupação de commit, não de descrição de PR, e se este repositório quer um é uma decisão do repositório, observável a partir de seu próprio histórico (git log -n 50 --format=%b | grep -c '^Co-Authored-By') em vez de algo que esta skill decide. Padrão é não adicioná-lo; se os commits do repositório rotineiramente o carregam, siga isso em vez de substituir. O rodapé de procedência AI e o label ai-assisted são uma coisa diferente e estão desativados por padrão — adicionados apenas no opt-in explícito descrito na Etapa 3 (rodapé) e aplicado na Etapa 4 (label) — e nunca são o trailer proibido.
Etapa 4 — Apresentar, confirmar, criar
Mostre o título e a descrição redigidos e deixe o usuário editá-los. Em seguida:
- Autônomo: crie apenas após o usuário confirmar explicitamente. Se a branch de origem ainda não estiver no remoto, publique-a primeiro (
git push -u origin <branch>), depois crie o PR através da receita de criação do adaptador de backend — escrevendo a descrição completa em um arquivo temporário e passando-o como a flag de corpo do adaptador, nunca como uma string inline. O adaptador documenta as armadilhas de codificação de arquivo da plataforma (por exemplo, peculiaridades deaz.cmdcp1252/UTF-8@<arquivo>do Azure DevOps) e — apenas quando a procedência é opt-in (Etapa 3) — como o labelai-assistedé aplicado (Azure DevOps cria a tag inline via--labels; GitHub a adiciona após a criação comgh pr edit --add-label, porquegh pr create --labelaborta se o label não existir). Quando opt-in, o label é de melhor esforço de qualquer forma (veja Limites declarados); por padrão, nenhum label é aplicado. Retorne a URL do PR. - Não é possível obter confirmação (executando de forma não interativa, ou dentro de um subagente que não pode solicitar): não faça push da branch e não crie o PR. Imprima o título e a descrição preparados para que o usuário crie manualmente, e diga isso. Não use uma flag de abrir no navegador (por exemplo, Azure DevOps
--open) em um contexto não interativo. Quando a procedência foi opt-in, a descrição impressa já carrega o rodapé; diga ao usuário para adicionar o labelai-assistedquando criar o PR. Por padrão (sem opt-in), nenhum marcador é impresso ou mencionado.
O invariante: nunca publique a branch ou abra um PR sem uma confirmação humana explícita — ambas são ações voltadas para o mundo externo.
Proteções de segurança
- Nunca resolva conflitos de merge automaticamente — pare e relate-os.
- Nunca exclua branches.
- Nunca faça force push sem uma solicitação explícita.
Limites declarados
- Se a ferramenta de PR da plataforma detectada estiver ausente ou não autenticada (veja a pré-condição de cada adaptador de backend — por exemplo,
az+ a extensãoazure-devopspara Azure DevOps,ghautenticado para GitHub), informe e imprima o título e a descrição preparados para criação manual — não falhe silenciosamente. - A convenção aprendida é de melhor esforço: se um fluxo de trabalho de squash deixou o corpo da descrição vazio, a capitalização ainda vem do assunto do commit e o layout recai para o padrão — anunciado, não silencioso.
- Marcadores de procedência estão desativados por padrão — sem rodapé e sem label, a menos que a solicitação invocadora opte explicitamente (Etapa 3, item 5). Quando opt-in, o label
ai-assistedé de melhor esforço: se a plataforma o rejeitar (uma organização que desabilita tags de PR ad-hoc no Azure DevOps, ou um label que ainda não existe no GitHub), remova o label, crie o PR apenas com o rodapé (o marcador opt-in) e informe — o adaptador de backend documenta o comportamento por plataforma.