CommunityProgramación y desarrollogithub.com

zheref/ao

Pone la rama al día con su base — rebase cuando no se ha publicado nada, merge cuando ya se ha publicado, resuelve los conflictos mecánicos y se detiene en G5 mostrando ambos lados para los semánticos.

¿Qué es ao?

Ao es una habilidad especializada en manipulación de ramas de git, diseñada para entornos como Claude Code, Codex y Cursor. Su función principal es sincronizar una rama de trabajo con su base, decidiendo automáticamente si realizar un rebase (cuando no hay commits publicados) o un merge (cuando ya se han publicado cambios). Ao clasifica meticulosamente cada conflicto antes de resolverlo, distinguiendo entre conflictos mecánicos (resolubles automáticamente) y semánticos (que requieren intervención humana, deteniéndose en G5 con ambos lados mostrados). Es invocable directamente o como parte de flujos más complejos orchestrados por otras habilidades como $murasaki, $aka o $en. Nunca realiza push, force-push ni reescribe commits que ya estén en el remoto, garantizando la integridad del historial compartido.

Compatible con✓Claude Code✓Codex CLI~Cursor
npx skills add https://github.com/zheref/hatsu/tree/HEAD/surfaces/codex/ao

Installed? Explore more Programación y desarrollo skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

Preguntar en tu IA favorita

Abre un nuevo chat con esta habilidad de agente ya precargada.

Documentación

Ubicación de la política compartida: docs/DISCOVERY.md, docs/WORKFLOW.md, docs/LAUNCH-MIGRATION.md, docs/STANDALONE-ENTRY.md, docs/PROCESS.md, docs/using/README.md y docs/using/mirrors.md pertenecen a la raíz del plugin Hatsu resuelta, no al repositorio consumidor. En una superficie instalada, usa la raíz absoluta impresa por ten para leer esos archivos (re-resuelve a través de esa habilidad si no está disponible). Los enlaces relativos a continuación identifican ubicaciones de origen; una copia faltante en docs/ del consumidor no es una política faltante y no debe activar una presentación duplicada. Nunca copies ni inventes una segunda política en el repositorio de destino.

Ao — la rama, actualizada

Naturaleza: Manipulador. Reconciliar una rama contra su base es una operación del lado de git sobre un cuerpo de trabajo que no es solo tuyo, cualquiera que sea la naturaleza que haya creado el diff.

Pon la base debajo de mí, resuelve solo lo que es texto, y entrégame cualquier cosa que sea significado.

Ao es el primer paso de $murasaki, el tercero de $aka, y el paso que $en ejecuta cuando un PR se queda atrás. También se puede invocar solo. Toda su disciplina es una distinción — texto versus significado — y un rechazo: nunca hace push de lo que produce.


0. Entrada independiente — ya total

Ao ya lee el checkout en lugar de un invocador. § 2 lee el estado antes de cualquier cosa, § 3 decide rebase-vs-merge basado en si algo ha sido publicado, y from <base> lleva la base con nen/workflow.json → branch.base debajo de ella. docs/STANDALONE-ENTRY.md § 4 la lista como ya total; las cláusulas que se aplican son P1 — $ten ao cuando ningún compuesto la ejecutó, actualizando los prerrequisitos de esta fase (ten § 6) — y la base resuelviendo contra la referencia fetched origin/, que § 3 ya requiere.

Nada de una llamada independiente relaja § 6: un conflicto semántico es una parada G5 con ambos lados mostrados, y nunca se resuelve eligiendo el lado que hace que la ejecución continúe. Ao aún nunca hace push, nunca hace force-push, y nunca reescribe un commit que ya está en el remoto.

Devolución. Siguiente en la ejecución cableada: el invocador que necesitaba la rama actual — $murasaki, $aka o $en. No se hizo push, y la evidencia tomada antes de esta actualización está obsoleta si algún rastro rastreado se movió.


1. Invocación

$ao [from <base>]
nen parse ao --grammar "from [<base>]" --line "<la invocación, sin el prefijo $ao>"

Verificado en vivo en v0.3.0 (docs/ab/ao.md § 2.1): from release/1.4 → base: release/1.4; un simple from se analiza sin la cláusula, salida 0. La cláusula está anclada detrás de un literal por la razón que $spiritual-message § 1 registra.

Sin cláusula, la base es nen/workflow.json → branch.base, por defecto main cuando la clave o el archivo están ausentes. Nombra la base en voz alta antes de hacer fetch — una rama actualizada silenciosamente contra la base incorrecta es un diff que nadie puede leer después.

Un argumento o elemento de configuración faltante se solicita y se configura en línea (missing-argument, missing-configuration; WORKFLOW.md § 4 Preguntar, configurar, continuar).

2. Leer el checkout primero

nen wc classify --repo <ruta> --base <base> --json

Verificado en vivo en v0.3.0 (docs/ab/ao.md § 2.2), --json lleva exactamente lo que esta habilidad necesita antes de tocar nada: state.branch, state.isTrunk, state.dirty, state.aheadOfBase, state.existingCommitSubjects[], state.uncommittedPaths[].

Caso de nen wc classifyLo que hace ao
must-move — en la troncalRechazar. No hay nada que actualizar: la troncal es la base. Dilo y pasa el invocador a $breath o $tensho, lo que la situación requiera
on-branch-dirtyRechazar, nombrando las rutas no confirmadas que el verbo imprimió. Un merge o un rebase sobre trabajo no confirmado o se rechaza en las propias manos de git o entierra el trabajo en un conflicto que nadie puede desenredar. Confírmalo ($kokusen) o guárdalo deliberadamente, luego vuelve a ejecutar
on-branch-cleanProceder a § 3

nen wc classify no es un detector de conflictos, y un merge a medio terminar se lee como suciedad ordinaria — verificado en vivo (docs/ab/ao.md § 2.2). Ejecutado dentro de un merge sin resolver reporta on-branch-dirty con las rutas en conflicto contadas entre las "ruta(s) no confirmada(s)", sin decir nada sobre el merge en curso. Así que pregunta a git por uno antes de clasificar, nunca a .git/ en disco (en un worktree vinculado .git es un archivo): git rev-parse -q --verify MERGE_HEAD resolviendo, o git rebase --show-current-patch saliendo 0 (un rebase detenido en un parche: un conflicto, o una parada edit), significa que una operación anterior se detuvo aquí, y esta ejecución reporta ese estado y no inicia nada — nunca una segunda operación encima de ella, y nunca una re-ejecución de wc catch-up desde aquí, que confirmaría un merge con el mensaje predeterminado de git y sin una compilación re-probada (§ 5). Las otras respuestas de la sonda: 1 (un rebase pausado sin parche actual, en un break o un exec fallido) no es asunto de ao, así que la ejecución lo reporta con el propio --continue / --abort de git y se detiene aquí, nunca confiando en catch-up para rechazarlo, lo que un host todavía en nen 0.18.0 o 0.18.1 no hace (zheref/hatsu#182); 128 es no hay rebase, así que clasificar; cualquier otra cosa se deja a la fila de sonda no respondida de § 3.

3. Qué operación — rebase o merge, decidido por si algo fue publicado

Rebase cuando no se haya publicado nada en esta rama. Merge cuando se haya publicado algo. Reescribir un commit que otra persona ya pudo haber fetchado es la única operación de git que cuesta trabajo a otras personas, y el plano local nunca lo hace.

nen wc catch-up --repo <ruta> --base <base> [--strategy rebase|merge|auto] [--dry-run] [--json]

El verbo primero hace fetch, luego decide, y la decisión se toma contra lo que origin dice ahora, nunca contra lo que este checkout escuchó la última vez. auto (lo que ao pasa) hace rebase cuando nada de la rama está en @{upstream} y merge en caso contrario; --strategy rebase|merge nombra una solo donde el invocador tiene una razón, dicha en voz alta. La salida 0 reporta {base, strategy, before, after, behindBefore, aheadBefore, noOp}, y un noOp: true se reporta con ambos SHA, nunca como "nada que hacer". Cada otra salida, leída de nen v0.20.0:

SalidaQué esao
1, con un reporte cuyo conflicted[] no está vacíoun conflicto; la línea de aborto se imprime§ 4 toma el control
3, un reporte cuyas rutas conflicted[] están todas en el bloque mechanical de nivel superior de nen/contract.json (v0.20.0)un conflicto que nen clasificó como manifiesto, changelog o espejo; la línea de aborto y los comandos de cada clase se imprimen, ninguno ejecutado§ 4 toma el control, las clases y comandos de nen citados como evidencia; § 4 aún clasifica cada ruta por sí misma
1, sin reporteun fetch, estado o lectura de HEAD falló, un rebase o merge falló sin conflicto, o un --continue fallódetenerse: citar la oración de stderr de nen textualmente, decir que el árbol está como git lo dejó; nunca § 4
2, un rebase pausado en un break o un exec fallido (v0.18.2)no es el rebase de aocitar la oración de nen, que nombra git rebase --continue / --abort; nunca continuarlo o abortarlo
2, una sonda de rebase que git no respondió (v0.18.2)puede que no haya ningún rebasecitar la oración de nen y detenerse, sin nombrar ningún comando de git
2, cualquier otra cosaun rechazo antes de cualquier mutación: un árbol sucio, un --base que git rechaza, un --strategy que discrepa con la operación en curso, un git demasiado viejo para --end-of-options, sin raíz de repositoriocitarlo textualmente y detenerse
cualquier otra salidainesperadadetenerse y citarla
  • strategy: merge → la rama existe en el remoto → la base se fusionó.
  • strategy: rebase → nada publicado → la rama se reprodujo en origin/<base>.

Un rebase sin nada sobre lo que rebasar aún reescribe el SHA, y eso es esperado. Verificado en vivo: una rama ya sentada directamente en la punta de origin/<base> respondió "Successfully rebased and updated" y movió HEAD de c8826c7 a 84b0444 — mismo árbol, mismo mensaje, nuevo objeto de commit, porque el rebase reproduce el commit en lugar de notar que no es necesario. Es inofensivo aquí y solo aquí: § 3 hace rebase solo de una rama no publicada, así que el commit reescrito es uno que nadie ha fetchado. No es inofensivo reportarlo como "nada que hacer" — § 7 pide la base y su SHA resuelto, y una ejecución que dice sin cambios mientras HEAD se movió deja cada referencia posterior al SHA antiguo silenciosamente incorrecta.

Di cuál eligió el verbo y por qué, en una línea, desde su reporte, y nombra la actualización: "origin fetched; the branch is on @{upstream}, so strategy: merge, not a rebase."

RETIRADO en nen 0.5, reemplazado en 0.13. La mitad de merge se ejecutó a través de nen pr cascade-main --repo <ruta> --trunk <base> --no-push (verificado en vivo en v0.5.0, docs/ab/ao.md § Retired at nen 0.5) y la mitad de rebase no tenía verbo en ninguna bandera. Ambas mitades son ahora nen wc catch-up's, que nunca hace push. cascade-main mantiene su fila mutating en la tabla de automatización de izanami, incluyendo --no-push, y ya no es lo que ao llama.

4. Clasificar cada ruta en conflicto antes de resolver una

git -C <ruta> status --porcelain                    # las filas de conflicto
git -C <ruta> diff --name-only --diff-filter=U      # las rutas en conflicto, solas
git -C <ruta> ls-files -u                           # qué etapas tiene cada ruta

Verificado en vivo contra un fixture construido que lleva uno de cada uno (docs/ab/ao.md § 2.4):

PorcelainTipoEtapas presentes
UUboth-modified — ambos lados cambiaron el mismo archivo1 base, 2 nuestro, 3 suyo
AAadd-add — ambos lados crearon la misma ruta2 nuestro, 3 suyo; sin base
UD / DUdelete-modify — un lado eliminó lo que el otro editósolo el lado superviviente
DD, AU, UAlas formas más raras; clasificar por la misma tabla y nombrarlascomo git reporta

nen wc catch-up --json lleva conflicted[] en la salida 1 o 3, una entrada por ruta no fusionada, con ours y theirs textuales (y, desde nen.wc.catch-up/v0.2, la class de nen). Lo que no lleva es el tipo, así que la tabla de porcelain anterior aún se lee para eso, y § 6 muestra ours/theirs exactamente como el verbo los imprimió. La propia regla del verbo es la que vale la pena citar donde aterriza: nunca elige un lado.

Clasifica cada ruta antes de resolver cualquiera de ellas, e imprime la tabla. Una ejecución que resuelve las primeras tres y descubre que la cuarta es semántica ya ha gastado la confianza del mantenedor en las primeras tres.

5. Mecánico, o semántico

Mecánico — la resolución está determinada, por el repositorio, no elegida por nadie:

  • una región de solo adición a la que ambos lados añadieron (un bloque de importaciones, un .gitignore, una lista de changelog) — mantener ambas, en el orden que la propia convención del archivo da;
  • un archivo generado o bloqueado que el repositorio regenera (un lockfile, una instantánea, un espejo) — tomar el lado de la base y regenerar (espejos de Hatsu: bash scripts/surface_mirror_regenerate.sh), luego probarlo con la compilación declarada (nen shu build; la tabla de salida es $rasengan § 6's);
  • una divergencia pura de formato o espacios en blanco sin diferencia de comportamiento;
  • un cambio idéntico hecho en ambos lados.

Una colisión de versión de Hatsu puede sobrevivir a una catch-up limpia: ramas paralelas pueden haber elegido el mismo número. Después de cada catch-up, compara ambos manifiestos reales (.claude-plugin/plugin.json y .codex-plugin/plugin.json) con la base fresca. Si la versión de la rama es igual o menor que la de la base, vuelve a aumentar ambos a la misma versión estrictamente por encima de esa base antes de la preparación; actualiza la línea de versión en el fragmento existente de changelog.d/ de este esfuerzo también. Esto es autoría de Hatsu, no un re-aumento automático de nen wc catch-up. Después de que se haya decidido la siguiente versión, ejecuta bash scripts/plugin_version_refs.sh --from <antiguo> --to <nuevo> --body-file <borrador-local> para listar referencias rastreadas y líneas de borrador. Añade --write para reescribir las formas rastreadas declaradas y cada token exacto de versión antigua en líneas de borrador no ambiguas; lee las líneas review impresas, que permanecen sin cambios. El asistente nunca elige la versión, reescribe espejos generados o edita un PR remoto. Regenera los espejos con el comando anterior, luego actualiza los hechos del cuerpo invalidados por la catch-up:

Hecho del cuerpoRe-derivar después de catch-up
Versión del plugingit show HEAD:.claude-plugin/plugin.json y git show HEAD:.codex-plugin/plugin.json después de confirmar el aumento
Commits de cabeza y basegit rev-parse HEAD origin/<base> después del commit final y fetch
Figuras medidas contra la base (bytes, diff, cobertura, evidencia de revisión)re-medir contra esa base fresca y cabeza final
Número de PR en la línea Drivegh pr list --repo <propietario/nombre> --state open --head <rama> --json number,url; usa el PR actual devuelto
Línea de prerrequisitos del fragmento de changelogre-medir contra el contrato de dependencia actualizado y los prerrequisitos reales de este esfuerzo

Revisa el borrador local actualizado, luego usa nen pr edit-body como escritor remoto. Vuelve a ejecutar la comprobación de aumento contra la base fresca; el punto de rama original no puede probar esta comparación.

Semántico — cualquier cosa donde una persona tenga que preferir una intención a otra. UD/DU es siempre semántico: "eliminado" y "aún siendo editado" son dos creencias sobre si una cosa existe, y ningún algoritmo de merge mantiene la creencia. También lo es un UU donde ambos lados cambiaron el mismo comportamiento, y un AA cuyos dos archivos no son el mismo archivo.

El caso de libro de texto, verificado en vivo (docs/ab/ao.md § 2...

[truncado para traducción]

Individual skills in this repo

This repo contains 3 individual skills — each has its own dedicated page.

Skills relacionados