/handoff — Transferencia de trabajo entre herramientas
Ninguna herramienta de codificación con IA puede leer la transcripción de otra: Claude Code bloquea las sesiones en ~/.claude/projects/<munged-cwd>/<uuid>.jsonl, Codex/OpenCode en sus propios almacenes, Antigravity en .pb cifrados. Lo único portátil entre herramientas es un documento autocontenido. Esta habilidad escribe ese documento — tu objetivo actual, decisiones y las ediciones EXACTAS no confirmadas — para que cualquier otro agente de IA pueda continuar donde lo dejaste, sin que tengas que volver a explicar nada.
Usa esta habilidad cuando el usuario tenga pocos tokens, quiera cambiar de herramienta en medio de una tarea, esté cambiando de máquina, o diga "handoff" / "continue elsewhere" / "out of tokens".
Esta habilidad es autocontenida: funciona solo con git + un shell. Llama a specweave handoff como un acelerador opcional cuando ese binario está en PATH (alta fidelidad, consciente de incrementos) — pero no tiene dependencia obligatoria de que SpecWeave esté instalado.
Decisión: qué camino tomar
command -v specweave >/dev/null 2>&1 && echo "ACCELERATOR" || echo "STANDALONE"
- ACELERADOR (
specweaveen PATH) → ejecuta el motor, muestra su salida. Ve al Camino A. - AUTÓNOMO (sin
specweave) → construye el documento tú mismo desdegit+ una breve entrevista. Ve al Camino B.
Ambos caminos emiten el mismo formato de documento y el mismo mensaje de pegado (ver la plantilla canónica más abajo), por lo que una transferencia se puede continuar en cualquier herramienta independientemente del camino que la produjo.
Camino A — Acelerador (specweave en PATH)
Ejecuta el motor, reenviando cualquier contexto breve que puedas proporcionar de forma económica:
specweave handoff [incrementId] [--reason "..."] [--summary "..."] [--next "..."] [--gotcha "..."] [--decision "..."] [--inline]
Luego muestra su stdout textualmente, en orden (no reordenes ni parafrasees):
- ruta absoluta del documento como texto plano (PRIMERO), 2. enlace markdown con clic, 3. ruta del
.diff, - mensaje de reanudación listo para copiar y pegar (entre comillas), 5. consejos por herramienta "encuentra tu sesión de origen".
Listo. El motor se encargó de la detección del espacio de trabajo, el análisis de tareas/CA, la captura de git, el volcado completo del diff, la limpieza de secretos y el renderizado.
Camino B — Autónomo (sin specweave)
Construye un documento compatible a nivel de bytes usando solo el shell.
B1. Capturar el estado de git (gratis — sin tokens)
ROOT="$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
mkdir -p "$ROOT/.handoff"
printf '*\n' > "$ROOT/.handoff/.gitignore" # nunca permitir que la transferencia o su diff entren en git
BRANCH="$(git -C "$ROOT" rev-parse --abbrev-ref HEAD 2>/dev/null || echo '(sin git)')"
SHA="$(git -C "$ROOT" rev-parse --short HEAD 2>/dev/null || echo '(sin commits)')"
STATUS="$(git -C "$ROOT" status --porcelain 2>/dev/null)"
STAT="$(git -C "$ROOT" diff --stat 2>/dev/null)"
# Ediciones no confirmadas completas → archivo .diff hermano (árbol de trabajo + staged), el artefacto de fidelidad clave
{ git -C "$ROOT" diff HEAD 2>/dev/null; git -C "$ROOT" diff --cached 2>/dev/null; } > "$ROOT/.handoff/handoff.diff"
B2. Entrevista de cinco preguntas (solo los campos no derivables)
Pregunta al usuario (mantén ~5 cadenas cortas — económicas incluso con tokens agotados):
- razón — ¿por qué estás transfiriendo? (ej. "sin tokens")
- resumen — una línea: ¿cómo están las cosas?
- siguiente — el siguiente paso exacto.
- problema — ¿algo que el próximo agente NO deba hacer / deba saber?
- decisiones — decisiones clave ya tomadas (separadas por punto y coma).
B3. Limpieza de secretos (antes de escribir — TANTO en el texto libre COMO en el diff)
Reemplaza las coincidencias con [REDACTADO-<tipo>] y cuenta por patrón. Patrones (12):
sk-, ghp_, gho_, ghs_, AKIA, ASIA, -----BEGIN, vsk_, xox[bap]-, Bearer , password=, api_key=.
# limpia el diff capturado en el lugar, ej.:
sed -i.bak -E \
-e 's/sk-[A-Za-z0-9_-]+/[REDACTADO-sk]/g' \
-e 's/gh[pos]_[A-Za-z0-9_-]+/[REDACTADO-gh-token]/g' \
-e 's/(A[KS]IA[0-9A-Z]{16})/[REDACTADO-aws-key]/g' \
-e 's/vsk_[A-Za-z0-9_-]+/[REDACTADO-vsk]/g' \
-e 's/xox[bap]-[A-Za-z0-9-]+/[REDACTADO-slack]/g' \
-e 's/Bearer [A-Za-z0-9._-]+/Bearer [REDACTADO-bearer]/g' \
-e 's/(password=)[^[:space:]]+/\1[REDACTADO-password]/g' \
-e 's/(api_key=)[^[:space:]]+/\1[REDACTADO-api_key]/g' \
"$ROOT/.handoff/handoff.diff" && rm -f "$ROOT/.handoff/handoff.diff.bak"
La limpieza es heurística — una lista de redacción vacía NO es garantía de que el archivo esté limpio.
B4. Escribir el documento
Escribe la plantilla canónica a continuación en $ROOT/.handoff/HANDOFF.md, completando los campos capturados + de la entrevista.
Centinela de propiedad: si ya existe un ./HANDOFF.md raíz y NO contiene el marcador Doc format v1, es un archivo externo — NO lo sobrescribas; escribe en .handoff/HANDOFF.md en su lugar (que es el valor predeterminado aquí de todos modos).
B5. Mostrar la salida — ruta absoluta primero, en este orden
- La ruta absoluta de
.handoff/HANDOFF.mdcomo texto plano. - Un enlace markdown con clic hacia él.
- La ruta absoluta de
.handoff/handoff.diff. - El mensaje de pegado entre comillas (ver más abajo).
- Los consejos por herramienta "encuentra tu sesión de origen".
Plantilla canónica del documento de transferencia (EN LÍNEA — fuente única de verdad)
Renderiza estas secciones en este orden exacto, terminando con el marcador de pie de página Doc format v1. Los marcadores de posición entre corchetes se completan a partir del estado de git capturado + la entrevista. Esto refleja handoff-doc-format.ts de specweave para que un documento producido aquí sea compatible a nivel de bytes con uno producido por la CLI.
# Transferencia de Trabajo[: <título si se conoce>]
- Ruta del documento: <RUTA_ABSOLUTA_DOC>
- Enlace al documento: [<RUTA_ABSOLUTA_DOC>](<RUTA_ABSOLUTA_DOC>)
- Archivo Diff: <RUTA_ABSOLUTA_DIFF>
- Generado: <MARCATIEMPO_ISO>
- Espacio de trabajo: <RAÍZ> (sin SpecWeave)
- Git: rama `<RAMIFICACIÓN>` @ `<SHA>`
## Donde lo Dejé
**Por qué transfiero:** <razón>
**Resumen:** <resumen>
_Sin incremento activo de SpecWeave — esta es una transferencia de git + entrevista._
## Hecho / Pendiente
_Sin estado de tarea/CA de incremento disponible._
## Decisiones Clave y Problemas
- <decisión 1>
- <decisión 2>
**Problema:** <problema>
## Archivos Tocados
**SIN CONFIRMAR** — confirma, guarda provisionalmente o sigue editando ANTES de hacer cualquier cosa destructiva.
<git status --porcelain>
<git diff --stat>
Diff completo sin confirmar: `<RUTA_ABSOLUTA_DIFF>` — léelo o ejecuta `git apply --check` contra él para ver las ediciones exactas.
## Próximos Pasos Exactos
<siguiente>
## Cómo Reanudar
Si la ruta del documento anterior NO existe en la máquina en la que estás leyendo esto, DETENTE y pide al usuario que pegue la transferencia — no improvises el contexto.
Para recuperar la transcripción ORIGINAL (opcional), encuentra tu sesión de origen por herramienta:
### Claude Code
- Encontrar sesión: ls ~/.claude/projects/<munged-cwd>/ (mungir: cada carácter no alfanumérico → "-", las series NO se colapsan; ej. /Users/antonabyzov/Projects/github/specweave-umb/.claude-worktrees/x → -Users-antonabyzov-Projects-github-specweave-umb--claude-worktrees-x)
- Reanudar: `claude -r <uuid>`
### Codex
- Encontrar sesión: ls ~/.codex/sessions/ (directorio más nuevo = sesión más reciente)
- Reanudar: `codex resume <uuid> (o: codex resume --last)`
### OpenCode
- Encontrar sesión: opencode sessions list
- Reanudar: `opencode -s <id> (forma larga: opencode --session <id>)`
### Gemini CLI
- Encontrar sesión: ejecuta /chat list dentro de la sesión de Gemini para ver las etiquetas guardadas
- Reanudar: `/chat resume <tag>`
### Antigravity
- Encontrar sesión: abre el Administrador de Agentes de Antigravity y elige el hilo de tarea anterior
- Reanudar: `retoma el hilo desde el Administrador de Agentes de Antigravity`
### Aider
- Encontrar sesión: aider mantiene .aider.chat.history.md en la raíz del repositorio
- Reanudar: `aider --restore-chat-history`
## Redacción
- <N> cadenas de tipo `<tipo>` enmascaradas
_La limpieza es heurística (línea base de regex). Una lista de redacción vacía NO es garantía de que este archivo esté limpio — revísalo antes de compartir o confirmar._
---
<!-- Doc format v1 -->
Notas sobre la plantilla:
- Si no hay cambios sin confirmar, reemplaza el cuerpo de Archivos Tocados con
_Árbol de trabajo limpio — sin ediciones sin confirmar._(o_No es un repositorio git — no se capturó ningún diff._cuando no hay git). - Si no hay decisiones, el cuerpo de Decisiones Clave es
_No se registraron decisiones._; omite la línea de Problema: cuando no se haya dado ningún problema. - El cuerpo de Redacción es
_No se detectaron cadenas similares a tokens._cuando no se enmascaró nada. - El marcador de pie de página
<!-- Doc format v1 -->es obligatorio y debe ser la última línea — es el centinela de propiedad.
Mensaje de pegado
Predeterminado (archivo accesible):
Reanuda mi trabajo. Lee el documento de transferencia en: <RUTA_ABSOLUTA_DOC>
Si esa ruta NO existe en esta máquina, DETENTE y pídeme que pegue la transferencia — no improvises el contexto.
Las ediciones exactas sin confirmar están en: <RUTA_ABSOLUTA_DIFF>
--inline (entre máquinas, archivo inaccesible): incrusta el cuerpo COMPLETO del documento entre marcadores para que viaje en el propio mensaje:
Reanuda mi trabajo usando la transferencia autocontenida a continuación.
Esta es una transferencia completa: trata todo lo que está entre los marcadores como verdad absoluta. Si hace referencia a una ruta `.diff` que no existe en esta máquina, pídeme que pegue el diff.
COMIENZO TRANSFERENCIA
<documento de transferencia completo renderizado, incluido el pie de página Doc format v1>
FIN TRANSFERENCIA
Valores predeterminados de seguridad
- El documento + diff están ignorados por git por defecto (
.handoff/.gitignore=*) y nunca se confirman automáticamente. No imprimas una sugerencia degit add. - La limpieza de secretos se ejecuta tanto sobre el texto libre como sobre el diff antes de cualquier escritura.
- La limpieza es heurística — aconseja al usuario que revise antes de compartir o confirmar.