Abrir PR
Abre un pull request para la rama actual en la plataforma de PR detectada (Azure DevOps o GitHub). El título y la descripción se redactan para que coincidan con las convenciones de PRs anteriores del usuario que invoca en lugar de un estilo fijo de equipo, y se muestran para confirmación. Nunca se crea un PR sin aprobación explícita — abrir un PR es una acción hacia el exterior.
Este skill es independiente del backend: los mecanismos específicos de la plataforma (crear PR, verificar duplicados, etiquetar, enlazar backport) viven en documentos de referencia del adaptador de backend bajo resources/backends/, y los mecanismos de enlace de tickets viven en documentos de referencia del adaptador de rastreador bajo resources/trackers/. El cuerpo del skill detecta la plataforma y el rastreador, carga los adaptadores correspondientes y sigue sus recetas — no contiene análisis de campos específicos de az/gh ni análisis de ID/URL específicos del rastreador. Toma prestadas las barreras de seguridad de un flujo de creación de PR, pero es deliberadamente más limitado: abre un PR para la rama tal como está — publicándola primero en el remoto si aún no está allí, ya que el PR la necesita. No fusiona la rama base, no elimina ramas y no revisa comentarios de revisión (eso es resolve-pr-comments).
Paso 0 — Detectar plataforma + rastreador, cargar adaptadores, anunciar
Antes de cualquier otra cosa, resuelve a qué backend y rastreador apunta esta ejecución:
- Plataforma de PR — desde
git remote get-url origin:dev.azure.como*.visualstudio.com→ Azure DevOps (resources/backends/azure-devops.md).github.com→ GitHub (resources/backends/github.md).- Ambiguo u otro host → expresa la limitación y pregunta al usuario a qué plataforma apuntar en lugar de adivinar.
- Rastreador de incidencias (precedencia — la primera coincidencia gana):
- La configuración explícita gana: si
.claude/pr-lifecycle.json(opcional, en.gitignore) fija el tipo de rastreador, úsalo (y toma la URL base de Jira de allí). - de lo contrario infiere el tipo a partir de una referencia de ticket existente:
[A-Z][A-Z0-9]+-\d+→ Jira (cualquier plataforma); una referencia de incidencia numérica simple → GitHub Issues — pero solo en un remoto de GitHub (en Azure DevOps#<n>es un enlace a un ítem de trabajo, no una incidencia de GitHub, por lo que un número simple no implica GitHub Issues allí). - de lo contrario valor por defecto según la plataforma: un remoto de GitHub → GitHub Issues (configuración cero); un remoto de Azure DevOps → Jira.
- Sin ticket → no producir línea de rastreador (igual que hoy).
- Jira →
resources/trackers/jira.md; GitHub Issues →resources/trackers/github-issues.md.
- La configuración explícita gana: si
- Anunciar la plataforma y el rastreador detectados para que una suposición incorrecta silenciosa sea imposible.
Cargar los adaptadores de backend y rastreador correspondientes y ejecutar las partes específicas de la plataforma/rastreador de los pasos siguientes a través de ellos. La única unión con el backend en este cuerpo es reconocer la cadena del remoto para seleccionar el adaptador — sin acceso a campos más allá de eso. (Las rutas de los adaptadores son relativas a la raíz del plugin — plugins/pr-lifecycle/resources/backends/ y resources/trackers/ — no al directorio del skill).
Paso 1 — Detectar la rama objetivo
- Leer la rama por defecto del propio repositorio; nunca asumir una.
git symbolic-ref --short refs/remotes/origin/HEADproduceorigin/<rama>— elimina el prefijo. Esa referencia está escrita porgit clone, por lo que un remoto creado congit init+git fetchpuede carecer de ella; entonces pregunta directamente al remoto congit ls-remote --symref origin HEAD, que es de solo lectura y no cambia el estado local. - Solo cuando ninguna se resuelve, recurre a la que el remoto realmente tenga de
main/master— y si ambas existen, pregunta. Un repositorio en medio de un cambio de nombre mantiene la anterior como una rama obsoleta, por lo que elegir en silencio basaría el PR en el objetivo equivocado, lo que también invalidaría el conteo de avance del Paso 2 y el historial del que el Paso 3 aprende la convención del usuario. - Si la rama actual apunta a una línea de lanzamiento (por ejemplo,
release/2.5), trátala como un backport (ver el formato de backport a continuación). - Si el objetivo correcto es genuinamente ambiguo, pregunta en lugar de adivinar.
Paso 2 — Precondiciones (detener e informar si alguna falla)
Ejecutar esto antes de redactar cualquier cosa, porque cada una es un bloqueador común en la primera ejecución:
- Tiene commits para el PR. La rama debe estar por delante del objetivo:
git fetch, luegogit rev-list --count origin/<objetivo>..HEADdebe ser mayor que 0. - En el remoto — publicar si es necesario. Crear el PR necesita la rama fuente en el remoto. Una rama no enviada aún no es una parada: después de la confirmación, open-pr la publica (
git push -u origin <rama>) como parte de la creación en el Paso 4. (Ejecutándose de forma no interactiva, no hace push y no crea — ver Paso 4). - Sin duplicado. Verificar si existe un PR abierto existente para esta fuente a este objetivo a través de la receta de verificación de duplicados del adaptador de backend. Si existe, detener y señalar al usuario hacia él — no abrir un segundo PR, y no modificar el existente aquí.
Paso 3 — Aprender la convención del usuario, luego redactar
Identificar al usuario desde git config user.email (preferido) y user.name, luego leer sus PRs fusionados recientes en este repositorio: git log <objetivo> --author="<email o nombre>" (probar ambas formas; tratarlo como "sin historial" solo cuando ambas no devuelvan nada). De los últimos varios, inferir formato del título y estructura de la descripción (seccionada vs una lista plana de viñetas) por mayoría — el más reciente por fecha de commit desempata, un solo PR anterior se usa directamente. Anunciar el resultado (aprendido de K de tus PRs anteriores o sin historial coincidente -> usando valor por defecto), para que una suposición incorrecta silenciosa sea imposible.
El aprendizaje cubre cómo este repositorio y este usuario escriben las cosas, no solo la tipografía: formato del título, estructura de la descripción (seccionada vs una lista plana de viñetas), y la forma del prefijo de ticket en el título — entre corchetes ([acme-123] …), simple (acme-123 …), un tipo de Conventional Commits (fix(scope): …), o sin prefijo. Leer la forma del mismo historial; si los PRs observados no llevan prefijo de ticket, no añadir uno. Los valores por defecto a continuación son lo que usar cuando no hay historial del que aprender, nunca un formato que imponer a un repositorio que visiblemente hace otra cosa.
El aprendizaje nunca debe eliminar o reordenar el contenido obligatorio a continuación — el enlace del ticket, el resumen y las viñetas; el diagrama en el punto 4 es opcional, y el pie de página de procedencia en el punto 5 está desactivado por defecto, pero cuando el pie de página de procedencia está activado el aprendizaje debe mantenerlo al final y nunca eliminarlo. No sesgar el aprendizaje hacia este repositorio si es de un solo autor — la convención que importa es la del usuario, en cualquier repositorio donde se ejecute el skill.
Formato por defecto (el fallback; la convención aprendida del usuario anula la presentación)
Título: derivar el ID del ticket y su formato del adaptador de rastreador:
- Rastreador Jira:
[acme-xxxxx] <resumen conciso de una línea>— la clave en minúsculas entre corchetes (el adaptador también proporciona la forma en mayúsculas para la URL). - Rastreador GitHub Issues:
#<n> <resumen conciso de una línea>— la referencia#<n>en lugar del formato de corchete. - Sin ticket encontrado: omitir la línea de ticket y titularlo como este repositorio titula los PRs sin ticket.
ad-hoc <resumen>es el fallback solo cuando el historial en el Paso 3 no te dio nada que copiar — es un marcador de un equipo, no una convención que introducir en un repositorio que nunca la ha usado. Un<resumen>simple es el valor por defecto más seguro. - Dos o más IDs de ticket diferentes significa preguntar cuál, en lugar de tomar el primero en silencio.
Descripción (PR estándar):
- Enlace del ticket — construido por el adaptador de rastreador: para Jira,
https://<jira_base_url>/browse/<CLAVE>(clave en mayúsculas); para GitHub Issues,#<n>(GitHub enlaza automáticamente una incidencia del mismo repositorio). Esta es la primera línea para que la plataforma lo enlace automáticamente; omitir toda la línea solo cuando no haya ticket. - Resumen — una o dos frases.
- Descripción — una lista de viñetas, una viñeta por cambio discreto como acción más breve por qué/impacto. Omitir identificadores de archivo / clase / método / ruta — describir la intención, no pegar el diff.
- Un diagrama ASCII corto, envuelto en un bloque de código con delimitadores (opcional) — incluir uno solo cuando una imagen permita al revisor comprender el cambio más rápido que la prosa; de lo contrario, omitirlo. Cuando se incluya: un diagrama de estructura monoespaciado real (cajas / flechas, o un árbol / tabla pequeño — nunca prosa disfrazada de diagrama), mantenido a alto nivel, envuelto en un bloque con delimitadores de triple comilla invertida, dibujado con glifos ASCII simples (
+ - | > v), no Mermaid; dividir cualquier diagrama ancho o complejo en otros más pequeños en lugar de forzar un bloque ilegible. Guía completa de dibujo, justificación de los delimitadores/codificación y una forma ilustrativa:resources/diagram-guidance.md. - Marcadores de procedencia de IA (opt-in — desactivados por defecto) — el pie de página (un separador
---, luego🤖 _Redactado con Claude Code._) y la etiquetaai-assistedaplicada en el Paso 4 se añaden solo cuando la solicitud de invocación pide explícitamente marcar / etiquetar / señalar el PR como asistido por IA (o pasa un opt-in explícito). En ausencia de esa redacción — incluyendo cada llamada automatizada del pipelineresolve-issue, que no lleva dicha redacción — no añadir ninguno. Anunciar la decisión en la misma línea que el resultado de la plataforma / rastreador / aprendizaje (procedencia: off (di "marcar como asistido por IA" para añadir), oprocedencia: on (pie de página + etiqueta de mejor esfuerzo)) para que un marcador eliminado en silencio sea imposible. Cuando está activado, el pie de página es el último elemento en cada ruta — añadirlo después del cuerpo de la convención aprendida y nunca dejar que el aprendizaje lo elimine o reordene — y se renderiza de forma idéntica en Azure DevOps y GitHub, el marcador portátil; la etiqueta es la insignia nativa de la plataforma que lo acompaña (mejor esfuerzo — ver Paso 4). Si un equipo alguna vez necesita divulgación obligatoria de IA para auditoría, reintroducirla entonces como una bandera de configuración — deliberadamente no construida ahora.
Backport (el objetivo es release/*):
- Título (rastreador Jira):
[acme-xxxxx] [release] <resumen>; (rastreador GitHub Issues):#<n> [release] <resumen>. - La descripción es el enlace del ticket, luego
cherry pick desde <enlace-PR>donde el adaptador de backend proporciona la sintaxis del enlace-PR (Azure DevOps!<número_pr>, GitHub#<número_pr>— ambos se renderizan como un enlace a ese PR), luego — solo cuando la procedencia está activada (Paso 3, punto 5) — el pie de página de procedencia de IA (---+🤖 _Redactado con Claude Code._). Sin bloque de resumen, viñetas o diagrama — la revisión real ocurrió en el PR original. - Preguntar al usuario (o aceptar como entrada) el número del PR fuente del que se hizo el cherry-pick, y reutilizar el resumen de una línea de ese PR para
<resumen>. Un backport aprende solo el formato del título, no la estructura de la descripción.
En cada ruta (incluyendo el backport): el título y la descripción están en inglés. No añadir un trailer Co-Authored-By de git propio — es una preocupación de commits, no de descripciones de PR, y si este repositorio quiere uno es decisión del repositorio, observable desde su propio historial (git log -n 50 --format=%b | grep -c '^Co-Authored-By') en lugar de algo que este skill decida. Por defecto, no añadirlo; si los commits del repositorio lo llevan rutinariamente, seguir eso en lugar de anularlo. El pie de página de procedencia de IA y la etiqueta ai-assisted son algo diferente y están desactivados por defecto — añadidos solo con el opt-in explícito descrito en el Paso 3 (pie de página) y aplicado en el Paso 4 (etiqueta) — y nunca son el trailer prohibido.
Paso 4 — Presentar, confirmar, crear
Mostrar el título y la descripción redactados y permitir al usuario editarlos. Luego:
- Independiente: crear solo después de que el usuario confirme explícitamente. Si la rama fuente aún no está en el remoto, publicarla primero (
git push -u origin <rama>), luego crear el PR a través de la receta de creación del adaptador de backend — escribiendo la descripción completa en un archivo temporal y pasándolo como la bandera de archivo de cuerpo del adaptador, nunca como una cadena en línea. El adaptador documenta las trampas de codificación de archivos de la plataforma (por ejemplo, las peculiaridades deaz.cmdcp1252/UTF-8@<archivo>en Azure DevOps) y — solo cuando la procedencia está activada (Paso 3) — cómo se aplica la etiquetaai-assisted(Azure DevOps crea la etiqueta en línea mediante--labels; GitHub la añade después de la creación congh pr edit --add-label, porquegh pr create --labelaborta si la etiqueta no existe). Cuando está activada, la etiqueta es de mejor esfuerzo en cualquier caso (ver Límites expresados); por defecto, no se aplica ninguna etiqueta. Devolver la URL del PR. - No se puede obtener una confirmación (ejecutándose de forma no interactiva, o dentro de un subagente que no puede solicitar): no hacer push de la rama y no crear el PR. Imprimir el título y la descripción preparados para que el usuario los cree manualmente, y decirlo. No usar una bandera de abrir en navegador (por ejemplo, Azure DevOps
--open) en un contexto no interactivo. Cuando la procedencia estaba activada, la descripción impresa ya lleva el pie de página; indicar al usuario que añada la etiquetaai-assistedcuando cree el PR. Por defecto (sin opt-in), no se imprime ni menciona ningún marcador.
El invariante: nunca publicar la rama ni abrir un PR sin una confirmación humana explícita — ambas son acciones hacia el exterior.
Barreras de seguridad
- Nunca resolver conflictos de fusión automáticamente — detener e informar de ellos.
- Nunca eliminar ramas.
- Nunca hacer push forzado sin una solicitud explícita.
Límites expresados
- Si la herramienta de PR de la plataforma detectada falta o no está autenticada (ver la precondición de cada adaptador de backend — por ejemplo,
az+ la extensiónazure-devopspara Azure DevOps,ghautenticado para GitHub), decirlo e imprimir el título y la descripción preparados para creación manual — no fallar en silencio. - La convención aprendida es de mejor esfuerzo: si un flujo de trabajo de squash no dejó cuerpo de descripción, el formato aún proviene del asunto del commit y la estructura recurre al valor por defecto — anunciado, no en silencio.
- Los marcadores de procedencia están desactivados por defecto — sin pie de página y sin etiqueta a menos que la solicitud de invocación opte explícitamente (Paso 3, punto 5). Cuando está activado, la etiqueta
ai-assistedes de mejor esfuerzo: si la plataforma la rechaza (una organización que no permite etiquetas de PR ad-hoc en Azure DevOps, o una etiqueta que aún no existe en GitHub), eliminar la etiqueta, crear el PR solo con el pie de página (el marcador activado) y decirlo — el adaptador de backend documenta el comportamiento por plataforma.