/handoff — Transferência de Trabalho entre Ferramentas
Nenhuma ferramenta de codificação AI consegue ler o transcript de outra: o Claude Code trava sessões em ~/.claude/projects/<munged-cwd>/<uuid>.jsonl, Codex/OpenCode em seus próprios armazenamentos, Antigravity em .pb criptografado. A única coisa portátil entre ferramentas é um documento autocontido. Esta skill escreve esse documento — seu objetivo atual, decisões e as edições EXATAS não commitadas — para que qualquer outro agente AI possa continuar de onde você parou, sem você precisar reexplicar nada.
Use esta skill quando o usuário estiver com poucos tokens, quiser trocar de ferramenta no meio da tarefa, estiver mudando de máquina, ou disser "handoff" / "continue elsewhere" / "out of tokens".
Esta skill é autocontida: funciona apenas com git + um shell. Ela chama specweave handoff como um acelerador opcional quando esse binário está no PATH (alta fidelidade, ciente de incrementos) — mas não tem dependência obrigatória do SpecWeave instalado.
Decisão: qual caminho seguir
command -v specweave >/dev/null 2>&1 && echo "ACELERADOR" || echo "AUTÔNOMO"
- ACELERADOR (
specweaveno PATH) → execute o mecanismo, exiba sua saída. Vá para o Caminho A. - AUTÔNOMO (sem
specweave) → construa o documento você mesmo a partir dogit+ uma breve entrevista. Vá para o Caminho B.
Ambos os caminhos emitem o mesmo formato de documento e o mesmo prompt de colagem (veja o modelo canônico abaixo), para que uma transferência seja continuável em qualquer ferramenta, independentemente de qual caminho a produziu.
Caminho A — Acelerador (specweave no PATH)
Execute o mecanismo, encaminhando qualquer contexto curto que você possa fornecer de forma barata:
specweave handoff [incrementId] [--reason "..."] [--summary "..."] [--next "..."] [--gotcha "..."] [--decision "..."] [--inline]
Em seguida, exiba sua saída padrão textualmente, na ordem (não reordene nem parafraseie):
- caminho absoluto do documento como texto simples (PRIMEIRO), 2. link clicável em markdown, 3. caminho do
.diff, - prompt de retomada entre crases, 5. dicas por ferramenta "encontre sua sessão de origem".
Pronto. O mecanismo cuidou da detecção do workspace, análise de tarefa/CA, captura git, despejo do diff completo, limpeza de segredos e renderização.
Caminho B — Autônomo (sem specweave)
Construa um documento byte-compatível usando apenas o shell.
B1. Capture o estado do git (grátis — sem tokens)
ROOT="$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
mkdir -p "$ROOT/.handoff"
printf '*\n' > "$ROOT/.handoff/.gitignore" # nunca deixe a transferência ou seu diff entrar no git
BRANCH="$(git -C "$ROOT" rev-parse --abbrev-ref HEAD 2>/dev/null || echo '(sem git)')"
SHA="$(git -C "$ROOT" rev-parse --short HEAD 2>/dev/null || echo '(sem commits)')"
STATUS="$(git -C "$ROOT" status --porcelain 2>/dev/null)"
STAT="$(git -C "$ROOT" diff --stat 2>/dev/null)"
# Edições não commitadas completas → arquivo .diff irmão (árvore de trabalho + staged), o artefato de fidelidade principal
{ git -C "$ROOT" diff HEAD 2>/dev/null; git -C "$ROOT" diff --cached 2>/dev/null; } > "$ROOT/.handoff/handoff.diff"
B2. Entrevista de cinco perguntas (apenas os campos não dedutíveis)
Pergunte ao usuário (mantenha em ~5 strings curtas — barato mesmo com exaustão de tokens):
- motivo — por que você está transferindo? (ex.: "sem tokens")
- resumo — uma linha: como estão as coisas?
- próximo — o próximo passo exato.
- cuidado — algo que o próximo agente NÃO DEVE fazer / deve saber?
- decisões — decisões importantes já tomadas (separadas por ponto e vírgula).
B3. Limpeza de segredos (antes de escrever — tanto no texto livre QUANTO no diff)
Substitua correspondências por [REDACTED-<tipo>] e conte por padrão. Padrões (12):
sk-, ghp_, gho_, ghs_, AKIA, ASIA, -----BEGIN, vsk_, xox[bap]-, Bearer , password=, api_key=.
# limpe o diff capturado no local, ex.:
sed -i.bak -E \
-e 's/sk-[A-Za-z0-9_-]+/[REDACTED-sk]/g' \
-e 's/gh[pos]_[A-Za-z0-9_-]+/[REDACTED-gh-token]/g' \
-e 's/(A[KS]IA[0-9A-Z]{16})/[REDACTED-aws-key]/g' \
-e 's/vsk_[A-Za-z0-9_-]+/[REDACTED-vsk]/g' \
-e 's/xox[bap]-[A-Za-z0-9-]+/[REDACTED-slack]/g' \
-e 's/Bearer [A-Za-z0-9._-]+/Bearer [REDACTED-bearer]/g' \
-e 's/(password=)[^[:space:]]+/\1[REDACTED-password]/g' \
-e 's/(api_key=)[^[:space:]]+/\1[REDACTED-api_key]/g' \
"$ROOT/.handoff/handoff.diff" && rm -f "$ROOT/.handoff/handoff.diff.bak"
A limpeza é heurística — uma lista de remoção vazia NÃO é garantia de que o arquivo está limpo.
B4. Escreva o documento
Escreva o modelo canônico abaixo em $ROOT/.handoff/HANDOFF.md, preenchendo os campos capturados + da entrevista.
Sentinela de propriedade: se um ./HANDOFF.md raiz já existir e NÃO contiver o marcador Doc format v1, é um arquivo estrangeiro — NÃO o sobrescreva; escreva em .handoff/HANDOFF.md (que já é o padrão aqui de qualquer forma).
B5. Imprima a saída — caminho absoluto primeiro, nesta ordem
- O caminho absoluto de
.handoff/HANDOFF.mdcomo texto simples. - Um link clicável em markdown para ele.
- O caminho absoluto de
.handoff/handoff.diff. - O prompt de colagem entre crases (veja abaixo).
- As dicas por ferramenta "encontre sua sessão de origem".
Modelo de documento de transferência canônico (EMBUTIDO — fonte única da verdade)
Renderize estas seções nesta ordem exata, terminando com o marcador de rodapé Doc format v1. Os placeholders entre colchetes são preenchidos a partir do estado git capturado + entrevista. Isso espelha o handoff-doc-format.ts do specweave, para que um documento produzido aqui seja byte-compatível com um produzido pela CLI.
# Transferência de Trabalho[: <título se conhecido>]
- Caminho do doc: <CAMINHO_ABSOLUTO_DO_DOC>
- Link do doc: [<CAMINHO_ABSOLUTO_DO_DOC>](<CAMINHO_ABSOLUTO_DO_DOC>)
- Arquivo diff: <CAMINHO_ABSOLUTO_DO_DIFF>
- Gerado: <TIMESTAMP_ISO>
- Workspace: <ROOT> (non-SpecWeave)
- Git: branch `<BRANCH>` @ `<SHA>`
## Onde Parei
**Motivo da transferência:** <motivo>
**Resumo:** <resumo>
_Nenhum incremento SpecWeave ativo — esta é uma transferência git + entrevista._
## Feito / Pendente
_Nenhum estado de tarefa/CA de incremento disponível._
## Decisões Principais e Cuidados
- <decisão 1>
- <decisão 2>
**Cuidado:** <cuidado>
## Arquivos Tocados
**NÃO COMMITADOS** — faça commit, stash ou continue editando ANTES de fazer qualquer coisa destrutiva.
<git status --porcelain>
<git diff --stat>
Diff não commitado completo: `<CAMINHO_ABSOLUTO_DO_DIFF>` — leia-o ou execute `git apply --check` contra ele para ver as edições exatas.
## Próximos Passos Exatos
<próximo>
## Como Retomar
Se o caminho do doc acima NÃO existir na máquina em que você está lendo isso, PARE e peça ao usuário para colar a transferência — não improvise contexto.
Para recuperar o transcript ORIGINAL (opcional), encontre sua sessão de origem por ferramenta:
### Claude Code
- Encontre sessão: ls ~/.claude/projects/<munged-cwd>/ (munge: todo caractere não alfanumérico → "-", execuções NÃO colapsadas; ex.: /Users/antonabyzov/Projects/github/specweave-umb/.claude-worktrees/x → -Users-antonabyzov-Projects-github-specweave-umb--claude-worktrees-x)
- Retome: `claude -r <uuid>`
### Codex
- Encontre sessão: ls ~/.codex/sessions/ (diretório mais novo = sessão mais recente)
- Retome: `codex resume <uuid> (ou: codex resume --last)`
### OpenCode
- Encontre sessão: opencode sessions list
- Retome: `opencode -s <id> (forma longa: opencode --session <id>)`
### Gemini CLI
- Encontre sessão: execute /chat list dentro da sessão Gemini para ver tags salvas
- Retome: `/chat resume <tag>`
### Antigravity
- Encontre sessão: abra o Gerenciador de Agentes Antigravity e escolha o thread de tarefa anterior
- Retome: `retome o thread do Gerenciador de Agentes Antigravity`
### Aider
- Encontre sessão: aider mantém .aider.chat.history.md na raiz do repositório
- Retome: `aider --restore-chat-history`
## Redação
- <N> strings `<tipo>` mascaradas
_A limpeza é heurística (regex básico). Uma lista de remoção vazia NÃO é garantia de que este arquivo está limpo — revise antes de compartilhar ou commitar._
---
<!-- Doc format v1 -->
Notas sobre o modelo:
- Se não houver alterações não commitadas, substitua o corpo de Arquivos Tocados por
_Árvore de trabalho limpa — nenhuma edição não commitada._(ou_Não é um repositório git — nenhum diff capturado._quando não houver git). - Se não houver decisões, o corpo de Decisões Principais é
_Nenhuma decisão registrada._; omita a linha Cuidado: quando nenhum cuidado foi dado. - O corpo de Redação é
_Nenhuma string semelhante a token foi detectada._quando nada foi mascarado. - O marcador de rodapé
<!-- Doc format v1 -->é obrigatório e deve ser a última linha — é o sentinela de propriedade.
Prompt de colagem
Padrão (arquivo acessível):
Retome meu trabalho. Leia o documento de transferência em: <CAMINHO_ABSOLUTO_DO_DOC>
Se esse caminho NÃO existir nesta máquina, PARE e peça-me para colar a transferência — não improvise contexto.
As edições não commitadas exatas estão em: <CAMINHO_ABSOLUTO_DO_DIFF>
--inline (entre máquinas, arquivo inacessível): incorpore o CORPO COMPLETO do documento entre marcadores para que ele viaje no próprio prompt:
Retome meu trabalho usando a transferência autocontida abaixo.
Esta é uma transferência completa — trate tudo entre os marcadores como verdade absoluta. Se ela referenciar um caminho `.diff` que não existir nesta máquina, peça-me para colar o diff.
INÍCIO DA TRANSFERÊNCIA
<documento de transferência completo renderizado, incluindo o rodapé Doc format v1>
FIM DA TRANSFERÊNCIA
Padrões de segurança
- O documento + diff são ignorados pelo git por padrão (
.handoff/.gitignore=*) e nunca são commitados automaticamente. Não imprima uma dica degit add. - A limpeza de segredos é executada tanto no texto livre quanto no diff antes de qualquer escrita.
- A limpeza é heurística — aconselhe o usuário a revisar antes de compartilhar ou commitar.