Abra um PR
Abrir um PR bem feito é um problema de pesquisa antes de ser um problema de git. Um revisor decide na primeira tela se o autor conhece o repositório — a gramática do título, a forma do corpo, os assuntos dos commits — tudo isso sinaliza. Portanto, o trabalho é: aprender o que os mantenedores deste repositório escrevem e, então, escrever isso.
Escolha a profundidade primeiro
Expresso é para "apenas abra o PR", "apenas envie", "coloque isso para dentro" — e para qualquer mudança pequena o suficiente para que a pesquisa custaria mais do que a revisão que ela economiza. Oriente, escreva, envie, entregue a vigilância. Pule o escoteiro de estilo e seu cartão, a calibração de voz e o controle de prosa. Não pergunte se o expresso é desejado: a frase já disse isso, e confirmar é o atraso que o usuário estava evitando.
ccx vcs lane --json
ccx vcs diff
ccx vcs ship --no-watch --pr-title-file "$TITLE" --pr-body-file "$BODY"
O corpo ainda diz o que mudou e por quê, no template do repositório quando ele tem um, e o título ainda corresponde à gramática dos últimos PRs mesclados — uma leitura de gh pr list --state merged --limit 5 --json title, não um escoteiro. O expresso elimina a pesquisa, nunca o corpo: um PR sem corpo é a única coisa que nenhum modo envia.
Completo é o restante deste arquivo, e ele vale seu custo em um repositório que você não possui, em uma mudança para a qual um mantenedor precisa ser persuadido, ou na primeira vez que você abre um PR em qualquer lugar. Em um repositório estrangeiro, as verificações de conformidade e polidez não são opcionais nem no expresso — um convidado que as pula desperdiça a viagem de ida e volta do mantenedor, não a sua.
Oriente
O caminho importa aqui: três comandos cuja saída nomeada é referenciada por tudo a jusante.
ccx vcs lane --json # lane, branch, trunk, dirty, github.mine, downstack PRs e quais não têm corpos
gh repo view --json isPrivate,owner,viewerPermission,pullRequestTemplates,nameWithOwner,defaultBranchRef
ccx vcs guidelines # CONTRIBUTING, template de PR, código de conduta, configuração de issue — imprime o caminho do cartão
Então ccx vcs diff para a mudança em si.
ccx vcs lane informa a lane — ela não a escolhe, e você também não. ccx vcs ship seleciona jj, git ou gt no momento do envio, e um repositório que o usuário não controla silenciosamente cai fora da lane gt, então não escreva nada que assuma uma lane antes de ship informar uma. github.mine é o veredito de propriedade; o teste por trás dele e tudo a jusante de mine: false vive em reference/oss.md. Leia o cartão que ccx vcs guidelines escreveu, então separe requisitos rígidos de preferências — reference/guidelines.md tem os indicadores, e os fallbacks de gh api para um repositório que não publica nada.
Aprenda o estilo da casa
O estilo da casa vive em um cartão no disco, escoteirado uma vez por repositório e armazenado em cache:
bash "${CLAUDE_PLUGIN_ROOT}/scripts/pr-cache.sh" status <owner/name> # fresh | stale:<reason> | missing
bash "${CLAUDE_PLUGIN_ROOT}/scripts/pr-cache.sh" path <owner/name> # imprime o diretório do cache
fresh não precisa de escoteiro — leia o cartão e siga em frente. stale ou missing → dispare o escoteiro, uma vez por repositório por execução:
Agent(subagent_type: "open-pr:pr-style-scout",
prompt: "repo: <owner/name>\ncache: <dir>\nviewer: <gh login>")
O escoteiro amostra PRs mesclados recentes, filtra bots, PRs escritos por IA e — em um repositório estrangeiro — os do próprio visualizador, e escreve o cartão no diretório de cache. Ele retorna um caminho, um resumo curto e uma confiança — leia o cartão que ele escreveu, não sua narração.
O cartão carrega seu tamanho de amostra e uma confiança por eixo, porque os filtros que mantêm a amostra humana também a encolhem. A gramática do título e a estrutura do corpo são convenções — elas se mantêm em qualquer tamanho de amostra. O tom da resposta de revisão e o registro da prosa dependem de menos sinais: em confidence: low eles são uma inclinação, não uma regra, e o template de PR e as diretrizes têm mais peso. Uma convenção lida a partir de três amostras descreveu essas três. O layout do cache, esquema do cartão e obsolescência vivem em reference/style-cache.md.
Calibre a voz
Quando o usuário tem um perfil wlm local, pegue emprestado as partes de sua voz que sobrevivem à mudança de formato:
wlm profile list
wlm -p <profile> stylecard show # -p vem antes do subcomando e não é opcional
O cartão wlm foi construído para prosa longa de blog: a lista Never e a escolha de palavras transferem-se inteiras, o tom com metade da força, comprimento e aberturas nem um pouco. A tabela de transferência completa e o fallback sem perfil estão em reference/voice.md. Onde o cartão do repositório e o cartão de voz discordam, o repositório vence — você é um convidado no formato deles.
Repositórios que você não controla
github.mine: false muda o registro e adiciona duas passagens antes de escrever (reference/oss.md):
- O registro de polidez — direto sobre a mudança, deferente sobre a decisão: números carregam as alegações, o mantenedor mantém as decisões que são dele.
- Conformidade com padrões — percorra
ccx vcs diffcontra o cartão de diretrizes e a lista de verificação: escopo, estilo, testes, docs, higiene de commit, tamanho do diff contra a norma de PRs mesclados do repositório. Cada falha é uma correção, ou uma frase no corpo assumindo o desvio. - Issue primeiro — quando o cartão de diretrizes marca uma issue como um requisito rígido, pesquise antes de abrir:
gh issue list --repo <slug> --search "<keywords>" --state all. Sem correspondência → rascunhe a issue, então coloque o rascunho na frente do usuário comAskUserQuestion— abrir como rascunhado / editar primeiro / vincular uma issue existente / pular o requisito deliberadamente — e aja na escolha deles. Abrir uma issue publica sob o nome do usuário no projeto de outra pessoa; rascunhar não.
Escreva
O título, o corpo e os assuntos dos commits seguem o cartão de estilo com sua confiança declarada; o template de PR, onde existir, é o esqueleto do corpo. Um número onde quer que um adjetivo classificaria a mudança: um revisor verifica "40ms a menos na inicialização a frio" e descarta "muito mais rápido".
Escreva o corpo e o título em arquivos, nunca argumentos de shell — um corpo com crases, $ ou um bloco de código não sobrevive intacto a uma linha de comando, e um título é recusado lá por menos (veja Ship):
BODY=$(mktemp)
TITLE=$(mktemp)
O corpo é prosa, então ele passa pelo controle de prosa antes de ser enviado: slop-cop check "$BODY" --lang=markdown, triando os sinalizadores em vez de aceitar todos eles.
As mensagens de commit recebem o mesmo tratamento: o cartão registra a gramática de assunto deste repositório, seu comprimento e quais trailers seus próprios commits mesclados carregam — corresponda a esses trailers e nenhum outro. Em um repositório cujo histórico não tem Co-Authored-By: Claude ou Generated with Claude Code, um trailer anunciando a ferramenta é a linha única que faz um PR cuidadoso parecer automatizado, e os mantenedores filtram por ele; em um repositório cujo histórico os carrega, mantê-los é a convenção.
Uma pilha por sessão
Trabalho relacionado de uma sessão vai em uma pilha encadeada, nunca irmãos independentes fora do trunk — mesmo quando os diffs são comprovadamente disjuntos. "Os arquivos não se sobrepõem" não é uma razão para dividir: irmãos apagam a ordem de revisão que uma cadeia declara e perdem a maquinaria de meio de pilha — um reajuste carrega uma alteração através de cada branch acima dele, onde irmãos cada um faz rebase sozinho. Encadeie em ordem de dependência, o que consome acima do que consome; uma lane ainda em andamento vai na ponta, para que os branches finalizados abaixo dela nunca sejam rebaseados novamente sob seu tumulto. Mecânica em reference/stack.md.
Um PR é uma unidade de trabalho do tamanho de uma funcionalidade. Acompanhamentos, correções e respostas de revisão são commits no PR aberto, nunca um filho empilhado. Envie-os com ccx vcs ship, adicionando --amend para fundi-los em seu commit ou --tip-only quando apenas a ponta de uma pilha mudou. Empilhe apenas quando um pai deve aterrissar antes que outro trabalho possa prosseguir, ou quando a revisão precisa da divisão. Envie em pontos de verificação coerentes, nunca por edição, porque cada push substitui a construção em execução e reexecuta o CI e os bots de revisão. Ainda assim, envie dentro de uma hora, já que a origem é o backup.
Ship
A combinação de sinalizadores é estrutural:
ccx vcs ship --no-watch --pr-title-file "$TITLE" --pr-body-file "$BODY"
Escreva o título em um arquivo de uma linha ao lado do arquivo do corpo e passe --pr-title-file, nunca um --pr-title inline. O sandbox Bash de um agente isolado por worktree recusa qualquer argumento que emparelhe uma aspa com a palavra git ou um nome de shell, como GitHub's ... git, e um título em um arquivo nunca chega à linha de comando. O ship pega o assunto do commit desse título e o corpo do commit do corpo do PR, então -m é necessário apenas para um assunto que difere do título.
--no-watch porque a vigilância embutida do ship bloqueia até que o CI conclua — certo quando você está esperando, errado quando a vigilância está prestes a ser entregue. O ship é dono da criação e atualização de PR em todas as lanes: um gh pr create feito à mão ao lado dele produz um PR que a lane gt não consegue reconciliar com sua própria pilha.
Em um PR que já está aberto, o ship avisa e mantém o título e o corpo que tem, então uma alteração não carrega nenhum sinalizador, e um PR cujo texto deve mudar recebe --replace-pr-text.
Na lane gt, um envio pode criar vários PRs, e cada PR no envio que ainda não tem corpo recebe um. --pr-title-file e --pr-body-file repetem e escopam por branch (--pr-body-file <branch>=<path>; um valor simples aplica-se à ponta); ccx vcs lane --json é o que informa quais PRs da pilha inferior estão sem corpo.
Uma recusa é informação, não uma repetição: nothing to commit significa que um envio anterior já aterrissou isso; o ship reproduz um needs_restack do gt sozinho. Quando o ship ainda recusa porque um branch está fora de seu pai ou o trunk moveu, execute ccx vcs stack submit (ou entregue a recusa literalmente ao dono da pilha quando outra lane a possui), então reexecute o ship.
O ship informa o branch, o número e URL do PR, e o sha da cabeça. A entrega precisa de todos os quatro.
Entregue a vigilância
Resolva ${CLAUDE_PLUGIN_ROOT} para seu caminho absoluto no chamador no momento da criação e preencha poll: com o comando pronto para executar. A variável é substituída no texto desta skill; o subagente não a recebe. Passe a frase após poll: literalmente para que o vigia possa armar o script mesmo se o arcabouço omitir sua definição de agente.
Agent(subagent_type: "open-pr:pr-watcher", run_in_background: true,
name: "pr-watch-<number>",
prompt: "pr: <number>\nurl: <url>\nrepo: <owner/name>\nhead: <sha>\n"
"branch: <branch>\nlane: <gt|jj|git>\ncache: <dir>\nownership: <mine|foreign>\n"
"poll: bash \"<abs plugin root>/scripts/pr-poll.sh\" <owner/name> <number> <cache>/pr/<number>.json\n"
"Run PR_POLL_WINDOW=40 <poll: command> alone as foreground Bash with timeout: 60000, rerun it at once on DONE window-elapsed, and keep calling until a final verdict: never arm a Monitor or background the call, since neither wakes a subagent, never wrap it in a loop, and never substitute a hand-rolled gh pr checks/bk loop, which cannot see a queue landing. On DONE ready-to-merge, SendMessage main before anything else.")
Após a criação, verifique se o script de sondagem escreveu seu arquivo de estado:
bash "${CLAUDE_PLUGIN_ROOT}/scripts/pr-watch-armed.sh" "<cache>/pr/<number>.json"
Em saída 1, SendMessage para o vigia a mesma linha poll: novamente e execute a verificação uma segunda vez. Se falhar novamente, relate ao usuário que a vigilância está desarmada. Uma criação de agente sozinha não prova que o script está em execução.
Um vigia por PR — um segundo no mesmo PR empurraria sobre o primeiro. Todo relatório exceto evicted encerra a vigilância; SendMessage pelo nome a retoma para a próxima rodada. Uma mensagem evicted: <reason> <detail> chega no meio da execução e o vigia continua vigiando para que o chamador re-enfileire por rótulo ou na interface do Graphite. Envie qualquer correção antes de re-enfileirar; o chamador decide quando re-enfileirar.
Após um relatório pronto para mesclar: open-pr.on-ready
Um relatório ready-to-merge significa que o PR está verde, mesclável e aprovado: toda verificação passou, toda suíte de verificação do GitHub Actions na cabeça foi concluída, mergeable é verdadeiro, o estado da fila foi lido de forma limpa (nunca QUEUE unknown), e o PR não está enfileirado nem removido em sua cabeça atual. Nenhuma revisão mais recente do revisor é CHANGES_REQUESTED, e o mergeable_state do REST não é blocked (o estado para uma aprovação necessária ausente). Um relatório ready-to-merge downstack #<n> é um PR empilhado esperando pelo PR da pilha inferior # (incluindo quando a verificação de mesclabilidade do Graphite é a única verificação não concluída em uma pilha Graphite legada). O PR em si está pronto, mas ele aterrissa apenas com sua pilha inferior: nomeie # na pergunta e enfileire a pilha, nunca este PR sozinho.
Leia o CLAUDE.md do usuário para uma destas linhas exatas:
open-pr.on-ready: offer-open(o padrão quando nenhuma linha está definida): nessa mesma volta, pergunte ao usuário através deAskUserQuestionse deve abrir a página do PR. Executegh pr view <number> --webapenas em um sim.open-pr.on-ready: offer-merge: nessa mesma volta, pergunte "mesclar # agora?" através deAskUserQuestion. Adicione o rótulo da fila do repositório apenas em um sim.
Nunca rotule ou abra apenas com o relatório. Sob a skill long-running, encaminhe o relatório para a mesa de aterrissagem; ela é dona da decisão independentemente da configuração.
Após adicionar o rótulo da fila a um PR cujo vigia já relatou ready-to-merge, retome esse vigia pelo nome para que ele vigie a fila através de verificações verdes até uma aterrissagem ou falha:
SendMessage(to: "pr-watch-<number>", message: "Queue label <label> added. Resume the queue watch on the same state file.")
Seu relatório chega como uma notificação no meio da tarefa — continue trabalhando até ele chegar. Quando ele relatar um julgamento
...
[truncado para tradução]
Mantenha a vigilância ativa
Depois de criar o vigia, o script de sondagem escreve seu arquivo de estado. Um agente sozinho não prova que o script está em execução; verifique sempre se ele armou. Se falhar, reenvie a linha de sondagem e verifique novamente.
Um vigia por PR — dois no mesmo PR se atropelam. Apenas evicted mantém o vigia ativo; todo outro relatório o encerra. Quando o PR estiver pronto para mesclar (ready-to-merge), pergunte ao usuário se deseja abrir a página do PR ou mesclá-lo, conforme configurado em CLAUDE.md.
Referências e recursos adicionais
Para detalhes sobre como lidar com repositórios que você não controla, consulte reference/oss.md. Para interpretar diretrizes e templates de PR, veja reference/guidelines.md. O layout do cache e o esquema do cartão de estilo estão em reference/style-cache.md. A tabela de transferência de voz completa e fallbacks estão em reference/voice.md. A mecânica de pilhas encadeadas está em reference/stack.md.