Herramientas de usuario

Herramientas del sitio


clase:daw:daw-proyecto:tema02

Diferencias

Muestra las diferencias entre dos versiones de la página.

Enlace a la vista de comparación

Ambos lados, revisión anteriorRevisión previa
Próxima revisión
Revisión previa
clase:daw:daw-proyecto:tema02 [2026/10/13 23:54] – Git: issues y tablero, dos ramas, ciclo de una rama, Closes #N, reglas y skill /git-flow claudeclase:daw:daw-proyecto:tema02 [2026/10/15 07:02] (actual) – [Claude Code y OpenCode] Lorenzo
Línea 1: Línea 1:
-====== 2. Git en el proyecto ======+====== 2. IA y agentes ======
  
-Objetivo del tema: que nadie vuelva a escribir a mano un comando de git del día a día. Al acabar, todo lo de git pasa por la skill ''/git-flow''.+Objetivo del tema: saber qué es lo que se va a usar durante todo el módulo. Es un repaso rápido de programar con agentes: qué es un agente, cómo funcionan Claude Code y OpenCode, qué es una skill, qué es un MCP y qué son los subagentes y los bucles de revisión. Nada de esto se profundiza aquí: lo que ya está en el [[cursos:sdd:start|curso de programación con IA]] se enlaza, y lo que es de este proyecto se cuenta en su tema (''AGENTS.md'' y la primera skill en el tema 3, la spec y el contexto en el tema 5, las revisiones en el tema 6).
  
-Lo que ya sabéis y aquí no se repite:+===== Qué es un agente =====
  
-  * Git básico, ''.gitignore'' y el formato de los mensajes de commit ''type(#issue):título'': [[clase:daw:daw:1eval:tema01#mensajes_de_commit|Despliegue 1]]. +Un **modelo de lenguaje** responde a un texto con otro texto. Un **agente** es ese modelo metido en un bucle con **herramientas**: puede leer y escribir ficheros, ejecutar comandos y mirar el resultado. La diferencia con un chat es esa: el chat te dice cómo cambiar un fichero; el agente lo cambia, compila, lee el error y vuelve a intentarlo.
-  * Ramas, los tipos de merge, conflictos y, sobre todo, **worktrees** y por qué uno por rama cuando se trabaja con agentes: [[clase:daw:daw:1eval:tema02#worktrees|Despliegue 2]]. +
-  * Scrum y los tableros de GitHub: [[clase:daw:proyecto:1eval:tema04#scrum_en_github|Proyecto 4]].+
  
-===== Issues y tablero =====+El bucle es siempre el mismo:
  
-Todo trabajo empieza por un **issue**. El issue es la unidad: de él sale la rama, su número va en los commits y al fusionar se cierra solo.+  - Recibe una petición («añade un endpoint que devuelva los clientes de una provincia»). 
 +  - Decide qué herramienta usar (leer ''ClienteController.java''). 
 +  - Ejecuta la herramienta y el resultado entra en la conversación. 
 +  - Con lo que ha visto, decide la siguiente (editar el fichero, lanzar ''mvn test''). 
 +  - Repite hasta que considera que ha terminado, y responde.
  
-El tablero es un **GitHub Project** del repositorio con tres columnas: //Todo//, //In progress// y //Done//. De sus automatizaciones (//Workflows// del proyecto) solo hace falta una, que viene activada de serie: **issue cerrado → Done**. El resto se hace a mano: al crear el issue se añade al tablero, y al empezar a trabajarlo se arrastra a //In progress//. Automatizar eso por línea de comandos no compensa.+Dos consecuencias que explican casi todo lo que viene después:
  
-Etiquetas: ''feature'' y ''bug''. No hacen falta más.+  * **Lo que el agente sabe es lo que tiene en la conversación.** No recuerda nada de la anterior. Lo que tenga que saber siempre, va en un fichero que lee al empezar (''AGENTS.md'', tema 3) o en uno que se le pasa (la spec, el plan). 
 +  * **Lo que el agente puede hacer es lo que sus herramientas y sus permisos le dejan.** Por eso en este módulo se le dan permisos justos y se le quitan los peligrosos (tema 3 y tema 5).
  
-Los issues se crean desde la web o con ''gh'':+El detalle, con los tipos de agente que existen, está en [[cursos:sdd:02-skills-agentes-mcp#agentes|Agentes]].
  
-<sxh bash> +===== Claude Code y OpenCode =====
-gh issue create --title "Alta de clientes" --label feature --body "Formulario de alta con nombre, NIF y email." +
-gh issue list +
-gh issue view 12 +
-</sxh>+
  
-===== Las ramas de este proyecto =====+Son los dos agentes de terminal que se usan en el módulo. Se abren en la carpeta del proyecto, leen sus instrucciones fijas y, a partir de ahí, se habla con ellos. Hacen lo mismo con nombres distintos:
  
-El modelo de ramas de Despliegue 2 tiene ''develop'', ''release'' y ''master''. Aquí, al ser un proyecto individual con un solo entorno, se recorta a dos:+^ ^ Claude Code ^ OpenCode ^ 
 +| Instrucciones fijas del proyecto | ''CLAUDE.md'' | ''AGENTS.md'' | 
 +| Skills | ''.claude/skills/'' | ''.claude/skills/'' (la misma carpeta) | 
 +| Modo plan: solo lee, no toca código | ''Shift+Tab'' hasta //plan mode// | tecla ''Shift+Tab'' | 
 +| Cambiar de modelo | ''/model'' | ''/models'' | 
 +| Ver cuánto contexto va usado | ''/context'' | junto a la caja de entrada | 
 +| Vaciar la conversación | ''/clear'' | ''/new'' | 
 +| Permisos | ''/permissions'' y ''.claude/settings.json'' | clave ''permission'' de ''opencode.json'' | 
 +| Servidores MCP | ''claude mcp add'' | ''opencode.json'' |
  
-  * ''develop'': la integración. Solo existe de verdad **en local**, en la carpeta principal del repositorio; en GitHub está porque es la rama por defecto y es donde se cierran los issues. Nunca se despliega. +Se usa cualquiera de los dos, y todo lo del proyecto (instrucciones, skills, specs) vale para ambos: lo único que cambia es la configuración. Cómo se instala y se maneja OpenCode, con su caja de entrada, sus modelos y su sesión, está en [[cursos:sdd:03-opencode|OpenCode]]; Claude Code es igual con los nombres de la tabla.
-  * ''main'': producción. Cada push a ''main'' despliega en el servidor (tema 6). Nunca se trabaja en ella.+
  
-Y por cada issue, una **rama de trabajo** en su propio worktree: 
  
-^ Cosa ^ Nombre ^ Ejemplo ^ +  * Modos de Claude code
-| Rama | ''<alumno>-<N>-<slug>'' | ''lorenzo-12-alta-clientes'' | +
-| Worktree | ''../<repo>-wt-<N>-<slug>'' | ''../mi-proyecto-wt-12-alta-clientes'' |+
  
-El número del issue en el nombre de la rama hace que la skill sepa siempre a qué issue pertenece, sin preguntarlo.+^ Modo ^ Leer ^ Editar en la propia carpeta ^ Comandos simples (mkdir, mv, cp, rm…) ^ Todo el resto ^ 
 +| **Manual** | ✅ | Pregunta | Pregunta | Pregunta | 
 +| **Accept Edits** | ✅ | ✅ | ✅ | Pregunta | 
 +| **Plan** | ✅ | No edita en modo plan | ✅ (revisado por el clasificador) | Pregunta | 
 +| **Auto** | ✅ | ✅ | ✅ | ✅ (revisado por el clasificador; bloquea lo peligroso pero continua) |
  
-**Sin pull requests.** En un proyecto individual nadie va a revisar el PR, así que es un trámite que no aporta nada: la rama se fusiona en ''develop'' **en local** y se hace push. La revisión del código la hará la IA antes de fusionar (tema 5).+  * Modos de opencode
  
-===== El ciclo de una rama =====+^ Modo ^ Leer ^ Editar en la propia carpeta ^ Comandos simples ^ Todo el resto ^ 
 +| Build | ✅ | ✅ | ✅ | ✅ (sin revisión; solo pregunta al leer .env o salir del workspace) | 
 +| Plan | ✅ | Denegado (solo escribe en ~/.opencode/plan) | ✅ | ✅ | 
 +===== El contexto ===== 
 + 
 +El **contexto** es todo lo que el modelo tiene delante en una conversación: las instrucciones fijas, las skills que ha cargado, los ficheros que ha leído, la salida de los comandos y todo lo hablado. Cada mensaje se lo reenvía entero. Dos cosas que hay que tener claras desde el primer día: 
 + 
 +  * **Es limitado y se llena.** Cuando está lleno, el agente trabaja peor y cada petición cuesta más. 
 +  * **Lo que no está en el contexto no existe para el agente.** Y lo que está de más, estorba: un log de doscientas líneas pegado entero tapa las tres que importan. 
 + 
 +De aquí sale la regla de oro del módulo, que ya aparecía en el tema 1: **una conversación por fase**, ''/clear'' entre fases, y lo que una fase necesita de la anterior va en un fichero. Las reglas concretas (qué modelo usar para qué, cuándo compactar) están en el tema 5, y la teoría en [[cursos:sdd:04-ingenieria#ingenieria_de_contexto|Ingeniería de contexto]]. 
 + 
 +===== Skills ===== 
 + 
 +Una **skill** es un fichero de instrucciones que el agente carga cuando toca. Es la forma de enseñarle cómo se hace algo **en este proyecto** sin repetírselo en cada conversación: cómo se cierra un issue, cómo se escriben los tests, qué convenciones sigue el backend. Es una carpeta con un ''SKILL.md'': 
 + 
 +<sxh yaml;title:.claude/skills/hola/SKILL.md> 
 +--- 
 +name: hola 
 +description: Saluda al usuario por su nombre. Usar cuando se invoque /hola. 
 +--- 
 +Saluda en castellano a la persona cuyo nombre llega en $ARGUMENTS. 
 +Si no llega ningún nombre, pregúntalo. 
 +</sxh>
  
-  - **Iniciar**: desde la carpeta principal (siempre en ''develop'', actualizada), crear la rama y su worktree. +Lo que importa de cada parte:
-  - **Trabajar** en el worktree. Commits pequeños con ''type(#N):título''. +
-  - **Actualizar**: si ''develop'' ha avanzado (otro issue que se ha terminado antes), traer ''develop'' a la rama con ''git merge develop''. Los conflictos se resuelven en la rama, nunca en ''develop''. +
-  - **Finalizar**: fusionar en ''develop'' con ''--squash'': todos los commits de la rama se funden en uno con el mensaje ''feat(#N): título''. Push de ''develop''. Borrar el worktree y la rama. +
-  - **Publicar**: cuando hay algo que sacar, ''develop'' → ''main'' con ''--ff-only'' y push.+
  
-Por qué ''--squash'' hacia ''develop'' y ''--ff-only'' hacia ''main'' está en [[clase:daw:daw:1eval:tema02#usos_de_merge|Usos de merge]].+  * **''description''** es lo que el agente lee para decidir si la carga. Dice qué hace y **cuándo usarla**. Una descripción vaga es una skill que nunca se carga o que se carga cuando no toca. 
 +  * **El cuerpo** es el procedimiento, escrito como se le explicaría a un compañero nuevo: pasos, en orden, con los comandos exactos y lo que hay que comprobar. 
 +  * **''$ARGUMENTS''** es lo que se escribe después del nombre: en ''/hola Ana'', ''Ana''. Las skills del módulo reciben así su subcomando (''/test e2e run'').
  
-==== El commit que cierra el issue ====+Cómo escribir una skill: se le pide al propio agente un primer borrador («escribe una skill que haga X con estos pasos») y se corrige. Se prueba lanzándola y mirando qué hace; si se salta un paso o se inventa uno, se afina el texto. Qué es una skill, cómo se escribe su descripción y los tipos que hay: [[cursos:sdd:02-skills-agentes-mcp#skills|Skills]]. Lo específico del proyecto (dónde van, los dos tipos que se usan, ''allowed-tools'') está en el tema 3, donde se escribe la primera.
  
-GitHub cierra un issue automáticamente cuando llega a la **rama por defecto** un commit cuyo mensaje contiene ''Closes #N''. Por eso ''develop'' es la rama por defecto, y por eso el commit de la fusión lleva el ''Closes'' en el cuerpo:+===== MCP =====
  
-<code> +Un **MCP** (//Model Context Protocol//) es un servidor que da al agente **herramientas nuevas**: abrir un navegador y ver una página, consultar la documentación actual de una librería, hacer consultas a una base de datos. El agente las usa como las suyas propias. Lo que es, cómo se conecta y qué servidores existen: [[cursos:sdd:02-skills-agentes-mcp#mcp|MCP]].
-feat(#12): Alta de clientes+
  
-Closes #12 +La diferencia con una skill: la skill es **conocimiento** (cómo se hace algo aquí); el MCP es **capacidad** (poder hacer algo que antes no podía). En el módulo se usan dos y ninguno más, Context7 y Playwright, y se configuran en el tema 5.
-</code>+
  
-Al hacer push de ''develop'', el issue 12 se cierra y el tablero lo pasa a //Done//. No hay que tocar nada en la web.+===== Subagentes y bucles =====
  
-===== Reglas para que la IA toque git =====+Un agente puede lanzar **otro agente** para una parte del trabajo: un **subagente**, con su propia conversación vacía y, a menudo, con instrucciones y herramientas propias. El principal le encarga la tarea, espera, y recibe **solo el resultado**: todo lo que el subagente ha leído por el camino se queda en su contexto, no en el del principal. Para eso sirven:
  
-Una skill que ejecuta git puede hacer daño si improvisa. Estas reglas van en la skill y no se negocian:+  * **Mantener limpio el contexto principal.** Buscar en qué ficheros se usa una clase lleva leer veinte; el subagente los lee y devuelve una lista de tres líneas. 
 +  * **Especializar.** Un subagente que solo revisa, con instrucciones de revisor y sin permiso para editar, no se deja llevar por lo que acaba de escribir. Un agente que revisa su propio código tiende a darlo por bueno; **otro agente, con otro contexto, no**.
  
-  * **Nunca ''git pull''**. Siempre ''git fetch --prune'' y ''git merge --ff-only origin/<rama>''. Así, si las historias han divergido, falla en vez de hacer un merge sorpresa. +Con subagentes se montan **bucles**: un agente hace, otro comprueba, y se repite hasta que la comprobación pasa. El patrón más útil es [[cursos:sdd:05-patrones-agenticos#ejecutor-revisor|Ejecutor-Revisor]]: el ejecutor implementa, el revisor compara el resultado con un criterio (la spec, las reglas de calidad, los tests) y devuelve hallazgos; el ejecutor corrige; otra vuelta. Lo que hace que un bucle funcione o se vuelva loco es su **condición de parada**: tiene que ser algo que se pueda comprobar, no «hasta que esté bien» ([[cursos:sdd:04-ingenieria#ingenieria_de_bucles|Ingeniería de bucles]]).
-  * **Nunca ''--force''**, ni ''--no-verify'', ni ''stash'', ni borrar worktrees con ''--force''. +
-  * **Nunca resolver un conflicto**. Si un merge da conflicto, la skill **se para**, enseña ''git status'' y dice qué comandos tiene que ejecutar el alumno. Resolver conflictos es trabajo humano. +
-  * **La carpeta principal siempre en ''develop''** y limpia. Si no lo está, la skill se para antes de hacer nada. +
-  * **Una operación por invocación**: ''/git-flow iniciar 12'', no «inicia y luego finaliza». +
-  * **''allowed-tools'' como lista blanca**: solo ''git'' y ''gh''. Nada de ''rm'', nada de escribir ficheros del proyecto.+
  
-===== Práctica: la skill /git-flow =====+En este módulo el bucle no está dentro de una herramienta: está **en el flujo**, con el alumno en medio ([[cursos:sdd:05-patrones-agenticos#human-in-the-loop_hitl|Human-in-the-loop]]). ''/sdd spec impl'' ejecuta, ''/code review'' revisa con otro contexto y deja los hallazgos en un fichero, el alumno decide, ''/code impl'' corrige, y la condición de parada la comprueba ''/git-flow finish'': tareas hechas, revisión sin hallazgos abiertos, tests en verde. Los tests son el **sensor** del bucle: la única comprobación que no depende de la opinión de nadie, ni de un agente ni de una persona.
  
-Se parte de la skill que ya enlaza Despliegue 2, {{ :clase:daw:daw:1eval:git-flow-skill.md |git-flow-skill.md}}, que es casi lo que hace falta. Pedir al agente que la adapte con estos cambios:+El resto de patrones (pipeline, orquestador, best-of-N...) están en [[cursos:sdd:05-patrones-agenticos|Patrones agénticos]]. No se usan en el módulo, pero conviene saber que existen para reconocerlos cuando una herramienta los lleva dentro.
  
-  * Quitar ''release'', ''bajar'' y ''subir''. Quedan **cinco operaciones**:+===== Lo que el agente no decide =====
  
-^ Operación ^ Qué hace ^ +Todo lo anterior hace el trabajo; nada de lo anterior decide **qué** trabajo. Qué se construye, si lo que ha salido es lo que se quería y si se da por bueno, lo decide una persona, y en el módulo eso tiene tres sitios fijos: el issue y la spec, el navegador y los tests, y la revisión antes de cerrar. El agente propone en ficheros y la persona decide entre comandos, nunca dentro de ellos. Es lo que hace que el día de trabajo del tema 1 sea posible sin que nadie se fíe a ciegas.
-| ''iniciar N'' | Lee el issue ''N'' con ''gh issue view'', deriva el slug del título, crea la rama ''<alumno>-<N>-<slug>'' desde ''develop'' actualizada y su worktree hermano, y hace push de la rama | +
-| ''commit'' | Mira ''git status'' y ''git diff'' del worktree actual y **agrupa los cambios por intención**, no por fichero: un commit por cosa hecha, cada uno con ''type(#N):título''. El ''N'' lo saca del nombre de la rama. Enseña los commits que va a hacer antes de hacerlos | +
-| ''actualizar'' | Trae ''develop'' a la rama del worktree actual | +
-| ''finalizar'' | ''actualizar'', ''--squash'' en ''develop'' con el mensaje ''feat(#N): <título del issue>'' y ''Closes #N'' en el cuerpo, push de ''develop'', borrar rama remota, worktree y rama local | +
-| ''publicar'' | ''develop'' → ''main'' con ''--ff-only'' y push de ''main'' |+
  
-  * El nombre del alumno para las ramas se lee de ''AGENTS.md'' (una línea: «las ramas empiezan por ''lorenzo-''»). +===== Ejercicios =====
-  * Añadir ''Bash(gh issue view:*)'' a ''allowed-tools''. +
-  * ''finalizar'' y ''actualizar'' deducen la rama del worktree en el que se ejecutan, como ya hace la skill original.+
  
-En el tema 3 ''iniciar'' y ''finalizar'' crecen para levantar y parar los contenedores, y en el tema 5 ''finalizar'' lanza antes la revisión por IA.+==== Ejercicio 1 ==== 
 +  * Instala Claude Code y OpenCode siguiendo el curso. Abre cada uno en una carpeta vacía y pídele que cree un ''hola.txt'' con la fecha de hoy. Mira qué herramientas ha usado y qué permisos te ha pedido. 
 +  * Con ''/context'' (o el indicador de OpenCode), anota cuánto contexto ocupa una conversación recién abierta y cuánto después de pedirle que lea un fichero grande.
  
-**Prueba**: crear dos issues pequeños (por ejemplo, «Página de inicio con el nombre del proyecto» y «README con cómo arrancar»), iniciarlos los dos, trabajarlos en paralelo en sus dos worktrees, hacer sus commits con ''/git-flow commit'', finalizarlos y comprobar en GitHub que los issues se han cerrado y están en //Done//. Después ''/git-flow publicar'': ''main'' avanza, aunque todavía no despliega nada.+==== Ejercicio 2 ==== 
 +  * Crea la skill ''/hola'' del tema y comprueba que ''/hola Ana'' saluda y que ''/hola'' a secas pregunta el nombre. 
 +  * Cambia la ''description'' por una vaga («una skill de saludo») y comprueba qué pasa cuando le pides «salúdame» sin invocarla. Vuelve a dejarla bien.
  
-<note>''AGENTS.md'' tiene que decir desde ahora: «git se maneja solo con ''/git-flow''; no ejecutes comandos de git que cambien el repositorio fuera de esa skill». Si no, el agente hará ''git commit'' por su cuenta a mitad de una tarea.</note>+==== Ejercicio 3 ==== 
 +  * En Claude Code, pídele que revise un fichero de código cualquiera **usando un subagente** y que te devuelva solo los hallazgos. Compara el ''/context'' antes y después con el de pedirle la misma revisión sin subagente. 
 +  * Pídele que corrija uno de los hallazgos y que después un subagente **distinto** compruebe que está corregido. Es el bucle ejecutor-revisor hecho a mano; en el tema 6 lo harán las skills.
  
clase/daw/daw-proyecto/tema02.1791928452.txt.gz · Última modificación: por claude