Ambientes auto-hospedados estão em beta público em planos Team e Enterprise; Disponibilidade e limitações cobre o caminho de habilitação. Esta página é a receita de teste de CI; consulte o guia de início rápido para configuração e Implantar em produção para as receitas de frota.
Instale o hook de captura em seu runner de teste
A leitura funciona através de um hook Stop do Claude Code: quando Claude termina um turno, o hook recebe a mensagem final do assistente comolast_assistant_message em seu JSON stdin e a anexa a $E2E_REPLY_DIR/<session_id>.txt. Instale-o da mesma forma que o hook Stop commit-nudge, no ~/.claude/ do host do runner, que o runner semeia em cada sessão.
Salve os arquivos do hook
Salve os dois arquivos abaixo no host do runner:- O bloco de configurações: mescle em
~/.claude/settings.jsonno host do runner - O script: salve como
~/.claude/hooks/e2e-stop-hook-capture.shno host do runner e torne-o executável
Antes de iniciar o runner
Duas coisas das quais o hook depende:- Instale-o antes de iniciar o runner. O runner captura
~/.claude/uma vez na inicialização, portanto um hook adicionado a um runner em execução entra em vigor apenas após uma reinicialização. - Exporte
E2E_REPLY_DIRpara o processo do runner. O hook é uma operação nula quando a variável não está definida ou o diretório não existe, portanto defina-a onde você inicia o runner, como a unidade systemd, especificação de pod ou etapa de CI. O script de teste abaixo também o requer.
E2E_REPLY_DIR existe, o que é inofensivo em um runner de CI descartável, mas não algo para levar para uma imagem de runner de ambiente de produção onde a variável pode ser definida acidentalmente.
Execute o loop de teste
Os sinalizadores de dispatch--environment e --ref requerem Claude Code v2.1.224 ou posterior na máquina que executa o script, o mesmo piso que o próprio runner. Com o hook em vigor e um runner iniciado neste host, o script de teste:
- Cria uma sessão no ambiente de teste com
claude -p "<prompt>" --environment <environment-id> --output-format json, executado a partir de um checkout de git para que a CLI possa detectar automaticamente o repositório a partir do remoteorigin. O--ref <branch>opcional baseia o checkout da sessão em uma ref nomeada em vez do HEAD local. O comando cria a sessão, imprime uma linha de JSON contendosession_ide sai sem aguardar a resposta do Claude. - Aguarda a resposta aparecer em
$E2E_REPLY_DIR/<session_id>.txt, escrita pelo hook Stop no runner assim que o turno é concluído. - Envia um acompanhamento com
claude -p "<message>" --cloud <session_id> --output-format json(consulte Enviar uma mensagem de acompanhamento para uma sessão em execução), que publica um evento de usuário na sessão existente e sai. - Aguarda a resposta do acompanhamento da mesma forma que a etapa 2.
Comportamento de dispatch --environment
Claude Code cria a sessão, imprime o ID da sessão e um link para ela, e sai.
O sinalizador tem precedência sobre a configuração remote.defaultEnvironmentId. Ele não suporta --output-format stream-json e não pode ser combinado com sinalizadores que retomam, anexam ou pré-configuram uma sessão, como --resume, --continue, --teleport, --session-id ou --init-only. --cloud é rejeitado com um ID de sessão ou URL, e em execuções não interativas quando carrega uma descrição. Um --cloud simples é tratado como ausente. A partir de um terminal, você pode passar a tarefa como a descrição --cloud em vez de um prompt posicional.
Script de exemplo
O script abaixo executa o loop completo contra$CLAUDE_TEST_ENVIRONMENT_ID, o ID ccpool_... do seu ambiente de teste, mostrado no diálogo de detalhes do ambiente na página de administração ou retornado pela chamada create-environment, e afirma uma frase sentinela em cada resposta. Execute-o a partir de um checkout de git do repositório no qual você deseja que a sessão funcione, após iniciar um runner neste host com o hook de captura instalado e E2E_REPLY_DIR exportado.
TURN1/TURN2 e as sentinelas EXPECT1/EXPECT2 por qualquer coisa que exercite sua configuração, como pedir ao Claude para executar uma de suas ferramentas MCP personalizadas e afirmar sua saída.
Runners de teste remotos
Se seus runners de teste estão em infraestrutura separada, como uma frota Kubernetes persistente com a qual seu trabalho de CI não pode compartilhar um sistema de arquivos, troque a escrita de arquivo no hook Stop por um POST para um endpoint que seu driver escuta:Autentique a partir de CI
Tantoclaude -p ... --environment quanto claude -p ... --cloud autenticam com um token OAuth claude.ai; chaves de API, como sk-ant-xxxxx, não são aceitas para nenhuma das duas chamadas. Duas abordagens disponibilizam um token em CI.
Host de CI de longa duração
Executeclaude auth login uma vez interativamente na máquina que executa o script, usando uma conta de usuário dedicada para automação. Claude Code armazena o token no chaveiro do SO no macOS, ou em ~/.claude/.credentials.json no Linux e Windows. Em um host macOS cujo Keychain não pode ser escrito, como é típico em uma sessão SSH onde o Keychain de login permanece bloqueado, Claude Code armazena o token em ~/.claude/.credentials.json lá também. Consulte Gerenciamento de credenciais.
A CLI atualiza o token de acesso de curta duração automaticamente em cada invocação, mas a concessão de token de atualização subjacente é limitada a 30 dias a partir do login inicial, portanto execute claude auth login interativamente nesse host a cada 30 dias.
Runners de CI efêmeros
Não há token de CI de longa duração para isso hoje. O escopo que concede controle de sessão remota,user:sessions:claude_code, é limitado no servidor a 30 dias, portanto claude setup-token, que cria um token somente de inferência de um ano, não o cobre. O segredo do ambiente também não é aceito, pois apenas autoriza um runner a se registrar no ambiente, não a criar sessões.
Para provisionar um login armazenado em um runner efêmero, defina CLAUDE_CODE_OAUTH_REFRESH_TOKEN e CLAUDE_CODE_OAUTH_SCOPES para que claude auth login troque o token sem um navegador; o mesmo limite de 30 dias se aplica à concessão de atualização. Entre em contato com sua equipe de conta Anthropic se você precisar de um caminho de identidade de máquina que não esteja vinculado a uma conta humana.
Crie um ambiente de teste dedicado
Crie e exclua ambientes programaticamente para que cada execução de CI obtenha um limpo; o runner que seu trabalho de CI inicia se registra no ambiente novo. As chamadas de criação e exclusão abaixo são os mesmos endpoints que a página de administração Cloud environments em claude.ai usa, e requerem o cabeçalhoanthropic-beta: ccr-byoc-2025-07-29.
Crie o token de administrador
$ADMIN_TOKEN é um token de acesso OAuth claude.ai para uma conta que possui uma função de Proprietário, criado da mesma forma que Autentique a partir de CI:
- Crie-o: execute
claude auth logincom uma conta que possui uma função de Proprietário, depois leia o token de acesso atual de onde Host de CI de longa duração diz que Claude Code o armazenou. - Leia-o novo em cada execução: a CLI rotaciona o token de acesso, e o mesmo limite de concessão de atualização de 30 dias se aplica, portanto não armazene uma cópia.
- Passe-o via stdin: como o exemplo faz, para que o token nunca chegue à lista de argumentos do curl ou seu log de compilação.
Crie o ambiente
Capture a resposta sem ecoá-la:pool_secret é uma credencial de longa duração que pode registrar runners no ambiente, portanto armazene-a como um segredo de CI mascarado e imprima apenas o ID do ambiente. O formulário -H @- que mantém o token fora da lista de processos requer curl 7.55 ou posterior; curl mais antigo trata @- como um cabeçalho literal e envia a solicitação sem autorização.
403 permission_error lendo self-hosted runners are disabled by your organization's policy.
Inicie um runner neste host com SELF_HOSTED_RUNNER_ENVIRONMENT_SECRET=$ENVIRONMENT_SECRET, mais o hook de captura e E2E_REPLY_DIR por Instale o hook de captura, depois execute o script de teste.