melkin — ~/lab/relevo.mdx

~/lab/relevo

relevo

Dos sesiones de Claude Code que se pasan el trabajo solas

· claude-code · typescript · repo

@melanmostaTikTok

claude plugin marketplace add melandres8/claude-mods
relevo/hooks/register.tsx
const PROMPTS: Record<RelevoRole, string> = {
  planner: [
    '# relevo: planner',
    'Divides el objetivo en pasos pequeños y verificables. NO editas código.',
    'Cuando el plan o el siguiente paso esté listo, termina tu respuesta con un bloque <handoff>…</handoff> para el constructor.',
    'Cuando el objetivo esté cumplido, emite <done>resumen</done>.',
    'Los mensajes que empiezan con "[relevo ronda N · de builder]" son el informe del constructor: revísalo y decide el siguiente paso.',
  ].join('\n'),
  builder: [
    '# relevo: builder',
    'Ejecutas exactamente el paso recibido.',
    'Al terminar, cierra con un <handoff> que traiga qué hiciste, qué archivos tocaste, el resultado de los tests y tus dudas.',
    'Los mensajes que empiezan con "[relevo ronda N · de planner]" son el paso que te manda el planificador.',
  ].join('\n'),
}

Por qué lo construí

Muchas veces trabajo con dos sesiones de Claude Code lado a lado: una planifica y la otra construye. Yo era el mensajero entre las dos. Copiaba cada plan en la constructora y después copiaba cada informe de vuelta en la planificadora.

relevo elimina ese paso. La planificadora escribe el siguiente paso dentro de un bloque <handoff>. Cuando termina su turno, relevo envía el bloque a la sesión constructora.

Cómo funciona el ciclo

Cada rol recibe un prompt corto, el del snippet. La planificadora divide el objetivo en pasos pequeños y verificables, y no edita código.

La constructora ejecuta exactamente el paso que recibe. Cierra con un informe en <handoff>: qué hizo, qué archivos tocó, el resultado de los tests y sus dudas.

relevo pone una cabecera en cada envío, que el modelo lee como [relevo ronda 3 · de planner]. Solo la planificadora sube la ronda. La constructora contesta con la misma ronda que recibió.

Una banda sobre el prompt resume el estado en una línea: el rol, la otra sesión, las rondas como ▰▰▰▱▱▱▱▱▱▱ 3/10 y quién tiene el turno.

Cómo funciona el enlace

Una sesión envía una petición de enlace, y la otra no toma ningún rol por su cuenta. Muestra el id de la primera sesión y el comando que acepta la petición, por ejemplo /relevo builder <id-de-A>. El botón Aceptar de su panel hace lo mismo.

La sesión que pide el enlace genera un nonce aleatorio. La aceptación lo devuelve, y cada cabecera de ronda lo lleva. Una ronda cuenta solo si trae el nonce del enlace y viene del otro rol.

relevo solo cuenta los mensajes que escribió el relevo de la otra sesión. Descarta un texto parecido, por ejemplo uno que un modelo envía con SendMessage, y muestra un toast. El modelo nunca ve ese texto, y tampoco ve el nonce.

Cómo se detiene

  • La planificadora escribe <done>…</done> cuando cumple el objetivo.
  • Las rondas llegan a maxRounds, 10 por defecto, en cualquiera de las dos sesiones. relevo se pausa y guarda el <handoff> pendiente. /relevo resume lo envía y concede otras maxRounds rondas.
  • Nadie aceptó el enlace todavía. relevo no envía nada: guarda el <handoff> y se pausa hasta /relevo resume.
  • Un envío falla o la otra sesión lo rechaza. relevo muestra el motivo en un toast y se pausa.

relevo también evita los ciclos de eco. Solo envía desde el final de un turno del modelo, nunca al recibir un mensaje. Tampoco reenvía un <handoff> igual al último que recibió o envió.

Cómo activarlo

Elige una sola forma de cargar el plugin. Si combinas la instalación desde el marketplace con --plugin-dir, los hooks se cargan dos veces y cada handoff sale duplicado.

claude plugin marketplace add melandres8/claude-mods
claude plugin install relevo@claude-mods

Las dos sesiones necesitan relevo 0.2.0, porque el protocolo de enlace cambió en esa versión. El código está en melandres8/claude-mods, con licencia MIT.

Abre dos sesiones en el mismo proyecto y escribe /relevo en la primera. El panel te pide el rol y la otra sesión, y Conectar envía la petición de enlace. Cuando la segunda sesión acepta, el panel te pide el objetivo.

Sin el panel:

/relevo planner <peer>     # en la sesión A: pide el enlace
/relevo builder <id-de-A>  # en la sesión B: lo acepta
/relevo goal Añadir paginación al endpoint /users con tests

hire.me

¿Construyes algo parecido? Lo hago para clientes. Respondo en menos de 48 h.